diff options
-rw-r--r-- | numericx.c | 175 |
1 files changed, 140 insertions, 35 deletions
diff --git a/numericx.c b/numericx.c index c3d6b97..695ef4e 100644 --- a/numericx.c +++ b/numericx.c @@ -368,42 +368,82 @@ free_numeral(numeral_ptr* numeral) } } - -/* ||MAIN FUNCTION|| */ +/** + * @brief Free numericx result + * + * Function frees up the result of numericx_translate(), + * after we are done with it + * + * @param string - char pointer to be free + */ +void +numericx_free(char* string) +{ + free(string); +} /** - * @brief Translate number. + * @brief Convert numeral_ptr to string * - * Main function that does the translation of the number. + * Allocates space for string and converts numeral_ptr* to char* + * + * @param numeral - numeral_ptr to be converted to string + * @param result_with_units_on_the_end - define if result has units on the end + * + * @return char pointer to converted string in case of success + * @return NULL in case of no memory */ -int -main(int argc, char* argv[]) +char* +numeral_to_string(numeral_ptr* numeral, bool result_with_units_on_the_end) { - /* argument processing */ - if( !(argc == 2) ) + size_t length = 1; + numeral_ptr* numeral_last = numeral; + + while( !(numeral_last->next == NULL) ) { - fprintf(stderr, "usage: %s <number>\n", PROG_NAME); - exit(EXIT_FAILURE); + ++length; + numeral_last = numeral_last->next; } - /* Numeral System variables from MACROS */ - char* from = malloc( (strlen(FROM_NUMERICALS) + 1) * sizeof(char) ); - char* to = malloc( (strlen(TO_NUMERICALS) + 1) * sizeof(char) ); + char* result = malloc((length + 1) * sizeof(char)); + char* tmp = result; - strcpy(from, FROM_NUMERICALS); - strcpy(to, TO_NUMERICALS); + if( !result_with_units_on_the_end ) + { + for( numeral_ptr* digit = numeral; + !(digit == NULL); digit = digit->next) + { + *tmp = *(digit->symbol); + ++tmp; + } + } + else + { + for( numeral_ptr* digit = numeral_last; + !(digit == NULL); digit = digit->previous) + { + *tmp = *(digit->symbol); + ++tmp; + } + } - /* Number variables to be converted */ - char* number = argv[1]; + *(tmp) = '\0'; + + return result; +} + +/** + */ +char* +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) +{ /* Check if number belongs to it's numerical system */ if( !is_valid_number(from, number) ) { fprintf(stderr, "error: %s: %s.\nValid numerals are: \"%s\"\n", PROG_NAME, strerror(EDOM), from); - free(from); - free(to); - exit(EDOM); + return NULL; } /* _first and _last variables */ @@ -413,7 +453,7 @@ main(int argc, char* argv[]) char* to_first = to; char* to_last = to + (strlen(to) - 1); - if( FROM_UNITS_ON_THE_END ) + if( from_units_on_the_end ) { reverse_string(number); } @@ -422,7 +462,7 @@ main(int argc, char* argv[]) numeral_ptr* counting = NULL; numeral_ptr* result = NULL; - if( FROM_INFINITE_BASE ) + if( from_infinite_base ) counting = numeral_infinity(from_first, strlen(number)); else counting = numeral_infinity(from_first, 1); @@ -430,36 +470,34 @@ main(int argc, char* argv[]) result = numeral_infinity(to_first, 1); /* first number void */ - if( !(FROM_FIRST_NUMBER_VOID && TO_FIRST_NUMBER_VOID) ) + if( !(from_first_number_void && to_first_number_void) ) { - if( FROM_FIRST_NUMBER_VOID ) + if( from_first_number_void ) { if( strlen(number) == 1 && *number == *from_first ) { - free(from); - free(to); free_numeral(counting); free_numeral(result); fprintf(stderr, "error: %s: unrepresentable void number\n", PROG_NAME); - exit(EXIT_FAILURE); + return NULL; } decrement_number_string(number, from_first, from_last, from_first); } - if( TO_FIRST_NUMBER_VOID ) + if( to_first_number_void ) increment(result, to_first, to_last, to_first); } /* minor optimization for the cycle below */ char* to_second = NULL; - if( TO_INFINITE_BASE ) + if( to_infinite_base ) to_second = to_first + 1; /* increments until it finishes */ while( !is_the_same(counting, number) ) { - if( TO_INFINITE_BASE ) + if( to_infinite_base ) increment(result, to_first, to_last, to_second); else increment(result, to_first, to_last, to_first); @@ -467,15 +505,82 @@ main(int argc, char* argv[]) increment(counting, from_first, from_last, from_first); } - /* print */ - print_numeral(result); - printf("\n"); + /* result to string (result_string) */ + char* result_string = numeral_to_string(result, to_units_on_the_end); /* free memory */ - free(from); - free(to); free_numeral(counting); free_numeral(result); + return result_string; +} + +/* ||MAIN FUNCTION|| */ + +/** + * @brief Translate number. + * + * Main function that does the translation of the number. + */ +int +main(int argc, char* argv[]) +{ + /* argument processing */ + if( !(argc == 2) ) + { + fprintf(stderr, "usage: %s <number>\n", PROG_NAME); + exit(EXIT_FAILURE); + } + + /* 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; + + /* Check if number belongs to it's numerical system */ + if( !is_valid_number(from, number) ) + { + fprintf(stderr, "error: %s: %s.\nValid numerals are: \"%s\"\n", + PROG_NAME, strerror(EDOM), from); + free(from); + free(to); + exit(EDOM); + } + + /* Translation */ + char* result = 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); + + /* Test for translation failure */ + if( result == NULL ) + { + fprintf(stderr, "error: %s: Invalid translation\n", PROG_NAME); + free(from); + free(to); + return EXIT_FAILURE; + } + + /* Print */ + printf("%s\n", result); + + /* Free */ + free(from); + free(to); + numericx_free(result); + return EXIT_SUCCESS; } |