about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Stephenson <pws@zsh.org>2015-06-02 10:21:55 +0100
committerPeter Stephenson <pws@zsh.org>2015-06-02 10:21:55 +0100
commit099e717c1587951458f9b3bd514c655001125f66 (patch)
tree2260b04957de51bdf4033d9ecd7dad95acbeee13
parentaab6bdc3661e83216d2e4bc58948ed21d394d3f5 (diff)
downloadzsh-099e717c1587951458f9b3bd514c655001125f66.tar.gz
zsh-099e717c1587951458f9b3bd514c655001125f66.tar.xz
zsh-099e717c1587951458f9b3bd514c655001125f66.zip
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.
-rw-r--r--ChangeLog5
-rw-r--r--Src/math.c21
-rw-r--r--Test/C01arith.ztst22
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  <p.stephenson@samsung.com>
 
+	* 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 ')'