about summary refs log tree commit diff stats
path: root/cli.c
blob: 1d012391f6bafcc24b885e7dec8e4dd27e2d459e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/** @file cli.c
 * Numericx command-line interface (CLI) program.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <errno.h>
#include "numericx.h"


/* ||COMPILATION FLAGS|| */

/**
 * @name Compilation Flags
 *
 * These are the valid compilation flags for the definition of numerical systems.
 * Use them to set the proprieties of the FROM and the TO numerical system, when
 * compiling the cli executable.
 *
 * @{
 */

/**
 * @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

/**
 * @param bool
 *
 * Configuration of the resulting numeral system
 * to start counting on the second number, being the
 * 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

/**
 * @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 ...
 */
#ifndef TO_INFINITE_BASE
#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

/** @} */


/* ||MAIN FUNCTION|| */

/**
 * @brief CLI program.
 *
 * This is a command-line interface program, that uses the 'numericx_*'
 * functions. It receives one number argument from the command-line and
 * prints the translated number, or an error message.
 *
 * @param argv[] - one number from the command-line.
 *
 * @return E2BIG in case of wrong number of arguments.
 * @return EXIT_FAILURE in case of unsuccessful number translation.
 * @return EXIT_SUCCESS in case of a successful number translation.
 */
int
main(int argc, char* argv[])
{
	/* argument processing */
	if( !(argc == 2) )
	{
		fprintf(stderr, "usage: %s <number>\n", argv[0]);
		return E2BIG;
	}

	/* 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;

	/* 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 )
	{
		case EINVAL:
			fprintf(stderr, "error: %s: %s. Resulting string argument value has to be NULL.\n",
					"numericx", strerror(EINVAL));
			break;
		case EDOM:
			fprintf(stderr, "error: %s: %s. Valid numerals are: \"%s\".\n",
					"numericx", strerror(EDOM), from);
			break;
		case ERANGE:
				fprintf(stderr, "error: %s: Unrepresentable void number.\n", "numericx");
			break;
	}
	if( !(status == true) )
	{
		fprintf(stderr, "error: %s: Incapable of translating.\n", "numericx");
		free(from);
		free(to);
		numericx_free(result);

		return EXIT_FAILURE;
	}

	/* Print */
	printf("%s\n", result);

	/* Free */
	free(from);
	free(to);
	numericx_free(result);

	return EXIT_SUCCESS;
}