diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | Src/math.c | 57 | ||||
-rw-r--r-- | Src/zsh.h | 1 | ||||
-rw-r--r-- | Test/C01arith.ztst | 10 |
4 files changed, 59 insertions, 15 deletions
diff --git a/ChangeLog b/ChangeLog index 1ba9d0a6d..1d4504887 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2001-07-06 Peter Stephenson <pws@csr.com> + + * 15291, 15292: Src/math.c, Src/zsh.h, Test/C01arith.yo: + fix bug that assignment to scalar in math mode failed if + scalar had non-math value in it. + 2001-07-06 Clint Adams <clint@zsh.org> * 15250: zsh/pcre module will load gracefully even diff --git a/Src/math.c b/Src/math.c index 0ea16e7ba..5e4b67c9b 100644 --- a/Src/math.c +++ b/Src/math.c @@ -476,7 +476,7 @@ static struct mathvalue *stack; /**/ static void -push(mnumber val, char *lval) +push(mnumber val, char *lval, int getme) { if (sp == STACKSZ - 1) zerr("stack overflow", NULL, 0); @@ -484,8 +484,21 @@ push(mnumber val, char *lval) sp++; stack[sp].val = val; stack[sp].lval = lval; + if (getme) + stack[sp].val.type = MN_UNSET; } +/**/ +static mnumber +pop(int noget) +{ + struct mathvalue *mv = stack+sp; + + if (mv->val.type == MN_UNSET && !noget) + mv->val = getnparam(mv->lval); + sp--; + return mv->val; +} /**/ static mnumber @@ -615,8 +628,8 @@ op(int what) if (tp & (OP_A2|OP_A2IR|OP_A2IO|OP_E2|OP_E2IO)) { /* Make sure anyone seeing this message reports it. */ DPUTS(sp < 1, "BUG: math: not enough wallabies in outback."); - b = stack[sp--].val; - a = stack[sp--].val; + b = pop(0); + a = pop(what == EQ); if (tp & (OP_A2IO|OP_E2IO)) { /* coerce to integers */ @@ -785,13 +798,15 @@ op(int what) } if (tp & (OP_E2|OP_E2IO)) { lv = stack[sp+1].lval; - push(setvar(lv,c), lv); + push(setvar(lv,c), lv, 0); } else - push(c,NULL); + push(c,NULL, 0); return; } spval = &stack[sp].val; + if (stack[sp].val.type == MN_UNSET) + *spval = getnparam(stack[sp].lval); switch (what) { case NOT: if (spval->type & MN_FLOAT) { @@ -837,11 +852,11 @@ op(int what) break; case QUEST: DPUTS(sp < 2, "BUG: math: three shall be the number of the counting."); - c = stack[sp--].val; - b = stack[sp--].val; - a = stack[sp--].val; + c = pop(0); + b = pop(0); + a = pop(0); /* b and c can stay different types in this case. */ - push(((a.type & MN_FLOAT) ? a.u.d : a.u.l) ? b : c, NULL); + push(((a.type & MN_FLOAT) ? a.u.d : a.u.l) ? b : c, NULL, 0); break; case COLON: zerr("':' without '?'", NULL, 0); @@ -872,7 +887,11 @@ static void bop(int tk) { mnumber *spval = &stack[sp].val; - int tst = (spval->type & MN_FLOAT) ? (zlong)spval->u.d : spval->u.l; + int tst; + + if (stack[sp].val.type == MN_UNSET) + *spval = getnparam(stack[sp].lval); + tst = (spval->type & MN_FLOAT) ? (zlong)spval->u.d : spval->u.l; switch (tk) { case DAND: @@ -938,7 +957,15 @@ mathevall(char *s, int prek, char **ep) DPUTS(!errflag && sp, "BUG: math: wallabies roaming too freely in outback"); - ret = stack[0].val; + if (errflag) { + ret.type = MN_INTEGER; + ret.u.l = errflag; + } else { + if (stack[0].val.type == MN_UNSET) + ret = getnparam(stack[0].lval); + else + ret = stack[0].val; + } if (--mlevel) { lastbase = xlastbase; @@ -1056,16 +1083,16 @@ mathparse(int pc) return; switch (mtok) { case NUM: - push(yyval, NULL); + push(yyval, NULL, 0); break; case ID: - push((noeval ? zero_mnumber : getnparam(yylval)), yylval); + push(zero_mnumber, yylval, !noeval); break; case CID: - push((noeval ? zero_mnumber : getcvar(yylval)), yylval); + push((noeval ? zero_mnumber : getcvar(yylval)), yylval, 0); break; case FUNC: - push((noeval ? zero_mnumber : callmathfunc(yylval)), yylval); + push((noeval ? zero_mnumber : callmathfunc(yylval)), yylval, 0); break; case M_INPAR: mathparse(TOPPREC); diff --git a/Src/zsh.h b/Src/zsh.h index 5014099ce..74d0753bb 100644 --- a/Src/zsh.h +++ b/Src/zsh.h @@ -75,6 +75,7 @@ typedef struct { #define MN_INTEGER 1 /* mnumber is integer */ #define MN_FLOAT 2 /* mnumber is floating point */ +#define MN_UNSET 4 /* mnumber not yet retrieved */ typedef struct mathfunc *MathFunc; typedef mnumber (*NumMathFunc)(char *, int, mnumber *, int); diff --git a/Test/C01arith.ztst b/Test/C01arith.ztst index c72bd5acb..c32d00209 100644 --- a/Test/C01arith.ztst +++ b/Test/C01arith.ztst @@ -88,3 +88,13 @@ print ${(t)newarray} ${#newarray} ${newarray[1]} 0:setting array elements in math context >array 1 2 + + print $(( 13 = 42 )) +1:bad lvalue +?ZTST_execchunk:2: lvalue required + + x=/bar + (( x = 32 )) + print $x +0:assigning to scalar which contains non-math string +>32 |