enhance prompt and format management
authorLaurent Mazet <laurent.mazet@thalesgroup.com>
Fri, 27 Jan 2023 09:51:42 +0000 (10:51 +0100)
committerLaurent Mazet <laurent.mazet@thalesgroup.com>
Fri, 27 Jan 2023 14:24:31 +0000 (15:24 +0100)
calc.c
parser.c
parser.h

diff --git a/calc.c b/calc.c
index 75189f5ec32404e5eb9ac705fc2f9cd30d6cc881..873e3103d87dc60de6fcd39074716da3069ef512 100644 (file)
--- 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'
index c70a15cfde5b65282851d52587cd3920971c317f..4da6b6b64b31497d702bffba03a42135cc206e95 100644 (file)
--- 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;
index 9e4c3f608f18196905f8eca679c70fae004ce369..522adba9dec018d88493f1e6e977cadce30e835c 100644 (file)
--- 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: */