summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/COPYRIGHT6
-rw-r--r--tests/alias.right8
-rw-r--r--tests/alias.tests2
-rw-r--r--tests/alias1.sub20
-rw-r--r--tests/arith.right67
-rw-r--r--tests/arith.tests6
-rw-r--r--tests/array.right156
-rw-r--r--tests/array.tests39
-rw-r--r--tests/array4.sub32
-rw-r--r--tests/array5.sub34
-rw-r--r--tests/array6.sub109
-rw-r--r--tests/array7.sub14
-rw-r--r--tests/array8.sub23
-rw-r--r--tests/array9.sub27
-rw-r--r--tests/assoc.right189
-rw-r--r--tests/assoc.tests186
-rw-r--r--tests/assoc1.sub16
-rw-r--r--tests/assoc2.sub15
-rw-r--r--tests/assoc3.sub15
-rw-r--r--tests/assoc4.sub22
-rw-r--r--tests/assoc5.sub27
-rw-r--r--tests/assoc6.sub146
-rw-r--r--tests/braces.right31
-rw-r--r--tests/braces.tests41
-rw-r--r--tests/builtins.right15
-rw-r--r--tests/builtins.tests3
-rw-r--r--tests/builtins1.sub2
-rw-r--r--tests/case.right6
-rw-r--r--tests/case.tests18
-rw-r--r--tests/casemod.right45
-rw-r--r--tests/casemod.tests99
-rw-r--r--tests/comsub-eof.right13
-rw-r--r--tests/comsub-eof.tests11
-rw-r--r--tests/comsub-eof0.sub4
-rw-r--r--tests/comsub-eof1.sub4
-rw-r--r--tests/comsub-eof2.sub2
-rw-r--r--tests/comsub-eof3.sub4
-rw-r--r--tests/comsub-eof4.sub4
-rw-r--r--tests/comsub-eof5.sub9
-rw-r--r--tests/comsub-posix.right57
-rw-r--r--tests/comsub-posix.tests207
-rw-r--r--tests/comsub-posix1.sub3
-rw-r--r--tests/comsub.right29
-rw-r--r--tests/comsub.tests44
-rw-r--r--tests/comsub1.sub48
-rw-r--r--tests/cond-regexp.sub42
-rw-r--r--tests/cond.right24
-rwxr-xr-xtests/cond.tests24
-rw-r--r--tests/coproc.right13
-rw-r--r--tests/coproc.tests45
-rw-r--r--tests/dbg-support.right26
-rwxr-xr-xtests/dbg-support.tests3
-rw-r--r--tests/dbg-support3.sub39
-rwxr-xr-xtests/dollar-at-star12
-rw-r--r--tests/dollar-at3.sub9
-rw-r--r--tests/dollar-star3.sub18
-rw-r--r--tests/dollar-star4.sub9
-rw-r--r--tests/dollar-star5.sub16
-rw-r--r--tests/dollar.right32
-rw-r--r--tests/dstack.right4
-rw-r--r--tests/dstack.tests2
-rw-r--r--tests/errors.right15
-rw-r--r--tests/exec.right9
-rw-r--r--tests/exec8.sub1
-rw-r--r--tests/execscript4
-rw-r--r--tests/exp.right21
-rw-r--r--tests/exp.tests (renamed from tests/exp-tests)6
-rw-r--r--tests/exp1.sub21
-rw-r--r--tests/exp2.sub12
-rw-r--r--tests/exp3.sub7
-rw-r--r--tests/extglob.right1
-rw-r--r--tests/extglob.tests10
-rw-r--r--tests/extglob1.sub37
-rw-r--r--tests/func.right7
-rw-r--r--tests/func2.sub10
-rw-r--r--tests/glob.right2
-rw-r--r--tests/glob.tests (renamed from tests/glob-test)2
-rw-r--r--tests/globstar.right155
-rw-r--r--tests/globstar.tests41
-rw-r--r--tests/globstar1.sub21
-rw-r--r--tests/heredoc.right21
-rw-r--r--tests/heredoc.tests6
-rw-r--r--tests/heredoc1.sub16
-rw-r--r--tests/history.right39
-rw-r--r--tests/history.tests15
-rw-r--r--tests/history1.sub13
-rw-r--r--tests/history2.sub10
-rw-r--r--tests/intl.right3
-rw-r--r--tests/intl.tests5
-rw-r--r--tests/intl1.sub11
-rw-r--r--tests/jobs.right4
-rw-r--r--tests/jobs.tests2
-rw-r--r--tests/mapfile.data17
-rw-r--r--tests/mapfile.right138
-rw-r--r--tests/mapfile.tests42
-rw-r--r--tests/mapfile1.sub11
-rw-r--r--tests/new-exp.right28
-rw-r--r--tests/new-exp.tests16
-rw-r--r--tests/new-exp5.sub10
-rw-r--r--tests/new-exp6.sub29
-rw-r--r--tests/new-exp7.sub13
-rw-r--r--tests/nquote.right3
-rw-r--r--tests/nquote.tests2
-rw-r--r--tests/nquote1.sub6
-rw-r--r--tests/nquote5.right86
-rw-r--r--tests/nquote5.tests63
-rw-r--r--tests/printf.rightbin1287 -> 1510 bytes
-rw-r--r--tests/printf.tests56
-rw-r--r--tests/printf2.sub6
-rw-r--r--tests/read.right15
-rw-r--r--tests/read.tests3
-rw-r--r--tests/read2.sub14
-rw-r--r--tests/read6.sub10
-rw-r--r--tests/redir.right45
-rw-r--r--tests/redir.tests67
-rw-r--r--tests/redir8.sub59
-rw-r--r--tests/redir9.sub50
-rw-r--r--tests/rsh.right2
-rw-r--r--tests/run-array2
-rw-r--r--tests/run-assoc4
-rw-r--r--tests/run-builtins4
-rw-r--r--tests/run-case2
-rw-r--r--tests/run-casemod2
-rw-r--r--tests/run-comsub2
-rw-r--r--tests/run-comsub-eof2
-rw-r--r--tests/run-comsub-posix2
-rw-r--r--tests/run-coproc4
-rw-r--r--tests/run-exp-tests2
-rw-r--r--tests/run-glob-test2
-rw-r--r--tests/run-globstar4
-rw-r--r--tests/run-invert2
-rw-r--r--tests/run-mapfile2
-rw-r--r--tests/run-minimal2
-rw-r--r--tests/run-nquote42
-rw-r--r--tests/run-nquote52
-rw-r--r--tests/run-set-e2
-rw-r--r--tests/run-trap6
-rw-r--r--tests/run-vredir2
-rw-r--r--tests/set-e.right39
-rw-r--r--tests/set-e.tests (renamed from tests/set-e-test)26
-rw-r--r--tests/set-e1.sub59
-rw-r--r--tests/set-e2.sub10
-rw-r--r--tests/set-x.right28
-rwxr-xr-xtests/set-x.tests7
-rw-r--r--tests/set-x1.sub25
-rw-r--r--tests/shopt.right23
-rw-r--r--tests/source5.sub2
-rw-r--r--tests/source6.sub31
-rw-r--r--tests/test.right1
-rw-r--r--tests/test.tests3
-rw-r--r--tests/trap.right11
-rw-r--r--tests/trap.tests7
-rw-r--r--tests/trap3.sub9
-rw-r--r--tests/type.right34
-rw-r--r--tests/type.tests11
-rw-r--r--tests/type1.sub10
-rw-r--r--tests/type2.sub16
-rw-r--r--tests/vredir.right88
-rw-r--r--tests/vredir.tests44
-rw-r--r--tests/vredir1.sub17
-rw-r--r--tests/vredir2.sub52
-rw-r--r--tests/vredir3.sub8
-rw-r--r--tests/vredir4.sub22
-rw-r--r--tests/vredir5.sub23
164 files changed, 3979 insertions, 173 deletions
diff --git a/tests/COPYRIGHT b/tests/COPYRIGHT
new file mode 100644
index 0000000..c69f297
--- /dev/null
+++ b/tests/COPYRIGHT
@@ -0,0 +1,6 @@
+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
+Free Software Foundation, Inc.
+
+The file ifs-posix.tests is Copyright (C) 2005 Glen Fowler.
diff --git a/tests/alias.right b/tests/alias.right
index 53111be..a37080c 100644
--- a/tests/alias.right
+++ b/tests/alias.right
@@ -2,3 +2,11 @@ alias: 0
alias: 0
./alias.tests: line 25: qfoo: command not found
quux
+bar
+value
+bar
+value
+OK
+OK
+OK
+OK
diff --git a/tests/alias.tests b/tests/alias.tests
index 9cfec16..a97d5ff 100644
--- a/tests/alias.tests
+++ b/tests/alias.tests
@@ -35,3 +35,5 @@ alias baz=quux
foo bar
unalias foo bar baz
+
+${THIS_SH} ./alias1.sub
diff --git a/tests/alias1.sub b/tests/alias1.sub
new file mode 100644
index 0000000..ed03031
--- /dev/null
+++ b/tests/alias1.sub
@@ -0,0 +1,20 @@
+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'
diff --git a/tests/arith.right b/tests/arith.right
index 1365786..51d740e 100644
--- a/tests/arith.right
+++ b/tests/arith.right
@@ -51,6 +51,7 @@
1
1
32
+4
20
1,i+=2
30
@@ -59,7 +60,7 @@
1,i+=2
30
1,j+=2
-./arith.tests: line 108: 1 ? 20 : x+=2: attempted assignment to non-variable (error token is "+=2")
+./arith.tests: line 114: 1 ? 20 : x+=2: attempted assignment to non-variable (error token is "+=2")
20
6
6,5,3
@@ -79,16 +80,16 @@
36
62
63
-./arith.tests: line 143: 3425#56: invalid arithmetic base (error token is "3425#56")
+./arith.tests: line 149: 3425#56: invalid arithmetic base (error token is "3425#56")
0
-./arith.tests: line 149: 7 = 43 : attempted assignment to non-variable (error token is "= 43 ")
-./arith.tests: line 150: 2#44: value too great for base (error token is "2#44")
-./arith.tests: line 151: 44 / 0 : division by 0 (error token is " ")
-./arith.tests: line 152: let: jv += $iv: syntax error: operand expected (error token is "$iv")
-./arith.tests: line 153: jv += $iv : syntax error: operand expected (error token is "$iv ")
-./arith.tests: line 154: let: rv = 7 + (43 * 6: missing `)' (error token is "6")
-./arith.tests: line 158: 0#4: invalid number (error token is "0#4")
-./arith.tests: line 159: 2#110#11: invalid number (error token is "2#110#11")
+./arith.tests: line 155: 7 = 43 : attempted assignment to non-variable (error token is "= 43 ")
+./arith.tests: line 156: 2#44: value too great for base (error token is "2#44")
+./arith.tests: line 157: 44 / 0 : division by 0 (error token is "0 ")
+./arith.tests: line 158: let: jv += $iv: syntax error: operand expected (error token is "$iv")
+./arith.tests: line 159: jv += $iv : syntax error: operand expected (error token is "$iv ")
+./arith.tests: line 160: let: rv = 7 + (43 * 6: missing `)' (error token is "6")
+./arith.tests: line 164: 0#4: invalid number (error token is "0#4")
+./arith.tests: line 165: 2#110#11: invalid number (error token is "2#110#11")
abc
def
ghi
@@ -96,15 +97,15 @@ ok
6
1
0
-./arith.tests: line 177: 4 + : syntax error: operand expected (error token is " ")
+./arith.tests: line 183: 4 + : syntax error: operand expected (error token is "+ ")
16
-./arith.tests: line 182: 4 ? : 3 + 5 : expression expected (error token is ": 3 + 5 ")
-./arith.tests: line 183: 1 ? 20 : `:' expected for conditional expression (error token is " ")
-./arith.tests: line 184: 4 ? 20 : : expression expected (error token is " ")
+./arith.tests: line 188: 4 ? : 3 + 5 : expression expected (error token is ": 3 + 5 ")
+./arith.tests: line 189: 1 ? 20 : `:' expected for conditional expression (error token is "20 ")
+./arith.tests: line 190: 4 ? 20 : : expression expected (error token is ": ")
9
-./arith.tests: line 190: 0 && B=42 : attempted assignment to non-variable (error token is "=42 ")
+./arith.tests: line 196: 0 && B=42 : attempted assignment to non-variable (error token is "=42 ")
9
-./arith.tests: line 193: 1 || B=88 : attempted assignment to non-variable (error token is "=88 ")
+./arith.tests: line 199: 1 || B=88 : attempted assignment to non-variable (error token is "=88 ")
9
0
9
@@ -130,20 +131,20 @@ ok
4
4
7
-./arith.tests: line 241: 7-- : syntax error: operand expected (error token is " ")
-./arith.tests: line 243: --x=7 : attempted assignment to non-variable (error token is "=7 ")
-./arith.tests: line 244: ++x=7 : attempted assignment to non-variable (error token is "=7 ")
-./arith.tests: line 246: x++=7 : attempted assignment to non-variable (error token is "=7 ")
-./arith.tests: line 247: x--=7 : attempted assignment to non-variable (error token is "=7 ")
+./arith.tests: line 247: 7-- : syntax error: operand expected (error token is "- ")
+./arith.tests: line 249: --x=7 : attempted assignment to non-variable (error token is "=7 ")
+./arith.tests: line 250: ++x=7 : attempted assignment to non-variable (error token is "=7 ")
+./arith.tests: line 252: x++=7 : attempted assignment to non-variable (error token is "=7 ")
+./arith.tests: line 253: x--=7 : attempted assignment to non-variable (error token is "=7 ")
4
7
-7
7
7
-./arith1.sub: line 2: 4-- : syntax error: operand expected (error token is " ")
-./arith1.sub: line 3: 4++ : syntax error: operand expected (error token is " ")
-./arith1.sub: line 4: 4 -- : syntax error: operand expected (error token is " ")
-./arith1.sub: line 5: 4 ++ : syntax error: operand expected (error token is " ")
+./arith1.sub: line 2: 4-- : syntax error: operand expected (error token is "- ")
+./arith1.sub: line 3: 4++ : syntax error: operand expected (error token is "+ ")
+./arith1.sub: line 4: 4 -- : syntax error: operand expected (error token is "- ")
+./arith1.sub: line 5: 4 ++ : syntax error: operand expected (error token is "+ ")
1
2
1
@@ -158,10 +159,10 @@ ok
2
-2
1
-./arith1.sub: line 35: ((: ++ : syntax error: operand expected (error token is " ")
+./arith1.sub: line 35: ((: ++ : syntax error: operand expected (error token is "+ ")
7
7
-./arith1.sub: line 38: ((: -- : syntax error: operand expected (error token is " ")
+./arith1.sub: line 38: ((: -- : syntax error: operand expected (error token is "- ")
7
7
7
@@ -180,10 +181,10 @@ ok
1
4
0
-./arith2.sub: line 33: ((: -- : syntax error: operand expected (error token is " ")
+./arith2.sub: line 33: ((: -- : syntax error: operand expected (error token is "- ")
-7
-7
-./arith2.sub: line 37: ((: ++ : syntax error: operand expected (error token is " ")
+./arith2.sub: line 37: ((: ++ : syntax error: operand expected (error token is "+ ")
7
7
-7
@@ -191,13 +192,13 @@ ok
7
7
8 12
-./arith.tests: line 268: ((: x=9 y=41 : syntax error in expression (error token is "y=41 ")
-./arith.tests: line 272: a b: syntax error in expression (error token is "b")
-./arith.tests: line 273: ((: a b: syntax error in expression (error token is "b")
+./arith.tests: line 274: ((: x=9 y=41 : syntax error in expression (error token is "y=41 ")
+./arith.tests: line 278: a b: syntax error in expression (error token is "b")
+./arith.tests: line 279: ((: a b: syntax error in expression (error token is "b")
42
42
42
42
42
42
-./arith.tests: line 284: b[c]d: syntax error in expression (error token is "d")
+./arith.tests: line 290: b[c]d: syntax error in expression (error token is "d")
diff --git a/tests/arith.tests b/tests/arith.tests
index 33622e7..9e82bb1 100644
--- a/tests/arith.tests
+++ b/tests/arith.tests
@@ -84,6 +84,12 @@ 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
diff --git a/tests/array.right b/tests/array.right
index 53a7a00..fdc0793 100644
--- a/tests/array.right
+++ b/tests/array.right
@@ -25,13 +25,13 @@ bdef
hello world
11
3
-bdef hello world test expression
-./array.tests: line 74: readonly: `a[5]': not a valid identifier
-declare -ar a='([1]="" [2]="bdef" [5]="hello world" [6]="test expression")'
+bdef hello world test expression test 2
+./array.tests: line 76: 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")'
+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")'
+readonly -a a='([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="test 2")'
readonly -a c='()'
a test
declare -a BASH_ARGC='()'
@@ -40,36 +40,36 @@ declare -a BASH_LINENO='([0]="0")'
declare -a BASH_SOURCE='([0]="./array.tests")'
declare -a DIRSTACK='()'
declare -a FUNCNAME='([0]="main")'
-declare -ar a='([1]="" [2]="bdef" [5]="hello world" [6]="test expression")'
+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 98: a: readonly variable
-./array.tests: line 100: b[]: bad array subscript
-./array.tests: line 101: b[*]: bad array subscript
-./array.tests: line 102: ${b[ ]}: bad substitution
-./array.tests: line 104: c[-2]: bad array subscript
-./array.tests: line 105: c: bad array subscript
+./array.tests: line 100: a: readonly variable
+./array.tests: line 102: b[]: bad array subscript
+./array.tests: line 103: b[*]: bad array subscript
+./array.tests: line 104: ${b[ ]}: bad substitution
+./array.tests: line 106: c[-2]: bad array subscript
+./array.tests: line 107: c: bad array subscript
-./array.tests: line 107: d[7]: cannot assign list to array member
-./array.tests: line 109: []=abcde: bad array subscript
-./array.tests: line 109: [*]=last: cannot assign to non-numeric index
-./array.tests: line 109: [-65]=negative: bad array subscript
+./array.tests: line 109: d[7]: cannot assign list to array member
+./array.tests: line 111: []=abcde: bad array subscript
+./array.tests: line 111: [*]=last: cannot assign to non-numeric index
+./array.tests: line 111: [-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='([0]="main")'
-declare -ar a='([1]="" [2]="bdef" [5]="hello world" [6]="test expression")'
+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 f='([0]="" [1]="bdef" [2]="hello world" [3]="test" [4]="ninth element")'
-./array.tests: line 117: unset: ps1: not an array variable
-./array.tests: line 121: declare: c: cannot destroy array variables in this way
+./array.tests: line 119: unset: ps1: not an array variable
+./array.tests: line 123: declare: c: cannot destroy array variables in this way
this of
this is a test of read using arrays
this test
@@ -80,7 +80,7 @@ declare -a BASH_LINENO='([0]="0")'
declare -a BASH_SOURCE='([0]="./array.tests")'
declare -a DIRSTACK='()'
declare -a FUNCNAME='([0]="main")'
-declare -ar a='([1]="" [2]="bdef" [5]="hello world" [6]="test expression")'
+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")'
@@ -127,7 +127,7 @@ grep [ 123 ] *
6 7 9 5
length = 3
value = new1 new2 new3
-./array.tests: line 237: narray: unbound variable
+./array.tests: line 239: 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: syntax error near unexpected token `('
@@ -152,10 +152,10 @@ for case if then else
12 14 16 18 20
4414758999202
aaa bbb
-./array.tests: line 285: syntax error near unexpected token `<>'
-./array.tests: line 285: `metas=( <> < > ! )'
-./array.tests: line 286: syntax error near unexpected token `<>'
-./array.tests: line 286: `metas=( [1]=<> [2]=< [3]=> [4]=! )'
+./array.tests: line 289: syntax error near unexpected token `<>'
+./array.tests: line 289: `metas=( <> < > ! )'
+./array.tests: line 290: syntax error near unexpected token `<>'
+./array.tests: line 290: `metas=( [1]=<> [2]=< [3]=> [4]=! )'
abc 3
case 4
abc case if then else 5
@@ -206,3 +206,109 @@ t
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 \'abc>
+argv[2] = <-iname \'def>
+argv[1] = <-iname>
+argv[2] = <'abc>
+argv[3] = <-iname>
+argv[4] = <'def>
+argv[1] = <"-iname '"abc>
+argv[2] = <"-iname '"def>
+argv[1] = <-iname 'abc>
+argv[2] = <-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] = <€>
diff --git a/tests/array.tests b/tests/array.tests
index ce46179..435ac15 100644
--- a/tests/array.tests
+++ b/tests/array.tests
@@ -69,6 +69,8 @@ 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]
@@ -253,6 +255,8 @@ foo=([10]="bar")
echo ${foo[0]}
rm 1=bar
+cd $OLDPWD
+
foo=(a b c d e f g)
echo ${foo[@]}
@@ -372,34 +376,13 @@ declare -a x=($0)
declare -a x=(\$0)
echo "${x[@]}"
-: ${TMPDIR:=/tmp}
-
-mkdir $TMPDIR/bash-test-$$
-cd $TMPDIR/bash-test-$$
-
-trap "cd / ; 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]
+# tests for bash-3.1 problems
+${THIS_SH} ./array5.sub
-x[9]='9'
+# tests for post-bash-3.2 problems, most fixed in bash-3.2 patches
+${THIS_SH} ./array6.sub
+${THIS_SH} ./array7.sub
-echo ${x[*]: -1}
+${THIS_SH} ./array8.sub
-TOOLKIT=(1 2 3 4 5 6 7 8 9 10)
-ARRAY="1"
-echo ${TOOLKIT["$ARRAY"]}
+${THIS_SH} ./array9.sub
diff --git a/tests/array4.sub b/tests/array4.sub
new file mode 100644
index 0000000..97c766d
--- /dev/null
+++ b/tests/array4.sub
@@ -0,0 +1,32 @@
+# 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 ))]}
diff --git a/tests/array5.sub b/tests/array5.sub
new file mode 100644
index 0000000..778a28d
--- /dev/null
+++ b/tests/array5.sub
@@ -0,0 +1,34 @@
+
+: ${TMPDIR:=/tmp}
+
+mkdir $TMPDIR/bash-test-$$
+cd $TMPDIR/bash-test-$$
+
+trap "cd / ; 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
diff --git a/tests/array6.sub b/tests/array6.sub
new file mode 100644
index 0000000..5901326
--- /dev/null
+++ b/tests/array6.sub
@@ -0,0 +1,109 @@
+# 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[@]}"
+
+a2=("${a[@]/#/-iname \'}")
+recho "${a2[@]}"
+
+eval a2=("${a[@]/#/-iname \'}")
+recho "${a2[@]}"
+
+set -- abc def
+
+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
diff --git a/tests/array7.sub b/tests/array7.sub
new file mode 100644
index 0000000..8935cc2
--- /dev/null
+++ b/tests/array7.sub
@@ -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}
diff --git a/tests/array8.sub b/tests/array8.sub
new file mode 100644
index 0000000..481ccdb
--- /dev/null
+++ b/tests/array8.sub
@@ -0,0 +1,23 @@
+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[@]^^?}"
+
diff --git a/tests/array9.sub b/tests/array9.sub
new file mode 100644
index 0000000..444247f
--- /dev/null
+++ b/tests/array9.sub
@@ -0,0 +1,27 @@
+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[@]}"
+
diff --git a/tests/assoc.right b/tests/assoc.right
new file mode 100644
index 0000000..8615519
--- /dev/null
+++ b/tests/assoc.right
@@ -0,0 +1,189 @@
+declare -A BASH_ALIASES='()'
+declare -A BASH_CMDS='()'
+declare -A fluff='()'
+declare -A BASH_ALIASES='()'
+declare -A BASH_CMDS='()'
+declare -A fluff='([bar]="two" [foo]="one" )'
+declare -A fluff='([bar]="two" [foo]="one" )'
+declare -A fluff='([bar]="two" )'
+declare -A fluff='([bar]="newval" [qux]="assigned" )'
+./assoc.tests: line 26: 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='([version]="4.0-devel" [source]="./assoc.tests" [lineno]="28" [pid]="42134" )'
+declare -A wheat='([one]="a" [zero]="0" [two]="b" [three]="c" )'
+declare -A chaff='([one]="10" ["hello world"]="flip" [zero]="5" )'
+./assoc.tests: line 38: unset: waste: cannot unset: readonly variable
+./assoc.tests: line 39: chaff[*]: bad array subscript
+./assoc.tests: line 40: [*]=12: invalid associative array key
+declare -A chaff='([one]="a" ["hello world"]="flip" )'
+flip
+argv[1] = <a>
+argv[2] = <flip>
+argv[3] = <multiple>
+argv[4] = <words>
+argv[1] = <a>
+argv[2] = <flip>
+argv[3] = <multiple words>
+argv[1] = <a>
+argv[2] = <flip>
+argv[3] = <multiple>
+argv[4] = <words>
+argv[1] = <a flip multiple words>
+./assoc.tests: line 57: declare: chaff: cannot destroy array variables in this way
+./assoc.tests: line 59: chaff[*]: bad array subscript
+./assoc.tests: line 60: [*]=12: invalid associative array key
+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] = <flix>
+argv[2] = <6>
+argv[1] = <six>
+argv[2] = <foo>
+argv[3] = <bar>
+argv[1] = <six>
+argv[2] = <foo bar>
+8
+/usr/local/bin . /bin /sbin /usr/sbin /usr/bin /bin /usr/ucb
+bin . bin sbin sbin bin bin ucb
+bin
+/ / / / / / /
+/
+argv[1] = <bin>
+argv[1] = </>
+argv[1] = <sbin>
+argv[1] = </>
+8
+/usr/local/bin . /bin /sbin /usr/sbin /usr/bin /bin /usr/ucb
+bin . bin sbin sbin bin bin ucb
+/ / / / / / /
+8
+4 -- /bin
+^usr^local^bin . ^bin ^sbin ^usr^sbin ^usr^bin ^bin ^usr^ucb
+^usr^local^bin . ^bin ^sbin ^usr^sbin ^usr^bin ^bin ^usr^ucb
+\usr/local/bin . \bin \sbin \usr/sbin \usr/bin \bin \usr/ucb
+\usr\local\bin . \bin \sbin \usr\sbin \usr\bin \bin \usr\ucb
+\usr\local\bin . \bin \sbin \usr\sbin \usr\bin \bin \usr\ucb
+([a]=1)
+
+qux foo
+/usr/local/bin/qux /usr/sbin/foo
+hits command
+ 0 /sbin/blat
+ 0 /usr/local/bin/qux
+ 0 /bin/sh
+ 0 /usr/sbin/foo
+blat qux sh foo
+/sbin/blat /usr/local/bin/qux /bin/sh /usr/sbin/foo
+
+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'
+sh foo blat qux
+argv[1] = </bin/bash --login -o posix>
+argv[2] = </usr/sbin/foo>
+argv[3] = <cd /blat ; echo $PWD>
+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] = <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] = <>
+abc
+def
+def
+./assoc5.sub: line 13: declare: `myarray[foo[bar]=bleh': not a valid identifier
+abc def bleh
+myarray=(["a]a"]="abc" ["]"]="def" ["a]=test1;#a"]="123" [foo]="bleh" )
+
+123
+myarray=(["a]a"]="abc" ["a]=test2;#a"]="def" ["]"]="def" ["a]=test1;#a"]="123" [foo]="bleh" )
+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" )'
diff --git a/tests/assoc.tests b/tests/assoc.tests
new file mode 100644
index 0000000..8b6fd55
--- /dev/null
+++ b/tests/assoc.tests
@@ -0,0 +1,186 @@
+# 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 - compount 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 - errors
+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 /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
+
+${THIS_SH} ./assoc1.sub
+
+${THIS_SH} ./assoc2.sub
+
+${THIS_SH} ./assoc3.sub
+
+${THIS_SH} ./assoc4.sub
+
+${THIS_SH} ./assoc5.sub
+
+${THIS_SH} ./assoc6.sub
diff --git a/tests/assoc1.sub b/tests/assoc1.sub
new file mode 100644
index 0000000..a045bde
--- /dev/null
+++ b/tests/assoc1.sub
@@ -0,0 +1,16 @@
+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[@]}"
diff --git a/tests/assoc2.sub b/tests/assoc2.sub
new file mode 100644
index 0000000..396b87a
--- /dev/null
+++ b/tests/assoc2.sub
@@ -0,0 +1,15 @@
+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[@]}"
diff --git a/tests/assoc3.sub b/tests/assoc3.sub
new file mode 100644
index 0000000..9129ef1
--- /dev/null
+++ b/tests/assoc3.sub
@@ -0,0 +1,15 @@
+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[@]}"
+
diff --git a/tests/assoc4.sub b/tests/assoc4.sub
new file mode 100644
index 0000000..1516dc5
--- /dev/null
+++ b/tests/assoc4.sub
@@ -0,0 +1,22 @@
+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[@]^^?}"
diff --git a/tests/assoc5.sub b/tests/assoc5.sub
new file mode 100644
index 0000000..400f3d3
--- /dev/null
+++ b/tests/assoc5.sub
@@ -0,0 +1,27 @@
+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=
diff --git a/tests/assoc6.sub b/tests/assoc6.sub
new file mode 100644
index 0000000..54112ee
--- /dev/null
+++ b/tests/assoc6.sub
@@ -0,0 +1,146 @@
+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
diff --git a/tests/braces.right b/tests/braces.right
index f00d39a..a02bfc6 100644
--- a/tests/braces.right
+++ b/tests/braces.right
@@ -43,3 +43,34 @@ f
-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
+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}
diff --git a/tests/braces.tests b/tests/braces.tests
index 5a57f28..c2b153e 100644
--- a/tests/braces.tests
+++ b/tests/braces.tests
@@ -73,3 +73,44 @@ echo {-20..0}
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}
+
+# 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}
diff --git a/tests/builtins.right b/tests/builtins.right
index 9266b5a..30e10ca 100644
--- a/tests/builtins.right
+++ b/tests/builtins.right
@@ -108,6 +108,15 @@ m n o p
./source5.sub: line 10: /tmp/source-notthere: No such file or directory
after bad source 1
./source5.sub: line 17: /tmp/source-notthere: No such file or directory
+one - OK
+0
+0
+two - OK
+0
+three - OK
+0
+four - OK
+0
AVAR
foo
foo
@@ -118,15 +127,15 @@ AVAR
foo
declare -x foo=""
declare -x FOO="\$\$"
-./builtins.tests: line 207: declare: FOO: not found
+./builtins.tests: line 210: declare: FOO: not found
declare -x FOO="\$\$"
ok
ok
-./builtins.tests: line 239: kill: 4096: invalid signal specification
+./builtins.tests: line 242: kill: 4096: invalid signal specification
1
a\n\n\nb
a
b
-./builtins.tests: line 248: exit: status: numeric argument required
+./builtins.tests: line 251: exit: status: numeric argument required
diff --git a/tests/builtins.tests b/tests/builtins.tests
index 3c28633..6d20ae9 100644
--- a/tests/builtins.tests
+++ b/tests/builtins.tests
@@ -176,6 +176,9 @@ ${THIS_SH} ./builtins1.sub
# test behavior of `.' when given a non-existant file argument
${THIS_SH} ./source5.sub
+# test bugs in sourcing non-regular files, fixed post-bash-3.2
+${THIS_SH} ./source6.sub
+
# in posix mode, assignment statements preceding special builtins are
# reflected in the shell environment. `.' and `eval' need special-case
# code.
diff --git a/tests/builtins1.sub b/tests/builtins1.sub
index 5b79711..52185b5 100644
--- a/tests/builtins1.sub
+++ b/tests/builtins1.sub
@@ -10,5 +10,5 @@ cd $DIR
pwd
echo $PWD
-cd $MYDIR
+cd "$MYDIR"
rmdir $FULLDIR
diff --git a/tests/case.right b/tests/case.right
new file mode 100644
index 0000000..d579253
--- /dev/null
+++ b/tests/case.right
@@ -0,0 +1,6 @@
+fallthrough
+to here
+and here
+retest
+and match
+no more clauses
diff --git a/tests/case.tests b/tests/case.tests
new file mode 100644
index 0000000..7c50165
--- /dev/null
+++ b/tests/case.tests
@@ -0,0 +1,18 @@
+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
diff --git a/tests/casemod.right b/tests/casemod.right
new file mode 100644
index 0000000..958b28d
--- /dev/null
+++ b/tests/casemod.right
@@ -0,0 +1,45 @@
+Acknowledgement
+ACKNOWLEDGEMENT
+Oenophile
+OEnOphIlE
+aCKNOWLEDGEMENT
+acknowledgement
+oENOPHILE
+oENOPHILE
+oeNoPHiLe
+Acknowledgement Oenophile
+AcknOwlEdgEmEnt OEnOphIlE
+aCKNOWLEDGEMENT oENOPHILE
+aCKNoWLeDGeMeNT oeNoPHiLe
+aCKNOWLEDGEMENT oENOPHILE
+acknowledgement oenophile
+Acknowledgement Oenophile
+ACKNOWLEDGEMENT OENOPHILE
+Acknowledgement Oenophile
+AcknOwlEdgEmEnt OEnOphIlE
+oENOPHILE aCKNOWLEDGEMENT
+oenophile acknowledgement
+oENOPHILE aCKNOWLEDGEMENT
+oeNoPHiLe aCKNoWLeDGeMeNT
+Acknowledgement Oenophile
+ACKNOWLEDGEMENT OENOPHILE
+acknowledgement oenophile
+ackNowLEdgEmENT oENophiLE
+acknowledgement oenophile
+ackNowLEdgEmENT oENophiLE
+acknowledgement oenophile
+acknowledgement oenophile
+acknowledgement oenophile
+acknowledgement oenophile
+Acknowledgement Oenophile
+ACKNOWLEDGEMENT OENOPHILE
+BE CONSERVATIVE IN WHAT YOU SEND AND LIBERAL IN WHAT YOU ACCEPT
+be conservative in what you send and liberal in what you accept
+Be conservative in what you send and liberal in what you accept
+Be conservative in what you send and liberal in what you accept
+be Conservative in what you send and Liberal in what you accept
+be conservative in what you send and liberal in what you accept
+Be Conservative in what you send and Liberal in what you accept
+BE CONSERVATIVE IN WHAT YOU SEND AND LIBERAL IN WHAT YOU ACCEPT
+Be conservative in what you send and liberal in what you accept
+BE CONSERVATIVE IN WHAT YOU SEND AND LIBERAL IN WHAT YOU ACCEPT
diff --git a/tests/casemod.tests b/tests/casemod.tests
new file mode 100644
index 0000000..3c7ad23
--- /dev/null
+++ b/tests/casemod.tests
@@ -0,0 +1,99 @@
+S1=acknowledgement
+S2=oenophile
+
+echo ${S1^}
+echo ${S1^^}
+
+echo ${S2^[aeiou]}
+echo ${S2^^[aeiou]}
+
+U1=${S1^^}
+U2=${S2^^}
+
+echo ${U1,}
+echo ${U1,,}
+
+echo ${U2,}
+echo ${U2,[AEIOU]}
+echo ${U2,,[AEIOU]}
+
+A1=( $S1 $S2 )
+
+echo ${A1[@]^[aeiou]}
+echo ${A1[@]^^[aeiou]}
+
+A2=( $U1 $U2 )
+
+echo ${A2[@],[AEIOU]}
+echo ${A2[@],,[AEIOU]}
+
+echo ${A2[@],?}
+echo ${A2[@],,?}
+
+declare -A AA1 AA2
+
+AA1[ack]=$S1
+AA1[oen]=$S2
+
+echo ${AA1[@]^}
+echo ${AA1[@]^^}
+
+echo ${AA1[@]^[aeiou]}
+echo ${AA1[@]^^[aeiou]}
+
+AA2[ACK]=$U1
+AA2[OEN]=$U2
+
+echo ${AA2[@],}
+echo ${AA2[@],,}
+
+echo ${AA2[@],[AEIOU]}
+echo ${AA2[@],,[AEIOU]}
+
+set -- $S1 $S2
+
+echo ${@^}
+echo ${@^^}
+
+
+echo ${S1^[rstlne]} ${S2^[rstlne]}
+echo ${S1^^[rstlne]} ${S2^^[rstlne]}
+
+echo ${@^[rstlne]}
+echo ${@^^[rstlne]}
+
+echo ${S1,[rstlne]} ${S2,[rstlne]}
+echo ${S1,,[rstlne]} ${S2,,[rstlne]}
+
+echo ${@,[rstlne]}
+echo ${@,,[rstlne]}
+
+echo ${@^?}
+echo ${@^^?}
+
+# make sure that multiple words in the string are handled as other expansions
+TEXT="Be Conservative in what you send and Liberal in what you accept"
+TEXT2="be conservative in what you send and liberal in what you accept"
+
+declare -u foo
+foo=$TEXT
+echo $foo
+
+declare -l bar
+bar=$TEXT
+echo $bar
+
+declare -c qux
+qux=$TEXT
+echo $qux
+qux=$TEXT2
+echo $qux
+
+echo ${TEXT,}
+echo ${TEXT,,}
+
+echo ${TEXT^}
+echo ${TEXT^^}
+
+echo ${TEXT2^}
+echo ${TEXT2^^}
diff --git a/tests/comsub-eof.right b/tests/comsub-eof.right
new file mode 100644
index 0000000..452a9c5
--- /dev/null
+++ b/tests/comsub-eof.right
@@ -0,0 +1,13 @@
+./comsub-eof0.sub: line 1: unexpected EOF while looking for matching `)'
+./comsub-eof0.sub: line 5: syntax error: unexpected end of file
+hi
+./comsub-eof2.sub: line 2: warning: here-document at line 1 delimited by end-of-file (wanted `EOF')
+hi
+./comsub-eof3.sub: line 1: unexpected EOF while looking for matching `)'
+./comsub-eof3.sub: line 5: syntax error: unexpected end of file
+./comsub-eof4.sub: line 6: warning: here-document at line 4 delimited by end-of-file (wanted `EOF')
+contents
+./comsub-eof5.sub: line 8: warning: here-document at line 6 delimited by end-of-file (wanted `)')
+hi
+./comsub-eof5.sub: line 13: warning: here-document at line 11 delimited by end-of-file (wanted `EOF')
+hi
diff --git a/tests/comsub-eof.tests b/tests/comsub-eof.tests
new file mode 100644
index 0000000..f96aeee
--- /dev/null
+++ b/tests/comsub-eof.tests
@@ -0,0 +1,11 @@
+${THIS_SH} ./comsub-eof0.sub
+
+${THIS_SH} ./comsub-eof1.sub
+
+${THIS_SH} ./comsub-eof2.sub
+
+${THIS_SH} ./comsub-eof3.sub
+
+${THIS_SH} ./comsub-eof4.sub
+
+${THIS_SH} ./comsub-eof5.sub
diff --git a/tests/comsub-eof0.sub b/tests/comsub-eof0.sub
new file mode 100644
index 0000000..7b0775f
--- /dev/null
+++ b/tests/comsub-eof0.sub
@@ -0,0 +1,4 @@
+foo=$(cat <<EOF
+hi
+EOF )
+echo $foo
diff --git a/tests/comsub-eof1.sub b/tests/comsub-eof1.sub
new file mode 100644
index 0000000..eaa0e97
--- /dev/null
+++ b/tests/comsub-eof1.sub
@@ -0,0 +1,4 @@
+foo=`cat <<EOF
+hi
+EOF`
+echo $foo
diff --git a/tests/comsub-eof2.sub b/tests/comsub-eof2.sub
new file mode 100644
index 0000000..e93e6c8
--- /dev/null
+++ b/tests/comsub-eof2.sub
@@ -0,0 +1,2 @@
+cat <<EOF
+hi
diff --git a/tests/comsub-eof3.sub b/tests/comsub-eof3.sub
new file mode 100644
index 0000000..f3038c7
--- /dev/null
+++ b/tests/comsub-eof3.sub
@@ -0,0 +1,4 @@
+foo=$(cat <<EOF
+hi
+)
+echo $foo
diff --git a/tests/comsub-eof4.sub b/tests/comsub-eof4.sub
new file mode 100644
index 0000000..870ede9
--- /dev/null
+++ b/tests/comsub-eof4.sub
@@ -0,0 +1,4 @@
+e=$(cat <<EOF
+contents
+EOF)
+echo $e
diff --git a/tests/comsub-eof5.sub b/tests/comsub-eof5.sub
new file mode 100644
index 0000000..3da9107
--- /dev/null
+++ b/tests/comsub-eof5.sub
@@ -0,0 +1,9 @@
+echo $(
+cat <<\)
+hi
+))
+
+echo $(
+cat <<\EOF
+hi
+EOF)
diff --git a/tests/comsub-posix.right b/tests/comsub-posix.right
new file mode 100644
index 0000000..a24f25f
--- /dev/null
+++ b/tests/comsub-posix.right
@@ -0,0 +1,57 @@
+abmnopyz
+abmnopyz
+ab
+
+
+abcd
+sh_352.26ax
+sh_352.26ay
+sh_352.25a sh_352.25b
+sh_352.27 ) ) )
+abc
+here doc with )
+)
+bad' syntax
+a
+sh_352.26a
+sh_352.26a
+sh_352.26
+sh_352.26
+sh_352.26
+1
+sh_352.28 )
+sh_352.28 )
+k
+abcd
+ab
+ab
+abcde
+
+argv[1] = <abcde^J >
+abcdefoo
+argv[1] = <abcde>
+argv[2] = <foo>
+argv[1] = <wxabcdeyz>
+argv[1] = <abcde>
+'
+after 1
+'
+after 2
+'
+after 3
+`
+after 4
+hello
+after 5
+'
+after 6
+x
+x
+quoted )
+comment
+here-doc with )
+here-doc terminated with a parenthesis
+' # or a single back- or doublequote
+./comsub-posix1.sub: command substitution: line 2: syntax error near unexpected token `)'
+./comsub-posix1.sub: command substitution: line 2: ` if x; then echo foo )'
+after
diff --git a/tests/comsub-posix.tests b/tests/comsub-posix.tests
new file mode 100644
index 0000000..d45cbf2
--- /dev/null
+++ b/tests/comsub-posix.tests
@@ -0,0 +1,207 @@
+
+# works right
+echo ab$(echo mnop)yz
+# works right
+echo ab$(echo mnop
+)yz
+#
+# works right
+echo $(echo ab
+ )
+# works right
+echo $(
+)
+echo $()
+echo ab$()cd
+
+echo $(case a in (a) echo sh_352.26ax; esac )
+echo $(case a in (a) echo sh_352.26ay; esac)
+
+echo $((echo sh_352.25a);(echo sh_352.25b))
+
+echo $(echo sh_352.27 ')' ")" \)
+ # ) comment
+ )
+
+echo $(
+echo abc # a comment with )
+)
+
+echo $(
+cat <<eof
+here doc with )
+eof
+)
+
+echo $(
+echo ')'
+)
+
+unset x
+x=$(cat <<"EOF"
+bad' syntax
+EOF
+)
+echo "$x"
+unset x
+
+echo $(for f in \); do echo a; done )
+echo $(case a in a) echo sh_352.26a; esac )
+echo $(case a in a) echo sh_352.26a; esac)
+
+echo $(case a in
+ (a) echo sh_352.26
+ ;;
+ esac
+ )
+
+echo $(case a in
+ a) echo sh_352.26
+ ;;
+ esac
+ )
+
+
+echo $(case a in
+ a) echo sh_352.26
+ ;;
+
+
+
+
+
+ esac
+
+ )
+
+echo $(( 4<(2+3) ? 1 : 32))
+
+echo $(cat << end
+sh_352.28 )
+end
+)
+
+echo $(cat <<- end
+sh_352.28 )
+ end
+)
+
+k=$(case x in x) echo k;; esac)
+echo $k
+
+x=$(
+ case $(ls) in
+ example) echo foobix;;
+ esac
+)
+
+echo $( echo ab\
+cd)
+
+echo `echo ab
+cd`
+
+echo `echo ab #xyz
+cd`
+
+echo "$(echo abcde)
+"
+
+recho "$(echo abcde)
+ "
+
+echo $(echo abcde)\
+foo
+
+recho $(echo abcde)\
+ foo
+
+recho "wx$(echo abcde)yz"
+recho "$(echo abcde)"
+
+echo $(cat <<eof
+'
+eof
+)
+
+echo after 1
+
+echo $(cat <<\eof
+'
+eof
+)
+
+echo after 2
+
+echo "$(cat <<\eof
+'
+eof
+)"
+
+echo after 3
+
+echo "$(cat <<\eof
+`
+eof
+)"
+
+echo after 4
+
+echo $(
+cat << ')'
+hello
+)
+)
+
+echo after 5
+
+echo $(cat <<'eof'
+'
+eof
+)
+
+echo after 6
+
+echo $(
+ case x in x) echo x;; esac
+)
+
+echo $(
+ case x in (x) echo x;; esac
+)
+
+echo $(
+ echo 'quoted )'
+)
+
+echo $(
+ echo comment # with )
+)
+
+echo $(
+cat <<\eof
+ here-doc with )
+eof
+)
+
+echo $(
+cat <<\)
+ here-doc terminated with a parenthesis
+)
+)
+
+echo $(
+cat <<\eof
+ ' # or a single back- or doublequote
+eof
+)
+
+${THIS_SH} ./comsub-posix1.sub
+
+# produced a parse error through bash-4.0-beta2
+: $(echo foo)"
+"
+
+# fixed after bash-4.0 released
+: $(case a in a) echo ;; # comment
+esac)
diff --git a/tests/comsub-posix1.sub b/tests/comsub-posix1.sub
new file mode 100644
index 0000000..bbcc60f
--- /dev/null
+++ b/tests/comsub-posix1.sub
@@ -0,0 +1,3 @@
+echo $( if x; then echo foo )
+
+echo after
diff --git a/tests/comsub.right b/tests/comsub.right
new file mode 100644
index 0000000..9894529
--- /dev/null
+++ b/tests/comsub.right
@@ -0,0 +1,29 @@
+./comsub.tests: line 7: hijkl: command not found
+argv[1] = <ab>
+argv[2] = <cd>
+argv[1] = <abmn>
+argv[2] = <opyz>
+argv[1] = <b>
+argv[1] = <a\>
+argv[2] = <b>
+argv[1] = <$>
+argv[2] = <bab>
+argv[1] = <`>
+argv[2] = <ab>
+argv[1] = <\>
+argv[2] = <ab>
+argv[1] = <foo \\^Jbar>
+argv[1] = <foo \^Jbar>
+argv[1] = <sed> argv[2] = <-e> argv[3] = <s/[^I:]/\^J/g>
+argv[1] = <sed> argv[2] = <-e> argv[3] = <s/[^I:]//g>
+argv[1] = <foo\^Jbar>
+argv[1] = <foobar>
+argv[1] = <foo\^Jbar>
+#esac
+a
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+ok 6
diff --git a/tests/comsub.tests b/tests/comsub.tests
new file mode 100644
index 0000000..493bbda
--- /dev/null
+++ b/tests/comsub.tests
@@ -0,0 +1,44 @@
+# command substution parsing tests
+
+TABSIZE=`grep -v '^[ #]' $CAPS </dev/null | grep -v "^$" | grep -v "^capalias"| grep -v "^infoalias" | wc -l`
+
+recho `echo ab cd #efg
+hijkl`
+
+recho ab$(echo mn; echo op)yz
+
+a=`echo 'a b c' | sed 's/ /\\
+/g' | grep 'b'`
+recho $a
+
+recho `echo 'a\' b`
+
+recho `echo '\$' bab`
+
+recho `echo '\`' ab`
+
+recho `echo '\\' ab`
+
+# old-style command substitution parsing compatibility tests -- post bash-3.1
+recho 'foo \\
+bar'
+
+recho 'foo \
+bar'
+
+echo `recho sed -e 's/[ :]/\\
+/g'`
+
+echo `recho sed -e 's/[ :]/\
+/g'`
+
+echo `recho 'foo\\
+bar'`
+
+echo `recho 'foo\
+bar'`
+
+echo $(recho 'foo\
+bar')
+
+${THIS_SH} ./comsub1.sub
diff --git a/tests/comsub1.sub b/tests/comsub1.sub
new file mode 100644
index 0000000..86565e2
--- /dev/null
+++ b/tests/comsub1.sub
@@ -0,0 +1,48 @@
+: $(echo \;)
+
+: $(case a in a) echo ;;# comment
+esac)
+
+: $(case a in a) echo ;; # comment
+esac)
+
+: $(: \;# not a comment )
+
+: $(: \ # not a comment)
+
+echo $(case a in a) echo \#esac ;;
+esac)
+
+: $(case a in a) : ;#esac ;;
+esac)
+
+: $(case a in a) : ;#esac comment )
+esac)
+
+: $(case a in a) : ;
+esac)
+
+echo $(#comment )
+echo a)
+
+echo $(case a in (a) echo ok 1;; # comment
+esac)
+
+echo $(case a in (a) echo ok 2;; # comment
+(b) echo moo;;
+esac)
+
+echo $(case a in (a) echo ok 3 # comment
+;;
+esac)
+
+echo $(case a in a) echo ok 4;; # comment
+esac)
+
+echo $(case a in a) echo ok 5;; # comment
+b) echo moo;;
+esac)
+
+echo $(case a in (a) echo ok 6 # comment
+;;
+esac)
diff --git a/tests/cond-regexp.sub b/tests/cond-regexp.sub
new file mode 100644
index 0000000..724957d
--- /dev/null
+++ b/tests/cond-regexp.sub
@@ -0,0 +1,42 @@
+VAR='[[:alpha:]]'
+
+[[ $VAR =~ '[[:alpha:]]' ]] && echo match 1
+
+[[ a =~ '[[:alpha:]]' ]] || echo match 2
+
+[[ a =~ [[:alpha:]] ]] && echo match 3
+
+[[ a =~ $VAR ]] && echo match 4
+
+[[ a =~ "$VAR" ]] || echo match 5
+
+line=aab
+[[ $line =~ [[:space:]]*(a)?b ]] && echo match 6
+
+V="alphabet"
+[[ $V == alphabet ]] && echo yes 1
+[[ $V == "alphabet" ]] && echo yes 2
+[[ $V == 'alphabet' ]] && echo yes 3
+[[ $V =~ alphabet ]] && echo yes 4
+[[ $V =~ "alphabet" ]] && echo yes 5
+[[ $V =~ 'alphabet' ]] && echo yes 6
+
+DOG="Dog name - 01 - Wiggles"
+REPAT='([[:alpha:][:blank:]]*)- ([[:digit:]]*) - (.*)$'
+if [[ $DOG =~ ([[:alpha:][:blank:]]*)-\ ([[:digit:]]*)\ -\ (.*)$ ]]
+then
+ echo Dog ${BASH_REMATCH[2]} is ${BASH_REMATCH[3]}
+fi
+if [[ $DOG =~ $REPAT ]]
+then
+ echo Dog ${BASH_REMATCH[2]} is ${BASH_REMATCH[3]}
+fi
+
+[[ $REPAT =~ "$REPAT" ]] && echo rematch 1
+
+v="one two buckle my shoe"
+[[ ${v} =~ "one two" ]] && echo matches 7
+
+[[ ${v} =~ (one two) ]] && echo matches 8
+
+[[ ${v} =~ one\ two ]] && echo matches 9
diff --git a/tests/cond.right b/tests/cond.right
index 06f36a9..3775230 100644
--- a/tests/cond.right
+++ b/tests/cond.right
@@ -33,5 +33,29 @@ returns: 0
returns: 1
returns: 0
ok
+jbig2dec
+
+found 1
+libc
+found 2
+libc
ok 42
ok 43
+match 1
+match 2
+match 3
+match 4
+match 5
+match 6
+yes 1
+yes 2
+yes 3
+yes 4
+yes 5
+yes 6
+Dog 01 is Wiggles
+Dog 01 is Wiggles
+rematch 1
+matches 7
+matches 8
+matches 9
diff --git a/tests/cond.tests b/tests/cond.tests
index 3abfa9d..b053e48 100755
--- a/tests/cond.tests
+++ b/tests/cond.tests
@@ -154,6 +154,30 @@ if [[ $STR = $PAT ]]; then
echo ok
fi
+# test the regular expression conditional operator
+[[ jbig2dec-0.9-i586-001.tgz =~ ([^-]+)-([^-]+)-([^-]+)-0*([1-9][0-9]*)\.tgz ]]
+echo ${BASH_REMATCH[1]}
+
+# this shouldn't echo anything
+[[ jbig2dec-0.9-i586-001.tgz =~ \([^-]+\)-\([^-]+\)-\([^-]+\)-0*\([1-9][0-9]*\)\.tgz ]]
+echo ${BASH_REMATCH[1]}
+
+LDD_BASH=" linux-gate.so.1 => (0xffffe000)
+ libreadline.so.5 => /lib/libreadline.so.5 (0xb7f91000)
+ libhistory.so.5 => /lib/libhistory.so.5 (0xb7f8a000)
+ libncurses.so.5 => /lib/libncurses.so.5 (0xb7f55000)
+ libdl.so.2 => /lib/libdl.so.2 (0xb7f51000)
+ libc.so.6 => /lib/libc.so.6 (0xb7e34000)
+ /lib/ld-linux.so.2 (0xb7fd0000)"
+
+[[ "$LDD_BASH" =~ "libc" ]] && echo "found 1"
+echo ${BASH_REMATCH[@]}
+
+[[ "$LDD_BASH" =~ libc ]] && echo "found 2"
+echo ${BASH_REMATCH[@]}
+
# bug in all versions up to and including bash-2.05b
if [[ "123abc" == *?(a)bc ]]; then echo ok 42; else echo bad 42; fi
if [[ "123abc" == *?(a)bc ]]; then echo ok 43; else echo bad 43; fi
+
+${THIS_SH} ./cond-regexp.sub
diff --git a/tests/coproc.right b/tests/coproc.right
new file mode 100644
index 0000000..6d9deaa
--- /dev/null
+++ b/tests/coproc.right
@@ -0,0 +1,13 @@
+84575
+63 60
+a b c
+84577
+63 60
+flop
+./coproc.tests: line 22: 84577 Terminated coproc REFLECT { cat -; }
+84579
+63 60
+FOO
+63 60
+root
+-1 -1
diff --git a/tests/coproc.tests b/tests/coproc.tests
new file mode 100644
index 0000000..8be3563
--- /dev/null
+++ b/tests/coproc.tests
@@ -0,0 +1,45 @@
+coproc { echo a b c; sleep 2; }
+
+echo $COPROC_PID
+echo ${COPROC[@]}
+
+read LINE <&${COPROC[0]}
+echo $LINE
+
+wait $COPROC_PID
+
+coproc REFLECT { cat - ; }
+
+echo $REFLECT_PID
+echo ${REFLECT[@]}
+
+echo flop >&${REFLECT[1]}
+read LINE <&${REFLECT[0]}
+
+echo $LINE
+
+kill $REFLECT_PID
+wait $REFLECT_PID
+
+coproc xcase -n -u
+
+echo $COPROC_PID
+echo ${COPROC[@]}
+
+echo foo >&${COPROC[1]}
+read <&${COPROC[0]}
+
+echo $REPLY
+echo ${COPROC[@]}
+
+cat /etc/passwd | grep root | awk -F: '{print $1;}' | sed 1q
+
+exec 4<&${COPROC[0]}-
+exec >&${COPROC[1]}-
+
+echo ${COPROC[@]}
+
+read foo <&4
+echo $foo >&2
+
+exit 0
diff --git a/tests/dbg-support.right b/tests/dbg-support.right
index eb7d3c3..c4a1609 100644
--- a/tests/dbg-support.right
+++ b/tests/dbg-support.right
@@ -19,7 +19,7 @@ debug lineno: 24 fn1
debug lineno: 24 fn1
debug lineno: 25 fn1
./dbg-support.tests: line 25: caller: foo: invalid number
-caller: usage: caller [EXPR]
+caller: usage: caller [expr]
debug lineno: 25 fn1
debug lineno: 17 fn1
debug lineno: 12 print_return_trap
@@ -48,7 +48,7 @@ debug lineno: 24 fn1
debug lineno: 24 fn1 71 main ./dbg-support.tests
debug lineno: 25 fn1
./dbg-support.tests: line 25: caller: foo: invalid number
-caller: usage: caller [EXPR]
+caller: usage: caller [expr]
debug lineno: 25 fn1
debug lineno: 17 fn1
debug lineno: 12 print_return_trap
@@ -190,7 +190,7 @@ FUNCNAME[0] fn1
79 main ./dbg-support.tests
./dbg-support.tests: line 25: caller: foo: invalid number
-caller: usage: caller [EXPR]
+caller: usage: caller [expr]
debug lineno: 80 main
fn2 here. Calling fn1...
@@ -202,7 +202,7 @@ FUNCNAME[0] fn1
30 fn2 ./dbg-support.tests
80 main ./dbg-support.tests
./dbg-support.tests: line 25: caller: foo: invalid number
-caller: usage: caller [EXPR]
+caller: usage: caller [expr]
debug lineno: 81 main
LINENO 34
@@ -351,3 +351,21 @@ debug lineno: 132 main
debug lineno: 133 main
debug lineno: 132 main
debug lineno: 133 main
+debug lineno: 137 main
+main: calling f1
+f1: calling f2
+f2: calling f3
+f3: calling callstack
+deep 6
+0 z
+1 3
+2 y
+3 2
+4 x
+5 1
+FUNCNAME stack: f3 f2 f1 main
+26 f2 ./dbg-support3.sub
+f3: returning
+f2: return from f3
+f1: return from f2
+main: f1 returns
diff --git a/tests/dbg-support.tests b/tests/dbg-support.tests
index 517591c..ad06d01 100755
--- a/tests/dbg-support.tests
+++ b/tests/dbg-support.tests
@@ -133,6 +133,9 @@ for i in 0 1 ; do
((x=i+j))
done
done
+
+${THIS_SH} ./dbg-support3.sub
+
#;;; Local Variables: ***
#;;; mode:shell-script ***
#;;; eval: (sh-set-shell "bash") ***
diff --git a/tests/dbg-support3.sub b/tests/dbg-support3.sub
new file mode 100644
index 0000000..cc52c65
--- /dev/null
+++ b/tests/dbg-support3.sub
@@ -0,0 +1,39 @@
+shopt -s extdebug
+
+callstack(){
+ deep=${#BASH_ARGV[*]}
+ echo "deep $deep"
+ i=0
+ for ff in ${BASH_ARGV[@]}
+ do
+ echo "$i $ff"
+ i=$(($i+1))
+ done
+}
+
+f3()
+{
+ echo $FUNCNAME: calling callstack
+ callstack
+ echo FUNCNAME stack: ${FUNCNAME[@]}
+ caller 0
+ echo $FUNCNAME: returning
+}
+
+f2()
+{
+ echo $FUNCNAME: calling f3
+ f3 3 z
+ echo $FUNCNAME: return from f3
+}
+
+f1()
+{
+ echo $FUNCNAME: calling f2
+ f2 2 y
+ echo $FUNCNAME: return from f2
+}
+
+echo main: calling f1
+f1 1 x
+echo main: f1 returns
diff --git a/tests/dollar-at-star b/tests/dollar-at-star
index 25c2443..54e499d 100755
--- a/tests/dollar-at-star
+++ b/tests/dollar-at-star
@@ -223,4 +223,16 @@ ${THIS_SH} ./dollar-at2.sub
# no splitting, etc. when $IFS is NUL
${THIS_SH} ./dollar-star2.sub
+# tests for expansions of "${array[*]}" and "${array[@]}" when $IFS is not the
+# default and the array contains null elements
+${THIS_SH} ./dollar-star3.sub
+
+# test for set -u and expansions of $@ when there are no positional parameters
+${THIS_SH} ./dollar-at3.sub
+# test for set -u and expansions of $* when there are no positional parameters
+${THIS_SH} ./dollar-star4.sub
+
+# tests for expansions of $* when IFS is null
+${THIS_SH} ./dollar-star5.sub
+
exit 0
diff --git a/tests/dollar-at3.sub b/tests/dollar-at3.sub
new file mode 100644
index 0000000..76a65c1
--- /dev/null
+++ b/tests/dollar-at3.sub
@@ -0,0 +1,9 @@
+set -u
+
+echo ${#@}
+echo ${@:-bar}
+
+echo $@
+echo after 1
+echo ${@}
+echo after 2
diff --git a/tests/dollar-star3.sub b/tests/dollar-star3.sub
new file mode 100644
index 0000000..8cf4bb2
--- /dev/null
+++ b/tests/dollar-star3.sub
@@ -0,0 +1,18 @@
+IFS=/
+#file=/mnt/cdrom/RedHat/RPMS
+#recho "${file[*]:0:3}"
+
+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
diff --git a/tests/dollar-star4.sub b/tests/dollar-star4.sub
new file mode 100644
index 0000000..1b551f2
--- /dev/null
+++ b/tests/dollar-star4.sub
@@ -0,0 +1,9 @@
+set -u
+
+echo ${#*}
+echo ${*:-bar}
+
+echo $*
+echo after 1
+echo ${*}
+echo after 2
diff --git a/tests/dollar-star5.sub b/tests/dollar-star5.sub
new file mode 100644
index 0000000..8448bf3
--- /dev/null
+++ b/tests/dollar-star5.sub
@@ -0,0 +1,16 @@
+set -- a b
+IFS=
+
+echo $*
+echo "$*"
+
+a=abcd
+echo "${a#$*}"
+
+case ab in
+$*) echo ok 1;;
+esac
+
+case $* in
+ab) echo ok 2 ;;
+esac
diff --git a/tests/dollar.right b/tests/dollar.right
index ff57f1c..13db8e2 100644
--- a/tests/dollar.right
+++ b/tests/dollar.right
@@ -134,3 +134,35 @@ argv[1] = <A B>
argv[2] = <C D>
argv[1] = <A BC D>
argv[1] = <A BC D>
+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] = <>
+0
+bar
+
+after 1
+
+after 2
+0
+bar
+
+after 1
+
+after 2
+a b
+ab
+cd
+ok 1
+ok 2
diff --git a/tests/dstack.right b/tests/dstack.right
index 73a006c..8f27d28 100644
--- a/tests/dstack.right
+++ b/tests/dstack.right
@@ -2,9 +2,9 @@
./dstack.tests: line 9: pushd: no other directory
./dstack.tests: line 10: popd: directory stack empty
./dstack.tests: line 13: pushd: -m: invalid number
-pushd: usage: pushd [dir | +N | -N] [-n]
+pushd: usage: pushd [-n] [+N | -N | dir]
./dstack.tests: line 14: popd: -m: invalid number
-popd: usage: popd [+N | -N] [-n]
+popd: usage: popd [-n] [+N | -N]
./dstack.tests: line 15: dirs: -m: invalid number
dirs: usage: dirs [-clpv] [+N] [-N]
./dstack.tests: line 16: dirs: 7: invalid option
diff --git a/tests/dstack.tests b/tests/dstack.tests
index 6c4cef1..49b97d3 100644
--- a/tests/dstack.tests
+++ b/tests/dstack.tests
@@ -84,4 +84,4 @@ dirs -c
dirs
# this is for the benefit of pure coverage
-cd $MYDIR
+cd "$MYDIR"
diff --git a/tests/errors.right b/tests/errors.right
index ac987fb..ae7bf29 100644
--- a/tests/errors.right
+++ b/tests/errors.right
@@ -15,12 +15,12 @@ unset: usage: unset [-f] [-v] [name ...]
./errors.tests: line 52: unset: `/bin/sh': not a valid identifier
./errors.tests: line 55: unset: cannot simultaneously unset a function and a variable
./errors.tests: line 58: declare: -z: invalid option
-declare: usage: declare [-afFirtx] [-p] [name[=value] ...]
+declare: usage: declare [-aAfFilrtux] [-p] [name[=value] ...]
./errors.tests: line 60: declare: `-z': not a valid identifier
./errors.tests: line 61: declare: `/bin/sh': not a valid identifier
./errors.tests: line 65: declare: cannot use `-f' to make functions
./errors.tests: line 68: exec: -i: invalid option
-exec: usage: exec [-cl] [-a name] file [redirection ...]
+exec: usage: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
./errors.tests: line 72: export: XPATH: not a function
./errors.tests: line 75: break: only meaningful in a `for', `while', or `until' loop
./errors.tests: line 76: continue: only meaningful in a `for', `while', or `until' loop
@@ -53,9 +53,10 @@ umask: usage: umask [-p] [-S] [mode]
./errors.tests: line 159: declare: VAR: readonly variable
./errors.tests: line 161: declare: unset: not found
./errors.tests: line 164: VAR: readonly variable
-./errors.tests: command substitution: line 168: syntax error: unexpected end of file
-./errors.tests: command substitution: line 168: syntax error near unexpected token `done'
-./errors.tests: command substitution: line 168: ` for z in 1 2 3; done '
+./errors.tests: command substitution: line 168: syntax error near unexpected token `)'
+./errors.tests: command substitution: line 168: ` for z in 1 2 3; do )'
+./errors.tests: command substitution: line 169: syntax error near unexpected token `done'
+./errors.tests: command substitution: line 169: ` for z in 1 2 3; done )'
./errors.tests: line 171: cd: HOME not set
./errors.tests: line 172: cd: /tmp/xyz.bash: No such file or directory
./errors.tests: line 174: cd: OLDPWD not set
@@ -68,7 +69,7 @@ source: usage: source filename [arguments]
./errors.tests: line 184: .: -i: invalid option
.: usage: . filename [arguments]
./errors.tests: line 187: set: -q: invalid option
-set: usage: set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
+set: usage: set [--abefhkmnptuvxBCHP] [-o option-name] [arg ...]
./errors.tests: line 190: enable: sh: not a shell builtin
./errors.tests: line 190: enable: bash: not a shell builtin
./errors.tests: line 193: shopt: cannot set and unset shell options simultaneously
@@ -85,7 +86,7 @@ command: usage: command [-pVv] command [arg ...]
./errors.tests: line 213: /bin/sh + 0: syntax error: operand expected (error token is "/bin/sh + 0")
./errors.tests: line 216: trap: NOSIG: invalid signal specification
./errors.tests: line 219: trap: -s: invalid option
-trap: usage: trap [-lp] [arg signal_spec ...]
+trap: usage: trap [-lp] [[arg] signal_spec ...]
./errors.tests: line 225: return: can only `return' from a function or sourced script
./errors.tests: line 229: break: 0: loop count out of range
./errors.tests: line 233: continue: 0: loop count out of range
diff --git a/tests/exec.right b/tests/exec.right
index d65b89d..86a099c 100644
--- a/tests/exec.right
+++ b/tests/exec.right
@@ -16,17 +16,17 @@ after exec1.sub without args: 0
126
./execscript: line 46: .: /: is a directory
1
-127
+126
0
this is bashenv
./exec3.sub: line 3: /tmp/bash-notthere: No such file or directory
./exec3.sub: line 3: exec: /tmp/bash-notthere: cannot execute: No such file or directory
126
-./execscript: line 68: notthere: No such file or directory
+./execscript: line 70: notthere: No such file or directory
127
-./execscript: line 71: notthere: No such file or directory
+./execscript: line 73: notthere: No such file or directory
127
-./execscript: line 74: notthere: No such file or directory
+./execscript: line 76: notthere: command not found
127
this is sh
this is sh
@@ -51,4 +51,5 @@ this is ohio-state
0
1
testb
+expand_aliases on
after
diff --git a/tests/exec8.sub b/tests/exec8.sub
new file mode 100644
index 0000000..014726d
--- /dev/null
+++ b/tests/exec8.sub
@@ -0,0 +1 @@
+shopt expand_aliases
diff --git a/tests/execscript b/tests/execscript
index 09a4ba5..3629c57 100644
--- a/tests/execscript
+++ b/tests/execscript
@@ -48,6 +48,8 @@ echo $?
# try sourcing a binary file -- post-2.04 versions don't do the binary file
# check, and will probably fail with `command not found', or status 127
+# bash-4.1 and later check for 256 NUL characters and fail as binary files
+# if there are more than that, it's probably binary
. ${THIS_SH} 2>/dev/null
echo $?
@@ -105,6 +107,8 @@ ${THIS_SH} ./exec6.sub
# checks for properly deciding what constitutes an executable file
${THIS_SH} ./exec7.sub
+${THIS_SH} -i ./exec8.sub
+
true | `echo true` &
echo after
diff --git a/tests/exp.right b/tests/exp.right
index fdadbd9..d46a2a1 100644
--- a/tests/exp.right
+++ b/tests/exp.right
@@ -145,3 +145,24 @@ argv[4] = <d>
argv[5] = <e>
a?b?c
a b c
+argv[1] = <^?>
+argv[1] = <^?>
+argv[1] = <^?>
+argv[1] = <^?>
+argv[1] = <^?>
+argv[1] = <^?>
+argv[1] = <^A>
+argv[2] = <^?>
+argv[1] = <^A^?>
+argv[1] = <^A^?^A^?>
+argv[1] = <^A^A^?>
+0.net
+0.net0
+
+0.net
+0.net
+0.net
+graph
+yes
+a
+a
diff --git a/tests/exp-tests b/tests/exp.tests
index 884b5a6..1f4a35b 100644
--- a/tests/exp-tests
+++ b/tests/exp.tests
@@ -378,3 +378,9 @@ a="a?b?c"
echo ${a//\\?/ }
echo ${a//\?/ }
+
+${THIS_SH} ./exp1.sub
+
+${THIS_SH} ./exp2.sub
+
+${THIS_SH} ./exp3.sub
diff --git a/tests/exp1.sub b/tests/exp1.sub
new file mode 100644
index 0000000..3e40f2a
--- /dev/null
+++ b/tests/exp1.sub
@@ -0,0 +1,21 @@
+# Test the substitution quoting characters (CTLESC and CTLNUL) in different
+# combinations
+
+recho `echo ''`
+recho `echo ""`
+recho `echo `
+
+# Test the unquoted special quoting characters
+recho 
+recho ""
+recho ''
+
+# This should give argv[1] = ^A argv[2] = ^?
+FOO=`echo ' ' | tr ' ' '\012'`
+recho $FOO
+
+# Test patterns that come up when the shell quotes funny character
+# combinations
+recho ''
+recho ''
+recho ''
diff --git a/tests/exp2.sub b/tests/exp2.sub
new file mode 100644
index 0000000..a70179e
--- /dev/null
+++ b/tests/exp2.sub
@@ -0,0 +1,12 @@
+K=dvb0.net A=${K#dvb} eval echo \$A
+unset K A
+x=${K:=dvb0.net0} A=${K#dvb} eval echo \$A
+
+unset K A
+K=dvb0.net A=${K#dvb} echo "$A"
+unset K A
+K=dvb0.net A=${K#dvb} ; echo "$A"
+unset K A
+K=dvb0.net A=${K#dvb} eval echo '$A'
+unset K A
+K=dvb0.net A=${K#dvb} eval echo \$A
diff --git a/tests/exp3.sub b/tests/exp3.sub
new file mode 100644
index 0000000..212d579
--- /dev/null
+++ b/tests/exp3.sub
@@ -0,0 +1,7 @@
+IFS=:
+
+case A in ([[:graph:]]) echo graph;; *) echo non-graph;; esac
+[[ A == [[:graph:]] ]] && echo yes || echo no
+
+IFS="~"; read a b <<< a~q; echo $a
+IFS=':'; read a b <<< a:q; echo $a
diff --git a/tests/extglob.right b/tests/extglob.right
index 301e97b..7b9cc94 100644
--- a/tests/extglob.right
+++ b/tests/extglob.right
@@ -78,6 +78,7 @@ a b a,b a-b a.b a:b a;b a_b
a b a,b a-b a.b a:b a;b a_b
a b a,b a-b a.b a:b a;b a_b
argv[1] = <ef>
+a,b
a.c
a.c
a.c
diff --git a/tests/extglob.tests b/tests/extglob.tests
index 51e33ee..f9c17c7 100644
--- a/tests/extglob.tests
+++ b/tests/extglob.tests
@@ -193,7 +193,8 @@ esac
MYDIR=$PWD # save where we are
-TESTDIR=/tmp/eglob-test-$$
+: ${TMPDIR:=/var/tmp}
+TESTDIR=$TMPDIR/eglob-test-$$
mkdir $TESTDIR
builtin cd $TESTDIR || { echo $0: cannot cd to $TESTDIR >&2 ; exit 1; }
rm -rf *
@@ -356,9 +357,14 @@ rm -rf $TESTDIR
x=abcdef
recho "${x#*(a|b)cd}"
+TEST='a , b'
+shopt -s globstar
+echo ${TEST//*([[:space:]]),*([[:space:]])/,}
+shopt -u globstar
+
# this is for the benefit of pure coverage, so it writes the pcv file
# in the right place
-builtin cd $MYDIR
+builtin cd "$MYDIR"
${THIS_SH} ./extglob1.sub
diff --git a/tests/extglob1.sub b/tests/extglob1.sub
new file mode 100644
index 0000000..bf65a9e
--- /dev/null
+++ b/tests/extglob1.sub
@@ -0,0 +1,37 @@
+MYDIR=$PWD
+
+: ${TMPDIR:=/tmp}
+GDIR=$TMPDIR/gtest-$$
+
+shopt -s extglob
+
+mkdir $GDIR || exit 1
+cd $GDIR || exit 1
+
+touch a.c
+
+echo +([[:alpha:].])
+echo +([[:alpha:].])+([[:alpha:].])
+echo *([[:alpha:].])
+echo *([[:alpha:].])*([[:alpha:].])
+
+echo ?([[:alpha:].])?([[:alpha:].])?([[:alpha:].])
+echo @([[:alpha:].])@([[:alpha:].])@([[:alpha:].])
+
+case . in
+!([[:alpha:].]) ) echo bad 1;;
+*) echo ok 1;;
+esac
+
+case . in
+?([[:alpha:].]) ) echo ok 2;;
+*) echo bad 2;;
+esac
+
+case . in
+@([[:alpha:].]) ) echo ok 3;;
+*) echo bad 3;;
+esac
+
+cd "$MYDIR"
+rm -rf $GDIR
diff --git a/tests/func.right b/tests/func.right
index e97a486..da8b45c 100644
--- a/tests/func.right
+++ b/tests/func.right
@@ -27,7 +27,7 @@ f1 ()
return $status
}
before: try to assign to FUNCNAME
-outside: FUNCNAME = main
+outside: FUNCNAME =
before: FUNCNAME = func
FUNCNAME = func2
after: FUNCNAME = func
@@ -136,6 +136,11 @@ funcc ()
func-a
func-b
func-c
+foo-bar
+foo-bar ()
+{
+ :
+}
expect 5 10
5 10
expect 20
diff --git a/tests/func2.sub b/tests/func2.sub
index 2f9d5ce..41a3844 100644
--- a/tests/func2.sub
+++ b/tests/func2.sub
@@ -15,3 +15,13 @@ type funcc
funca
funcb
funcc
+
+# when not in posix mode, bash allows non-identifiers as function names
+set +o posix
+foo-bar()
+{
+ :;
+}
+
+declare -F foo-bar
+declare -f foo-bar
diff --git a/tests/glob.right b/tests/glob.right
index 46ac4d3..04a0fd5 100644
--- a/tests/glob.right
+++ b/tests/glob.right
@@ -13,7 +13,7 @@ argv[2] = <abc>
argv[3] = <abd>
argv[4] = <abe>
tmp/l1 tmp/l2 tmp/*4 tmp/l3
-./glob-test: line 44: no match: tmp/*4
+./glob.tests: line 44: no match: tmp/*4
argv[1] = <bdir/>
argv[1] = <*>
argv[1] = <a*>
diff --git a/tests/glob-test b/tests/glob.tests
index d435708..d32988b 100644
--- a/tests/glob-test
+++ b/tests/glob.tests
@@ -1,4 +1,4 @@
-LC_COLLATE=C
+export LC_COLLATE=C
#
# test the shell globbing
#
diff --git a/tests/globstar.right b/tests/globstar.right
new file mode 100644
index 0000000..b75d80b
--- /dev/null
+++ b/tests/globstar.right
@@ -0,0 +1,155 @@
+lib/glob/glob.o
+lib/glob/smatch.o
+lib/glob/strmatch.o
+lib/readline/bind.o
+lib/readline/callback.o
+lib/readline/compat.o
+lib/readline/complete.o
+lib/readline/display.o
+lib/sh/casemod.o
+lib/sh/clktck.o
+lib/sh/clock.o
+lib/sh/eaccess.o
+lib/sh/fdprintf.o
+lib/sh/fmtullong.o
+lib/sh/fmtulong.o
+lib/sh/fmtumax.o
+lib/sh/fpurge.o
+lib/sh/getenv.o
+lib/sh/input_avail.o
+lib/sh/itos.o
+
+lib/:
+glob
+readline
+sh
+
+lib/glob:
+glob.o
+smatch.o
+strmatch.o
+
+lib/readline:
+bind.o
+callback.o
+compat.o
+complete.o
+display.o
+
+lib/sh:
+casemod.o
+clktck.o
+clock.o
+eaccess.o
+fdprintf.o
+fmtullong.o
+fmtulong.o
+fmtumax.o
+fpurge.o
+getenv.o
+input_avail.o
+itos.o
+lib/glob/glob.o
+lib/glob/smatch.o
+lib/glob/strmatch.o
+lib/readline/bind.o
+lib/readline/callback.o
+lib/readline/compat.o
+lib/readline/complete.o
+lib/readline/display.o
+lib/sh/casemod.o
+lib/sh/clktck.o
+lib/sh/clock.o
+lib/sh/eaccess.o
+lib/sh/fdprintf.o
+lib/sh/fmtullong.o
+lib/sh/fmtulong.o
+lib/sh/fmtumax.o
+lib/sh/fpurge.o
+lib/sh/getenv.o
+lib/sh/input_avail.o
+lib/sh/itos.o
+alias.o builtins/history.o builtins/jobs.o builtins/kill.o builtins/let.o builtins/mapfile.o lib/glob/glob.o lib/glob/smatch.o lib/glob/strmatch.o lib/readline/bind.o lib/readline/callback.o lib/readline/compat.o lib/readline/complete.o lib/readline/display.o lib/sh/casemod.o lib/sh/clktck.o lib/sh/clock.o lib/sh/eaccess.o lib/sh/fdprintf.o lib/sh/fmtullong.o lib/sh/fmtulong.o lib/sh/fmtumax.o lib/sh/fpurge.o lib/sh/getenv.o lib/sh/input_avail.o lib/sh/itos.o pcomplib.o print_cmd.o redir.o shell.o sig.o stringlib.o subst.o syntax.o test.o trap.o unwind_prot.o variables.o version.o xmalloc.o y.tab.o
+alias.o
+builtins/history.o
+builtins/jobs.o
+builtins/kill.o
+builtins/let.o
+builtins/mapfile.o
+lib/glob/glob.o
+lib/glob/smatch.o
+lib/glob/strmatch.o
+lib/readline/bind.o
+lib/readline/callback.o
+lib/readline/compat.o
+lib/readline/complete.o
+lib/readline/display.o
+lib/sh/casemod.o
+lib/sh/clktck.o
+lib/sh/clock.o
+lib/sh/eaccess.o
+lib/sh/fdprintf.o
+lib/sh/fmtullong.o
+lib/sh/fmtulong.o
+lib/sh/fmtumax.o
+lib/sh/fpurge.o
+lib/sh/getenv.o
+lib/sh/input_avail.o
+lib/sh/itos.o
+pcomplib.o
+print_cmd.o
+redir.o
+shell.o
+sig.o
+stringlib.o
+subst.o
+syntax.o
+test.o
+trap.o
+unwind_prot.o
+variables.o
+version.o
+xmalloc.o
+y.tab.o
+
+builtins:
+history.o
+jobs.o
+kill.o
+let.o
+mapfile.o
+
+lib:
+glob
+readline
+sh
+
+lib/glob:
+glob.o
+smatch.o
+strmatch.o
+
+lib/readline:
+bind.o
+callback.o
+compat.o
+complete.o
+display.o
+
+lib/sh:
+casemod.o
+clktck.o
+clock.o
+eaccess.o
+fdprintf.o
+fmtullong.o
+fmtulong.o
+fmtumax.o
+fpurge.o
+getenv.o
+input_avail.o
+itos.o
+alias.o builtins builtins/history.o builtins/jobs.o builtins/kill.o builtins/let.o builtins/mapfile.o lib lib/glob lib/glob/glob.o lib/glob/smatch.o lib/glob/strmatch.o lib/readline lib/readline/bind.o lib/readline/callback.o lib/readline/compat.o lib/readline/complete.o lib/readline/display.o lib/sh lib/sh/casemod.o lib/sh/clktck.o lib/sh/clock.o lib/sh/eaccess.o lib/sh/fdprintf.o lib/sh/fmtullong.o lib/sh/fmtulong.o lib/sh/fmtumax.o lib/sh/fpurge.o lib/sh/getenv.o lib/sh/input_avail.o lib/sh/itos.o pcomplib.o print_cmd.o redir.o shell.o sig.o stringlib.o subst.o syntax.o test.o trap.o unwind_prot.o variables.o version.o xmalloc.o y.tab.o
+bar/foo foo
+bar/foo/ foo/
+bar/foo/e bar/foo/f foo/a foo/b
diff --git a/tests/globstar.tests b/tests/globstar.tests
new file mode 100644
index 0000000..9b1f9d2
--- /dev/null
+++ b/tests/globstar.tests
@@ -0,0 +1,41 @@
+: ${TMPDIR:=/var/tmp}
+dir=$PWD
+
+shopt -s globstar
+
+export LANG=C LC_ALL=C LC_COLLATE=C
+
+GDIR=$TMPDIR/globstar-$$
+
+mkdir $GDIR || exit 1
+cd $GDIR || exit 1
+
+mkdir lib builtins
+mkdir lib/glob lib/readline lib/sh
+
+touch builtins/history.o builtins/jobs.o builtins/kill.o builtins/let.o builtins/mapfile.o
+touch lib/glob/glob.o lib/glob/smatch.o lib/glob/strmatch.o
+touch lib/readline/bind.o lib/readline/callback.o lib/readline/compat.o lib/readline/complete.o lib/readline/display.o
+
+touch lib/sh/casemod.o lib/sh/clktck.o lib/sh/clock.o lib/sh/eaccess.o
+touch lib/sh/fdprintf.o lib/sh/fmtullong.o lib/sh/fmtulong.o lib/sh/fmtumax.o
+touch lib/sh/fpurge.o lib/sh/getenv.o lib/sh/input_avail.o lib/sh/itos.o
+
+touch alias.o
+touch pcomplib.o print_cmd.o redir.o shell.o sig.o stringlib.o subst.o syntax.o
+touch test.o trap.o unwind_prot.o variables.o version.o xmalloc.o y.tab.o
+
+ls lib/**
+
+ls lib/**/*.o
+
+echo **/*.o
+
+ls **
+
+echo **
+
+cd $dir
+rm -rf $GDIR
+
+${THIS_SH} ./globstar1.sub
diff --git a/tests/globstar1.sub b/tests/globstar1.sub
new file mode 100644
index 0000000..8b9e36d
--- /dev/null
+++ b/tests/globstar1.sub
@@ -0,0 +1,21 @@
+shopt -s globstar
+wdir=$PWD
+
+: ${TMPDIR:=/var/tmp}
+DIR=$TMPDIR/globstar-$$
+mkdir -p $DIR
+cd $DIR || {
+ echo "$DIR: cannot cd" >&2
+ exit 1
+}
+mkdir -p foo/{a,b} bar/{c,d,foo/{e,f}} baz/{g,h}
+
+
+echo **/foo*
+
+echo **/foo*/
+
+echo **/foo*/*
+
+cd $wdir
+rm -rf $DIR
diff --git a/tests/heredoc.right b/tests/heredoc.right
index c3f6a7f..b8754de 100644
--- a/tests/heredoc.right
+++ b/tests/heredoc.right
@@ -39,5 +39,26 @@ ENDOFINPUT
aa=1
}
+foo is a function
+foo ()
+{
+ echo;
+ cat <<END
+bar
+END
+
+ cat <<EOF
+qux
+EOF
+
+}
+
+bar
+qux
+
+bar
+qux
+comsub here-string
+./heredoc.tests: line 100: warning: here-document at line 98 delimited by end-of-file (wanted `EOF')
hi
there
diff --git a/tests/heredoc.tests b/tests/heredoc.tests
index c07ef64..79bf4ce 100644
--- a/tests/heredoc.tests
+++ b/tests/heredoc.tests
@@ -86,6 +86,12 @@ type fff
export -f fff
${THIS_SH} -c 'type fff'
+${THIS_SH} ./heredoc1.sub
+
+echo $(
+ cat <<< "comsub here-string"
+)
+
# check that end of file delimits a here-document
# THIS MUST BE LAST!
diff --git a/tests/heredoc1.sub b/tests/heredoc1.sub
new file mode 100644
index 0000000..3f85ead
--- /dev/null
+++ b/tests/heredoc1.sub
@@ -0,0 +1,16 @@
+foo()
+{
+ echo
+ cat <<END
+bar
+END
+ cat <<EOF
+qux
+EOF
+}
+
+type foo
+foo
+
+eval "$(type foo | sed 1d)"
+foo
diff --git a/tests/history.right b/tests/history.right
index 556a312..cb58f98 100644
--- a/tests/history.right
+++ b/tests/history.right
@@ -1,8 +1,8 @@
./history.tests: line 4: history: -x: invalid option
-history: usage: history [-c] [-d offset] [n] or history -awrn [filename] or history -ps arg [arg...]
+history: usage: history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg [arg...]
./history.tests: line 6: history: cannot use more than one of -anrw
./history.tests: line 9: fc: -v: invalid option
-fc: usage: fc [-e ename] [-nlr] [first] [last] or fc -s [pat=rep] [cmd]
+fc: usage: fc [-e ename] [-lnr] [first] [last] or fc -s [pat=rep] [command]
1 for i in one two three; do echo $i; done
2 /bin/sh -c 'echo this is $0'
3 ls
@@ -108,4 +108,39 @@ xx xb xc
echo 44 48 4c
44 48 4c
./history.tests: line 90: fc: no command found
+aa
+bb
+cc
+echo cc
+echo cc
+cc
+aa
+bb
+cc
+echo cc
+echo cc
+cc
1
+one
+two
+three
+ 1 cat <<!
+one
+two
+three
+!
+
+ 2 history
+cat <<!
+one
+two
+three
+!
+
+one
+two
+three
+4.1
+echo ${BASH_VERSION%\.*}
+4.1
+ echo ${BASH_VERSION%\.*}
diff --git a/tests/history.tests b/tests/history.tests
index 833cf3a..688095d 100644
--- a/tests/history.tests
+++ b/tests/history.tests
@@ -92,7 +92,22 @@ r cc
unalias -a
alias
+# these two blocks had better both result in the same output
+echo aa
+echo bb
+echo cc
+fc -e cat
+
+echo aa
+echo bb
+echo cc
+fc -e cat -1
+
set +o history
shopt -q -o history
echo $?
+
+${THIS_SH} ./history1.sub
+
+${THIS_SH} ./history2.sub
diff --git a/tests/history1.sub b/tests/history1.sub
new file mode 100644
index 0000000..543a3e8
--- /dev/null
+++ b/tests/history1.sub
@@ -0,0 +1,13 @@
+HISTFILE=foohist-$$
+unset HISTIGNORE HISTCONTROL
+set -o history
+
+history -c
+cat <<!
+one
+two
+three
+!
+
+history
+fc -s cat
diff --git a/tests/history2.sub b/tests/history2.sub
new file mode 100644
index 0000000..1a8e78c
--- /dev/null
+++ b/tests/history2.sub
@@ -0,0 +1,10 @@
+set -o history
+HISTSIZE=256
+HISTFILE=/dev/null
+
+# these two lines should be the same
+echo ${BASH_VERSION%\.*}
+echo $(fc -nl -1)
+
+echo ${BASH_VERSION%\.*}
+fc -nl -1
diff --git a/tests/intl.right b/tests/intl.right
index 21a3b4f..449d5b0 100644
--- a/tests/intl.right
+++ b/tests/intl.right
@@ -8,3 +8,6 @@ ok 2
aéb
0000000 141 303 251 142
0000004
+-абвгдежзиклмноп - 16
+-абвгдежзиклмноп- 15
+-абвгд- 5
diff --git a/tests/intl.tests b/tests/intl.tests
index 0dc33cb..cd919df 100644
--- a/tests/intl.tests
+++ b/tests/intl.tests
@@ -1,4 +1,4 @@
-export LANG=en_US.UTF-8
+export LC_ALL=en_US.UTF-8
a=$'\303\251'
@@ -36,3 +36,6 @@ set a b
printf '%s\n' "$*"
printf '%s' "$*" | od -b
+
+# display differences make this problematic
+${THIS_SH} ./intl1.sub
diff --git a/tests/intl1.sub b/tests/intl1.sub
new file mode 100644
index 0000000..a03648f
--- /dev/null
+++ b/tests/intl1.sub
@@ -0,0 +1,11 @@
+LC_ALL=en_US.UTF-8
+LANG=en_US.UTF-8
+
+var='абвгдежзиклмноп '
+echo -"$var"- ${#var}
+
+read foo <<< "$var"
+echo -"$foo"- ${#foo}
+
+read -n 5 foo <<< "$var"
+echo -"$foo"- ${#foo}
diff --git a/tests/jobs.right b/tests/jobs.right
index 0a6fce9..a4c8a7c 100644
--- a/tests/jobs.right
+++ b/tests/jobs.right
@@ -72,8 +72,8 @@ running jobs:
[1] Running sleep 300 &
[2]- Running sleep 350 &
[3]+ Running sleep 400 &
-./jobs.tests: line 127: kill: %4: no such job
-./jobs.tests: line 129: jobs: %4: no such job
+./jobs.tests: line 128: kill: %4: no such job
+./jobs.tests: line 130: jobs: %4: no such job
current job:
[3]+ Running sleep 400 &
previous job:
diff --git a/tests/jobs.tests b/tests/jobs.tests
index 5866b0c..e2acba5 100644
--- a/tests/jobs.tests
+++ b/tests/jobs.tests
@@ -115,6 +115,7 @@ exit 1 | exit 2 | exit 3
echo $? -- ${PIPESTATUS[@]} -- ${PIPESTATUS[0]} - ${PIPESTATUS[1]} - ${PIPESTATUS[2]}
sleep 300 &
+sleep300pid=$!
sleep 350 &
sleep 400 &
@@ -168,6 +169,7 @@ exec 5>&2
exec 2>/dev/null
echo killing...
+kill -n 9 $sleep300pid
kill -n 9 %2 %3
wait # make sure we reap the processes while stderr is still redirected
echo done
diff --git a/tests/mapfile.data b/tests/mapfile.data
new file mode 100644
index 0000000..4f1d3ce
--- /dev/null
+++ b/tests/mapfile.data
@@ -0,0 +1,17 @@
+[0] Abcdefghijklmnop
+[1] aBcdefghijklmnop
+[2] abCdefghijklmnop
+[3] abcDefghijklmnop
+[4] abcdEfghijklmnop
+[5] abcdeFghijklmnop
+[6] abcdefGhijklmnop
+[7] abcdefgHijklmnop
+[8] abcdefghIjklmnop
+[9] abcdefghiJklmnop
+[a] abcdefghijKlmnop
+[b] abcdefghijkLmnop
+[c] abcdefghijklMnop
+[d] abcdefghijklmNop
+[e] abcdefghijklmnOp
+[f] abcdefghijklmnoP
+a \ No newline at end of file
diff --git a/tests/mapfile.right b/tests/mapfile.right
new file mode 100644
index 0000000..1e73eb1
--- /dev/null
+++ b/tests/mapfile.right
@@ -0,0 +1,138 @@
+[0] Abcdefghijklmnop
+[1] aBcdefghijklmnop
+[2] abCdefghijklmnop
+[3] abcDefghijklmnop
+[4] abcdEfghijklmnop
+[5] abcdeFghijklmnop
+[6] abcdefGhijklmnop
+[7] abcdefgHijklmnop
+[8] abcdefghIjklmnop
+[9] abcdefghiJklmnop
+[a] abcdefghijKlmnop
+[b] abcdefghijkLmnop
+[c] abcdefghijklMnop
+[d] abcdefghijklmNop
+[e] abcdefghijklmnOp
+[f] abcdefghijklmnoP
+a[0] Abcdefghijklmnop
+[1] aBcdefghijklmnop
+[2] abCdefghijklmnop
+[3] abcDefghijklmnop
+[4] abcdEfghijklmnop
+[5] abcdeFghijklmnop
+[6] abcdefGhijklmnop
+[7] abcdefgHijklmnop
+[8] abcdefghIjklmnop
+[9] abcdefghiJklmnop
+[a] abcdefghijKlmnop
+[b] abcdefghijkLmnop
+[c] abcdefghijklMnop
+[d] abcdefghijklmNop
+[e] abcdefghijklmnOp
+[f] abcdefghijklmnoP
+a
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+2
+5
+8
+11
+14
+[0] Abcdefghijklmnop
+[1] aBcdefghijklmnop
+[2] abCdefghijklmnop
+[3] abcDefghijklmnop
+[4] abcdEfghijklmnop
+[5] abcdeFghijklmnop
+[6] abcdefGhijklmnop
+[7] abcdefgHijklmnop
+[8] abcdefghIjklmnop
+[9] abcdefghiJklmnop
+[a] abcdefghijKlmnop
+[b] abcdefghijkLmnop
+[c] abcdefghijklMnop
+[d] abcdefghijklmNop
+[e] abcdefghijklmnOp
+[f] abcdefghijklmnoP
+a
+[0] aaa
+[1] aaa
+[2] aaa
+[3] aaa
+[4] aaa
+[5] aaa
+[6] aaa
+[7] aaa
+[8] aaa
+[9] aaa
+[0] Abcdefghijklmnop
+[1] aBcdefghijklmnop
+[2] abCdefghijklmnop
+[3] abcDefghijklmnop
+[4] abcdEfghijklmnop
+[5] abcdeFghijklmnop
+[6] abcdefGhijklmnop
+[7] abcdefgHijklmnop
+[8] abcdefghIjklmnop
+[9] abcdefghiJklmnop
+[a] abcdefghijKlmnop
+[b] abcdefghijkLmnop
+[c] abcdefghijklMnop
+[d] abcdefghijklmNop
+[e] abcdefghijklmnOp
+[f] abcdefghijklmnoP
+a
+[27] aaa
+[28] aaa
+[29] aaa
+[0] aaa
+[1] aaa
+[2] aaa
+[3] aaa
+[4] aaa
+[5] aaa
+[6] aaa
+[7] aaa
+[8] aaa
+[9] aaa
+[0] Abcdefghijklmnop
+[1] aBcdefghijklmnop
+[2] abCdefghijklmnop
+[3] abcDefghijklmnop
+[4] abcdEfghijklmnop
+[15] aaa
+[16] aaa
+[17] aaa
+[18] aaa
+[19] aaa
+[20] aaa
+[21] aaa
+[22] aaa
+[23] aaa
+[24] aaa
+[25] aaa
+[26] aaa
+[27] aaa
+[28] aaa
+[29] aaa
+1 2 3 4 5
+foo 0
+foo 1
+foo 2
+foo 3
+foo 4
diff --git a/tests/mapfile.tests b/tests/mapfile.tests
new file mode 100644
index 0000000..a9170c1
--- /dev/null
+++ b/tests/mapfile.tests
@@ -0,0 +1,42 @@
+declare -a A
+mapfile A < mapfile.data
+for (( i = 0 ; i < ${#A[@]} ; i++ )); do
+ echo -n "${A[${i}]}"
+done
+
+declare -a B
+mapfile -t B < mapfile.data
+for (( i = 0 ; i < ${#B[@]} ; i++ )); do
+ echo "${B[${i}]}"
+done
+
+mapfile -C "echo" -c 1 A < mapfile.data
+mapfile -C "echo" -c 3 A < mapfile.data
+mapfile -C "echo" -c 19 A < mapfile.data
+
+declare -a C
+mapfile -t -u 3 C 3< mapfile.data < mapfile.tests
+for (( i = 0 ; i < ${#C[@]} ; i++ )); do
+ echo "${C[${i}]}"
+done
+
+
+declare -a D
+for (( i = 0 ; i < 30; i++ )); do
+ D[${i}]="[$i] aaa"
+done
+mapfile -O 10 -t D < mapfile.data
+for (( i = 0 ; i < ${#D[@]} ; i++ )); do
+ echo "${D[${i}]}"
+done
+
+declare -a E
+for (( i = 0 ; i < 30; i++ )); do
+ E[${i}]="[$i] aaa"
+done
+mapfile -O 10 -n 5 -t E < mapfile.data
+for (( i = 0 ; i < ${#E[@]} ; i++ )); do
+ echo "${E[${i}]}"
+done
+
+${THIS_SH} ./mapfile1.sub
diff --git a/tests/mapfile1.sub b/tests/mapfile1.sub
new file mode 100644
index 0000000..b3d77f9
--- /dev/null
+++ b/tests/mapfile1.sub
@@ -0,0 +1,11 @@
+: ${TMPDIR:=/tmp}
+FILE=$TMPDIR/file
+
+trap 'rm -f $FILE' 0 1 2 3 6 15
+printf "%d\n" {1..20} > $FILE
+
+mapfile -n 5 array < $FILE
+echo ${array[@]}
+
+mapfile -n 5 -c 1 -C "echo foo" array < $FILE
+mapfile -n 5 -c 1 -C "echo foo" array < /dev/null
diff --git a/tests/new-exp.right b/tests/new-exp.right
index f2dfbc1..c86c546 100644
--- a/tests/new-exp.right
+++ b/tests/new-exp.right
@@ -430,7 +430,7 @@ Case05---3---A:B:C---
Case06---1---A B C::---
Case07---3---A:B:C---
Case08---3---A:B:C---
-./new-exp.tests: line 506: /${$(($#-1))}: bad substitution
+./new-exp.tests: line 506: ${$(($#-1))}: bad substitution
argv[1] = <a>
argv[2] = <b>
argv[3] = <c>
@@ -496,12 +496,16 @@ one
123456789
9
9
+4, A B C D
+2, C D
h
h
--blah
--blah
lah
lah
+abcde abcfg abchi
+foode foofg foohi
argv[1] = <>
argv[1] = <+>
argv[1] = <+^?>
@@ -515,4 +519,24 @@ argv[1] = <>
argv[1] = <>
argv[1] = <>
argv[1] = <12>
-./new-exp.tests: line 560: ABXD: parameter unset
+argv[1] = <>
+argv[1] = <>
+argv[1] = </tmp/test/TEST>
+foo is a function
+foo ()
+{
+ echo < <(cat x1)
+}
+foo ()
+{
+ echo < <(cat x1)
+}
+bar () { echo < <(cat x1) }
+bar is a function
+bar ()
+{
+ echo < <(cat x1)
+}
+argv[1] = </>
+argv[1] = </>
+./new-exp.tests: line 576: ABXD: parameter unset
diff --git a/tests/new-exp.tests b/tests/new-exp.tests
index 78a0e7f..8c43b66 100644
--- a/tests/new-exp.tests
+++ b/tests/new-exp.tests
@@ -553,8 +553,24 @@ echo ${var/#/--}
echo ${var[@]##?}
echo ${var##?}
+unset var
+var=(abcde abcfg abchi)
+
+# problems with anchoring pattern replacements
+echo ${var[*]//#abc/foo}
+echo ${var[*]/#abc/foo}
+unset var
+
${THIS_SH} ./new-exp6.sub
+${THIS_SH} ./new-exp7.sub
+
+# problems with stray CTLNUL in bash-4.0-alpha
+unset a
+a=/a
+recho "/${a%/*}"
+recho "/${a///a/}"
+
# this must be last!
expect $0: 'ABXD: parameter unset'
recho ${ABXD:?"parameter unset"}
diff --git a/tests/new-exp5.sub b/tests/new-exp5.sub
index 9b3e1b3..0ee86e9 100644
--- a/tests/new-exp5.sub
+++ b/tests/new-exp5.sub
@@ -28,3 +28,13 @@ a=0123456789
echo ${a:1}
echo ${a: -1}
echo ${a: ${#a}-1}
+
+# problem with bash through 3.2.33
+oIFS="$IFS"
+IFS=$'\n'
+a=(A B C D)
+b=("${a[@]}")
+echo "${#b[@]}", "${b[@]}" # 4, A B C D -- OK
+b=("${a[@]:2}")
+echo "${#b[@]}", "${b[@]}" # 1, C D -- bug, should be 2, C D
+IFS="$oIFS"
diff --git a/tests/new-exp6.sub b/tests/new-exp6.sub
new file mode 100644
index 0000000..532ec1a
--- /dev/null
+++ b/tests/new-exp6.sub
@@ -0,0 +1,29 @@
+# quoted null problems in versions of bash prior to 3.2
+
+str='12'
+snul=$'\177'
+
+recho "${str:2}"
+recho "+${str:2}"
+recho "+${snul:0:1}"
+recho "+""${str:2}"
+
+recho "${str/?/$snul}"
+recho ${str/?/$snul}
+
+recho "${snul/x/y}"
+recho ${snul/x/y}
+
+recho "${snul/$snul/}"
+recho "${str/$str/}"
+
+recho "${snul##$snul}"
+recho "${str##$str}"
+recho "${str##$nul}"
+
+A=""
+B="${A:0}"
+
+recho "$B"
+recho "${A:0}"
+recho "/tmp/test/TEST${A:0}"
diff --git a/tests/new-exp7.sub b/tests/new-exp7.sub
new file mode 100644
index 0000000..970475c
--- /dev/null
+++ b/tests/new-exp7.sub
@@ -0,0 +1,13 @@
+foo()
+{
+ echo < <(cat x1)
+}
+
+type foo
+
+declare -f foo
+
+echo $(declare -f foo | sed 's:foo:bar:')
+eval "$(declare -f foo | sed 's:foo:bar:')"
+
+type bar
diff --git a/tests/nquote.right b/tests/nquote.right
index 6d936d5..267f0e7 100644
--- a/tests/nquote.right
+++ b/tests/nquote.right
@@ -35,3 +35,6 @@ argv[1] = <hello, $world>
;foo
argv[1] = <^I>
argv[1] = <'A^IB'>
+hello' world
+hello world!
+hello' world!
diff --git a/tests/nquote.tests b/tests/nquote.tests
index 62d90b9..720c3e1 100644
--- a/tests/nquote.tests
+++ b/tests/nquote.tests
@@ -114,3 +114,5 @@ args ()
unset mytab
recho "${mytab:-$'\t'}"
recho "$( args $'A\tB' )"
+
+${THIS_SH} ./nquote1.sub
diff --git a/tests/nquote1.sub b/tests/nquote1.sub
new file mode 100644
index 0000000..b3bc0db
--- /dev/null
+++ b/tests/nquote1.sub
@@ -0,0 +1,6 @@
+set -o history
+set -H
+
+echo $'hello\' world'
+echo $'hello world!'
+echo $'hello\' world!'
diff --git a/tests/nquote5.right b/tests/nquote5.right
new file mode 100644
index 0000000..a893329
--- /dev/null
+++ b/tests/nquote5.right
@@ -0,0 +1,86 @@
+argv[1] = <ab>
+argv[2] = <cd>
+argv[3] = <ef>
+argv[1] = <ab>
+argv[2] = <cd>
+argv[3] = <ef>
+argv[1] = <xxab>
+argv[2] = <cd>
+argv[3] = <efyy>
+argv[1] = <ab^Acd^Aef>
+argv[1] = <ab cd ef>
+argv[1] = <ab>
+argv[2] = <cd>
+argv[3] = <ef>
+argv[1] = <ab>
+argv[2] = <cd>
+argv[1] = <ab^Acd^A>
+argv[1] = <ab>
+argv[2] = <cd>
+argv[3] = <e>
+argv[1] = <ab^Acd^Ae>
+argv[1] = <ab>
+argv[2] = <cd>
+argv[3] = <ef>
+argv[1] = <ab>
+argv[2] = <cd>
+argv[3] = <ef>
+argv[1] = <>
+argv[2] = <c>
+argv[1] = <ab>
+argv[2] = <-->
+argv[3] = <cd>
+argv[4] = <-->
+argv[5] = <ef>
+argv[1] = <ab>
+argv[2] = <cd>
+argv[3] = <ef>
+argv[1] = <ab>
+argv[2] = <cd>
+argv[3] = <ef>
+argv[1] = <ab>
+argv[2] = <-->
+argv[3] = <cd>
+argv[4] = <-->
+argv[5] = <ef>
+argv[1] = <uv^?wx^?yz>
+argv[1] = <abyab^Acd^Aefz>
+argv[1] = <abyab>
+argv[2] = <cd>
+argv[3] = <efz>
+argv[1] = <abuv^?wx^?yzyab^Acd^Aefz>
+argv[1] = <abuv^?wx^?yzyab>
+argv[2] = <cd>
+argv[3] = <efz>
+argv[1] = <abuv^?wx^?yzyab>
+argv[2] = <-->
+argv[3] = <cd>
+argv[4] = <-->
+argv[5] = <efz>
+argv[6] = <-->
+argv[1] = <ab^Acd^Aef>
+argv[1] = <uv>
+argv[2] = <wx>
+argv[3] = <yz>
+argv[1] = <abyuv^?wx^?yzz>
+argv[1] = <abyuv>
+argv[2] = <wx>
+argv[3] = <yzz>
+argv[1] = <abuv^?wx^?yzyab^Acd^Aefz>
+argv[1] = <abuv>
+argv[2] = <wx>
+argv[3] = <yzyab^Acd^Aefz>
+argv[1] = <abuv^?wx^?yzyab>
+argv[2] = <-->
+argv[3] = <cd>
+argv[4] = <-->
+argv[5] = <efz>
+argv[6] = <-->
+argv[7] = <>
+argv[1] = <abuv>
+argv[2] = <-->
+argv[3] = <wx>
+argv[4] = <-->
+argv[5] = <yzyab^Acd^Aefz>
+argv[6] = <-->
+argv[7] = <>
diff --git a/tests/nquote5.tests b/tests/nquote5.tests
new file mode 100644
index 0000000..85a2ff6
--- /dev/null
+++ b/tests/nquote5.tests
@@ -0,0 +1,63 @@
+a=$'ab\001cd\001ef'
+IFS=$'\001'
+
+recho $a
+recho ${a}
+recho xx${a}yy
+recho "$a"
+
+recho $(echo $a)
+recho $(echo "$a")
+
+recho ${a%%??}
+recho "${a%%??}"
+
+recho ${a/f/}
+recho "${a/f/}"
+
+a1=("$a")
+recho ${a1[0]}
+recho ${a1}
+
+recho ${a:2:2}
+
+set -- $a
+recho $1 -- $2 -- $3
+
+set -- "$a"
+recho $1
+recho ${1}
+
+echo "$a" | { IFS=$'\001' read x y z; recho $x -- $y -- $z ; }
+unset x y z
+b=$'uv\177wx\177yz'
+
+recho $b
+
+recho "ab${x}y${a}z"
+recho ab${x}y${a}z
+
+recho "ab${b}y${a}z"
+recho ab${b}y${a}z
+
+echo "ab${b}y${a}z" | { IFS=$'\001' read l m n o ; recho $l -- $m -- $n -- $o; }
+unset l m n o
+
+a=$'ab\001cd\001ef'
+b=$'uv\177wx\177yz'
+
+IFS=$'\177'
+
+recho $a
+recho $b
+
+recho "ab${x}y${b}z"
+recho ab${x}y${b}z
+
+recho "ab${b}y${a}z"
+recho ab${b}y${a}z
+
+echo "ab${b}y${a}z" | { IFS=$'\001' read l m n o ; recho "$l" -- "$m" -- "$n" -- "$o"; }
+unset l m n o
+echo "ab${b}y${a}z" | { IFS=$'\177' read l m n o ; recho "$l" -- "$m" -- "$n" -- "$o"; }
+unset l m n o
diff --git a/tests/printf.right b/tests/printf.right
index 656b198..a6bb04d 100644
--- a/tests/printf.right
+++ b/tests/printf.right
Binary files differ
diff --git a/tests/printf.tests b/tests/printf.tests
index 60928d6..3dd5248 100644
--- a/tests/printf.tests
+++ b/tests/printf.tests
@@ -253,3 +253,59 @@ printf '%0.5d\n' 1
printf '%05d\n' 1
printf '%5d\n' 1
printf '%0d\n' 1
+
+# failures with various floating point formats and 0 after bash-3.2
+
+printf "%G\n" 0
+printf "%g\n" 0
+printf "%4.2G\n" 0
+printf "%4.2g\n" 0
+
+printf "%G\n" 4
+printf "%g\n" 4
+printf "%4.2G\n" 4
+printf "%4.2g\n" 4
+
+printf "%F\n" 0
+printf "%f\n" 0
+printf "%4.2F\n" 0
+printf "%4.2f\n" 0
+
+printf "%F\n" 4
+printf "%f\n" 4
+printf "%4.2F\n" 4
+printf "%4.2f\n" 4
+
+printf "%E\n" 0
+printf "%e\n" 0
+printf "%4.2E\n" 0
+printf "%4.2e\n" 0
+
+printf "%E\n" 4
+printf "%e\n" 4
+printf "%4.2E\n" 4
+printf "%4.2e\n" 4
+
+printf "%08X\n" 2604292517
+
+# make sure these format specifiers all output '' for empty string arguments
+echo q
+printf "%q\n" ""
+printf "%q\n"
+
+echo s
+printf "%s\n" ''
+printf "%s\n"
+
+echo b
+printf "%b\n" ''
+printf "%b\n"
+
+# bug in bash versions up to and including bash-3.2
+v=yyy
+printf -v var "%s" '/current/working/directory/*.@(m3|i3|ig|mg)'
+shopt -s nullglob extglob
+echo "x$(printf "%b" @(hugo))x"
+printf -v var "%b" @(hugo); echo "x${var}x"
+
+${THIS_SH} ./printf2.sub
diff --git a/tests/printf2.sub b/tests/printf2.sub
new file mode 100644
index 0000000..4cff30d
--- /dev/null
+++ b/tests/printf2.sub
@@ -0,0 +1,6 @@
+export LANG=en_US.UTF-8
+
+case $(printf %d\\n \'À) in
+192) exit 0;;
+*) echo "printf2.sub: multibyte character conversion failed" >&2 ; exit 2 ;;
+esac
diff --git a/tests/read.right b/tests/read.right
index 8f0b2bf..b463825 100644
--- a/tests/read.right
+++ b/tests/read.right
@@ -33,13 +33,13 @@ a = abcdefg
a = xyz
a = -xyz 123-
a = abc
+timeout 1: ok
+
+timeout 2: ok
+
+./read2.sub: line 23: read: -3: invalid timeout specification
1
-4
-1
-4
-./read2.sub: line 13: read: -3: invalid timeout specification
-1
-4
+
abcde
./read3.sub: line 4: read: -1: invalid number
abc
@@ -60,3 +60,6 @@ argv[2] = <>
argv[3] = <>
FOO
0 0 0
+0
+0
+1
diff --git a/tests/read.tests b/tests/read.tests
index f9c78c5..fe27dae 100644
--- a/tests/read.tests
+++ b/tests/read.tests
@@ -93,3 +93,6 @@ ${THIS_SH} ./read4.sub
# test behavior when IFS is not the default -- bug through bash-2.05b
${THIS_SH} ./read5.sub
+
+# test behavior of read -t 0
+${THIS_SH} ./read6.sub
diff --git a/tests/read2.sub b/tests/read2.sub
index 176cf86..c4a1f77 100644
--- a/tests/read2.sub
+++ b/tests/read2.sub
@@ -1,12 +1,22 @@
a=4
read -t 2 a < /dev/tty
-echo $?
+estat=$?
+if [ $estat -gt 128 ]; then
+ echo timeout 1: ok
+else
+ echo $estat
+fi
echo $a
sleep 5 | read -t 1 a
-echo $?
+estat=$?
+if [ $estat -gt 128 ]; then
+ echo timeout 2: ok
+else
+ echo $estat
+fi
echo $a
diff --git a/tests/read6.sub b/tests/read6.sub
new file mode 100644
index 0000000..abfe89d
--- /dev/null
+++ b/tests/read6.sub
@@ -0,0 +1,10 @@
+# test read with a timeout of 0 -- input polling
+# sleep with fractional seconds argument is not universal
+echo abcde | { sleep 0.25 2>/dev/null ; read -t 0; }
+echo $?
+
+read -t 0 < $0
+echo $?
+
+read -t 0
+echo $?
diff --git a/tests/redir.right b/tests/redir.right
index e56b980..f816c63 100644
--- a/tests/redir.right
+++ b/tests/redir.right
@@ -1,9 +1,9 @@
abc
-./redir.tests: line 13: /tmp/redir-test: cannot overwrite existing file
+./redir.tests: line 15: /tmp/redir-test: cannot overwrite existing file
abc
def
def
-./redir.tests: line 29: $z: ambiguous redirect
+./redir.tests: line 31: $z: ambiguous redirect
Point 1
Point 2
to a
@@ -44,7 +44,7 @@ kl
ab
cd
cd
-./redir.tests: line 152: redir1.*: No such file or directory
+./redir.tests: line 154: redir1.*: No such file or directory
# tests of ksh93-like dup-and-close redirection operators
exec 9<$0
@@ -100,3 +100,42 @@ c1 is 1
c2 is 2
c3 is 3
c4 is 4
+fd 10
+fd 8
+fd 10
+fd 8
+1
+2
+3
+4
+1
+2
+3
+4
+cat /tmp/foo
+whatsis
+hey
+to stdout
+to stderr
+
+to stdout
+to stderr
+
+to stderr
+to stdout
+
+to stderr
+hey
+to stdout
+logfunc is a function
+logfunc ()
+{
+ echo "$@" &>>$TMPDIR/log
+}
+foo
+bix is a function
+bix ()
+{
+ echo foo 2>&1 | cat
+}
+foo
diff --git a/tests/redir.tests b/tests/redir.tests
index 2669cd4..37759b5 100644
--- a/tests/redir.tests
+++ b/tests/redir.tests
@@ -1,3 +1,5 @@
+: ${TMPDIR:=/tmp}
+
export LC_ALL=C
export LANG=C
@@ -31,31 +33,31 @@ cat < $z
echo "Point 1"
exec 3</etc/passwd
-exec 4>/tmp/bash-a
-exec 5>/tmp/bash-b
+exec 4>$TMPDIR/bash-a
+exec 5>$TMPDIR/bash-b
echo "Point 2"
echo to a 1>&4
echo to b 1>&5
-cat /tmp/bash-a
-cat /tmp/bash-b
+cat $TMPDIR/bash-a
+cat $TMPDIR/bash-b
exec 11</dev/null
echo "Point 3"
echo to a 1>&4
echo to b 1>&5
-cat /tmp/bash-a
-cat /tmp/bash-b
+cat $TMPDIR/bash-a
+cat $TMPDIR/bash-b
exec 11<&-
echo "Point 4"
-exec 6<>/tmp/bash-c
+exec 6<>$TMPDIR/bash-c
echo to c 1>&6
-cat /tmp/bash-c
+cat $TMPDIR/bash-c
echo "Point 5"
-rm -f /tmp/bash-a /tmp/bash-b /tmp/bash-c
+rm -f $TMPDIR/bash-a $TMPDIR/bash-b $TMPDIR/bash-c
#
# Test the effect of input buffering on the shell's input
@@ -78,34 +80,34 @@ testf()
fi
}
-> /tmp/null-redir-a
-testf /tmp/null-redir-a
+> $TMPDIR/null-redir-a
+testf $TMPDIR/null-redir-a
-$EXIT > /tmp/null-redir-b
-testf /tmp/null-redir-b
+$EXIT > $TMPDIR/null-redir-b
+testf $TMPDIR/null-redir-b
-( > /tmp/null-redir-c )
-testf /tmp/null-redir-c
+( > $TMPDIR/null-redir-c )
+testf $TMPDIR/null-redir-c
-$EXIT > /tmp/null-redir-d &
+$EXIT > $TMPDIR/null-redir-d &
wait
-testf /tmp/null-redir-d
+testf $TMPDIR/null-redir-d
-exit 3 | $EXIT > /tmp/null-redir-e
+exit 3 | $EXIT > $TMPDIR/null-redir-e
echo $? -- ${PIPESTATUS[@]}
-testf /tmp/null-redir-e
+testf $TMPDIR/null-redir-e
-exit 4 | > /tmp/null-redir-f
+exit 4 | > $TMPDIR/null-redir-f
echo $? -- ${PIPESTATUS[@]}
-testf /tmp/null-redir-f
+testf $TMPDIR/null-redir-f
-> /tmp/null-redir-g &
+> $TMPDIR/null-redir-g &
wait
-testf /tmp/null-redir-g
+testf $TMPDIR/null-redir-g
-exec >/tmp/null-redir-h &
+exec >$TMPDIR/null-redir-h &
wait
-testf /tmp/null-redir-h
+testf $TMPDIR/null-redir-h
# make sure async commands don't get /dev/null as stdin when an explicit
# input redirection is supplied
@@ -158,7 +160,7 @@ ${THIS_SH} ./redir5.sub
${THIS_SH} ./redir6.sub
# problem with redirections using fds bash uses internally
-: ${TMPDIR:=/tmp}
+: ${TMPDIR:=$TMPDIR}
trap 'rm -f $TMPDIR/bash-redir-$$' 0 1 2 3 6 15
@@ -172,3 +174,16 @@ echo before block
echo after block
${THIS_SH} ./redir7.sub
+
+${THIS_SH} ./redir8.sub
+
+exec 9>&2
+command exec 2>$TMPDIR/foo-$$
+echo whatsis >&2
+echo cat /tmp/foo
+cat $TMPDIR/foo-$$
+rm -f $TMPDIR/foo-$$
+exec 2>&9
+exec 9>&-
+
+${THIS_SH} ./redir9.sub
diff --git a/tests/redir8.sub b/tests/redir8.sub
new file mode 100644
index 0000000..5f972a1
--- /dev/null
+++ b/tests/redir8.sub
@@ -0,0 +1,59 @@
+cd ${TMPDIR:=/var/tmp}
+rm -f u
+
+${THIS_SH} -c 'exec 10>&1; echo fd 10 >&10' 10>u
+cat u
+rm -f u
+
+${THIS_SH} -c 'exec 8>&1; echo fd 8 >&8' 8>u
+cat u
+rm -f u
+
+exec 10>u
+exec 10>&1; echo 'fd 10' >&10
+cat u
+rm -f u
+exec 10>&-
+
+exec 8>u
+exec 8>&1; echo 'fd 8' >&8
+cat u
+rm -f u
+exec 8>&-
+
+rm -f infile
+cat > infile <<EOF
+1
+2
+3
+4
+EOF
+
+exec 7<&0
+exec 10<infile
+exec 0<&10; cat <&10
+exec 0<&7
+exec 7<&-
+
+exec 7<&0
+exec 8<infile
+exec 0<&8 ; cat <&8
+exec 0<&7
+exec 7<&-
+
+exec 7<&0
+exec 0</dev/null
+exec 10<infile
+exec 10<&0; cat <&10
+exec 0<&7
+exec 7<&-
+
+exec 7<&0
+exec 0</dev/null
+exec 8<infile
+exec 8<&0; cat <&8
+exec 0<&7
+exec 7<&-
+
+rm -f infile
+exit 0
diff --git a/tests/redir9.sub b/tests/redir9.sub
new file mode 100644
index 0000000..386ae56
--- /dev/null
+++ b/tests/redir9.sub
@@ -0,0 +1,50 @@
+: ${TMPDIR:=/tmp}
+
+func()
+{
+ echo "to stdout"
+ echo "to stderr" >&2
+}
+
+TMPFN=$TMPDIR/foo-$$
+
+rm -f $TMPFN
+
+echo hey > $TMPFN
+func &>> $TMPFN
+
+cat $TMPFN
+
+echo
+func &> $TMPFN
+
+cat $TMPFN
+
+echo
+func >$TMPFN
+cat $TMPFN
+
+echo
+echo hey > $TMPFN
+func >> $TMPFN
+cat $TMPFN
+
+rm -f $TMPFN
+
+logfunc()
+{
+ echo "$@" &>> $TMPDIR/log
+}
+
+type logfunc
+
+echo foo 2>&1
+
+bix()
+{
+echo foo |& cat
+}
+
+type bix
+
+bix
diff --git a/tests/rsh.right b/tests/rsh.right
index e673b94..04c6971 100644
--- a/tests/rsh.right
+++ b/tests/rsh.right
@@ -7,7 +7,7 @@
./rsh.tests: line 21: /tmp/restricted: restricted: cannot redirect output
./rsh.tests: line 26: command: -p: restricted
./rsh.tests: line 28: set: +r: invalid option
-set: usage: set [--abefhkmnptuvxBCHP] [-o option] [arg ...]
+set: usage: set [--abefhkmnptuvxBCHP] [-o option-name] [arg ...]
./rsh.tests: line 29: set: restricted: invalid option name
./rsh.tests: line 31: exec: restricted
./rsh.tests: after exec
diff --git a/tests/run-array b/tests/run-array
index 44207d9..6fdbae4 100644
--- a/tests/run-array
+++ b/tests/run-array
@@ -1,4 +1,6 @@
echo "warning: all of these tests will fail if arrays have not" >&2
echo "warning: been compiled into the shell" >&2
+echo "warning: the BASH_ARGC and BASH_ARGV tests will fail if debugging support" >&2
+echo "warning: has not been compiled into the shell" >&2
${THIS_SH} ./array.tests > /tmp/xx 2>&1
diff /tmp/xx array.right && rm -f /tmp/xx
diff --git a/tests/run-assoc b/tests/run-assoc
new file mode 100644
index 0000000..18c3a9c
--- /dev/null
+++ b/tests/run-assoc
@@ -0,0 +1,4 @@
+echo "warning: all of these tests will fail if arrays have not" >&2
+echo "warning: been compiled into the shell" >&2
+${THIS_SH} ./assoc.tests > /tmp/xx 2>&1
+diff /tmp/xx assoc.right && rm -f /tmp/xx
diff --git a/tests/run-builtins b/tests/run-builtins
index 53d963e..db88c8c 100644
--- a/tests/run-builtins
+++ b/tests/run-builtins
@@ -1,2 +1,6 @@
+echo "warning: some of these tests may fail if process substitution has not" >&2
+echo "warning: been compiled into the shell or if the OS does not provide" >&2
+echo "warning: /dev/fd." >&2
+
${THIS_SH} ./builtins.tests > /tmp/xx 2>&1
diff /tmp/xx builtins.right && rm -f /tmp/xx
diff --git a/tests/run-case b/tests/run-case
new file mode 100644
index 0000000..71d9b83
--- /dev/null
+++ b/tests/run-case
@@ -0,0 +1,2 @@
+${THIS_SH} ./case.tests > /tmp/xx 2>&1
+diff /tmp/xx case.right && rm -f /tmp/xx
diff --git a/tests/run-casemod b/tests/run-casemod
new file mode 100644
index 0000000..83c1b5a
--- /dev/null
+++ b/tests/run-casemod
@@ -0,0 +1,2 @@
+${THIS_SH} ./casemod.tests > /tmp/xx 2>&1
+diff /tmp/xx casemod.right && rm -f /tmp/xx
diff --git a/tests/run-comsub b/tests/run-comsub
new file mode 100644
index 0000000..0bbcad5
--- /dev/null
+++ b/tests/run-comsub
@@ -0,0 +1,2 @@
+${THIS_SH} ./comsub.tests > /tmp/xx 2>&1
+diff /tmp/xx comsub.right && rm -f /tmp/xx
diff --git a/tests/run-comsub-eof b/tests/run-comsub-eof
new file mode 100644
index 0000000..5c006be
--- /dev/null
+++ b/tests/run-comsub-eof
@@ -0,0 +1,2 @@
+${THIS_SH} ./comsub-eof.tests > /tmp/xx 2>&1
+diff /tmp/xx comsub-eof.right && rm -f /tmp/xx
diff --git a/tests/run-comsub-posix b/tests/run-comsub-posix
new file mode 100644
index 0000000..38bf8ee
--- /dev/null
+++ b/tests/run-comsub-posix
@@ -0,0 +1,2 @@
+${THIS_SH} ./comsub-posix.tests > /tmp/xx 2>&1
+diff /tmp/xx comsub-posix.right && rm -f /tmp/xx
diff --git a/tests/run-coproc b/tests/run-coproc
new file mode 100644
index 0000000..ce62474
--- /dev/null
+++ b/tests/run-coproc
@@ -0,0 +1,4 @@
+echo "warning: the process IDs printed will differ on every run" >&2
+echo "warning: and generate diffs" >&2
+${THIS_SH} ./coproc.tests > /tmp/xx 2>&1
+diff /tmp/xx coproc.right && rm -f /tmp/xx
diff --git a/tests/run-exp-tests b/tests/run-exp-tests
index c55f714..cbabace 100644
--- a/tests/run-exp-tests
+++ b/tests/run-exp-tests
@@ -1,2 +1,2 @@
-${THIS_SH} ./exp-tests | grep -v '^expect' > /tmp/xx
+${THIS_SH} ./exp.tests | grep -v '^expect' > /tmp/xx
diff /tmp/xx exp.right && rm -f /tmp/xx
diff --git a/tests/run-glob-test b/tests/run-glob-test
index 659112a..7a12343 100644
--- a/tests/run-glob-test
+++ b/tests/run-glob-test
@@ -1,4 +1,4 @@
PATH=$PATH:`pwd`
export PATH
-${THIS_SH} ./glob-test 2>&1 | grep -v '^expect' > /tmp/xx
+${THIS_SH} ./glob.tests 2>&1 | grep -v '^expect' > /tmp/xx
diff /tmp/xx glob.right && rm -f /tmp/xx
diff --git a/tests/run-globstar b/tests/run-globstar
new file mode 100644
index 0000000..d12cce9
--- /dev/null
+++ b/tests/run-globstar
@@ -0,0 +1,4 @@
+PATH=$PATH:`pwd`
+export PATH
+${THIS_SH} ./globstar.tests > /tmp/xx 2>&1
+diff /tmp/xx globstar.right && rm -f /tmp/xx
diff --git a/tests/run-invert b/tests/run-invert
index 67e0879..4949307 100644
--- a/tests/run-invert
+++ b/tests/run-invert
@@ -1,2 +1,2 @@
-${THIS_SH} ./invert.tests | grep -v '^expect' > /tmp/xx
+${THIS_SH} ./invert.tests 2>&1 | grep -v '^expect' > /tmp/xx
diff /tmp/xx invert.right && rm -f /tmp/xx
diff --git a/tests/run-mapfile b/tests/run-mapfile
new file mode 100644
index 0000000..a207f09
--- /dev/null
+++ b/tests/run-mapfile
@@ -0,0 +1,2 @@
+${THIS_SH} ./mapfile.tests > /tmp/xx 2>&1
+diff /tmp/xx mapfile.right && rm -f /tmp/xx
diff --git a/tests/run-minimal b/tests/run-minimal
index 5c5dcc4..0054cda 100644
--- a/tests/run-minimal
+++ b/tests/run-minimal
@@ -27,7 +27,7 @@ do
*.orig|*~) ;;
run-dollars|run-execscript|run-func|run-getopts|run-heredoc) echo $x ; sh $x ;;
run-ifs-tests|run-input-test|run-invert|run-more-exp|run-nquote) echo $x ; sh $x ;;
- run-ifs-0posix|run-posix2|run-posixpat) echo $x ; sh $x ;;
+ run-ifs-posix|run-posix2|run-posixpat) echo $x ; sh $x ;;
run-precedence|run-quote|run-read|run-rhs-exp|run-strip|run-tilde) echo $x ; sh $x ;;
*) ;;
esac
diff --git a/tests/run-nquote4 b/tests/run-nquote4
index f7d05bb..493f4aa 100644
--- a/tests/run-nquote4
+++ b/tests/run-nquote4
@@ -1,4 +1,4 @@
echo warning: some of these tests will fail if you do not have UTF-8 >&2
-echo warning: locales installed on your system
+echo warning: locales installed on your system >&2
${THIS_SH} ./nquote4.tests 2>&1 | grep -v '^expect' > /tmp/xx
diff /tmp/xx nquote4.right && rm -f /tmp/xx
diff --git a/tests/run-nquote5 b/tests/run-nquote5
new file mode 100644
index 0000000..14cef64
--- /dev/null
+++ b/tests/run-nquote5
@@ -0,0 +1,2 @@
+${THIS_SH} ./nquote5.tests 2>&1 | grep -v '^expect' > /tmp/xx
+diff /tmp/xx nquote5.right && rm -f /tmp/xx
diff --git a/tests/run-set-e b/tests/run-set-e
index cca61cd..3389f11 100644
--- a/tests/run-set-e
+++ b/tests/run-set-e
@@ -1,2 +1,2 @@
-${THIS_SH} ./set-e-test > /tmp/xx
+${THIS_SH} ./set-e.tests > /tmp/xx
diff /tmp/xx set-e.right && rm -f /tmp/xx
diff --git a/tests/run-trap b/tests/run-trap
index b448443..14f6874 100644
--- a/tests/run-trap
+++ b/tests/run-trap
@@ -1,6 +1,6 @@
-echo "warning: UNIX versions number signals differently. If output differing" >&2
-echo "warning: only in line numbers is produced, please do not consider this" >&2
-echo "warning: a test failure." >&2
+echo "warning: UNIX versions number signals and schedule processes differently." >&2
+echo "warning: If output differing only in line numbers is produced, please" >&2
+echo "warning: do not consider this a test failure." >&2
${THIS_SH} ./trap.tests > /tmp/xx 2>&1
diff /tmp/xx trap.right && rm -f /tmp/xx
diff --git a/tests/run-vredir b/tests/run-vredir
new file mode 100644
index 0000000..9a96377
--- /dev/null
+++ b/tests/run-vredir
@@ -0,0 +1,2 @@
+${THIS_SH} ./vredir.tests > /tmp/xx 2>&1
+diff /tmp/xx vredir.right && rm -f /tmp/xx
diff --git a/tests/set-e.right b/tests/set-e.right
index 6448413..85a5986 100644
--- a/tests/set-e.right
+++ b/tests/set-e.right
@@ -26,3 +26,42 @@ OR list succeeded
eval succeeded
! eval succeeded -- 1
! eval succeeded -- 2
+a
+0
+b
+0
+after 1
+a
+0
+non-posix foo
+after brace group failure: 1
+A 1
+B 0
+C 0
+D 0
+D 1
+A 1
+B 0
+C 0
+D 0
+D 1
+A 1
+B 0
+C 0
+A 1
+B 1
+C 0
+B 0
+C 0
+after negation 1: 0
+after negation 2: 0
+after negation 3: 1
+after negation 4: 0
+after brace pipeline
+foo
+after failure 1
+after failure 2
+after failure 3
+true || false no exit
+false || true no exit
+false && false no exit
diff --git a/tests/set-e-test b/tests/set-e.tests
index fe1549c..8c0cfcf 100644
--- a/tests/set-e-test
+++ b/tests/set-e.tests
@@ -82,3 +82,29 @@ echo ! eval succeeded -- 1
! eval '(exit 5)'
echo ! eval succeeded -- 2
+
+set -e
+until builtin false; do echo a; break; done
+echo $?
+
+until eval false; do echo b; break; done
+echo $?
+
+: ${TMPDIR:=/tmp}
+FN=$TMPDIR/set-e-$$
+cat > $FN << EOF
+false
+echo after 1
+false
+EOF
+
+set -e
+until . $FN; do echo a; break; done
+echo $?
+
+rm -f $FN
+
+set +e
+
+${THIS_SH} ./set-e1.sub
+${THIS_SH} ./set-e2.sub
diff --git a/tests/set-e1.sub b/tests/set-e1.sub
new file mode 100644
index 0000000..a800560
--- /dev/null
+++ b/tests/set-e1.sub
@@ -0,0 +1,59 @@
+# subshell failure should cause the shell to exit silently
+${THIS_SH} -ce '(exit 17) ; echo "after (exit 17): $?"'
+
+# pipeline failure should cause shell to exit silently
+${THIS_SH} -c 'set -e ; false | echo foo | while read x ; do ( exit 17 ) ; done; echo after pipeline subshell;'
+
+# should be silent in posix mode
+${THIS_SH} -c 'set -o posix; set -e ; z=$(false;echo posix foo) ; echo $z'
+# but echo foo in non-posix
+${THIS_SH} -c 'set -e ; z=$(false;echo non-posix foo) ; echo $z'
+
+${THIS_SH} -ce 'x=$(false) ; echo "x=\$(false) does not exit"'
+
+${THIS_SH} -ce '{ false; echo false in brace group does not exit; }'
+echo after brace group failure: $?
+
+${THIS_SH} -ce '(false ; echo A $?) && echo B $?; echo C $?'; echo D $?
+
+${THIS_SH} -ce '(false ; echo A $?) ; echo B $?; echo C $?'; echo D $?
+
+${THIS_SH} -ce 'f() (false ; echo A $?); f && echo B $?; echo C $?'; echo D $?
+
+${THIS_SH} -ce 'f() (false ; echo A $?) ; f; echo B $?; echo C $?'; echo D $?
+
+${THIS_SH} -ce 'if false; echo A $?; then echo B $?; fi'; echo C $?
+
+${THIS_SH} -ce '! { false; echo A $?; } | cat; echo B $?'; echo C $?
+
+${THIS_SH} -ce '{ false; echo A $?; } | cat ; echo B $?'; echo C $?
+
+set -e
+
+! false
+echo after negation 1: $?
+
+! false | false
+echo after negation 2: $?
+
+! true
+echo after negation 3: $?
+
+! (false)
+echo after negation 4: $?
+
+{ false ; echo foo; } | cat
+echo after brace pipeline
+
+false | echo foo | cat
+echo after failure 1
+
+false | (echo foo; false) | true
+echo after failure 2
+
+false | echo foo | while read x ; do ( exit 17 ) ; done | true
+echo after failure 3
+
+# this pipeline failure should cause the shell to exit
+false | echo foo | false
+echo after failure 4
diff --git a/tests/set-e2.sub b/tests/set-e2.sub
new file mode 100644
index 0000000..de04e99
--- /dev/null
+++ b/tests/set-e2.sub
@@ -0,0 +1,10 @@
+${THIS_SH} -ce 'true || false ; echo "true || false no exit"'
+${THIS_SH} -ce 'false || false ; echo "false || false no exit"'
+${THIS_SH} -ce 'false || true ; echo "false || true no exit"'
+
+${THIS_SH} -ce 'false && false ; echo "false && false no exit"'
+${THIS_SH} -ce 'true && false ; echo "true && false no exit"'
+
+${THIS_SH} -ce 'true && (exit 1) ; echo "true && (exit 1) no exit"'
+${THIS_SH} -ce 'true && true|false ; echo "true && true|false no exit"'
+${THIS_SH} -ce 'true && true|(false) ; echo "true && true|(false) no exit"'
diff --git a/tests/set-x.right b/tests/set-x.right
index fc55bd8..a41a382 100644
--- a/tests/set-x.right
+++ b/tests/set-x.right
@@ -26,3 +26,31 @@
+ x=i
+ case x in
+ x=i
++ set +x
+1
+2
+3
+4
++ for f in a b c d e
++ echo a
+a
++ for f in a b c d e
++ echo b
+b
++ for f in a b c d e
++ echo c
+c
++ for f in a b c d e
++ echo d
+d
++ for f in a b c d e
++ echo e
+e
++ set +x
+TRACEFILE:
++ echo 1
++ echo 2
++ echo 3
++ echo 4
++ unset BASH_XTRACEFD
+=====
diff --git a/tests/set-x.tests b/tests/set-x.tests
index 323b772..648f0a9 100755
--- a/tests/set-x.tests
+++ b/tests/set-x.tests
@@ -14,8 +14,7 @@ case x in
0) x=i ;;
*) x=i ;;
esac
+set +x
-#;;; Local Variables: ***
-#;;; mode:shell-script ***
-#;;; eval: (sh-set-shell "bash") ***
-#;;; End: ***
+# test BASH_XTRACEFD
+${THIS_SH} ./set-x1.sub
diff --git a/tests/set-x1.sub b/tests/set-x1.sub
new file mode 100644
index 0000000..b2aa216
--- /dev/null
+++ b/tests/set-x1.sub
@@ -0,0 +1,25 @@
+: ${TMPDIR:=/var/tmp}
+TRACEFILE=$TMPDIR/bash-trace-$$
+trap 'rm -f $TRACEFILE' 0 1 2 3 6 15
+
+exec 4>$TRACEFILE
+BASH_XTRACEFD=4
+
+set -x
+
+echo 1
+echo 2
+echo 3
+echo 4
+
+unset BASH_XTRACEFD
+
+for f in a b c d e; do echo $f ; done
+
+set +x
+
+echo TRACEFILE:
+cat $TRACEFILE
+echo =====
+
+exit 0
diff --git a/tests/shopt.right b/tests/shopt.right
index b2fc219..7bacc0e 100644
--- a/tests/shopt.right
+++ b/tests/shopt.right
@@ -1,11 +1,17 @@
./shopt.tests: line 2: shopt: -z: invalid option
-shopt: usage: shopt [-pqsu] [-o long-option] optname [optname...]
+shopt: usage: shopt [-pqsu] [-o] [optname ...]
--
+shopt -u autocd
shopt -u cdable_vars
shopt -s cdspell
shopt -u checkhash
+shopt -u checkjobs
shopt -u checkwinsize
shopt -s cmdhist
+shopt -u compat31
+shopt -u compat32
+shopt -u compat40
+shopt -u dirspell
shopt -u dotglob
shopt -u execfail
shopt -s expand_aliases
@@ -14,6 +20,7 @@ shopt -u extglob
shopt -s extquote
shopt -u failglob
shopt -s force_fignore
+shopt -u globstar
shopt -u gnu_errfmt
shopt -u histappend
shopt -u histreedit
@@ -50,14 +57,21 @@ shopt -s progcomp
shopt -s promptvars
shopt -s sourcepath
--
+shopt -u autocd
shopt -u cdable_vars
shopt -u checkhash
+shopt -u checkjobs
shopt -u checkwinsize
+shopt -u compat31
+shopt -u compat32
+shopt -u compat40
+shopt -u dirspell
shopt -u dotglob
shopt -u execfail
shopt -u extdebug
shopt -u extglob
shopt -u failglob
+shopt -u globstar
shopt -u gnu_errfmt
shopt -u histappend
shopt -u histreedit
@@ -74,14 +88,21 @@ shopt -u restricted_shell
shopt -u shift_verbose
shopt -u xpg_echo
--
+autocd off
cdable_vars off
checkhash off
+checkjobs off
checkwinsize off
+compat31 off
+compat32 off
+compat40 off
+dirspell off
dotglob off
execfail off
extdebug off
extglob off
failglob off
+globstar off
gnu_errfmt off
histappend off
histreedit off
diff --git a/tests/source5.sub b/tests/source5.sub
index 813ffae..e618809 100644
--- a/tests/source5.sub
+++ b/tests/source5.sub
@@ -1,4 +1,4 @@
-LC_ALL=en_US
+LC_ALL=en_US.UTF-8
unset LC_ALL
unset LANG
export LC_ALL=C
diff --git a/tests/source6.sub b/tests/source6.sub
new file mode 100644
index 0000000..9e1cb64
--- /dev/null
+++ b/tests/source6.sub
@@ -0,0 +1,31 @@
+# tests sourcing non-regular files, fixed post-3.2
+
+: ${TMPDIR:=/tmp}
+
+TMPFN=$TMPDIR/foo-$$
+
+rm -f $TMPFN
+echo "echo one - OK" > $TMPFN
+. $TMPFN
+echo $?
+rm -f $TMPFN
+
+# non-regular readable file
+. /dev/null
+echo $?
+
+# FIFO or pipe via /dev/fd
+. <(echo "echo two - OK")
+echo $?
+
+# pipe
+echo "echo three - OK" | . /dev/stdin
+echo $?
+
+# FIFO
+mkfifo $TMPDIR/fifo-$$
+echo "echo four - OK" > $TMPDIR/fifo-$$ &
+sleep 1 # allow the child echo to execute
+. $TMPDIR/fifo-$$
+echo $?
+rm -f $TMPDIR/fifo-$$
diff --git a/tests/test.right b/tests/test.right
index beb3af6..c5d7c90 100644
--- a/tests/test.right
+++ b/tests/test.right
@@ -282,3 +282,4 @@ t -t /dev/tty4
1
t -t /dev/tty4444444...
1
+1
diff --git a/tests/test.tests b/tests/test.tests
index a915c4e..47ad9bb 100644
--- a/tests/test.tests
+++ b/tests/test.tests
@@ -421,3 +421,6 @@ echo 't -t /dev/tty4'
t -t /dev/tty4
echo 't -t /dev/tty4444444...'
t -t /dev/tty4444444...
+
+# fixed in bash-4.0-beta
+t -t ' '
diff --git a/tests/trap.right b/tests/trap.right
index 72f3b6d..c8417ac 100644
--- a/tests/trap.right
+++ b/tests/trap.right
@@ -63,6 +63,17 @@ after while
before false in trap2a.sub
after false in trap2a.sub
command substitution
++[6] echo 1
+1
++[7] echo 2
+2
++[8] echo 3
++[8] cat
++[8] false
+++[8] echo trap: 8
+trap: 8
++[9] echo 4
+4
caught a child death
caught a child death
caught a child death
diff --git a/tests/trap.tests b/tests/trap.tests
index 9aac725..ded1d70 100644
--- a/tests/trap.tests
+++ b/tests/trap.tests
@@ -66,6 +66,8 @@ trap '' USR2
# test ERR trap
./trap2.sub
+${THIS_SH} ./trap3.sub
+
#
# show that setting a trap on SIGCHLD is not disastrous.
#
@@ -75,6 +77,7 @@ trap 'echo caught a child death' SIGCHLD
sleep 7 & sleep 6 & sleep 5 &
+# this will only catch the first, since there's a trap on SIGCHLD
wait
trap -p SIGCHLD
@@ -84,3 +87,7 @@ trap -p SIGCHLD
trap - SIGINT QUIT TERM
trap
+
+trap - SIGCHLD
+wait
+
diff --git a/tests/trap3.sub b/tests/trap3.sub
new file mode 100644
index 0000000..0df4455
--- /dev/null
+++ b/tests/trap3.sub
@@ -0,0 +1,9 @@
+PS4='+[$LINENO] '
+trap 'echo trap: $LINENO' ERR
+
+set -x
+
+echo 1
+echo 2
+echo 3 | cat | false
+echo 4
diff --git a/tests/type.right b/tests/type.right
index dbd51ca..a628231 100644
--- a/tests/type.right
+++ b/tests/type.right
@@ -46,3 +46,37 @@ file
hits command
3 /tmp/bash
1 /bin/sh
+f is a function
+f ()
+{
+ v='^A'
+}
+foo is a function
+foo ()
+{
+ echo $(<x1)
+}
+bar is a function
+bar ()
+{
+ echo $(<x1)
+}
+foo is a function
+foo ()
+{
+ echo;
+ cat <<END
+bar
+END
+
+ cat <<EOF
+qux
+EOF
+
+}
+
+bar
+qux
+
+bar
+qux
diff --git a/tests/type.tests b/tests/type.tests
index d47ae64..6caa243 100644
--- a/tests/type.tests
+++ b/tests/type.tests
@@ -80,3 +80,14 @@ type -t $SHBASE
# make sure the hash table looks right
hash
+
+# bug in versions of bash up to and including bash-3.2
+f() {
+ v=$'\001'
+ }
+
+type f | cat -v
+
+${THIS_SH} type1.sub
+
+${THIS_SH} type2.sub
diff --git a/tests/type1.sub b/tests/type1.sub
new file mode 100644
index 0000000..95f96ae
--- /dev/null
+++ b/tests/type1.sub
@@ -0,0 +1,10 @@
+foo()
+{
+ echo $(<x1)
+}
+
+type foo
+
+eval "$(declare -f foo | sed 's:foo:bar:')"
+
+type bar
diff --git a/tests/type2.sub b/tests/type2.sub
new file mode 100644
index 0000000..3f85ead
--- /dev/null
+++ b/tests/type2.sub
@@ -0,0 +1,16 @@
+foo()
+{
+ echo
+ cat <<END
+bar
+END
+ cat <<EOF
+qux
+EOF
+}
+
+type foo
+foo
+
+eval "$(type foo | sed 1d)"
+foo
diff --git a/tests/vredir.right b/tests/vredir.right
new file mode 100644
index 0000000..0e3b24b
--- /dev/null
+++ b/tests/vredir.right
@@ -0,0 +1,88 @@
+10
+foo 1
+foo 2
+foo 3
+bar is a function
+bar ()
+{
+ exec {v}> $TMPFILE;
+ echo $v
+}
+./vredir.tests: line 6: v: readonly variable
+./vredir.tests: line 6: v: cannot assign fd to variable
+42
+./vredir.tests: line 25: $v: Bad file descriptor
+./vredir.tests: line 26: $v: Bad file descriptor
+./vredir.tests: line 27: $v: Bad file descriptor
+bar is a function
+bar ()
+{
+ exec {v}> $TMPFILE;
+ echo $v
+}
+11
+line 1
+line 2
+line 3
+bar is a function
+bar ()
+{
+ exec {v}<<EOF
+line 1
+line 2
+line 3
+EOF
+
+ echo $v
+}
+11
+foo 1
+foo 2
+foo 3
+11
+/bin/bash
+/bin/csh
+/bin/ksh
+/bin/sh
+/bin/tcsh
+/bin/zsh
+oclosev is a function
+oclosev ()
+{
+ exec {v}>&-
+}
+iclosev is a function
+iclosev ()
+{
+ exec {v}>&-
+}
+/bin/bash
+/bin/csh
+/bin/ksh
+/bin/sh
+/bin/tcsh
+/bin/zsh
+./vredir3.sub: line 4: v: ambiguous redirect
+after
+11 12
+a
+a
+swizzle is a function
+swizzle ()
+{
+ fd0=0;
+ fd1=1;
+ exec {stdin}<&$fd0;
+ exec {stdout}>&$fd1
+}
+13 11
+a
+a
+swizzle is a function
+swizzle ()
+{
+ exec {fd0}<&0;
+ exec {fd1}>&1;
+ exec {stdin}<&$fd0-;
+ exec {stdout}>&$fd1-
+}
diff --git a/tests/vredir.tests b/tests/vredir.tests
new file mode 100644
index 0000000..df4fd8f
--- /dev/null
+++ b/tests/vredir.tests
@@ -0,0 +1,44 @@
+: ${TMPDIR:=/var/tmp}
+TMPFILE=$TMPDIR/foo
+
+bar()
+{
+exec {v}>$TMPFILE
+echo $v
+}
+
+bar
+
+echo foo 1 >&$v
+echo foo 2 >&$v
+echo foo 3 >&$v
+
+cat $TMPFILE
+rm -f $TMPFILE
+
+type bar
+exec {v}>&-
+
+readonly v=42
+bar
+
+echo foo 1 >&$v
+echo foo 2 >&$v
+echo foo 3 >&$v
+
+cat $TMPFILE
+rm -f $TMPFILE
+
+type bar
+
+${THIS_SH} ./vredir1.sub
+
+${THIS_SH} ./vredir2.sub
+
+${THIS_SH} ./vredir3.sub
+
+${THIS_SH} ./vredir4.sub
+
+${THIS_SH} ./vredir5.sub
+
+exit 0
diff --git a/tests/vredir1.sub b/tests/vredir1.sub
new file mode 100644
index 0000000..403734c
--- /dev/null
+++ b/tests/vredir1.sub
@@ -0,0 +1,17 @@
+bar()
+{
+exec {v}<<EOF
+line 1
+line 2
+line 3
+EOF
+echo $v
+}
+
+bar
+
+cat <&$v
+
+type bar
+
+exit 0
diff --git a/tests/vredir2.sub b/tests/vredir2.sub
new file mode 100644
index 0000000..e1a380d
--- /dev/null
+++ b/tests/vredir2.sub
@@ -0,0 +1,52 @@
+: ${TMPDIR:=/var/tmp}
+SHELLSFILE=$TMPDIR/shells-$$
+
+cat > $TMPDIR/shells-$$ <<EOF
+/bin/bash
+/bin/csh
+/bin/ksh
+/bin/sh
+/bin/tcsh
+/bin/zsh
+EOF
+
+oclosev()
+{
+exec {v}>&-
+}
+
+iclosev()
+{
+exec {v}<&-
+}
+
+exec {v}>&1
+echo $v
+
+echo foo 1 >&$v
+echo foo 2 >&$v
+echo foo 3 >&$v
+
+oclosev
+
+exec {v}<$SHELLSFILE
+echo $v
+
+while read line <&$v
+do
+ echo $line
+done
+
+iclosev
+
+type oclosev
+type iclosev
+
+while read -r -u ${fd}
+do
+ echo $REPLY
+done {fd}<$SHELLSFILE
+
+rm -f $SHELLSFILE
+
+exit 0
diff --git a/tests/vredir3.sub b/tests/vredir3.sub
new file mode 100644
index 0000000..358ded2
--- /dev/null
+++ b/tests/vredir3.sub
@@ -0,0 +1,8 @@
+# Right now, the {varname} mechanism does not honor set -u for compatibility
+unset v
+set -u
+exec {v}>&-
+
+echo after
+
+exit 0
diff --git a/tests/vredir4.sub b/tests/vredir4.sub
new file mode 100644
index 0000000..e1cef05
--- /dev/null
+++ b/tests/vredir4.sub
@@ -0,0 +1,22 @@
+swizzle()
+{
+fd0=0
+fd1=1
+
+exec {stdin}<&$fd0
+exec {stdout}>&$fd1
+}
+
+swizzle
+echo $stdin $stdout
+
+read line <&$stdin <<EOF
+a
+EOF
+
+echo $line
+echo $line >&$stdout
+
+type swizzle
+
+exit 0
diff --git a/tests/vredir5.sub b/tests/vredir5.sub
new file mode 100644
index 0000000..d1531e9
--- /dev/null
+++ b/tests/vredir5.sub
@@ -0,0 +1,23 @@
+swizzle()
+{
+exec {fd0}<&0
+exec {fd1}>&1
+
+exec {stdin}<&$fd0-
+exec {stdout}>&$fd1-
+}
+
+swizzle
+
+echo $stdin $stdout
+
+read line <&$stdin <<EOF
+a
+EOF
+
+echo $line
+echo $line >&$stdout
+
+type swizzle
+
+exit 0