From e2a309f921968691af1566000dd694f191eca857 Mon Sep 17 00:00:00 2001 From: Laurent Mazet Date: Sat, 25 Feb 2023 16:04:42 +0100 Subject: [PATCH] new function: format --- calc.c | 12 +++++++--- element.h | 3 ++- format.c | 70 +++++++++++++++++++++++++++++++++++++++++++------------ format.h | 9 +++---- parser.c | 19 +++++++++++++-- stack.c | 8 +++---- storage.c | 8 +++---- 7 files changed, 96 insertions(+), 33 deletions(-) diff --git a/calc.c b/calc.c index 1432acc..bd816b9 100644 --- a/calc.c +++ b/calc.c @@ -130,7 +130,7 @@ int main (int argc, char *argv[]) VERBOSE (ERROR, fprintf (stderr, "%s: missing output prompt\n", progname); usage (1)); return 1; } - oprompt = arg; + set_prompt (oprompt = arg); break; case 'p': arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; @@ -138,7 +138,7 @@ int main (int argc, char *argv[]) VERBOSE (ERROR, fprintf (stderr, "%s: missing precision\n", progname); usage (1)); return 1; } - precision = atoi (arg); + set_precision (precision = atoi (arg)); break; case 'v': arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; @@ -155,7 +155,7 @@ int main (int argc, char *argv[]) } /* set format */ - set_format (oprompt, precision); + set_format (); /* completion list*/ completion_list = generate_completion_list (); @@ -404,6 +404,12 @@ int main (int argc, char *argv[]) // test: echo -e 'set (1, 2, -5, 6, -8, 9, -2, 23, 4)\nmin (5, -3)\nmax (-1)\nmin\nmean\nmed\nmax\nord\nprod\nsum\nvar\nquit' | calc.exe -n -v 3 | grep -q bye // test: echo -e 'min\nmean\nmed\nmax\nprod\nsum\nvar\nord\nset (1)\nord' | calc.exe -n | grep -c error | xargs test 9 = // test: echo -e 'prog (1, cos(pi * arg (1))) / 4' | calc.exe | grep -c error | xargs test 1 = +// test: echo -e 'format\n.12345678901' | calc.exe | grep -n '=> 6' +// test: echo -e 'format (8)\n.12345678901' | calc.exe | grep -n '=> 0.12345679' +// test: echo -e 'format (12)\n.12345678901' | calc.exe | grep -n '=> 0.12345678901' +// test: echo -e 'format (4)\n.12345678901\format' | calc.exe | grep -n '=> 4' +// test: echo -e 'format (0)' | calc.exe | grep -n 'error' + // Gauss sequence // test: echo -e '{sto (1, 0), sto (10, 0), while (inc (10) <= 100, {sto (1, rcl (1) + rcl (10)), print (rcl (1))})};' | calc.exe | grep -q '=> 5050' diff --git a/element.h b/element.h index 15e6ecc..c2acb4d 100644 --- a/element.h +++ b/element.h @@ -22,7 +22,8 @@ typedef enum { Cond, While, Code, Print, Prog, Arg, Call, List, Edit, Del, Get, Length, Pop, Push, Put, Set, Show, - Max, Mean, Median, Min, Order, Prod, Sum, Variance + Max, Mean, Median, Min, Order, Prod, Sum, Variance, + Precision } func_t; /* keyword type */ diff --git a/format.c b/format.c index 93000a2..1528750 100644 --- a/format.c +++ b/format.c @@ -7,36 +7,76 @@ /* global variables */ #define DEFAULT_FORMAT "=> %.6g\n" -char *format = NULL; -char *minform = NULL; +char *_format = NULL; +#define DEFAULT_MINFORM "%.6g" +char *_minform = NULL; + +int _precision = 6; + +#define DEFAULT_PROMPT "=> " +char *_prompt = NULL; /* print function */ -void set_format (char *prompt, int precision) +void set_precision (int precision) +{ + _precision = precision; +} + +int get_precision () +{ + return _precision; +} + +void set_prompt (char *prompt) +{ + if (_prompt) { + free (_prompt); + } + _prompt = strdup (prompt); +} + +void set_format () { char buffer[128] = {0}; - free_format (); - sprintf (buffer, "%s%%.%dg\n", prompt, precision); - format = strdup (buffer); - sprintf (buffer, "%%.%dg", precision); - minform = strdup (buffer); + sprintf (buffer, "%s%%.%dg\n", _prompt ? _prompt : DEFAULT_PROMPT, _precision); + if (_format) { + free (_format); + } + _format = strdup (buffer); + sprintf (buffer, "%%.%dg", _precision); + if (_minform) { + free (_minform); + } + _minform = strdup (buffer); } void free_format () { - if (format) { - free (format); - format = NULL; + if (_format) { + free (_format); + _format = NULL; + } + if (_minform) { + free (_minform); + _minform = NULL; } - if (minform) { - free (minform); - minform = NULL; + if (_prompt) { + free (_prompt); + _prompt = NULL; } } double print (double value) { - fprintf (stdout, format ? format : DEFAULT_FORMAT, value); + fprintf (stdout, _format ? _format : DEFAULT_FORMAT, value); + fflush (stdout); + return value; +} + +double printl (double value) +{ + fprintf (stdout, _minform ? _minform : DEFAULT_MINFORM, value); fflush (stdout); return value; } diff --git a/format.h b/format.h index 9849205..dbbaec1 100644 --- a/format.h +++ b/format.h @@ -3,16 +3,17 @@ /* global variables */ -extern char *format; -extern char *minform; - /* print function */ -void set_format (char *prompt, int precision); +void set_precision (int precision); +int get_precision (); +void set_prompt (char *prompt); +void set_format (); void free_format (); double print (double value); +double printl (double value); #endif /* __FORMAT_H__ */ diff --git a/parser.c b/parser.c index bf1a7dc..b9823ab 100644 --- a/parser.c +++ b/parser.c @@ -62,7 +62,7 @@ keyword_t operators[NB_OPERATORS] = { { "|", Or, 2, 1, -2} }; -#define NB_FUNCTIONS 50 +#define NB_FUNCTIONS 51 keyword_t functions[NB_FUNCTIONS] = { { "sqrt", Sqr, 1, 4, 5}, { "pow", Pow, 2, 3, 5}, @@ -114,6 +114,7 @@ keyword_t functions[NB_FUNCTIONS] = { { "prod", Prod, 0, 4, 5}, { "sum", Sum, 0, 3, 5}, { "var", Variance, 2, 3, 5}, + { "format", Precision, 1, 6, 9} }; #define NB_CONSTANTS 3 @@ -522,6 +523,7 @@ void print_element (element_t *root, int level) case Prod: func = "Product"; break; case Sum: func = "Sum"; break; case Variance: func = "Variance"; break; + case Precision: func = "Precision"; break; } fprintf (stdout, "Function: %s\n", func); @@ -617,7 +619,7 @@ void help (void) fprintf (stdout, "stack func.:"); fprintf (stdout, " max mean med min ord prod sum var\n"); fprintf (stdout, "control management:"); - fprintf (stdout, " help quit\n"); + fprintf (stdout, " format help quit\n"); fprintf (stdout, "constants:"); fprintf (stdout, " ans e pi\n"); } @@ -774,6 +776,10 @@ double evaluate_element (element_t *root, char mask) op0 = evaluate_element (root->ops[0], 0); op1 = (root->ops[1]) ? evaluate_element (root->ops[1], 0) : answer; } + break; + case Precision: + op0 = (root->ops[0]) ? evaluate_element (root->ops[0], 0) : -1; + break; } switch (root->func) { @@ -887,6 +893,15 @@ double evaluate_element (element_t *root, char mask) return op0 * op0 + op1 * op1; } return variance (); + case Precision: + if (op0 > 0) { + set_precision ((int)op0); + set_format (); + } else if (op0 != -1) { + VERBOSE (WARNING, fprintf (stdout, "error incorrect precision (%g)\n", op0)); + return 0; + } + return get_precision(); } return 0; diff --git a/stack.c b/stack.c index 081023f..f4117f5 100644 --- a/stack.c +++ b/stack.c @@ -62,12 +62,12 @@ double set (int nbops, element_t **ops) void show (void) { int i, n = size_tab (stack); - fprintf (stdout, "stack:"); + printf ("stack:"); for (i = 0; i < n; i++) { - fprintf (stdout, " "); - fprintf (stdout, minform, get_tab (stack, i + 1)); + printf (" "); + printl (get_tab (stack, i + 1)); } - fprintf (stdout, "\n"); + printf ("\n"); } /* stack functions */ diff --git a/storage.c b/storage.c index 54815e2..15a6470 100644 --- a/storage.c +++ b/storage.c @@ -73,12 +73,12 @@ void display (void) memory (DEFAULT_STORAGE_SIZE); } int i, n = size_tab (storage); - fprintf (stdout, "storage:"); + printf ("storage:"); for (i = 0; i < n; i++) { - fprintf (stdout, " "); - fprintf (stdout, minform, get_tab (storage, i + 1)); + printf (" "); + printl (get_tab (storage, i + 1)); } - fprintf (stdout, "\n"); + printf ("\n"); } void clear () -- 2.30.2