29 #define NUMERUS_PROMPT_AGAIN 1 36 #define NUMERUS_STOP_REPL 0 38 static const char *PROMPT_TEXT =
"numerus> ";
39 static const char *WELCOME_TEXT =
"" 40 "+-----------------+\n" 42 "+-----------------+\n";
43 static const char *INFO_TEXT =
"" 44 "Numerus, C library for conversion and manipulation of roman numerals.\n" 45 "Version 2.0.0, Command Line Interface\n" 46 "Copyright (c) 2015-2016 Matjaž Guštin <dev@matjaz.it> http://matjaz.it\n" 47 "This software is subject to the terms of the BSD 3-Clause license.\n" 48 "Project page and source code: https://github.com/TheMatjaz/Numerus\n";
49 static const char *MOO_TEXT =
"This is not an easter egg. Try `ascii`.\n";
50 static const char *PING_TEXT =
"Pong.\n";
51 static const char *AVE_TEXT =
"Ave tibi!\n";
52 static const char *HELP_TEXT =
"" 53 "For ANY information about the library or the syntax of roman numeral, \n" 54 "check the documentation available on https://thematjaz.github.io/Numerus/\n\n" 56 "To convert an (arabic) integer to a roman numeral or vice-versa,\n" 57 "just type it in the shell and press enter.\n" 58 "Other Numerus commands are:\n\n" 60 "pretty switches on/off the pretty printing of long roman numerals\n" 61 " (with overlined notation instead of underscore notation)\n" 62 " and the pretty printing of values as integer and fractional part\n" 63 "?, help shows this help text\n" 64 "info, about shows version, credits, licence, repository of Numerus\n" 65 "exit, quit ends this shell\n\n" 67 "We also have: moo, ping, ave.\n";
68 static const char *QUIT_TEXT =
"Vale!\n";
69 static const char *ASCII_TEXT =
"" 70 " ____ _____ ____ ____ ____ ____ _________ _______ ____ ____ _______ \n" 71 "|_ \\|_ _| |_ _| |_ _| |_ \\ / _| |_ ___ | |_ __ \\ |_ _| |_ _| / ___ |\n" 72 " | \\ | | \\ \\ / / | \\/ | | |_ \\_| | |__) | \\ \\ / / | (__ \\_|\n" 73 " | |\\ \\| | \\ \\ / / | |\\ /| | | _| _ | __ / \\ \\ / / '.___`-. \n" 74 " _| |_\\ |_ \\ ' / _| |_\\/_| |_ _| |___/ | _| | \\ \\_ \\ ' / |`\\____) |\n" 75 "|_____|\\____| \\_/ |_____||_____| |_________| |____| |___| \\_/ |_______.'\n";
76 static const char *UNKNOWN_COMMAND_TEXT =
"Unknown command or wrong roman numeral syntax:\n";
77 static const char *PRETTY_ON_TEXT =
"Pretty printing is enabled.\n";
78 static const char *PRETTY_OFF_TEXT =
"Pretty printing is disabled.\n";
79 static int pretty_printing = 0;
95 static char *_num_get_first_word_trimmed_lowercased(
char *
string) {
96 while(isspace(*
string)) {
103 char *first_word_start = string;
104 while (*
string !=
'\0' && !isspace(*
string)) {
105 *
string = (char) tolower(*
string);
109 return first_word_start;
121 static short _num_string_is_double_zero(
char *zero_as_string) {
122 if (*zero_as_string ==
'-') {
125 while (*zero_as_string ==
'0') {
128 if (*zero_as_string ==
'.' || *zero_as_string ==
',') {
130 if (*zero_as_string ==
'0') {
131 while (*zero_as_string ==
'0') {
138 if (*zero_as_string ==
'\0') {
157 void _num_convert_to_other_form_and_print(
char *
string) {
163 if (_num_string_is_double_zero(
string)) {
168 value = strtod(
string, NULL);
180 if (pretty_printing == 1) {
187 printf(
"%s\n", roman_pretty);
192 printf(
"%s\n", roman);
201 if (pretty_printing == 1) {
204 if (pretty_value == NULL) {
208 printf(
"%s\n", pretty_value);
213 printf(
"%f\n", value);
227 static int _num_parse_command(
char *command) {
228 if (strcmp(command,
"?") == 0 || strcmp(command,
"help") == 0) {
229 printf(
"%s", HELP_TEXT);
230 return NUMERUS_PROMPT_AGAIN;
231 }
else if (strcmp(command,
"moo") == 0) {
232 printf(
"%s", MOO_TEXT);
233 return NUMERUS_PROMPT_AGAIN;
234 }
else if (strcmp(command,
"ascii") == 0) {
235 printf(
"%s", ASCII_TEXT);
236 return NUMERUS_PROMPT_AGAIN;
237 }
else if (strcmp(command,
"info") == 0 || strcmp(command,
"about") == 0) {
238 printf(
"%s", INFO_TEXT);
239 return NUMERUS_PROMPT_AGAIN;
240 }
else if (strcmp(command,
"ave") == 0) {
241 printf(
"%s", AVE_TEXT);
242 return NUMERUS_PROMPT_AGAIN;
243 }
else if (strcmp(command,
"pretty") == 0) {
245 if (pretty_printing == 1) {
247 printf(
"%s", PRETTY_OFF_TEXT);
248 return NUMERUS_PROMPT_AGAIN;
251 printf(
"%s", PRETTY_ON_TEXT);
252 return NUMERUS_PROMPT_AGAIN;
254 }
else if (strcmp(command,
"ping") == 0) {
255 printf(
"%s", PING_TEXT);
256 return NUMERUS_PROMPT_AGAIN;
257 }
else if (strcmp(command,
"exit") == 0 || strcmp(command,
"quit") == 0) {
258 printf(
"%s", QUIT_TEXT);
259 return NUMERUS_STOP_REPL;
260 }
else if (*command ==
'\0') {
262 return NUMERUS_PROMPT_AGAIN;
264 _num_convert_to_other_form_and_print(command);
265 return NUMERUS_PROMPT_AGAIN;
289 size_t line_buffer_size = 50;
290 char *line = malloc(line_buffer_size);
300 command = _num_get_first_word_trimmed_lowercased(*args);
301 _num_parse_command(command);
308 printf(
"%s", WELCOME_TEXT);
309 int command_result = NUMERUS_PROMPT_AGAIN;
310 while (command_result == NUMERUS_PROMPT_AGAIN) {
311 printf(
"%s", PROMPT_TEXT);
312 if (getline(&line, &line_buffer_size, stdin) == -1) {
315 command = _num_get_first_word_trimmed_lowercased(line);
316 command_result = _num_parse_command(command);
Numerus roman numerals library header.
char * numerus_overline_long_numerals(char *roman, int *errcode)
Allocates a string with a prettier representation of a long roman numeral with actual overlining...
const char * numerus_explain_error(int error_code)
Returns a pointer to the human-friendly text description of any NUMERUS_ERROR_* error code...
#define NUMERUS_OK
Everything went all right.
int numerus_error_code
The global error code variable to store any errors during conversions.
#define NUMERUS_ERROR_MALLOC_FAIL
Heap memory allocation failure.
int numerus_cli(int argc, char **args)
Starts a command line interface that converts any typed value to a roman numeral or vice-versa...
char * numerus_double_to_roman(double double_value, int *errcode)
Converts a double value to a roman numeral with its value.
char * numerus_create_pretty_value_as_double(double double_value)
Allocates a string with a prettier representation of a double value of a roman numeral as integer par...
double numerus_roman_to_double(char *roman, int *errcode)
Converts a roman numeral to its value expressed as a double.