Compare commits

...

16 Commits

Author SHA1 Message Date
Daniel Santos 4eb78790a9 numericx_translate() not printing message
* numericx_translate() only returns status codes. Instead of returning
   the resulting translated string.
 * add result_string to numericx_translate() arguments, that is the
   variable to where to store the resulting translated string.
 * for the cli program, now the message is delegated to main. Also
   changed the doxygen comments of main().

Signed-off-by: Daniel Santos <dacs.git@brilhante.top>
2022-03-17 11:56:52 +00:00
Daniel Santos 089a2a899c Makefile more memory rules
* add to Makefile the rules: mem1, mem2 and mem3

Signed-off-by: Daniel Santos <dacs.git@brilhante.top>
2022-03-17 11:51:42 +00:00
Daniel Santos 30d4aede61 doc update
Signed-off-by: Daniel Santos <dacs.git@brilhante.top>
2022-03-17 09:09:14 +00:00
Daniel Santos 327de4f901 update numericx.c comments
Signed-off-by: Daniel Santos <dacs.git@brilhante.top>
2022-03-17 09:07:07 +00:00
Daniel Santos 23772dbb14 doc update
Signed-off-by: Daniel Santos <dacs.git@brilhante.top>
2022-03-17 07:55:41 +00:00
Daniel Santos a23fe88c3a Makefile fix
* fix sun-to-earth rule, missing -o

Signed-off-by: Daniel Santos <dacs.git@brilhante.top>
2022-03-17 07:49:49 +00:00
Daniel Santos 2fe995048c 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>
2022-03-17 07:49:49 +00:00
Daniel Santos 2775a1670c remove DEBUG
* remove debug message printing and the DEBUG variable

Signed-off-by: Daniel Santos <dacs.git@brilhante.top>
2022-03-17 07:49:49 +00:00
Daniel Santos c4bc0ae725 rename doxygen.conf to Doxyfile
Signed-off-by: Daniel Santos <dacs.git@brilhante.top>
2022-03-16 21:39:09 +00:00
Daniel Santos e4545cb7fd doc update
Signed-off-by: Daniel Santos <dacs.git@brilhante.top>
2022-03-16 20:04:29 +00:00
Daniel Santos 2952ed7c23 add html symlink for doxygen build
* add html symbolic link pointing to doc/, so that when building the
   doc with doxygen, all documentation goes to doc/

Signed-off-by: Daniel Santos <dacs.git@brilhante.top>
2022-03-16 20:01:12 +00:00
Daniel Santos c6d7a8a26f add Documentation section in README.md
* README.md has a Documentation section with a link to the online
   documentation website

