From 099e717c1587951458f9b3bd514c655001125f66 Mon Sep 17 00:00:00 2001 From: Peter Stephenson Date: Tue, 2 Jun 2015 10:21:55 +0100 Subject: 35359: Improved math parsing and errors. Check for bogus trailing ")" at end of top-level parse. Extend some math error messages to indicate they are math errors. --- ChangeLog | 5 +++++ Src/math.c | 21 ++++++++++++++------- Test/C01arith.ztst | 22 ++++++++++++++++++---- 3 files changed, 37 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3aac52281..89c6e85f4 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2015-06-02 Peter Stephenson + * 35359 (plus changed error strings in tests): Src/math.c, + Test/C01arith.ztst: fix math parsing problem that trailing ")" + wasn't detected; also improve error messages to indicate they + refer to math expressions. + * Baptiste Daroussin: 35357: Src/Modules/zpty.c: HAVE_POSIX_OPENPT is needed for FreeBSD zpty. diff --git a/Src/math.c b/Src/math.c index 97a97b32b..977e92345 100644 --- a/Src/math.c +++ b/Src/math.c @@ -407,6 +407,13 @@ mathevall(char *s, enum prec_type prec_tp, char **ep) stack[0].val.type = MN_INTEGER; stack[0].val.u.l = 0; mathparse(prec_tp == MPREC_TOP ? TOPPREC : ARGPREC); + /* + * Internally, we parse the contents of parentheses at top + * precedence... so we can return a parenthesis here if + * there are too many at the end. + */ + if (mtok == M_OUTPAR && !errflag) + zerr("bad math expression: unexpected ')'"); *ep = ptr; DPUTS(!errflag && sp > 0, "BUG: math: wallabies roaming too freely in outback"); @@ -791,7 +798,7 @@ zzlex(void) ptr++; if (!*ptr) { - zerr("character missing after ##"); + zerr("bad math expression: character missing after ##"); return EOI; } ptr = getkeystring(ptr, NULL, GETKEYS_MATH, &v); @@ -914,7 +921,7 @@ setmathvar(struct mathvalue *mvp, mnumber v) mvp->pval = NULL; } if (!mvp->lval) { - zerr("lvalue required"); + zerr("bad math expression: lvalue required"); v.type = MN_INTEGER; v.u.l = 0; return v; @@ -1256,7 +1263,7 @@ op(int what) /* Error if (-num ** b) and b is not an integer */ double tst = (double)(zlong)b.u.d; if (tst != b.u.d) { - zerr("imaginary power"); + zerr("bad math expression: imaginary power"); return; } } @@ -1338,7 +1345,7 @@ op(int what) push(((a.type & MN_FLOAT) ? a.u.d : a.u.l) ? b : c, NULL, 0); break; case COLON: - zerr("':' without '?'"); + zerr("bad math expression: ':' without '?'"); break; case PREPLUS: if (spval->type & MN_FLOAT) @@ -1355,7 +1362,7 @@ op(int what) setmathvar(stack + sp, *spval); break; default: - zerr("out of integers"); + zerr("bad math expression: out of integers"); return; } } @@ -1525,7 +1532,7 @@ mathparse(int pc) mathparse(TOPPREC); if (mtok != M_OUTPAR) { if (!errflag) - zerr("')' expected"); + zerr("bad math expression: ')' expected"); return; } break; @@ -1543,7 +1550,7 @@ mathparse(int pc) noeval--; if (mtok != COLON) { if (!errflag) - zerr("':' expected"); + zerr("bad math expression: ':' expected"); return; } if (q) diff --git a/Test/C01arith.ztst b/Test/C01arith.ztst index d284e0869..c7bd81fc3 100644 --- a/Test/C01arith.ztst +++ b/Test/C01arith.ztst @@ -69,11 +69,11 @@ print $(( 3 ? 2 )) 1:parsing ternary (1) -?(eval):1: ':' expected +?(eval):1: bad math expression: ':' expected print $(( 3 ? 2 : 1 : 4 )) 1:parsing ternary (2) -?(eval):1: ':' without '?' +?(eval):1: bad math expression: ':' without '?' print $(( 0, 4 ? 3 : 1, 5 )) 0:comma operator @@ -86,7 +86,7 @@ print $((##)) 1:## without following character -?(eval):1: character missing after ## +?(eval):1: bad math expression: character missing after ## print $((## )) 0:## followed by a space @@ -126,7 +126,7 @@ print $(( 13 = 42 )) 1:bad lvalue -?(eval):1: lvalue required +?(eval):1: bad math expression: lvalue required x=/bar (( x = 32 )) @@ -395,3 +395,17 @@ >6 >7 >120 + + foo="(1)" + print $((foo)) + print $(($foo)) + print $(((2))) + foo="3)" + (print $((foo))) 2>&1 + (print $(($foo))) 2>&1 +1: Good and bad trailing parentheses +>1 +>1 +>2 +>(eval):6: bad math expression: unexpected ')' +>(eval):7: bad math expression: unexpected ')' -- cgit 1.4.1