Compare commits
3 Commits
c4bc0ae725
...
a23fe88c3a
Author | SHA1 | Date | |
---|---|---|---|
|
a23fe88c3a | ||
|
2fe995048c | ||
|
2775a1670c |
2
Makefile
2
Makefile
|
@ -18,7 +18,7 @@ sun-to-decimal: $(DEP)
|
||||||
$(CC) $(CFLAGS) -DFROM_NUMERICALS=\"123456789\" -DTO_NUMERICALS=\"0123456789\" -DTO_FIRST_NUMBER_VOID -DTO_INFINITE_BASE -o $@ $^
|
$(CC) $(CFLAGS) -DFROM_NUMERICALS=\"123456789\" -DTO_NUMERICALS=\"0123456789\" -DTO_FIRST_NUMBER_VOID -DTO_INFINITE_BASE -o $@ $^
|
||||||
|
|
||||||
sun-to-earth: $(DEP)
|
sun-to-earth: $(DEP)
|
||||||
$(CC) $(CFLAGS) -DFROM_NUMERICALS=\"123456789\" -DTO_NUMERICALS=\"12345\" $@ $^
|
$(CC) $(CFLAGS) -DFROM_NUMERICALS=\"123456789\" -DTO_NUMERICALS=\"12345\" -o $@ $^
|
||||||
|
|
||||||
earth-to-sun: $(DEP)
|
earth-to-sun: $(DEP)
|
||||||
$(CC) $(CFLAGS) -DFROM_NUMERICALS=\"12345\" -DTO_NUMERICALS=\"123456789\" -o $@ $^
|
$(CC) $(CFLAGS) -DFROM_NUMERICALS=\"12345\" -DTO_NUMERICALS=\"123456789\" -o $@ $^
|
||||||
|
|
260
numericx.c
260
numericx.c
|
@ -22,15 +22,6 @@
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @param bool
|
|
||||||
*
|
|
||||||
* Show debug message of the step by step incrementation of the number.
|
|
||||||
*/
|
|
||||||
#ifndef DEBUG
|
|
||||||
#define DEBUG false
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param bool
|
* @param bool
|
||||||
*
|
*
|
||||||
|
@ -377,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|| */
|
/* ||MAIN FUNCTION|| */
|
||||||
|
|
||||||
|
@ -395,15 +532,22 @@ main(int argc, char* argv[])
|
||||||
exit(EXIT_FAILURE);
|
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* from = malloc( (strlen(FROM_NUMERICALS) + 1) * sizeof(char) );
|
||||||
char* to = malloc( (strlen(TO_NUMERICALS) + 1) * sizeof(char) );
|
char* to = malloc( (strlen(TO_NUMERICALS) + 1) * sizeof(char) );
|
||||||
|
|
||||||
strcpy(from, FROM_NUMERICALS);
|
strcpy(from, FROM_NUMERICALS);
|
||||||
strcpy(to, TO_NUMERICALS);
|
strcpy(to, TO_NUMERICALS);
|
||||||
|
|
||||||
/* Number variables to be converted */
|
bool to_units_on_the_end = TO_UNITS_ON_THE_END;
|
||||||
char* number = argv[1];
|
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 */
|
/* Check if number belongs to it's numerical system */
|
||||||
if( !is_valid_number(from, number) )
|
if( !is_valid_number(from, number) )
|
||||||
|
@ -415,94 +559,28 @@ main(int argc, char* argv[])
|
||||||
exit(EDOM);
|
exit(EDOM);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* _first and _last variables */
|
/* Translation */
|
||||||
char* from_first = from;
|
char* result = numericx_translate(
|
||||||
char* from_last = from + (strlen(from) - 1);
|
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;
|
/* Test for translation failure */
|
||||||
char* to_last = to + (strlen(to) - 1);
|
if( result == NULL )
|
||||||
|
|
||||||
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 )
|
|
||||||
{
|
{
|
||||||
|
fprintf(stderr, "error: %s: Invalid translation\n", PROG_NAME);
|
||||||
free(from);
|
free(from);
|
||||||
free(to);
|
free(to);
|
||||||
free_numeral(counting);
|
return EXIT_FAILURE;
|
||||||
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 )
|
/* Print */
|
||||||
increment(result, to_first, to_last, to_first);
|
printf("%s\n", result);
|
||||||
}
|
|
||||||
|
|
||||||
/* minor optimization for the cycle below */
|
/* Free */
|
||||||
char* to_second = NULL;
|
|
||||||
|
|
||||||
if( TO_INFINITE_BASE )
|
|
||||||
to_second = to_first + 1;
|
|
||||||
|
|
||||||
/* increments until it finishes */
|
|
||||||
while( !is_the_same(counting, number) )
|
|
||||||
{
|
|
||||||
if(DEBUG)
|
|
||||||
print_numeral(result);
|
|
||||||
|
|
||||||
if( TO_INFINITE_BASE )
|
|
||||||
increment(result, to_first, to_last, to_second);
|
|
||||||
else
|
|
||||||
increment(result, to_first, to_last, to_first);
|
|
||||||
|
|
||||||
if(DEBUG)
|
|
||||||
{
|
|
||||||
printf(" | ");
|
|
||||||
print_numeral(counting);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
increment(counting, from_first, from_last, from_first);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* print */
|
|
||||||
if(DEBUG)
|
|
||||||
{
|
|
||||||
print_numeral(result);
|
|
||||||
printf(" | ");
|
|
||||||
print_numeral(counting);
|
|
||||||
printf("\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
print_numeral(result);
|
|
||||||
printf("\n");
|
|
||||||
|
|
||||||
/* free memory */
|
|
||||||
free(from);
|
free(from);
|
||||||
free(to);
|
free(to);
|
||||||
free_numeral(counting);
|
numericx_free(result);
|
||||||
free_numeral(result);
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user