diff --git a/cli.c b/cli.c new file mode 100644 index 0000000..816da7d --- /dev/null +++ b/cli.c @@ -0,0 +1,176 @@ +/** @file cli.c + * Numericx command-line interface (CLI) program. + */ +#include +#include +#include +#include +#include +#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 \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; +} diff --git a/numericx.c b/numericx.c index 3518fcc..f6f3b31 100644 --- a/numericx.c +++ b/numericx.c @@ -1,110 +1,12 @@ /** @file numericx.c - * Source code of the number translator command-line interface. + * Numericx library implementation. */ #include #include #include #include #include - -#define PROG_NAME "numericx" - - -/* ||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 - -/** @} */ - -/* ||DATA STRUCTURE|| */ - -/** - * @brief Numeral structure - * - * This struct is in use to apply our operations on the number. - * The number are converted to this struct, the operations are applied, - * and on the end, the resulting number is converted from this struct. - */ -typedef struct NumeralPtr -{ - char const* symbol; /**< a pointer to the glyph/numeral/symbol of this digit. */ - struct NumeralPtr *next; /**< a pointer to the next digit */ - struct NumeralPtr *previous; /**< a pointer to the previous digit */ -} numeral_ptr; +#include "numericx.h" /* ||FUNCTIONS|| */ @@ -122,7 +24,7 @@ typedef struct NumeralPtr * @return pointer to new numeral_ptr in case of success. * @return NULL in case of no memory. */ -numeral_ptr* +static numeral_ptr* new_digit(numeral_ptr* last_numeral, char const* to_first) { numeral_ptr* new_numeral = malloc(sizeof(numeral_ptr)); @@ -153,7 +55,7 @@ new_digit(numeral_ptr* last_numeral, char const* to_first) * @return NULL in case of no memory ( because depends * on new_digit() ). */ -numeral_ptr* +static numeral_ptr* numeral_infinity(char const* to_first, size_t cases) { numeral_ptr* starting_case = new_digit(NULL, to_first); @@ -182,7 +84,7 @@ numeral_infinity(char const* to_first, size_t cases) * @param num_last - number's numeral system last numeral. * @param brand_new_digit - brand new created numeral, if needed by incrementation. */ -void +static void increment(numeral_ptr* numeral, char* num_first, char* num_last, char* brand_new_digit) { bool cycled = false; @@ -216,7 +118,7 @@ increment(numeral_ptr* numeral, char* num_first, char* num_last, char* brand_new * @param last_numeral - number's numeral system last numeral. * @param numeral_system - string of the corresponding number's numeral system numeral. */ -void +static void decrement_number_string(char* number, char* first_numeral, char* last_numeral, char* numeral_system) { while( *number == *first_numeral ) @@ -249,7 +151,7 @@ decrement_number_string(char* number, char* first_numeral, char* last_numeral, c * @return true if matches. * @return false if doesn't match. */ -bool +static bool is_the_same(numeral_ptr* numeral, char* number_arg) { while( !(numeral == NULL) ) @@ -273,11 +175,12 @@ is_the_same(numeral_ptr* numeral, char* number_arg) * Prints to standard output numeral_ptr ('numeral'). * * @param numeral - numeral_ptr to print. + * @param to_units_on_the_end - define if printing a number with units on the end (on the right) */ -void -print_numeral(numeral_ptr* numeral) +static void +print_numeral(numeral_ptr* numeral, bool to_units_on_the_end) { - if( TO_UNITS_ON_THE_END ) + if( to_units_on_the_end ) { while( !(numeral->next == NULL) ) numeral = numeral->next; @@ -303,7 +206,7 @@ print_numeral(numeral_ptr* numeral) * * @param string - string to be reversed. */ -void +static void reverse_string(char* string) { char tmp; @@ -331,7 +234,7 @@ reverse_string(char* string) * @return true if it belongs. * @return false if it doesn't belong. */ -bool +static bool is_valid_number(char* numeral_system, char *number) { /* @@ -355,7 +258,7 @@ is_valid_number(char* numeral_system, char *number) * * @param numeral - numeral_ptr to free. */ -void +static void free_numeral(numeral_ptr* numeral) { numeral_ptr* tmp = NULL; @@ -393,7 +296,7 @@ numericx_free(char* string) * @return char pointer to converted string, in case of success. * @return NULL in case of no memory. */ -char* +static char* numeral_to_string(numeral_ptr* numeral, bool result_with_units_on_the_end) { size_t length = 1; @@ -534,88 +437,3 @@ numericx_translate(char* from, bool from_units_on_the_end, bool from_first_numbe return EXIT_SUCCESS; } - -/* ||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 \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; -} diff --git a/numericx.h b/numericx.h new file mode 100644 index 0000000..410f932 --- /dev/null +++ b/numericx.h @@ -0,0 +1,67 @@ +/** @file numericx.h + * Numericx library header file. + */ +#ifndef _NUMERICX_H +#define _NUMERICX_H + +#include + +#define PROG_NAME "numericx" + +/* ||DATA STRUCTURE|| */ + +/** + * @brief Numeral structure + * + * This struct is in use to apply our operations on the number. + * The number are converted to this struct, the operations are applied, + * and on the end, the resulting number is converted from this struct. + */ +typedef struct NumeralPtr +{ + char const* symbol; /**< a pointer to the glyph/numeral/symbol of this digit. */ + struct NumeralPtr *next; /**< a pointer to the next digit */ + struct NumeralPtr *previous; /**< a pointer to the previous digit */ +} numeral_ptr; + + +/* ||FUNCTIONS|| */ + +/** + * @brief Free numericx result. + * + * Free up the result string of numericx_translate(), + * after we are done with it. + * + * @param string - char pointer to be free. + */ +void +numericx_free(char* string); + +/** + * @brief Translate string to a different numerical system. + * + * After definition of the 'from' numerical system proprieties and the + * 'to' numerical system proprieties, will be translate 'number' from the + * 'from' to the 'to' numerical system, resulting in a string. + * + * @param from - string with all the numerals of the number's numerical system. + * @param from_units_on_the_end - does the translate 'from' numerical system have units on the end (on the right)? + * @param from_first_number_void - does the translate 'from' numerical system start counting on the second number? + * @param from_infinite_base - is the translate 'from' numerical system first numeral infinite? For example, if first numeral is 'A', then does 'A' == 'AA' == 'AAA' == 'AAAA' ... ? + * @param to - string with all the numerals of the resulting number's numerical system. + * @param to_units_on_the_end - does the translate 'to' numerical system have units on the end (on the right)? + * @param to_first_number_void - does the translate 'to' numerical system start counting on the second number? + * @param to_infinite_base - is the translate 'to' numerical system first numeral infinite? For example, if first numeral is 'A', then does 'A' == 'AA' == 'AAA' == 'AAAA' ... ? + * @param number - number of the 'from' numerical system, to be translated into the 'to' numerical system. + * @param result_string - string to where to store the result. + * + * @return EINVAL if argument of result_string is not NULL. + * @return EDOM if number doesn't belong to the 'from' numerical system. + * @return ERANGE if the resulting number cannot be represented, because of a 'from' void number and a lack of void number in 'to'. + * @return EXIT_SUCCESS in case of success. + */ +int +numericx_translate(char* from, bool from_units_on_the_end, bool from_first_number_void, bool from_infinite_base, char* to, bool to_units_on_the_end, bool to_first_number_void, bool to_infinite_base, char* number, char** result_string); + +#endif