Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: Arith expansion accepts extra closing parenthesis



Some of the errors from arithmetic evaluation are a bit cryptic in that
it's not obvious the failure reported is actually to do with arithmetic
at all: "unexpected ')'" could refer to lots of uses of ')'.  This
improves the previous patch so that more messages indicate where the
error has come from.  I've left alone those that don't seem as cryptic.

I'm glad I've never been "out of integers".  That sounds bad.

pws

diff --git a/Src/math.c b/Src/math.c
index 97a97b3..977e923 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 d284e08..2d35ea6 100644
--- a/Test/C01arith.ztst
+++ b/Test/C01arith.ztst
@@ -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: unexpected ')'
+>(eval):7: unexpected ')'



Messages sorted by: Reverse Date, Date, Thread, Author