From 2a5ec9d1e2e19f934a02d0b697b01ae12ebc313f Mon Sep 17 00:00:00 2001 From: Laurent Mazet Date: Fri, 27 Jan 2023 10:51:42 +0100 Subject: [PATCH] enhance prompt and format management --- calc.c | 35 ++++++++++++++++++++++++++++++----- parser.c | 29 +++++++++++++++++++++++++++-- parser.h | 10 ++++++++-- 3 files changed, 65 insertions(+), 9 deletions(-) diff --git a/calc.c b/calc.c index 75189f5..873e310 100644 --- a/calc.c +++ b/calc.c @@ -28,7 +28,9 @@ /* gobal variables */ char *progname = NULL; +char *iprompt = "<= "; int mode = 1; +char *oprompt = "=> "; int precision = 6; char **completion_list = NULL; @@ -39,7 +41,9 @@ int usage (int ret) FILE *fid = ret ? stderr : stdout; fprintf (fid, "usage: %s\n", progname); fprintf (fid, " -h : help message\n"); + fprintf (fid, " -i : input prompt (%s)\n", iprompt); fprintf (fid, " -n : no readline mode (%s)\n", mode ? "yes" : "no"); + fprintf (fid, " -o : output prompt (%s)\n", oprompt); fprintf (fid, " -p : precision (%d)\n", precision); fprintf (fid, " -v : verbose level (%d)\n", verbose); @@ -110,6 +114,22 @@ int main (int argc, char *argv[]) mode = 0; buffer = buffer_static; break; + case 'i': + arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + if (arg == NULL) { + VERBOSE (ERROR, fprintf (stderr, "%s: missing input prompt\n", progname); usage (1)); + return 1; + } + iprompt = arg; + break; + case 'o': + arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + if (arg == NULL) { + VERBOSE (ERROR, fprintf (stderr, "%s: missing output prompt\n", progname); usage (1)); + return 1; + } + oprompt = arg; + break; case 'p': arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; if (arg == NULL) { @@ -132,8 +152,8 @@ int main (int argc, char *argv[]) } } - /* format */ - format[5] = '0' + precision; + /* set format */ + set_format (oprompt, precision); /* completion list*/ completion_list = generate_completion_list (); @@ -145,7 +165,7 @@ int main (int argc, char *argv[]) char *line[BUFFER_SIZE] = {0}; if (mode) { - if ((buffer = readline ("<= ")) == NULL) { + if ((buffer = readline (iprompt)) == NULL) { break; } @@ -197,8 +217,7 @@ int main (int argc, char *argv[]) } else if (element != NULL) { VERBOSE (INFO, print_element (element, 0)); answer = evaluate_element (element, 0); - fprintf (stdout, format, answer); - fflush (stdout); + print (answer); delelement (element); ret = 0; } @@ -213,6 +232,8 @@ int main (int argc, char *argv[]) free_completion_list (completion_list); + free_format (); + return ret; } @@ -222,8 +243,12 @@ int main (int argc, char *argv[]) // test: calc.exe -_ 2> /dev/null | awk 'END { if (NR == 0) { exit(0) } else exit (1) }' // test: calc.exe -_ 2>&1 | awk '/usage:/ { rc=1 } END { exit (1-rc) }' // test: calc.exe error 2>&1 | grep -q 'invalid option' +// test: calc.exe -i 2>&1 | grep -q 'missing input prompt' +// test: calc.exe -o 2>&1 | grep -q 'missing output prompt' // test: calc.exe -p 2>&1 | grep -q 'missing precision' // test: calc.exe -v 2>&1 | grep -q 'missing verbose' +// test: echo "1 + 1" | calc.exe -i '# ' | grep -q '# 1 + 1' +// test: echo "1 + 1" | calc.exe -o '# ' | grep -q '# 2' // test: echo "1 + 2" | calc.exe | grep -q '=> 3' // test: echo "1 - 2" | calc.exe | grep -q '=> -1' // test: echo "2 * 3" | calc.exe | grep -q '=> 6' diff --git a/parser.c b/parser.c index c70a15c..4da6b6b 100644 --- a/parser.c +++ b/parser.c @@ -15,7 +15,7 @@ double answer = 0; #define STORAGE_SIZE 10 double storage[STORAGE_SIZE] = {0}; -char format[9] = "=> %..g\n"; +char *format = NULL; /* compare codes */ @@ -617,6 +617,31 @@ double program_do (element_t **prog, int nbcalls) return ret; } +/* print function */ + +void set_format (char *prompt, int precision) +{ + char buffer[128] = {0}; + sprintf (buffer, "%s%%.%dg\n", prompt, precision); + free_format (); + format = strdup (buffer); +} + +void free_format () +{ + if (format) { + free (format); + format = NULL; + } +} + +double print (double value) +{ + fprintf (stdout, format ? format : "=> %.6g\n", value); + fflush (stdout); + return value; +} + /* quit function */ void quit (void) @@ -807,7 +832,7 @@ double evaluate_element (element_t *root, char mask) } case While: return while_do (root->ops[0], root->ops[1]); case Prog: return program_do (root->ops, root->nbops); - case Print: printf (format, op0); return op0; + case Print: return print (op0); } return 0; diff --git a/parser.h b/parser.h index 9e4c3f6..522adba 100644 --- a/parser.h +++ b/parser.h @@ -5,8 +5,6 @@ extern double answer; -extern char format[9]; - /* function type */ typedef enum { @@ -63,6 +61,14 @@ char **generate_completion_list (); void free_completion_list (char **list); +/* print function */ + +void set_format (char *prompt, int precision); + +void free_format (); + +double print (double value); + #endif /* __PARSER_H__ */ /* vim: set ts=4 sw=4 et: */ -- 2.30.2