about summary refs log blame commit diff stats
path: root/cli.c
blob: 816da7d0d03b07a7dd46cf9c33e946d67a309da7 (plain) (tree)
/** @file cli.c
 * Numericx command-line interface (CLI) program.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <errno.h>
#include "numericx.h"


/* ||COMPILATION FLAGS|| */

/**
 * @name Compilation Flags
 *
 * These are the valid compilation flags for the definition of numerical systems.
 * Use them to set the proprieties of the FROM and the TO numerical system, when
 * compiling the cli executable.
 *
 * @{
 */

/**
 * @param bool
 *
 * Configuration of the resulting numeral system
 * to have the units place on the end of the writing direction (on the right).
 */
#ifndef TO_UNITS_ON_THE_END
#define TO_UNITS_ON_THE_END false
#endif

/**
 * @param bool
 *
 * Configuration of the numeral system of the number input
 * to have the units place on the end of the writing direction (on the right).
 */
#ifndef FROM_UNITS_ON_THE_END
#define FROM_UNITS_ON_THE_END false
#endif

/**
 * @param bool
 *
 * Configuration of the resulting numeral system
 * to start counting on the second number, being the
 * first number void.
 */
#ifndef TO_FIRST_NUMBER_VOID
#define TO_FIRST_NUMBER_VOID false
#endif

/**
 * @param bool
 *
 * Configuration of the numeral system of the number input
 * to start counting on the second number, being the
 * first number void.
 */
#ifndef FROM_FIRST_NUMBER_VOID
#define FROM_FIRST_NUMBER_VOID false
#endif

/**
 * @param bool
 *
 * Configuration of the resulting numeral system
 * to have the first number as an infinite number,
 * for example, if the first number is 'A', then
 * A == AA == AAA == AAAA ...
 */
#ifndef TO_INFINITE_BASE
#define TO_INFINITE_BASE false
#endif

/**
 * @param bool
 *
 * Configuration of the numeral system of the number input
 * to have the first number as an infinite number,
 * for example, if the first number is 'A', then
 * A == AA == AAA == AAAA ...
 */
#ifndef FROM_INFINITE_BASE
#define FROM_INFINITE_BASE false
#endif

/** @} */


/* ||MAIN FUNCTION|| */

/**
 * @brief CLI program.
 *
 * This is a command-line interface program, that uses the 'numericx_*'
 * functions. It receives one number argument from the command-line and
 * prints the translated number, or an error message.
 *
 * @param argv[] - one number from the command-line.
 *
 * @return E2BIG in case of wrong number of arguments.
 * @return EXIT_FAILURE in case of unsuccessful number translation.
 * @return EXIT_SUCCESS in case of a successful number translation.
 */
int
main(int argc, char* argv[])
{
	/* argument processing */
	if( !(argc == 2) )
	{
		fprintf(stderr, "usage: %s <number>\n", PROG_NAME);
		return E2BIG;
	}

	/* Number variables to be converted */
	char* number = argv[1];

	/* Arguments for translation */
	char* from = malloc( (strlen(FROM_NUMERICALS) + 1) * sizeof(char) );
	char* to = malloc( (strlen(TO_NUMERICALS) + 1) * sizeof(char) );

	strcpy(from, FROM_NUMERICALS);
	strcpy(to, TO_NUMERICALS);

	bool to_units_on_the_end = TO_UNITS_ON_THE_END;
	bool from_units_on_the_end = FROM_UNITS_ON_THE_END;
	bool to_first_number_void = TO_FIRST_NUMBER_VOID;
	bool from_first_number_void = FROM_FIRST_NUMBER_VOID;
	bool to_infinite_base = TO_INFINITE_BASE;
	bool from_infinite_base = FROM_INFINITE_BASE;

	/* Translation */
	char* result = NULL;
	int status = numericx_translate(
			from, from_units_on_the_end, from_first_number_void, from_infinite_base,
			to, to_units_on_the_end, to_first_number_void, to_infinite_base,
			number, &result);

	/* Test for translation failure */
	switch( status )
	{
		case EINVAL:
			fprintf(stderr, "error: %s: %s. Resulting string variable has to be NULL.\n",
					PROG_NAME, strerror(EINVAL));
			break;
		case EDOM:
			fprintf(stderr, "error: %s: %s. Valid numerals are: \"%s\".\n",
					PROG_NAME, strerror(EDOM), from);
			break;
		case ERANGE:
				fprintf(stderr, "error: %s: Unrepresentable void number.\n", PROG_NAME);
			break;
	}
	if( !(status == EXIT_SUCCESS) )
	{
		fprintf(stderr, "error: %s: Incapable of translating.\n", PROG_NAME);
		free(from);
		free(to);
		numericx_free(result);

		return EXIT_FAILURE;
	}

	/* Print */
	printf("%s\n", result);

	/* Free */
	free(from);
	free(to);
	numericx_free(result);

	return EXIT_SUCCESS;
}