Signed-off-by: Daniel Santos <dacs.git@brilhante.top>
2022-03-16 19:50:28 +00:00
Daniel Santos 9393cea4a4 add submodule doc/
Signed-off-by: Daniel Santos <dacs.git@brilhante.top>
2022-03-16 16:49:37 +00:00
Daniel Santos b1f890b434 remove html/ for submodule
* remove html/* for the creating on a submodule in this directory, so
   that the documentation can be in a separate branch, for codeberg
   pages

Signed-off-by: Daniel Santos <dacs.git@brilhante.top>
2022-03-16 16:18:42 +00:00
Daniel Santos fdd2142827 update README.md
* text 'console program' to 'command-line interface'

Signed-off-by: Daniel Santos <dacs.git@brilhante.top>
2022-03-16 14:33:18 +00:00
Daniel Santos acc2126757 add doxygen
* transformed comments into doxygen comments and set it's attributes
 * add doxygen.conf file
 * add doxygen html documentation

Signed-off-by: Daniel Santos <dacs.git@brilhante.top>
2022-03-16 14:29:11 +00:00
7 changed files with 3027 additions and 140 deletions

4
.gitmodules vendored Normal file
View File

@ -0,0 +1,4 @@
[submodule "doc"]
path = doc
url = git@codeberg.org:dacs-git/numericx.git
branch = pages

2658
Doxyfile Normal file

File diff suppressed because it is too large Load Diff

View File

@ -18,7 +18,7 @@ sun-to-decimal: $(DEP)
$(CC) $(CFLAGS) -DFROM_NUMERICALS=\"123456789\" -DTO_NUMERICALS=\"0123456789\" -DTO_FIRST_NUMBER_VOID -DTO_INFINITE_BASE -o $@ $^
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)
$(CC) $(CFLAGS) -DFROM_NUMERICALS=\"12345\" -DTO_NUMERICALS=\"123456789\" -o $@ $^
@ -61,10 +61,19 @@ clean:
run: decimal-to-earth
./decimal-to-earth 21
.PHONY: mem
mem: decimal-to-earth
.PHONY: mem mem1 mem2 mem3
mem:
echo "the memory make rules are: mem1 mem2 mem3"
mem1: decimal-to-earth
valgrind --leak-check=full --show-leak-kinds=all -s decimal-to-earth 999
mem2: decimal-to-earth
valgrind --leak-check=full --show-leak-kinds=all -s decimal-to-earth 0
mem3: decimal-to-earth
valgrind --leak-check=full --show-leak-kinds=all -s decimal-to-earth abc
decimal-to-earth_test-1: $(DEP)
$(CC) $(CFLAGS) -DFROM_NUMERICALS=\"0123456789\" -DFROM_FIRST_NUMBER_VOID -DFROM_INFINITE_BASE -DTO_NUMERICALS=\"12345\" -o $@ $^

View File

@ -1,6 +1,6 @@
# Numericx
A console program that converts a number (or text) from one numerical system into another different numerical system.
A command-line interface (CLI) program that converts a number (or text) from one numerical system into another different numerical system.
## Compiling
@ -55,6 +55,10 @@ Below, are the meanings of the `FROM` flags. The `TO` flags are the same as the
There is also the `DEBUG` flag, which will show all the steps that you number walked through. Remember: you use `-DDEBUG` as an compiler argument.
## Documentation
See [numericx documentation page](https://dacs-git.codeberg.page/numericx/). Look at `Files > File List` in the documentation menubar website.
## License
MIT

1
doc Submodule

@ -0,0 +1 @@
Subproject commit 5d253764e6b4e989ba4e043ef7345439a9979789

1
html Symbolic link
View File

@ -0,0 +1 @@
doc/

View File

@ -1,3 +1,6 @@
/** @file numericx.c
* Source code of the number translator command-line interface.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -9,40 +12,62 @@
/* ||COMPILATION FLAGS|| */
/*
* Show debug message of step by step
* incrementation of the number
/**
* @name Compilation Flags
*
* These are the valid compilation flags for the definition of numerical systems.
* Use them to make the program show more output, or
* to set the proprieties of the FROM and the TO numerical system.
*
* @{
*/
#ifndef DEBUG
#define DEBUG false
#endif
/*
* Configuration of the corresponding numeral system
* to have the units place of the end (on the right)
/**
* @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
/*
* Configuration of the corresponding numeral system
/**
* @param bool
*
* Configuration of the resulting numeral system
* to start counting on the second number, being the
* first number void
* 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
/* Configuration of the corresponding numeral system
/**
* @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 ...
@ -51,56 +76,81 @@
#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;
struct NumeralPtr *next;
struct NumeralPtr *previous;
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|| */
/*
* Creates new digit for numeral_ptr.
/**
* @brief Create new digit for numeral_ptr.
*
* It needs the last_numeral ('last_numeral') into which will
* add the new numeral, and also need to know the symbol of the
* new numeral ('to_first').
*
* Return pointer to new numeral_ptr.
* Returns NULL in case of no memory.
* @param last_numeral - last numeral_ptr* into which new numeral_ptr will be added.
* @param to_first - symbol of the new digit.
*
* @return pointer to new numeral_ptr in case of success.
* @return NULL in case of no memory.
*/
numeral_ptr*
new_digit(numeral_ptr* last_numeral, char const* to_first)
{
numeral_ptr* starting_point = malloc(sizeof(numeral_ptr));
if(starting_point == NULL)
numeral_ptr* new_numeral = malloc(sizeof(numeral_ptr));
if(new_numeral == NULL)
{
fprintf(stderr, "error: %s: %s!", PROG_NAME, strerror(ENOMEM));
return NULL;
}
starting_point->symbol = to_first;
starting_point->previous = last_numeral;
starting_point->next = NULL;
new_numeral->symbol = to_first;
new_numeral->previous = last_numeral;
new_numeral->next = NULL;
return starting_point;
return new_numeral;
}
/*
/**
* @brief Initializer of numeral_ptr
*
* Creates a number of the form numeral_ptr that
* begins with 'case' number of cases, and all cases
* are set to 'to_first' char.
*
* Returns pointer to numeral_ptr.
* Returns NULL in case of no memory (because depends
* @param to_first - the symbol of the cases for the new number.
* @param cases - number of cases of the new number.
*
* @return pointer to numeral_ptr in case of success.
* @return NULL in case of no memory ( because depends
* on new_digit() ).
*/
numeral_ptr*
@ -118,12 +168,19 @@ numeral_infinity(char const* to_first, size_t cases)
return starting_case;
}
/* Increments numeral_ptr 'numeral' one unit up.
/**
* @brief Increment numeral_ptr 'numeral' one unit up.
*
* It needs 'num_first' as the first numeral of the numerical
* system. Also needs 'num_last' as the last numeral of the
* numerical system.
* If incrementing, the function adds a new digit/numeral, it
* will use the 'brand_new_digit' as its numeral/digit.
* When incrementing, if the function adds a new digit/numeral, it
* will use the 'brand_new_digit' as its new numeral/digit.
*
* @param numeral - numeral to increment.
* @param num_first - number's numeral system first numeral.
* @param num_last - number's numeral system last numeral.
* @param brand_new_digit - brand new created numeral, if needed by incrementation.
*/
void
increment(numeral_ptr* numeral, char* num_first, char* num_last, char* brand_new_digit)
@ -146,12 +203,18 @@ increment(numeral_ptr* numeral, char* num_first, char* num_last, char* brand_new
++(numeral->symbol);
}
/*
* Decrements a string 'number' by one unit.
/**
* @brief Decrement a string 'number' by one unit.
*
* It needs to know the first numeral ('first_numeral') and also the
* last numeral ('last_numeral'). It also needs the numeral system in
* form of a string ('numeral_system') to know which is the numeral
* before the actual numeral that needs decrementation.
*
* @param number - the string number to be decremented.
* @param first_numeral - number's numeral system first numeral.
* @param last_numeral - number's numeral system last numeral.
* @param numeral_system - string of the corresponding number's numeral system numeral.
*/
void
decrement_number_string(char* number, char* first_numeral, char* last_numeral, char* numeral_system)
@ -175,10 +238,16 @@ decrement_number_string(char* number, char* first_numeral, char* last_numeral, c
}
}
/*
/**
* @brief Check if numeral_ptr and string are of the same value
*
* Compares if a numeral_ptr ('numeral') matches the string ('number_arg').
*
* Return true if matches, false if numeral_ptr doesn't match the string.
* @param numeral - numeral_ptr to check.
* @param number_arg - string to check.
*
* @return true if matches.
* @return false if doesn't match.
*/
bool
is_the_same(numeral_ptr* numeral, char* number_arg)
@ -198,8 +267,12 @@ is_the_same(numeral_ptr* numeral, char* number_arg)
return (*number_arg == '\0') ? true : false;
}
/*
/**
* @brief Print numeral
*
* Prints to standard output numeral_ptr ('numeral').
*
* @param numeral - numeral_ptr to print.
*/
void
print_numeral(numeral_ptr* numeral)
@ -225,8 +298,10 @@ print_numeral(numeral_ptr* numeral)
}
}
/*
* Reverse a string.
/**
* @brief Reverse a string.
*
* @param string - string to be reversed.
*/
void
reverse_string(char* string)
@ -242,13 +317,19 @@ reverse_string(char* string)
}
}
/*
/**
* @brief Does string belongs to numeral system?
*
* Check if string 'number' belongs to the numerical
* system ('numeral_system'), which is also a string.
* Belonging mean all the symbols of 'number' are included
* in 'numeral_system'.
*
* Return true if it belongs, false otherwise.
* @param numeral_system - numeral system string to check against.
* @param number - number to see if belongs.
*
* @return true if it belongs.
* @return false if it doesn't belong.
*/
bool
is_valid_number(char* numeral_system, char *number)
@ -267,8 +348,12 @@ is_valid_number(char* numeral_system, char *number)
return true;
}
/*
* Free up numeral_ptr ('numeral').
/**
* @brief Free numeral memory.
*
* Free up numeral_ptr ('numeral') linked chain.
*
* @param numeral - numeral_ptr to free.
*/
void
free_numeral(numeral_ptr* numeral)
@ -283,9 +368,186 @@ 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;
}
/**
* @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 to - string with all the numerals of the resulting 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 to_units_on_the_end - does the translate to 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 to_first_number_void - does the translate to 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_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)
{
/* result_string has to be NULL */
if( !(*result_string == NULL) )
return EINVAL;
/* Check if number belongs to it's numerical system */
if( !is_valid_number(from, number) )
return EDOM;
/* _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);
return ERANGE;
}
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) */
*result_string = numeral_to_string(result, to_units_on_the_end);
/* free memory */
free_numeral(counting);
free_numeral(result);
return EXIT_SUCCESS;
}
/* ||MAIN FUNCTION|| */
/**
* @brief CLI program.
*
* This is a command-line interface program, that uses the 'numericx_*'
* functions. It receives on number and returns the translated number.
*
* @param argv[] - one number as a string
*
* @return EXIT_SUCCESS in case of a successful number translation
* @return EXIT_FAILURE in case of unsuccessful number translation
*/
int
main(int argc, char* argv[])
{
@ -296,114 +558,62 @@ 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) )
/* 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 )
{
fprintf(stderr, "error: %s: %s.\nValid numerals are: \"%s\"\n",
PROG_NAME, strerror(EDOM), from);
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);
exit(EDOM);
numericx_free(result);
return EXIT_FAILURE;
}
/* _first and _last variables */
char* from_first = from;
char* from_last = from + (strlen(from) - 1);
/* Print */
printf("%s\n", result);
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(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(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 */
free(from);
free(to);
free_numeral(counting);
free_numeral(result);
numericx_free(result);
return EXIT_SUCCESS;
}