make numericx_translate()

* add numericx_free() and numericx_translate()
 * functionality in main() to the minimum, to house the
   numericx_translate() in it

Signed-off-by: Daniel Santos <dacs.git@brilhante.top>
This commit is contained in:
Daniel Santos 2022-03-17 07:34:32 +00:00
parent 2775a1670c
commit 2fe995048c
1 changed files with 171 additions and 66 deletions

View File

@ -368,6 +368,152 @@ free_numeral(numeral_ptr* numeral)
}
}
/**
* @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 Convert numeral_ptr to string
*
* 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
*/
char*
numeral_to_string(numeral_ptr* numeral, bool result_with_units_on_the_end)
{
size_t length = 1;
numeral_ptr* numeral_last = numeral;
while( !(numeral_last->next == NULL) )
{
++length;
numeral_last = numeral_last->next;
}
char* result = malloc((length + 1) * sizeof(char));
char* tmp = result;
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;
}
}
*(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);
return NULL;
}
/* _first and _last variables */
char* from_first = from;
char* from_last = from + (strlen(from) - 1);
char* to_first = to;
char* to_last = to + (strlen(to) - 1);
if( from_units_on_the_end )
{
reverse_string(number);
}
/* initializing counting and result */
numeral_ptr* counting = NULL;
numeral_ptr* result = NULL;
if( from_infinite_base )
counting = numeral_infinity(from_first, strlen(number));
else
counting = numeral_infinity(from_first, 1);
result = numeral_infinity(to_first, 1);
/* first number void */
if( !(from_first_number_void && to_first_number_void) )
{
if( from_first_number_void )
{
if( strlen(number) == 1 && *number == *from_first )
{
free_numeral(counting);
free_numeral(result);
fprintf(stderr, "error: %s: unrepresentable void number\n", PROG_NAME);
return NULL;
}
decrement_number_string(number, from_first, from_last, from_first);
}
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 )
to_second = to_first + 1;
/* increments until it finishes */
while( !is_the_same(counting, number) )
{
if( to_infinite_base )
increment(result, to_first, to_last, to_second);
else
increment(result, to_first, to_last, to_first);
increment(counting, from_first, from_last, from_first);
}
/* result to string (result_string) */
char* result_string = numeral_to_string(result, to_units_on_the_end);
/* free memory */
free_numeral(counting);
free_numeral(result);
return result_string;
}
/* ||MAIN FUNCTION|| */
@ -386,15 +532,22 @@ main(int argc, char* argv[])
exit(EXIT_FAILURE);
}
/* Numeral System variables from MACROS */
/* 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);
/* Number variables to be converted */
char* number = argv[1];
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) )
@ -406,76 +559,28 @@ main(int argc, char* argv[])
exit(EDOM);
}
/* _first and _last variables */
char* from_first = from;
char* from_last = from + (strlen(from) - 1);
/* 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);
char* to_first = to;
char* to_last = to + (strlen(to) - 1);
if( FROM_UNITS_ON_THE_END )
/* Test for translation failure */
if( result == NULL )
{
reverse_string(number);
fprintf(stderr, "error: %s: Invalid translation\n", PROG_NAME);
free(from);
free(to);
return EXIT_FAILURE;
}
/* initializing counting and result */
numeral_ptr* counting = NULL;
numeral_ptr* result = NULL;
/* Print */
printf("%s\n", result);
if( FROM_INFINITE_BASE )
counting = numeral_infinity(from_first, strlen(number));
else
counting = numeral_infinity(from_first, 1);
result = numeral_infinity(to_first, 1);
/* first number void */
if( !(FROM_FIRST_NUMBER_VOID && TO_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);
}
decrement_number_string(number, from_first, from_last, from_first);
}
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 )
to_second = to_first + 1;
/* increments until it finishes */
while( !is_the_same(counting, number) )
{
if( TO_INFINITE_BASE )
increment(result, to_first, to_last, to_second);
else
increment(result, to_first, to_last, to_first);
increment(counting, from_first, from_last, from_first);
}
/* print */
print_numeral(result);
printf("\n");
/* free memory */
/* Free */
free(from);
free(to);
free_numeral(counting);
free_numeral(result);
numericx_free(result);
return EXIT_SUCCESS;
}