about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--numericx.c175
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;
 }