mirror of
https://https.git.savannah.gnu.org/git/bash.git
synced 2026-06-28 16:09:51 +02:00
minor changes for builtin array subscript expansion; additional tests
This commit is contained in:
@@ -10312,3 +10312,11 @@ subst.c
|
||||
resulting WORD_LIST * as if special == 0, because we don't want to
|
||||
quote the list for pattern matching. Report from
|
||||
Adjudicator Darren <adjudicatordarren@protonmail.com>
|
||||
|
||||
5/14
|
||||
----
|
||||
subst.c
|
||||
- expand_array_subscript: add double quote (") to the list of characters
|
||||
that are backslash-quoted in subscripts after word expansion.
|
||||
skipsubscript treats them specially, so you have to quote them to
|
||||
do things like `key='"' ; array[$key]=1 ; [[ -v array[$key] ]]'
|
||||
|
||||
@@ -1314,6 +1314,7 @@ tests/quotearray1.sub f
|
||||
tests/quotearray2.sub f
|
||||
tests/quotearray3.sub f
|
||||
tests/quotearray4.sub f
|
||||
tests/quotearray5.sub f
|
||||
tests/read.tests f
|
||||
tests/read.right f
|
||||
tests/read1.sub f
|
||||
|
||||
@@ -10199,6 +10199,7 @@ expand_array_subscript (string, sindex, quoted, flags)
|
||||
abstab[LBRACK] = abstab[RBRACK] = 1;
|
||||
abstab['$'] = abstab['`'] = abstab['~'] = 1;
|
||||
abstab['\\'] = abstab['\''] = 1;
|
||||
abstab['"'] = 1; /* XXX */
|
||||
/* We don't quote `@' or `*' in the subscript at all. */
|
||||
}
|
||||
|
||||
|
||||
+41
-10
@@ -21,17 +21,17 @@ declare -A A=(["~"]="43" ["~0"]="43" )
|
||||
declare -a a=([0]="12" [1]="42")
|
||||
2
|
||||
2
|
||||
declare -Ai assoc=(["']"]="2" ["\$var"]="1" )
|
||||
declare -Ai assoc=(["']"]="3" ["\$var"]="1" )
|
||||
105
|
||||
declare -A assoc=(["\` echo >&2 foo\`"]="42" ["\$( echo >&2 bar)"]="63" )
|
||||
./quotearray.tests: line 139: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
|
||||
./quotearray.tests: line 143: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
|
||||
./quotearray.tests: line 140: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
|
||||
./quotearray.tests: line 144: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
|
||||
1
|
||||
./quotearray.tests: line 146: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
|
||||
./quotearray.tests: line 147: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
|
||||
1
|
||||
./quotearray.tests: line 149: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
|
||||
./quotearray.tests: line 150: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
|
||||
1
|
||||
./quotearray.tests: line 152: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
|
||||
./quotearray.tests: line 153: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
|
||||
1
|
||||
declare -A assoc
|
||||
0
|
||||
@@ -57,8 +57,11 @@ foo
|
||||
0
|
||||
1
|
||||
1
|
||||
./quotearray1.sub: line 111: test: aa[$(echo: binary operator expected
|
||||
./quotearray1.sub: line 113: test: aa[$(echo: binary operator expected
|
||||
2
|
||||
[[ -v assoc[a] ]]; $?=0
|
||||
[[ -v assoc["] ]]; $?=0
|
||||
declare -A assoc=(["\""]="123" [a]="123" )
|
||||
declare -A a=([1]="1" [0]="0" [" "]="11" )
|
||||
7
|
||||
7
|
||||
@@ -80,18 +83,23 @@ declare -A assoc=(["\$var"]="value" )
|
||||
declare -A assoc=(["\$var"]="value" )
|
||||
declare -A assoc=(["\$var"]="value" )
|
||||
declare -A assoc=()
|
||||
declare -A a=()
|
||||
declare -A a=(["\$(echo foo)"]="1" )
|
||||
declare -A a=()
|
||||
declare -A a=(["\$(echo foo)"]="1" )
|
||||
declare -A a=(["\$(echo foo)"]="1" )
|
||||
declare -A assoc=(["!"]="bang" )
|
||||
1
|
||||
1
|
||||
declare -A assoc=(["!"]="bang" ["@"]="at" )
|
||||
declare -A assoc=(["!"]="bang" )
|
||||
declare -a array=([0]="1" [1]="2" [2]="3")
|
||||
./quotearray3.sub: line 93: declare: array: not found
|
||||
./quotearray3.sub: line 97: declare: array: not found
|
||||
./quotearray3.sub: line 94: declare: array: not found
|
||||
./quotearray3.sub: line 98: declare: array: not found
|
||||
declare -A map=(["foo\$(uname >/dev/tty)bar"]="1" )
|
||||
1
|
||||
declare -A map=()
|
||||
$(DOESNOTEXIST)
|
||||
declare -A blah=()
|
||||
declare -A assoc=(["*"]="star" ["!"]="bang" ["@"]="at" )
|
||||
declare -A assoc=(["*"]="star" ["!"]="bang" )
|
||||
declare -A assoc=(["!"]="bang" )
|
||||
@@ -119,3 +127,26 @@ declare -a array=([0]="1" [1]="2" [2]="3")
|
||||
0
|
||||
./quotearray4.sub: line 115: array[@]: bad array subscript
|
||||
declare -a array=([0]="1" [1]="2" [2]="3")
|
||||
./quotearray5.sub: line 27: unset: `a[$(echo': not a valid identifier
|
||||
./quotearray5.sub: line 27: unset: `foo)]': not a valid identifier
|
||||
declare -A a=()
|
||||
declare -A a=()
|
||||
declare -A a=()
|
||||
-----
|
||||
declare -A a=(["\$(echo foo)"]="1" )
|
||||
declare -A a=()
|
||||
declare -A a=()
|
||||
declare -A a=()
|
||||
-----
|
||||
declare -A a=()
|
||||
declare -A a=()
|
||||
declare -A a=()
|
||||
----------
|
||||
declare -A a=([.]="v1" )
|
||||
declare -A a=([.]="v1" )
|
||||
-----
|
||||
declare -A a=([.]="v1" )
|
||||
declare -A a=([.]="v1" )
|
||||
-----
|
||||
declare -A a=([.]="v1" )
|
||||
declare -A a=([.]="v1" )
|
||||
|
||||
@@ -119,6 +119,7 @@ declare -Ai assoc
|
||||
assoc[$var]=1
|
||||
assoc[$var]+=1
|
||||
((assoc['$var']++))
|
||||
((assoc[$var]++))
|
||||
typeset -p assoc
|
||||
|
||||
unset assoc
|
||||
@@ -158,3 +159,6 @@ ${THIS_SH} ./quotearray3.sub
|
||||
|
||||
# behavior of builtins with array subscripts @ and *
|
||||
${THIS_SH} ./quotearray4.sub
|
||||
|
||||
# behavior of unset with quoted and unquoted array arguments
|
||||
${THIS_SH} ./quotearray5.sub
|
||||
|
||||
@@ -91,6 +91,8 @@ echo $?
|
||||
[[ -v assoc['$key4'] ]]
|
||||
echo $?
|
||||
|
||||
unset -v assoc
|
||||
|
||||
declare -A aa
|
||||
aa[$key5]=foo
|
||||
|
||||
@@ -112,3 +114,18 @@ test -v aa[$key6]
|
||||
echo $?
|
||||
|
||||
unset aa key
|
||||
|
||||
declare -A assoc
|
||||
|
||||
mytest ()
|
||||
{
|
||||
assoc["$1"]=123
|
||||
[[ -v assoc["$1"] ]]
|
||||
printf '[[ -v assoc[%s] ]]; $?=%s\n' "$1" "$?"
|
||||
}
|
||||
|
||||
mytest 'a'
|
||||
mytest '"'
|
||||
declare -p assoc
|
||||
unset -v assoc
|
||||
unset -f mytest
|
||||
|
||||
@@ -101,3 +101,7 @@ declare -p assoc
|
||||
|
||||
shopt -s assoc_expand_once
|
||||
test -v assoc["$key"] ; echo $?
|
||||
|
||||
unset assoc
|
||||
shopt -u assoc_expand_once
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ unset 'assoc[$var]'
|
||||
declare -p assoc
|
||||
|
||||
unset assoc
|
||||
shopt -u assoc_expand_once
|
||||
|
||||
declare -A a
|
||||
a['$(echo foo)']=1
|
||||
@@ -95,3 +96,22 @@ declare -p array
|
||||
BASH_COMPAT=51
|
||||
unset array[@]
|
||||
declare -p array
|
||||
|
||||
declare -A map; key='foo$(uname >/dev/tty)bar'; map[$key]=1
|
||||
declare -p map
|
||||
echo ${map["$key"]}
|
||||
|
||||
unset map["$key"]
|
||||
declare -p map
|
||||
unset map
|
||||
|
||||
declare -A blah
|
||||
blah['$(DOESNOTEXIST)']=broken
|
||||
for i in "${!blah[@]}"; do echo "$i"; done
|
||||
|
||||
for i in "${!blah[@]}"; do unset blah["$i"]; done
|
||||
declare -p blah
|
||||
unset blah
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# a set of tests for unset to try to ensure that subscripts are only expanded
|
||||
# once. Derived from tests submitted by konsolebox@gmail.com
|
||||
|
||||
declare -A a
|
||||
key='$(echo foo)'
|
||||
|
||||
# Here the tokens are valid array references and pass that fact to unset
|
||||
# post-expansion
|
||||
|
||||
# This solves the surprise expansion issues.
|
||||
|
||||
a[$key]=1
|
||||
unset -v a[$key] # this performs normal word splitting
|
||||
unset -v a["$key"] # prevent word splitting
|
||||
declare -p a # Displays no element
|
||||
|
||||
a['$key']=2
|
||||
unset -v a['$key']
|
||||
declare -p a # Displays no element
|
||||
|
||||
a["foo"]=3
|
||||
unset -v a["foo"]
|
||||
declare -p a # Displays no element
|
||||
|
||||
echo -----
|
||||
|
||||
# Here the tokens are "strings". They expand and keep the
|
||||
# original behavior and allows existing scripts to not break.
|
||||
# It also allows nref or iref references to be transparently
|
||||
# referenced in it.
|
||||
|
||||
# the quotes prevent the arguments from being recognized as valid array
|
||||
# references before word expansion. since unset doesn't know to treat
|
||||
# them specially, they're treated as in previous versions and expansion
|
||||
# is performed as part of evaluating the subscript
|
||||
|
||||
a[$key]=1
|
||||
declare -p a
|
||||
unset 'a[$key]' # Transforms to a[$key] after expansion
|
||||
declare -p a # Displays no element
|
||||
|
||||
a['$key']=2
|
||||
unset "a['\$key']" # Transforms to a['$key'] after expansion
|
||||
declare -p a # Displays no element
|
||||
|
||||
a["foo"]=3
|
||||
unset 'a["foo"]' # Transforms to a["foo"] after expansion
|
||||
declare -p a # Displays no element
|
||||
|
||||
echo -----
|
||||
|
||||
# The update also keeps compatibility with already existing behavior of
|
||||
# unset when assoc_expand_once is enabled, but only for quoted tokens.
|
||||
|
||||
a=()
|
||||
shopt -s assoc_expand_once
|
||||
|
||||
a[$key]=1
|
||||
unset "a[$key]"
|
||||
declare -p a # Displays no element
|
||||
|
||||
a['$key']=2
|
||||
unset "a[\$key]"
|
||||
declare -p a # Displays no element
|
||||
|
||||
a["foo"]=3
|
||||
unset "a[foo]"
|
||||
declare -p a # Displays no element
|
||||
|
||||
echo ----------
|
||||
|
||||
# For unsetting '@' and all elements:
|
||||
|
||||
key=@
|
||||
|
||||
declare -A a=(@ v0 . v1)
|
||||
unset a[$key]
|
||||
declare -p a # Displays 'declare -A a=([.]="v1" )'
|
||||
|
||||
declare -A a=(@ v0 . v1)
|
||||
unset a[@]
|
||||
declare -p a # same behavior
|
||||
|
||||
echo -----
|
||||
|
||||
# these are quoted strings and unset doesn't treat them specially
|
||||
|
||||
unset a
|
||||
shopt -u assoc_expand_once
|
||||
|
||||
declare -A a=(@ v0 . v1)
|
||||
unset 'a[$key]'
|
||||
declare -p a # Displays 'declare -A a=([.]="v1" )'
|
||||
|
||||
declare -A a=(@ v0 . v1)
|
||||
unset 'a[@]'
|
||||
declare -p a # same behavior
|
||||
|
||||
echo -----
|
||||
|
||||
unset a
|
||||
shopt -s assoc_expand_once
|
||||
|
||||
declare -A a=(@ v0 . v1)
|
||||
unset "a[$key]" # $key is expanded
|
||||
declare -p a # Displays 'declare -A a=([.]="v1" )'
|
||||
|
||||
declare -A a=(@ v0 . v1)
|
||||
unset 'a[@]'
|
||||
declare -p a # same behavior
|
||||
Reference in New Issue
Block a user