From: Chet Ramey Date: Tue, 5 Jun 2012 14:16:44 +0000 (-0400) Subject: commit bash-20120511 snapshot X-Git-Tag: bash-4.3-alpha~66 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=861a1900bab613a0c22ba8108392029a15965d1e;p=thirdparty%2Fbash.git commit bash-20120511 snapshot --- diff --git a/CWRU/CWRU.chlog b/CWRU/CWRU.chlog index 6168935f3..74022607a 100644 --- a/CWRU/CWRU.chlog +++ b/CWRU/CWRU.chlog @@ -13803,3 +13803,23 @@ subst.c only set W_HASQUOTEDNULL in the returned word flags if the word is a quoted null string AND had_quoted_null is set. Rest of fix + 5/9 + --- +variables.c + - bind_variable_internal: if we get an array variable here (implicit + assignment to index 0), call make_array_variable_value, which + dummies up a fake SHELL_VAR * from array[0]. This matters when + we're appending and have to use the current value + - bind_variable_internal: after computing the new value, treat assoc + variables with higher precedence than simple array variables; it + might be that a variable has both attributes set + +arrayfunc.c + - bind_array_var_internal: break code out that handles creating the + new value to be assigned to an array variable index into a new + function, make_array_variable_value. This handles creating a + dummy SHELL_VAR * for implicit array[0] assignment. Fixes bug + reported by Dan Douglas + +arrayfunc.h + - make_array_variable_value: new extern declaration diff --git a/MANIFEST b/MANIFEST index 770102d45..966f76126 100644 --- a/MANIFEST +++ b/MANIFEST @@ -766,6 +766,7 @@ tests/alias.tests f tests/alias1.sub f tests/alias.right f tests/appendop.tests f +tests/appendop1.sub f tests/appendop.right f tests/arith-for.tests f tests/arith-for.right f diff --git a/arrayfunc.c b/arrayfunc.c index 0ae89dacf..5fcfa91d1 100644 --- a/arrayfunc.c +++ b/arrayfunc.c @@ -118,8 +118,8 @@ convert_var_to_assoc (var) return var; } -static SHELL_VAR * -bind_array_var_internal (entry, ind, key, value, flags) +char * +make_array_variable_value (entry, ind, key, value, flags) SHELL_VAR *entry; arrayind_t ind; char *key; @@ -156,6 +156,21 @@ bind_array_var_internal (entry, ind, key, value, flags) else newval = make_variable_value (entry, value, flags); + return newval; +} + +static SHELL_VAR * +bind_array_var_internal (entry, ind, key, value, flags) + SHELL_VAR *entry; + arrayind_t ind; + char *key; + char *value; + int flags; +{ + char *newval; + + newval = make_array_variable_value (entry, ind, key, value, flags); + if (entry->assign_func) (*entry->assign_func) (entry, newval, ind, key); else if (assoc_p (entry)) diff --git a/arrayfunc.h b/arrayfunc.h index 23649bcdd..26f4879af 100644 --- a/arrayfunc.h +++ b/arrayfunc.h @@ -33,6 +33,8 @@ extern SHELL_VAR *convert_var_to_array __P((SHELL_VAR *)); extern SHELL_VAR *convert_var_to_assoc __P((SHELL_VAR *)); +extern char *make_array_variable_value __P((SHELL_VAR *, arrayind_t, char *, char *, int)); + extern SHELL_VAR *bind_array_variable __P((char *, arrayind_t, char *, int)); extern SHELL_VAR *bind_array_element __P((SHELL_VAR *, arrayind_t, char *, int)); extern SHELL_VAR *assign_array_element __P((char *, char *, int)); diff --git a/doc/bash.1 b/doc/bash.1 index d1b124231..077a172cf 100644 --- a/doc/bash.1 +++ b/doc/bash.1 @@ -2382,6 +2382,7 @@ be indexed or assigned contiguously. Indexed arrays are referenced using integers (including arithmetic expressions) and are zero-based; associative arrays are referenced using arbitrary strings. +Unless otherwise noted, indexed array indices must be non-negative integers. .PP An indexed array is created automatically if any variable is assigned to using the syntax \fIname\fP[\fIsubscript\fP]=\fIvalue\fP. The diff --git a/doc/bashref.texi b/doc/bashref.texi index 19c56c171..820d1fd43 100644 --- a/doc/bashref.texi +++ b/doc/bashref.texi @@ -6462,6 +6462,7 @@ be indexed or assigned contiguously. Indexed arrays are referenced using integers (including arithmetic expressions (@pxref{Shell Arithmetic})) and are zero-based; associative arrays use arbitrary strings. +Unless otherwise noted, indexed array indices must be non-negative integers. An indexed array is created automatically if any variable is assigned to using the syntax diff --git a/execute_cmd.c b/execute_cmd.c index f6f7bc8ce..eefa05e53 100644 --- a/execute_cmd.c +++ b/execute_cmd.c @@ -4118,7 +4118,7 @@ run_builtin: } if (command_line == 0) - command_line = savestring (the_printed_command_except_trap); + command_line = savestring (the_printed_command_except_trap ? the_printed_command_except_trap : ""); #if defined (PROCESS_SUBSTITUTION) if ((subshell_environment & SUBSHELL_COMSUB) && (simple_command->flags & CMD_NO_FORK) && fifos_pending() > 0) diff --git a/tests/RUN-ONE-TEST b/tests/RUN-ONE-TEST index 72ec06a2c..3efcf32d6 100755 --- a/tests/RUN-ONE-TEST +++ b/tests/RUN-ONE-TEST @@ -1,4 +1,4 @@ -BUILD_DIR=/usr/local/build/bash/bash-current +BUILD_DIR=/usr/local/build/chet/bash/bash-current THIS_SH=$BUILD_DIR/bash PATH=$PATH:$BUILD_DIR diff --git a/tests/appendop.right b/tests/appendop.right index 1e2433323..5d55b9c21 100644 --- a/tests/appendop.right +++ b/tests/appendop.right @@ -16,3 +16,8 @@ 9 16 ./appendop.tests: line 83: x: readonly variable +declare -A foo='([one]="bar" [two]="baz" [three]="quux" )' +declare -A foo='([one]="bar" [two]="baz" [0]="zero" [three]="quux" )' +declare -A foo='([four]="four" [one]="bar" [two]="baz" [0]="zero" [three]="quux" )' +declare -ai iarr='([0]="3" [1]="2" [2]="3")' +declare -ai iarr='([0]="3" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6")' diff --git a/tests/appendop.tests b/tests/appendop.tests index 7b61f3f15..be6c97166 100644 --- a/tests/appendop.tests +++ b/tests/appendop.tests @@ -81,3 +81,5 @@ readonly x+=7 echo $x x+=5 + +${THIS_SH} ./appendop1.sub diff --git a/tests/appendop1.sub b/tests/appendop1.sub new file mode 100644 index 000000000..7101d0cc4 --- /dev/null +++ b/tests/appendop1.sub @@ -0,0 +1,15 @@ +typeset -A foo=([one]=bar [two]=baz [three]=quux) +typeset -p foo + +foo+=zero +typeset -p foo + +foo+=([four]=four) +typeset -p foo + +typeset -ia iarr=(2 2 3) +iarr+=1 +typeset -p iarr + +iarr+=(4 5 6) +typeset -p iarr diff --git a/tests/run-printf.save b/tests/run-printf.save new file mode 100644 index 000000000..4555c6267 --- /dev/null +++ b/tests/run-printf.save @@ -0,0 +1,5 @@ +# See whether or not we can use `diff -a' +( diff -a ./printf.tests ./printf.tests >/dev/null 2>&1 ) && AFLAG=-a + +${THIS_SH} ./printf.tests > /tmp/xx 2>&1 +diff $AFLAG /tmp/xx printf.right && rm -f /tmp/xx diff --git a/variables.c b/variables.c index 13fccbd2d..10000d9d3 100644 --- a/variables.c +++ b/variables.c @@ -2241,6 +2241,12 @@ bind_variable_internal (name, value, table, hflags, aflags) /* Variables which are bound are visible. */ VUNSETATTR (entry, att_invisible); +#if defined (ARRAY_VARS) + if (assoc_p (entry) || array_p (entry)) + newval = make_array_variable_value (entry, 0, "0", value, aflags); + else +#endif + newval = make_variable_value (entry, value, aflags); /* XXX */ /* Invalidate any cached export string */ @@ -2251,14 +2257,14 @@ bind_variable_internal (name, value, table, hflags, aflags) /* If an existing array variable x is being assigned to with x=b or `read x' or something of that nature, silently convert it to x[0]=b or `read x[0]'. */ - if (array_p (entry)) + if (assoc_p (entry)) { - array_insert (array_cell (entry), 0, newval); + assoc_insert (assoc_cell (entry), savestring ("0"), newval); free (newval); } - else if (assoc_p (entry)) + else if (array_p (entry)) { - assoc_insert (assoc_cell (entry), savestring ("0"), newval); + array_insert (array_cell (entry), 0, newval); free (newval); } else