1
0
Fork 0

Adding upstream version 5.2.37.

Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
This commit is contained in:
Daniel Baumann 2025-06-21 06:49:21 +02:00
parent cf91100bce
commit fa1b3d3922
Signed by: daniel.baumann
GPG key ID: BCC918A2ABD66424
1435 changed files with 757174 additions and 0 deletions

9
tests/COPYRIGHT Normal file
View file

@ -0,0 +1,9 @@
Unless otherwise stated, all files in this directory are Copyright (C)
1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,
2004,2005,2006,2007,2008,2009,2010,2011
Free Software Foundation, Inc.
See the file COPYING in the bash distribution root directory for copying
and usage restrictions.
The file ifs-posix.tests is Copyright (C) 2005 Glen Fowler.

3
tests/README Normal file
View file

@ -0,0 +1,3 @@
Type `sh run-all'.
Read COPYRIGHT for copyright information.

45
tests/alias.right Normal file
View file

@ -0,0 +1,45 @@
alias: 0
alias: 0
./alias.tests: line 38: qfoo: command not found
quux
hi
bar
value
bar
value
OK
OK
OK
OK
one
two
three
four
one
two
three
four
Error: bar
ok 1
ok 2
text
whoops: nullalias
foo
a
a b
a b
a a b
ok 3
ok 4
bar
bad
0
<|cat>
foo
bar
baz
foo
bar
baz
<áa>
<aá>

65
tests/alias.tests Normal file
View file

@ -0,0 +1,65 @@
# 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/>.
#
# place holder for future alias testing
shopt -s expand_aliases
# alias/unalias tests originally in builtins.tests
unalias -a
# this should return success, according to POSIX.2
alias
echo alias: $?
alias foo=bar
unalias foo
# this had better return success, according to POSIX.2
alias
echo alias: $?
# bug in all versions through bash-2.05b
unalias qfoo qbar qbaz quux 2>/dev/null
alias qfoo=qbar
alias qbar=qbaz
alias qbaz=quux
alias quux=qfoo
qfoo
unalias qfoo qbar qbaz quux
unalias -a
alias foo='echo '
alias bar=baz
alias baz=quux
foo bar
unalias foo bar baz
# post bash-5.1 problems with compound array assignment during multiline
# alias expansion
alias foo='a=() b=""
for i in 1; do echo hi; done'
foo
unalias foo
${THIS_SH} ./alias1.sub
${THIS_SH} ./alias2.sub
${THIS_SH} ./alias3.sub
${THIS_SH} ./alias4.sub
${THIS_SH} ./alias5.sub
${THIS_SH} ./alias6.sub

33
tests/alias1.sub Normal file
View file

@ -0,0 +1,33 @@
# 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/>.
#
shopt -s expand_aliases
alias foo=echo
< /dev/null foo bar
< /dev/null x=value
echo $x
< /dev/null x=newvalue foo bar
echo $x
# problem reported by Vincent Lefevre
alias a="echo OK >&2"
a
> /dev/null a
${THIS_SH} -c 'shopt -s expand_aliases; alias a="echo OK >&2"
a
> /dev/null a'

35
tests/alias2.sub Normal file
View file

@ -0,0 +1,35 @@
# 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/>.
#
THIS=alias2
FN=$TMPDIR/$THIS.script
cat > $FN <<'EOF'
#
(echo "$1")
EOF
chmod u+x $FN
shopt -s expand_aliases
alias foo1='$FN one; source $FN two; source $FN three; $FN four'
alias foo2='$FN one
source $FN two
source $FN three
$FN four'
foo1
foo2
rm -f $FN

11
tests/alias3.sub Normal file
View file

@ -0,0 +1,11 @@
shopt -s expand_aliases
alias foo='oneword'
foo_word='foo'
#
# Fails silently to match 'foo':
#
case "$foo_word"
in
foo) ;;
*) echo bad 1;;
esac

100
tests/alias4.sub Normal file
View file

@ -0,0 +1,100 @@
# 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/>.
#
shopt -s expand_aliases
# from an austin-group report
alias foo="echo 'Error:"
foo bar'
# from some FreeBSD sh tests
v=1
alias a='unalias -a
v=2'
eval a
[ "$v" = 2 ] && echo ok 1
v=1
alias a='unalias a
v=2'
eval a
[ "$v" = 2 ] && echo ok 2
# make sure command doesn't ever reset anything even if it's made a keyword
unalias -a
alias command=command
alias true='echo bad'
eval 'command true'
unalias -a
alias alias0=command
alias true='echo bad'
eval 'alias0 true'
# make sure null aliases are ok
unalias -a
alias nullalias=''
alias foo='echo '
foo nullalias text
unalias foo
# aliases shouldn't be expanded in quoted strings even when the previous word
# is an alias whose expansion ends in a space
alias foo="echo 'whoops: "
foo nullalias'
unalias -a
# recursive alias definitions
alias echo=echo
eval echo foo
alias echo='echo a'
echo
echo b
eval echo b
echo $(eval echo b)
unalias -a
# alias expansion when in a command position after redirections
alias e=echo
eval '</dev/null e ok 3'
eval 'a=true e ok 4'
alias comment=#
comment
alias long_comment='# for x in '
long_comment text after
# comment
comment foo bar
# alias ending in a tab
alias foo="\
echo \"bar\" \
"
foo
alias foo=$'echo bad \t'
foo
# this should probably just echo a blank line to stdout
alias foo='echo 0'
foo>&2
alias a='printf "<%s>\n" \'
a|cat

28
tests/alias5.sub Normal file
View file

@ -0,0 +1,28 @@
# 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/>.
#
# -c commands ending with multi-line aliases; post-bash-5.0
: ${THIS_SH:=./bash}
${THIS_SH} -c "shopt -s expand_aliases &>/dev/null;
alias myalias='/bin/echo foo
echo bar
echo baz'
myalias"
${THIS_SH} -c "shopt -s expand_aliases &>/dev/null;
alias myalias='echo foo
echo bar
echo baz'
myalias"

13
tests/alias6.sub Normal file
View file

@ -0,0 +1,13 @@
# make sure aliases that end in multibyte characters don't interfere with the
# space sentinel alias expansion adds; problem through bash-5.1
shopt -s expand_aliases
LC_ALL=en_US.UTF-8
alias a1='printf "<%s>\\n" áa'
a1
alias a2='printf "<%s>\\n" aá'
a2
unalias a1 a2

28
tests/appendop.right Normal file
View file

@ -0,0 +1,28 @@
14
1 2 3 4 5 6
1 2 3 4 51 6
145
14
7
42
1 2 3 4 12
18
1 2 3 4 18
1 2 7 4 5
1 2 7 13 5 9
14
9
4
9
16
./appendop.tests: line 97: x: readonly variable
declare -A foo=([two]="baz" [three]="quux" [one]="bar" )
declare -A foo=([0]="zero" [two]="baz" [three]="quux" [one]="bar" )
declare -A foo=([four]="four" [0]="zero" [two]="baz" [three]="quux" [one]="bar" )
declare -ai iarr=([0]="3" [1]="2" [2]="3")
declare -ai iarr=([0]="3" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6")
25 25
7 7
14
145
145 145

100
tests/appendop.tests Normal file
View file

@ -0,0 +1,100 @@
# 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/>.
#
# basic cases
a=1
a+=4
echo $a
x=(1 2 3)
x+=(4 5 6)
echo ${x[@]}
x[4]+=1
echo ${x[@]}
# trickier cases
# post-bash-4.2: bash understands += in environment assignments preceding
# command names
a+=5 printenv a
echo $a
# if the integer flag is set, ksh93 appears to do arithmetic += and evaluate
# old value as an arithmetic expression
a=
typeset -i a
a+=7
echo $a
b=4+1
typeset -i b
b+=37
echo $b
unset x
x=(1 2 3 4 5)
typeset -i x
x[4]+=7
echo ${x[@]}
unset x
typeset -i x
x=([0]=7+11)
echo ${x[@]}
unset x
x=(1 2 3 4 5)
typeset -i x
#x[4]=7+11
x=(1 2 3 4 [4]=7+11 )
echo ${x[@]}
x=( 1 2 [2]+=7 4 5 )
echo ${x[@]}
x+=( [3]+=9 [5]=9 )
echo ${x[@]}
unset a
a=1
export a+=4
printenv a
printenv a+
unset x
typeset -i x=4+5
echo $x
unset x
typeset x+=4
echo $x
typeset -i x+=5
echo $x
readonly x+=7
echo $x
x+=5
${THIS_SH} ./appendop1.sub
${THIS_SH} ./appendop2.sub

28
tests/appendop1.sub Normal file
View file

@ -0,0 +1,28 @@
# 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/>.
#
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

31
tests/appendop2.sub Normal file
View file

@ -0,0 +1,31 @@
# 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/>.
#
POSIXLY_CORRECT=1
x=2
x+=5 eval printf '"$x "'
echo "$x"
unset x
typeset -i x=2
x+=5 eval printf '"$x "'
echo "$x"
a=1
a+=4
echo $a
# idiotically, ksh93 makes these two cases differ (?)
a+=5 printenv a
a+=5 eval printf '"$a "'
echo $a

86
tests/arith-for.right Normal file
View file

@ -0,0 +1,86 @@
0
1
2
0
1
2
0
1
2
0
2
4
fx is a function
fx ()
{
i=0;
for ((1; i < 3; i++ ))
do
echo $i;
done;
for ((i=0; 1; i++ ))
do
if (( i >= 3 )); then
break;
fi;
echo $i;
done;
for ((i=0; i<3; 1))
do
echo $i;
(( i++ ));
done;
i=0;
for ((1; 1; 1))
do
if (( i > 2 )); then
break;
fi;
echo $i;
(( i++ ));
done;
i=0;
for ((1; 1; 1))
do
if (( i > 2 )); then
break;
fi;
echo $i;
(( i++ ));
done
}
0
1
2
0
1
2
0
1
2
0
1
2
0
1
2
bash: -c: line 1: syntax error: arithmetic expression required
bash: -c: line 1: syntax error: `(( i=0; "i < 3" ))'
2
bash: -c: line 1: syntax error: `;' unexpected
bash: -c: line 1: syntax error: `(( i=0; i < 3; i++; 7 ))'
2
20
20
12345678 987654321 012345678 987654321 012345678 987654321 012345678 987654321 012345678 987654321 012345678
12345678 987654321 012345678 987654321 012345678 987654321 012345678 987654321 012345678 987654321 012345678
4
3
2
1
0
4
3
2
1
0

128
tests/arith-for.tests Normal file
View file

