mirror of
git://git.code.sf.net/p/zsh/code
synced 2025-09-29 19:00:57 +02:00
15291, 15292: fix bug setting scalar in math mode
This commit is contained in:
parent
3dc88e102e
commit
2c75f5b0da
4 changed files with 59 additions and 15 deletions
|
@ -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
|
||||
|
|
57
Src/math.c
57
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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue