[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Arithmetic assignment to array element broken
From: |
Joe Burpee |
Subject: |
Arithmetic assignment to array element broken |
Date: |
Tue, 25 Dec 2001 10:07:40 -0500 |
Configuration Information [Automatically generated, do not change]:
Machine: i586
OS: linux-gnu
Compiler: gcc
Compilation CFLAGS: -DPROGRAM='bash' -DCONF_HOSTTYPE='i586'
-DCONF_OSTYPE='linux-gnu' -DCONF_MACHTYPE='i586-pc-linux-gnu'
-DCONF_VENDOR='pc' -DSHELL -DHAVE_CONFIG_H -I. -I. -I./include -I./lib -g -O2
uname output: Linux jeep1.burkby.com 2.4.9-6 #1 Thu Oct 18 09:47:34 EDT 2001
i586 unknown
Machine Type: i586-pc-linux-gnu
Bash Version: 2.05a
Patch Level: 0
Release Status: release
Description:
Arithmetic assignment $((X=Y)) uses bind_int_variable. This seems to be
wrong since the rhs has no need for re-evaluation. Also the lhs does
not permit array element lvalues $((X[I]=Y)), etc. (Hence it also
creates extra vars with names like "X[I]".)
This breaks other things. E.g.
for ((X[I]=1; X[I]<9; X[I]++))
is doubly broken.
I attempted a patch (below) using the routine for substitute ${X=Y}
which seems to be the general form borrowed by simple X=Y.
Works for me, but I've no doubt missed something. Anyway, apologies for
kludginess; this stuff is new to me.
Repeat-By:
$ Arr=(0 1 2)
$ set|grep ^Arr
Arr=([0]="0" [1]="1" [2]="2")
$ echo $((++Arr[2]))
3
$ set|grep ^Arr
Arr=([0]="0" [1]="1" [2]="2")
Arr[2]=3
Fix:
--- bash-2.05a/expr.c.orig Mon Oct 15 14:19:21 2001
+++ bash-2.05a/expr.c Tue Dec 25 08:47:37 2001
@@ -383,7 +383,7 @@
expassign ()
{
register long value;
- char *lhs, *rhs;
+ char *lhs;
value = expcond ();
if (curtok == EQ || curtok == OP_ASSIGN)
@@ -448,10 +448,8 @@
value = lvalue;
}
- rhs = itos (value);
if (noeval == 0)
- (void)bind_int_variable (lhs, rhs);
- free (rhs);
+ do_assignment_value (lhs, value);
free (lhs);
FREE (tokstr);
tokstr = (char *)NULL; /* For freeing on errors. */
@@ -784,7 +782,6 @@
exp0 ()
{
register long val = 0, v2;
- char *vincdec;
int stok;
/* XXX - might need additional logic here to decide whether or not
@@ -798,10 +795,8 @@
evalerror ("identifier expected after pre-increment or
pre-decrement");
v2 = tokval + ((stok == PREINC) ? 1 : -1);
- vincdec = itos (v2);
if (noeval == 0)
- (void)bind_int_variable (tokstr, vincdec);
- free (vincdec);
+ do_assignment_value (tokstr, v2);
val = v2;
curtok = NUM; /* make sure --x=7 is flagged as an error */
@@ -836,10 +831,8 @@
{
/* post-increment or post-decrement */
v2 = val + ((*tp == '+') ? 1 : -1);
- vincdec = itos (v2);
if (noeval == 0)
- (void)bind_int_variable (tokstr, vincdec);
- free (vincdec);
+ do_assignment_value (tokstr, v2);
tp += 2;
curtok = NUM; /* make sure x++=7 is flagged as an error */
}
@@ -1113,6 +1106,26 @@
}
return (val);
}
+
+/* Use ${X=Y} substitution assignment code for $((X=Y)), etc. */
+int
+do_assignment_value (lhs, value)
+ char *lhs;
+ register long value;
+{
+ char *str, *rhs; /* revert to string "lhs=rhs" */
+ int i;
+
+ rhs = itos (value);
+ i = strlen (lhs);
+ str = (char *)xmalloc (i + 1 + strlen(rhs) + 1);
+ strcpy (str, lhs);
+ str[i++] = '=';
+ strcpy (str + i, rhs);
+ free (rhs);
+ do_assignment_no_expand (str); /* includes subscripted lhs */
+ free (str);
+ }
#if defined (EXPR_TEST)
void *
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- Arithmetic assignment to array element broken,
Joe Burpee <=