@ -0,0 +1,128 @@
# 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/>.
#
fx()
{
i=0
for (( ; i < 3; i++ ))
do
echo $i
done
for (( i=0; ; i++ ))
do
if (( i >= 3 )); then
break;
fi
echo $i
done
for (( i=0; i<3; ))
do
echo $i
(( i++ ))
done
i=0
for (( ; ; ))
do
if (( i > 2 )); then
break;
fi
echo $i;
(( i++ ))
done
i=0
for ((;;))
do
if (( i > 2 )); then
break;
fi
echo $i;
(( i++ ))
done
}
for (( i=0; "i < 3" ; i++ ))
do
echo $i
done
i=0
for (( ; "i < 3"; i++ ))
do
echo $i
done
for (( i=0; ; i++ ))
do
if (( i >= 3 )); then
break;
fi
echo $i
done
for ((i = 0; ;i++ ))
do
echo $i
if (( i < 3 )); then
(( i++ ))
continue;
fi
break
done
type fx
fx
# errors
{
${THIS_SH} -c 'for (( i=0; "i < 3" ))
do
echo $i
done' ; echo $? ; } 2>&1 | sed 's|^.*/||'
#echo $?
{
${THIS_SH} -c 'for (( i=0; i < 3; i++; 7 ))
do
echo $i
done' ; echo $?; } 2>&1 | sed 's|^.*/||'
#echo $?
# one-liners added in post-bash-2.04
for ((i=0; i < 20; i++)) do : ; done
echo $i
for ((i=0; i < 20; i++)) { : ; }
echo $i
# added post-bash-4.2
for (( i = j = k = 1; i % 9 || (j *= -1, $( ((i%9)) || printf " " >&2; echo 0), k++ <= 10); i += j ))
do
printf "$i"
done
echo
( for (( i = j = k = 1; i % 9 || (j *= -1, $( ((i%9)) || printf " " >&2; echo 0), k++ <= 10); i += j ))
do
printf "$i"
done )
echo
for (( i = 4; ;i--)) ; do echo $i; if (( $i == 0 )); then break; fi; done
for (( i = 4;;i--)) ; do echo $i; if (( $i == 0 )); then break; fi; done

263
tests/arith.right Normal file
View file

@ -0,0 +1,263 @@
163
166
4
16
8
2
4
2
2
1
0
0
0
1
1
2
-3
-2
1
0
2
131072
29
33
49
1
1
0
0
1
1
1
2
3
1
58
2
60
1
256
16
62
4
29
5
-4
4
1
32
32
1
1
32
4
20
1,i+=2
30
1,j+=2
20
1,i+=2
30
1,j+=2
./arith.tests: line 127: 1 ? 20 : x+=2: attempted assignment to non-variable (error token is "+=2")
20
6
6,5,3
263
255
255
127
36
40
10
10
10
10
10
10
36
36
62
63
./arith.tests: line 162: 3425#56: invalid arithmetic base (error token is "3425#56")
./arith.tests: line 165: 2#: invalid integer constant (error token is "2#")
./arith.tests: line 168: 7 = 43 : attempted assignment to non-variable (error token is "= 43 ")
./arith.tests: line 169: 2#44: value too great for base (error token is "2#44")
./arith.tests: line 170: 44 / 0 : division by 0 (error token is "0 ")
./arith.tests: line 171: let: jv += $iv: syntax error: operand expected (error token is "$iv")
./arith.tests: line 172: jv += $iv : syntax error: operand expected (error token is "$iv ")
./arith.tests: line 173: let: rv = 7 + (43 * 6: missing `)' (error token is "6")
./arith.tests: line 177: 0#4: invalid number (error token is "0#4")
./arith.tests: line 178: 2#110#11: invalid number (error token is "2#110#11")
abc
def
ghi
ok
6
1
0
./arith.tests: line 196: 4 + : syntax error: operand expected (error token is "+ ")
16
./arith.tests: line 201: 4 ? : 3 + 5 : expression expected (error token is ": 3 + 5 ")
./arith.tests: line 202: 1 ? 20 : `:' expected for conditional expression (error token is "20 ")
./arith.tests: line 203: 4 ? 20 : : expression expected (error token is ": ")
9
./arith.tests: line 209: 0 && B=42 : attempted assignment to non-variable (error token is "=42 ")
9
./arith.tests: line 212: 1 || B=88 : attempted assignment to non-variable (error token is "=88 ")
9
0
9
0
9
1
9
7
7
4
32767
32768
131072
2147483647
1
4
4
5
5
4
3
3
4
4
7
./arith.tests: line 260: 7-- : syntax error: operand expected (error token is "- ")
./arith.tests: line 262: --x=7 : attempted assignment to non-variable (error token is "=7 ")
./arith.tests: line 263: ++x=7 : attempted assignment to non-variable (error token is "=7 ")
./arith.tests: line 265: x++=7 : attempted assignment to non-variable (error token is "=7 ")
./arith.tests: line 266: x--=7 : attempted assignment to non-variable (error token is "=7 ")
4
7
-7
7
7
2
2
./arith1.sub: line 15: 4-- : syntax error: operand expected (error token is "- ")
./arith1.sub: line 16: 4++ : syntax error: operand expected (error token is "+ ")
./arith1.sub: line 17: 4 -- : syntax error: operand expected (error token is "- ")
./arith1.sub: line 18: 4 ++ : syntax error: operand expected (error token is "+ ")
1
2
1
2
6
3
7
4
0
3
7
2
-2
1
./arith1.sub: line 48: ((: ++ : syntax error: operand expected (error token is "+ ")
7
7
./arith1.sub: line 51: ((: -- : syntax error: operand expected (error token is "- ")
7
7
7
7
1
2
1
2
1
0
5
1
6
2
3
1
4
0
./arith2.sub: line 46: ((: -- : syntax error: operand expected (error token is "- ")
-7
-7
./arith2.sub: line 50: ((: ++ : syntax error: operand expected (error token is "+ ")
7
7
-7
-7
7
7
1
1
4
5
-3
2
4
5000
5000
1
0
0
1
2147483649
0
0
0
0
0
0
-9223372036854775808
-9223372036854775808
-9223372036854775808
-9223372036854775808
-9223372036854775808
-9223372036854775808
-9223372036854775808
-9223372036854775808
-9223372036854775808
-9223372036854775808
9223372036854775805 9223372036854775806 9223372036854775807
123 456
123 456
123 456
123 456
123 456
123 456
1
1 2 3 4 5 6 7
0 1 2 3 4 5 6 7
0
0, 0
0, 1
efg
e
efg
e
abcdefg
efg
0
0
0
0
0
0
0
8 12
./arith.tests: line 310: ((: x=9 y=41 : syntax error in expression (error token is "y=41 ")
./arith.tests: line 314: a b: syntax error in expression (error token is "b")
./arith.tests: line 315: ((: a b: syntax error in expression (error token is "b")
42
42
42
42
42
42
./arith.tests: line 330: 'foo' : syntax error: operand expected (error token is "'foo' ")
./arith.tests: line 333: b[c]d: syntax error in expression (error token is "d")

333
tests/arith.tests Normal file
View file

@ -0,0 +1,333 @@
# 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/>.
#
set +o posix
declare -i iv jv
iv=$(( 3 + 5 * 32 ))
echo $iv
iv=iv+3
echo $iv
iv=2
jv=iv
let "jv *= 2"
echo $jv
jv=$(( $jv << 2 ))
echo $jv
let jv="$jv / 2"
echo $jv
jv="jv >> 2"
echo $jv
iv=$((iv+ $jv))
echo $iv
echo $((iv -= jv))
echo $iv
echo $(( iv == jv ))
echo $(( iv != $jv ))
echo $(( iv < jv ))
echo $(( $iv > $jv ))
echo $(( iv <= $jv ))
echo $(( $iv >= jv ))
echo $jv
echo $(( ~$jv ))
echo $(( ~1 ))
echo $(( ! 0 ))
echo $(( jv % 2 ))
echo $(( $iv % 4 ))
echo $(( iv <<= 16 ))
echo $(( iv %= 33 ))
echo $(( 33 & 55 ))
echo $(( 33 | 17 ))
echo $(( iv && $jv ))
echo $(( $iv || jv ))
echo $(( iv && 0 ))
echo $(( iv & 0 ))
echo $(( iv && 1 ))
echo $(( iv & 1 ))
echo $(( $jv || 0 ))
echo $(( jv | 0 ))
echo $(( jv | 1 ))
echo $(( $jv || 1 ))
let 'iv *= jv'
echo $iv
echo $jv
let "jv += $iv"
echo $jv
echo $(( jv /= iv ))
echo $(( jv <<= 8 ))
echo $(( jv >>= 4 ))
echo $(( iv |= 4 ))
echo $(( iv &= 4 ))
echo $(( iv += (jv + 9)))
echo $(( (iv + 4) % 7 ))
# unary plus, minus
echo $(( +4 - 8 ))
echo $(( -4 + 8 ))
# conditional expressions
echo $(( 4<5 ? 1 : 32))
echo $(( 4>5 ? 1 : 32))
echo $(( 4>(2+3) ? 1 : 32))
echo $(( 4<(2+3) ? 1 : 32))
echo $(( (2+2)<(2+3) ? 1 : 32))
echo $(( (2+2)>(2+3) ? 1 : 32))
# bug in bash versions through bash-3.2
S=105
W=$((S>99?4:S>9?3:S>0?2:0))
echo $W
unset W S
# check that the unevaluated part of the ternary operator does not do
# evaluation or assignment
x=i+=2
y=j+=2
declare -i i=1 j=1
echo $((1 ? 20 : (x+=2)))
echo $i,$x
echo $((0 ? (y+=2) : 30))
echo $j,$y
x=i+=2
y=j+=2
declare -i i=1 j=1
echo $((1 ? 20 : (x+=2)))
echo $i,$x
echo $((0 ? (y+=2) : 30))
echo $i,$y
# check precedence of assignment vs. conditional operator
# should be an error
declare -i x=2
y=$((1 ? 20 : x+=2))
# check precedence of assignment vs. conditional operator
declare -i x=2
echo $((0 ? x+=2 : 20))
# associativity of assignment-operator operator
declare -i i=1 j=2 k=3
echo $((i += j += k))
echo $i,$j,$k
# octal, hex
echo $(( 0x100 | 007 ))
echo $(( 0xff ))
echo $(( 16#ff ))
echo $(( 16#FF/2 ))
echo $(( 8#44 ))
echo $(( 8 ^ 32 ))
# other bases
echo $(( 16#a ))
echo $(( 32#a ))
echo $(( 56#a ))
echo $(( 64#a ))
echo $(( 16#A ))
echo $(( 32#A ))
echo $(( 56#A ))
echo $(( 64#A ))
echo $(( 64#@ ))
echo $(( 64#_ ))
# weird bases
echo $(( 3425#56 ))
# missing number after base now generates an error
echo $(( 2# ))
# these should generate errors
echo $(( 7 = 43 ))
echo $(( 2#44 ))
echo $(( 44 / 0 ))
let 'jv += $iv'
echo $(( jv += \$iv ))
let 'rv = 7 + (43 * 6'
# more errors
declare -i i
i=0#4
i=2#110#11
((echo abc; echo def;); echo ghi)
if (((4+4) + (4 + 7))); then
echo ok
fi
(()) # make sure the null expression works OK
a=(0 2 4 6)
echo $(( a[1] + a[2] ))
echo $(( (a[1] + a[2]) == a[3] ))
(( (a[1] + a[2]) == a[3] )) ; echo $?
# test pushing and popping the expression stack
unset A
A="4 + "
echo $(( ( 4 + A ) + 4 ))
A="3 + 5"
echo $(( ( 4 + A ) + 4 ))
# badly-formed conditional expressions
echo $(( 4 ? : $A ))
echo $(( 1 ? 20 ))
echo $(( 4 ? 20 : ))
# precedence and short-circuit evaluation
B=9
echo $B
echo $(( 0 && B=42 ))
echo $B
echo $(( 1 || B=88 ))
echo $B
echo $(( 0 && (B=42) ))
echo $B
echo $(( (${$} - $$) && (B=42) ))
echo $B
echo $(( 1 || (B=88) ))
echo $B
# until command with (( )) command
x=7
echo $x
until (( x == 4 ))
do
echo $x
x=4
done
echo $x
# exponentiation
echo $(( 2**15 - 1))
echo $(( 2**(16-1)))
echo $(( 2**16*2 ))
echo $(( 2**31-1))
echo $(( 2**0 ))
# {pre,post}-{inc,dec}rement and associated errors
x=4
echo $x
echo $(( x++ ))
echo $x
echo $(( x-- ))
echo $x
echo $(( --x ))
echo $x
echo $(( ++x ))
echo $x
echo $(( ++7 ))
echo $(( 7-- ))
echo $(( --x=7 ))
echo $(( ++x=7 ))
echo $(( x++=7 ))
echo $(( x--=7 ))
echo $x
echo $(( +7 ))
echo $(( -7 ))
echo $(( ++7 ))
echo $(( --7 ))
# combinations of expansions
echo $(( "`echo 1+1`" ))
echo $(( `echo 1+1` ))
${THIS_SH} ./arith1.sub
${THIS_SH} ./arith2.sub
${THIS_SH} ./arith3.sub
${THIS_SH} ./arith4.sub
# make sure arithmetic expansion handles ints > 2**31 - 1 using intmax_t
echo $(( 2147483645 + 4 ))
# other tests using INTMAX_MIN and INTMAX_MAX that cause exceptions if not
# handled correctly -- problem through bash-4.2
${THIS_SH} ./arith5.sub
# problems with suppressing evaluation present through bash-4.2
${THIS_SH} ./arith6.sub
# problems with parsing arithmetic expressions containing colons that are
# part of word expansions such as substring extraction
${THIS_SH} ./arith7.sub
# problems with evaluation of conditional expressions
${THIS_SH} ./arith8.sub
x=4
y=7
(( x=8 , y=12 ))
echo $x $y
# should be an error
(( x=9 y=41 ))
# These are errors
unset b
echo $((a b))
((a b))
n=42
printf "%d\n" $n
printf "%i\n" $n
echo $(( 8#$(printf "%o\n" $n) ))
printf "%u\n" $n
echo $(( 16#$(printf "%x\n" $n) ))
echo $(( 16#$(printf "%X\n" $n) ))
# allow reserved words after an arithmetic command just because
if ((expr)) then ((expr)) fi
# these are errors
foo=1
echo $(( 'foo' ))
# causes longjmp botches through bash-2.05b
a[b[c]d]=e

51
tests/arith1.sub Normal file
View file

@ -0,0 +1,51 @@
# 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/>.
#
# test of redone post-increment and post-decrement code
echo $(( 4-- ))
echo $(( 4++ ))
echo $(( 4 -- ))
echo $(( 4 ++ ))
(( array[0]++ ))
echo ${array}
(( array[0] ++ ))
echo ${array}
(( a++ ))
echo $a
(( a ++ ))
echo $a
echo $(( a ++ + 4 ))
echo $a
echo $(( a+++4 ))
echo $a
echo $(( a---4 ))
echo $a
echo $(( a -- + 4 ))
echo $a
echo $(( a -- - 4 ))
echo $a
(( ++ + 7 ))
(( ++ ))
echo $(( +++7 ))
echo $(( ++ + 7 ))
(( -- ))

58
tests/arith2.sub Normal file
View file

@ -0,0 +1,58 @@
# 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/>.
#
echo $(( --7 ))
echo $(( ++7 ))
echo $(( -- 7 ))
echo $(( ++ 7 ))
((++array[0] ))
echo $array
(( ++ array[0] ))
echo $array
(( ++a ))
echo $a
(( ++ a ))
echo $a
(( --a ))
echo $a
(( -- a ))
echo $a
echo $(( 4 + ++a ))
echo $a
echo $(( 4+++a ))
echo $a
echo $(( 4---a ))
echo $a
echo $(( 4 - -- a ))
echo $a
(( -- ))
echo $(( ---7 ))
echo $(( -- - 7 ))
(( ++ ))
echo $(( ++7 ))
echo $(( ++ + 7 ))
echo $(( ++-7 ))
echo $(( ++ - 7 ))
echo $(( +--7 ))
echo $(( -- + 7 ))

60
tests/arith3.sub Normal file
View file

@ -0,0 +1,60 @@
# 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/>.
#
# this depends on the sequence of random numbers from the internal LCRNG
RANDOM=42
(( dice[RANDOM%6+1 + RANDOM%6+1]++ ))
echo ${dice[6]}
(( ++dice[RANDOM%6+1 + RANDOM%6+1] ))
echo ${dice[7]}
v=4
DIND=20
(( dice[DIND%6 + 1]=v ))
echo ${dice[3]}
(( dice[DIND/v]+=2 ))
RANDOM=42
(( dice[RANDOM%6+1 + RANDOM%6+1]+=v ))
echo ${dice[6]}
(( dice[RANDOM%6+1 + RANDOM%6+1]-=v ))
echo ${dice[7]}
(( dice[RANDOM%6+1 + RANDOM%6+1]+=2 ))
echo ${dice[8]}
(( dice[RANDOM%6+1 + RANDOM%6+1]*=2 ))
echo ${dice[5]}
unset dice1 dice2
RANDOM=42
for i in {1..5000}; do ((dice1[$RANDOM%6+1 + $RANDOM%6+1]++)); done;
unset t; for i in ${dice1[@]}; do ((t+=i)); done; echo $t
foo="${dice1[@]}"
RANDOM=42
for i in {1..5000}; do ((dice2[RANDOM%6+1 + RANDOM%6+1]++)); done;
unset t; for i in ${dice2[@]}; do ((t+=i)); done; echo $t
bar="${dice2[@]}"
if [ "$foo" != "$bar" ]; then
echo "random sequences differ"
fi

10
tests/arith4.sub Normal file
View file

@ -0,0 +1,10 @@
x=$(( !!1 ))
echo $x
x=$(( -!+1 ))
echo $x
x=$(( +--+!!0 ))
echo $x
echo $(( !!+-+-~0 ))

72
tests/arith5.sub Normal file
View file

@ -0,0 +1,72 @@
# 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 lot of this is technically undefined behavior due to signed 64-bit
# integer overflow, but we're testing exception handling here
intmax_max=$((2**63 - 1))
intmax_min1=$((2**63))
intmax_min2=$((-2**63))
case $intmax_max in
9223372036854775807) ;;
*) echo "warning: your machine does not support 64-bit arithmetic using intmax_t" 2>&1 ;;
esac
# these are actually the same
echo $(( $intmax_min1 % -1 ))
echo $(( $intmax_min2 % -1 ))
echo $(( $intmax_max % -1 ))
lvalue=$intmax_min1
(( lvalue%= -1 ))
echo $lvalue
lvalue=$intmax_min2
(( lvalue%= -1 ))
echo $lvalue
lvalue=$intmax_max
(( lvalue%= -1 ))
echo $lvalue
# and these
echo $(( $intmax_min1 / -1 ))
echo $(( $intmax_min2 / -1 ))
lvalue=$intmax_min1
(( lvalue /= -1 ))
echo $lvalue
lvalue=$intmax_min2
(( lvalue /= -1 ))
echo $lvalue
echo $(( $intmax_min1 * -1 ))
echo $(( $intmax_min2 * -1 ))
lvalue=$intmax_min1
(( lvalue *= -1 ))
echo $lvalue
lvalue=$intmax_min2
(( lvalue *= -1 ))
echo $lvalue
echo $(( -${intmax_min1} ))
echo $(( -${intmax_min2} ))
foo1=$(( $intmax_max - 2 ))
eval echo \{${foo1}..${intmax_max}\}

65
tests/arith6.sub Normal file
View file

@ -0,0 +1,65 @@
# 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/>.
#
function reorder
{
(( x[1] < x && (x=x[1], x[1]=$x) ))
echo "${x[@]}"
}
x=(123 456)
reorder
x=(456 123)
reorder
unset x
unset -f reorder
function reorder
{
(( x[1] < x[0] && (x=x[1], x[1]=$x) ))
echo "${x[@]}"
}
x=(123 456)
reorder
x=(456 123)
reorder
unset x
unset -f reorder
function reorder
{
(( x[1] < x[0] && (x[0]=x[1], x[1]=$x) ))
echo "${x[@]}"
}
x=(123 456)
reorder
x=(456 123)
reorder
unset -f reorder
n=0 ; (( (a[n]=++n)<7&&a[0])); echo "${a[@]:1}"
n=0 a="(a[n]=++n)<7&&a[0]"; ((a[0])); echo "${a[@]:1}"
n=0 a="(a[n]=n++)<7&&a"; ((a)); echo "${a[@]:1}"
# bugs with lvalue caching and pointer aliasing through bash-4.2
echo $(( a=(y[0] + y[1]) & 0xff, b=(y[2] + y[3]) & 0xff, a << 8 | b))
echo $a, $b
((a = y[0], b = 1 ))
echo $a, $b

11
tests/arith7.sub Normal file
View file

@ -0,0 +1,11 @@
PARAM=abcdefg
echo ${PARAM:1 ? 4 : 2}
echo ${PARAM:1 ? 4 : 2:1}
echo ${PARAM: 4<5 ? 4 : 2}
echo ${PARAM: 5>4 ? 4 : 2:1}
echo ${PARAM:${OFFSET:-0}}
OFFSET=4
echo ${PARAM:${OFFSET:-0}}

50
tests/arith8.sub Normal file
View file

@ -0,0 +1,50 @@
# 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/>.
#
# problems with evaluation of wrong terms in conditional expressions through
# bash-4.4
a=0 x="a=1"
((0?x:0))
echo $a
unset a x
a=0 x="a=1"
((1?0:x))
echo $a
unset a x
a=0 x="a=1"
((0?(x):0))
echo $a
unset a x
a=0 x="a=1"
((0?$x:0))
echo $a
unset a x
a=0 x="a=1"
((0&&x))
echo $a
unset a x
a=0 x="a=1"
((1||x))
echo $a
unset a x
a=0
((0?arr[a=1]:0))
echo $a
unset a

120
tests/array-at-star Normal file
View file

@ -0,0 +1,120 @@
# test the expansion of ${array[@]} and ${array[*]}, both quoted and
# unquoted. the expansions should be exactly analogous to the
# expansions of $@ and $* quoted and unquoted
A=(a b)
recho "${A[*]}"
# If IFS is null, the parameters are joined without separators
IFS=''
recho "${A[*]}"
# If IFS is unset, the parameters are separated by spaces
unset IFS
recho "${A[*]}"
recho "${A[@]}"
recho ${A[@]}
IFS='/'
A=(bob 'tom dick harry' joe)
set ${A[*]}
recho $#
recho $1
recho $2
recho $3
A=(bob 'tom dick harry' joe)
set ${A[*]}
recho $#
recho $1
recho $2
recho $3
A=(bob 'tom dick harry' joe)
set ${A[@]}
recho $#
recho $1
recho $2
recho $3
A=(bob 'tom dick harry' joe)
set ${A[@]}
recho $#
recho $1
recho $2
recho $3
# according to POSIX.2, unquoted $* should expand to multiple words if
# $IFS is null, just like unquoted $@
IFS=''
A=(bob 'tom dick harry' joe)
set "${A[*]}"
recho $#
recho $1
recho $2
recho $3
A=(bob 'tom dick harry' joe)
set ${A[*]}
recho $#
recho $1
recho $2
recho $3
A=(bob 'tom dick harry' joe)
set ${A[@]}
recho $#
recho $1
recho $2
recho $3
# if IFS is unset, the individual positional parameters are split on
# " \t\n" if $* or $@ are unquoted
unset IFS
A=(bob 'tom dick harry' joe)
set ${A[*]}
recho $#
recho $1
recho $2
recho $3
A=(bob 'tom dick harry' joe)
set ${A[@]}
recho $#
recho $1
recho $2
recho $3
# but not for "$@" or "$*"
A=(bob 'tom dick harry' joe)
set "${A[*]}"
recho $#
recho $1
recho $2
recho $3
A=(bob 'tom dick harry' joe)
set "${A[@]}"
recho $#
recho $1
recho $2
recho $3
# these should both expand the value of A to multiple words
A=(a b c d e)
IFS=""
recho ${A[@]}
recho "${A[@]}"
# this example is straight from the POSIX.2 rationale and adapted to arrays
A=(foo bar bam)
recho "${A[@]}"
recho "${A[*]}"
unset IFS
recho "${A[@]}"
recho ${A[@]}
recho "${A[*]}"

787
tests/array.right Normal file
View file

@ -0,0 +1,787 @@
./array.tests: line 28: syntax error near unexpected token `&'
./array.tests: line 28: `test=(first & second)'
1
abcde
abcde
abcde bdef
abcde bdef
declare -a BASH_ARGC=()
declare -a BASH_ARGV=()
declare -a BASH_LINENO=([0]="0")
declare -a BASH_SOURCE=([0]="./array.tests")
declare -a DIRSTACK=()
declare -a FUNCNAME
declare -a a=([0]="abcde" [1]="" [2]="bdef")
declare -a b
declare -ar c
abcde bdef
abcde bdef
abcde
abcde
abcde
bdef
hello world
11
3
bdef hello world test expression test 2
./array.tests: line 92: readonly: `a[5]': not a valid identifier
declare -ar a=([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="test 2")
declare -ar c
declare -ar a=([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="test 2")
declare -ar c
readonly -a a=([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="test 2")
readonly -a c
a test
declare -a BASH_ARGC=()
declare -a BASH_ARGV=()
declare -a BASH_LINENO=([0]="0")
declare -a BASH_SOURCE=([0]="./array.tests")
declare -a DIRSTACK=()
declare -a FUNCNAME
declare -ar a=([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="test 2")
declare -a b=([0]="this" [1]="is" [2]="a" [3]="test" [4]="" [5]="/etc/passwd")
declare -ar c
declare -a d=([1]="" [2]="bdef" [5]="hello world" [6]="test" [9]="ninth element")
declare -a e=([0]="test")
declare -a f=([0]="" [1]="bdef" [2]="hello world" [3]="test" [4]="ninth element")
./array.tests: line 116: a: readonly variable
./array.tests: line 118: b[]: bad array subscript
./array.tests: line 119: b[*]: bad array subscript
this
./array.tests: line 122: c[-2]: bad array subscript
./array.tests: line 123: c: bad array subscript
./array.tests: line 125: d[7]: cannot assign list to array member
./array.tests: line 127: []=abcde: bad array subscript
./array.tests: line 127: [*]=last: cannot assign to non-numeric index
./array.tests: line 127: [-65]=negative: bad array subscript
declare -a BASH_ARGC=()
declare -a BASH_ARGV=()
declare -a BASH_LINENO=([0]="0")
declare -a BASH_SOURCE=([0]="./array.tests")
declare -a DIRSTACK=()
declare -a FUNCNAME
declare -ar a=([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="test 2")
declare -a b=([0]="this" [1]="is" [2]="a" [3]="test" [4]="" [5]="/etc/passwd")
declare -ar c
declare -a d=([1]="test test")
declare -a e=()
declare -a f=([0]="" [1]="bdef" [2]="hello world" [3]="test" [4]="ninth element")
./array.tests: line 135: unset: ps1: not an array variable
./array.tests: line 139: declare: c: cannot destroy array variables in this way
this of
this is a test of read using arrays
this test
this is a test of arrays
declare -a BASH_ARGC=()
declare -a BASH_ARGV=()
declare -a BASH_LINENO=([0]="0")
declare -a BASH_SOURCE=([0]="./array.tests")
declare -a DIRSTACK=()
declare -a FUNCNAME
declare -ar a=([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="test 2")
declare -a b=([0]="this" [1]="is" [2]="a" [3]="test" [4]="" [5]="/etc/passwd")
declare -ar c
declare -a d=([1]="test test")
declare -a e=()
declare -a f=([0]="" [1]="bdef" [2]="hello world" [3]="test" [4]="ninth element")
declare -a rv=([0]="this" [1]="is" [2]="a" [3]="test" [4]="of" [5]="read" [6]="using" [7]="arrays")
abde
abde
bbb
efgh
wxyz
wxyz
./array.tests
a
b c
d
e f g
h
./array.tests
a
b c
d
e f g
h
/bin /usr/bin /usr/ucb /usr/local/bin . /sbin /usr/sbin
bin bin ucb bin . sbin sbin
bin
/ / / / / /
/
argv[1] = <bin>
argv[1] = </>
argv[1] = <sbin>
argv[1] = </>
\bin \usr/bin \usr/ucb \usr/local/bin . \sbin \usr/sbin
\bin \usr\bin \usr\ucb \usr\local\bin . \sbin \usr\sbin
\bin \usr\bin \usr\ucb \usr\local\bin . \sbin \usr\sbin
4 -- 4
7 -- 7
55
49
6 -- 6
42 14 44
grep [ 123 ] *
6 7 9
6 7 9 5
length = 3
value = new1 new2 new3
./array.tests: line 255: narray: unbound variable
./array1.sub: line 1: syntax error near unexpected token `('
./array1.sub: line 1: `printf "%s\n" -a a=(a 'b c')'
./array2.sub: line 1: declare: `[]=asdf': not a valid identifier
./array2.sub: line 2: a[]: bad array subscript
./array2.sub: line 4: syntax error near unexpected token `('
./array2.sub: line 4: `declare -a ''=(a 'b c')'
9
9
7 8 9
8 11
8 11
6
6
nordholz
8
8
8
a b c d e f g
for case if then else
<> < > !
12 14 16 18 20
4414758999202
aaa bbb
./array.tests: line 305: syntax error near unexpected token `<>'
./array.tests: line 305: `metas=( <> < > ! )'
./array.tests: line 306: syntax error near unexpected token `<>'
./array.tests: line 306: `metas=( [1]=<> [2]=< [3]=> [4]=! )'
abc 3
case 4
abc case if then else 5
abc case if then else 5
0
case 4
case if then else 5
case if then else 5
argv[1] = <0>
argv[2] = <1>
argv[3] = <4>
argv[4] = <10>
argv[1] = <0>
argv[2] = <1>
argv[3] = <4>
argv[4] = <10>
argv[1] = <0>
argv[2] = <1>
argv[3] = <4>
argv[4] = <10>
argv[1] = <0 1 4 10>
include null element -- expect one
one
include unset element -- expect three five
three five
start at unset element -- expect five seven
five seven
too many elements -- expect three five seven
three five seven
positive offset - expect five seven
five seven
negative offset to unset element - expect seven
seven
positive offset 2 - expect seven
seven
negative offset 2 - expect seven
seven
out-of-range offset
e
4
1 4 7 10
'b
b c
$0
declare -a A=([0]="X=a" [1]="b")
t
[3]=abcde r s t u v
e
9
2
a b c
argv[1] = <-iname 'a>
argv[2] = <-iname 'b>
argv[3] = <-iname 'c>
'hey'
hey
''hey
'hey'
argv[1] = <c>
argv[2] = <d>
argv[3] = <e>
argv[4] = <f>
argv[1] = <c d>
argv[2] = <e f>
argv[1] = <c d>
argv[2] = <e f>
argv[1] = <c d>
argv[2] = <e f>
argv[1] = <-iname 'abc>
argv[2] = <-iname 'def>
argv[1] = <-iname 'abc>
argv[2] = <-iname 'def>
argv[1] = <-iname>
argv[2] = <abc -iname def>
argv[1] = <-iname 'abc>
argv[2] = <-iname 'def>
argv[1] = <-iname>
argv[2] = <abc -iname def>
argv[1] = <-iname 'abc>
argv[2] = <-iname 'def>
argv[1] = <-iname 'abc>
argv[2] = <-iname 'def>
argv[1] = <-iname>
argv[2] = <abc -iname def>
*.* OK
1
a1 2 3c
argv[1] = <var with spaces>
argv[1] = <var with spaces>
argv[1] = <var with spacesab>
argv[2] = <cd>
argv[3] = <ef>
argv[1] = <var with spacesab>
argv[2] = <cd>
argv[3] = <ef>
argv[1] = <var with spacesab>
argv[2] = <cd>
argv[3] = <ef>
argv[1] = <var with spacesab>
argv[2] = <cd>
argv[3] = <ef>
argv[1] = <var with spacesab>
argv[2] = <cd>
argv[3] = <ef>
argv[1] = <var with spacesab>
argv[2] = <cd>
argv[3] = <ef>
2
argv[1] = <element1 with spaces>
argv[2] = <element2 with spaces>
argv[1] = <element1 with spaces>
argv[2] = <element2 with spaces>
nord!olz
rdholz
rdholz
rdho
argv[1] = <fooq//barq/>
argv[1] = <fooq>
argv[2] = <>
argv[3] = <barq>
argv[4] = <>
argv[1] = <foo!//bar!/>
argv[1] = <foo!>
argv[2] = <>
argv[3] = <bar!>
argv[4] = <>
argv[1] = <ooq//arq/>
argv[1] = <ooq>
argv[2] = <>
argv[3] = <arq>
argv[4] = <>
argv[1] = <Fooq//Barq/>
argv[1] = <Fooq>
argv[2] = <>
argv[3] = <Barq>
argv[4] = <>
argv[1] = <FOOQ//BARQ/>
argv[1] = <FOOQ>
argv[2] = <>
argv[3] = <BARQ>
argv[4] = <>
126
127
128
argv[1] = <€>
argv[1] = <~>
argv[2] = <^?>
argv[3] = <€>
argv[1] = <~>
argv[2] = <^?>
argv[3] = <€>
argv[1] = <~>
argv[2] = <^?>
argv[3] = <€>
Monday Tuesday Wednesday Thursday Friday Saturday Sunday
Monday
Monday
Tuesday
Monday
Monday
Tuesday
Monday
Tuesday
Wednesday
Monday
Tuesday
Wednesday
monday, monday, tuesday
wednesday, wednesday, thursday
monday, monday, tuesday
Wednesday, Wednesday, Thursday
nday
esday
dnesday
nday
esday
dnesday
onday
uesday
ednesday
onday
uesday
ednesday
version[agent]
version.agent
version[agent]
version.agent
foo[bar] version[agent]
bowl version.agent
foobar] foo foo[bar]
bleh bbb bleh
ab]
bar
1
1
1
1
1
1
main main
function function
function function
declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="5")
declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4")
declare -a x=([0]="0" [1]="1" [2]="2" [4]="4")
./array14.sub: line 24: unset: [-10]: bad array subscript
declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4")
declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="five")
declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="5")
declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="foo")
declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="5")
declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4four" [5]="5")
strlen(4four) = 5
1 2 0 3
1 2 0 3
1 2 0 3
1 2 0 3
1 2 0 3
declare -ai arr=([0]="2" [1]="4" [2]="6")
declare -a arr=([0]="hello" [1]="world")
foo index 1: ok
foo index 2: ok
foo: implicit reference to element 0: ok
foo: arithmetic evaluation: ok
bar: array with element zero unset: ok
bar: element zero: ok
qux: unset array: ok
qux: unset array element 0: ok
2
2
2
2
0
0
1
./array17.sub: line 43: ~: syntax error: operand expected (error token is "~")
0
0
3
3
0
0
zero
zero
one
one
one
one
two
two
./array17.sub: line 89: ~ : syntax error: operand expected (error token is "~ ")
1
argv[1] = <>
argv[2] = <>
argv[3] = <>
argv[1] = <bar>
argv[1] = <->
argv[2] = <->
argv[1] = < >
argv[1] = <qux>
argv[1] = <->
argv[2] = <->
argv[1] = < >
argv[1] = <>
argv[2] = <>
argv[3] = <>
argv[1] = <bar>
argv[1] = <->
argv[2] = <->
argv[1] = < >
argv[1] = <qux>
argv[1] = <->
argv[2] = <->
argv[1] = < >
declare -a foo=([0]="( zeroind )")
declare -a foo=([0]="zeroind")
declare -a foo=([0]="zeroind")
declare -a foo=([0]="[0]=bar")
declare -a foo=([0]="[0]=bar")
declare -a foo=([0]="[0]=bar")
declare -- a="(1 2 3)"
declare -a a=([0]="1" [1]="2" [2]="3")
declare -- a="([0]=a [1]=b)"
declare -a a=([0]="a" [1]="b")
declare -A a=([1]="b" [0]="a" )
declare -a var=([0]="[\$(echo" [1]="total" [2]="0)]=1" [3]="[2]=2]")
declare -a var=([0]="[\$(echo total 0)]=1 [2]=2]")
declare -a var=([0]="[\$(echo" [1]="total" [2]="0)]=1" [3]="[2]=2]")
./array19.sub: line 89: total 0: syntax error in expression (error token is "0")
declare -a var=()
declare -al foo=([0]="abcde" [1]="two" [2]="three")
declare -al foo=([0]="abcde")
declare -al ar=([0]="one" [1]="two" [2]="three")
declare -a a=([2]="foo")
declare -a a=([2]="foo")
declare -a a=([1]="(var)" [2]="foo")
./array19.sub: line 128: warning: a[1]=(var): quoted compound array assignment deprecated
declare -a a=([1]="(var)")
declare -a a=([0]="1" [1]="2" [2]="(1 2 3)")
declare -a a=([0]="1" [1]="2" [2]="(1 2 3)")
declare -a a=([0]="1" [1]="2" [2]="3")
declare -a a=([0]="1" [1]="2" [2]="3")
declare -a a=([0]="1" [1]="2" [2]="3")
declare -- a="a b"
declare -- b="/scratch/bash"
declare -- c="(1 2)"
declare -- d="(\$a)"
declare -- e="(\$(echo Darwin))"
declare -a a=([0]="a b")
declare -a b=([0]="/scratch/bash")
declare -a c=([0]="1" [1]="2")
declare -a d=([0]="a" [1]="b")
declare -a e=([0]="Darwin")
declare -A a=([0]="a b" )
declare -A b=([0]="/scratch/bash" )
declare -A c=([1]="2" )
declare -A d=(["a b"]="" )
declare -A e=([Darwin]="" )
a+b+c
x+b+c
a+b+c
x+b+c
argv[1] = <a+b+c+d+e+f>
argv[1] = <x+b+c+d+e+f>
a b c
x b c
a b c
x b c
declare -a a=([1]="2" [2]="3" [3]="4")
abcd
unset
declare -a a=()
declare -A A=([four]="4" [two]="2" [three]="3" [one]="1" )
declare -a a=()
declare -A A=()
declare -a foo=([0]="1" [1]="(4 5 6)" [2]="3")
a1
argv[1] = <>
argv[2] = <>
a2
argv[1] = <y>
argv[1] = <z>
a3
argv[1] = <>
argv[2] = <x>
a4
argv[1] = <y>
p1
argv[1] = <>
argv[2] = <>
p2
argv[1] = <>
argv[2] = <x>
p3
argv[1] = <y>
<X> <X> <X> <X>
<X> <X> <X> <X>
./array23.sub: line 22: $( echo >&2 foo ) : syntax error: operand expected (error token is "$( echo >&2 foo ) ")
./array23.sub: line 23: $( echo >&2 foo ) : syntax error: operand expected (error token is "$( echo >&2 foo ) ")
./array23.sub: line 24: $( echo >&2 foo ) : syntax error: operand expected (error token is "$( echo >&2 foo ) ")
./array23.sub: line 26: $( echo >&2 foo ) : syntax error: operand expected (error token is "$( echo >&2 foo ) ")
./array23.sub: line 30: $( echo >&2 foo ): syntax error: operand expected (error token is "$( echo >&2 foo )")
./array23.sub: line 33: $( echo >&2 foo ): syntax error: operand expected (error token is "$( echo >&2 foo )")
./array23.sub: line 34: $index: syntax error: operand expected (error token is "$index")
./array23.sub: line 35: $( echo >&2 foo ): syntax error: operand expected (error token is "$( echo >&2 foo )")
0
0
0
IFS=: ${var-$*}
abc
def ghi
jkl
abc
def ghi
jkl
----
IFS=: ${var=$*}
abc
def ghi
jkl
var=abc:def ghi:jkl
abc
def ghi
jkl
var=abc:def ghi:jkl
----
IFS=: ${var+$*}
abc
def ghi
jkl
abc
def ghi
jkl
----
IFS= ${var-$*}
abc
def ghi
jkl
abc
def ghi
jkl
----
IFS= ${var=$*}
abcdef ghijkl
var=abcdef ghijkl
abcdef ghijkl
var=abcdef ghijkl
----
IFS= ${var+$*}
abc
def ghi
jkl
abc
def ghi
jkl
1. indexed:
reference:
1. 0
./array25.sub: line 24: ' ': syntax error: operand expected (error token is "' '")
3. 0
4. 0
5. 0
6. 0
assignment:
1.declare -a a=([0]="10" [1]="1")
2.declare -a a=([0]="11" [1]="1")
3.declare -a a=([0]="12" [1]="1")
4.declare -a a=([0]="13" [1]="1")
arithmetic:
1.declare -a a=([0]="10" [1]="1")
2.declare -a a=([0]="11" [1]="1")
3.declare -a a=([0]="12" [1]="1")
4.declare -a a=([0]="13" [1]="1")
5.declare -a a=([0]="10" [1]="1")
6.declare -a a=([0]="11" [1]="1")
7.declare -a a=([0]="12" [1]="1")
8.declare -a a=([0]="13" [1]="1")
2. associative:
reference:
1.
2.
3.
4.
5.
6.
assignment:
1.declare -A a=([1]="1" [0]="0" [" "]="10" )
2.declare -A a=([1]="1" [0]="0" [" "]="11" )
3.declare -A a=([1]="1" [0]="0" [" "]="12" )
4.declare -A a=([1]="1" [0]="0" [" "]="13" )
arithmetic:
1.declare -A a=([1]="1" [0]="0" [" "]="10" )
2.declare -A a=([1]="1" [0]="0" [" "]="11" )
3.declare -A a=([1]="1" [0]="0" [" "]="12" )
4.declare -A a=([1]="1" [0]="0" [" "]="13" )
5.declare -A a=([1]="1" [0]="0" [" "]="10" )
6.declare -A a=([1]="1" [0]="0" [" "]="10" ["\" \""]="11" )
7.declare -A a=([1]="1" [0]="0" [" "]="12" ["\" \""]="11" )
8.declare -A a=([1]="1" [0]="0" [" "]="12" ["\" \""]="13" )
argv[1] = <aa>
argv[2] = <bb>
argv[1] = <aa>
argv[2] = <bb>
argv[1] = <aa>
argv[2] = <bb>
argv[1] = <aa>
argv[2] = <bb>
argv[1] = <aa>
argv[2] = <bb>
argv[3] = <aa>
argv[4] = <bb>
argv[1] = <aa>
argv[2] = <bb>
argv[3] = <aa>
argv[4] = <bb>
argv[1] = <aa+bb>
argv[2] = <aa+bb>
argv[1] = <aa>
argv[2] = <bb>
argv[3] = <aa>
argv[4] = <bb>
argv[1] = <xa>
argv[2] = <bb>
argv[1] = <xa>
argv[2] = <bb>
argv[1] = <xa>
argv[2] = <bb>
argv[1] = <xa>
argv[2] = <bb>
argv[1] = <xa>
argv[2] = <bb>
argv[1] = <xa>
argv[2] = <bb>
argv[1] = <xa+bb>
argv[1] = <xa+bb>
argv[1] = <xa+bb>
argv[2] = <xa+bb>
argv[1] = <bb>
argv[2] = <xa>
argv[1] = <bb>
argv[2] = <xa>
argv[1] = <bb>
argv[2] = <xa>
argv[1] = <bb+xa>
argv[1] = <xa>
argv[2] = <bb>
argv[1] = <xa>
argv[2] = <bb>
argv[1] = <xa>
argv[2] = <bb>
argv[1] = <xa>
argv[2] = <bb>
argv[1] = <xa>
argv[2] = <bb>
argv[1] = <xa>
argv[2] = <bb>
argv[1] = <xabb>
argv[1] = <xabb>
argv[1] = <xabb>
argv[2] = <xabb>
argv[1] = <bb>
argv[2] = <xa>
argv[1] = <bb>
argv[2] = <xa>
argv[1] = <bb>
argv[2] = <xa>
argv[1] = <bbxa>
argv[1] = <aa>
argv[2] = <bb>
argv[1] = <aa>
argv[2] = <bb>
argv[1] = <aa>
argv[2] = <bb>
argv[1] = <aa>
argv[2] = <bb>
argv[1] = <aa>
argv[2] = <bb>
argv[3] = <aa>
argv[4] = <bb>
argv[1] = <aa>
argv[2] = <bb>
argv[3] = <aa>
argv[4] = <bb>
argv[1] = <aa+bb>
argv[2] = <aa+bb>
argv[1] = <aa+bb>
argv[2] = <aa+bb>
argv[1] = <aa>
argv[2] = <bb>
argv[3] = <aa>
argv[4] = <bb>
argv[1] = <bb>
argv[2] = <aa>
argv[1] = <bb>
argv[2] = <aa>
argv[1] = <bb>
argv[2] = <aa>
argv[1] = <bb+aa>
argv[1] = <a>
argv[2] = <b>
argv[1] = <a>
argv[2] = <b>
argv[1] = <a>
argv[2] = <b>
argv[3] = <a>
argv[4] = <b>
argv[1] = <a+b>
argv[2] = <a+b>
argv[1] = <a>
argv[2] = <b>
argv[3] = <a>
argv[4] = <b>
argv[1] = <b>
argv[2] = <a>
argv[1] = <b>
argv[2] = <a>
argv[1] = <b>
argv[2] = <a>
argv[1] = <b+a>
7
7
declare -A A=([$'\t']="2" [" "]="2" )
declare -A A=([$'\t']="2" ["*"]="2" [" "]="2" ["]"]="2" ["@"]="2" )
declare -A A=([$'\t']="2" ["*"]="2" [" "]="2" ["]"]="2" ["@"]="2" )
./array27.sub: line 52: read: `A[]]': not a valid identifier
declare -A A=([$'\t']="X" ["*"]="X" [" "]="X" ["@"]="X" )
./array27.sub: line 60: printf: `A[]]': not a valid identifier
declare -A A=([$'\t']="X" ["*"]="X" [" "]="X" ["@"]="X" )
./array27.sub: line 68: declare: `A[]]=X': not a valid identifier
declare -A A=(["*"]="X" ["@"]="X" )
./array27.sub: line 76: declare: `A[]]=X': not a valid identifier
declare -A A=(["*"]="X" ["@"]="X" )
declare -a bug4=([0]="" [1]="5" [2]="" [3]="1" [4]="")
declare -a bug=([0]="" [1]="5" [2]="" [3]="1" [4]="")
declare -a bug2=([0]="")
declare -a bug3=([0]="" [1]="5" [2]="" [3]="1" [4]="")
declare -a not_bug=([0]="no" [1]="nulls")
declare -a workaround=([0]="")
declare -a var=([0]=$'\001\001\001\001')
declare -A v2=([$'\001']=$'ab\001c' )
declare -a foo=([0]=$'\001\001\001\001')
declare -A foo=([$'\001']=$'ab\001c' )
declare -a foo=([0]=$'\001\001\001\001')
declare -a foo=([0]=$'\001\001\001\001')
declare -A foo=([v]=$'\001\001\001\001' )
declare -A foo=([v]=$'\001\001\001\001' )
declare -A foo=([$'\001']=$'ab\001c' )
declare -A foo=([$'\001']=$'ab\001c' )
foo
declare -a a=([42]="foo")
foo
declare -a a=([42]="foo")
7
declare -ai a=([42]="7")
42
declare -ai a=([42]="42")
FOO
declare -Au A=([Darwin]="FOO" )
FOO
declare -Au A=(["@"]="FOO" )

429
tests/array.tests Normal file
View file

@ -0,0 +1,429 @@
# 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/>.
#
# this is needed so that the bad assignments (b[]=bcde, for example) do not
# cause fatal shell errors when in posix mode
set +o posix
set +a
# The calls to egrep -v are to filter out builtin array variables that are
# automatically set and possibly contain values that vary.
# first make sure we handle the basics
x=()
echo ${x[@]}
unset x
# this should be an error
test=(first & second)
echo $?
unset test
# make sure declare -a converts an existing variable to an array
unset a
a=abcde
declare -a a
echo ${a[0]}
if [ "$a" != "${a[0]}" ]; then
echo 'array.tests: $a and $a[0] array mismatch'
fi
unset a
a=abcde
a[2]=bdef
unset b
declare -a b[256]
unset c[2]
unset c[*]
a[1]=
_ENV=/bin/true
x=${_ENV[(_$-=0)+(_=1)-_${-%%*i*}]}
declare -r c[100]
echo ${a[0]} ${a[4]}
echo ${a[@]}
echo ${a[*]}
# this should print out values, too
declare -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
unset a[7]
echo ${a[*]}
unset a[4]
echo ${a[*]}
echo ${a}
echo "${a}"
echo $a
unset a[0]
echo ${a}
echo ${a[@]}
a[5]="hello world"
echo ${a[5]}
echo ${#a[5]}
echo ${#a[@]}
a[4+5/2]="test expression"
declare a["7 + 8"]="test 2"
a[7 + 8]="test 2"
echo ${a[@]}
readonly a[5]
readonly a
# these two lines should output `declare' commands
readonly -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
declare -ar | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
# this line should output `readonly' commands, even for arrays
set -o posix
readonly -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
set +o posix
declare -a d='([1]="" [2]="bdef" [5]="hello world" "test")'
d[9]="ninth element"
declare -a e[10]=test # this works in post-bash-2.05 versions
declare -a e[10]='(test)'
pass=/etc/passwd
declare -a f='("${d[@]}")'
b=([0]=this [1]=is [2]=a [3]=test [4]="$PS1" [5]=$pass)
echo ${b[@]:2:3}
declare -pa | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
a[3]="this is a test"
b[]=bcde
b[*]=aaa
echo ${b[ ]}
c[-2]=4
echo ${c[-4]}
d[7]=(abdedfegeee)
d=([]=abcde [1]="test test" [*]=last [-65]=negative )
unset d[12]
unset e[*]
declare -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
ps1='hello'
unset ps1[2]
unset ${ps1[2]}
declare +a ps1
declare +a c
# the prompt should not print when using a here doc
read -p "array test: " -a rv <<!
this is a test of read using arrays
!
echo ${rv[0]} ${rv[4]}
echo ${rv[@]}
# the variable should be converted to an array when `read -a' is done
vv=1
read -a vv <<!
this is a test of arrays
!
echo ${vv[0]} ${vv[3]}
echo ${vv[@]}
unset vv
declare -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
export rv
#set
x[4]=bbb
x=abde
echo $x
echo ${x[0]}
echo ${x[4]}
echo efgh | ( read x[1] ; echo ${x[1]} )
echo wxyz | ( declare -a x ; read x ; echo $x ; echo ${x[0]} )
# Make sure that arrays can be used to save the positional parameters verbatim
set -- a 'b c' d 'e f g' h
ARGV=( [0]=$0 "$@" )
for z in "${ARGV[@]}"
do
echo "$z"
done
echo "$0"
for z in "$@"
do
echo "$z"
done
# do various pattern removal and length tests
XPATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:.:/sbin:/usr/sbin
xpath=( $( IFS=: ; echo $XPATH ) )
echo ${xpath[@]}
echo ${xpath[@]##*/}
echo ${xpath[0]##*/}
echo ${xpath[@]%%[!/]*}
echo ${xpath[0]%%[!/]*}
recho ${xpath##*/}
recho ${xpath%%[!/]*}
recho ${xpath[5]##*/}
recho ${xpath[5]%%[!/]*}
# let's try to make it a DOS-style path
zecho "${xpath[@]/\//\\}"
zecho "${xpath[@]//\//\\}"
zecho "${xpath[@]//[\/]/\\}"
# length of the first element of the array, since array without subscript
# is equivalent to referencing first element
echo ${#xpath} -- ${#xpath[0]}
# number of elements in the array
nelem=${#xpath[@]}
echo ${#xpath[@]} -- $nelem
# total length of all elements in the array, including space separators
xx="${xpath[*]}"
echo ${#xx}
# total length of all elements in the array
xx=$( IFS='' ; echo "${xpath[*]}" )
echo ${#xx}
unset xpath[nelem-1]
nelem=${#xpath[@]}
echo ${#xpath[@]} -- $nelem
# arrays and things that look like index assignments
array=(42 [1]=14 [2]=44)
array2=(grep [ 123 ] \*)
echo ${array[@]}
echo "${array2[@]}"
# arrays and implicit arithmetic evaluation
declare -i -a iarray
iarray=( 2+4 1+6 7+2 )
echo ${iarray[@]}
iarray[4]=4+1
echo ${iarray[@]}
# make sure assignment using the compound assignment syntax removes all
# of the old elements from the array value
barray=(old1 old2 old3 old4 old5)
barray=(new1 new2 new3)
echo "length = ${#barray[@]}"
echo "value = ${barray[*]}"
# make sure the array code behaves correctly with respect to unset variables
set -u
( echo ${#narray[4]} )
${THIS_SH} ./array1.sub
${THIS_SH} ./array2.sub
# some old bugs and ksh93 compatibility tests
${THIS_SH} ./array3.sub
# some compound assignment parsing problems that showed up in bash-3.1-release
${THIS_SH} ./array4.sub
set +u
cd ${TMPDIR:=/tmp}
touch 1=bar
foo=([10]="bar")
echo ${foo[0]}
rm 1=bar
cd $OLDPWD
foo=(a b c d e f g)
echo ${foo[@]}
# quoted reserved words are ok
foo=(\for \case \if \then \else)
echo ${foo[@]}
# quoted metacharacters are ok
foo=( [1]='<>' [2]='<' [3]='>' [4]='!' )
echo ${foo[@]}
# numbers are just words when not in a redirection context
foo=( 12 14 16 18 20 )
echo ${foo[@]}
foo=( 4414758999202 )
echo ${foo[@]}
# this was a bug in all versions of bash 2.x up to and including bash-2.04
declare -a ddd=(aaa
bbb)
echo ${ddd[@]}
# errors until post-bash-2.05a; now reserved words are OK
foo=(a b c for case if then else)
foo=(for case if then else)
# errors
metas=( <> < > ! )
metas=( [1]=<> [2]=< [3]=> [4]=! )
# various expansions that didn't really work right until post-bash-2.04
foo='abc'
echo ${foo[0]} ${#foo[0]}
echo ${foo[1]} ${#foo[1]}
echo ${foo[@]} ${#foo[@]}
echo ${foo[*]} ${#foo[*]}
foo=''
echo ${foo[0]} ${#foo[0]}
echo ${foo[1]} ${#foo[1]}
echo ${foo[@]} ${#foo[@]}
echo ${foo[*]} ${#foo[*]}
# new expansions added after bash-2.05b
x[0]=zero
x[1]=one
x[4]=four
x[10]=ten
recho ${!x[@]}
recho "${!x[@]}"
recho ${!x[*]}
recho "${!x[*]}"
# sparse array tests for code fixed in bash-3.0
unset av
av[1]='one'
av[2]=''
av[3]=three
av[5]=five
av[7]=seven
echo include null element -- expect one
echo ${av[@]:1:2} # what happens when we include a null element?
echo include unset element -- expect three five
echo ${av[@]:3:2} # what happens when we include an unset element?
echo start at unset element -- expect five seven
echo ${av[@]:4:2} # what happens when we start at an unset element?
echo too many elements -- expect three five seven
echo ${av[@]:3:5} # how about too many elements?
echo positive offset - expect five seven
echo ${av[@]:5:2}
echo negative offset to unset element - expect seven
echo ${av[@]: -2:2}
echo positive offset 2 - expect seven
echo ${av[@]: 6:2}
echo negative offset 2 - expect seven
echo ${av[@]: -1:2}
echo out-of-range offset
echo ${av[@]:12}
# parsing problems and other inconsistencies not fixed until post bash-3.0
unset x
declare -a x=(')' $$)
[ ${x[1]} -eq $$ ] || echo bad
unset x
declare -a x=(a b c d e)
echo ${x[4]}
z=([1]=one [4]=four [7]=seven [10]=ten)
echo ${#z[@]}
echo ${!z[@]}
unset x
declare -a x=(a \'b c\')
echo "${x[1]}"
unset x
declare -a x=(a 'b c')
echo "${x[1]}"
unset x
declare -a x=($0)
[ "${x[@]}" = $0 ] || echo double expansion of \$0
declare -a x=(\$0)
echo "${x[@]}"
unset A Z
Z='a b'
A=( X=$Z )
declare -p A
# tests for bash-3.1 problems
${THIS_SH} ./array5.sub
# tests for post-bash-3.2 problems, most fixed in bash-3.2 patches
${THIS_SH} ./array6.sub
${THIS_SH} ./array7.sub
${THIS_SH} ./array8.sub
${THIS_SH} ./array9.sub
${THIS_SH} ./array10.sub
${THIS_SH} ./array11.sub
${THIS_SH} ./array12.sub
${THIS_SH} ./array13.sub
${THIS_SH} ./array14.sub
${THIS_SH} ./array15.sub
${THIS_SH} ./array16.sub
${THIS_SH} ./array17.sub
${THIS_SH} ./array18.sub
${THIS_SH} ./array19.sub
${THIS_SH} ./array20.sub
${THIS_SH} ./array21.sub
${THIS_SH} ./array22.sub
${THIS_SH} ./array23.sub
${THIS_SH} ./array24.sub
${THIS_SH} ./array25.sub
${THIS_SH} ./array26.sub
${THIS_SH} ./array27.sub
${THIS_SH} ./array28.sub
${THIS_SH} ./array29.sub
${THIS_SH} ./array30.sub

1
tests/array1.sub Normal file
View file

@ -0,0 +1 @@
printf "%s\n" -a a=(a 'b c')

65
tests/array10.sub Normal file
View file

@ -0,0 +1,65 @@
# 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/>.
#
days=({Mon,Tues,Wednes,Thurs,Fri,Satur,Sun}day)
echo ${days[@]}
typeset -i count
count=0
echo ${days[${count}]}
echo ${days[$((count++))]}
echo ${days[$((count++))]}
count=0
echo ${days[count]}
echo ${days[count++]}
echo ${days[count++]}
count=0
echo ${days[$((count++))]/foo/bar}
echo ${days[$((count++))]/foo/bar}
echo ${days[$((count++))]/foo/bar}
count=0
echo ${days[count++]/foo/bar}
echo ${days[count++]/foo/bar}
echo ${days[count++]/foo/bar}
count=0
echo "${days[${count}],,}, ${days[$((count++))],,}, ${days[$((count++))],,}"
echo "${days[${count}],,}, ${days[$((count++))],,}, ${days[$((count++))],,}"
count=0
echo "${days[${count}],,}, ${days[$((count++))],,}, ${days[$((count++))],,}"
echo "${days[${count}]/foo/bar}, ${days[$((count++))]/foo/bar}, ${days[$((count++))]/foo/bar}"
count=0
echo ${days[$((count++))]:2}
echo ${days[$((count++))]:2}
echo ${days[$((count++))]:2}
count=0
echo ${days[count++]:2}
echo ${days[count++]:2}
echo ${days[count++]:2}
count=0
echo ${days[$((count++))]#?}
echo ${days[$((count++))]#?}
echo ${days[$((count++))]#?}
count=0
echo ${days[count++]#?}
echo ${days[count++]#?}
echo ${days[count++]#?}

48
tests/array11.sub Normal file
View file

@ -0,0 +1,48 @@
# 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/>.
#
# problems with associative array keys with ] and unbalanced [ ]
# fixed after bash-4.2
declare -A foo
foo=(["version[agent]"]=version.agent)
echo ${!foo[@]}
echo ${foo[@]}
unset foo
declare -A foo
foo["version[agent]"]=version.agent
echo ${!foo[@]}
echo ${foo[@]}
declare foo["foo[bar]"]=bowl
echo ${!foo[@]}
echo ${foo[@]}
declare -A array2["foo[bar]"]=bleh
array2["foobar]"]=bleh
array2["foo"]=bbb
echo ${!array2[@]}
echo ${array2[@]}
declare -A foo
foo=( ['ab]']=bar )
echo ${!foo[@]}
echo ${foo[@]}

34
tests/array12.sub Normal file
View file

@ -0,0 +1,34 @@
# 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/>.
#
# problems with fix for posix interp 217 introduced in bash-4.2
declare -ax array
array[$(( $( echo -n 1001 ) - 1001 ))]=1
echo ${array[0]}
echo ${array[@]}
unset 'array[0]'
array[$( echo -n 1001 ) - 1001 ]=1
echo ${array[0]}
unset 'array[0]'
array[$(( 1001 - $( echo -n 1001 ) ))]=1
echo ${array[0]}
array[$(( 1001 - $( echo -n 1001 ) ))]=1
echo ${array[0]}
unset 'array[0]'
array[1001 - $( echo -n 1001 )]=1
echo ${array[0]}

12
tests/array13.sub Normal file
View file

@ -0,0 +1,12 @@
func1(){
declare -g variable='function'
declare -g -a array=(function)
echo ${variable} ${array[@]}
}
declare -g variable='main'
declare -g -a array=(main)
echo ${variable} ${array[@]}
func1
echo ${variable} ${array[@]}

43
tests/array14.sub Normal file
View file

@ -0,0 +1,43 @@
# 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/>.
#
# start at a test suite for negative indexed array subscripts -- post bash-4.2
x=( 0 1 2 3 4 5)
declare -p x
unset 'x[-1]'
declare -p x
unset 'x[-2]'
declare -p x
unset 'x[-10]'
x[-2]=3
declare -p x
x+=( five )
declare -p x
x[-1]=5
declare -p x
x+=( [-1]=foo )
declare -p x
x[-1]=5
declare -p x
x[-2]+=four
declare -p x
echo "strlen(${x[-2]})" = ${#x[-2]}

52
tests/array15.sub Normal file
View file

@ -0,0 +1,52 @@
# 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/>.
#
# fixes for make_internal_declare not handling integer attribute for arrays
declare -ai -g foo=(1 2 xx 3)
echo "${foo[@]}"
unset foo
declare -ai -g foo='(1 2 xx 3)'
echo "${foo[@]}"
unset foo
declare -ia -g foo=(1 2 xx 3)
echo "${foo[@]}"
unset foo
declare -ia -g foo='(1 2 xx 3)'
echo "${foo[@]}"
unset foo
func()
{
declare -ai -g foo=(1 2 xx 3)
}
func
echo "${foo[@]}"
unset foo
# test options to declare that disable attributes that affect how values
# are expanded
#
# we already handle options that set attributes specially, so we should
# handle attributes that unset those attributes specially as well
unset arr
declare -i -a arr=(1+1 2+2 3+3)
declare -p arr
declare +i arr=(hello world)
declare -p arr

34
tests/array16.sub Normal file
View file

@ -0,0 +1,34 @@
# 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/>.
#
foo[0]=a
foo[1]=b
[[ -v foo[1] ]] && echo foo index 1: ok
[[ -v foo[2] ]] || echo foo index 2: ok
[[ -v foo ]] && echo foo: implicit reference to element 0: ok
typeset -i foo
[[ -v foo[1] ]] && echo foo: arithmetic evaluation: ok
typeset -a bar
bar[1]=set
[[ -v bar ]] || echo bar: array with element zero unset: ok
[[ -v bar[0] ]] || echo bar: element zero: ok
typeset -a qux
[[ -v qux ]] || echo qux: unset array: ok
[[ -v qux[0] ]] || echo qux: unset array element 0: ok

91
tests/array17.sub Normal file
View file

@ -0,0 +1,91 @@
# 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/>.
#
# this shows the expansions an array subscript undergoes before being run
# through the arithmetic evaluator
b=(0 1 2 3)
# array subscripts undergo variable expansion
a=2
echo ${b[$a]}
# array subscripts undergo command substitution
echo ${b[$(echo 2)]}
c='1+1'
d='1-+1'
# array subscripts are expanded and the expanded value is treated as an
# expression
echo ${b[$c]}
echo ${b[c]}
echo ${b[$d]}
echo ${b[d]}
# array subscripts undergo parameter expansion
set -- 1 2 3
echo ${b[$1]}
# array subscripts undergo tilde expansion
HOME=2
echo ${b[~]}
# array subscripts undergo word splitting -- bug in bash versions through 4.3
x='b[$d]'
IFS=-
echo $((x))
IFS=$' \t\n'
set -- 1 + 2
x='d'
IFS=-
echo $((x))
IFS=$' \t\n'
# start of quoting tests; make sure that subscript is treated as double
# quoted (inhibits word splitting) but that double quotes are silently
# discarded through quote removal
echo $(( $@ ))
echo "$(( $@ ))"
echo $(( "$x" ))
echo $(( "x" ))
unset a foo bar
a=(zero one two three four five six seven eight nine ten)
echo ${a[0]}
echo ${a["0"]}
foo=1
echo ${a[$foo]}
echo ${a["$foo"]}
echo ${a[foo]}
echo ${a["foo"]}
bar=2
echo ${a[" $bar "]}
echo ${a[" bar "]}
# tilde expansion is performed by array subscript expansion but not by posix
# style arithmetic expansion
HOME=2
echo $(( ~ ))

47
tests/array18.sub Normal file
View file

@ -0,0 +1,47 @@
# 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/>.
#
# arrays referenced using @ subscript and positional parameters should behave
# the same way
foo=(0 0 0); [[ -z ${foo[@]#0} ]]; echo $?
recho "${foo[@]#0}"
bar=${foo[@]#0}
recho bar
recho $bar
recho -$bar-
recho "$bar"
qux="${foo[@]#0}"
recho qux
recho $qux
recho -$qux-
recho "$qux"
unset foo qux bar
set -- 0 0 0
recho "${@#0}"
bar=${@#0}
recho bar
recho $bar
recho -$bar-
recho "$bar"
qux="${@#0}"
recho qux
recho $qux
recho -$qux-
recho "$qux"

175
tests/array19.sub Normal file
View file

@ -0,0 +1,175 @@
# 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/>.
#
# tests for changes to declare and assignment statement arguments post-bash-4.3
unset foo l a b
l="( zeroind )"
unset foo
declare -a foo
foo="$l"
declare -p foo
unset foo
declare -a foo="$l"
declare -p foo
unset foo
declare -a foo=$l
declare -p foo
b='[0]=bar'
unset foo
declare -a foo="$b"
declare -p foo
unset foo
declare -a foo=("$b")
declare -p foo
unset foo
declare -a foo=($b)
declare -p foo
unset a
declare a='(1 2 3)'
declare -p a
unset a
declare -a a
declare a='(1 2 3)'
declare -p a
unset a
declare a='([0]=a [1]=b)'
declare -p a
unset a
declare -a a
declare a='([0]=a [1]=b)'
declare -p a
unset a
declare -A a
declare a='([0]=a [1]=b)'
declare -p a
unset a
unset var value
value='[$(echo total 0)]=1 [2]=2]'
unset var
declare -a var
var=($value)
declare -p var
unset var
declare -a var=("$value")
declare -p var
unset var
declare -a var=($value)
declare -p var
unset var
declare -a var="($value)"
declare -p var
unset foo value
value="AbCdE"
declare -a foo
foo=( one two three )
declare -l foo="$value"
declare -p foo
unset foo
value='(AbCdE)'
declare -a foo
foo=( one two three )
declare -l foo="$value"
declare -p foo
unset ar
declare -a ar=(ONE TWO THREE)
declare -al ar=(${ar[@]})
declare -p ar
unset a
declare -a a
a[2]=foo
declare -p a
unset a
declare -a a
declare a[2]=foo
declare -p a
declare a[1]='(var)'
declare -p a
unset a
declare a[1]='(var)'
declare -p a
unset a
a=(1 2 3)
a[2]='(1 2 3)'
declare -p a
unset a
a=(1 2 3)
declare a[2]='(1 2 3)'
declare -p a
unset a
a=(1 2 3)
declare a='(1 2 3)'
declare -p a
unset a
a=(1 2 3)
declare 'a=(1 2 3)'
declare -p a
unset a
declare -a a='(1 2 3)'
declare -p a
unset a b c d e x y
HOME=/scratch/bash
x='a b'
y='($(echo Darwin))'
declare a=$x b=~ c='(1 2)' d='($a)' e=$y
declare -p a b c d e
unset a b c d e
declare -a a=$x b=~ c='(1 2)' d='($a)' e=$y
declare -p a b c d e
unset a b c d e
declare -A a=$x b=~ c='(1 2)' d='($a)' e=$y
declare -p a b c d e

74
tests/array2.right Normal file
View file

@ -0,0 +1,74 @@
argv[1] = <a b>
argv[1] = <ab>
argv[1] = <a b>
argv[1] = <a>
argv[2] = <b>
argv[1] = <a>
argv[2] = <b>
argv[1] = <3>
argv[1] = <bob>
argv[1] = <tom dick harry>
argv[1] = <joe>
argv[1] = <3>
argv[1] = <bob>
argv[1] = <tom dick harry>
argv[1] = <joe>
argv[1] = <3>
argv[1] = <bob>
argv[1] = <tom dick harry>
argv[1] = <joe>
argv[1] = <3>
argv[1] = <bob>
argv[1] = <tom dick harry>
argv[1] = <joe>
argv[1] = <1>
argv[1] = <bobtom dick harryjoe>
argv[1] = <3>
argv[1] = <bob>
argv[1] = <tom dick harry>
argv[1] = <joe>
argv[1] = <3>
argv[1] = <bob>
argv[1] = <tom dick harry>
argv[1] = <joe>
argv[1] = <5>
argv[1] = <bob>
argv[1] = <tom>
argv[1] = <dick>
argv[1] = <5>
argv[1] = <bob>
argv[1] = <tom>
argv[1] = <dick>
argv[1] = <1>
argv[1] = <bob>
argv[2] = <tom>
argv[3] = <dick>
argv[4] = <harry>
argv[5] = <joe>
argv[1] = <3>
argv[1] = <bob>
argv[1] = <tom>
argv[2] = <dick>
argv[3] = <harry>
argv[1] = <joe>
argv[1] = <a>
argv[2] = <b>
argv[3] = <c>
argv[4] = <d>
argv[5] = <e>
argv[1] = <a>
argv[2] = <b>
argv[3] = <c>
argv[4] = <d>
argv[5] = <e>
argv[1] = <foo>
argv[2] = <bar>
argv[3] = <bam>
argv[1] = <foobarbam>
argv[1] = <foo>
argv[2] = <bar>
argv[3] = <bam>
argv[1] = <foo>
argv[2] = <bar>
argv[3] = <bam>
argv[1] = <foo bar bam>

4
tests/array2.sub Normal file
View file

@ -0,0 +1,4 @@
declare -r []=asdf
declare -r a[]=asdf
declare -a ''=(a 'b c')

47
tests/array20.sub Normal file
View file

@ -0,0 +1,47 @@
# 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/>.
#
# tests to make sure that $* and ${array[*]} expand consistently in `list'
# and `scalar' contexts
arr=(a b c)
IFS=+
# these two should both expand to `+' separated strings
a=${arr[*]} ; echo "$a"
b=${arr[*]/a/x}; echo "$b"
set -- a b c
# these two should both expand to `+' separated strings
a=${*} ; echo "$a"
b=${*/a/x}; echo "$b"
# these two should both expand to `+' separated strings and it should handle
# characters in IFS as chars in the string
unset a b
set -- 'a+b' 'c+d' 'e+f'
a=${*} ; recho "$a"
b=${*/a/x}; recho "$b"
# now let's make sure that @ always uses space separators even in contexts
# where we don't do word splitting
set -- a b c
a=${@} ; echo "$a"
b=${@/a/x}; echo "$b"
unset a b
a=${arr[@]} ; echo "$a"
b=${arr[@]/a/x}; echo "$b"

50
tests/array21.sub Normal file
View file

@ -0,0 +1,50 @@
# 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/>.
#
typeset -a a
a=(1 2 3 4)
typeset -A A
A=([one]=1 [two]=2 [three]=3 [four]=4)
unset 'a[0]'
typeset -p a
scalar=abcd
echo ${scalar[0]}
unset 'scalar[0]'
echo ${scalar-unset}
unset 'a[@]'
typeset -p a
unset 'A[@]'
typeset -p A
typeset -a a
a=(1 2 3 4)
typeset -A A
A=([one]=1 [two]=2 [three]=3 [four]=4)
# supported, recommended way to unset all array elements
a=()
typeset -p a
A=()
typeset -p A
declare -a foo
declare foo='(1 2 3)'
declare foo[1]='(4 5 6)'
declare -p foo

59
tests/array22.sub Normal file
View file

@ -0,0 +1,59 @@
# 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/>.
#
# This isn't perfect behavior, but it establishes a baseline and will provide
# a way to detect behavior changes
echo a1
a[0]= a[1]=; recho "${a[@]:-y}"
unset a
echo a2
a[1]=; recho "${a[@]:-y}"
a[1]=; recho "${a[*]:-z}"
unset a
echo a3
a[0]= a[1]=x; recho "${a[@]:-y}"
unset a
echo a4
a[0]= a[1]=x; recho ${a[@]:+y}
unset a
echo p1
set '' ''
recho "${@:-y}"
shift $#
echo p2
set '' x
recho "${@:-y}"
shift $#
echo p3
set '' x
recho ${@:+y}
# problems with * and null expansions dating back to bash's earliest days
A=(''); set -- ''
echo "<${A[*]:-X}>" "<${*:-X}>" "<${A:-X}>" "<${A[0]:-X}>"
IFS=
A=('' ''); set -- '' ''
B=''
echo "<${A[*]:-X}>" "<${*:-X}>" "<${B:-X}>" "<${B[*]:-X}>"

41
tests/array23.sub Normal file
View file

@ -0,0 +1,41 @@
# 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/>.
#
# this captures how bash and ksh93 expand indexed array subscripts in
# various contexts. if changes are ever made, or an option added to do
# this differently, the diffs will show up here
typeset -a array
index='$( echo >&2 foo )' # Literal shell code should never be evaluated unless an 'eval' is involved.
echo ${array[ $index ]} # [] expands $index, results in a literal that [] does not re-evaluate.
echo $(( $index )) # (( )) expands $index, results in a literal that (( )) does not re-evaluate.
echo $(( array[ $index ] )) # (( )) expands $index, results in a literal that [] DOES re-evaluate.
(( array[ $index ] ))
typeset -a a
: $(( a[$index]=5 ))
#shopt -s assoc_expand_once
echo $((1+a[$index]))
echo $((1+a[\$index]))
echo "1+${a[$index]}"
# intermediate problems discovered while bash-5.0 was in testing
a=0
echo $(( a[a[0]] ))
echo ${a[a[a[0]]]}
echo $(( a[a[a[0]]] ))

60
tests/array24.sub Normal file
View file

@ -0,0 +1,60 @@
# 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/>.
#
set -- "abc" "def ghi" "jkl"
A=("$@")
IFS=':'
echo 'IFS=: ${var-$*}'
unset var; printf '%s\n' ${var-$*}
printf '%s\n' ${var-${A[*]}}
echo "----"
echo 'IFS=: ${var=$*}'
unset var; printf '%s\n' ${var=$*}
printf 'var=%s\n' "$var"
unset var; printf '%s\n' ${var=${A[*]}}
printf 'var=%s\n' "$var"
echo "----"
echo 'IFS=: ${var+$*}'
printf '%s\n' ${var+$*}
printf '%s\n' ${var+${A[*]}}
echo "----"
echo 'IFS= ${var-$*}'
IFS=''
unset var; printf '%s\n' ${var-$*}
unset var; printf '%s\n' ${var-${A[*]}}
echo "----"
echo 'IFS= ${var=$*}'
unset var
printf '%s\n' ${var=$*}
printf 'var=%s\n' "$var"
unset var
printf '%s\n' ${var=${A[*]}}
printf 'var=%s\n' "$var"
echo "----"
echo 'IFS= ${var+$*}'
printf '%s\n' ${var+$*}
printf '%s\n' ${var+${A[*]}}

83
tests/array25.sub Normal file
View file

@ -0,0 +1,83 @@
# 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/>.
#
# tests with blank subscripts, indexed and associative
echo 1. indexed:
a[0]=0 a[1]=1
v=" "
echo reference:
echo 1. ${a[ ]}
echo 2. ${a[' ']}
echo 3. "${a[ ]}"
echo 4. ${a[$v]}
echo 5. ${a["$v"]}
echo 6. "${a[$v]}"
echo assignment:
echo -n 1. ; a[ ]=10 ; typeset -p a ; a[0]=0
echo -n 2. ; a[" "]=11 ; typeset -p a ; a[0]=0
echo -n 3. ; a[$v]=12 ; typeset -p a ; a[0]=0
echo -n 4. ; a["$v"]=13 ; typeset -p a ; a[0]=0
echo arithmetic:
echo -n 1. ; (( a[ ]=10 )); typeset -p a ; a[0]=0
echo -n 2. ; (( a[" "]=11 )); typeset -p a ; a[0]=0
echo -n 3. ; (( a[$v]=12 )); typeset -p a ; a[0]=0
echo -n 4. ; (( a["$v"]=13 )); typeset -p a ; a[0]=0
echo -n 5. ; let "a[ ]=10" ; typeset -p a ; a[0]=0
echo -n 6. ; let "a[\" \"]=11" ; typeset -p a ; a[0]=0
echo -n 7. ; let "a[$v]=12" ; typeset -p a ; a[0]=0
echo -n 8. ; let "a[\"$v\"]=13" ; typeset -p a ; a[0]=0
unset -v a v
echo 2. associative:
shopt -s assoc_expand_once
typeset -A a
a[0]=0 a[1]=1
v=" "
echo reference:
echo 1. ${a[ ]}
echo 2. ${a[' ']}
echo 3. "${a[ ]}"
echo 4. ${a[$v]}
echo 5. ${a["$v"]}
echo 6. "${a[$v]}"
echo assignment:
echo -n 1. ; a[ ]=10 ; typeset -p a ; a[0]=0
echo -n 2. ; a[" "]=11 ; typeset -p a ; a[0]=0
echo -n 3. ; a[$v]=12 ; typeset -p a ; a[0]=0
echo -n 4. ; a["$v"]=13 ; typeset -p a ; a[0]=0
echo arithmetic:
echo -n 1. ; (( a[ ]=10 )); typeset -p a ; a[0]=0
echo -n 2. ; (( a[" "]=11 )); typeset -p a ; a[0]=0
echo -n 3. ; (( a[$v]=12 )); typeset -p a ; a[0]=0
echo -n 4. ; (( a["$v"]=13 )); typeset -p a ; a[0]=0
echo -n 5. ; let "a[ ]=10" ; typeset -p a ; a[0]=0
echo -n 6. ; let "a[\" \"]=11" ; typeset -p a ; a[0]=0
echo -n 7. ; let "a[$v]=12" ; typeset -p a ; a[0]=0
echo -n 8. ; let "a[\"$v\"]=13" ; typeset -p a ; a[0]=0

131
tests/array26.sub Normal file
View file

@ -0,0 +1,131 @@
# 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/>.
#
# these should produce the same results
a=(aa bb)
set -- aa bb
IFS=+
recho ${a[@]}
recho ${a[@]:0}
recho $@
recho ${@:1}
A=${a[*]} B=${a[*]:0}
recho $* ${*:1}
recho ${a[*]} ${a[*]:0}
recho "$A" "$B"
recho $A $B
unset A B
recho ${@/a/x}
recho ${a[@]/a/x}
recho "${@/a/x}"
recho "${a[@]/a/x}"
recho ${*/a/x}
recho ${a[*]/a/x}
recho "${*/a/x}"
recho "${a[*]/a/x}"
A=${*/a/x}
B=${a[*]/a/x}
recho "$A" "$B"
unset A B
declare -A A
A[0]=aa
A[1]=bb
recho ${A[@]/a/x}
recho "${A[@]/a/x}"
recho ${A[*]/a/x}
recho "${A[*]/a/x}"
unset A
IFS=
recho ${@/a/x}
recho ${a[@]/a/x}
recho "${@/a/x}"
recho "${a[@]/a/x}"
recho ${*/a/x}
recho ${a[*]/a/x}
recho "${*/a/x}"
recho "${a[*]/a/x}"
A=${*/a/x}
B=${a[*]/a/x}
recho "$A" "$B"
unset A B
declare -A A
A[0]=aa
A[1]=bb
recho ${A[@]/a/x}
recho "${A[@]/a/x}"
recho ${A[*]/a/x}
recho "${A[*]/a/x}"
unset A
IFS=+
recho ${a[@]}
recho ${a[@],,}
recho "${a[@]}"
recho "${a[@],,}"
A=${a[*]} B=${a[*],,}
recho $* ${*,,}
recho ${a[*]} ${a[*],,}
recho "${a[*]}" "${a[*],,}"
recho "$A" "$B"
recho $A $B
unset A B
declare -A A
A[0]=aa
A[1]=bb
recho ${A[@],,}
recho "${A[@],,}"
recho ${A[*],,}
recho "${A[*],,}"
unset A
recho ${a[@]#?}
recho ${@#?}
A=${a[*]#?} B=${a[*]#?}
recho ${*#?} ${a[*]#?}
recho "$A" "$B"
recho $A $B
unset A B
declare -A A
A[0]=aa
A[1]=bb
recho ${A[@]#?}
recho "${A[@]#?}"
recho ${A[*]#?}
recho "${A[*]#?}"

78
tests/array27.sub Normal file
View file

@ -0,0 +1,78 @@
# 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/>.
#
# tests for `problem' keys when using associative arrays and assoc_expand_once
# deal with problems for now; this is a placeholder for if and when I fix them
typeset -A a
shopt -s assoc_expand_once
k='['
echo $(( a[$k]=7 ))
k=']'
echo $(( a[$k]=7 ))
unset a
declare -A A
for k in $'\t' ' '; do
(( A[$k]=2 ))
done
declare -p A
for k in ']' '*' '@'; do
(( A[$k]=2 ))
done
declare -p A
unset A
declare -A A
for k in ']' '*' '@' $'\t' ' '; do
A[$k]=2
done
declare -p A
unset A
declare -A A
for k in $'\t' ' ' ']' '*' '@'; do
read "A[$k]" <<< X
done
declare -p A
unset A
declare -A A
for k in $'\t' ' ' ']' '*' '@'; do
printf -v "A[$k]" "%s" X
done
declare -p A
unset A
declare -A A
for k in ']' '*' '@'; do
declare A[$k]=X
done
declare -p A
unset A
declare -A A
for k in ']' '*' '@'; do
declare "A[$k]=X"
done
declare -p A

30
tests/array28.sub Normal file
View file

@ -0,0 +1,30 @@
# 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/>.
#
# tests for assigning empty string array elements without subscripts
function foo()
{
local bug=("" "5" "" 1 "")
declare -a bug2=("")
declare -ga bug3=("" "5" "" 1 "")
local not_bug=("no" "nulls")
local workaround; workaround=("")
declare -p bug bug2 bug3 not_bug workaround
}
declare -a bug4=("" "5" "" 1 "")
declare -p bug4
foo

86
tests/array29.sub Normal file
View file

@ -0,0 +1,86 @@
# 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/>.
#
# Issues with CTLESC characters in array subscripts and values. Bash-5.1 and
# earlier didn't quote them correctly and therefore halved the number of
# CTLESCs.
declare -a var
var=( $'\x01\x01\x01\x01' )
declare -p var
declare -A v2
v2=( $'\x01' ab$'\x01'c )
declare -p v2
pv()
{
local -a foo
foo=( "${var[@]}" )
declare -p foo
}
pv
unset -f pv
pv()
{
local -A foo
eval foo=\( "${v2[@]@k}" \)
declare -p foo
}
pv
# these are wrong through bash-5.1; there is a fix tagged for bash-5.2
# when I uncomment that fix, these results will reflect it
pv1()
{
local -a foo=( "${var[@]}" )
declare -p foo
}
pv1
pv2()
{
local -a foo=( [0]="${var[@]}" )
declare -p foo
}
pv2
pv3()
{
local -A foo=( v "${var[@]}" )
declare -p foo
}
pv3
pv4()
{
local -A foo=( [v]="${var[@]}" )
declare -p foo
}
pv4
unset -f pv3 pv4
pv3()
{
local -A foo=( $'\x01' "${v2[@]}" )
declare -p foo
}
pv3
pv4()
{
local -A foo=( [$'\x01']="${v2[@]}" )
declare -p foo
}
pv4

9
tests/array3.sub Normal file
View file

@ -0,0 +1,9 @@
a=(0 1 2 3 4 5 6 7 8 9)
echo ${a[@]: -1}
echo ${a[@]:9}
echo ${a[@]:10}
echo ${a[@]:11}
echo ${a[@]:7:3}

46
tests/array30.sub Normal file
View file

@ -0,0 +1,46 @@
# 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/>.
#
declare -a a
a=()
echo ${a[42]=foo}
declare -p a
a=()
echo ${a[$(echo 42)]=foo}
declare -p a
unset a
declare -ai a
a=()
echo ${a[42]=4+3}
declare -p a
a=()
echo ${a[$(echo 42)]=42}
declare -p a
unset a
declare -A A
declare -u A
A=()
echo ${A[$(echo Darwin)]=foo}
declare -p A
A=()
echo ${A[@]:=foo}
declare -p A

45
tests/array4.sub Normal file
View file

@ -0,0 +1,45 @@
# 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/>.
#
# compound assignment parsing problems in bash-3.1-release
func()
{
local -a x=() y=()
}
a=() b=()
eval foo=()
eval foo=() bar=() qux=( "bash" )
foo=( "bash" )
eval foo=( "bash" )
eval bar=( "bash" ) bax=( "bash" )
let a=(5 + 3) b=(4 + 7)
echo $a $b
typeset -i a b
a=(5+3) b=(4+7)
echo $a $b
let a=(4*3)/2
echo $a
a=(4*3)/2
echo $a
LNAME=nordholz
echo ${LNAME}
echo ${#LNAME}
echo ${#LNAME[$(( 0 ))]}
echo ${#LNAME[$(( 0+0 ))]}

47
tests/array5.sub Normal file
View file

@ -0,0 +1,47 @@
# 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/>.
#
: ${TMPDIR:=/tmp}
mkdir $TMPDIR/bash-test-$$
cd $TMPDIR/bash-test-$$
trap "cd $OLDPWD ; rm -rf $TMPDIR/bash-test-$$" 0 1 2 3 6 15
touch '[3]=abcde'
touch r s t u v
declare -a x=(*)
echo ${x[3]}
echo ${x[@]}
unset x
x=(a b c d e)
echo ${x[*]: -1}
unset x[4]
unset x[2]
x[9]='9'
echo ${x[*]: -1}
TOOLKIT=(1 2 3 4 5 6 7 8 9 10)
ARRAY="1"
echo ${TOOLKIT["$ARRAY"]}
exit 0

128
tests/array6.sub Normal file
View file

@ -0,0 +1,128 @@
# 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/>.
#
# test cases for array quoting and escaping fixed post bash-3.2-release
oIFS="$IFS"
a=(a b c)
echo ${a[@]}
a2=("${a[@]/#/"-iname '"}")
recho "${a2[@]}"
echo "${dbg-"'hey'"}"
echo "${dbg-"hey"}"
echo "${dbg-'"'hey}"
echo "${dbg-'"hey'}"
unset a a2
IFS=
a2=(${a[@]/#/"-iname '"})
recho "${a2[@]}"
IFS="$oIFS"
unset a a2
a=('a b' 'c d' 'e f')
recho ${a[@]:1:2}
recho "${a[@]:1:2}"
IFS=
recho ${a[@]:1:2}
recho "${a[@]:1:2}"
IFS="$oIFS"
unset a a2
a=(abc def)
# Prevent word splitting
#IFS=
a2=("${a[@]/#/"-iname '"}")
recho "${a2[@]}"
eval a2=("${a[@]/#/\"-iname \'\"}")
recho "${a2[@]}"
eval a2=("${a[@]/#/"-iname '"}")
recho "${a2[@]}"
a2=("${a[@]/#/-iname \'}")
recho "${a2[@]}"
eval a2=("${a[@]/#/-iname \'}")
recho "${a2[@]}"
set -- abc def
a2=("${@/#/"-iname '"}")
recho "${a2[@]}"
eval a2=("${@/#/\"-iname \'\"}")
recho "${a2[@]}"
eval a2=("${@/#/"-iname '"}")
recho "${a2[@]}"
unset a a2
IFS=
pat=('*.*')
case $(ls ${pat[@]} 2>/dev/null) in
'') echo '*.* BAD' ;;
*) echo '*.* OK' ;;
esac
IFS="$oIFS"
unset a a2 pat
IFS=
s='abc'
set - ${s/b/1 2 3}
echo $#
echo "$1"
IFS="$oIFS"
unset s
set -- ab cd ef
foo="var with spaces"
IFS=
recho $foo
recho "$foo"
recho ${foo}"$@"
recho ${foo}$@
array=(ab cd ef)
recho ${foo}"${array[@]}"
recho ${foo}${array[@]}
recho $(echo $foo)"$@"
recho $(echo $foo)$@
a=('word1 with spaces' 'word2 with spaces')
set - ${a[@]/word/element}
echo $#
recho "$@"
recho $@
IFS="$oIFS"
unset a a2 array foo

14
tests/array7.sub Normal file
View file

@ -0,0 +1,14 @@
# these didn't work in versions of bash before bash-4.0
LNAME=nordholz
echo ${LNAME[$(( 0 ))]//h/!}
echo ${LNAME[$(( 2 ))]//h/!}
echo ${LNAME[$(( 0 ))]##??}
echo ${LNAME[$(( 2 ))]##??}
echo ${LNAME[$(( 0 ))]:2}
echo ${LNAME[$(( 0 ))]:2:4}
echo ${LNAME[$(( 2 ))]:2}
echo ${LNAME[$(( 2 ))]:2:4}

36
tests/array8.sub Normal file
View file

@ -0,0 +1,36 @@
# 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/>.
#
IFS=/
declare -a i
i[0]=fooq
i[1]=
i[2]=barq
i[3]=
recho "${i[*]:0}"
recho "${i[@]:0}"
recho "${i[*]/q/!}"
recho "${i[@]/q/!}"
recho "${i[*]#?}"
recho "${i[@]#?}"
# Need to complete this with case-modifying expansion examples
recho "${i[*]^?}"
recho "${i[@]^?}"
recho "${i[*]^^?}"
recho "${i[@]^^?}"

40
tests/array9.sub Normal file
View file

@ -0,0 +1,40 @@
# 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/>.
#
echo $(( 0x7e ))
echo $(( 0x7f ))
echo $(( 0x80 ))
a=$'\x80'
recho "$a"
a=( $'\x7e' $'\x7f' $'\x80' )
recho "${a[@]}"
unset a
a[0]=$'\x7e'
a[1]=$'\x7f'
a[2]=$'\x80'
recho "${a[@]}"
b1=$'\x7e'
b2=$'\x7f'
b3=$'\x80'
unset a
a=( "$b1" "$b2" "$b3" )
recho "${a[@]}"

400
tests/assoc.right Normal file
View file

@ -0,0 +1,400 @@
declare -A BASH_ALIASES=()
declare -A BASH_CMDS=()
declare -A fluff
declare -A BASH_ALIASES=()
declare -A BASH_CMDS=()
declare -A fluff=([foo]="one" [bar]="two" )
declare -A fluff=([foo]="one" [bar]="two" )
declare -A fluff=([bar]="two" )
declare -A fluff=([qux]="assigned" [bar]="newval" )
./assoc.tests: line 39: chaff: four: must use subscript when assigning associative array
declare -A BASH_ALIASES=()
declare -A BASH_CMDS=()
declare -Ai chaff=([one]="10" [zero]="5" )
declare -Ar waste=([pid]="42134" [lineno]="41" [source]="./assoc.tests" [version]="4.0-devel" )
declare -A wheat=([two]="b" [three]="c" [one]="a" [zero]="0" )
declare -A chaff=(["hello world"]="flip" [one]="10" [zero]="5" )
./assoc.tests: line 51: waste: readonly variable
./assoc.tests: line 52: unset: waste: cannot unset: readonly variable
declare -A chaff=(["*"]="12" ["hello world"]="flip" [one]="a" )
flip
argv[1] = <multiple>
argv[2] = <words>
argv[3] = <12>
argv[4] = <flip>
argv[5] = <a>
argv[1] = <multiple words>
argv[2] = <12>
argv[3] = <flip>
argv[4] = <a>
argv[1] = <multiple>
argv[2] = <words>
argv[3] = <12>
argv[4] = <flip>
argv[5] = <a>
argv[1] = <multiple words 12 flip a>
./assoc.tests: line 71: declare: chaff: cannot destroy array variables in this way
declare -A wheat=([six]="6" ["foo bar"]="qux qix" )
argv[1] = <qux>
argv[2] = <qix>
argv[1] = <qux qix>
declare -A wheat=([six]="6" ["foo bar"]="qux qix" )
argv[1] = <2>
argv[1] = <7>
argv[1] = <qux>
argv[2] = <qix>
argv[3] = <blat>
argv[1] = <qux qix blat>
argv[1] = <16>
argv[1] = <16>
argv[1] = <6>
argv[2] = <flix>
argv[1] = <six>
argv[2] = <foo>
argv[3] = <bar>
argv[1] = <six>
argv[2] = <foo bar>
8
/usr/local/bin /bin . /usr/bin /usr/ucb /usr/sbin /bin /sbin
bin bin . bin ucb sbin bin sbin
bin
/ / / / / / /
/
argv[1] = <bin>
argv[1] = </>
argv[1] = <sbin>
argv[1] = </>
8
/usr/local/bin /bin . /usr/bin /usr/ucb /usr/sbin /bin /sbin
bin bin . bin ucb sbin bin sbin
/ / / / / / /
8
4 -- /bin
^usr^local^bin ^bin . ^usr^bin ^usr^ucb ^usr^sbin ^bin ^sbin
^usr^local^bin ^bin . ^usr^bin ^usr^ucb ^usr^sbin ^bin ^sbin
\usr/local/bin \bin . \usr/bin \usr/ucb \usr/sbin \bin \sbin
\usr\local\bin \bin . \usr\bin \usr\ucb \usr\sbin \bin \sbin
\usr\local\bin \bin . \usr\bin \usr\ucb \usr\sbin \bin \sbin
([a]=1)
foo qux
/usr/sbin/foo /usr/local/bin/qux
hits command
0 /usr/sbin/foo
0 /bin/sh
0 /sbin/blat
0 /usr/local/bin/qux
foo sh blat qux
/usr/sbin/foo /bin/sh /sbin/blat /usr/local/bin/qux
foo qux
argv[1] = </usr/sbin/foo>
argv[2] = </usr/local/bin/qux>
argv[3] = <-l>
alias blat='cd /blat ; echo $PWD'
alias foo='/usr/sbin/foo'
alias qux='/usr/local/bin/qux -l'
alias sh='/bin/bash --login -o posix'
blat foo sh qux
argv[1] = <cd /blat ; echo $PWD>
argv[2] = </usr/sbin/foo>
argv[3] = </bin/bash --login -o posix>
argv[4] = </usr/local/bin/qux -l>
outside: outside
declare -A BASH_ALIASES=()
declare -A BASH_CMDS=()
declare -A afoo=([six]="six" ["foo bar"]="foo quux" )
argv[1] = <inside:>
argv[2] = <six>
argv[3] = <foo quux>
outside 2: outside
argv[1] = </barq//fooq>
argv[1] = <>
argv[2] = <barq>
argv[3] = <>
argv[4] = <fooq>
argv[1] = </bar!//foo!>
argv[1] = <>
argv[2] = <bar!>
argv[3] = <>
argv[4] = <foo!>
argv[1] = </arq//ooq>
argv[1] = <>
argv[2] = <arq>
argv[3] = <>
argv[4] = <ooq>
argv[1] = </Barq//Fooq>
argv[1] = <>
argv[2] = <Barq>
argv[3] = <>
argv[4] = <Fooq>
argv[1] = </BARQ//FOOQ>
argv[1] = <>
argv[2] = <BARQ>
argv[3] = <>
argv[4] = <FOOQ>
abc
def
def
./assoc5.sub: line 26: declare: `myarray[foo[bar]=bleh': not a valid identifier
def bleh abc
myarray=(["]"]="def" [foo]="bleh" ["a]a"]="abc" ["a]=test1;#a"]="123" )
123
myarray=(["]"]="def" ["a]=test2;#a"]="def" [foo]="bleh" ["a]a"]="abc" ["a]=test1;#a"]="123" )
bar"bie
doll
declare -A foo=(["bar\"bie"]="doll" )
bar"bie
doll
declare -A foo=(["bar\"bie"]="doll" )
bar"bie
doll
declare -A foo=(["bar\"bie"]="doll" )
bar"bie
doll
declare -A foo=(["bar\"bie"]="doll" )
bar"bie
doll
declare -A foo=(["bar\"bie"]="doll" )
bar'bie
doll
declare -A foo=(["bar'bie"]="doll" )
bar'bie
doll
declare -A foo=(["bar'bie"]="doll" )
bar'bie
doll
declare -A foo=(["bar'bie"]="doll" )
bar'bie
doll
declare -A foo=(["bar'bie"]="doll" )
bar'bie
doll
declare -A foo=(["bar'bie"]="doll" )
bar$bie
doll
declare -A foo=(["bar\$bie"]="doll" )
bar[bie
doll
declare -A foo=(["bar[bie"]="doll" )
bar`bie
doll
declare -A foo=(["bar\`bie"]="doll" )
bar\]bie
doll
declare -A foo=(["bar\\]bie"]="doll" )
bar${foo}bie
doll
declare -A foo=(["bar\${foo}bie"]="doll" )
bar
after printf
after use: 0
declare -A assoc=([0]="assoc" )
assoc
declare -A assoc=([two]="twoless" [three]="three" [one]="onemore" )
declare -Ar assoc=([two]="twoless" [three]="three" [one]="onemore" )
declare -A hash=([key]="value1" )
declare -A hash=([key]="value1 value2" )
declare -A b=([")"]="" ["\""]="" ["]"]="" ["\\"]="" ["\`"]="" )
declare -A b=(["]"]="" ["\`"]="" )
declare -A dict=(["'"]="3" ["\""]="1" ["\\"]="4" ["\`"]="2" )
declare -A dict=()
declare -A dict=(["'"]="3" ["\""]="1" ["\\"]="4" ["\`"]="2" )
declare -A dict=()
4
4
a[$b]= 5
declare -A a=(["80's"]="Depeche Mode" )
./assoc9.sub: line 84: read: `a[80's]': not a valid identifier
declare -A a
declare -A a=(["80's"]="Depeche Mode" )
./assoc9.sub: line 96: printf: `a[80's]': not a valid identifier
declare -A a
declare -A a=(["80's"]="Depeche Mode" )
6
1
1+5
declare -A a=(["\$(date >&2)"]="5" )
declare -A myarray=([foo]="bleh" ["foo[bar"]="bleh" )
foo
declare -A assoc=(["\$var"]="value" )
declare -A assoc=(["\$var"]="value" )
declare -A assoc=(["\$var"]="value" )
declare -A assoc=()
./assoc9.sub: line 154: typeset: `foo[foo]bar]=bax': not a valid identifier
foo]bar
bip
declare -A foo=(["foo]bar"]="bip" )
./assoc10.sub: line 14: declare: a: cannot convert indexed to associative array
f: declare -a a
./assoc10.sub: line 17: declare: a: cannot convert associative to indexed array
f: declare -A a
f: declare -a a
main: declare -- a="7"
f: declare -A a
main: declare -- a="42"
declare -A a=([3]="" [1]="2" )
declare -A foo=([d]="4" [c]="3" [b]="2" [a]="1" )
foo=( d "4" c "3" b "2" a "1" )
declare -A foo=(["\\"]="5" ["@"]="3" ["holy hell this works"]="4" ["a b"]="1" ["spa ces"]="2" )
foo=( echo "\\" "5" "@" "3" "holy hell this works" "4" "a b" "1" "spa ces" "2" )
./assoc11.sub: line 34: "": bad array subscript
declare -A foo=([";"]="semicolon" ["]"]="def" [a=b]="assignment" ["a]a"]="abc" ["foo[bar"]="bleh" )
foo=( ";" "semicolon" "]" "def" a=b "assignment" "a]a" "abc" "foo[bar" "bleh" )
declare -A foo=(["'"]="squote" ["\""]="dquote" ["\\"]="bslash" ["\`"]="backquote" )
foo=( "'" "squote" "\"" "dquote" "\\" "bslash" "\`" "backquote" )
declare -A foo=(["bar]bie"]="doll" ["a]=test1;#a"]="123" ["bar\"bie"]="doll" )
foo=( "bar]bie" "doll" "a]=test1;#a" "123" "bar\"bie" "doll" )
declare -A inside=([c]="3" [b]="2" [a]="1" )
inside=( c "3" b "2" a "1" )
declare -A dict=(["?"]="quest" ["*"]="star" ["'"]="squote" ["\$"]="dol" ["\""]="dquote" ["\\"]="bslash" ["@"]="at" ["}"]="rbrace" ["{"]="lbrace" ["\`"]="bquote" )
dict=( "?" "quest" "*" "star" "'" "squote" "\$" "dol" "\"" "dquote" "\\" "bslash" "@" "at" "}" "rbrace" "{" "lbrace" "\`" "bquote" )
declare -A foo=([two]="" [one]="1" )
foo=( two "" one "1" )
rparen dquote rbracket bs
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbracket" ["\\"]="bs" )
")" "rparen" "\"" "dquote" "]" "rbracket" "\\" "bs"
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbracket" ["\\"]="bs" )
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbracket" ["\\"]="bs" )
declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbracket" ["\\"]="bs" )
declare -Arx foo=([two]="2" [three]="3" [one]="1" )
./assoc11.sub: line 90: foo: readonly variable
declare -A v1=(["1 2"]="3" )
declare -A v2=(["1 2"]="3" )
declare -A v3=(["1 2"]="3" )
declare -A v1=(["1 2"]="3 4 5" )
declare -A v2=(["1 2"]="3 4 5" )
declare -A v3=(["1 2"]="3 4 5" )
declare -A v1=(["1 2"]="3 4 5" )
declare -A v2=(["1 2"]="3 4 5" )
declare -A v3=(["1 2"]="3 4 5" )
declare -A v1=(["1 2"]="3 4 5" )
declare -A v2=(["1 2"]="3 4 5" )
declare -A v3=(["1 2"]="3 4 5" )
declare -A v1=(["20 40 80"]="xtra" ["1 2"]="3 4 5" )
declare -A v2=(["20 40 80"]="xtra" ["1 2"]="3 4 5" )
declare -A v3=(["1 2"]="3 4 5" ["\$xtra"]="xtra" )
declare -A v1=(["20 40 80"]="new xtra" ["1 2"]="3 4 5" )
declare -A v2=(["20 40 80"]="new xtra" ["1 2"]="3 4 5" )
declare -A v3=(["1 2"]="3 4 5" ["\$xtra"]="new xtra" )
declare -A assoc=(["*"]="star" ["!"]="bang" ["@"]="at" )
at
star
declare -A a=(["@"]="at" )
./assoc13.sub: line 22: ia[@]: bad array subscript
declare -a ia
declare -A a=(["@"]="at2" )
declare -A a=(["@"]=" string" )
declare -A a=(["*"]="star2" ["@"]="at" )
declare -A assoc=([hello]="world" ["key with spaces"]="value with spaces" [foo]="bar" [one]="1" )
argv[1] = <world>
argv[2] = <value with spaces>
argv[3] = <bar>
argv[4] = <1>
argv[1] = <hello>
argv[2] = <world>
argv[3] = <key with spaces>
argv[4] = <value with spaces>
argv[5] = <foo>
argv[6] = <bar>
argv[7] = <one>
argv[8] = <1>
argv[1] = <world value with spaces bar 1>
argv[1] = <hello world key with spaces value with spaces foo bar one 1>
argv[1] = <hello>
argv[2] = <world>
argv[3] = <key with spaces>
argv[4] = <value with spaces>
argv[5] = <one>
argv[6] = <1>
argv[7] = <foo>
argv[8] = <bar>
argv[1] = <'hello'>
argv[2] = <'world'>
argv[3] = <'key with spaces'>
argv[4] = <'value with spaces'>
argv[5] = <'one'>
argv[6] = <'1'>
argv[7] = <'foo'>
argv[8] = <'bar'>
argv[1] = <'hello'>
argv[2] = <'world'>
argv[3] = <'key with spaces'>
argv[4] = <'value with spaces'>
argv[5] = <'one'>
argv[6] = <'1'>
argv[7] = <'foo'>
argv[8] = <'bar'>
declare -A clone=([hello]="world" ["key with spaces"]="value with spaces" [foo]="bar" [one]="1" )
declare -A posparams=([hello]="world" ["key with spaces"]="value with spaces" [foo]="bar" [one]="1" )
declare -A var=([$'\001']=$'\001\001\001\001' )
declare -A v2=([$'\001']=$'\001\001\001\001' )
argv[1] = <^A>
argv[2] = <^A^A^A^A>
declare -A foo=([$'\001']=$'\001\001\001\001' )
declare -A var=([$'\001']=$'\001\001\001\001' )
argv[1] = <^A>
argv[2] = <^A^A^A^A>
declare -A foo=([$'\001']=$'\001\001\001\001' )
declare -A var=([$'\001']=$'\001\001\001\001' )
argv[1] = <^A>
argv[2] = <^A^A^A^A>
declare -A foo=([$'\001']=$'\001\001\001\001' )
declare -a var=([0]=$'\001\001\001\001')
argv[1] = <$'\001\001\001\001'>
declare -a foo=([0]=$'\001\001\001\001')
declare -a var=([0]=$'\001\001\001\001')
argv[1] = <$'\001\001\001\001'>
declare -a foo=([0]=$'\001\001\001\001')
declare -A var=([two]=$'ab\001cd' [one]=$'\001\001\001\001' )
declare -A foo=([two]=$'ab\001cd' [one]=$'\001\001\001\001' )
declare -A foo=([$'\001']=$'ab\001cd' )
declare -A foo=([$'\001']=$'\001\001\001\001' )
declare -A A=(["\$(echo Darwin ; echo stderr>&2)"]="darjeeling" [Darwin]="darjeeling" )
stderr
darjsharking
darjsharking
stderr
darj
darj
stderr
DARJEELING
DARJEELING
stderr
'darjeeling'
'darjeeling'
stderr
darjeel
darjeel
stderr
10
10
stderr
darjeeling
darjeeling
stderr
set
set
stderr
set
set
stderr
42
42
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
declare -A A=(["]"]="rbracket" ["["]="lbracket" )
declare -A A=()
5: ok 1

268
tests/assoc.tests Normal file
View file

@ -0,0 +1,268 @@
# 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/>.
#
# TEST - basic declaration and assignment
typeset -A fluff
declare -A
fluff[foo]=one
fluff[bar]=two
declare -A
declare -p fluff
unset fluff[foo]
declare -p fluff
fluff[bar]=newval
declare fluff[qux]=assigned
declare -p fluff
unset fluff
# TEST - compound assignment and variable attributes
declare -A wheat chaff
wheat=( [zero]=0 [one]=a [two]=b [three]=c )
declare -i chaff
chaff=( [zero]=1+4 [one]=3+7 four )
declare -A waste=( [pid]=42134 [version]=4.0-devel [source]=$0 [lineno]=$LINENO )
declare -r waste
declare -A
declare +i chaff
chaff[hello world]=flip
declare -p chaff
# TEST - no longer errors
waste[stuff]=other
unset waste
chaff[*]=12
chaff=( [one]=a [*]=12 )
# TEST - key expansion -- no word splitting
chaff[hello world]=flip
declare -p chaff
echo ${chaff[hello world]}
chaff[box]="multiple words"
recho ${chaff[@]}
recho "${chaff[@]}"
recho ${chaff[*]}
recho "${chaff[*]}"
unset chaff
declare -A chaff[200]
declare +A chaff
chaff[*]=12
chaff=( [one]=a [*]=12 )
# TEST - keys and values containing spaces
unset wheat
declare -A wheat
wheat=([six]=6 [foo bar]="qux qix" )
declare -p wheat
unset wheat
declare -A wheat=([six]=6 [foo bar]="qux qix" )
recho ${wheat[foo bar]}
recho "${wheat[foo bar]}"
declare -p wheat
# TEST - basic expansions: number of elements and value length
unset wheat
typeset -A wheat
wheat=([six]=6 [foo bar]="qux qix" )
recho ${#wheat[@]}
recho ${#wheat[foo bar]}
# TEST - appending assignment operator
unset wheat
typeset -A wheat
wheat=([six]=6 [foo bar]="qux qix" )
wheat[foo bar]+=' blat'
recho ${wheat[foo bar]}
recho "${wheat[foo bar]}"
unset wheat
flix=9
typeset -Ai wheat
wheat=([six]=6 [foo bar]=flix )
wheat[foo bar]+=7
recho ${wheat[foo bar]}
recho "${wheat[foo bar]}"
unset flix wheat
# TEST - index expansion: no word splitting or globbing
typeset -A wheat
cd ${TMPDIR:=/tmp}
touch '[sfiri]'
wheat=([s*]=6 [foo bar]=flix )
recho ${wheat[@]}
rm '[sfiri]'
cd $OLDPWD
# TEST -- associative array keys expansion
unset wheat
typeset -A wheat
wheat=([six]=6 [foo bar]=flix )
recho ${!wheat[@]}
recho "${!wheat[@]}"
# TEST -- associative array pattern removal
unset xpath
typeset -A xpath
xpath=( [0]=/bin [one]=/bin [two]=/usr/bin [three]=/usr/ucb [four]=/usr/local/bin)
xpath+=( [five]=/sbin [six]=/usr/sbin [seven]=. )
echo ${#xpath[@]}
echo ${xpath[@]}
echo ${xpath[@]##*/}
echo ${xpath[0]##*/}
echo ${xpath[@]%%[!/]*}
echo ${xpath[0]%%[!/]*}
recho ${xpath##*/}
recho ${xpath%%[!/]*}
recho ${xpath[five]##*/}
recho ${xpath[five]%%[!/]*}
echo ${#xpath[*]}
echo ${xpath[*]}
echo ${xpath[*]##*/}
echo ${xpath[*]%%[!/]*}
# TEST -- associative array pattern substitution
unset xpath
typeset -A xpath
xpath=( [0]=/bin [one]=/bin [two]=/usr/bin [three]=/usr/ucb [four]=/usr/local/bin)
xpath+=( [five]=/sbin [six]=/usr/sbin [seven]=. )
echo ${#xpath[@]}
# default element is "0" (as a string)
echo ${#xpath} -- ${xpath["0"]}
echo ${xpath[@]//\//^}
echo "${xpath[@]//\//^}" | cat -v
zecho "${xpath[@]/\//\\}"
zecho "${xpath[@]//\//\\}"
zecho "${xpath[@]//[\/]/\\}"
# test assignment to key "0"
unset T
declare -A T
T='([a]=1)'
echo "${T[@]}"
unset T
# peculiar ksh93 semantics for unsubscripted assoc variable reference
declare -A T
T[0]='zero'
if [ "$T" != "${T[0]}" ]; then
echo 'assoc.tests: $T and ${T[0]} mismatch'
fi
${THIS_SH} ./assoc1.sub
${THIS_SH} ./assoc2.sub
${THIS_SH} ./assoc3.sub
${THIS_SH} ./assoc4.sub
${THIS_SH} ./assoc5.sub
${THIS_SH} ./assoc6.sub
${THIS_SH} ./assoc7.sub
# test converting between scalars and assoc arrays
unset assoc
assoc=assoc
declare -A assoc
declare -p assoc
echo ${assoc[@]}
# weird syntax required to append to multiple existing array elements using
# compound assignment syntax
unset assoc
declare -A assoc
assoc=( [one]=one [two]=two [three]=three )
assoc+=( [one]+=more [two]+=less )
declare -p assoc
readonly -A assoc
declare -p assoc
declare -A hash
hash=(["key"]="value1")
declare -p hash
hash=(["key"]="${hash["key"]} value2")
declare -p hash
unset hash
${THIS_SH} ./assoc8.sub
# new shopt option to prevent multiple expansion of assoc array subscripts
${THIS_SH} ./assoc9.sub
${THIS_SH} ./assoc10.sub
# test assigning associative arrays using compound key/value pair assignments
${THIS_SH} ./assoc11.sub
# more kvpair associative array assignment tests
${THIS_SH} ./assoc12.sub
# assignment to @ and *
${THIS_SH} ./assoc13.sub
# tests of the @k transformation on associative arrays
${THIS_SH} ./assoc14.sub
# tests with subscripts and values containing 0x01 (some indexed array tests too)
${THIS_SH} ./assoc15.sub
# tests with subscripts being expanded more than one in ${xxx} word expansions
${THIS_SH} ./assoc16.sub
# tests with `[' and `]' subscripts and `unset'
${THIS_SH} ./assoc17.sub
# tests with `[' and `]' subscripts and printf/read/wait builtins
${THIS_SH} ./assoc18.sub

29
tests/assoc1.sub Normal file
View file

@ -0,0 +1,29 @@
# 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/>.
#
hash -r
echo ${BASH_CMDS[@]}
hash -p /usr/sbin/foo foo
hash -p /usr/local/bin/qux qux
echo ${!BASH_CMDS[@]}
echo ${BASH_CMDS[@]}
BASH_CMDS[blat]=/sbin/blat
BASH_CMDS[sh]=/bin/sh
hash
echo ${!BASH_CMDS[@]}
echo "${BASH_CMDS[@]}"

30
tests/assoc10.sub Normal file
View file

@ -0,0 +1,30 @@
# 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/>.
#
f() { declare -a a; declare -A a; echo -n "$FUNCNAME: " ; declare -p a; }
f
f() { declare -A a; declare -a a; echo -n "$FUNCNAME: " ; declare -p a; }
f
echo
f() { declare -a a; echo -n "$FUNCNAME: " ; declare -p a; }
a=7
f
echo -n 'main: '; declare -p a
f() { declare -A a; echo -n "$FUNCNAME: " ; declare -p a; }
a=42
f
echo -n 'main: '; declare -p a

90
tests/assoc11.sub Normal file
View file

@ -0,0 +1,90 @@
# 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/>.
#
# these tests were previously in array19.sub, but they are acceptable syntax now
declare -A a
declare a='(1 2 3)'
declare -p a
unset a
declare -A foo
v1='spa ces'
v2=@
foo=(a 1 b 2 c 3 d 4 )
declare -p foo
echo foo=\( ${foo[@]@K} \)
foo=('a b' 1 "$v1" 2 "$v2" 3 'holy hell this works' 4 \\ 5)
declare -p foo
echo foo=\( echo ${foo[@]@K} \)
foo=( "" null )
foo=('a]a' abc ']' def $(echo 'foo[bar') bleh \; semicolon a=b assignment)
declare -p foo
echo foo=\( ${foo[@]@K} \)
foo=('`' backquote '"' dquote "'" squote \\ bslash)
declare -p foo
echo foo=\( ${foo[@]@K} \)
bar='a]=test1;#a'
foo=( $bar 123 bar\"bie doll bar]bie doll )
declare -p foo
echo foo=\( ${foo[@]@K} \)
func()
{
declare -A inside=(a 1 b 2 c 3)
declare -p inside
echo inside=\( ${inside[@]@K} \)
}
func
loaddict()
{
dict=( '"' dquote '`' bquote "'" squote '\' bslash)
dict+=( '$' dol @ at * star \{ lbrace \} rbrace ? quest)
declare -p dict
echo dict=\( ${dict[@]@K} \)
}
declare -A dict
loaddict
foo=(one 1 two)
declare -p foo
echo foo=\( ${foo[@]@K} \)
typeset -A a=( [\\]=bs [\"]=dquote [\)]=rparen [\]]=rbracket )
echo ${a[@]}
declare -p a
echo ${a[@]@K}
echo ${a[@]@A}
eval "${a[@]@A}"
declare -p a
eval "a=( ${a[@]@K} )"
declare -p a
unset a foo
readonly -A foo=( one 1 two 2 three 3 )
export foo
declare -p foo
declare foo+=( seven 7 eight 8 )

74
tests/assoc12.sub Normal file
View file

@ -0,0 +1,74 @@
# 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/>.
#
foo='1 2'
bar='3 4 5'
xtra='20 40 80'
declare -A v1=( $foo 3 )
declare -p v1
declare -A v2=( [$foo]=3 )
declare -p v2
declare -A v3
v3=( $foo 3 )
declare -p v3
unset v1 v2 v3
declare -A v1=( $foo $bar )
declare -p v1
declare -A v2=( [$foo]=$bar )
declare -p v2
declare -A v3
v3=( $foo $bar )
declare -p v3
unset v1 v2 v3
declare -A v1=( "$foo" $bar )
declare -p v1
declare -A v2=( ["$foo"]=$bar )
declare -p v2
declare -A v3
v3=( "$foo" $bar )
declare -p v3
unset v1 v2 v3
declare -A v1=( "$foo" "$bar" )
declare -p v1
declare -A v2=( ["$foo"]="$bar" )
declare -p v2
declare -A v3
v3=( "$foo" "$bar" )
declare -p v3
v1+=( $xtra xtra )
v2+=( "$xtra" xtra )
v3+=( '$xtra' xtra )
declare -p v1 v2 v3
v1+=( [$xtra]='new xtra' )
v2+=( ["$xtra"]='new xtra' )
v3+=( ['$xtra']='new xtra' )
declare -p v1 v2 v3

44
tests/assoc13.sub Normal file
View file

@ -0,0 +1,44 @@
# assignment to @ and *
declare -A assoc
key=@
key2=*
assoc[$key]=at
assoc[$key2]=star
assoc[!]=bang
declare -p assoc
echo ${assoc[$key]}
echo ${assoc[$key2]}
unset assoc
declare -A a
a[@]=at
declare -p a
declare -a ia
ia[@]=garbage
declare -p ia
declare a[@]=at2
declare -p a
unset a ia
declare -A a
printf -v a[@] "%10s" string
declare -p a
unset a
declare -A a
declare a[$key2]=star
declare a[@]=at
declare a[*]=star2
declare -p a
unset a

35
tests/assoc14.sub Normal file
View file

@ -0,0 +1,35 @@
# 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/>.
#
declare -A assoc=(hello world "key with spaces" "value with spaces" one 1 foo bar)
declare -p assoc
recho "${assoc[@]}"
recho "${assoc[@]@k}"
recho "${assoc[*]}"
recho "${assoc[*]@k}"
set -- hello world "key with spaces" "value with spaces" one 1 foo bar
recho "${@}"
recho "${@@K}"
recho "${@@k}"
declare -A clone
eval clone=\( "${assoc[@]@K}" \)
declare -p clone
declare -A posparams
eval posparams=\( "${@@K}" \)
declare -p posparams

92
tests/assoc15.sub Normal file
View file

@ -0,0 +1,92 @@
# 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/>.
#
# associative arrays first
v=$'\x01'
declare -A var foo v2
var=( $'\x01' $'\x01\x01\x01\x01' )
declare -p var
v2=( $v $v$v$v$v )
declare -p v2
recho "${var[@]@k}"
eval foo=\( "${var[@]@k}" \)
declare -p foo
var=(   )
declare -p var
recho "${var[@]@k}"
eval foo=\( "${var[@]@k}" \)
declare -p foo
var=( []= )
declare -p var
recho "${var[@]@k}"
eval foo=\( "${var[@]@k}" \)
declare -p foo
# now indexed arrays
unset -v var foo
declare -a var
var=( [0]= )
declare -p var
declare -a foo
recho "${var[@]@Q}"
eval foo=\( "${var[@]@Q}" \)
declare -p foo
var=(  )
declare -p var
unset foo
declare -a foo
recho "${var[@]@Q}"
eval foo=\( "${var[@]@Q}" \)
declare -p foo
# similar to array29.sub
unset -v var foo v2
declare -A var
var=( one $'\x01\x01\x01\x01' two ab$'\001'cd )
declare -p var
pv()
{
local -A foo
eval foo=\( "${var[@]@k}" \)
declare -p foo
}
pv
pv1()
{
local -A foo=( $'\x01' "${var[two]}" )
declare -p foo
}
pv1
pv2()
{
local -A foo=( [$'\x01']="${var[one]}" )
declare -p foo
}
pv2

56
tests/assoc16.sub Normal file
View file

@ -0,0 +1,56 @@
# 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/>.
#
# bash versions up to and including bash-5.1 expanded these subscripts more
# than once
declare -A A
A["Darwin"]=darjeeling
A['$(echo Darwin ; echo stderr>&2)']=darjeeling
declare -p A
echo ${A[$(echo Darwin ; echo stderr>&2)]//eel/shark}
echo ${A['$(echo Darwin ; echo stderr>&2)']//eel/shark}
echo ${A[$(echo Darwin ; echo stderr>&2)]:0:4}
echo ${A['$(echo Darwin ; echo stderr>&2)']:0:4}
echo ${A[$(echo Darwin ; echo stderr>&2)]^^}
echo ${A['$(echo Darwin ; echo stderr>&2)']^^}
echo ${A[$(echo Darwin ; echo stderr>&2)]@Q}
echo ${A['$(echo Darwin ; echo stderr>&2)']@Q}
echo ${A[$(echo Darwin ; echo stderr>&2)]%ing}
echo ${A['$(echo Darwin ; echo stderr>&2)']%ing}
echo ${#A[$(echo Darwin ; echo stderr>&2)]}
echo ${#A['$(echo Darwin ; echo stderr>&2)']}
echo ${A[$(echo Darwin ; echo stderr>&2)]:-value}
echo ${A['$(echo Darwin ; echo stderr>&2)']:-value}
echo ${A[$(echo Darwin ; echo stderr>&2)]:+set}
echo ${A['$(echo Darwin ; echo stderr>&2)']:+set}
echo ${A[$(echo Darwin ; echo stderr>&2)]:+set}
echo ${A['$(echo Darwin ; echo stderr>&2)']:+set}
darjeeling=7*6
Darwin=7*4
echo $(( ${A[$(echo Darwin ; echo stderr>&2)]} ))
echo $(( ${A['$(echo Darwin ; echo stderr>&2)']} ))

58
tests/assoc17.sub Normal file
View file

@ -0,0 +1,58 @@
# 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/>.
#
# test behavior with `unset' and `[' and ']' subscripts
declare -A A
rkey=']'
lkey='['
A[$rkey]=rbracket
A[$lkey]=lbracket
declare -p A
unset A[$rkey]
unset A[$lkey]
declare -p A
A["$rkey"]=rbracket
A["$lkey"]=lbracket
declare -p A
unset A["$rkey"]
unset A["$lkey"]
declare -p A
A[\]]=rbracket
A[\[]=lbracket
declare -p A
unset A[\]]
unset A[\[]
declare -p A
A[']']=rbracket
A['[']=lbracket
declare -p A
unset A[']']
unset A['[']
declare -p A
A["]"]=rbracket
A["["]=lbracket
declare -p A
unset A["]"]
unset A["["]
declare -p A

59
tests/assoc18.sub Normal file
View file

@ -0,0 +1,59 @@
# 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/>.
#
# test behavior of builtins that can take array subscript arguments, make
# sure they work in the presence of associative arrays and `problematic' keys
# if assoc_expand_once is set
#
# affected builtins: printf, read, wait
declare -A A
rkey=']'
lkey='['
shopt -s assoc_expand_once
printf -v A[$rkey] rbracket
printf -v A[$lkey] lbracket
declare -p A
unset A[$rkey]
unset A[$lkey]
declare -p A
unset A
declare -A A
read A[$rkey] <<<rbracket
read A[$lkey] <<<lbracket
declare -p A
unset A[$rkey]
unset A[$lkey]
declare -p A
unset A
declare -A A
{ sleep 1 ; exit 4; } &
{ sleep 2 ; exit 5; } & bgpid1=$!
{ sleep 4 ; exit 6; } &
wait -p A[$rkey] -n %2 %3
case "${A[$rkey]}" in
$bgpid1) echo $?: ok 1;;
*) echo bad 1;;
esac
exit 0

28
tests/assoc2.sub Normal file
View file

@ -0,0 +1,28 @@
# 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/>.
#
echo ${BASH_ALIASES[@]}
alias foo=/usr/sbin/foo
alias qux='/usr/local/bin/qux -l'
echo ${!BASH_ALIASES[@]}
recho ${BASH_ALIASES[@]}
BASH_ALIASES[blat]='cd /blat ; echo $PWD'
BASH_ALIASES[sh]='/bin/bash --login -o posix'
alias -p
echo ${!BASH_ALIASES[@]}
recho "${BASH_ALIASES[@]}"

28
tests/assoc3.sub Normal file
View file

@ -0,0 +1,28 @@
# 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/>.
#
foo()
{
declare -A afoo=([six]="six" [foo bar]="foo quux")
declare -A
recho inside: "${afoo[@]}"
}
declare -A afoo=([main]=outside)
echo outside: "${afoo[@]}"
foo
echo outside 2: "${afoo[@]}"

35
tests/assoc4.sub Normal file
View file

@ -0,0 +1,35 @@
# 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/>.
#
IFS=/
declare -A i
i[0]=fooq
i[1]=
i[2]=barq
i[3]=
recho "${i[*]:0}"
recho "${i[@]:0}"
recho "${i[*]/q/!}"
recho "${i[@]/q/!}"
recho "${i[*]#?}"
recho "${i[@]#?}"
# Need to complete this with case-modifying expansion examples
recho "${i[*]^?}"
recho "${i[@]^?}"
recho "${i[*]^^?}"
recho "${i[@]^^?}"

40
tests/assoc5.sub Normal file
View file

@ -0,0 +1,40 @@
# 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/>.
#
declare -A myarray
# this needs fixes to skipsubscript
myarray["a]a"]="abc"
echo ${myarray["a]a"]}
myarray[$(echo ])]=def
echo ${myarray[']']}
echo ${myarray[\]]}
declare myarray["foo[bar"]=bleh
myarray["foo"]=bleh
echo "${myarray[@]}"
bar='a]=test1;#a'
myarray[$bar]=123
set | grep ^myarray=
echo ${myarray[a]}
echo "${myarray['a]=test1;#a']}"
myarray['a]=test2;#a']="def"
set | grep ^myarray=

159
tests/assoc6.sub Normal file
View file

@ -0,0 +1,159 @@
# 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/>.
#
declare -A foo
foo=([bar\"bie]=doll)
echo ${!foo[@]}
echo ${foo[@]}
declare -p foo
unset foo
declare -A foo=(["bar\"bie"]="doll")
echo ${!foo[@]}
echo ${foo[@]}
declare -p foo
unset foo
declare -A foo
foo=(["bar\"bie"]="doll")
echo ${!foo[@]}
echo ${foo[@]}
declare -p foo
unset foo
declare -A foo
foo["bar\"bie"]="doll"
echo ${!foo[@]}
echo ${foo[@]}
declare -p foo
unset foo
declare -A foo
foo[bar\"bie]="doll"
echo ${!foo[@]}
echo ${foo[@]}
declare -p foo
unset foo
declare -A foo
foo=([bar\'bie]=doll)
echo ${!foo[@]}
echo ${foo[@]}
declare -p foo
unset foo
declare -A foo=(["bar'bie"]="doll")
echo ${!foo[@]}
echo ${foo[@]}
declare -p foo
unset foo
declare -A foo
foo=(["bar'bie"]="doll")
echo ${!foo[@]}
echo ${foo[@]}
declare -p foo
unset foo
declare -A foo
foo["bar'bie"]="doll"
echo ${!foo[@]}
echo ${foo[@]}
declare -p foo
unset foo
declare -A foo
foo[bar\'bie]="doll"
echo ${!foo[@]}
echo ${foo[@]}
declare -p foo
unset foo
declare -A foo
foo=([bar\$bie]=doll)
echo ${!foo[@]}
echo ${foo[@]}
declare -p foo
unset foo
declare -A foo=(["bar[bie"]="doll")
echo ${!foo[@]}
echo ${foo[@]}
declare -p foo
unset foo
declare -A foo
foo=(["bar\`bie"]="doll")
echo ${!foo[@]}
echo ${foo[@]}
declare -p foo
unset foo
declare -A foo
# this doesn't work right without the backslash
foo["bar\]bie"]="doll"
echo ${!foo[@]}
echo ${foo[@]}
declare -p foo
unset foo
declare -A foo
foo[bar\${foo}bie]="doll"
echo ${!foo[@]}
echo ${foo[@]}
declare -p foo
unset foo
declare -A foo

29
tests/assoc7.sub Normal file
View file

@ -0,0 +1,29 @@
# 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/>.
#
# problem with bash versions through bash-4.2
foo()
{
declare -A hash
declare hash[baz]=bar #bash crashes here
echo ${hash[@]}
}
foo
declare -a ary
printf -v ary[0] "%b" ""
echo "after printf"
x="${ary[*]}" # segfaults here
echo "after use: $?"

7
tests/assoc8.sub Normal file
View file

@ -0,0 +1,7 @@
# warnings introduced beginning with bash-4.4-alpha
var=foo; declare -A "arr$var=([x]=y)"
key1=foo key2=bar
declare -A a=([foo]='([bar]=baz)') "b=${a[$key1]}"

159
tests/assoc9.sub Normal file
View file

@ -0,0 +1,159 @@
# 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/>.
#
typeset -A a=( [\\]= [\"]= [\)]= ) b
for x in "${!a[@]}"; do b[$x]=; done
b+=([\`]= [\]]=)
typeset -p b
for x in "${!a[@]}"; do
unset -v 'b[$x]'
done
typeset -p b
unset -v a b
loaddict()
{
dict['"']=1
dict['`']=2
dict["'"]=3
dict['\']=4
declare -p dict
}
del()
{
unset -v dict["$1"];
}
declare -A dict
loaddict
for k in "${!dict[@]}"; do del "$k"; done
declare -p dict
unset 'dict[@]'
shopt -s assoc_expand_once
declare -A dict
loaddict
for k in "${!dict[@]}"; do del "$k"; done
declare -p dict
unset a b dict
typeset -A a
b="80's"
((++a[$b]))
((++a["$b"]))
[[ $((++a[$b])) ]]
[[ $((++a["$b"])) ]]
echo ${a["$b"]}
echo ${a[$b]}
let "++a[$b]"
echo 'a[$b]=' "${a[$b]}"
unset a b
declare -A a
b="80's"
: ${a[$b]:='Depeche Mode'}
declare -p a
unset a b
shopt -u assoc_expand_once
typeset -A a
b="80's"
read a[$b] <<<"Depeche Mode"
typeset -p a
shopt -s assoc_expand_once
read a[$b] <<<"Depeche Mode"
typeset -p a
unset a
shopt -u assoc_expand_once
typeset -A a
printf -v a[$b] "%s" "Depeche Mode"
typeset -p a
shopt -s assoc_expand_once
printf -v a[$b] "%s" "Depeche Mode"
typeset -p a
unset a
declare -A a
x='$(date >&2)'
a[$x]=5
shopt -s assoc_expand_once
echo $((1+a[$x]))
echo $((1+a[\$x]))
echo "1+${a[$x]}"
declare -p a
shopt -s assoc_expand_once
declare -A myarray
declare myarray["foo[bar"]=bleh
myarray["foo"]=bleh
declare -p myarray
key='$(date >&2)'
declare -A aa
aa[$key]=foo
echo "${aa[$key]}"
[[ -v aa[$key] ]] || echo bad assoc expansion
shopt -u assoc_expand_once
declare -A assoc
var=x123
assoc['$var']=value
declare -p assoc
unset "assoc[$var]"
declare -p assoc
unset 'assoc[$var]'
declare -p assoc
shopt -s assoc_expand_once
unset 'assoc[$var]'
declare -p assoc
typeset -A foo
foo["foo]bar"]=bip
typeset foo["foo]bar"]=bax
echo ${!foo[@]}
echo ${foo[@]}
declare -p foo

37
tests/attr.right Normal file
View file

@ -0,0 +1,37 @@
after f1:declare -ar a=([0]="1")
./attr.tests: line 17: a: readonly variable
after f2:declare -ar a=([0]="1")
./attr.tests: line 18: a: readonly variable
after f3:declare -ar a=([0]="1")
./attr.tests: line 19: readonly: a: readonly variable
after f4:declare -ar a=([0]="1")
after f2:declare -ar b=([0]="2")
after f3:declare -ar c=([0]="(3)")
after f4:declare -ar d=([0]="4")
declare -r m="4"
in func:declare -r n="4"
declare -r n="4"
./attr1.sub: line 26: p: readonly variable
declare -r p="1"
./attr1.sub: line 32: r: readonly variable
declare -ar r=([0]="1")
./attr1.sub: line 36: r: readonly variable
declare -ar r=([0]="1")
./attr1.sub: line 40: r: readonly variable
declare -ar r=([0]="1")
./attr1.sub: line 44: readonly: r: readonly variable
declare -ar r=([0]="1")
declare -ar x=([0]="4")
in func:declare -ar y=([0]="4")
declare -ar y=([0]="4")
in func:declare -ar z=([0]="4")
declare -ar z=([0]="4")
in func:declare -ar y1=([0]="4")
declare -ar y1=([0]="4")
in func:declare -ar z1=([0]="4")
declare -ar z1=([0]="4")
declare -x p="4"
declare -ax r=([0]="4")
declare -ax r=([0]="(5)")
declare -ax r=([0]="6")
declare -ax r=([0]="7")

54
tests/attr.tests Normal file
View file

@ -0,0 +1,54 @@
# 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=(outside)
f1() { readonly a=(1) ; }
f2() { readonly -a a=(2) ; }
f3() { readonly 'a=(3)' ; }
f4() { readonly -a 'a=(4)' ; }
f1
echo -n after f1:
declare -p a
f2
echo -n after f2:
declare -p a
f3
echo -n after f3:
declare -p a
f4
echo -n after f4:
declare -p a
b=(outside)
c=(outside)
d=(outside)
f2() { readonly -a b=(2) ; }
f3() { readonly 'c=(3)' ; }
f4() { readonly -a 'd=(4)' ; }
f2
echo -n after f2:
declare -p b
f3
echo -n after f3:
declare -p c
f4
echo -n after f4:
declare -p d
${THIS_SH} ./attr1.sub
${THIS_SH} ./attr2.sub

68
tests/attr1.sub Normal file
View file

@ -0,0 +1,68 @@
# 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/>.
#
m=1
readonly m=4
declare -p m
n=1
f() { readonly n=4; echo -n in func: ; declare -p n ; }
f
declare -p n
p=1
readonly p
readonly p=4
declare -p p
r=(1)
readonly r
f() { readonly r=(4) ; }
f
declare -p r
f() { readonly r='(5)' ; }
f
declare -p r
f() { readonly -a r=(6) ; }
f
declare -p r
f() { readonly -a r='(7)' ; }
f
declare -p r
x=(1)
readonly x=(4)
declare -p x
y=(1)
f() { readonly y=(4); echo -n in func: ; declare -p y; }
f
declare -p y
z=(1)
f() { readonly -a z=(4); echo -n in func: ; declare -p z; }
f
declare -p z
f() { readonly y1=(4); echo -n in func: ; declare -p y1; }
f
declare -p y1
f() { readonly -a z1=(4); echo -n in func: ; declare -p z1; }
f
declare -p z1

37
tests/attr2.sub Normal file
View file

@ -0,0 +1,37 @@
# 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/>.
#
p=1
export p
export p=4
declare -p p
r=(1)
export r
f() { export r=(4) ; }
f
declare -p r
f() { export r='(5)' ; }
f
declare -p r
f() { export -a r=(6) ; }
f
declare -p r
f() { export -a r='(7)' ; }
f
declare -p r

77
tests/braces.right Normal file
View file

@ -0,0 +1,77 @@
ffc ffb ffa
fdg feg ffg
lxyz nxyz mxyz
{abc,def}
{abc}
{a,b,c,d,e}
x} y} {a} b} c}
x,y {abc} trie
/usr/ucb/ex /usr/ucb/edit /usr/lib/ex /usr/lib/how_ex
XXXX{a,b,c}
XXXXa XXXXb XXXXc
{}
{ }
}
{
abcd{efgh
foo 1 2 bar
foo 1 2 bar
foo 1 2 bar
foobar foobaz.
foobar foobaz
bazx bazy
vx vy
bazx bazy
1 2 3 4 5 6 7 8 9 10
0..10 braces
0 1 2 3 4 5 6 7 8 9 10 braces
x0y x1y x2y x3y x4y x5y x6y x7y x8y x9y x10y xbracesy
3
x3y
10 9 8 7 6 5 4 3 2 1
10y 9y 8y 7y 6y 5y 4y 3y 2y 1y
x10y x9y x8y x7y x6y x5y x4y x3y x2y x1y
a b c d e f
f e d c b a
a ` _ ^ ] [ Z Y X W V U T S R Q P O N M L K J I H G F E D C B A
A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ ] ^ _ ` a
f
{1..f}
{f..1}
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20
-1 -2 -3 -4 -5 -6 -7 -8 -9 -10
-20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0
a-{bd}-c a-{be}-c
a-{bdef-g-c a-{bdef-i-c
{klklkl}1 {klklkl}2 {klklkl}3
{x,x}
1 3 5 7 9
-1 -3 -5 -7 -9
-1 -3 -5 -7 -9
10 8 6 4 2
10 8 6 4 2
1 3 5 7 9 11 13 15 17 19
1
100 95 90 85 80 75 70 65 60 55 50 45 40 35 30 25 20 15 10 5 0
100 95 90 85 80 75 70 65 60 55 50 45 40 35 30 25 20 15 10 5 0
a b c d e f g h i j k l m n o p q r s t u v w x y z
a c e g i k m o q s u w y
z x v t r p n l j h f d b
2147483645 2147483646 2147483647 2147483648 2147483649
10 8 6 4 2 0
10 8 6 4 2 0
-50 -45 -40 -35 -30 -25 -20 -15 -10 -5 0
{1..10.f}
{1..ff}
{1..10..ff}
{1.20..2}
{1..20..f2}
{1..20..2f}
{1..2f..2}
{1..ff..2}
{1..ff}
{1..f}
{1..0f}
{1..10f}
{1..10.f}
{1..10.f}

132
tests/braces.tests Normal file
View file

@ -0,0 +1,132 @@
# 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/>.
#
echo ff{c,b,a}
echo f{d,e,f}g
echo {l,n,m}xyz
echo {abc\,def}
echo {abc}
echo \{a,b,c,d,e}
echo {x,y,\{a,b,c}}
echo {x\,y,\{abc\},trie}
echo /usr/{ucb/{ex,edit},lib/{ex,how_ex}}
echo XXXX\{`echo a b c | tr ' ' ','`\}
eval echo XXXX\{`echo a b c | tr ' ' ','`\}
echo {}
echo { }
echo }
echo {
echo abcd{efgh
echo foo {1,2} bar
echo `zecho foo {1,2} bar`
echo $(zecho foo {1,2} bar)
var=baz
varx=vx
vary=vy
echo foo{bar,${var}.}
echo foo{bar,${var}}
echo "${var}"{x,y}
echo $var{x,y}
echo ${var}{x,y}
unset var varx vary
# new sequence brace operators
echo {1..10}
# this doesn't work yet
echo {0..10,braces}
# but this does
echo {{0..10},braces}
echo x{{0..10},braces}y
echo {3..3}
echo x{3..3}y
echo {10..1}
echo {10..1}y
echo x{10..1}y
echo {a..f}
echo {f..a}
echo {a..A}
echo {A..a}
echo {f..f}
# mixes are incorrectly-formed brace expansions
echo {1..f}
echo {f..1}
echo 0{1..9} {10..20}
# do negative numbers work?
echo {-1..-10}
echo {-20..0}
# weirdly-formed brace expansions -- fixed in post-bash-3.1
echo a-{b{d,e}}-c
echo a-{bdef-{g,i}-c
echo {"klklkl"}{1,2,3}
echo {"x,x"}
echo {1..10..2}
echo {-1..-10..2}
echo {-1..-10..-2}
echo {10..1..-2}
echo {10..1..2}
echo {1..20..2}
echo {1..20..20}
echo {100..0..5}
echo {100..0..-5}
echo {a..z}
echo {a..z..2}
echo {z..a..-2}
# make sure brace expansion handles ints > 2**31 - 1 using intmax_t
echo {2147483645..2147483649}
# unwanted zero-padding -- fixed post-bash-4.0
echo {10..0..2}
echo {10..0..-2}
echo {-50..-0..5}
# bad
echo {1..10.f}
echo {1..ff}
echo {1..10..ff}
echo {1.20..2}
echo {1..20..f2}
echo {1..20..2f}
echo {1..2f..2}
echo {1..ff..2}
echo {1..ff}
echo {1..f}
echo {1..0f}
echo {1..10f}
echo {1..10.f}
echo {1..10.f}

281
tests/builtins.right Normal file
View file

@ -0,0 +1,281 @@
1000
a
end-1
a
end-2
a:x
end-a
b:x
end-b
c:x
end-c
end-3
a:x
end
a
b
c
end-1
a
b
c
end-2
a:x
a:y
a:z
end-a
b:x
b:y
b:z
end-b
c:x
c:y
c:z
end-c
end-3
a:x
b:x
c:x
end
$BVAR
$BVAR
$BVAR
$BVAR
foo
bar
xxx
0022
u=rwx,g=rx,o=rx
0002
u=rwx,g=rwx,o=rx
umask 0002
umask -S u=rwx,g=rwx,o=rx
u=rwx,g=rwx,o=rwx
enable .
enable :
enable break
enable continue
enable eval
enable exec
enable exit
enable export
enable readonly
enable return
enable set
enable shift
enable source
enable times
enable trap
enable unset
enable .
enable :
enable break
enable continue
enable eval
enable exec
enable exit
enable export
enable readonly
enable return
enable set
enable shift
enable source
enable times
enable trap
enable unset
enable -n test worked
enable test worked
specialname
-specialname
FOO=BAR
FOO=BAR
hash: hash table empty
0
AVAR
foo
in source.sub2, calling return
5
a b c
a b c
x y z
a b c
a b c
m n o p
a b c
m n o p
/tmp/bash-dir-a
/tmp/bash-dir-a
/tmp/bash-dir-a
./source5.sub: line 23: /tmp/source-notthere: No such file or directory
after bad source 1
./source5.sub: line 30: /tmp/source-notthere: No such file or directory
one - OK
0
0
two - OK
0
three - OK
0
four - OK
0
abc
def
ghi
after
one.1 subshell
two.1 subshell
three.1 subshell
four.1 subshell
one.2 subshell
two.2 subshell
three.2 subshell
four.2 subshell
x29 - done
abc
def
ghi
ok
AVAR
foo
foo
AVAR
foo
foo
AVAR
foo
declare -x foo=""
declare -x FOO="\$\$"
./builtins.tests: line 228: declare: FOO: not found
declare -x FOO="\$\$"
ok
ok
./builtins.tests: line 260: kill: 4096: invalid signal specification
1
a\n\n\nb
a
b
before: f = 4
inside
after: f = 8 bar = 4
declare -a c
declare -A d
declare -a c=([0]="4")
declare -A c=([0]="4" )
declare -a c=([0]="1" [1]="2" [2]="3")
declare -A c=([two]="2" [three]="3" [one]="1" )
declare -a c=([0]="1" [1]="2" [2]="3")
declare -a c=([0]="1" [1]="2" [2]="3")
unset
unset
assoc 1 unset
array 1 unset
assoc 2 unset
array 2 unset
unset1
unset2
1
1
1
1
0
0
assoc A unset
array a
assoc A
array a
assoc B unset
array b unset
assoc B unset
array b unset
scalar 1
scalar 2
scalar 3 unset
argv[1] = <one two three>
assoc: 3
array: 3
scalar: 13
scalar: 1
scalar: 0
scalar: 1
scalar: 0
scalar: 0
all set:
one
two
f1 ()
{
echo f1
}
f2 ()
{
echo f2
}
all unset:
unset1
unset2
./builtins6.sub: line 41: declare: f1: not found
./builtins6.sub: line 41: declare: f2: not found
all reset:
one-one
two-one
f1 ()
{
echo f1
}
f2 ()
{
echo f2
}
vars unset:
unset1
unset2
f1 ()
{
echo f1
}
f2 ()
{
echo f2
}
funcs unset:
one-two
two-two
bash: line 1: notthere: No such file or directory
one
bash: line 1: notthere: No such file or directory
two
bash: line 1: .: notthere: file not found
one
bash: line 1: .: notthere: file not found
0
0
0
0
argv[1] = <one>
0
argv[1] = <two>
0
three
0
four
0
./builtins7.sub: line 19: : command not found
127
0
./builtins7.sub: line 27: notthere: No such file or directory
after 1
./builtins7.sub: line 28: notthere: No such file or directory
after 2
type is a shell builtin
+ command -v type
type
+ command command -v type
type
+ command -p command -v type
type
+ command -p -- command -v type
type
+ set +x
./builtins.tests: line 284: exit: status: numeric argument required

286
tests/builtins.tests Normal file
View file

@ -0,0 +1,286 @@
# 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/>.
#
# tests for miscellaneous builtins not tested elsewhere
set +p
set +o posix
ulimit -S -c 0 2>/dev/null
ulimit -c -S -- 1000 2>/dev/null
ulimit -c 2>/dev/null
# check that break breaks loops
for i in a b c; do echo $i; break; echo bad-$i; done
echo end-1
for i in a b c; do echo $i; break 1; echo bad-$i; done
echo end-2
for i in a b c; do
for j in x y z; do
echo $i:$j
break
echo bad-$i
done
echo end-$i
done
echo end-3
# check that break breaks nested loops
for i in a b c; do
for j in x y z; do
echo $i:$j
break 2
echo bad-$i
done
echo end-$i
done
echo end
# check that continue continues loops
for i in a b c; do echo $i; continue; echo bad-$i ; done
echo end-1
for i in a b c; do echo $i; continue 1; echo bad-$i; done
echo end-2
for i in a b c; do
for j in x y z; do
echo $i:$j
continue
echo bad-$i-$j
done
echo end-$i
done
echo end-3
# check that continue breaks out of nested loops
for i in a b c; do
for j in x y z; do
echo $i:$j
continue 2
echo bad-$i-$j
done
echo end-$i
done
echo end
# check that `eval' re-evaluates arguments, but `builtin' and `command' do not
AVAR='$BVAR'
BVAR=foo
echo $AVAR
builtin echo $AVAR
command echo $AVAR
eval echo \$AVAR
eval echo $AVAR
# test out eval with a temp environment
AVAR=bar eval echo \$AVAR
BVAR=xxx eval echo $AVAR
unset -v AVAR BVAR
# test umask
mask=$(umask)
umask 022
umask
umask -S
umask -S u=rwx,g=rwx,o=rx >/dev/null # 002
umask
umask -S
umask -p
umask -p -S
umask 0
umask -S
umask ${mask} # restore original mask
# builtin/command without arguments should do nothing. maybe someday they will
builtin
command
# test enable
enable -ps
enable -aps ; enable -nps
enable -n test
case "$(type -t test)" in
builtin) echo oops -- enable -n test failed ;;
*) echo enable -n test worked ;;
esac
enable test
case "$(type -t test)" in
builtin) echo enable test worked ;;
*) echo oops -- enable test failed ;;
esac
# test options to exec
(exec -a specialname ${THIS_SH} -c 'echo $0' )
(exec -l -a specialname ${THIS_SH} -c 'echo $0' )
# test `clean' environment. if /bin/sh is bash, and the script version of
# printenv is run, there will be variables in the environment that bash
# sets on startup. Also test code that prefixes argv[0] with a dash.
(export FOO=BAR ; exec -c -l printenv ) | grep FOO
(FOO=BAR exec -c printenv ) | grep FOO
(export FOO=BAR ; exec printenv ) | grep FOO
(FOO=BAR exec printenv ) | grep FOO
# ok, forget everything about hashed commands
hash -r
hash
# this had better succeed, since command -p guarantees we will find the
# standard utilities
command -p hash rm
# check out source/.
# sourcing a zero-length-file had better not be an error
rm -f /tmp/zero-length-file
cp /dev/null /tmp/zero-length-file
. /tmp/zero-length-file
echo $?
rm /tmp/zero-length-file
AVAR=AVAR
. ./source1.sub
AVAR=foo . ./source1.sub
. ./source2.sub
echo $?
set -- a b c
. ./source3.sub
# make sure source with arguments does not change the shell's positional
# parameters, but that the sourced file sees the arguments as its
# positional parameters
echo "$@"
. ./source3.sub x y z
echo "$@"
# but if the sourced script sets the positional parameters explicitly, they
# should be reflected in the calling shell's positional parameters. this
# also tests one of the shopt options that controls source using $PATH to
# find the script
echo "$@"
shopt -u sourcepath
. source4.sub
echo "$@"
# this is complicated when the sourced scripts gets its own positional
# parameters from arguments to `.'
set -- a b c
echo "$@"
. source4.sub x y z
echo "$@"
# test out cd and $CDPATH
${THIS_SH} ./builtins1.sub
# test behavior of `.' when given a non-existent file argument
${THIS_SH} ./source5.sub
# test bugs in sourcing non-regular files, fixed post-bash-3.2
${THIS_SH} ./source6.sub
# test bugs with source called from multiline aliases and other contexts
${THIS_SH} ./source7.sub
# in posix mode, assignment statements preceding special builtins are
# reflected in the shell environment. `.' and `eval' need special-case
# code.
set -o posix
echo $AVAR
AVAR=foo . ./source1.sub
echo $AVAR
AVAR=AVAR
echo $AVAR
AVAR=foo eval echo \$AVAR
echo $AVAR
AVAR=AVAR
echo $AVAR
AVAR=foo :
echo $AVAR
set +o posix
# but assignment statements preceding `export' are always reflected in
# the environment
foo="" export foo
declare -p foo
unset foo
# assignment statements preceding `declare' should be displayed correctly,
# but not persist after the command
FOO='$$' declare -p FOO
declare -p FOO
unset FOO
# except for `declare -x', which should be equivalent to `export'
FOO='$$' declare -x FOO
declare -p FOO
unset FOO
# test out kill -l. bash versions prior to 2.01 did `kill -l num' wrong
sigone=$(kill -l | sed -n 's:^ 1) *\([^ ]*\)[ ].*$:\1:p')
case "$(kill -l 1)" in
${sigone/SIG/}) echo ok;;
*) echo oops -- kill -l failure;;
esac
# kill -l and trap -l should display exactly the same output
sigonea=$(trap -l | sed -n 's:^ 1) *\([^ ]*\)[ ].*$:\1:p')
if [ "$sigone" != "$sigonea" ]; then
echo oops -- kill -l and trap -l differ
fi
# POSIX.2 says that exit statuses > 128 are mapped to signal names by
# subtracting 128 so you can find out what signal killed a process
case "$(kill -l $(( 128 + 1)) )" in
${sigone/SIG/}) echo ok;;
*) echo oops -- kill -l 129 failure;;
esac
# out-of-range signal numbers should report the argument in the error
# message, not 128 less than the argument
kill -l 4096
# kill -l NAME should return the signal number
kill -l ${sigone/SIG/}
# test behavior of shopt xpg_echo
${THIS_SH} ./builtins2.sub
# test behavior of declare -g
${THIS_SH} ./builtins3.sub
# test behavior of using declare to create variables without assigning values
${THIS_SH} ./builtins4.sub
# test behavior of set and unset array variables
${THIS_SH} ./builtins5.sub
# test behavior of unset builtin with -f and -v options
${THIS_SH} ./builtins6.sub
# test behavior of command builtin after changing it to a pseudo-keyword
${THIS_SH} ./builtins7.sub
# this must be last -- it is a fatal error
exit status
echo after bad exit

14
tests/builtins1.sub Normal file
View file

@ -0,0 +1,14 @@
unset CDPATH
MYDIR=$(pwd -P)
FULLDIR=/tmp/bash-dir-a
DIR=${FULLDIR##*/}
mkdir $FULLDIR
CDPATH=.:/tmp
cd $DIR
pwd
echo $PWD
cd "$MYDIR"
rmdir $FULLDIR

10
tests/builtins2.sub Normal file
View file

@ -0,0 +1,10 @@
# test behavior of shopt xpg_echo
USG_ECHO=off
shopt -q xpg_echo && USG_ECHO=on
shopt -u xpg_echo
echo 'a\n\n\nb'
shopt -s xpg_echo
echo 'a\n\n\nb'

14
tests/builtins3.sub Normal file
View file

@ -0,0 +1,14 @@
# declare -g added in bash-4.2
f=4
foo()
{
declare -g f=8
declare -g bar=4
echo inside
}
echo before: f = $f
foo
echo after: f = $f bar = $bar

57
tests/builtins4.sub Normal file
View file

@ -0,0 +1,57 @@
# 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/>.
#
declare -a c
declare -p c
declare -A d
declare -p d
unset c d
declare -a c
c=4
declare -p c
unset c
declare -A c
c=4
declare -p c
unset c
declare -a c
c=(1 2 3)
declare -p c
unset c
declare -A c
c=([one]=1 [two]=2 [three]=3)
declare -p c
unset c
declare -a c
read -a c < <(echo 1 2 3)
declare -p c
unset c
declare -a c
mapfile -t c < <(echo 1$'\n'2$'\n'3)
declare -p c
unset c
unset foo
declare -A foo
echo ${foo-unset}
unset foo
declare -a foo
echo ${foo-unset}

83
tests/builtins5.sub Normal file
View file

@ -0,0 +1,83 @@
# 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 start at a test suite for what it means for an array to be set or unset and
# how to test that state
typeset -A A
A[a]=1
typeset -a a
a[1]=1
if [ -v A ]; then echo assoc 1; else echo assoc 1 unset; fi
if [ -v a ]; then echo array 1; else echo array 1 unset; fi
if [ -v "${A[@]}" ]; then echo assoc 2; else echo assoc 2 unset; fi
if [ -v "${a[@]}" ]; then echo array 2; else echo array 2 unset; fi
echo ${A-unset1}
echo ${a-unset2}
echo ${A[@]-unset3}
echo ${a[@]-unset4}
echo ${#A[@]}
echo ${#a[@]}
typeset -A B
typeset -a b
echo ${#B[@]}
echo ${#b[@]}
scalar1=foo
scalar2=
# this now checks for A[@] treating @ as a valid key - post-bash-5.1
if [ -v A[@] ]; then echo assoc A; else echo assoc A unset; fi
if [ -v a[@] ]; then echo array a; else echo array a unset; fi
if [ ${#A[@]} -gt 0 ]; then echo assoc A; else echo assoc A unset; fi
if [ ${#a[@]} -gt 0 ]; then echo array a; else echo array a unset; fi
if [ -v B[@] ]; then echo assoc B; else echo assoc B unset; fi
if [ -v b[@] ]; then echo array b; else echo array b unset; fi
if [ ${#B[@]} -gt 0 ]; then echo assoc B; else echo assoc B unset; fi
if [ ${#b[@]} -gt 0 ]; then echo array b; else echo array b unset; fi
if [ -v scalar1[@] ]; then echo scalar 1; else echo scalar 1 unset; fi
if [ -v scalar2[@] ]; then echo scalar 2; else echo scalar 2 unset; fi
if [ -v scalar3[@] ]; then echo scalar 3; else echo scalar 3 unset; fi
unset a A
declare -A assoc=([one]=one [two]=two [three]=three)
declare -a array=(one two three)
scalar="one two three"
scalar2=
recho "${scalar[@]}"
echo assoc: ${#assoc[@]}
echo array: ${#array[@]}
echo scalar: ${#scalar}
echo scalar: ${#scalar[@]}
echo scalar: ${#scalar2}
echo scalar: ${#scalar2[@]}
echo scalar: ${#scalar3}
echo scalar: ${#scalar3[@]}

81
tests/builtins6.sub Normal file
View file

@ -0,0 +1,81 @@
# 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/>.
#
f1()
{
echo f1
}
f2()
{
echo f2
}
v1=one
v2=two
echo all set:
echo ${v1-unset1}
echo ${v2-unset2}
declare -f -p f1 f2
unset v1 f1 v2 f2
echo all unset:
echo ${v1-unset1}
echo ${v2-unset2}
declare -f -p f1 f2
f1()
{
echo f1
}
f2()
{
echo f2
}
v1=one-one
v2=two-one
echo all reset:
echo ${v1-unset1}
echo ${v2-unset2}
declare -f -p f1 f2
unset -v v1 f1 v2 f2
echo vars unset:
echo ${v1-unset1}
echo ${v2-unset2}
declare -f -p f1 f2
v1=one-two
v2=two-two
unset -f v1 f1 v2 f2
echo funcs unset:
echo ${v1-unset1}
echo ${v2-unset2}
declare -f f1 f2

38
tests/builtins7.sub Normal file
View file

@ -0,0 +1,38 @@
: ${THIS_SH:=./bash}
${THIS_SH} -c 'command . notthere ; echo one' bash
${THIS_SH} -c '. notthere ; echo two' bash
${THIS_SH} -o posix -c 'command . notthere ; echo one' bash
${THIS_SH} -o posix -c '. notthere ; echo two' bash
command ; echo $?
command -- ; echo $?
command -p ; echo $?
command -p -- ; echo $?
command recho one; echo $?
command -- recho two; echo $?
command -p echo three; echo $?
command -p -- echo four ; echo $?
command ''
echo $?
command -p
echo $?
${THIS_SH} -c 'set -e ; command false ; echo after' bash
command command command -p . notthere ; echo after 1
command -p command command . notthere ; echo after 2
command -p command -V type
set -x
command -v type
command command -v type
command -p command -v type
command -p -- command -v type
set +x

63
tests/case.right Normal file
View file

@ -0,0 +1,63 @@
fallthrough
to here
and here
retest
and match
no more clauses
1.0
./case.tests: line 42: xx: readonly variable
1.1
matches 1
no
no
no
no
no
ok
esac
ok 1
ok 2
ok 3
ok 4
ok 5
ok 6
ok 7
ok 8
ok 9
mysterious 1
mysterious 2
argv[1] = <\a\b\c\^A\d\e\f>
argv[1] = <\a\b\c\^A\d\e\f>
argv[1] = <abc^Adef>
ok 1
ok 2
ok 3
ok 4
ok 5
ok 6
ok 7
ok 8
--- testing: soh
ok1ok2ok3ok4ok5
ok1ok2ok3ok4ok5
ok1ok2ok3ok4ok5
ok1ok2ok3ok4ok5
ok1ok2ok3ok4ok5
ok1ok2ok3ok4ok5
ok1ok2ok3ok4ok5
--- testing: stx
ok1ok2ok3ok4ok5
ok1ok2ok3ok4ok5
ok1ok2ok3ok4ok5
ok1ok2ok3ok4ok5
ok1ok2ok3ok4ok5
ok1ok2ok3ok4ok5
ok1ok2ok3ok4ok5
--- testing: del
ok1ok2ok3ok4ok5
ok1ok2ok3ok4ok5
ok1ok2ok3ok4ok5
ok1ok2ok3ok4ok5
ok1ok2ok3ok4ok5
ok1ok2ok3ok4ok5
ok1ok2ok3ok4ok5

73
tests/case.tests Normal file
View file

@ -0,0 +1,73 @@
# 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/>.
#
case foo in
bar) echo skip ;;
foo) echo fallthrough ;&
bax) echo to here ;&
qux) echo and here;;
fop) echo but not here;;
esac
case foobar in
bar) echo skip ;;
foo*) echo retest ;;&
*bar) echo and match ;;&
qux) echo but not this ;;
esac
case a in
a) echo no more clauses;&
esac
x=0 y=1
case 1 in
$((y=0)) ) ;;
$((x=1)) ) ;&
$((x=2)) ) echo $x.$y ;;
esac
unset x
readonly xx=1
case 1 in $((xx++)) ) echo hi1 ;; *) echo hi2; esac
echo ${xx}.$?
unset var empty
var=
case ']' in
[$var]*[$var]) echo matches 1;;
*) echo no match 1 ;;
esac
case abc in ( [] ) echo yes ;; ( * ) echo no ;; esac
empty=''
case abc in ( ["$empty"] ) echo yes ;; ( * ) echo no ;; esac
case abc in ( [] | [!a-z]* ) echo yes ;; ( * ) echo no ;; esac
empty=''
case abc in ( ["$empty"] | [!a-z]* ) echo yes ;; ( * ) echo no ;; esac
case abc in (["$empty"]|[!a-z]*) echo yes ;; (*) echo no ;; esac
case " " in ( [" "] ) echo ok;; ( * ) echo no;; esac
# posix issue discovered after bash-5.1 was released
case esac in (esac) echo esac;; esac
case k in else|done|time|esac) for f in 1 2 3 ; do :; done esac
# tests of quote removal and pattern matching
${THIS_SH} ./case1.sub
${THIS_SH} ./case2.sub
${THIS_SH} ./case3.sub
${THIS_SH} ./case4.sub

77
tests/case1.sub Normal file
View file

@ -0,0 +1,77 @@
# 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/>.
#
x='\x'
case x in
\x) echo ok 1;;
*) echo bad 1;;
esac
case x in
$x) echo ok 2;;
*) echo bad 2;;
esac
case $x in
\x) echo bad 3;;
\\x) echo ok 3 ;;
*) echo bad 3.1 ;;
esac
case $x in
\\$x) echo ok 4 ;;
x) echo bad 4;;
$x) echo bad 4.1 ;;
*) echo bad 4.2;;
esac
case x in
\\x) echo bad 5;;
\x) echo ok 5;;
*) echo bad 5.1;;
esac
case x in
\\x) echo bad 6;;
x) echo ok 6;;
*) echo bad 6.1;;
esac
case x in
$x) echo ok 7 ;;
\\$x) echo bad 7 ;;
*) echo bad 7.1 ;;
esac
case x in
\x) echo ok 8 ;;
\\x) echo bad 8 ;;
*) echo bad 8.1 ;;
esac
case \x in
\x) echo ok 9 ;;
\\x) echo bad 9 ;;
*) echo bad 9.1 ;;
esac
case $x in
$x) echo oops 1 ;;
*) echo mysterious 1 ;;
esac
case \x in
\x) echo mysterious 2 ;;
*) echo oops 2 ;;
esac

65
tests/case2.sub Normal file
View file

@ -0,0 +1,65 @@
# 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/>.
#
x=$'\\a\\b\\c\\\001\\d\\e\\f'
y='\a\b\c\\d\e\f'
z=$'abc\001def'
recho "$x"
recho "$y"
recho "$z"
case $'abc\001def' in
$x) echo ok 1 ;;
*) echo oops 1;;
esac
case $z in
$x) echo ok 2 ;;
*) echo oops 2;;
esac
case $'abc\001def' in
$y) echo ok 3 ;;
*) echo oops 3;;
esac
case $z in
$y) echo ok 4 ;;
*) echo oops 4;;
esac
# no backslash before \001
x=$'\\a\\b\\c\001\\d\\e\\f'
y='\a\b\c\d\e\f'
case $'abc\001def' in
$x) echo ok 5 ;;
*) echo oops 5;;
esac
case $z in
$x) echo ok 6 ;;
*) echo oops 6;;
esac
case $'abc\001def' in
$y) echo ok 7 ;;
*) echo oops 7;;
esac
case $z in
$y) echo ok 8 ;;
*) echo oops 8;;
esac

52
tests/case3.sub Normal file
View file

@ -0,0 +1,52 @@
# 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/>.
#
testmatch() {
case $1 in
( $2 ) printf ok1 ;;
( * ) printf fail1 ;;
esac
case $1,$2 in
( $2,"$2" ) printf ok2 ;;
( * ) printf fail2 ;;
esac
case $1, in
( $2, ) printf ok3 ;;
( * ) printf fail3 ;;
esac
case ,$2 in
( ,"$2" ) printf ok4 ;;
( * ) printf fail4 ;;
esac
case "$1,$2" in
( $2,"$2" ) printf ok5 ;;
( * ) printf fail5 ;;
esac
echo
}
for c in $'\1' $'\2' $'\177'; do
echo -n "--- testing: "
echo "$c" | od -t a | awk 'NR==1 { print $2 } '
testmatch "${c}" "\\${c}"
testmatch "${c}x" "\\${c}\\x" # bash-git fails case 2 and 5 for $'\1'
testmatch "${c}x" "${c}\\x"
testmatch "${c}x" "${c}x"
testmatch "${c}x" "\\${c}x"
testmatch "x${c}" "\\x\\${c}"
testmatch "x${c}" "x\\${c}"
done
match() { case $1 in ( $2 ) ;; ( * ) return 1 ;; esac; }
match $'? *x\1y\177z' $'??\\*\\x\\\1\\y\\\177\\z' || echo bad 6

Some files were not shown because too many files have changed in this diff Show more