aboutsummaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorcvpcs <root@cvpcs.org>2010-06-02 11:02:31 -0500
committercvpcs <root@cvpcs.org>2010-06-02 11:02:31 -0500
commit772f20abb0a3a0979c440114bf3a1cff5b3cef03 (patch)
tree3384b9291d73a12542c526a8557218c7435491b0 /tests
downloadexternal_bash-772f20abb0a3a0979c440114bf3a1cff5b3cef03.zip
external_bash-772f20abb0a3a0979c440114bf3a1cff5b3cef03.tar.gz
external_bash-772f20abb0a3a0979c440114bf3a1cff5b3cef03.tar.bz2
initial import of bash 4.1
Diffstat (limited to 'tests')
-rw-r--r--tests/COPYRIGHT6
-rw-r--r--tests/README3
-rw-r--r--tests/alias.right12
-rw-r--r--tests/alias.tests39
-rw-r--r--tests/alias1.sub20
-rw-r--r--tests/appendop.right18
-rw-r--r--tests/appendop.tests83
-rw-r--r--tests/arith-for.right74
-rw-r--r--tests/arith-for.tests94
-rw-r--r--tests/arith.right204
-rw-r--r--tests/arith.tests290
-rw-r--r--tests/arith1.sub38
-rw-r--r--tests/arith2.sub45
-rwxr-xr-xtests/array-at-star120
-rw-r--r--tests/array.right314
-rw-r--r--tests/array.tests388
-rw-r--r--tests/array1.sub1
-rw-r--r--tests/array2.right74
-rw-r--r--tests/array2.sub1
-rw-r--r--tests/array3.sub9
-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.right76
-rw-r--r--tests/braces.tests116
-rw-r--r--tests/builtins.right141
-rw-r--r--tests/builtins.tests253
-rw-r--r--tests/builtins1.sub14
-rw-r--r--tests/builtins2.sub10
-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.right61
-rwxr-xr-xtests/cond.tests183
-rw-r--r--tests/coproc.right13
-rw-r--r--tests/coproc.tests45
-rw-r--r--tests/cprint.right72
-rw-r--r--tests/cprint.tests67
-rw-r--r--tests/dbg-support.right371
-rw-r--r--tests/dbg-support.sub26
-rwxr-xr-xtests/dbg-support.tests142
-rw-r--r--tests/dbg-support2.right7
-rwxr-xr-xtests/dbg-support2.tests26
-rw-r--r--tests/dbg-support3.sub39
-rwxr-xr-xtests/dollar-at-star238
-rw-r--r--tests/dollar-at1.sub29
-rw-r--r--tests/dollar-at2.sub19
-rw-r--r--tests/dollar-at3.sub9
-rw-r--r--tests/dollar-star1.sub31
-rw-r--r--tests/dollar-star2.sub26
-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.right168
-rw-r--r--tests/dstack.right55
-rw-r--r--tests/dstack.tests87
-rw-r--r--tests/dstack2.right24
-rw-r--r--tests/dstack2.tests33
-rw-r--r--tests/errors.right101
-rw-r--r--tests/errors.tests265
-rw-r--r--tests/exec.right55
-rwxr-xr-xtests/exec1.sub1
-rw-r--r--tests/exec2.sub5
-rw-r--r--tests/exec3.sub6
-rw-r--r--tests/exec4.sub8
-rw-r--r--tests/exec5.sub9
-rw-r--r--tests/exec6.sub54
-rw-r--r--tests/exec7.sub20
-rw-r--r--tests/exec8.sub1
-rw-r--r--tests/execscript114
-rw-r--r--tests/exp.right168
-rw-r--r--tests/exp.tests386
-rw-r--r--tests/exp1.sub21
-rw-r--r--tests/exp2.sub12
-rw-r--r--tests/exp3.sub7
-rw-r--r--tests/extglob.right90
-rw-r--r--tests/extglob.tests371
-rw-r--r--tests/extglob1.sub37
-rw-r--r--tests/extglob2.right70
-rwxr-xr-xtests/extglob2.tests90
-rw-r--r--tests/extglob3.right27
-rw-r--r--tests/extglob3.tests56
-rw-r--r--tests/func.right156
-rw-r--r--tests/func.tests176
-rw-r--r--tests/func1.sub55
-rw-r--r--tests/func2.sub27
-rw-r--r--tests/func3.sub54
-rw-r--r--tests/getopts.right56
-rw-r--r--tests/getopts.tests38
-rw-r--r--tests/getopts1.sub26
-rw-r--r--tests/getopts2.sub26
-rw-r--r--tests/getopts3.sub27
-rw-r--r--tests/getopts4.sub30
-rw-r--r--tests/getopts5.sub50
-rw-r--r--tests/getopts6.sub27
-rw-r--r--tests/getopts7.sub30
-rw-r--r--tests/glob.right135
-rw-r--r--tests/glob.tests388
-rw-r--r--tests/glob1.sub14
-rw-r--r--tests/globstar.right155
-rw-r--r--tests/globstar.tests41
-rw-r--r--tests/globstar1.sub21
-rw-r--r--tests/heredoc.right64
-rw-r--r--tests/heredoc.tests100
-rw-r--r--tests/heredoc1.sub16
-rw-r--r--tests/herestr.right28
-rw-r--r--tests/herestr.tests39
-rw-r--r--tests/histexp.right129
-rw-r--r--tests/histexp.tests124
-rw-r--r--tests/history.list4
-rw-r--r--tests/history.right146
-rw-r--r--tests/history.tests113
-rw-r--r--tests/history1.sub13
-rw-r--r--tests/history2.sub10
-rw-r--r--tests/ifs-posix.right1
-rw-r--r--tests/ifs-posix.tests257
-rw-r--r--tests/ifs.right10
-rw-r--r--tests/ifs.tests61
-rw-r--r--tests/input-line.sh4
-rw-r--r--tests/input-line.sub2
-rw-r--r--tests/input.right3
-rw-r--r--tests/intl.right13
-rw-r--r--tests/intl.tests41
-rw-r--r--tests/intl1.sub11
-rw-r--r--tests/invert.right10
-rw-r--r--tests/invert.tests19
-rw-r--r--tests/iquote.right61
-rw-r--r--tests/iquote.tests143
-rw-r--r--tests/jobs.right105
-rw-r--r--tests/jobs.tests185
-rw-r--r--tests/jobs1.sub17
-rw-r--r--tests/jobs2.sub13
-rw-r--r--tests/jobs3.sub26
-rw-r--r--tests/jobs4.sub24
-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/misc/dev-tcp.tests16
-rw-r--r--tests/misc/perf-script81
-rw-r--r--tests/misc/perftest10
-rw-r--r--tests/misc/read-nchars.tests11
-rw-r--r--tests/misc/redir-t2.sh17
-rwxr-xr-xtests/misc/run-r2.sh1
-rwxr-xr-xtests/misc/sigint-1.sh9
-rwxr-xr-xtests/misc/sigint-2.sh7
-rwxr-xr-xtests/misc/sigint-3.sh11
-rwxr-xr-xtests/misc/sigint-4.sh13
-rw-r--r--tests/misc/test-minus-e.19
-rw-r--r--tests/misc/test-minus-e.211
-rw-r--r--tests/misc/wait-bg.tests25
-rw-r--r--tests/more-exp.right214
-rw-r--r--tests/more-exp.tests504
-rw-r--r--tests/new-exp.right542
-rw-r--r--tests/new-exp.tests576
-rw-r--r--tests/new-exp1.sub11
-rw-r--r--tests/new-exp2.sub36
-rw-r--r--tests/new-exp3.sub26
-rw-r--r--tests/new-exp4.sub31
-rw-r--r--tests/new-exp5.sub40
-rw-r--r--tests/new-exp6.sub29
-rw-r--r--tests/new-exp7.sub13
-rw-r--r--tests/nquote.right40
-rw-r--r--tests/nquote.tests118
-rw-r--r--tests/nquote1.right121
-rw-r--r--tests/nquote1.sub6
-rw-r--r--tests/nquote1.tests97
-rw-r--r--tests/nquote2.right76
-rw-r--r--tests/nquote2.tests82
-rw-r--r--tests/nquote3.right60
-rw-r--r--tests/nquote3.tests85
-rw-r--r--tests/nquote4.right18
-rw-r--r--tests/nquote4.tests24
-rw-r--r--tests/nquote5.right86
-rw-r--r--tests/nquote5.tests63
-rw-r--r--tests/posix2.right2
-rw-r--r--tests/posix2.tests179
-rw-r--r--tests/posixpat.right42
-rw-r--r--tests/posixpat.tests233
-rw-r--r--tests/prec.right28
-rwxr-xr-xtests/precedence75
-rw-r--r--tests/printf.rightbin0 -> 1510 bytes
-rw-r--r--tests/printf.tests311
-rw-r--r--tests/printf2.sub6
-rw-r--r--tests/quote.right68
-rw-r--r--tests/quote.tests111
-rw-r--r--tests/read.right65
-rw-r--r--tests/read.tests98
-rw-r--r--tests/read1.sub23
-rw-r--r--tests/read2.sub32
-rw-r--r--tests/read3.sub19
-rw-r--r--tests/read4.sub4
-rw-r--r--tests/read5.sub36
-rw-r--r--tests/read6.sub10
-rw-r--r--tests/redir.right141
-rw-r--r--tests/redir.tests189
-rw-r--r--tests/redir1.sub8
-rw-r--r--tests/redir2.sub1
-rw-r--r--tests/redir3.in12
-rw-r--r--tests/redir3.in22
-rw-r--r--tests/redir3.sub26
-rw-r--r--tests/redir4.in11
-rw-r--r--tests/redir4.sub56
-rw-r--r--tests/redir5.sub31
-rw-r--r--tests/redir6.sub8
-rw-r--r--tests/redir7.sub69
-rw-r--r--tests/redir8.sub59
-rw-r--r--tests/redir9.sub50
-rw-r--r--tests/rhs-exp.right74
-rw-r--r--tests/rhs-exp.tests49
-rw-r--r--tests/rsh.right13
-rw-r--r--tests/rsh.tests33
-rw-r--r--tests/run-alias2
-rw-r--r--tests/run-all29
-rw-r--r--tests/run-appendop2
-rw-r--r--tests/run-arith2
-rw-r--r--tests/run-arith-for2
-rw-r--r--tests/run-array6
-rw-r--r--tests/run-array24
-rw-r--r--tests/run-assoc4
-rw-r--r--tests/run-braces2
-rw-r--r--tests/run-builtins6
-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-cond7
-rw-r--r--tests/run-coproc4
-rw-r--r--tests/run-cprint2
-rwxr-xr-xtests/run-dbg-support11
-rwxr-xr-xtests/run-dbg-support216
-rw-r--r--tests/run-dirstack5
-rw-r--r--tests/run-dollars2
-rw-r--r--tests/run-errors2
-rw-r--r--tests/run-execscript9
-rw-r--r--tests/run-exp-tests2
-rw-r--r--tests/run-extglob4
-rw-r--r--tests/run-extglob24
-rw-r--r--tests/run-extglob34
-rw-r--r--tests/run-func5
-rw-r--r--tests/run-getopts2
-rw-r--r--tests/run-glob-test4
-rw-r--r--tests/run-globstar4
-rw-r--r--tests/run-heredoc2
-rw-r--r--tests/run-herestr2
-rw-r--r--tests/run-histexpand4
-rw-r--r--tests/run-history4
-rw-r--r--tests/run-ifs2
-rw-r--r--tests/run-ifs-posix2
-rw-r--r--tests/run-input-test2
-rw-r--r--tests/run-intl8
-rw-r--r--tests/run-invert2
-rw-r--r--tests/run-iquote2
-rw-r--r--tests/run-jobs7
-rw-r--r--tests/run-mapfile2
-rw-r--r--tests/run-minimal36
-rw-r--r--tests/run-more-exp2
-rw-r--r--tests/run-new-exp10
-rw-r--r--tests/run-nquote2
-rw-r--r--tests/run-nquote14
-rw-r--r--tests/run-nquote24
-rw-r--r--tests/run-nquote34
-rw-r--r--tests/run-nquote44
-rw-r--r--tests/run-nquote52
-rw-r--r--tests/run-posix22
-rw-r--r--tests/run-posixpat2
-rw-r--r--tests/run-precedence2
-rw-r--r--tests/run-printf5
-rw-r--r--tests/run-quote2
-rw-r--r--tests/run-read4
-rw-r--r--tests/run-redir7
-rw-r--r--tests/run-rhs-exp2
-rw-r--r--tests/run-rsh2
-rw-r--r--tests/run-set-e2
-rwxr-xr-xtests/run-set-x11
-rw-r--r--tests/run-shopt2
-rw-r--r--tests/run-strip2
-rw-r--r--tests/run-test4
-rw-r--r--tests/run-tilde2
-rw-r--r--tests/run-tilde22
-rw-r--r--tests/run-trap6
-rw-r--r--tests/run-type2
-rw-r--r--tests/run-varenv2
-rw-r--r--tests/run-vredir2
-rw-r--r--tests/set-e.right67
-rw-r--r--tests/set-e.tests110
-rw-r--r--tests/set-e1.sub59
-rw-r--r--tests/set-e2.sub10
-rw-r--r--tests/set-x.right56
-rwxr-xr-xtests/set-x.tests20
-rw-r--r--tests/set-x1.sub25
-rw-r--r--tests/shopt.right259
-rw-r--r--tests/shopt.tests94
-rw-r--r--tests/source1.sub1
-rw-r--r--tests/source2.sub5
-rw-r--r--tests/source3.sub1
-rw-r--r--tests/source4.sub1
-rw-r--r--tests/source5.sub19
-rw-r--r--tests/source6.sub31
-rw-r--r--tests/strip.right12
-rw-r--r--tests/strip.tests22
-rw-r--r--tests/test.right285
-rw-r--r--tests/test.tests426
-rw-r--r--tests/tilde.right25
-rw-r--r--tests/tilde.tests69
-rw-r--r--tests/tilde2.right24
-rw-r--r--tests/tilde2.tests70
-rw-r--r--tests/trap.right85
-rw-r--r--tests/trap.tests93
-rwxr-xr-xtests/trap1.sub4
-rwxr-xr-xtests/trap2.sub25
-rwxr-xr-xtests/trap2a.sub3
-rw-r--r--tests/trap3.sub9
-rw-r--r--tests/type.right82
-rw-r--r--tests/type.tests93
-rw-r--r--tests/type1.sub10
-rw-r--r--tests/type2.sub16
-rw-r--r--tests/varenv.right56
-rw-r--r--tests/varenv.sh206
-rw-r--r--tests/varenv1.sub28
-rw-r--r--tests/varenv2.sub44
-rw-r--r--tests/version8
-rw-r--r--tests/version.mini8
-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
358 files changed, 19583 insertions, 0 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/README b/tests/README
new file mode 100644
index 0000000..b023ef6
--- /dev/null
+++ b/tests/README
@@ -0,0 +1,3 @@
+Type `sh run-all'.
+
+Read COPYRIGHT for copyright information.
diff --git a/tests/alias.right b/tests/alias.right
new file mode 100644
index 0000000..a37080c
--- /dev/null
+++ b/tests/alias.right
@@ -0,0 +1,12 @@
+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
new file mode 100644
index 0000000..a97d5ff
--- /dev/null
+++ b/tests/alias.tests
@@ -0,0 +1,39 @@
+# place holder for future alias testing
+shopt -s expand_aliases
+
+# alias/unalias tests originally in builtins.tests
+
+unalias -a
+# this should return success, according to POSIX.2
+alias
+echo alias: $?
+alias foo=bar
+unalias foo
+# this had better return success, according to POSIX.2
+alias
+echo alias: $?
+
+# bug in all versions through bash-2.05b
+
+unalias qfoo qbar qbaz quux 2>/dev/null
+
+alias qfoo=qbar
+alias qbar=qbaz
+alias qbaz=quux
+alias quux=qfoo
+
+qfoo
+
+unalias qfoo qbar qbaz quux
+
+unalias -a
+
+alias foo='echo '
+alias bar=baz
+alias baz=quux
+
+foo bar
+
+unalias foo bar baz
+
+${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/appendop.right b/tests/appendop.right
new file mode 100644
index 0000000..1e24333
--- /dev/null
+++ b/tests/appendop.right
@@ -0,0 +1,18 @@
+14
+1 2 3 4 5 6
+1 2 3 4 51 6
+5
+14
+7
+42
+1 2 3 4 12
+18
+1 2 3 4 18
+1 2 7 4 5
+1 2 7 13 5 9
+14
+9
+4
+9
+16
+./appendop.tests: line 83: x: readonly variable
diff --git a/tests/appendop.tests b/tests/appendop.tests
new file mode 100644
index 0000000..7b61f3f
--- /dev/null
+++ b/tests/appendop.tests
@@ -0,0 +1,83 @@
+# basic cases
+a=1
+a+=4
+echo $a
+
+x=(1 2 3)
+x+=(4 5 6)
+
+echo ${x[@]}
+
+x[4]+=1
+echo ${x[@]}
+
+# trickier cases
+
+a+=5 printenv a
+echo $a
+
+# if the integer flag is set, ksh93 appears to do arithmetic += and evaluate
+# old value as an arithmetic expression
+a=
+typeset -i a
+a+=7
+echo $a
+
+b=4+1
+typeset -i b
+b+=37
+
+echo $b
+
+unset x
+x=(1 2 3 4 5)
+
+typeset -i x
+
+x[4]+=7
+
+echo ${x[@]}
+
+unset x
+typeset -i x
+
+x=([0]=7+11)
+echo ${x[@]}
+
+unset x
+x=(1 2 3 4 5)
+
+typeset -i x
+
+#x[4]=7+11
+
+x=(1 2 3 4 [4]=7+11 )
+echo ${x[@]}
+
+x=( 1 2 [2]+=7 4 5 )
+echo ${x[@]}
+
+x+=( [3]+=9 [5]=9 )
+echo ${x[@]}
+
+unset a
+a=1
+export a+=4
+printenv a
+printenv a+
+
+unset x
+typeset -i x=4+5
+echo $x
+
+unset x
+typeset x+=4
+echo $x
+
+typeset -i x+=5
+echo $x
+
+readonly x+=7
+echo $x
+
+x+=5
diff --git a/tests/arith-for.right b/tests/arith-for.right
new file mode 100644
index 0000000..4494110
--- /dev/null
+++ b/tests/arith-for.right
@@ -0,0 +1,74 @@
+0
+1
+2
+0
+1
+2
+0
+1
+2
+0
+2
+4
+fx is a function
+fx ()
+{
+ i=0;
+ for ((1; i < 3; i++ ))
+ do
+ echo $i;
+ done;
+ for ((i=0; 1; i++ ))
+ do
+ if (( i >= 3 )); then
+ break;
+ fi;
+ echo $i;
+ done;
+ for ((i=0; i<3; 1))
+ do
+ echo $i;
+ (( i++ ));
+ done;
+ i=0;
+ for ((1; 1; 1))
+ do
+ if (( i > 2 )); then
+ break;
+ fi;
+ echo $i;
+ (( i++ ));
+ done;
+ i=0;
+ for ((1; 1; 1))
+ do
+ if (( i > 2 )); then
+ break;
+ fi;
+ echo $i;
+ (( i++ ));
+ done
+}
+0
+1
+2
+0
+1
+2
+0
+1
+2
+0
+1
+2
+0
+1
+2
+./arith-for.tests: line 77: syntax error: arithmetic expression required
+./arith-for.tests: line 77: syntax error: `(( i=0; "i < 3" ))'
+2
+./arith-for.tests: line 83: syntax error: `;' unexpected
+./arith-for.tests: line 83: syntax error: `(( i=0; i < 3; i++; 7 ))'
+2
+20
+20
diff --git a/tests/arith-for.tests b/tests/arith-for.tests
new file mode 100644
index 0000000..585aa51
--- /dev/null
+++ b/tests/arith-for.tests
@@ -0,0 +1,94 @@
+fx()
+{
+i=0
+for (( ; i < 3; i++ ))
+do
+ echo $i
+done
+
+for (( i=0; ; i++ ))
+do
+ if (( i >= 3 )); then
+ break;
+ fi
+ echo $i
+done
+
+for (( i=0; i<3; ))
+do
+ echo $i
+ (( i++ ))
+done
+
+i=0
+for (( ; ; ))
+do
+ if (( i > 2 )); then
+ break;
+ fi
+ echo $i;
+ (( i++ ))
+done
+
+i=0
+for ((;;))
+do
+ if (( i > 2 )); then
+ break;
+ fi
+ echo $i;
+ (( i++ ))
+done
+}
+
+for (( i=0; "i < 3" ; i++ ))
+do
+ echo $i
+done
+
+i=0
+for (( ; "i < 3"; i++ ))
+do
+ echo $i
+done
+
+for (( i=0; ; i++ ))
+do
+ if (( i >= 3 )); then
+ break;
+ fi
+ echo $i
+done
+
+for ((i = 0; ;i++ ))
+do
+ echo $i
+ if (( i < 3 )); then
+ (( i++ ))
+ continue;
+ fi
+ break
+done
+
+type fx
+fx
+
+# errors
+for (( i=0; "i < 3" ))
+do
+ echo $i
+done
+echo $?
+
+for (( i=0; i < 3; i++; 7 ))
+do
+ echo $i
+done
+echo $?
+
+# one-liners added in post-bash-2.04
+for ((i=0; i < 20; i++)) do : ; done
+echo $i
+
+for ((i=0; i < 20; i++)) { : ; }
+echo $i
diff --git a/tests/arith.right b/tests/arith.right
new file mode 100644
index 0000000..51d740e
--- /dev/null
+++ b/tests/arith.right
@@ -0,0 +1,204 @@
+163
+166
+4
+16
+8
+2
+4
+2
+2
+1
+0
+0
+0
+1
+1
+2
+-3
+-2
+1
+0
+2
+131072
+29
+33
+49
+1
+1
+0
+0
+1
+1
+1
+2
+3
+1
+58
+2
+60
+1
+256
+16
+62
+4
+29
+5
+-4
+4
+1
+32
+32
+1
+1
+32
+4
+20
+1,i+=2
+30
+1,j+=2
+20
+1,i+=2
+30
+1,j+=2
+./arith.tests: line 114: 1 ? 20 : x+=2: attempted assignment to non-variable (error token is "+=2")
+20
+6
+6,5,3
+263
+255
+255
+127
+36
+40
+10
+10
+10
+10
+10
+10
+36
+36
+62
+63
+./arith.tests: line 149: 3425#56: invalid arithmetic base (error token is "3425#56")
+0
+./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
+ok
+6
+1
+0
+./arith.tests: line 183: 4 + : syntax error: operand expected (error token is "+ ")
+16
+./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 196: 0 && B=42 : attempted assignment to non-variable (error token is "=42 ")
+9
+./arith.tests: line 199: 1 || B=88 : attempted assignment to non-variable (error token is "=88 ")
+9
+0
+9
+0
+9
+1
+9
+7
+7
+4
+32767
+32768
+131072
+2147483647
+1
+4
+4
+5
+5
+4
+3
+3
+4
+4
+7
+./arith.tests: line 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 "+ ")
+1
+2
+1
+2
+6
+3
+7
+4
+0
+3
+7
+2
+-2
+1
+./arith1.sub: line 35: ((: ++ : syntax error: operand expected (error token is "+ ")
+7
+7
+./arith1.sub: line 38: ((: -- : syntax error: operand expected (error token is "- ")
+7
+7
+7
+7
+1
+2
+1
+2
+1
+0
+5
+1
+6
+2
+3
+1
+4
+0
+./arith2.sub: line 33: ((: -- : syntax error: operand expected (error token is "- ")
+-7
+-7
+./arith2.sub: line 37: ((: ++ : syntax error: operand expected (error token is "+ ")
+7
+7
+-7
+-7
+7
+7
+8 12
+./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 290: b[c]d: syntax error in expression (error token is "d")
diff --git a/tests/arith.tests b/tests/arith.tests
new file mode 100644
index 0000000..9e82bb1
--- /dev/null
+++ b/tests/arith.tests
@@ -0,0 +1,290 @@
+set +o posix
+declare -i iv jv
+
+iv=$(( 3 + 5 * 32 ))
+echo $iv
+iv=iv+3
+echo $iv
+iv=2
+jv=iv
+
+let "jv *= 2"
+echo $jv
+jv=$(( $jv << 2 ))
+echo $jv
+
+let jv="$jv / 2"
+echo $jv
+jv="jv >> 2"
+echo $jv
+
+iv=$((iv+ $jv))
+echo $iv
+echo $((iv -= jv))
+echo $iv
+echo $(( iv == jv ))
+echo $(( iv != $jv ))
+echo $(( iv < jv ))
+echo $(( $iv > $jv ))
+echo $(( iv <= $jv ))
+echo $(( $iv >= jv ))
+
+echo $jv
+echo $(( ~$jv ))
+echo $(( ~1 ))
+echo $(( ! 0 ))
+
+echo $(( jv % 2 ))
+echo $(( $iv % 4 ))
+
+echo $(( iv <<= 16 ))
+echo $(( iv %= 33 ))
+
+echo $(( 33 & 55 ))
+echo $(( 33 | 17 ))
+
+echo $(( iv && $jv ))
+echo $(( $iv || jv ))
+
+echo $(( iv && 0 ))
+echo $(( iv & 0 ))
+echo $(( iv && 1 ))
+echo $(( iv & 1 ))
+
+echo $(( $jv || 0 ))
+echo $(( jv | 0 ))
+echo $(( jv | 1 ))
+echo $(( $jv || 1 ))
+
+let 'iv *= jv'
+echo $iv
+echo $jv
+let "jv += $iv"
+echo $jv
+
+echo $(( jv /= iv ))
+echo $(( jv <<= 8 ))
+echo $(( jv >>= 4 ))
+
+echo $(( iv |= 4 ))
+echo $(( iv &= 4 ))
+
+echo $(( iv += (jv + 9)))
+echo $(( (iv + 4) % 7 ))
+
+# unary plus, minus
+echo $(( +4 - 8 ))
+echo $(( -4 + 8 ))
+
+# conditional expressions
+echo $(( 4<5 ? 1 : 32))
+echo $(( 4>5 ? 1 : 32))
+echo $(( 4>(2+3) ? 1 : 32))
+echo $(( 4<(2+3) ? 1 : 32))
+echo $(( (2+2)<(2+3) ? 1 : 32))
+echo $(( (2+2)>(2+3) ? 1 : 32))
+
+# bug in bash versions through bash-3.2
+S=105
+W=$((S>99?4:S>9?3:S>0?2:0))
+echo $W
+unset W S
+
+# check that the unevaluated part of the ternary operator does not do
+# evaluation or assignment
+x=i+=2
+y=j+=2
+declare -i i=1 j=1
+echo $((1 ? 20 : (x+=2)))
+echo $i,$x
+echo $((0 ? (y+=2) : 30))
+echo $j,$y
+
+x=i+=2
+y=j+=2
+declare -i i=1 j=1
+echo $((1 ? 20 : (x+=2)))
+echo $i,$x
+echo $((0 ? (y+=2) : 30))
+echo $i,$y
+
+# check precedence of assignment vs. conditional operator
+# should be an error
+declare -i x=2
+y=$((1 ? 20 : x+=2))
+
+# check precedence of assignment vs. conditional operator
+declare -i x=2
+echo $((0 ? x+=2 : 20))
+
+# associativity of assignment-operator operator
+declare -i i=1 j=2 k=3
+echo $((i += j += k))
+echo $i,$j,$k
+
+# octal, hex
+echo $(( 0x100 | 007 ))
+echo $(( 0xff ))
+echo $(( 16#ff ))
+echo $(( 16#FF/2 ))
+echo $(( 8#44 ))
+
+echo $(( 8 ^ 32 ))
+
+# other bases
+echo $(( 16#a ))
+echo $(( 32#a ))
+echo $(( 56#a ))
+echo $(( 64#a ))
+
+echo $(( 16#A ))
+echo $(( 32#A ))
+echo $(( 56#A ))
+echo $(( 64#A ))
+
+echo $(( 64#@ ))
+echo $(( 64#_ ))
+
+# weird bases
+echo $(( 3425#56 ))
+
+# missing number after base
+echo $(( 2# ))
+
+# these should generate errors
+echo $(( 7 = 43 ))
+echo $(( 2#44 ))
+echo $(( 44 / 0 ))
+let 'jv += $iv'
+echo $(( jv += \$iv ))
+let 'rv = 7 + (43 * 6'
+
+# more errors
+declare -i i
+i=0#4
+i=2#110#11
+
+((echo abc; echo def;); echo ghi)
+
+if (((4+4) + (4 + 7))); then
+ echo ok
+fi
+
+(()) # make sure the null expression works OK
+
+a=(0 2 4 6)
+echo $(( a[1] + a[2] ))
+echo $(( (a[1] + a[2]) == a[3] ))
+(( (a[1] + a[2]) == a[3] )) ; echo $?
+
+# test pushing and popping the expression stack
+unset A
+A="4 + "
+echo $(( ( 4 + A ) + 4 ))
+A="3 + 5"
+echo $(( ( 4 + A ) + 4 ))
+
+# badly-formed conditional expressions
+echo $(( 4 ? : $A ))
+echo $(( 1 ? 20 ))
+echo $(( 4 ? 20 : ))
+
+# precedence and short-circuit evaluation
+B=9
+echo $B
+
+echo $(( 0 && B=42 ))
+echo $B
+
+echo $(( 1 || B=88 ))
+echo $B
+
+echo $(( 0 && (B=42) ))
+echo $B
+
+echo $(( (${$} - $$) && (B=42) ))
+echo $B
+
+echo $(( 1 || (B=88) ))
+echo $B
+
+# until command with (( )) command
+x=7
+
+echo $x
+until (( x == 4 ))
+do
+ echo $x
+ x=4
+done
+
+echo $x
+
+# exponentiation
+echo $(( 2**15 - 1))
+echo $(( 2**(16-1)))
+echo $(( 2**16*2 ))
+echo $(( 2**31-1))
+echo $(( 2**0 ))
+
+# {pre,post}-{inc,dec}rement and associated errors
+
+x=4
+
+echo $x
+echo $(( x++ ))
+echo $x
+echo $(( x-- ))
+echo $x
+
+echo $(( --x ))
+echo $x
+
+echo $(( ++x ))
+echo $x
+
+echo $(( ++7 ))
+echo $(( 7-- ))
+
+echo $(( --x=7 ))
+echo $(( ++x=7 ))
+
+echo $(( x++=7 ))
+echo $(( x--=7 ))
+
+echo $x
+
+echo $(( +7 ))
+echo $(( -7 ))
+
+echo $(( ++7 ))
+echo $(( --7 ))
+
+${THIS_SH} ./arith1.sub
+${THIS_SH} ./arith2.sub
+
+x=4
+y=7
+
+(( x=8 , y=12 ))
+
+echo $x $y
+
+# should be an error
+(( x=9 y=41 ))
+
+# These are errors
+unset b
+echo $((a b))
+((a b))
+
+n=42
+printf "%d\n" $n
+printf "%i\n" $n
+echo $(( 8#$(printf "%o\n" $n) ))
+printf "%u\n" $n
+echo $(( 16#$(printf "%x\n" $n) ))
+echo $(( 16#$(printf "%X\n" $n) ))
+
+# causes longjmp botches through bash-2.05b
+a[b[c]d]=e
diff --git a/tests/arith1.sub b/tests/arith1.sub
new file mode 100644
index 0000000..43cae80
--- /dev/null
+++ b/tests/arith1.sub
@@ -0,0 +1,38 @@
+# test of redone post-increment and post-decrement code
+echo $(( 4-- ))
+echo $(( 4++ ))
+echo $(( 4 -- ))
+echo $(( 4 ++ ))
+
+(( array[0]++ ))
+echo ${array}
+
+(( array[0] ++ ))
+echo ${array}
+
+(( a++ ))
+echo $a
+(( a ++ ))
+echo $a
+
+echo $(( a ++ + 4 ))
+echo $a
+
+echo $(( a+++4 ))
+echo $a
+
+echo $(( a---4 ))
+echo $a
+
+echo $(( a -- + 4 ))
+echo $a
+
+echo $(( a -- - 4 ))
+echo $a
+
+(( ++ + 7 ))
+
+(( ++ ))
+echo $(( +++7 ))
+echo $(( ++ + 7 ))
+(( -- ))
diff --git a/tests/arith2.sub b/tests/arith2.sub
new file mode 100644
index 0000000..7eac952
--- /dev/null
+++ b/tests/arith2.sub
@@ -0,0 +1,45 @@
+echo $(( --7 ))
+echo $(( ++7 ))
+echo $(( -- 7 ))
+echo $(( ++ 7 ))
+
+((++array[0] ))
+echo $array
+(( ++ array[0] ))
+echo $array
+
+(( ++a ))
+echo $a
+(( ++ a ))
+echo $a
+
+(( --a ))
+echo $a
+(( -- a ))
+echo $a
+
+echo $(( 4 + ++a ))
+echo $a
+
+echo $(( 4+++a ))
+echo $a
+
+echo $(( 4---a ))
+echo $a
+
+echo $(( 4 - -- a ))
+echo $a
+
+(( -- ))
+echo $(( ---7 ))
+echo $(( -- - 7 ))
+
+(( ++ ))
+echo $(( ++7 ))
+echo $(( ++ + 7 ))
+
+echo $(( ++-7 ))
+echo $(( ++ - 7 ))
+
+echo $(( +--7 ))
+echo $(( -- + 7 ))
diff --git a/tests/array-at-star b/tests/array-at-star
new file mode 100755
index 0000000..80f039d
--- /dev/null
+++ b/tests/array-at-star
@@ -0,0 +1,120 @@
+# test the expansion of ${array[@]} and ${array[*]}, both quoted and
+# unquoted. the expansions should be exactly analogous to the
+# expansions of $@ and $* quoted and unquoted
+A=(a b)
+
+recho "${A[*]}"
+
+# If IFS is null, the parameters are joined without separators
+IFS=''
+recho "${A[*]}"
+
+# If IFS is unset, the parameters are separated by spaces
+unset IFS
+recho "${A[*]}"
+
+recho "${A[@]}"
+recho ${A[@]}
+
+IFS='/'
+A=(bob 'tom dick harry' joe)
+set ${A[*]}
+recho $#
+recho $1
+recho $2
+recho $3
+
+A=(bob 'tom dick harry' joe)
+set ${A[*]}
+recho $#
+recho $1
+recho $2
+recho $3
+
+A=(bob 'tom dick harry' joe)
+set ${A[@]}
+recho $#
+recho $1
+recho $2
+recho $3
+
+A=(bob 'tom dick harry' joe)
+set ${A[@]}
+recho $#
+recho $1
+recho $2
+recho $3
+
+# according to POSIX.2, unquoted $* should expand to multiple words if
+# $IFS is null, just like unquoted $@
+IFS=''
+A=(bob 'tom dick harry' joe)
+set "${A[*]}"
+recho $#
+recho $1
+recho $2
+recho $3
+
+A=(bob 'tom dick harry' joe)
+set ${A[*]}
+recho $#
+recho $1
+recho $2
+recho $3
+
+A=(bob 'tom dick harry' joe)
+set ${A[@]}
+recho $#
+recho $1
+recho $2
+recho $3
+
+# if IFS is unset, the individual positional parameters are split on
+# " \t\n" if $* or $@ are unquoted
+unset IFS
+A=(bob 'tom dick harry' joe)
+set ${A[*]}
+recho $#
+recho $1
+recho $2
+recho $3
+
+A=(bob 'tom dick harry' joe)
+set ${A[@]}
+recho $#
+recho $1
+recho $2
+recho $3
+
+# but not for "$@" or "$*"
+A=(bob 'tom dick harry' joe)
+set "${A[*]}"
+recho $#
+recho $1
+recho $2
+recho $3
+
+A=(bob 'tom dick harry' joe)
+set "${A[@]}"
+recho $#
+recho $1
+recho $2
+recho $3
+
+# these should both expand the value of A to multiple words
+A=(a b c d e)
+IFS=""
+recho ${A[@]}
+recho "${A[@]}"
+
+# this example is straight from the POSIX.2 rationale and adapted to arrays
+A=(foo bar bam)
+
+recho "${A[@]}"
+recho "${A[*]}"
+
+unset IFS
+
+recho "${A[@]}"
+recho ${A[@]}
+recho "${A[*]}"
diff --git a/tests/array.right b/tests/array.right
new file mode 100644
index 0000000..fdc0793
--- /dev/null
+++ b/tests/array.right
@@ -0,0 +1,314 @@
+
+./array.tests: line 15: syntax error near unexpected token `&'
+./array.tests: line 15: `test=(first & second)'
+1
+abcde
+abcde
+abcde bdef
+abcde bdef
+declare -a BASH_ARGC='()'
+declare -a BASH_ARGV='()'
+declare -a BASH_LINENO='([0]="0")'
+declare -a BASH_SOURCE='([0]="./array.tests")'
+declare -a DIRSTACK='()'
+declare -a FUNCNAME='([0]="main")'
+declare -a a='([0]="abcde" [1]="" [2]="bdef")'
+declare -a b='()'
+declare -ar c='()'
+abcde bdef
+abcde bdef
+abcde
+abcde
+abcde
+
+bdef
+hello world
+11
+3
+bdef hello world test expression test 2
+./array.tests: line 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" [15]="test 2")'
+declare -ar c='()'
+readonly -a a='([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="test 2")'
+readonly -a c='()'
+a test
+declare -a BASH_ARGC='()'
+declare -a BASH_ARGV='()'
+declare -a BASH_LINENO='([0]="0")'
+declare -a BASH_SOURCE='([0]="./array.tests")'
+declare -a DIRSTACK='()'
+declare -a FUNCNAME='([0]="main")'
+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 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 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" [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 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
+this is a test of arrays
+declare -a BASH_ARGC='()'
+declare -a BASH_ARGV='()'
+declare -a BASH_LINENO='([0]="0")'
+declare -a BASH_SOURCE='([0]="./array.tests")'
+declare -a DIRSTACK='()'
+declare -a FUNCNAME='([0]="main")'
+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")'
+declare -a rv='([0]="this" [1]="is" [2]="a" [3]="test" [4]="of" [5]="read" [6]="using" [7]="arrays")'
+abde
+abde
+bbb
+efgh
+wxyz
+wxyz
+./array.tests
+a
+b c
+d
+e f g
+h
+./array.tests
+a
+b c
+d
+e f g
+h
+/bin /usr/bin /usr/ucb /usr/local/bin . /sbin /usr/sbin
+bin bin ucb bin . sbin sbin
+bin
+/ / / / / /
+/
+argv[1] = <bin>
+argv[1] = </>
+argv[1] = <sbin>
+argv[1] = </>
+\bin \usr/bin \usr/ucb \usr/local/bin . \sbin \usr/sbin
+\bin \usr\bin \usr\ucb \usr\local\bin . \sbin \usr\sbin
+\bin \usr\bin \usr\ucb \usr\local\bin . \sbin \usr\sbin
+4 -- 4
+7 -- 7
+55
+49
+6 -- 6
+42 14 44
+grep [ 123 ] *
+6 7 9
+6 7 9 5
+length = 3
+value = new1 new2 new3
+./array.tests: line 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 `('
+./array2.sub: line 1: `declare -a ''=(a 'b c')'
+9
+9
+
+
+7 8 9
+8 11
+8 11
+6
+6
+nordholz
+8
+8
+8
+
+a b c d e f g
+for case if then else
+<> < > !
+12 14 16 18 20
+4414758999202
+aaa bbb
+./array.tests: line 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
+abc case if then else 5
+0
+case 4
+case if then else 5
+case if then else 5
+argv[1] = <0>
+argv[2] = <1>
+argv[3] = <4>
+argv[4] = <10>
+argv[1] = <0>
+argv[2] = <1>
+argv[3] = <4>
+argv[4] = <10>
+argv[1] = <0>
+argv[2] = <1>
+argv[3] = <4>
+argv[4] = <10>
+argv[1] = <0 1 4 10>
+include null element -- expect one
+one
+include unset element -- expect three five
+three five
+start at unset element -- expect five seven
+five seven
+too many elements -- expect three five seven
+three five seven
+positive offset - expect five seven
+five seven
+negative offset to unset element - expect seven
+seven
+positive offset 2 - expect seven
+seven
+negative offset 2 - expect seven
+seven
+out-of-range offset
+
+e
+4
+1 4 7 10
+'b
+b c
+$0
+t
+[3]=abcde r s t u v
+e
+9
+2
+a b c
+argv[1] = <"-iname '"a>
+argv[2] = <"-iname '"b>
+argv[3] = <"-iname '"c>
+'hey'
+hey
+''hey
+'hey'
+argv[1] = <c>
+argv[2] = <d>
+argv[3] = <e>
+argv[4] = <f>
+argv[1] = <c d>
+argv[2] = <e f>
+argv[1] = <c d>
+argv[2] = <e f>
+argv[1] = <c d>
+argv[2] = <e f>
+argv[1] = <"-iname '"abc>
+argv[2] = <"-iname '"def>
+argv[1] = <-iname 'abc>
+argv[2] = <-iname 'def>
+argv[1] = <-iname \'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
new file mode 100644
index 0000000..435ac15
--- /dev/null
+++ b/tests/array.tests
@@ -0,0 +1,388 @@
+# this is needed so that the bad assignments (b[]=bcde, for example) do not
+# cause fatal shell errors when in posix mode
+set +o posix
+
+set +a
+# The calls to egrep -v are to filter out builtin array variables that are
+# automatically set and possibly contain values that vary.
+
+# first make sure we handle the basics
+x=()
+echo ${x[@]}
+unset x
+
+# this should be an error
+test=(first & second)
+echo $?
+unset test
+
+# make sure declare -a converts an existing variable to an array
+unset a
+a=abcde
+declare -a a
+echo ${a[0]}
+
+unset a
+a=abcde
+a[2]=bdef
+
+unset b
+declare -a b[256]
+
+unset c[2]
+unset c[*]
+
+a[1]=
+
+_ENV=/bin/true
+x=${_ENV[(_$-=0)+(_=1)-_${-%%*i*}]}
+
+declare -r c[100]
+
+echo ${a[0]} ${a[4]}
+echo ${a[@]}
+
+echo ${a[*]}
+
+# this should print out values, too
+declare -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
+
+unset a[7]
+echo ${a[*]}
+
+unset a[4]
+echo ${a[*]}
+
+echo ${a}
+echo "${a}"
+echo $a
+
+unset a[0]
+echo ${a}
+
+echo ${a[@]}
+
+a[5]="hello world"
+echo ${a[5]}
+echo ${#a[5]}
+
+echo ${#a[@]}
+
+a[4+5/2]="test expression"
+declare a["7 + 8"]="test 2"
+a[7 + 8]="test 2"
+echo ${a[@]}
+
+readonly a[5]
+readonly a
+# these two lines should output `declare' commands
+readonly -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
+declare -ar | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
+# this line should output `readonly' commands, even for arrays
+set -o posix
+readonly -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
+set +o posix
+
+declare -a d='([1]="" [2]="bdef" [5]="hello world" "test")'
+d[9]="ninth element"
+
+declare -a e[10]=test # this works in post-bash-2.05 versions
+declare -a e[10]='(test)'
+
+pass=/etc/passwd
+declare -a f='("${d[@]}")'
+b=([0]=this [1]=is [2]=a [3]=test [4]="$PS1" [5]=$pass)
+
+echo ${b[@]:2:3}
+
+declare -pa | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
+
+a[3]="this is a test"
+
+b[]=bcde
+b[*]=aaa
+echo ${b[ ]}
+
+c[-2]=4
+echo ${c[-4]}
+
+d[7]=(abdedfegeee)
+
+d=([]=abcde [1]="test test" [*]=last [-65]=negative )
+
+unset d[12]
+unset e[*]
+
+declare -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
+
+ps1='hello'
+unset ps1[2]
+unset ${ps1[2]}
+
+declare +a ps1
+declare +a c
+
+# the prompt should not print when using a here doc
+read -p "array test: " -a rv <<!
+this is a test of read using arrays
+!
+
+echo ${rv[0]} ${rv[4]}
+echo ${rv[@]}
+
+# the variable should be converted to an array when `read -a' is done
+vv=1
+read -a vv <<!
+this is a test of arrays
+!
+echo ${vv[0]} ${vv[3]}
+echo ${vv[@]}
+unset vv
+
+declare -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
+
+export rv
+#set
+
+x[4]=bbb
+x=abde
+echo $x
+echo ${x[0]}
+echo ${x[4]}
+echo efgh | ( read x[1] ; echo ${x[1]} )
+echo wxyz | ( declare -a x ; read x ; echo $x ; echo ${x[0]} )
+
+# Make sure that arrays can be used to save the positional paramters verbatim
+set -- a 'b c' d 'e f g' h
+
+ARGV=( [0]=$0 "$@" )
+
+for z in "${ARGV[@]}"
+do
+ echo "$z"
+done
+
+echo "$0"
+for z in "$@"
+do
+ echo "$z"
+done
+
+# do various pattern removal and length tests
+XPATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:.:/sbin:/usr/sbin
+
+xpath=( $( IFS=: ; echo $XPATH ) )
+
+echo ${xpath[@]}
+echo ${xpath[@]##*/}
+echo ${xpath[0]##*/}
+echo ${xpath[@]%%[!/]*}
+echo ${xpath[0]%%[!/]*}
+recho ${xpath##*/}
+recho ${xpath%%[!/]*}
+recho ${xpath[5]##*/}
+recho ${xpath[5]%%[!/]*}
+
+# let's try to make it a DOS-style path
+
+zecho "${xpath[@]/\//\\}"
+zecho "${xpath[@]//\//\\}"
+zecho "${xpath[@]//[\/]/\\}"
+
+# length of the first element of the array, since array without subscript
+# is equivalent to referencing first element
+echo ${#xpath} -- ${#xpath[0]}
+
+# number of elements in the array
+nelem=${#xpath[@]}
+echo ${#xpath[@]} -- $nelem
+
+# total length of all elements in the array, including space separators
+xx="${xpath[*]}"
+echo ${#xx}
+
+# total length of all elements in the array
+xx=$( IFS='' ; echo "${xpath[*]}" )
+echo ${#xx}
+
+unset xpath[nelem-1]
+
+nelem=${#xpath[@]}
+echo ${#xpath[@]} -- $nelem
+
+# arrays and things that look like index assignments
+array=(42 [1]=14 [2]=44)
+
+array2=(grep [ 123 ] \*)
+
+echo ${array[@]}
+echo "${array2[@]}"
+
+# arrays and implicit arithmetic evaluation
+declare -i -a iarray
+
+iarray=( 2+4 1+6 7+2 )
+echo ${iarray[@]}
+
+iarray[4]=4+1
+echo ${iarray[@]}
+
+# make sure assignment using the compound assignment syntax removes all
+# of the old elements from the array value
+barray=(old1 old2 old3 old4 old5)
+barray=(new1 new2 new3)
+echo "length = ${#barray[@]}"
+echo "value = ${barray[*]}"
+
+# make sure the array code behaves correctly with respect to unset variables
+set -u
+( echo ${#narray[4]} )
+
+${THIS_SH} ./array1.sub
+${THIS_SH} ./array2.sub
+
+# some old bugs and ksh93 compatibility tests
+${THIS_SH} ./array3.sub
+
+# some compound assingment parsing problems that showed up in bash-3.1-release
+${THIS_SH} ./array4.sub
+
+set +u
+cd /tmp
+
+touch 1=bar
+foo=([10]="bar")
+echo ${foo[0]}
+rm 1=bar
+
+cd $OLDPWD
+
+foo=(a b c d e f g)
+echo ${foo[@]}
+
+# quoted reserved words are ok
+foo=(\for \case \if \then \else)
+echo ${foo[@]}
+
+# quoted metacharacters are ok
+foo=( [1]='<>' [2]='<' [3]='>' [4]='!' )
+echo ${foo[@]}
+
+# numbers are just words when not in a redirection context
+foo=( 12 14 16 18 20 )
+echo ${foo[@]}
+
+foo=( 4414758999202 )
+echo ${foo[@]}
+
+# this was a bug in all versions of bash 2.x up to and including bash-2.04
+declare -a ddd=(aaa
+bbb)
+echo ${ddd[@]}
+
+# errors until post-bash-2.05a; now reserved words are OK
+foo=(a b c for case if then else)
+
+foo=(for case if then else)
+
+# errors
+metas=( <> < > ! )
+metas=( [1]=<> [2]=< [3]=> [4]=! )
+
+# various expansions that didn't really work right until post-bash-2.04
+foo='abc'
+echo ${foo[0]} ${#foo[0]}
+echo ${foo[1]} ${#foo[1]}
+echo ${foo[@]} ${#foo[@]}
+echo ${foo[*]} ${#foo[*]}
+
+foo=''
+echo ${foo[0]} ${#foo[0]}
+echo ${foo[1]} ${#foo[1]}
+echo ${foo[@]} ${#foo[@]}
+echo ${foo[*]} ${#foo[*]}
+
+# new expansions added after bash-2.05b
+x[0]=zero
+x[1]=one
+x[4]=four
+x[10]=ten
+
+recho ${!x[@]}
+recho "${!x[@]}"
+recho ${!x[*]}
+recho "${!x[*]}"
+
+# sparse array tests for code fixed in bash-3.0
+unset av
+av[1]='one'
+av[2]=''
+
+av[3]=three
+av[5]=five
+av[7]=seven
+
+echo include null element -- expect one
+echo ${av[@]:1:2} # what happens when we include a null element?
+echo include unset element -- expect three five
+echo ${av[@]:3:2} # what happens when we include an unset element?
+echo start at unset element -- expect five seven
+echo ${av[@]:4:2} # what happens when we start at an unset element?
+
+echo too many elements -- expect three five seven
+echo ${av[@]:3:5} # how about too many elements?
+
+echo positive offset - expect five seven
+echo ${av[@]:5:2}
+echo negative offset to unset element - expect seven
+echo ${av[@]: -2:2}
+
+echo positive offset 2 - expect seven
+echo ${av[@]: 6:2}
+echo negative offset 2 - expect seven
+echo ${av[@]: -1:2}
+
+echo out-of-range offset
+echo ${av[@]:12}
+
+# parsing problems and other inconsistencies not fixed until post bash-3.0
+unset x
+declare -a x=(')' $$)
+[ ${x[1]} -eq $$ ] || echo bad
+
+unset x
+declare -a x=(a b c d e)
+echo ${x[4]}
+
+z=([1]=one [4]=four [7]=seven [10]=ten)
+
+echo ${#z[@]}
+
+echo ${!z[@]}
+
+unset x
+declare -a x=(a \'b c\')
+
+echo "${x[1]}"
+
+unset x
+declare -a x=(a 'b c')
+
+echo "${x[1]}"
+
+unset x
+declare -a x=($0)
+[ "${x[@]}" = $0 ] || echo double expansion of \$0
+declare -a x=(\$0)
+echo "${x[@]}"
+
+# tests for bash-3.1 problems
+${THIS_SH} ./array5.sub
+
+# tests for post-bash-3.2 problems, most fixed in bash-3.2 patches
+${THIS_SH} ./array6.sub
+${THIS_SH} ./array7.sub
+
+${THIS_SH} ./array8.sub
+
+${THIS_SH} ./array9.sub
diff --git a/tests/array1.sub b/tests/array1.sub
new file mode 100644
index 0000000..86e9332
--- /dev/null
+++ b/tests/array1.sub
@@ -0,0 +1 @@
+printf "%s\n" -a a=(a 'b c')
diff --git a/tests/array2.right b/tests/array2.right
new file mode 100644
index 0000000..b5145c2
--- /dev/null
+++ b/tests/array2.right
@@ -0,0 +1,74 @@
+argv[1] = <a b>
+argv[1] = <ab>
+argv[1] = <a b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <3>
+argv[1] = <bob>
+argv[1] = <tom dick harry>
+argv[1] = <joe>
+argv[1] = <3>
+argv[1] = <bob>
+argv[1] = <tom dick harry>
+argv[1] = <joe>
+argv[1] = <3>
+argv[1] = <bob>
+argv[1] = <tom dick harry>
+argv[1] = <joe>
+argv[1] = <3>
+argv[1] = <bob>
+argv[1] = <tom dick harry>
+argv[1] = <joe>
+argv[1] = <1>
+argv[1] = <bobtom dick harryjoe>
+argv[1] = <3>
+argv[1] = <bob>
+argv[1] = <tom dick harry>
+argv[1] = <joe>
+argv[1] = <3>
+argv[1] = <bob>
+argv[1] = <tom dick harry>
+argv[1] = <joe>
+argv[1] = <5>
+argv[1] = <bob>
+argv[1] = <tom>
+argv[1] = <dick>
+argv[1] = <5>
+argv[1] = <bob>
+argv[1] = <tom>
+argv[1] = <dick>
+argv[1] = <1>
+argv[1] = <bob>
+argv[2] = <tom>
+argv[3] = <dick>
+argv[4] = <harry>
+argv[5] = <joe>
+argv[1] = <3>
+argv[1] = <bob>
+argv[1] = <tom>
+argv[2] = <dick>
+argv[3] = <harry>
+argv[1] = <joe>
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <c>
+argv[4] = <d>
+argv[5] = <e>
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <c>
+argv[4] = <d>
+argv[5] = <e>
+argv[1] = <foo>
+argv[2] = <bar>
+argv[3] = <bam>
+argv[1] = <foobarbam>
+argv[1] = <foo>
+argv[2] = <bar>
+argv[3] = <bam>
+argv[1] = <foo>
+argv[2] = <bar>
+argv[3] = <bam>
+argv[1] = <foo bar bam>
diff --git a/tests/array2.sub b/tests/array2.sub
new file mode 100644
index 0000000..0e6417d
--- /dev/null
+++ b/tests/array2.sub
@@ -0,0 +1 @@
+declare -a ''=(a 'b c')
diff --git a/tests/array3.sub b/tests/array3.sub
new file mode 100644
index 0000000..579b42b
--- /dev/null
+++ b/tests/array3.sub
@@ -0,0 +1,9 @@
+a=(0 1 2 3 4 5 6 7 8 9)
+
+echo ${a[@]: -1}
+
+echo ${a[@]:9}
+echo ${a[@]:10}
+echo ${a[@]:11}
+
+echo ${a[@]:7:3}
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
new file mode 100644
index 0000000..a02bfc6
--- /dev/null
+++ b/tests/braces.right
@@ -0,0 +1,76 @@
+ffc ffb ffa
+fdg feg ffg
+lxyz nxyz mxyz
+{abc,def}
+{abc}
+{a,b,c,d,e}
+x} y} {a} b} c}
+x,y {abc} trie
+/usr/ucb/ex /usr/ucb/edit /usr/lib/ex /usr/lib/how_ex
+XXXX{a,b,c}
+XXXXa XXXXb XXXXc
+{}
+{ }
+}
+{
+abcd{efgh
+foo 1 2 bar
+foo 1 2 bar
+foo 1 2 bar
+foobar foobaz.
+foobar foobaz
+bazx bazy
+vx vy
+bazx bazy
+1 2 3 4 5 6 7 8 9 10
+0..10 braces
+0 1 2 3 4 5 6 7 8 9 10 braces
+x0y x1y x2y x3y x4y x5y x6y x7y x8y x9y x10y xbracesy
+3
+x3y
+10 9 8 7 6 5 4 3 2 1
+10y 9y 8y 7y 6y 5y 4y 3y 2y 1y
+x10y x9y x8y x7y x6y x5y x4y x3y x2y x1y
+a b c d e f
+f e d c b a
+a ` _ ^ ] [ Z Y X W V U T S R Q P O N M L K J I H G F E D C B A
+A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ ] ^ _ ` a
+f
+{1..f}
+{f..1}
+01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20
+-1 -2 -3 -4 -5 -6 -7 -8 -9 -10
+-20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0
+a-{bd}-c a-{be}-c
+a-{bdef-g-c a-{bdef-i-c
+{klklkl}1 {klklkl}2 {klklkl}3
+{x,x}
+1 3 5 7 9
+-1 -3 -5 -7 -9
+-1 -3 -5 -7 -9
+10 8 6 4 2
+10 8 6 4 2
+1 3 5 7 9 11 13 15 17 19
+1
+100 95 90 85 80 75 70 65 60 55 50 45 40 35 30 25 20 15 10 5 0
+100 95 90 85 80 75 70 65 60 55 50 45 40 35 30 25 20 15 10 5 0
+a b c d e f g h i j k l m n o p q r s t u v w x y z
+a c e g i k m o q s u w y
+z x v t r p n l j h f d b
+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
new file mode 100644
index 0000000..c2b153e
--- /dev/null
+++ b/tests/braces.tests
@@ -0,0 +1,116 @@
+echo ff{c,b,a}
+echo f{d,e,f}g
+echo {l,n,m}xyz
+echo {abc\,def}
+echo {abc}
+
+echo \{a,b,c,d,e}
+echo {x,y,\{a,b,c}}
+echo {x\,y,\{abc\},trie}
+
+echo /usr/{ucb/{ex,edit},lib/{ex,how_ex}}
+
+echo XXXX\{`echo a b c | tr ' ' ','`\}
+eval echo XXXX\{`echo a b c | tr ' ' ','`\}
+
+echo {}
+echo { }
+echo }
+echo {
+echo abcd{efgh
+
+echo foo {1,2} bar
+echo `zecho foo {1,2} bar`
+echo $(zecho foo {1,2} bar)
+
+var=baz
+varx=vx
+vary=vy
+
+echo foo{bar,${var}.}
+echo foo{bar,${var}}
+
+echo "${var}"{x,y}
+echo $var{x,y}
+echo ${var}{x,y}
+
+unset var varx vary
+
+# new sequence brace operators
+echo {1..10}
+
+# this doesn't work yet
+echo {0..10,braces}
+# but this does
+echo {{0..10},braces}
+echo x{{0..10},braces}y
+
+echo {3..3}
+echo x{3..3}y
+echo {10..1}
+echo {10..1}y
+echo x{10..1}y
+
+echo {a..f}
+echo {f..a}
+
+echo {a..A}
+echo {A..a}
+
+echo {f..f}
+
+# mixes are incorrectly-formed brace expansions
+echo {1..f}
+echo {f..1}
+
+echo 0{1..9} {10..20}
+
+# do negative numbers work?
+echo {-1..-10}
+echo {-20..0}
+
+# weirdly-formed brace expansions -- fixed in post-bash-3.1
+echo a-{b{d,e}}-c
+
+echo a-{bdef-{g,i}-c
+
+echo {"klklkl"}{1,2,3}
+echo {"x,x"}
+
+echo {1..10..2}
+echo {-1..-10..2}
+echo {-1..-10..-2}
+
+echo {10..1..-2}
+echo {10..1..2}
+
+echo {1..20..2}
+echo {1..20..20}
+
+echo {100..0..5}
+echo {100..0..-5}
+
+echo {a..z}
+echo {a..z..2}
+echo {z..a..-2}
+
+# 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
new file mode 100644
index 0000000..30e10ca
--- /dev/null
+++ b/tests/builtins.right
@@ -0,0 +1,141 @@
+a
+end-1
+a
+end-2
+a:x
+end-a
+b:x
+end-b
+c:x
+end-c
+end-3
+a:x
+end
+a
+b
+c
+end-1
+a
+b
+c
+end-2
+a:x
+a:y
+a:z
+end-a
+b:x
+b:y
+b:z
+end-b
+c:x
+c:y
+c:z
+end-c
+end-3
+a:x
+b:x
+c:x
+end
+$BVAR
+$BVAR
+$BVAR
+$BVAR
+foo
+bar
+xxx
+0022
+u=rwx,g=rx,o=rx
+0002
+u=rwx,g=rwx,o=rx
+umask 0002
+umask -S u=rwx,g=rwx,o=rx
+u=rwx,g=rwx,o=rwx
+enable .
+enable :
+enable break
+enable continue
+enable eval
+enable exec
+enable exit
+enable export
+enable readonly
+enable return
+enable set
+enable shift
+enable source
+enable times
+enable trap
+enable unset
+enable .
+enable :
+enable break
+enable continue
+enable eval
+enable exec
+enable exit
+enable export
+enable readonly
+enable return
+enable set
+enable shift
+enable source
+enable times
+enable trap
+enable unset
+enable -n test worked
+enable test worked
+specialname
+-specialname
+FOO=BAR
+FOO=BAR
+hash: hash table empty
+0
+AVAR
+foo
+in source.sub2, calling return
+5
+a b c
+a b c
+x y z
+a b c
+a b c
+m n o p
+a b c
+m n o p
+/tmp/bash-dir-a
+/tmp/bash-dir-a
+/tmp/bash-dir-a
+./source5.sub: line 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
+AVAR
+foo
+foo
+AVAR
+foo
+declare -x foo=""
+declare -x FOO="\$\$"
+./builtins.tests: line 210: declare: FOO: not found
+declare -x FOO="\$\$"
+ok
+ok
+./builtins.tests: line 242: kill: 4096: invalid signal specification
+1
+a\n\n\nb
+a
+
+
+b
+./builtins.tests: line 251: exit: status: numeric argument required
diff --git a/tests/builtins.tests b/tests/builtins.tests
new file mode 100644
index 0000000..6d20ae9
--- /dev/null
+++ b/tests/builtins.tests
@@ -0,0 +1,253 @@
+# tests for miscellaneous builtins not tested elsewhere
+set +p
+set +o posix
+
+ulimit -c 0 2>/dev/null
+
+# check that break breaks loops
+for i in a b c; do echo $i; break; echo bad-$i; done
+echo end-1
+for i in a b c; do echo $i; break 1; echo bad-$i; done
+echo end-2
+for i in a b c; do
+ for j in x y z; do
+ echo $i:$j
+ break
+ echo bad-$i
+ done
+ echo end-$i
+done
+echo end-3
+
+# check that break breaks nested loops
+for i in a b c; do
+ for j in x y z; do
+ echo $i:$j
+ break 2
+ echo bad-$i
+ done
+ echo end-$i
+done
+echo end
+
+# check that continue continues loops
+for i in a b c; do echo $i; continue; echo bad-$i ; done
+echo end-1
+for i in a b c; do echo $i; continue 1; echo bad-$i; done
+echo end-2
+for i in a b c; do
+ for j in x y z; do
+ echo $i:$j
+ continue
+ echo bad-$i-$j
+ done
+ echo end-$i
+done
+echo end-3
+
+# check that continue breaks out of nested loops
+for i in a b c; do
+ for j in x y z; do
+ echo $i:$j
+ continue 2
+ echo bad-$i-$j
+ done
+ echo end-$i
+done
+echo end
+
+# check that `eval' re-evaluates arguments, but `builtin' and `command' do not
+AVAR='$BVAR'
+BVAR=foo
+
+echo $AVAR
+builtin echo $AVAR
+command echo $AVAR
+eval echo \$AVAR
+eval echo $AVAR
+
+# test out eval with a temp environment
+AVAR=bar eval echo \$AVAR
+BVAR=xxx eval echo $AVAR
+
+unset -v AVAR BVAR
+
+# test umask
+mask=$(umask)
+umask 022
+umask
+umask -S
+umask -S u=rwx,g=rwx,o=rx >/dev/null # 002
+umask
+umask -S
+umask -p
+umask -p -S
+umask 0
+umask -S
+umask ${mask} # restore original mask
+
+# builtin/command without arguments should do nothing. maybe someday they will
+builtin
+command
+
+# test enable
+enable -ps
+
+enable -aps ; enable -nps
+
+enable -n test
+case "$(type -t test)" in
+builtin) echo oops -- enable -n test failed ;;
+*) echo enable -n test worked ;;
+esac
+
+enable test
+case "$(type -t test)" in
+builtin) echo enable test worked ;;
+*) echo oops -- enable test failed ;;
+esac
+
+# test options to exec
+(exec -a specialname ${THIS_SH} -c 'echo $0' )
+(exec -l -a specialname ${THIS_SH} -c 'echo $0' )
+# test `clean' environment. if /bin/sh is bash, and the script version of
+# printenv is run, there will be variables in the environment that bash
+# sets on startup. Also test code that prefixes argv[0] with a dash.
+(export FOO=BAR ; exec -c -l printenv ) | grep FOO
+(FOO=BAR exec -c printenv ) | grep FOO
+
+(export FOO=BAR ; exec printenv ) | grep FOO
+(FOO=BAR exec printenv ) | grep FOO
+
+# ok, forget everything about hashed commands
+hash -r
+hash
+
+# this had better succeed, since command -p guarantees we will find the
+# standard utilties
+command -p hash rm
+
+# check out source/.
+
+# sourcing a zero-length-file had better not be an error
+rm -f /tmp/zero-length-file
+cp /dev/null /tmp/zero-length-file
+. /tmp/zero-length-file
+echo $?
+rm /tmp/zero-length-file
+
+AVAR=AVAR
+
+. ./source1.sub
+AVAR=foo . ./source1.sub
+
+. ./source2.sub
+echo $?
+
+set -- a b c
+. ./source3.sub
+
+# make sure source with arguments does not change the shell's positional
+# parameters, but that the sourced file sees the arguments as its
+# positional parameters
+echo "$@"
+. ./source3.sub x y z
+echo "$@"
+
+# but if the sourced script sets the positional parameters explicitly, they
+# should be reflected in the calling shell's positional parameters. this
+# also tests one of the shopt options that controls source using $PATH to
+# find the script
+echo "$@"
+shopt -u sourcepath
+. source4.sub
+echo "$@"
+
+# this is complicated when the sourced scripts gets its own positional
+# parameters from arguments to `.'
+set -- a b c
+echo "$@"
+. source4.sub x y z
+echo "$@"
+
+# test out cd and $CDPATH
+${THIS_SH} ./builtins1.sub
+
+# test behavior of `.' when given a non-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.
+set -o posix
+echo $AVAR
+AVAR=foo . ./source1.sub
+echo $AVAR
+
+AVAR=AVAR
+echo $AVAR
+AVAR=foo eval echo \$AVAR
+echo $AVAR
+
+AVAR=AVAR
+echo $AVAR
+AVAR=foo :
+echo $AVAR
+set +o posix
+
+# but assignment statements preceding `export' are always reflected in
+# the environment
+foo="" export foo
+declare -p foo
+unset foo
+
+# assignment statements preceding `declare' should be displayed correctly,
+# but not persist after the command
+FOO='$$' declare -p FOO
+declare -p FOO
+unset FOO
+
+# except for `declare -x', which should be equivalent to `export'
+FOO='$$' declare -x FOO
+declare -p FOO
+unset FOO
+
+# test out kill -l. bash versions prior to 2.01 did `kill -l num' wrong
+sigone=$(kill -l | sed -n 's:^ 1) *\([^ ]*\)[ ].*$:\1:p')
+
+case "$(kill -l 1)" in
+${sigone/SIG/}) echo ok;;
+*) echo oops -- kill -l failure;;
+esac
+
+# kill -l and trap -l should display exactly the same output
+sigonea=$(trap -l | sed -n 's:^ 1) *\([^ ]*\)[ ].*$:\1:p')
+
+if [ "$sigone" != "$sigonea" ]; then
+ echo oops -- kill -l and trap -l differ
+fi
+
+# POSIX.2 says that exit statuses > 128 are mapped to signal names by
+# subtracting 128 so you can find out what signal killed a process
+case "$(kill -l $(( 128 + 1)) )" in
+${sigone/SIG/}) echo ok;;
+*) echo oops -- kill -l 129 failure;;
+esac
+
+# out-of-range signal numbers should report the argument in the error
+# message, not 128 less than the argument
+kill -l 4096
+
+# kill -l NAME should return the signal number
+kill -l ${sigone/SIG/}
+
+# test behavior of shopt xpg_echo
+${THIS_SH} ./builtins2.sub
+
+# this must be last -- it is a fatal error
+exit status
+
+echo after bad exit
diff --git a/tests/builtins1.sub b/tests/builtins1.sub
new file mode 100644
index 0000000..52185b5
--- /dev/null
+++ b/tests/builtins1.sub
@@ -0,0 +1,14 @@
+unset CDPATH
+
+MYDIR=$(pwd -P)
+FULLDIR=/tmp/bash-dir-a
+DIR=${FULLDIR##*/}
+
+mkdir $FULLDIR
+CDPATH=.:/tmp
+cd $DIR
+pwd
+echo $PWD
+
+cd "$MYDIR"
+rmdir $FULLDIR
diff --git a/tests/builtins2.sub b/tests/builtins2.sub
new file mode 100644
index 0000000..e4cb32a
--- /dev/null
+++ b/tests/builtins2.sub
@@ -0,0 +1,10 @@
+# test behavior of shopt xpg_echo
+
+USG_ECHO=off
+shopt -q xpg_echo && USG_ECHO=on
+
+shopt -u xpg_echo
+echo 'a\n\n\nb'
+
+shopt -s xpg_echo
+echo 'a\n\n\nb'
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
new file mode 100644
index 0000000..3775230
--- /dev/null
+++ b/tests/cond.right
@@ -0,0 +1,61 @@
+returns: 0
+returns: 0
+returns: 1
+returns: 0
+returns: 0
+returns: 0
+returns: 0
+returns: 0
+returns: 1
+returns: 0
+returns: 0
+returns: 1
+returns: 1
+returns: 1
+returns: 1
+returns: 0
+returns: 0
+returns: 0
+returns: 1
+returns: 0
+returns: 1
+returns: 0
+returns: 1
+returns: 1
+returns: 0
+./cond.tests: line 101: [[: 4+: syntax error: operand expected (error token is "+")
+returns: 1
+returns: 0
+returns: 0
+returns: 1
+returns: 0
+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
new file mode 100755
index 0000000..b053e48
--- /dev/null
+++ b/tests/cond.tests
@@ -0,0 +1,183 @@
+#
+# the test/[ code is tested elsewhere, and the [[...]] just uses the same
+# code. this tests the special features of [[...]]
+#
+TDIR=/usr/homes/chet
+
+# this one is straight out of the ksh88 book
+[[ foo > bar && $PWD -ef . ]]
+echo returns: $?
+
+# [[ x ]] is equivalent to [[ -n x ]]
+[[ x ]]
+echo returns: $?
+
+# [[ ! x ]] is equivalent to [[ ! -n x ]]
+[[ ! x ]]
+echo returns: $?
+
+# ! binds tighter than test/[ -- it binds to a term, not an expression
+[[ ! x || x ]]
+echo returns: $?
+
+# parenthesized terms didn't work right until post-2.04
+[[ a ]]
+echo returns: $?
+
+[[ (a) ]]
+echo returns: $?
+
+[[ -n a ]]
+echo returns: $?
+
+[[ (-n a) ]]
+echo returns: $?
+
+# unset variables don't need to be quoted
+[[ -n $UNSET ]]
+echo returns: $?
+
+[[ -z $UNSET ]]
+echo returns: $?
+
+# the ==/= and != operators do pattern matching
+[[ $TDIR == /usr/homes/* ]]
+echo returns: $?
+
+# ...but you can quote any part of the pattern to have it matched as a string
+[[ $TDIR == /usr/homes/\* ]]
+echo returns: $?
+
+[[ $TDIR == '/usr/homes/*' ]]
+echo returns: $?
+
+# if the first part of && fails, the second is not executed
+[[ -n $UNSET && $UNSET == foo ]]
+echo returns: $?
+
+[[ -z $UNSET && $UNSET == foo ]]
+echo returns: $?
+
+# if the first part of || succeeds, the second is not executed
+[[ -z $UNSET || -d $PWD ]]
+echo returns: $?
+
+# if the rhs were executed, it would be an error
+[[ -n $TDIR || $HOME -ef ${H*} ]]
+echo returns: $?
+
+[[ -n $TDIR && -z $UNSET || $HOME -ef ${H*} ]]
+echo returns: $?
+
+# && has a higher parsing precedence than ||
+[[ -n $TDIR && -n $UNSET || $TDIR -ef . ]]
+echo returns: $?
+
+# ...but expressions in parentheses may be used to override precedence rules
+[[ -n $TDIR || -n $UNSET && $PWD -ef xyz ]]
+echo returns: $?
+
+[[ ( -n $TDIR || -n $UNSET ) && $PWD -ef xyz ]]
+echo returns: $?
+
+# some arithmetic tests for completeness -- see what happens with missing
+# operands, bad expressions, makes sure arguments are evaluated as
+# arithmetic expressions, etc.
+
+unset IVAR A
+[[ 7 -gt $IVAR ]]
+echo returns: $?
+
+[[ $IVAR -gt 7 ]]
+echo returns: $?
+
+IVAR=4
+[[ $IVAR -gt 7 ]]
+echo returns: $?
+
+[[ 7 -eq 4+3 ]]
+echo returns: $?
+
+[[ 7 -eq 4+ ]]
+echo returns: $?
+
+IVAR=4+3
+[[ $IVAR -eq 7 ]]
+echo returns: $?
+
+A=7
+[[ $IVAR -eq A ]]
+echo returns: $?
+
+unset IVAR A
+
+# more pattern matching tests
+
+[[ $filename == *.c ]]
+echo returns: $?
+
+filename=patmatch.c
+
+[[ $filename == *.c ]]
+echo returns: $?
+
+# the extended globbing features may be used when matching patterns
+shopt -s extglob
+
+arg=-7
+
+[[ $arg == -+([0-9]) ]]
+echo returns: $?
+
+arg=-H
+
+[[ $arg == -+([0-9]) ]]
+echo returns: $?
+
+arg=+4
+[[ $arg == ++([0-9]) ]]
+echo returns: $?
+
+# make sure the null string is never matched if the string is not null
+STR=file.c
+PAT=
+
+if [[ $STR = $PAT ]]; then
+ echo oops
+fi
+
+# but that if the string is null, a null pattern is matched correctly
+STR=
+PAT=
+
+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/cprint.right b/tests/cprint.right
new file mode 100644
index 0000000..2000072
--- /dev/null
+++ b/tests/cprint.right
@@ -0,0 +1,72 @@
+tf is a function
+tf ()
+{
+ echo this is ${0##*/} > /dev/null;
+ echo a | cat - > /dev/null;
+ test -f ${0##*/} && echo ${0##*/} is a regular file;
+ test -d ${0##*/} || echo ${0##*/} is not a directory;
+ echo a;
+ echo b;
+ echo c;
+ echo background > /dev/null & ( exit 1 );
+ echo $?;
+ {
+ echo a
+ };
+ i=0;
+ while (( i < 3 )); do
+ test -r /dev/fd/$i;
+ i=$(( i + 1 ));
+ done;
+ [[ -r /dev/fd/0 && -w /dev/fd/1 ]] || echo oops > /dev/null;
+ for name in $( echo 1 2 3 );
+ do
+ test -r /dev/fd/$name;
+ done;
+ if [[ -r /dev/fd/0 && -w /dev/fd/1 ]]; then
+ echo ok > /dev/null;
+ else
+ if (( 7 > 40 )); then
+ echo oops;
+ else
+ echo done;
+ fi;
+ fi > /dev/null;
+ case $PATH in
+ *$PWD*)
+ echo \$PWD in \$PATH
+ ;;
+ *)
+ echo \$PWD not in \$PATH
+ ;;
+ esac > /dev/null;
+ while false; do
+ echo z;
+ done > /dev/null;
+ until true; do
+ echo z;
+ done > /dev/null;
+ echo \&\|'()' \{ echo abcde \; \};
+ eval fu\%nc'()' \{ echo abcde \; \};
+ type fu\%nc
+}
+tf2 is a function
+tf2 ()
+{
+ ( {
+ time -p echo a | cat - > /dev/null
+ } ) 2>&1
+}
+cprint.tests is a regular file
+cprint.tests is not a directory
+a
+b
+c
+1
+a
+&|() { echo abcde ; }
+fu%nc is a function
+fu%nc ()
+{
+ echo abcde
+}
diff --git a/tests/cprint.tests b/tests/cprint.tests
new file mode 100644
index 0000000..08ff1eb
--- /dev/null
+++ b/tests/cprint.tests
@@ -0,0 +1,67 @@
+#
+# a nonsense script and shell function to test out the command printing code
+#
+tf()
+{
+ # simple command with redir
+ echo this is ${0##*/} > /dev/null
+
+ # pipeline
+ echo a | cat - > /dev/null
+
+ test -f ${0##*/} && echo ${0##*/} is a regular file
+ test -d ${0##*/} || echo ${0##*/} is not a directory
+
+ echo a ; echo b ; echo c
+
+ echo background >/dev/null &
+
+ ( exit 1 )
+ echo $?
+
+ { echo a ; }
+
+ i=0
+ while (( i < 3 )); do
+ test -r /dev/fd/$i
+ i=$(( i + 1 ))
+ done
+
+ [[ -r /dev/fd/0 && -w /dev/fd/1 ]] || echo oops > /dev/null
+
+ for name in $( echo 1 2 3 ); do
+ test -r /dev/fd/$name
+ done
+
+ if [[ -r /dev/fd/0 && -w /dev/fd/1 ]] ; then
+ echo ok > /dev/null
+ elif (( 7 > 40 )) ; then
+ echo oops
+ else
+ echo done
+ fi > /dev/null
+
+ case $PATH in
+ *$PWD*) echo \$PWD in \$PATH ;;
+ *) echo \$PWD not in \$PATH ;;
+ esac > /dev/null
+
+ while false; do echo z; done > /dev/null
+
+ until true; do echo z ; done > /dev/null
+
+ echo \&\|'()' \{ echo abcde \; \}
+ # when not in POSIX mode, we can have weirdly-named functions
+ eval fu\%nc'()' \{ echo abcde \; \}
+ type fu\%nc
+}
+
+tf2()
+{
+ ( { time -p echo a | cat - > /dev/null ; } ) 2>&1
+}
+
+type tf
+type tf2
+
+tf
diff --git a/tests/dbg-support.right b/tests/dbg-support.right
new file mode 100644
index 0000000..c4a1609
--- /dev/null
+++ b/tests/dbg-support.right
@@ -0,0 +1,371 @@
+debug lineno: 63 main
+debug lineno: 66 main
+FUNCNAME main
+debug lineno: 70 main
+debug lineno: 17 fn1
+debug lineno: 18 fn1
+LINENO 18
+debug lineno: 19 fn1
+LINENO 19
+debug lineno: 20 fn1
+BASH_SOURCE[0] ./dbg-support.tests
+debug lineno: 21 fn1
+FUNCNAME[0] fn1
+debug lineno: 22 fn1
+debug lineno: 22 fn1 70 ./dbg-support.tests
+debug lineno: 23 fn1
+debug lineno: 23 fn1 70 main ./dbg-support.tests
+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]
+debug lineno: 25 fn1
+debug lineno: 17 fn1
+debug lineno: 12 print_return_trap
+debug lineno: 13 print_return_trap
+return lineno: 17 fn1
+debug lineno: 14 print_return_trap
+debug lineno: 71 main
+debug lineno: 28 fn2
+debug lineno: 29 fn2
+fn2 here. Calling fn1...
+debug lineno: 30 fn2
+debug lineno: 17 fn1
+debug lineno: 18 fn1
+LINENO 18
+debug lineno: 19 fn1
+LINENO 19
+debug lineno: 20 fn1
+BASH_SOURCE[0] ./dbg-support.tests
+debug lineno: 21 fn1
+FUNCNAME[0] fn1
+debug lineno: 22 fn1
+debug lineno: 22 fn1 30 ./dbg-support.tests
+debug lineno: 23 fn1
+debug lineno: 23 fn1 30 fn2 ./dbg-support.tests
+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]
+debug lineno: 25 fn1
+debug lineno: 17 fn1
+debug lineno: 12 print_return_trap
+debug lineno: 13 print_return_trap
+return lineno: 17 fn1
+debug lineno: 14 print_return_trap
+debug lineno: 28 fn2
+debug lineno: 12 print_return_trap
+debug lineno: 13 print_return_trap
+return lineno: 28 fn2
+debug lineno: 14 print_return_trap
+debug lineno: 72 main
+debug lineno: 33 fn3
+debug lineno: 34 fn3
+LINENO 34
+debug lineno: 35 fn3
+BASH_SOURCE[0] ./dbg-support.tests
+debug lineno: 38 fn3
+debug lineno: 39 fn3
+debug lineno: 40 fn3
+debug lineno: 40 fn3
+debug lineno: 41 fn3
+debug lineno: 42 fn3
+debug lineno: 43 fn3
+fn3 called from file `./dbg-support.tests' at line 0
+debug lineno: 40 fn3
+debug lineno: 40 fn3
+debug lineno: 41 fn3
+debug lineno: 42 fn3
+debug lineno: 42 fn3
+debug lineno: 43 fn3
+main called from file `./dbg-support.tests' at line 0
+debug lineno: 40 fn3
+debug lineno: 40 fn3
+debug lineno: 46 fn3
+debug lineno: 18 source
+SOURCED LINENO 18
+debug lineno: 19 source
+SOURCED BASH_SOURCE[0] ./dbg-support.sub
+debug lineno: 20 source
+debug lineno: 3 sourced_fn
+debug lineno: 4 sourced_fn
+debug lineno: 5 sourced_fn
+SOURCED FN LINENO 5
+debug lineno: 8 sourced_fn
+debug lineno: 9 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 11 sourced_fn
+debug lineno: 12 sourced_fn
+debug lineno: 13 sourced_fn
+FUNCNAME[0]: sourced_fn called from ./dbg-support.sub at line 20
+debug lineno: 10 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 11 sourced_fn
+debug lineno: 12 sourced_fn
+debug lineno: 13 sourced_fn
+FUNCNAME[1]: source called from ./dbg-support.tests at line 46
+debug lineno: 10 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 11 sourced_fn
+debug lineno: 12 sourced_fn
+debug lineno: 13 sourced_fn
+FUNCNAME[2]: fn3 called from ./dbg-support.tests at line 72
+debug lineno: 10 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 11 sourced_fn
+debug lineno: 12 sourced_fn
+debug lineno: 12 sourced_fn
+debug lineno: 13 sourced_fn
+FUNCNAME[3]: main called from ./dbg-support.tests at line 0
+debug lineno: 10 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 3 sourced_fn
+debug lineno: 12 print_return_trap
+debug lineno: 13 print_return_trap
+return lineno: 3 sourced_fn
+debug lineno: 14 print_return_trap
+debug lineno: 46 fn3
+debug lineno: 12 print_return_trap
+debug lineno: 13 print_return_trap
+return lineno: 46 fn3
+debug lineno: 14 print_return_trap
+debug lineno: 33 fn3
+debug lineno: 12 print_return_trap
+debug lineno: 13 print_return_trap
+return lineno: 33 fn3
+debug lineno: 14 print_return_trap
+debug lineno: 73 main
+debug lineno: 18 source
+SOURCED LINENO 18
+debug lineno: 19 source
+SOURCED BASH_SOURCE[0] ./dbg-support.sub
+debug lineno: 20 source
+debug lineno: 3 sourced_fn
+debug lineno: 4 sourced_fn
+debug lineno: 5 sourced_fn
+SOURCED FN LINENO 5
+debug lineno: 8 sourced_fn
+debug lineno: 9 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 11 sourced_fn
+debug lineno: 12 sourced_fn
+debug lineno: 13 sourced_fn
+FUNCNAME[0]: sourced_fn called from ./dbg-support.sub at line 20
+debug lineno: 10 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 11 sourced_fn
+debug lineno: 12 sourced_fn
+debug lineno: 13 sourced_fn
+FUNCNAME[1]: source called from ./dbg-support.tests at line 73
+debug lineno: 10 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 11 sourced_fn
+debug lineno: 12 sourced_fn
+debug lineno: 12 sourced_fn
+debug lineno: 13 sourced_fn
+FUNCNAME[2]: main called from ./dbg-support.tests at line 0
+debug lineno: 10 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 3 sourced_fn
+debug lineno: 12 print_return_trap
+debug lineno: 13 print_return_trap
+return lineno: 3 sourced_fn
+debug lineno: 14 print_return_trap
+debug lineno: 73 main
+debug lineno: 12 print_return_trap
+debug lineno: 13 print_return_trap
+return lineno: 73 main
+debug lineno: 14 print_return_trap
+debug lineno: 76 main
+debug lineno: 79 main
+LINENO 18
+LINENO 19
+BASH_SOURCE[0] ./dbg-support.tests
+FUNCNAME[0] fn1
+79 ./dbg-support.tests
+79 main ./dbg-support.tests
+
+./dbg-support.tests: line 25: caller: foo: invalid number
+caller: usage: caller [expr]
+
+debug lineno: 80 main
+fn2 here. Calling fn1...
+LINENO 18
+LINENO 19
+BASH_SOURCE[0] ./dbg-support.tests
+FUNCNAME[0] fn1
+30 ./dbg-support.tests
+30 fn2 ./dbg-support.tests
+80 main ./dbg-support.tests
+./dbg-support.tests: line 25: caller: foo: invalid number
+caller: usage: caller [expr]
+
+debug lineno: 81 main
+LINENO 34
+BASH_SOURCE[0] ./dbg-support.tests
+fn3 called from file `./dbg-support.tests' at line 0
+main called from file `./dbg-support.tests' at line 0
+SOURCED LINENO 18
+SOURCED BASH_SOURCE[0] ./dbg-support.sub
+SOURCED FN LINENO 5
+FUNCNAME[0]: sourced_fn called from ./dbg-support.sub at line 20
+FUNCNAME[1]: source called from ./dbg-support.tests at line 46
+FUNCNAME[2]: fn3 called from ./dbg-support.tests at line 81
+FUNCNAME[3]: main called from ./dbg-support.tests at line 0
+debug lineno: 82 main
+fn4 here. Calling fn3...
+LINENO 34
+BASH_SOURCE[0] ./dbg-support.tests
+fn3 called from file `./dbg-support.tests' at line 82
+fn4 called from file `./dbg-support.tests' at line 0
+main called from file `./dbg-support.tests' at line 0
+SOURCED LINENO 18
+SOURCED BASH_SOURCE[0] ./dbg-support.sub
+SOURCED FN LINENO 5
+FUNCNAME[0]: sourced_fn called from ./dbg-support.sub at line 20
+FUNCNAME[1]: source called from ./dbg-support.tests at line 46
+FUNCNAME[2]: fn3 called from ./dbg-support.tests at line 51
+FUNCNAME[3]: fn4 called from ./dbg-support.tests at line 82
+FUNCNAME[4]: main called from ./dbg-support.tests at line 0
+debug lineno: 83 main
+SOURCED LINENO 18
+SOURCED BASH_SOURCE[0] ./dbg-support.sub
+SOURCED FN LINENO 5
+FUNCNAME[0]: sourced_fn called from ./dbg-support.sub at line 20
+FUNCNAME[1]: source called from ./dbg-support.tests at line 83
+FUNCNAME[2]: main called from ./dbg-support.tests at line 0
+return lineno: 83 main
+debug lineno: 86 main
+debug lineno: 89 main
+debug lineno: 18 source
+SOURCED LINENO 18
+debug lineno: 19 source
+SOURCED BASH_SOURCE[0] ./dbg-support.sub
+debug lineno: 20 source
+debug lineno: 3 sourced_fn
+debug lineno: 4 sourced_fn
+debug lineno: 5 sourced_fn
+SOURCED FN LINENO 5
+debug lineno: 8 sourced_fn
+debug lineno: 9 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 11 sourced_fn
+debug lineno: 12 sourced_fn
+debug lineno: 13 sourced_fn
+FUNCNAME[0]: sourced_fn called from ./dbg-support.sub at line 20
+debug lineno: 10 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 11 sourced_fn
+debug lineno: 12 sourced_fn
+debug lineno: 13 sourced_fn
+FUNCNAME[1]: source called from ./dbg-support.tests at line 89
+debug lineno: 10 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 11 sourced_fn
+debug lineno: 12 sourced_fn
+debug lineno: 12 sourced_fn
+debug lineno: 13 sourced_fn
+FUNCNAME[2]: main called from ./dbg-support.tests at line 0
+debug lineno: 10 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 3 sourced_fn
+debug lineno: 12 print_return_trap
+debug lineno: 13 print_return_trap
+return lineno: 3 sourced_fn
+debug lineno: 14 print_return_trap
+debug lineno: 89 main
+debug lineno: 12 print_return_trap
+debug lineno: 13 print_return_trap
+return lineno: 89 main
+debug lineno: 14 print_return_trap
+debug lineno: 90 main
+debug lineno: 93 main
+debug lineno: 93 main
+debug lineno: 94 main
+debug lineno: 97 main
+debug lineno: 93 main
+debug lineno: 93 main
+debug lineno: 94 main
+debug lineno: 97 main
+debug lineno: 93 main
+debug lineno: 93 main
+debug lineno: 94 main
+debug lineno: 95 main
+Hit 2
+debug lineno: 97 main
+debug lineno: 93 main
+debug lineno: 93 main
+debug lineno: 103 main
+SOURCED FN LINENO 5 FUNCNAME[0]: sourced_fn called from ./dbg-support.tests at line 103 FUNCNAME[1]: main called from ./dbg-support.tests at line 0
+debug lineno: 104 main
+SOURCED FN LINENO 5 FUNCNAME[0]: sourced_fn called from ./dbg-support.tests at line 104 FUNCNAME[1]: main called from ./dbg-support.tests at line 0
+debug lineno: 105 main
+debug lineno: 106 main
+SOURCED FN LINENO 5
+FUNCNAME[0]: sourced_fn called from ./dbg-support.tests at line 106
+FUNCNAME[1]: main called from ./dbg-support.tests at line 0
+debug lineno: 110 main
+debug lineno: 111 main
+debug lineno: 3 sourced_fn
+debug lineno: 4 sourced_fn
+debug lineno: 5 sourced_fn
+SOURCED FN LINENO 5
+debug lineno: 8 sourced_fn
+debug lineno: 9 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 11 sourced_fn
+debug lineno: 12 sourced_fn
+debug lineno: 13 sourced_fn
+FUNCNAME[0]: sourced_fn called from ./dbg-support.tests at line 111
+debug lineno: 10 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 11 sourced_fn
+debug lineno: 12 sourced_fn
+debug lineno: 12 sourced_fn
+debug lineno: 13 sourced_fn
+FUNCNAME[1]: main called from ./dbg-support.tests at line 0
+debug lineno: 10 sourced_fn
+debug lineno: 10 sourced_fn
+debug lineno: 3 sourced_fn
+debug lineno: 12 print_return_trap
+debug lineno: 13 print_return_trap
+return lineno: 3 sourced_fn
+debug lineno: 14 print_return_trap
+debug lineno: 114 main
+debug lineno: 119 main
+debug lineno: 123 main
+got it
+debug lineno: 131 main
+debug lineno: 132 main
+debug lineno: 133 main
+debug lineno: 132 main
+debug lineno: 133 main
+debug lineno: 131 main
+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.sub b/tests/dbg-support.sub
new file mode 100644
index 0000000..f68f8d9
--- /dev/null
+++ b/tests/dbg-support.sub
@@ -0,0 +1,26 @@
+# This file is intended to be sourced from one of the bashdb test programs
+
+sourced_fn() {
+ name="fn2"
+ echo "SOURCED FN LINENO $LINENO"
+
+ # Print a stack trace
+ declare -i n
+ n=${#FUNCNAME[@]}
+ for (( i=0 ; (( i < $n )) ; i++ )) ; do
+ local -i j=i+1
+ [ $j -eq $n ] && j=i # main()'s file is the same as the first caller
+ echo "FUNCNAME[$i]: ${FUNCNAME[$i]} called from ${BASH_SOURCE[$j]}" \
+ "at line ${BASH_LINENO[$i]}"
+ done
+}
+
+echo "SOURCED LINENO $LINENO"
+echo "SOURCED BASH_SOURCE[0]" ${BASH_SOURCE[0]}
+sourced_fn
+
+#;;; Local Variables: ***
+#;;; mode:shell-script ***
+#;;; eval: (sh-set-shell "bash") ***
+#;;; End: ***
+
diff --git a/tests/dbg-support.tests b/tests/dbg-support.tests
new file mode 100755
index 0000000..ad06d01
--- /dev/null
+++ b/tests/dbg-support.tests
@@ -0,0 +1,142 @@
+#!../bash
+#
+# Test correct functioning bash debug support not via the bashdb
+# debugger but merely by printing via print_trap()
+# $Id: dbg-support.tests,v 1.13 2003/02/17 22:02:25 rockyb Exp $
+shopt -s extdebug
+print_debug_trap() {
+ echo "debug lineno: $1 ${FUNCNAME[1]}"
+ return
+}
+
+print_return_trap() {
+ echo "return lineno: $1 ${FUNCNAME[1]}"
+ return
+}
+
+fn1() {
+ echo "LINENO $LINENO"
+ echo "LINENO $LINENO"
+ echo "BASH_SOURCE[0]" ${BASH_SOURCE[0]}
+ echo "FUNCNAME[0]" ${FUNCNAME[0]}
+ echo `caller`
+ echo `caller 0`
+ echo `caller 1`
+ echo `caller foo`
+}
+
+fn2() {
+ echo "fn2 here. Calling fn1..."
+ fn1
+}
+
+fn3() {
+ echo "LINENO $LINENO"
+ echo "BASH_SOURCE[0]" ${BASH_SOURCE[0]}
+
+ # Print a stack trace
+ declare -i n
+ n=${#FUNCNAME[@]}
+ for (( i=0 ; (( i < $n )) ; i++ )) ; do
+ local -i j=i+1
+ [ $j -eq $n ] && j=i # main()'s file is the same as the first caller
+ echo "${FUNCNAME[$i]} called from file " \
+ "\`${BASH_SOURCE[$j]}' at line ${BASH_LINENO[$j]}"
+ done
+ source ./dbg-support.sub
+}
+
+fn4() {
+ echo "fn4 here. Calling fn3..."
+ fn3
+}
+
+
+#!../bash
+#
+# Test of support for debugging facilities in bash
+#
+# Test debugger set option functrace - set on. Not in vanilla Bash 2.05
+#
+set -o functrace
+trap 'print_debug_trap $LINENO' DEBUG
+trap 'print_return_trap $LINENO' RETURN
+
+# Funcname is now an array, but you still can't see it outside a function
+echo "FUNCNAME" ${FUNCNAME[0]:-main}
+
+# We should trace into the below.
+# Start easy with a simple function.
+fn1
+fn2
+fn3
+source ./dbg-support.sub
+
+# Test debugger set option functrace - set off
+set +T
+
+# We should not trace into this.
+fn1
+fn2
+fn3
+fn4
+source ./dbg-support.sub
+
+# Another way to say: set -o functrace
+set -T
+
+# We should trace into this.
+source ./dbg-support.sub
+set +T
+
+# Test that the line numbers in the presence of conditionals are correct.
+for (( i=0 ; (( i <= 2 )) ; i++ )) ; do
+ if [ $i -eq 2 ] ; then
+ echo "Hit 2"
+ fi
+ j=4
+done
+
+#
+# Check line numbers in command substitution
+#
+echo $(sourced_fn)
+echo `sourced_fn`
+x=$((sourced_fn))
+x={ sourced_fn }
+
+# Make sure we step into sourced_fn as a comand when we request to do so.
+# Vanilla bash 2.0 doesn't do.
+set -o functrace
+x={ sourced_fn }
+
+# Should see line number of xyzzy below. Vanilla bash 2.05b doesn't do
+case xyzzy in
+ a )
+ x=5
+ ;;
+ xyzz? )
+ case 3 in
+ 2 )
+ x=6 ;;
+ 3 )
+ echo "got it" ;;
+ * ) echo "no good" ;;
+ esac
+ ;;
+ * )
+esac
+
+# Should see line numbers for initial for lines.
+for i in 0 1 ; do
+ for j in 3 4 ; do
+ ((x=i+j))
+ done
+done
+
+${THIS_SH} ./dbg-support3.sub
+
+#;;; Local Variables: ***
+#;;; mode:shell-script ***
+#;;; eval: (sh-set-shell "bash") ***
+#;;; End: ***
diff --git a/tests/dbg-support2.right b/tests/dbg-support2.right
new file mode 100644
index 0000000..c9d884e
--- /dev/null
+++ b/tests/dbg-support2.right
@@ -0,0 +1,7 @@
+lineno: 17 (6) main
+lineno: 18 (6) main
+x is 1
+lineno: 19 (6) main
+lineno: 20 (6) main
+lineno: 21 (6) main
+x is 1
diff --git a/tests/dbg-support2.tests b/tests/dbg-support2.tests
new file mode 100755
index 0000000..fdc0f31
--- /dev/null
+++ b/tests/dbg-support2.tests
@@ -0,0 +1,26 @@
+#!../bash
+#
+# Test correct trap return codes = 2 means skip execution.
+shopt -s extdebug
+print_trap() {
+ echo "lineno: $1 ($LINENO) ${FUNCNAME[1]}"
+ if [[ $debug_exit == 2 ]] ; then
+ debug_exit=0
+ return 2
+ fi
+ return 0
+}
+
+debug_exit=0
+trap 'print_trap $LINENO' DEBUG
+
+x=1
+echo "x is $x"
+debug_exit=2
+x=2
+echo "x is $x"
+
+#;;; Local Variables: ***
+#;;; mode:shell-script ***
+#;;; eval: (sh-set-shell "bash") ***
+#;;; End: ***
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
new file mode 100755
index 0000000..54e499d
--- /dev/null
+++ b/tests/dollar-at-star
@@ -0,0 +1,238 @@
+# first, let's start with the basics
+
+recho "$@"
+recho "$*"
+
+recho $@
+recho $*
+
+set a b
+
+recho "$*"
+
+# If IFS is null, the parameters are joined without separators
+IFS=''
+recho "$*"
+
+# If IFS is unset, the parameters are separated by spaces
+unset IFS
+recho "${*}"
+
+recho "$@"
+recho $@
+
+IFS='/'
+set bob 'tom dick harry' joe
+set $*
+recho $#
+recho $1
+recho $2
+recho $3
+
+set bob 'tom dick harry' joe
+set ${*}
+recho $#
+recho $1
+recho $2
+recho $3
+
+set bob 'tom dick harry' joe
+set $@
+recho $#
+recho $1
+recho $2
+recho $3
+
+set bob 'tom dick harry' joe
+set ${@}
+recho $#
+recho $1
+recho $2
+recho $3
+
+# according to POSIX.2, unquoted $* should expand to multiple words if
+# $IFS is null, just like unquoted $@
+IFS=''
+set bob 'tom dick harry' joe
+set $*
+recho $#
+recho $1
+recho $2
+recho $3
+
+set bob 'tom dick harry' joe
+set $@
+recho $#
+recho $1
+recho $2
+recho $3
+
+# if IFS is unset, the individual positional parameters are split on
+# " \t\n" if $* or $@ are unquoted
+unset IFS
+set bob 'tom dick harry' joe
+set $*
+recho $#
+recho $1
+recho $2
+recho $3
+
+set bob 'tom dick harry' joe
+set $@
+recho $#
+recho $1
+recho $2
+recho $3
+
+# but not for "$@" or "$*"
+set bob 'tom dick harry' joe
+set "$*"
+recho $#
+recho $1
+recho $2
+recho $3
+
+set bob 'tom dick harry' joe
+set "$@"
+recho $#
+recho $1
+recho $2
+recho $3
+
+# POSIX.2 says these should both expand the positional parameters
+# to multiple words
+set a b c d e
+IFS=""
+recho $@
+recho "$@"
+
+# this example is straight from the POSIX.2 rationale
+set foo bar bam
+
+recho "$@"
+recho "$*"
+
+unset IFS
+
+recho "$@"
+recho $@
+recho "$*"
+
+IFS=:
+
+# special variables
+set -- 1 2 3 4 5 6 7 8 9 10
+
+bar=${*}
+foo=$*
+echo foo = "$foo"
+echo bar = "$bar"
+
+foo1=$@
+bar1=${@}
+
+echo foo1 = "$foo1"
+echo bar1 = "$bar1"
+
+foo2="$*"
+bar2="${*}"
+
+echo foo2 = "$foo2"
+echo bar2 = "$bar2"
+
+eval foo3='$*' bar3='${*}'
+echo foo3 = "$foo3"
+echo bar3 = "$bar3"
+
+case $* in
+*\:*) echo ok 1;;
+*) echo bad 1;;
+esac
+
+case $@ in
+*\:*) echo bad 2;;
+*) echo ok 2;;
+esac
+
+case "$*" in
+*\:*) echo ok 3;;
+*) echo bad 3;;
+esac
+
+case "$@" in
+*\:*) echo bad 4;;
+*) echo ok 4;;
+esac
+
+IFS=$' \t\n'
+
+bar=${*}
+foo=$*
+echo foo = "$foo"
+echo bar = "$bar"
+
+foo1=$@
+bar1=${@}
+
+echo foo1 = "$foo1"
+echo bar1 = "$bar1"
+
+foo2="$*"
+bar2="${*}"
+
+echo foo2 = "$foo2"
+echo bar2 = "$bar2"
+
+eval foo3='$*' bar3='${*}'
+echo foo3 = "$foo3"
+echo bar3 = "$bar3"
+
+case $* in
+*\ *) echo ok 1;;
+*) echo bad 1;;
+esac
+
+case $@ in
+*\ *) echo ok 2;;
+*) echo bad 2;;
+esac
+
+case "$*" in
+*\ *) echo ok 3;;
+*) echo bad 3;;
+esac
+
+case "$@" in
+*\ *) echo ok 4;;
+*) echo bad 4;;
+esac
+
+# tests for special expansion of "$*" and "${array[*]}" when used with other
+# expansions -- bugs through bash-2.05b
+${THIS_SH} ./dollar-star1.sub
+
+# tests for expansion of "$@" on rhs of things like ${param:+word}. Bugs
+# though bash-2.05b
+${THIS_SH} ./dollar-at1.sub
+
+# tests for expansion of other variables in double-quoted strings containing
+# $@. Bugs through bash-2.05b
+${THIS_SH} ./dollar-at2.sub
+
+# tests for various expansions of $* in different contexts -- word split,
+# 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-at1.sub b/tests/dollar-at1.sub
new file mode 100644
index 0000000..6d40786
--- /dev/null
+++ b/tests/dollar-at1.sub
@@ -0,0 +1,29 @@
+echo_argc()
+{
+ echo $#
+}
+
+a()
+{
+ shift
+ echo_argc "$@"
+ echo_argc ${1:+"$@"}
+ echo_argc "${1:+$@}"
+ echo_argc 1 2 3
+}
+
+b()
+{
+ _IFS="$IFS"
+ IFS="$1"
+ shift
+ echo_argc "$@"
+ echo_argc ${1:+"$@"}
+ echo_argc "${1:+$@}"
+ echo_argc 1 2 3
+ IFS="$_IFS"
+}
+
+a "X" foo bar hoge
+
+b "X" foo bar hoge
diff --git a/tests/dollar-at2.sub b/tests/dollar-at2.sub
new file mode 100644
index 0000000..c079a29
--- /dev/null
+++ b/tests/dollar-at2.sub
@@ -0,0 +1,19 @@
+t1()
+{
+ xxx="echo $@"
+
+ recho "$xxx ; echo $@"
+}
+
+t2()
+{
+ xxx="echo $@"
+
+ recho "${xxx} ; echo $@"
+}
+
+t1 1
+t1 1 2
+
+t2 1
+t2 1 2
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-star1.sub b/tests/dollar-star1.sub
new file mode 100644
index 0000000..63a9ef8
--- /dev/null
+++ b/tests/dollar-star1.sub
@@ -0,0 +1,31 @@
+set -- a b c
+x=(a b c); IFS='|'
+
+echo "${*/#/x}"
+echo "${x[*]/#/x}"
+
+echo "$*"
+echo "${x[*]}"
+
+echo "$@"
+echo "${x[@]}"
+
+echo "${@/#/x}"
+echo "${x[@]/#/x}"
+
+echo "${*:1:2}"
+echo "${x[*]:1:2}"
+
+echo "${@:1:2}"
+echo "${x[@]:1:2}"
+
+IFS=$' \t\n'
+set -- xa xb xc
+x=(xa xb xc)
+IFS='|'
+
+echo "${*#x}"
+echo "${x[*]#x}"
+
+echo "$*"
+echo "${x[*]}"
diff --git a/tests/dollar-star2.sub b/tests/dollar-star2.sub
new file mode 100644
index 0000000..844a297
--- /dev/null
+++ b/tests/dollar-star2.sub
@@ -0,0 +1,26 @@
+set A B
+
+IFS=
+
+x=$*
+y="$*"
+
+recho "$x"
+recho "$y"
+
+IFS=$' \t\n'
+
+set 'A B' 'C D'
+
+IFS=
+
+x=$*
+y="$*"
+
+recho "$x"
+recho "$y"
+
+recho $x
+recho $*
+recho $y
+recho "$*"
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
new file mode 100644
index 0000000..13db8e2
--- /dev/null
+++ b/tests/dollar.right
@@ -0,0 +1,168 @@
+argv[1] = <>
+argv[1] = <a b>
+argv[1] = <ab>
+argv[1] = <a b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <3>
+argv[1] = <bob>
+argv[1] = <tom dick harry>
+argv[1] = <joe>
+argv[1] = <3>
+argv[1] = <bob>
+argv[1] = <tom dick harry>
+argv[1] = <joe>
+argv[1] = <3>
+argv[1] = <bob>
+argv[1] = <tom dick harry>
+argv[1] = <joe>
+argv[1] = <3>
+argv[1] = <bob>
+argv[1] = <tom dick harry>
+argv[1] = <joe>
+argv[1] = <3>
+argv[1] = <bob>
+argv[1] = <tom dick harry>
+argv[1] = <joe>
+argv[1] = <3>
+argv[1] = <bob>
+argv[1] = <tom dick harry>
+argv[1] = <joe>
+argv[1] = <5>
+argv[1] = <bob>
+argv[1] = <tom>
+argv[1] = <dick>
+argv[1] = <5>
+argv[1] = <bob>
+argv[1] = <tom>
+argv[1] = <dick>
+argv[1] = <1>
+argv[1] = <bob>
+argv[2] = <tom>
+argv[3] = <dick>
+argv[4] = <harry>
+argv[5] = <joe>
+argv[1] = <3>
+argv[1] = <bob>
+argv[1] = <tom>
+argv[2] = <dick>
+argv[3] = <harry>
+argv[1] = <joe>
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <c>
+argv[4] = <d>
+argv[5] = <e>
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <c>
+argv[4] = <d>
+argv[5] = <e>
+argv[1] = <foo>
+argv[2] = <bar>
+argv[3] = <bam>
+argv[1] = <foobarbam>
+argv[1] = <foo>
+argv[2] = <bar>
+argv[3] = <bam>
+argv[1] = <foo>
+argv[2] = <bar>
+argv[3] = <bam>
+argv[1] = <foo bar bam>
+foo = 1:2:3:4:5:6:7:8:9:10
+bar = 1:2:3:4:5:6:7:8:9:10
+foo1 = 1 2 3 4 5 6 7 8 9 10
+bar1 = 1 2 3 4 5 6 7 8 9 10
+foo2 = 1:2:3:4:5:6:7:8:9:10
+bar2 = 1:2:3:4:5:6:7:8:9:10
+foo3 = 1:2:3:4:5:6:7:8:9:10
+bar3 = 1:2:3:4:5:6:7:8:9:10
+ok 1
+ok 2
+ok 3
+ok 4
+foo = 1 2 3 4 5 6 7 8 9 10
+bar = 1 2 3 4 5 6 7 8 9 10
+foo1 = 1 2 3 4 5 6 7 8 9 10
+bar1 = 1 2 3 4 5 6 7 8 9 10
+foo2 = 1 2 3 4 5 6 7 8 9 10
+bar2 = 1 2 3 4 5 6 7 8 9 10
+foo3 = 1 2 3 4 5 6 7 8 9 10
+bar3 = 1 2 3 4 5 6 7 8 9 10
+ok 1
+ok 2
+ok 3
+ok 4
+xa|xb|xc
+xa|xb|xc
+a|b|c
+a|b|c
+a b c
+a b c
+xa xb xc
+xa xb xc
+a|b
+b|c
+a b
+b c
+a|b|c
+a|b|c
+xa|xb|xc
+xa|xb|xc
+3
+3
+3
+3
+3
+3
+3
+3
+argv[1] = <echo 1 ; echo 1>
+argv[1] = <echo 1 2 ; echo 1>
+argv[2] = <2>
+argv[1] = <echo 1 ; echo 1>
+argv[1] = <echo 1 2 ; echo 1>
+argv[2] = <2>
+argv[1] = <AB>
+argv[1] = <AB>
+argv[1] = <A BC D>
+argv[1] = <A BC D>
+argv[1] = <A BC D>
+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
new file mode 100644
index 0000000..8f27d28
--- /dev/null
+++ b/tests/dstack.right
@@ -0,0 +1,55 @@
+./dstack.tests: line 6: pushd: /tmp/xxx-notthere: No such file or directory
+./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 [-n] [+N | -N | dir]
+./dstack.tests: line 14: popd: -m: invalid number
+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
+dirs: usage: dirs [-clpv] [+N] [-N]
+/
+ok
+/usr /
+/usr /
+/usr /
+/usr /
+/usr /
+/
+/usr /
+/etc /usr /
+/etc /usr /
+/etc /usr /
+ 0 /etc
+ 1 /usr
+ 2 /
+/usr /etc /
+/etc /usr /
+/tmp /etc /usr /
+/tmp
+/tmp
+/usr
+/usr
+./dstack.tests: line 58: dirs: 9: directory stack index out of range
+./dstack.tests: line 58: dirs: 9: directory stack index out of range
+./dstack.tests: line 59: pushd: +9: directory stack index out of range
+./dstack.tests: line 59: pushd: -9: directory stack index out of range
+./dstack.tests: line 60: popd: +9: directory stack index out of range
+./dstack.tests: line 60: popd: -9: directory stack index out of range
+/tmp /etc /
+/tmp /etc /
+/tmp /etc /
+/tmp /usr /etc /
+/tmp
+/tmp /usr /etc /
+/tmp /usr /etc /
+/tmp
+/tmp /bin /etc /
+/tmp
+/tmp /bin /
+/tmp
+/bin / /tmp
+/bin / /tmp
+/bin
+/bin
diff --git a/tests/dstack.tests b/tests/dstack.tests
new file mode 100644
index 0000000..49b97d3
--- /dev/null
+++ b/tests/dstack.tests
@@ -0,0 +1,87 @@
+export LC_ALL=C
+export LANG=C
+
+dirs -c
+# error -- nonexistant directory
+pushd /tmp/xxx-notthere
+
+# errors -- empty stack
+pushd
+popd
+
+# errors -- bad numeric arguments -- should not cause the script to exit
+pushd -m
+popd -m
+dirs -m
+dirs 7
+
+MYDIR=$PWD
+unalias cd 2>/dev/null
+
+unalias -a
+
+command cd -P /
+command pwd -P # better be `/'
+
+case "$OLDPWD" in
+$MYDIR) echo ok ;;
+*) echo oops -- bad \$OLDPWD ;;
+esac
+
+pushd /usr
+echo $PWD $OLDPWD
+dirs
+echo ${DIRSTACK[@]}
+
+# this should not change the directory stack at all
+pushd -n +0
+dirs
+
+popd
+pushd /usr
+
+pushd /etc
+dirs
+dirs -l
+dirs -v
+
+# two consecutive `pushd's should swap the top two stack elements, then
+# swap them back, leaving the stack intact
+pushd
+pushd
+
+pushd /tmp
+echo ${DIRSTACK[0]} ; dirs +0
+echo ${DIRSTACK[2]} ; dirs +2
+
+# these should be errors, but not affect the directory stack
+dirs +9; dirs -9
+pushd +9 ; pushd -9
+popd +9 ; popd -9
+
+popd -n +2
+dirs
+echo ${DIRSTACK[@]}
+
+pushd -n /usr
+echo $PWD
+dirs
+echo ${DIRSTACK[@]}
+
+builtin pwd
+
+DIRSTACK[1]=/bin
+dirs
+
+builtin pwd
+popd +2
+builtin pwd -L
+pushd -1
+dirs
+echo ${DIRSTACK[0]}
+
+dirs -c
+dirs
+
+# this is for the benefit of pure coverage
+cd "$MYDIR"
diff --git a/tests/dstack2.right b/tests/dstack2.right
new file mode 100644
index 0000000..d682a27
--- /dev/null
+++ b/tests/dstack2.right
@@ -0,0 +1,24 @@
+expect ~1
+~1
+/usr /
+/tmp /usr /
+/tmp /usr /
+these lines should be the same
+/tmp
+/tmp /tmp
+these lines should be the same
+/usr
+/usr /usr
+these lines should be the same
+/
+/ /
+these lines should be the same
+/tmp
+/tmp /tmp
+these lines should be the same
+/usr
+/usr /usr
+ 1 /usr
+these lines should be the same
+/
+/ /
diff --git a/tests/dstack2.tests b/tests/dstack2.tests
new file mode 100644
index 0000000..d902bff
--- /dev/null
+++ b/tests/dstack2.tests
@@ -0,0 +1,33 @@
+cd /
+
+echo expect '~1'
+echo ~1
+
+pushd /usr
+pushd /tmp
+dirs
+
+echo these lines should be the same
+dirs +0
+echo ~0 ${DIRSTACK[0]}
+echo these lines should be the same
+dirs +1
+echo ~1 ${DIRSTACK[1]}
+echo these lines should be the same
+dirs +2
+echo ~2 ${DIRSTACK[2]}
+
+NDIRS=$(( ${#DIRSTACK[@]} - 1 ))
+
+echo these lines should be the same
+dirs -2
+echo ~-2 ${DIRSTACK[NDIRS-2]}
+
+echo these lines should be the same
+dirs -1
+echo ~-1 ${DIRSTACK[NDIRS-1]}
+dirs -v -1
+
+echo these lines should be the same
+dirs -0
+echo ~-0 ${DIRSTACK[NDIRS]}
diff --git a/tests/errors.right b/tests/errors.right
new file mode 100644
index 0000000..ae7bf29
--- /dev/null
+++ b/tests/errors.right
@@ -0,0 +1,101 @@
+./errors.tests: line 17: alias: -x: invalid option
+alias: usage: alias [-p] [name[=value] ... ]
+./errors.tests: line 18: unalias: -x: invalid option
+unalias: usage: unalias [-a] name [name ...]
+./errors.tests: line 19: alias: hoowah: not found
+./errors.tests: line 20: unalias: hoowah: not found
+./errors.tests: line 23: `1': not a valid identifier
+declare -fr func
+./errors.tests: line 36: func: readonly function
+./errors.tests: line 39: unset: -x: invalid option
+unset: usage: unset [-f] [-v] [name ...]
+./errors.tests: line 42: unset: func: cannot unset: readonly function
+./errors.tests: line 45: declare: func: readonly function
+./errors.tests: line 49: unset: XPATH: cannot unset: readonly variable
+./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 [-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] [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
+./errors.tests: line 79: shift: label: numeric argument required
+./errors.tests: line 84: shift: too many arguments
+./errors.tests: line 90: let: expression expected
+./errors.tests: line 93: local: can only be used in a function
+./errors.tests: line 96: logout: not login shell: use `exit'
+./errors.tests: line 99: hash: notthere: not found
+./errors.tests: line 102: hash: -v: invalid option
+hash: usage: hash [-lr] [-p pathname] [-dt] [name ...]
+./errors.tests: line 106: hash: hashing disabled
+./errors.tests: line 109: export: `AA[4]': not a valid identifier
+./errors.tests: line 110: readonly: `AA[4]': not a valid identifier
+./errors.tests: line 113: [-2]: bad array subscript
+./errors.tests: line 117: AA: readonly variable
+./errors.tests: line 121: AA: readonly variable
+./errors.tests: line 129: shift: 5: shift count out of range
+./errors.tests: line 130: shift: -2: shift count out of range
+./errors.tests: line 133: shopt: no_such_option: invalid shell option name
+./errors.tests: line 134: shopt: no_such_option: invalid shell option name
+./errors.tests: line 137: umask: 09: octal number out of range
+./errors.tests: line 138: umask: `:': invalid symbolic mode character
+./errors.tests: line 139: umask: `:': invalid symbolic mode operator
+./errors.tests: line 142: umask: -i: invalid option
+umask: usage: umask [-p] [-S] [mode]
+./errors.tests: line 146: umask: `u': invalid symbolic mode character
+./errors.tests: line 155: VAR: readonly variable
+./errors.tests: line 158: declare: VAR: readonly variable
+./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 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
+./errors.tests: line 175: cd: /bin/sh: Not a directory
+./errors.tests: line 177: cd: /tmp/cd-notthere: No such file or directory
+./errors.tests: line 180: .: filename argument required
+.: usage: . filename [arguments]
+./errors.tests: line 181: source: filename argument required
+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-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
+./errors.tests: line 196: read: var: invalid timeout specification
+./errors.tests: line 199: read: `/bin/sh': not a valid identifier
+./errors.tests: line 202: VAR: readonly variable
+./errors.tests: line 205: readonly: -x: invalid option
+readonly: usage: readonly [-af] [name[=value] ...] or readonly -p
+./errors.tests: line 208: eval: -i: invalid option
+eval: usage: eval [arg ...]
+./errors.tests: line 209: command: -i: invalid option
+command: usage: command [-pVv] command [arg ...]
+./errors.tests: line 212: /bin/sh + 0: syntax error: operand expected (error token is "/bin/sh + 0")
+./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 ...]
+./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
+./errors.tests: line 238: builtin: bash: not a shell builtin
+./errors.tests: line 242: bg: no job control
+./errors.tests: line 243: fg: no job control
+./errors.tests: line 246: kill: -s: option requires an argument
+./errors.tests: line 248: kill: S: invalid signal specification
+./errors.tests: line 250: kill: `': not a pid or valid job spec
+kill: usage: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
+./errors.tests: line 255: set: trackall: invalid option name
+./errors.tests: line 262: `!!': not a valid identifier
diff --git a/tests/errors.tests b/tests/errors.tests
new file mode 100644
index 0000000..4ead467
--- /dev/null
+++ b/tests/errors.tests
@@ -0,0 +1,265 @@
+# These should all be safe
+LC_ALL=C
+LC_CTYPE=C
+LC_COLLATE=C
+LC_MESSAGES=C
+
+# these tests should all generate errors
+
+# make sure we don't exit prematurely
+set +e
+set +o posix
+
+# various alias/unalias errors
+
+# at some point, this may mean to `export' an alias, like ksh, but
+# for now it is an error
+alias -x foo=barz
+unalias -x fooaha
+alias hoowah
+unalias hoowah
+
+# the iteration variable must be a valid identifier
+for 1 in a b c; do echo $1; done
+
+# try to rebind a read-only function
+func()
+{
+ echo func
+}
+readonly -f func
+# make sure `readonly' and `declare' play well together
+declare -Fr
+func()
+{
+ echo bar
+}
+
+# bad option
+unset -x func
+
+# cannot unset readonly functions or variables
+unset -f func
+# or make them not readonly
+declare -fr func
+declare -f +r func
+
+XPATH=$PATH
+declare -r XPATH
+unset -v XPATH
+
+# cannot unset invalid identifiers
+unset /bin/sh
+
+# cannot unset function and variable at the same time
+unset -f -v SHELL
+
+# bad option
+declare -z
+# cannot declare invalid identifiers
+declare -- -z
+declare /bin/sh
+
+# this is the syntax used to export functions in the environment, but
+# it cannot be used with `declare'
+declare -f func='() { echo "this is func"; }'
+
+# bad option to exec -- this should not exit the script
+exec -i /bin/sh
+
+# try to export -f something that is not a function -- this should be
+# an error, not create an `invisible function'
+export -f XPATH
+
+# this depends on the setting of BREAK_COMPLAINS in config.h.in
+break
+continue
+
+# this should not exit the shell; it did in versions before 2.01
+shift label
+
+# other shells do not complain about the extra arguments; maybe someday
+# we won't either
+set -- a b c
+shift $# label
+# and get rid of the positional parameters
+shift $#
+
+# let without an expression is an error, though maybe it should just return
+# success
+let
+
+# local outside a function is an error
+local
+
+# logout of a non-login shell is an error
+logout
+
+# try to hash a non-existant command
+hash notthere
+
+# bad option to hash, although it may mean `verbose' at some future point
+hash -v
+
+# turn off hashing, then try to hash something
+set +o hashall
+hash -p ${THIS_SH} ${THIS_SH##*/}
+
+# bad identifiers to declare/readonly/export
+export AA[4]
+readonly AA[4]
+
+declare -a AA
+unset AA[-2]
+
+# try to assign to a readonly array
+declare -r AA
+AA=( one two three )
+
+# make sure `readonly -n' doesn't turn off readonly status
+readonly -n AA
+AA=(one two three)
+
+# try to assign a readonly array with bad assignment syntax
+# NOTE: this works in post-bash-2.05 (at least when I write this)
+# readonly -a ZZZ=bbb
+
+# bad counts to `shift'
+shopt -s shift_verbose
+shift $(( $# + 5 ))
+shift -2
+
+# bad shell options
+shopt -s no_such_option
+shopt no_such_option
+
+# non-octal digits for umask and other errors
+umask 09
+umask -S u=rwx:g=rwx:o=rx >/dev/null # 002
+umask -S u:rwx,g:rwx,o:rx >/dev/null # 002
+
+# at some point, this may mean `invert', but for now it is an error
+umask -i
+
+# bad assignments shouldn't change the umask
+mask=$(umask)
+umask g=u
+mask2=$(umask)
+if [ "$mask" != "$mask2" ]; then
+ echo "umask errors change process umask"
+fi
+
+# assignment to a readonly variable in environment
+VAR=4
+readonly VAR
+VAR=7 :
+
+# more readonly variable tests
+declare VAR=88
+declare +r VAR
+
+declare -p unset
+
+# iteration variable in a for statement being readonly
+for VAR in 1 2 3 ; do echo $VAR; done
+
+# parser errors
+: $( for z in 1 2 3; do )
+: $( for z in 1 2 3; done )
+
+# various `cd' errors
+( unset HOME ; cd )
+( HOME=/tmp/xyz.bash ; cd )
+# errors from cd
+cd -
+cd /bin/sh # error - not a directory
+OLDPWD=/tmp/cd-notthere
+cd -
+
+# various `source/.' errors
+.
+source
+
+# maybe someday this will work like in rc
+. -i /dev/tty
+
+# make sure that this gives an error rather than setting $1
+set -q
+
+# enable non-builtins
+enable sh bash
+
+# try to set and unset shell options simultaneously
+shopt -s -u checkhash
+
+# this is an error -- bad timeout spec
+read -t var < /dev/null
+
+# try to read into an invalid identifier
+read /bin/sh < /dev/null
+
+# try to read into a readonly variable
+read VAR < /dev/null
+
+# bad option to readonly/export
+readonly -x foo
+
+# someday these may mean something, but for now they're errors
+eval -i "echo $-"
+command -i "echo $-"
+
+# this caused a core dump in bash-2.01 (fixed in bash-2.01.1)
+eval echo \$[/bin/sh + 0]
+eval echo '$((/bin/sh + 0))'
+
+# error to list trap for an unknown signal
+trap -p NOSIG
+
+# maybe someday trap will take a -s argument like kill, but not now
+trap -p -s NOSIG
+
+# we have a ksh-like ERR trap, post-bash-2.05
+#trap 'echo [$LINENO] -- error' ERR
+
+# can only return from a function or sourced script
+return 2
+
+# break and continue with arguments <= 0
+for z in 1 2 3; do
+ break 0
+ echo $x
+done
+for z in 1 2 3; do
+ continue 0
+ echo $x
+done
+
+# builtin with non-builtin
+builtin bash
+
+# maybe someday you will be able to use fg/bg when job control is not really
+# active, but for now they are errors
+bg
+fg
+
+# argument required
+kill -s
+# bad argument
+kill -S
+# null argument
+kill -INT ''
+# argument required
+kill -INT
+
+# bad shell option names
+set -o trackall # bash is not ksh
+
+# this must be last!
+# in posix mode, a function name must be a valid identifier
+# this can't go in posix2.tests, since it causes the shell to exit
+# immediately
+set -o posix
+function !! () { fc -s "$@" ; }
+set +o posix
+
+echo end
diff --git a/tests/exec.right b/tests/exec.right
new file mode 100644
index 0000000..86a099c
--- /dev/null
+++ b/tests/exec.right
@@ -0,0 +1,55 @@
+before exec1.sub: one two three
+calling exec1.sub
+aa bb cc dd ee
+after exec1.sub with args: 0
+
+after exec1.sub without args: 0
+./execscript: line 20: notthere: command not found
+127
+/tmp/bash: notthere: No such file or directory
+127
+/bin/sh: /bin/sh: cannot execute binary file
+126
+./execscript: line 39: /: is a directory
+126
+/: /: is a directory
+126
+./execscript: line 46: .: /: is a directory
+1
+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 70: notthere: No such file or directory
+127
+./execscript: line 73: notthere: No such file or directory
+127
+./execscript: line 76: notthere: command not found
+127
+this is sh
+this is sh
+unset
+ok
+5
+./exec5.sub: line 4: exec: bash-notthere: not found
+127
+this is ohio-state
+0
+1
+1
+0
+42
+42
+0
+1
+1
+0
+0
+1
+0
+1
+testb
+expand_aliases on
+after
diff --git a/tests/exec1.sub b/tests/exec1.sub
new file mode 100755
index 0000000..4a12501
--- /dev/null
+++ b/tests/exec1.sub
@@ -0,0 +1 @@
+echo "$@"
diff --git a/tests/exec2.sub b/tests/exec2.sub
new file mode 100644
index 0000000..c1caaea
--- /dev/null
+++ b/tests/exec2.sub
@@ -0,0 +1,5 @@
+# make sure an exit command in an exit trap sets the shell's exit status
+trap - 0
+trap 'exit 5' 0
+
+exit 0
diff --git a/tests/exec3.sub b/tests/exec3.sub
new file mode 100644
index 0000000..4f2f8e2
--- /dev/null
+++ b/tests/exec3.sub
@@ -0,0 +1,6 @@
+shopt -s execfail
+
+exec /tmp/bash-notthere
+# make sure we're still around
+echo $?
+
diff --git a/tests/exec4.sub b/tests/exec4.sub
new file mode 100644
index 0000000..a60d8b3
--- /dev/null
+++ b/tests/exec4.sub
@@ -0,0 +1,8 @@
+# let's test out the noexec code
+set -n
+
+fail
+whoops
+wow
+
+set +n
diff --git a/tests/exec5.sub b/tests/exec5.sub
new file mode 100644
index 0000000..1462f9e
--- /dev/null
+++ b/tests/exec5.sub
@@ -0,0 +1,9 @@
+# try exec'ing a command that cannot be found in $PATH
+shopt -s execfail
+
+exec bash-notthere
+# make sure we're still around
+echo $?
+
+# now we need to go away, but this should echo 'this is ohio-state'
+exec -a ohio-state ${THIS_SH} -c 'echo this is $0'
diff --git a/tests/exec6.sub b/tests/exec6.sub
new file mode 100644
index 0000000..50d0e70
--- /dev/null
+++ b/tests/exec6.sub
@@ -0,0 +1,54 @@
+# builtins with exit status inverted
+
+( true )
+echo $?
+( ! true )
+echo $?
+
+( false )
+echo $?
+( ! false )
+echo $?
+
+# inverting shouldn't affect exit
+(exit 42)
+echo $?
+
+( ! exit 42 )
+echo $?
+
+# commands requiring an exec with exit status inverted -- broken in bash-2.04
+
+( ls > /dev/null 2>&1 )
+echo $?
+( ! ls > /dev/null 2>&1 )
+echo $?
+
+touch /tmp/notwrite
+chmod 400 /tmp/notwrite
+
+# make sure redirection failures in commands whose exit status is inverted
+# are handled correctly
+
+( ls > /tmp/notwrite ) 2>/dev/null
+echo $?
+
+( ! ls > /tmp/notwrite ) 2>/dev/null
+echo $?
+
+# now add exit traps, true and false for commands with and without exit
+# status inversion
+
+(trap 'false' 0 ; ! ls > /tmp/notwrite ) 2>/dev/null
+echo $?
+
+(trap 'false' 0 ; ls > /tmp/notwrite ) 2>/dev/null
+echo $?
+
+(trap 'true' 0 ; ! ls > /tmp/notwrite ) 2>/dev/null
+echo $?
+
+(trap 'true' 0 ; ls > /tmp/notwrite ) 2>/dev/null
+echo $?
+
+rm -f /tmp/notwrite
diff --git a/tests/exec7.sub b/tests/exec7.sub
new file mode 100644
index 0000000..ea2fd06
--- /dev/null
+++ b/tests/exec7.sub
@@ -0,0 +1,20 @@
+# make sure that bash really checks the right things when deciding what
+# constitutes an executable file
+
+[ $UID -eq 0 ] && { echo "exec7.sub: the test suite should not be run as root" >&2 ; }
+
+: ${TMPDIR:=/tmp}
+
+cd $TMPDIR || { echo "cannot cd to $TMPDIR" >&2 ; exit 2; }
+
+mkdir testa testb
+
+echo 'echo "testa"' > testa/foo
+echo 'echo "testb"' > testb/foo
+
+chmod 655 testa/foo
+chmod 755 testb/foo
+
+PATH=$TMPDIR/testa:$TMPDIR/testb $THIS_SH -c foo
+
+rm -rf testa testb
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
new file mode 100644
index 0000000..3629c57
--- /dev/null
+++ b/tests/execscript
@@ -0,0 +1,114 @@
+export LC_ALL=C
+export LANG=C
+
+if [ $UID -eq 0 ]; then
+ echo "execscript: the test suite should not be run as root" >&2
+fi
+
+set -- one two three
+echo before exec1.sub: "$@"
+echo calling exec1.sub
+./exec1.sub aa bb cc dd ee
+echo after exec1.sub with args: $?
+./exec1.sub
+echo after exec1.sub without args: $?
+
+# set up a fixed path so we know notthere will not be found
+PATH=/usr/bin:/bin:/usr/local/bin:
+export PATH
+
+notthere
+echo $?
+
+# this is iffy, since the error messages may vary from system to system
+# and /tmp might not exist
+ln -s ${THIS_SH} /tmp/bash 2>/dev/null
+if [ -f /tmp/bash ]; then
+ /tmp/bash notthere
+else
+ ${THIS_SH} notthere
+fi
+echo $?
+rm -f /tmp/bash
+
+# /bin/sh should be there on all systems
+${THIS_SH} /bin/sh
+echo $?
+
+# try executing a directory
+/
+echo $?
+
+${THIS_SH} /
+echo $?
+
+# try sourcing a directory
+. /
+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 $?
+
+# post-bash-2.05 versions allow sourcing non-regular files
+. /dev/null
+echo $?
+
+# kill two birds with one test -- test out the BASH_ENV code
+echo echo this is bashenv > /tmp/bashenv
+export BASH_ENV=/tmp/bashenv
+${THIS_SH} ./exec3.sub
+rm -f /tmp/bashenv
+unset BASH_ENV
+
+# we're resetting the $PATH to empty, so this should be last
+PATH=
+
+notthere
+echo $?
+
+command notthere
+echo $?
+
+command -p notthere
+echo $?
+
+# but -p should guarantee that we find all the standard utilities, even
+# with an empty or unset $PATH
+command -p sh -c 'echo this is $0'
+unset PATH
+command -p sh -c 'echo this is $0'
+
+# a bug in bash before bash-2.01 caused PATH to be set to the empty string
+# when command -p was run with PATH unset
+echo ${PATH-unset}
+
+echo "echo ok" | ${THIS_SH} -t
+
+${THIS_SH} ./exec2.sub
+echo $?
+
+${THIS_SH} ./exec4.sub
+
+# try exec'ing a command that cannot be found in $PATH
+${THIS_SH} ./exec5.sub
+
+# this was a bug in bash versions before bash-2.04
+${THIS_SH} -c 'cat </dev/null | cat >/dev/null' >&-
+
+# checks for proper return values in subshell commands with inverted return
+# values
+
+${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
new file mode 100644
index 0000000..d46a2a1
--- /dev/null
+++ b/tests/exp.right
@@ -0,0 +1,168 @@
+argv[1] = <^A>
+argv[1] = <^A>
+argv[1] = <^B>
+argv[1] = <^B>
+argv[1] = <^A>
+argv[1] = <^B>
+argv[1] = <abcdefgh>
+argv[1] = <abcdefgh>
+argv[1] = <abcdefgh>
+argv[1] = <abcdefgh>
+argv[1] = <abcd>
+argv[1] = <abcd>
+argv[1] = < >
+argv[1] = <-->
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <abc>
+argv[1] = <abc>
+argv[1] = <abc>
+argv[1] = <abc>
+argv[1] = <abcdef>
+argv[1] = <abcdef>
+argv[1] = <^A>
+argv[1] = <^B>
+argv[1] = <^A>
+argv[1] = <^B>
+argv[1] = <^A>
+argv[1] = <^B>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <Hello world!>
+argv[1] = <`>
+argv[1] = <">
+argv[1] = <\^A>
+argv[1] = <\$>
+argv[1] = <\\>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <^A>
+argv[2] = <^B>
+argv[1] = <**>
+argv[1] = <\.\./*/>
+argv[1] = <^A^B^A^B>
+argv[1] = <^A^A>
+argv[1] = <^A^B>
+argv[1] = <^A^A^B>
+argv[1] = < abc>
+argv[2] = <def>
+argv[3] = <ghi>
+argv[4] = <jkl >
+argv[1] = < abc>
+argv[2] = <def>
+argv[3] = <ghi>
+argv[4] = <jkl >
+argv[1] = <--abc>
+argv[2] = <def>
+argv[3] = <ghi>
+argv[4] = <jkl-->
+argv[1] = <a b>
+argv[2] = <cd>
+argv[3] = <ef>
+argv[4] = <gh>
+argv[1] = <a b>
+argv[2] = <cd>
+argv[3] = <ef>
+argv[4] = <gh>
+argv[1] = <a b>
+argv[2] = <cd>
+argv[3] = <ef>
+argv[4] = <gh>
+argv[1] = < >
+argv[1] = < - >
+argv[1] = </^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/>
+argv[1] = <foo bar>
+argv[1] = <foo>
+argv[2] = <bar>
+argv[1] = <abc>
+argv[1] = <abc>
+argv[1] = <posix>
+argv[1] = <10>
+argv[1] = <file.o>
+argv[1] = <posix>
+argv[1] = </src/cmd>
+argv[1] = <three>
+argv[1] = <abcdef>
+argv[1] = <abcdef>
+argv[1] = <abcdef>
+argv[1] = <abcdef>
+argv[1] = <\$x>
+argv[1] = <$x>
+argv[1] = <\$x>
+argv[1] = <abc>
+argv[2] = <def>
+argv[3] = <ghi>
+argv[4] = <jkl>
+argv[1] = <abc def ghi jkl>
+argv[1] = <abc:def ghi:jkl>
+argv[1] = <abc>
+argv[2] = <def ghi>
+argv[3] = <jkl>
+argv[1] = <xxabc>
+argv[2] = <def ghi>
+argv[3] = <jklyy>
+argv[1] = <abc>
+argv[2] = <def ghi>
+argv[3] = <jklabc>
+argv[4] = <def ghi>
+argv[5] = <jkl>
+argv[1] = <abcdef>
+argv[1] = <bar>
+argv[2] = <>
+argv[3] = <xyz>
+argv[4] = <>
+argv[5] = <abc>
+argv[1] = <$foo>
+argv[1] = <10>
+argv[1] = <newline expected>
+argv[1] = <got it>
+argv[1] = <got it>
+argv[1] = <one>
+argv[2] = <three>
+argv[3] = <five>
+argv[1] = <5>
+argv[2] = <5>
+argv[1] = <3>
+argv[1] = <1>
+argv[1] = <1>
+argv[1] = <5>
+argv[1] = <5>
+argv[1] = <5>
+argv[1] = <5>
+argv[1] = <42>
+argv[1] = <26>
+argv[1] = <\>
+argv[1] = <~>
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <c>
+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
new file mode 100644
index 0000000..1f4a35b
--- /dev/null
+++ b/tests/exp.tests
@@ -0,0 +1,386 @@
+#
+# A suite of tests for bash word expansions
+#
+# This tests parameter and variable expansion, with an empahsis on
+# proper quoting behavior.
+#
+# Chet Ramey
+
+#
+# If you comment out the body of this function, you can do a diff against
+# `expansion-tests.right' to see if the shell is behaving correctly
+#
+expect()
+{
+ echo expect "$@"
+}
+
+# Test the substitution quoting characters (CTLESC and CTLNUL) in different
+# combinations
+
+expect "<^A>"
+recho `echo ''`
+expect "<^A>"
+recho `echo ""`
+expect "<^B>"
+recho `echo ''`
+expect "<^B>"
+recho `echo ""`
+expect "<^A>"
+recho `echo `
+expect "<^B>"
+recho `echo `
+
+# Test null strings without variable expansion
+expect "<abcdefgh>"
+recho abcd""efgh
+expect "<abcdefgh>"
+recho abcd''efgh
+expect "<abcdefgh>"
+recho ""abcdefgh
+expect "<abcdefgh>"
+recho ''abcdefgh
+expect "<abcd>"
+recho abcd""
+expect "<abcd>"
+recho abcd''
+
+# Test the quirky behavior of $@ in ""
+expect nothing
+recho "$@"
+expect "< >"
+recho " $@"
+expect "<-->"
+recho "-${@}-"
+
+# Test null strings with variable expansion that fails
+expect '<>'
+recho $xxx""
+expect '<>'
+recho ""$xxx
+expect '<>'
+recho $xxx''
+expect '<>'
+recho ''$xxx
+expect '<>'
+recho $xxx""$yyy
+expect '<>'
+recho $xxx''$yyy
+
+# Test null strings with variable expansion that succeeds
+xxx=abc
+yyy=def
+
+expect '<abc>'
+recho $xxx""
+expect '<abc>'
+recho ""$xxx
+expect '<abc>'
+recho $xxx''
+expect '<abc>'
+recho ''$xxx
+expect '<abcdef>'
+recho $xxx""$yyy
+expect '<abcdef>'
+recho $xxx''$yyy
+
+unset xxx yyy
+
+# Test the unquoted special quoting characters
+expect "<^A>"
+recho 
+expect "<^B>"
+recho 
+expect "<^A>"
+recho ""
+expect "<^B>"
+recho ""
+expect "<^A>"
+recho ''
+expect "<^B>"
+recho ''
+
+# Test expansion of a variable that is unset
+expect nothing
+recho $xxx
+expect '<>'
+recho "$xxx"
+
+expect nothing
+recho "$xxx${@}"
+
+# Test empty string expansion
+expect '<>'
+recho ""
+expect '<>'
+recho ''
+
+# Test command substitution with (disabled) history substitution
+expect '<Hello World!>'
+# set +H
+recho "`echo \"Hello world!\"`"
+
+# Test some shell special characters
+expect '<`>'
+recho "\`"
+expect '<">'
+recho "\""
+expect '<\^A>'
+recho "\"
+
+expect '<\$>'
+recho "\\$"
+
+expect '<\\>'
+recho "\\\\"
+
+# This should give argv[1] = a argv[2] = b
+expect '<a> <b>'
+FOO=`echo 'a b' | tr ' ' '\012'`
+recho $FOO
+
+# This should give argv[1] = ^A argv[2] = ^B
+expect '<^A> <^B>'
+FOO=`echo ' ' | tr ' ' '\012'`
+recho $FOO
+
+# Test quoted and unquoted globbing characters
+expect '<**>'
+recho "*"*
+
+expect '<\.\./*/>'
+recho "\.\./*/"
+
+# Test patterns that come up when the shell quotes funny character
+# combinations
+expect '<^A^B^A^B>'
+recho ''
+expect '<^A^A>'
+recho ''
+expect '<^A^B>'
+recho ''
+expect '<^A^A^B>'
+recho ''
+
+# More tests of "$@"
+set abc def ghi jkl
+expect '< abc> <def> <ghi> <jkl >'
+recho " $@ "
+expect '< abc> <def> <ghi> <jkl >'
+recho "${1+ $@ }"
+
+set abc def ghi jkl
+expect '<--abc> <def> <ghi> <jkl-->'
+recho "--$@--"
+
+set "a b" cd ef gh
+expect '<a b> <cd> <ef> <gh>'
+recho ${1+"$@"}
+expect '<a b> <cd> <ef> <gh>'
+recho ${foo:-"$@"}
+expect '<a b> <cd> <ef> <gh>'
+recho "${@}"
+
+expect '< >'
+recho " "
+expect '< - >'
+recho " - "
+
+# Test combinations of different types of quoting in a fully-quoted string
+# (so the WHOLLY_QUOTED tests fail and it doesn't get set)
+expect '</^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/>'
+recho "/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*"'$'"/\1/"
+
+# Test the various Posix parameter expansions
+
+expect '<foo bar>'
+recho "${x:-$(echo "foo bar")}"
+expect '<foo> <bar>'
+recho ${x:-$(echo "foo bar")}
+
+unset X
+expect '<abc>'
+recho ${X:=abc}
+expect '<abc>'
+recho $X
+
+set a b c
+expect '<posix>'
+recho ${3:+posix}
+
+POSIX=/usr/posix
+expect '<10>'
+recho ${#POSIX}
+
+# remove shortest trailing match
+x=file.c
+expect '<file.o>'
+recho ${x%.c}.o
+
+# remove longest trailing match
+x=posix/src/std
+expect '<posix>'
+recho ${x%%/*}
+
+# remove shortest leading pattern
+x=$HOME/src/cmd
+expect '</src/cmd>'
+recho ${x#$HOME}
+
+# remove longest leading pattern
+x=/one/two/three
+expect '<three>'
+recho ${x##*/}
+
+# pattern removal of patterns that don't match
+z=abcdef
+
+expect '<abcdef>'
+recho ${z#xyz}
+expect '<abcdef>'
+recho ${z##xyz}
+
+expect '<abcdef>'
+recho ${z%xyz}
+expect '<abcdef>'
+recho ${z%%xyz}
+
+# Command substitution and the quirky differences between `` and $()
+
+expect '<\$x>'
+recho '\$x'
+
+expect '<$x>'
+recho `echo '\$x'`
+
+expect '<\$x>'
+recho $(echo '\$x')
+
+# The difference between $* "$*" and "$@"
+
+set "abc" "def ghi" "jkl"
+
+expect '<abc> <def> <ghi> <jkl>'
+recho $*
+
+expect '<abc def ghi jkl>'
+recho "$*"
+
+OIFS="$IFS"
+IFS=":$IFS"
+
+# The special behavior of "$*", using the first character of $IFS as separator
+expect '<abc:def ghi:jkl>'
+recho "$*"
+
+IFS="$OIFS"
+
+expect '<abc> <def ghi> <jkl>'
+recho "$@"
+
+expect '<xxabc> <def ghi> <jklyy>'
+recho "xx$@yy"
+
+expect '<abc> <def ghi> <jklabc> <def ghi> <jkl>'
+recho "$@$@"
+
+foo=abc
+bar=def
+
+expect '<abcdef>'
+recho "$foo""$bar"
+
+unset foo
+set $foo bar '' xyz "$foo" abc
+
+expect '<bar> <> <xyz> <> <abc>'
+recho "$@"
+
+# More tests of quoting and deferred evaluation
+
+foo=10 x=foo
+y='$'$x
+expect '<$foo>'
+recho $y
+eval y='$'$x
+expect '<10>'
+recho $y
+
+# case statements
+
+NL='
+'
+x='ab
+cd'
+
+expect '<newline expected>'
+case "$x" in
+*$NL*) recho "newline expected" ;;
+esac
+
+expect '<got it>'
+case \? in
+*"?"*) recho "got it" ;;
+esac
+
+expect '<got it>'
+case \? in
+*\?*) recho "got it" ;;
+esac
+
+set one two three four five
+expect '<one> <three> <five>'
+recho $1 $3 ${5} $8 ${9}
+
+# length tests on positional parameters and some special parameters
+
+expect '<5> <5>'
+recho $# ${#}
+expect '<3>'
+recho ${#1}
+expect '<1>'
+recho ${##}
+expect '<1>'
+recho ${#?}
+expect '<5>'
+recho ${#@}
+expect '<5>'
+recho ${#*}
+expect '<5>'
+recho "${#@}"
+expect '<5>'
+recho "${#*}"
+
+expect '<42>'
+recho $((28 + 14))
+expect '<26>'
+recho $[ 13 * 2 ]
+
+expect '<\>'
+recho `echo \\\\`
+
+expect '<~>'
+recho '~'
+
+expect nothing
+recho $!
+expect nothing
+recho ${!}
+
+# test word splitting of assignment statements not preceding a command
+a="a b c d e"
+declare b=$a
+expect '<a> <b> <c> <d> <e>'
+recho $b
+
+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
new file mode 100644
index 0000000..7b9cc94
--- /dev/null
+++ b/tests/extglob.right
@@ -0,0 +1,90 @@
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+ok 6
+ok 7
+ok 8
+ok 9
+ok 10
+ok 11
+ok 12
+ok 13
+ok 14
+ok 15
+ok 16
+ok 17
+ok 18
+ok 19
+ok 20
+ok 21
+ok 22
+ok 23
+ok 24
+ok 25
+ok 26
+ok 27
+ok 28
+ok 29
+ok 30
+ok 31
+ok 32
+ok 33
+ok 34
+ok 35
+ok 36
+!([*)*
++(a|b[)*
+[a*(]*)z
++()c
++()x
+abc
++(*)x
+abc
+no-file+(a|b)stuff
+no-file+(a*(c)|b)stuff
+abd acd
+acd
+abd
+no
+yes
+yes
+1: bcdef
+2: def
+3: abcde
+4: abc
+5: ef
+6: ef
+7: abcdef
+ab abef
+abcfef abef
+abcdef
+ab abcdef abcfef abef
+abcdef abcfef abef
+ok 37
+ok 38
+ok 39
+ok 40
+ok 41
+ok 42
+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
+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
+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
+a.c
+a.c
+a.c
+ok 1
+ok 2
+ok 3
diff --git a/tests/extglob.tests b/tests/extglob.tests
new file mode 100644
index 0000000..f9c17c7
--- /dev/null
+++ b/tests/extglob.tests
@@ -0,0 +1,371 @@
+# test the ksh-like extended globbing features: [!@*?+](patlist)
+
+shopt -s extglob
+
+expect()
+{
+ echo expect "$@"
+}
+
+case "/dev/udp/129.22.8.102/45" in
+/dev/@(tcp|udp)/*/*) echo ok 1;;
+*) echo bad 1;;
+esac
+
+# valid numbers
+case 12 in
+0|[1-9]*([0-9])) echo ok 2;;
+*) echo bad 2;;
+esac
+
+case 12abc in
+0|[1-9]*([0-9])) echo bad 3;;
+*) echo ok 3;;
+esac
+
+case 1 in
+0|[1-9]*([0-9])) echo ok 4;;
+*) echo bad 4;;
+esac
+
+# octal numbers
+case 07 in
++([0-7])) echo ok 5;;
+*) echo bad 5;;
+esac
+
+case 0377 in
++([0-7])) echo ok 6;;
+*) echo bad 6;;
+esac
+
+case 09 in
++([0-7])) echo bad 7;;
+*) echo ok 7;;
+esac
+
+# stuff from korn's book
+case paragraph in
+para@(chute|graph)) echo ok 8;;
+*) echo bad 8;;
+esac
+
+case paramour in
+para@(chute|graph)) echo bad 9;;
+*) echo ok 9;;
+esac
+
+case para991 in
+para?([345]|99)1) echo ok 10;;
+*) echo bad 10;;
+esac
+
+case para381 in
+para?([345]|99)1) echo bad 11;;
+*) echo ok 11;;
+esac
+
+case paragraph in
+para*([0-9])) echo bad 12;;
+*) echo ok 12;;
+esac
+
+case para in
+para*([0-9])) echo ok 13;;
+*) echo bad 13;;
+esac
+
+case para13829383746592 in
+para*([0-9])) echo ok 14;;
+*) echo bad 14;;
+esac
+
+case paragraph in
+para*([0-9])) echo bad 15;;
+*) echo ok 15;;
+esac
+
+case para in
+para+([0-9])) echo bad 16;;
+*) echo ok 16;;
+esac
+
+case para987346523 in
+para+([0-9])) echo ok 17;;
+*) echo bad 17;;
+esac
+
+case paragraph in
+para!(*.[0-9])) echo ok 18;;
+*) echo bad 18;;
+esac
+
+case para.38 in
+para!(*.[0-9])) echo ok 19;;
+*) echo bad 19;;
+esac
+
+case para.graph in
+para!(*.[0-9])) echo ok 20;;
+*) echo bad 20;;
+esac
+
+case para39 in
+para!(*.[0-9])) echo ok 21;;
+*) echo bad 21;;
+esac
+
+# tests derived from those in rosenblatt's korn shell book
+
+case "" in
+*(0|1|3|5|7|9)) echo ok 22;;
+*) echo bad 22;
+esac
+
+case 137577991 in
+*(0|1|3|5|7|9)) echo ok 23;;
+*) echo bad 23;
+esac
+
+case 2468 in
+*(0|1|3|5|7|9)) echo bad 24;;
+*) echo ok 24;
+esac
+
+case file.c in
+*.c?(c)) echo ok 25;;
+*) echo bad 25;;
+esac
+
+case file.C in
+*.c?(c)) echo bad 26;;
+*) echo ok 26;;
+esac
+
+case file.cc in
+*.c?(c)) echo ok 27;;
+*) echo bad 27;;
+esac
+
+case file.ccc in
+*.c?(c)) echo bad 28;;
+*) echo ok 28;;
+esac
+
+case parse.y in
+!(*.c|*.h|Makefile.in|config*|README)) echo ok 29;;
+*) echo bad 29;;
+esac
+
+case shell.c in
+!(*.c|*.h|Makefile.in|config*|README)) echo bad 30;;
+*) echo ok 30;;
+esac
+
+case Makefile in
+!(*.c|*.h|Makefile.in|config*|README)) echo ok 31;;
+*) echo bad 31;;
+esac
+
+case "VMS.FILE;1" in
+*\;[1-9]*([0-9])) echo ok 32;;
+*) echo bad 32;;
+esac
+
+case "VMS.FILE;0" in
+*\;[1-9]*([0-9])) echo bad 33;;
+*) echo ok 33;;
+esac
+case "VMS.FILE;" in
+*\;[1-9]*([0-9])) echo bad 34;;
+*) echo ok 34;;
+esac
+case "VMS.FILE;139" in
+*\;[1-9]*([0-9])) echo ok 35;;
+*) echo bad 35;;
+esac
+case "VMS.FILE;1N" in
+*\;[1-9]*([0-9])) echo bad 36;;
+*) echo ok 36;;
+esac
+
+# tests derived from the pd-ksh test suite
+
+MYDIR=$PWD # save where we are
+
+: ${TMPDIR:=/var/tmp}
+TESTDIR=$TMPDIR/eglob-test-$$
+mkdir $TESTDIR
+builtin cd $TESTDIR || { echo $0: cannot cd to $TESTDIR >&2 ; exit 1; }
+rm -rf *
+
+touch abcx abcz bbc
+expect '!([*)*'
+echo !([*)*
+
+expect '+(a|b[)*'
+echo +(a|b[)*
+
+expect '[a*(]*z'
+echo [a*(]*)z
+
+rm -f abcx abcz bbc
+
+touch abc
+
+expect '+()c'
+echo +()c
+expect '+()x'
+echo +()x
+expect abc
+echo +(*)c
+expect '+(*)x'
+echo +(*)x
+
+# extended globbing should not be performed on the output of substitutions
+x='@(*)'
+expect '@(*)'
+echo $x
+
+expect 'no-file+(a|b)stuff'
+echo no-file+(a|b)stuff
+expect 'no-file+(a*(c)|b)stuff'
+echo no-file+(a*(c)|b)stuff
+
+touch abd acd
+
+expect 'abd acd'
+echo a+(b|c)d
+
+expect 'acd'
+echo a!(@(b|B))d
+
+expect 'abd'
+echo a[b*(foo|bar)]d
+
+# simple kleene star tests
+expect no
+case foo in *(a|b[)) echo yes;; *) echo no;; esac
+
+expect yes
+case foo in *(a|b[)|f*) echo yes;; *) echo no;; esac
+
+# this doesn't work right yet; it is an incorrectly formed pattern
+expect yes
+case '*(a|b[)' in *(a|b[)) echo yes;; *) echo no;; esac
+
+# check extended globbing in pattern removal -- these don't work right yet
+x=abcdef
+
+expect '1: bcdef'
+echo 1: ${x#+(a|abc)}
+expect '2: def'
+echo 2: ${x##+(a|abc)}
+expect '3: abcde'
+echo 3: ${x%+(def|f)}
+expect '4: abc'
+echo 4: ${x%%+(f|def)}
+
+# these work ok
+
+expect '5: ef'
+echo 5: ${x#*(a|b)cd}
+expect '6: ef'
+echo 6: "${x#*(a|b)cd}"
+expect '7: abcdef'
+echo 7: ${x#"*(a|b)cd"}
+
+# More tests derived from a bug report concerning extended glob patterns
+# following a *
+builtin cd $TESTDIR || { echo $0: cannot cd to $TESTDIR >&2 ; exit 1; }
+rm -rf *
+
+touch ab abcdef abef abcfef
+
+expect 'ab abef'
+echo ab*(e|f)
+
+expect 'abcfef abef'
+echo ab?*(e|f)
+
+expect abcdef
+echo ab*d+(e|f)
+
+expect 'ab abcdef abcfef abef'
+echo ab**(e|f)
+
+expect 'abcdef abcfef abef'
+echo ab*+(e|f)
+
+case 'abcfefg' in
+ab**(e|f)) echo ok 37;;
+*) echo bad 37;;
+esac
+
+case 'abcfefg' in
+ab**(e|f)g) echo ok 38;;
+*a) echo bad 38;;
+esac
+
+case ab in
+ab*+(e|f)) echo bad 39;;
+*) echo ok 39;;
+esac
+
+case abef in
+ab***ef) echo ok 40;;
+*) echo bad 40;;
+esac
+
+case abef in
+ab**) echo ok 41;;
+*) echo bad 41;;
+esac
+
+# bug in all versions up to and including bash-2.05b
+case "123abc" in
+*?(a)bc) echo ok 42;;
+*) echo bad 42;;
+esac
+
+# clean up and do the next one
+
+builtin cd /
+rm -rf $TESTDIR
+
+mkdir $TESTDIR
+builtin cd $TESTDIR
+
+LC_COLLATE=C # have to set this; it affects the sorting
+touch a.b a,b a:b a-b a\;b a\ b a_b
+
+echo a[^[:alnum:]]b
+echo a[-.,:\;\ _]b
+
+echo a@([^[:alnum:]])b
+echo a@([-.,:; _])b
+echo a@([.])b
+echo a@([^.])b
+echo a@([^x])b
+echo a+([^[:alnum:]])b
+
+echo a@(.|[^[:alnum:]])b
+
+builtin cd /
+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"
+
+${THIS_SH} ./extglob1.sub
+
+exit 0
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/extglob2.right b/tests/extglob2.right
new file mode 100644
index 0000000..f8a09df
--- /dev/null
+++ b/tests/extglob2.right
@@ -0,0 +1,70 @@
+0: [[ fofo = *(f*(o)) ]]
+0: [[ ffo = *(f*(o)) ]]
+0: [[ foooofo = *(f*(o)) ]]
+0: [[ foooofof = *(f*(o)) ]]
+0: [[ fooofoofofooo = *(f*(o)) ]]
+1: [[ foooofof = *(f+(o)) ]]
+1: [[ xfoooofof = *(f*(o)) ]]
+1: [[ foooofofx = *(f*(o)) ]]
+0: [[ ofxoofxo = *(*(of*(o)x)o) ]]
+1: [[ ofooofoofofooo = *(f*(o)) ]]
+0: [[ foooxfooxfoxfooox = *(f*(o)x) ]]
+1: [[ foooxfooxofoxfooox = *(f*(o)x) ]]
+0: [[ foooxfooxfxfooox = *(f*(o)x) ]]
+0: [[ ofxoofxo = *(*(of*(o)x)o) ]]
+0: [[ ofoooxoofxo = *(*(of*(o)x)o) ]]
+0: [[ ofoooxoofxoofoooxoofxo = *(*(of*(o)x)o) ]]
+0: [[ ofoooxoofxoofoooxoofxoo = *(*(of*(o)x)o) ]]
+1: [[ ofoooxoofxoofoooxoofxofo = *(*(of*(o)x)o) ]]
+0: [[ ofoooxoofxoofoooxoofxooofxofxo = *(*(of*(o)x)o) ]]
+0: [[ aac = *(@(a))a@(c) ]]
+0: [[ ac = *(@(a))a@(c) ]]
+1: [[ c = *(@(a))a@(c) ]]
+0: [[ aaac = *(@(a))a@(c) ]]
+1: [[ baaac = *(@(a))a@(c) ]]
+0: [[ abcd = ?@(a|b)*@(c)d ]]
+0: [[ abcd = @(ab|a*@(b))*(c)d ]]
+0: [[ acd = @(ab|a*(b))*(c)d ]]
+0: [[ abbcd = @(ab|a*(b))*(c)d ]]
+0: [[ effgz = @(b+(c)d|e*(f)g?|?(h)i@(j|k)) ]]
+0: [[ efgz = @(b+(c)d|e*(f)g?|?(h)i@(j|k)) ]]
+0: [[ egz = @(b+(c)d|e*(f)g?|?(h)i@(j|k)) ]]
+0: [[ egzefffgzbcdij = *(b+(c)d|e*(f)g?|?(h)i@(j|k)) ]]
+1: [[ egz = @(b+(c)d|e+(f)g?|?(h)i@(j|k)) ]]
+0: [[ ofoofo = *(of+(o)) ]]
+0: [[ oxfoxoxfox = *(oxf+(ox)) ]]
+1: [[ oxfoxfox = *(oxf+(ox)) ]]
+0: [[ ofoofo = *(of+(o)|f) ]]
+0: [[ foofoofo = @(foo|f|fo)*(f|of+(o)) ]]
+0: [[ oofooofo = *(of|oof+(o)) ]]
+0: [[ fffooofoooooffoofffooofff = *(*(f)*(o)) ]]
+0: [[ fofoofoofofoo = *(fo|foo) ]]
+0: [[ foo = !(x) ]]
+0: [[ foo = !(x)* ]]
+1: [[ foo = !(foo) ]]
+0: [[ foo = !(foo)* ]]
+0: [[ foobar = !(foo) ]]
+0: [[ foobar = !(foo)* ]]
+0: [[ moo.cow = !(*.*).!(*.*) ]]
+1: [[ mad.moo.cow = !(*.*).!(*.*) ]]
+1: [[ mucca.pazza = mu!(*(c))?.pa!(*(z))? ]]
+0: [[ fff = !(f) ]]
+0: [[ fff = *(!(f)) ]]
+0: [[ fff = +(!(f)) ]]
+0: [[ ooo = !(f) ]]
+0: [[ ooo = *(!(f)) ]]
+0: [[ ooo = +(!(f)) ]]
+0: [[ foo = !(f) ]]
+0: [[ foo = *(!(f)) ]]
+0: [[ foo = +(!(f)) ]]
+1: [[ f = !(f) ]]
+1: [[ f = *(!(f)) ]]
+1: [[ f = +(!(f)) ]]
+0: [[ foot = @(!(z*)|*x) ]]
+1: [[ zoot = @(!(z*)|*x) ]]
+0: [[ foox = @(!(z*)|*x) ]]
+0: [[ zoox = @(!(z*)|*x) ]]
+0: [[ foo = *(!(foo)) ]]
+1: [[ foob = !(foo)b* ]]
+0: [[ foobb = !(foo)b* ]]
+0 tests failed.
diff --git a/tests/extglob2.tests b/tests/extglob2.tests
new file mode 100755
index 0000000..f35c3e8
--- /dev/null
+++ b/tests/extglob2.tests
@@ -0,0 +1,90 @@
+#
+# More ksh-like extended globbing tests, cribbed from zsh-3.1.5
+#
+shopt -s extglob
+
+failed=0
+while read res str pat; do
+ [[ $res = '#' ]] && continue
+ [[ $str = ${pat} ]]
+ ts=$?
+ [[ $1 = -q ]] || echo "$ts: [[ $str = $pat ]]"
+ if [[ ( $ts -gt 0 && $res = t) || ($ts -eq 0 && $res = f) ]]; then
+ echo "Test failed: [[ $str = $pat ]]"
+ (( failed += 1 ))
+ fi
+done <<EOT
+t fofo *(f*(o))
+t ffo *(f*(o))
+t foooofo *(f*(o))
+t foooofof *(f*(o))
+t fooofoofofooo *(f*(o))
+f foooofof *(f+(o))
+f xfoooofof *(f*(o))
+f foooofofx *(f*(o))
+t ofxoofxo *(*(of*(o)x)o)
+f ofooofoofofooo *(f*(o))
+t foooxfooxfoxfooox *(f*(o)x)
+f foooxfooxofoxfooox *(f*(o)x)
+t foooxfooxfxfooox *(f*(o)x)
+t ofxoofxo *(*(of*(o)x)o)
+t ofoooxoofxo *(*(of*(o)x)o)
+t ofoooxoofxoofoooxoofxo *(*(of*(o)x)o)
+t ofoooxoofxoofoooxoofxoo *(*(of*(o)x)o)
+f ofoooxoofxoofoooxoofxofo *(*(of*(o)x)o)
+t ofoooxoofxoofoooxoofxooofxofxo *(*(of*(o)x)o)
+t aac *(@(a))a@(c)
+t ac *(@(a))a@(c)
+f c *(@(a))a@(c)
+t aaac *(@(a))a@(c)
+f baaac *(@(a))a@(c)
+t abcd ?@(a|b)*@(c)d
+t abcd @(ab|a*@(b))*(c)d
+t acd @(ab|a*(b))*(c)d
+t abbcd @(ab|a*(b))*(c)d
+t effgz @(b+(c)d|e*(f)g?|?(h)i@(j|k))
+t efgz @(b+(c)d|e*(f)g?|?(h)i@(j|k))
+t egz @(b+(c)d|e*(f)g?|?(h)i@(j|k))
+t egzefffgzbcdij *(b+(c)d|e*(f)g?|?(h)i@(j|k))
+f egz @(b+(c)d|e+(f)g?|?(h)i@(j|k))
+t ofoofo *(of+(o))
+t oxfoxoxfox *(oxf+(ox))
+f oxfoxfox *(oxf+(ox))
+t ofoofo *(of+(o)|f)
+# The following is supposed to match only as fo+ofo+ofo
+t foofoofo @(foo|f|fo)*(f|of+(o))
+t oofooofo *(of|oof+(o))
+t fffooofoooooffoofffooofff *(*(f)*(o))
+# The following tests backtracking in alternation matches
+t fofoofoofofoo *(fo|foo)
+# Exclusion
+t foo !(x)
+t foo !(x)*
+f foo !(foo)
+t foo !(foo)*
+t foobar !(foo)
+t foobar !(foo)*
+t moo.cow !(*.*).!(*.*)
+f mad.moo.cow !(*.*).!(*.*)
+f mucca.pazza mu!(*(c))?.pa!(*(z))?
+t fff !(f)
+t fff *(!(f))
+t fff +(!(f))
+t ooo !(f)
+t ooo *(!(f))
+t ooo +(!(f))
+t foo !(f)
+t foo *(!(f))
+t foo +(!(f))
+f f !(f)
+f f *(!(f))
+f f +(!(f))
+t foot @(!(z*)|*x)
+f zoot @(!(z*)|*x)
+t foox @(!(z*)|*x)
+t zoox @(!(z*)|*x)
+t foo *(!(foo))
+f foob !(foo)b*
+t foobb !(foo)b*
+EOT
+echo "$failed tests failed."
diff --git a/tests/extglob3.right b/tests/extglob3.right
new file mode 100644
index 0000000..db9447e
--- /dev/null
+++ b/tests/extglob3.right
@@ -0,0 +1,27 @@
+match 1
+match 2
+match 3
+match 4
+match 1a
+match 1b
+match 2a
+match 2b
+match 3a
+match 3b
+match 4a
+match 4b
+match 5
+match 6
+match 7
+match 8
+match 9
+match 10
+match 11
+match 12
+match 13
+match 14
+match 15
+match 16
+match 17
+match 18
+ok 19
diff --git a/tests/extglob3.tests b/tests/extglob3.tests
new file mode 100644
index 0000000..60454a2
--- /dev/null
+++ b/tests/extglob3.tests
@@ -0,0 +1,56 @@
+shopt -s extglob
+
+[[ ab/../ == @(ab|+([^/]))/..?(/) ]] && echo match 1
+
+[[ ab/../ == +([^/])/..?(/) ]] && echo match 2
+
+[[ ab/../ == @(ab|?b)/..?(/) ]] && echo match 3
+
+[[ ab/../ == +([^/])/../ ]] && echo match 4
+
+[[ ab/../ == +([!/])/..?(/) ]] && echo match 1a
+
+[[ ab/../ == @(ab|+([!/]))/..?(/) ]] && echo match 1b
+
+[[ ab/../ == +([!/])/../ ]] && echo match 2a
+
+[[ ab/../ == +([!/])/..?(/) ]] && echo match 2b
+
+[[ ab/../ == +([!/])/..@(/) ]] && echo match 3a
+
+[[ ab/../ == +(ab)/..?(/) ]] && echo match 3b
+
+[[ ab/../ == [!/][!/]/../ ]] && echo match 4a
+
+[[ ab/../ == @(ab|?b)/..?(/) ]] && echo match 4b
+
+[[ ab/../ == [^/][^/]/../ ]] && echo match 5
+
+[[ ab/../ == ?b/..?(/) ]] && echo match 6
+
+[[ ab/../ == +(?b)/..?(/) ]] && echo match 7
+
+[[ ab/../ == +(?b|?b)/..?(/) ]] && echo match 8
+
+[[ ab/../ == @(?b|?b)/..?(/) ]] && echo match 9
+
+[[ ab/../ == @(a?|?b)/..?(/) ]] && echo match 10
+
+[[ ab/../ == ?(ab)/..?(/) ]] && echo match 11
+
+[[ ab/../ == ?(ab|??)/..?(/) ]] && echo match 12
+
+[[ ab/../ == @(??)/..?(/) ]] && echo match 13
+
+[[ ab/../ == @(??|a*)/..?(/) ]] && echo match 14
+
+[[ ab/../ == @(a*)/..?(/) ]] && echo match 15
+
+[[ ab/../ == +(??)/..?(/) ]] && echo match 16
+
+[[ ab/../ == +(??|a*)/..?(/) ]] && echo match 17
+
+[[ ab/../ == +(a*)/..?(/) ]] && echo match 18
+
+#
+j="@(x)" ; [[ x == $j ]] && echo ok 19
diff --git a/tests/func.right b/tests/func.right
new file mode 100644
index 0000000..da8b45c
--- /dev/null
+++ b/tests/func.right
@@ -0,0 +1,156 @@
+a returns 5
+b returns 4
+c returns 3
+d returns 2
+in e
+e returned 25
+x is 25
+ZZ
+abcde
+defghi
+ZZ
+5
+0
+AVAR
+AVAR
+foo
+foo
+AVAR
+5
+5
+f1
+f1 ()
+{
+ ( return 5 );
+ status=$?;
+ echo $status;
+ return $status
+}
+before: try to assign to FUNCNAME
+outside: FUNCNAME =
+before: FUNCNAME = func
+FUNCNAME = func2
+after: FUNCNAME = func
+outside2: FUNCNAME =
+function
+zf is a function
+zf ()
+{
+ echo this is zf
+}
+f is a function
+f ()
+{
+ echo f-x;
+ echo f-y
+} 1>&2
+subshell
+f is a function
+f ()
+{
+ echo f-x;
+ echo f-y
+} 1>&2
+f2 is a function
+f2 ()
+{
+ echo f2-a;
+ function f3 ()
+ {
+ echo f3-a;
+ echo f3-b
+ } 1>&2;
+ f3
+}
+subshell
+f2 is a function
+f2 ()
+{
+ echo f2-a;
+ function f3 ()
+ {
+ echo f3-a;
+ echo f3-b
+ } 1>&2;
+ f3
+}
+f4 is a function
+f4 ()
+{
+ echo f4-a;
+ function f5 ()
+ {
+ echo f5-a;
+ echo f5-b
+ } 1>&2;
+ f5
+} 2>&1
+subshell
+f4 is a function
+f4 ()
+{
+ echo f4-a;
+ function f5 ()
+ {
+ echo f5-a;
+ echo f5-b
+ } 1>&2;
+ f5
+} 2>&1
+testgrp is a function
+testgrp ()
+{
+ echo testgrp-a;
+ {
+ echo tg-x;
+ echo tg-y
+ } 1>&2;
+ echo testgrp-b
+}
+subshell
+testgrp is a function
+testgrp ()
+{
+ echo testgrp-a;
+ {
+ echo tg-x;
+ echo tg-y
+ } 1>&2;
+ echo testgrp-b
+}
+funca is a function
+funca ()
+{
+ ( echo func-a )
+}
+funcb is a function
+funcb ()
+{
+ ( echo func-b )
+}
+funcc is a function
+funcc ()
+{
+ ( echo func-c ) 2>&1
+}
+func-a
+func-b
+func-c
+foo-bar
+foo-bar ()
+{
+ :
+}
+expect 5 10
+5 10
+expect 20
+20
+expect 5 20
+5 20
+expect 5 30
+5 30
+expect 2 40
+2 40
+expect 5 20
+5 20
+5
diff --git a/tests/func.tests b/tests/func.tests
new file mode 100644
index 0000000..23dff44
--- /dev/null
+++ b/tests/func.tests
@@ -0,0 +1,176 @@
+a()
+{
+ x=$((x - 1))
+ return 5
+}
+
+b()
+{
+ x=$((x - 1))
+ a
+ echo a returns $?
+ return 4
+}
+
+c()
+{
+ x=$((x - 1))
+ b
+ echo b returns $?
+ return 3
+}
+
+d()
+{
+ x=$((x - 1))
+ c
+ echo c returns $?
+ return 2
+}
+
+e()
+{
+ d
+ echo d returns $?
+ echo in e
+ x=$((x - 1))
+ return $x
+}
+
+f()
+{
+ e
+ echo e returned $?
+ echo x is $x
+ return 0
+}
+
+x=30
+f
+
+# make sure unsetting a local variable preserves the `local' attribute
+f1()
+{
+ local zz
+ zz=abcde
+ echo $zz
+ unset zz
+ zz=defghi
+ echo $zz
+}
+
+zz=ZZ
+echo $zz
+f1
+echo $zz
+
+unset -f f1
+f1()
+{
+ return 5
+}
+
+( f1 )
+echo $?
+
+unset -f f1
+f1()
+{
+ sleep 5
+ return 5
+}
+
+f1 &
+wait
+echo $?
+
+unset -f f1
+
+f1()
+{
+ echo $AVAR
+ printenv AVAR
+}
+
+AVAR=AVAR
+echo $AVAR
+f1
+AVAR=foo f1
+echo $AVAR
+
+unset -f f1
+# make sure subshells can do a `return' if we're executing in a function
+f1()
+{
+ ( return 5 )
+ status=$?
+ echo $status
+ return $status
+}
+
+f1
+echo $?
+
+declare -F f1 # should print just the name
+declare -f f1 # should print the definition, too
+
+# no functions should be exported, right?
+declare -xF
+declare -xf
+
+# FUNCNAME tests
+func2()
+{
+ echo FUNCNAME = $FUNCNAME
+}
+
+func()
+{
+ echo before: FUNCNAME = $FUNCNAME
+ func2
+ echo after: FUNCNAME = $FUNCNAME
+}
+
+echo before: try to assign to FUNCNAME
+FUNCNAME=7
+
+echo outside: FUNCNAME = $FUNCNAME
+func
+echo outside2: FUNCNAME = $FUNCNAME
+
+# test exported functions (and cached exportstr)
+zf()
+{
+ echo this is zf
+}
+export -f zf
+
+${THIS_SH} -c 'type -t zf'
+${THIS_SH} -c 'type zf'
+
+${THIS_SH} ./func1.sub
+
+# tests for functions whose bodies are not group commands, with and without
+# attached redirections
+${THIS_SH} ./func2.sub
+
+# test for some posix-specific function behavior
+${THIS_SH} ./func3.sub
+
+unset -f myfunction
+myfunction() {
+ echo "bad shell function redirection"
+} >> /dev/null
+
+myfunction
+myfunction | cat
+
+segv()
+{
+ echo foo | return 5
+}
+
+segv
+echo $?
+
+exit 0
diff --git a/tests/func1.sub b/tests/func1.sub
new file mode 100644
index 0000000..345645f
--- /dev/null
+++ b/tests/func1.sub
@@ -0,0 +1,55 @@
+#
+# Test that redirections attached to shell functions are printed correctly.
+# This was a bug in all bash versions before bash-2.04.
+#
+f()
+{
+ echo f-x
+ echo f-y
+} >&2
+
+type f
+export -f f
+${THIS_SH} -c 'echo subshell; type f'
+
+f2()
+{
+ echo f2-a
+ f3()
+ {
+ echo f3-a
+ echo f3-b
+ } >&2
+ f3
+}
+
+type f2
+
+export -f f2
+${THIS_SH} -c 'echo subshell; type f2'
+
+f4()
+{
+ echo f4-a
+ f5()
+ {
+ echo f5-a
+ echo f5-b
+ } >&2
+ f5
+} 2>&1
+
+type f4
+export -f f4
+${THIS_SH} -c 'echo subshell; type f4'
+
+testgrp()
+{
+ echo testgrp-a
+ { echo tg-x; echo tg-y; } >&2
+ echo testgrp-b
+}
+type testgrp
+
+export -f testgrp
+${THIS_SH} -c 'echo subshell; type testgrp'
diff --git a/tests/func2.sub b/tests/func2.sub
new file mode 100644
index 0000000..41a3844
--- /dev/null
+++ b/tests/func2.sub
@@ -0,0 +1,27 @@
+funca() (
+ echo func-a
+)
+
+funcb() ( echo func-b )
+
+funcc() (
+ echo func-c
+) 2>&1
+
+type funca
+type funcb
+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/func3.sub b/tests/func3.sub
new file mode 100644
index 0000000..9d3d069
--- /dev/null
+++ b/tests/func3.sub
@@ -0,0 +1,54 @@
+#
+# test some posix-mode-specific function behavior
+#
+set -o posix
+func()
+{
+ return 5
+}
+
+myfunction () {
+ var=20 return
+}
+var=10
+echo expect 5 10
+func
+echo $? $var
+
+myfunction
+echo expect 20
+echo $var
+
+echo expect 5 20
+func
+echo $? $var
+
+echo expect 5 30
+var=30 func
+echo $? $var
+
+: ${TMPDIR:=/tmp}
+TMPFILE=$TMPDIR/func3.sub.$$
+
+rm -f $TMPFILE
+echo 'var=40 return 2' > $TMPFILE
+
+# test the behavior of `return' and preceding variable assignments here
+# because it's convenient
+var=10
+echo expect 2 40
+. $TMPFILE
+echo $? $var
+
+rm -f $TMPFILE
+
+#set -o posix
+var=0
+func()
+{
+ var=20 return 5
+}
+
+echo expect 5 20
+var=30 func
+echo $? $var
diff --git a/tests/getopts.right b/tests/getopts.right
new file mode 100644
index 0000000..9226103
--- /dev/null
+++ b/tests/getopts.right
@@ -0,0 +1,56 @@
+getopts: usage: getopts optstring name [arg]
+2
+getopts: usage: getopts optstring name [arg]
+2
+./getopts.tests: line 10: getopts: -a: invalid option
+getopts: usage: getopts optstring name [arg]
+-a specified
+-b bval specified
+remaining args: one two three
+-a specified
+-b bval specified
+remaining args: one two three four five six seven eight nine ten eleven twelve
+./getopts1.sub: option requires an argument -- b
+Usage: ./getopts1.sub [-a] [-b value] args
+-a specified
+-c cval specified
+-d specified
+-a specified
+-b 3 specified
+remaining args: one two three four five
+-a specified
+-b bval specified
+remaining args: one two three
+-a specified
+-b bval specified
+remaining args: one two three
+./getopts4.sub: error: option `b' requires an argument
+Usage: ./getopts4.sub [-a] [-b value] args
+./getopts4.sub: error: illegal option character `c'
+Usage: ./getopts4.sub [-a] [-b value] args
+-a specified
+remaining args: -b bval one two three
+OPTERR=0
+a here
+something else here
+OPTIND=3
+getop: OPTERR=1
+a here
+./getopts5.sub: illegal option -- c
+something else here
+./getopts5.sub: illegal option -- d
+something else here
+./getopts5.sub: illegal option -- e
+something else here
+getop: OPTIND=5
+OPTIND=3
+OPTERR=0
+-a specified
+remaining args:
+-a specified
+remaining args:
+-a specified
+remaining args:
+0
+./getopts7.sub: line 4: getopts: `opt-var': not a valid identifier
+remaining args:
diff --git a/tests/getopts.tests b/tests/getopts.tests
new file mode 100644
index 0000000..1814d78
--- /dev/null
+++ b/tests/getopts.tests
@@ -0,0 +1,38 @@
+# getopts tests
+# this should fail
+getopts
+echo $?
+getopts opts
+echo $?
+
+# maybe someday we will have a ksh93-like -a argument to set the name
+# used in error messages, but not yet
+getopts -a opts name
+
+${THIS_SH} ./getopts1.sub -a -b bval one two three
+# make sure getopts works when there are more than 9 positional parameters
+${THIS_SH} ./getopts1.sub -a -b bval one two three four five six seven eight nine ten eleven twelve
+${THIS_SH} ./getopts1.sub -a -b
+
+${THIS_SH} ./getopts2.sub -ad -c cval three four five
+
+${THIS_SH} ./getopts3.sub
+
+# make sure that `-b bval' and `-bbval' are equivalent
+${THIS_SH} ./getopts4.sub -a -b bval one two three
+${THIS_SH} ./getopts4.sub -a -bbval one two three
+# this tests `silent' error reporting
+${THIS_SH} ./getopts4.sub -a -b
+${THIS_SH} ./getopts4.sub -a -c
+
+# make sure that `--' can be used to end the list of options
+${THIS_SH} ./getopts4.sub -a -- -b bval one two three
+
+${THIS_SH} ./getopts5.sub -a -c
+
+${THIS_SH} ./getopts6.sub -a
+${THIS_SH} ./getopts6.sub -a -c
+${THIS_SH} ./getopts6.sub -ac
+echo $? # this should be 2
+
+${THIS_SH} ./getopts7.sub -a
diff --git a/tests/getopts1.sub b/tests/getopts1.sub
new file mode 100644
index 0000000..df0a342
--- /dev/null
+++ b/tests/getopts1.sub
@@ -0,0 +1,26 @@
+aflag=
+bflag=
+
+while getopts ab: name
+do
+ case $name in
+ a) aflag=1 ;;
+ b) bflag=1
+ bval=$OPTARG;;
+ ?) echo Usage: $0 [-a] [-b value] args
+ exit 2;;
+ esac
+
+done
+
+if [ ! -z "$aflag" ] ; then echo -a specified ; fi
+if [ ! -z "$bflag" ] ; then echo -b $bval specified ; fi
+
+if [ "$OPTIND" -gt 1 ]
+then
+ shift $(( $OPTIND - 1 ))
+fi
+
+echo remaining args: "$*"
+
+exit 0
diff --git a/tests/getopts2.sub b/tests/getopts2.sub
new file mode 100644
index 0000000..d91fd26
--- /dev/null
+++ b/tests/getopts2.sub
@@ -0,0 +1,26 @@
+aflag=
+bflag=
+
+while getopts ab:c:de name "$@"
+do
+ case $name in
+ a) aflag=1 ;;
+ b) bflag=1
+ bval=$OPTARG;;
+ c) cflag=1
+ cval=$OPTARG ;;
+ d) dflag=1 ;;
+ e) eflag=1;;
+ ?) echo Usage: $0 [-a] [-b value] [-c value] -[de] args
+ exit 2;;
+ esac
+
+done
+
+[ ! -z "$aflag" ] && echo -a specified
+[ ! -z "$bflag" ] && echo -b $bval specified
+[ ! -z "$cflag" ] && echo -c $cval specified
+[ ! -z "$dflag" ] && echo -d specified
+[ ! -z "$eflag" ] && { echo -n - ; echo e specified; }
+
+exit 0
diff --git a/tests/getopts3.sub b/tests/getopts3.sub
new file mode 100644
index 0000000..2d8b316
--- /dev/null
+++ b/tests/getopts3.sub
@@ -0,0 +1,27 @@
+aflag=
+bflag=
+
+while getopts ab: name -a -b 1 -a -a -a -b 5 -b 3 -a one two three four five
+do
+ case $name in
+ a) aflag=1 ;;
+ b) bflag=1
+ bval=$OPTARG;;
+ ?) echo Usage: $0 [-a] [-b value] args
+ exit 2;;
+ esac
+
+done
+
+if [ ! -z "$aflag" ] ; then echo -a specified ; fi
+if [ ! -z "$bflag" ] ; then echo -b $bval specified ; fi
+
+set -- -a -b 1 -a -a -a -b 5 -b 3 -a one two three four five
+if [ "$OPTIND" -gt 1 ]
+then
+ shift $(( $OPTIND - 1 ))
+fi
+
+echo remaining args: "$*"
+
+exit 0
diff --git a/tests/getopts4.sub b/tests/getopts4.sub
new file mode 100644
index 0000000..9cd5aef
--- /dev/null
+++ b/tests/getopts4.sub
@@ -0,0 +1,30 @@
+aflag=
+bflag=
+
+while getopts :ab: name "$@"
+do
+ case $name in
+ a) aflag=1 ;;
+ b) bflag=1
+ bval=$OPTARG;;
+ :) echo $0: error: option \`$OPTARG\' requires an argument
+ echo Usage: $0 [-a] [-b value] args
+ exit 2;;
+ ?) echo $0: error: illegal option character \`$OPTARG\'
+ echo Usage: $0 [-a] [-b value] args
+ exit 2;;
+ esac
+
+done
+
+if [ ! -z "$aflag" ] ; then echo -a specified ; fi
+if [ ! -z "$bflag" ] ; then echo -b $bval specified ; fi
+
+if [ "$OPTIND" -gt 1 ]
+then
+ shift $(( $OPTIND - 1 ))
+fi
+
+echo remaining args: "$*"
+
+exit 0
diff --git a/tests/getopts5.sub b/tests/getopts5.sub
new file mode 100644
index 0000000..c6e3888
--- /dev/null
+++ b/tests/getopts5.sub
@@ -0,0 +1,50 @@
+#!/local/bin/bash
+#Time-stamp: <95/06/07 07:40:40 hrue@imf.unit.no>
+
+getop () {
+
+ local OPTIND
+ local OPTERR=1
+
+ echo getop: OPTERR=$OPTERR
+ while getopts ab arg "$@"; do
+ case $arg in
+ a)
+ echo a here
+ ;;
+ b)
+ echo b here
+ ;;
+ :|?|*)
+ echo something else here
+ ;;
+ esac
+ done
+ echo getop: OPTIND=$OPTIND
+}
+
+OPTIND=
+OPTERR=0
+
+echo OPTERR=$OPTERR
+while getopts ab arg; do
+ case $arg in
+ a)
+ echo a here
+ ;;
+ b)
+ echo b here
+ ;;
+ :|?|*)
+
+ echo something else here
+ ;;
+ esac
+done
+
+echo OPTIND=$OPTIND
+
+getop "$@" -d -e
+
+echo OPTIND=$OPTIND
+echo OPTERR=$OPTERR
diff --git a/tests/getopts6.sub b/tests/getopts6.sub
new file mode 100644
index 0000000..75d768c
--- /dev/null
+++ b/tests/getopts6.sub
@@ -0,0 +1,27 @@
+aflag=
+bflag=
+
+while getopts :ac name "$@"
+do
+ case $name in
+ a) aflag=1 ;;
+ c) cflag=1 ;;
+ ?) exit 2;;
+ esac
+
+ # this came in in a bug report -- it's really a usage error
+ # but it shouldn't cause the shell to crash
+ shift
+done
+
+if [ ! -z "$aflag" ] ; then echo -a specified ; fi
+if [ ! -z "$cflag" ] ; then echo -c specified ; fi
+
+if [ "$OPTIND" -gt 1 ]
+then
+ shift $(( $OPTIND - 1 ))
+fi
+
+echo remaining args: "$*"
+
+exit 0
diff --git a/tests/getopts7.sub b/tests/getopts7.sub
new file mode 100644
index 0000000..a20a6df
--- /dev/null
+++ b/tests/getopts7.sub
@@ -0,0 +1,30 @@
+aflag=
+bflag=
+
+while getopts :ab: opt-var "$@"
+do
+ case $name in
+ a) aflag=1 ;;
+ b) bflag=1
+ bval=$OPTARG;;
+ :) echo $0: error: option \`$OPTARG\' requires an argument
+ echo Usage: $0 [-a] [-b value] args
+ exit 2;;
+ ?) echo $0: error: illegal option character \`$OPTARG\'
+ echo Usage: $0 [-a] [-b value] args
+ exit 2;;
+ esac
+
+done
+
+if [ ! -z "$aflag" ] ; then echo -a specified ; fi
+if [ ! -z "$bflag" ] ; then echo -b $bval specified ; fi
+
+if [ "$OPTIND" -gt 1 ]
+then
+ shift $(( $OPTIND - 1 ))
+fi
+
+echo remaining args: "$*"
+
+exit 0
diff --git a/tests/glob.right b/tests/glob.right
new file mode 100644
index 0000000..04a0fd5
--- /dev/null
+++ b/tests/glob.right
@@ -0,0 +1,135 @@
+foo/bar foobar/bar
+argv[1] = <a>
+argv[2] = <abc>
+argv[3] = <abd>
+argv[4] = <abe>
+argv[5] = <X*>
+argv[1] = <a>
+argv[2] = <abc>
+argv[3] = <abd>
+argv[4] = <abe>
+argv[1] = <a>
+argv[2] = <abc>
+argv[3] = <abd>
+argv[4] = <abe>
+tmp/l1 tmp/l2 tmp/*4 tmp/l3
+./glob.tests: line 44: no match: tmp/*4
+argv[1] = <bdir/>
+argv[1] = <*>
+argv[1] = <a*>
+argv[1] = <a*>
+argv[1] = <c>
+argv[2] = <ca>
+argv[3] = <cb>
+argv[4] = <a*>
+argv[5] = <*q*>
+argv[1] = <**>
+argv[1] = <**>
+argv[1] = <\.\./*/>
+argv[1] = <s/\..*//>
+argv[1] = </^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/>
+argv[1] = <abc>
+argv[2] = <abd>
+argv[3] = <abe>
+argv[4] = <bb>
+argv[5] = <cb>
+argv[1] = <abd>
+argv[2] = <abe>
+argv[3] = <bb>
+argv[4] = <bcd>
+argv[5] = <bdir>
+argv[6] = <ca>
+argv[7] = <cb>
+argv[8] = <dd>
+argv[9] = <de>
+argv[1] = <abd>
+argv[2] = <abe>
+argv[1] = <a-b>
+argv[2] = <aXb>
+argv[1] = <Beware>
+argv[2] = <d>
+argv[3] = <dd>
+argv[4] = <de>
+argv[1] = <a*b/ooo>
+argv[1] = <a*b/ooo>
+no match
+not there
+argv[1] = <abc>
+argv[1] = <abc>
+argv[1] = <abc>
+argv[1] = <abc>
+match 1
+match 2
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+argv[1] = <man/man1/bash.1>
+argv[1] = <man/man1/bash.1>
+argv[1] = <man/man1/bash.1>
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+ok 6
+ok 7
+ok 8
+ok 9
+ok 10
+ok 11
+ok 20
+ok 21
+ok 22
+ok 23
+ok 24
+ok 25
+ok 26
+ok 27
+ok 28
+ok 29
+ok 30
+ok 31
+ok 32
+ok 33
+ok 34
+ok 35
+ok 36
+ok 37
+argv[1] = <b>
+argv[2] = <bb>
+argv[3] = <bcd>
+argv[4] = <bdir>
+argv[1] = <Beware>
+argv[2] = <b>
+argv[3] = <bb>
+argv[4] = <bcd>
+argv[5] = <bdir>
+argv[1] = <Beware>
+argv[2] = <b>
+argv[3] = <bb>
+argv[4] = <bcd>
+argv[5] = <bdir>
+argv[1] = <*>
+argv[1] = <a*b>
+argv[2] = <a-b>
+argv[3] = <aXb>
+argv[4] = <abd>
+argv[5] = <bb>
+argv[6] = <bcd>
+argv[7] = <bdir>
+argv[8] = <ca>
+argv[9] = <cb>
+argv[10] = <dd>
+argv[11] = <man>
+argv[1] = <Beware>
+argv[2] = <abc>
+argv[3] = <abe>
+argv[4] = <bdir>
+argv[5] = <ca>
+argv[6] = <de>
+argv[7] = <man>
+argv[1] = <*>
+argv[1] = <man/man1/bash.1>
+argv[1] = <man/man1/bash.1>
diff --git a/tests/glob.tests b/tests/glob.tests
new file mode 100644
index 0000000..d32988b
--- /dev/null
+++ b/tests/glob.tests
@@ -0,0 +1,388 @@
+export LC_COLLATE=C
+#
+# test the shell globbing
+#
+expect()
+{
+ echo expect "$@"
+}
+
+# First, a test that bash-2.01.1 fails
+${THIS_SH} ./glob1.sub
+
+MYDIR=$PWD # save where we are
+
+TESTDIR=/tmp/glob-test
+mkdir $TESTDIR
+builtin cd $TESTDIR || { echo $0: cannot cd to $TESTDIR >&2 ; exit 1; }
+rm -rf *
+
+touch a b c d abc abd abe bb bcd ca cb dd de Beware
+mkdir bdir
+
+# see if `regular' globbing works right
+expect '<a> <abc> <abd> <abe> <X*>'
+recho a* X*
+
+expect '<a> <abc> <abd> <abe>'
+recho \a*
+
+# see if null glob expansion works
+shopt -s nullglob
+
+expect '<a> <abc> <abd> <abe>'
+recho a* X*
+
+shopt -u nullglob
+
+# see if the failglob option works
+
+mkdir tmp
+touch tmp/l1 tmp/l2 tmp/l3
+builtin echo tmp/l[12] tmp/*4 tmp/*3
+shopt -s failglob
+builtin echo tmp/l[12] tmp/*4 tmp/*3
+rm -r tmp
+shopt -u failglob
+
+# see if the code that expands directories only works
+expect '<bdir/>'
+recho b*/
+
+# Test quoted and unquoted globbing characters
+expect '<*>'
+recho \*
+
+expect '<a*>'
+recho 'a*'
+
+expect '<a*>'
+recho a\*
+
+expect '<c> <ca> <cb> <a*> <*q*>'
+recho c* a\* *q*
+
+expect '<**>'
+recho "*"*
+
+expect '<**>'
+recho \**
+
+expect '<\.\./*/>'
+recho "\.\./*/"
+
+expect '<s/\..*//>'
+recho 's/\..*//'
+
+# Pattern from Larry Wall's Configure that caused bash to blow up
+expect '</^root:/{s/^[^:]*:[^:]*:\([^:]*\).*$/\1/>'
+recho "/^root:/{s/^[^:]*:[^:]*:\([^:]*\).*"'$'"/\1/"
+
+# Make sure character classes work properly
+
+expect '<abc> <abd> <abe> <bb> <cb>'
+recho [a-c]b*
+
+expect '<abd> <abe> <bb> <bcd> <bdir> <ca> <cb> <dd> <de>'
+recho [a-y]*[^c]
+
+expect '<abd> <abe>'
+recho a*[^c]
+
+touch a-b aXb
+expect '<a-b> <aXb>'
+recho a[X-]b
+
+touch .x .y
+expect '<Beware> <d> <dd> <de>'
+recho [^a-c]*
+
+# Make sure that filenames with embedded globbing characters are handled
+# properly
+mkdir a\*b
+> a\*b/ooo
+
+expect '<a*b/ooo>'
+recho a\*b/*
+
+expect '<a*b/ooo>'
+recho a\*?/*
+
+expect '<no match>'
+cmd='echo !7'
+case "$cmd" in
+*\\!*) echo match ;;
+*) echo no match ;;
+esac
+
+expect '<not there>'
+file='r.*'
+case $file in
+*.\*) echo not there ;;
+*) echo there ;;
+esac
+
+# examples from the Posix.2 spec (d11.2, p. 243)
+expect '<abc>'
+recho a[b]c
+
+expect '<abc>'
+recho a["b"]c
+
+expect '<abc>'
+recho a[\b]c
+
+expect '<abc>'
+recho a?c
+
+expect '<match 1>'
+case abc in
+a"b"c) echo 'match 1' ;;
+*) echo 'BAD match 1' ;;
+esac
+
+expect '<match 2>'
+case abc in
+a*c) echo 'match 2' ;;
+*) echo 'BAD match 2' ;;
+esac
+
+expect '<ok 1>'
+case abc in
+"a?c") echo 'bad 1' ;;
+*) echo 'ok 1' ;;
+esac
+
+expect '<ok 2>'
+case abc in
+a\*c) echo 'bad 2' ;;
+*) echo 'ok 2' ;;
+esac
+
+expect '<ok 3>'
+case abc in
+a\[b]c) echo 'bad 3' ;;
+*) echo 'ok 3' ;;
+esac
+
+expect '<ok 4>'
+case "$nosuchvar" in
+"") echo 'ok 4' ;;
+*) echo 'bad 4' ;;
+esac
+
+# This is very odd, but sh and ksh seem to agree
+expect '<ok 5>'
+case abc in
+a["\b"]c) echo 'ok 5' ;;
+*) echo 'bad 5' ;;
+esac
+
+mkdir man
+mkdir man/man1
+touch man/man1/bash.1
+expect '<man/man1/bash.1>'
+recho */man*/bash.*
+expect '<man/man1/bash.1>'
+recho $(echo */man*/bash.*)
+expect '<man/man1/bash.1>'
+recho "$(echo */man*/bash.*)"
+
+# tests with multiple `*'s
+case abc in
+a***c) echo ok 1;;
+esac
+
+case abc in
+a*****?c) echo ok 2;;
+esac
+
+case abc in
+?*****??) echo ok 3;;
+esac
+
+case abc in
+*****??) echo ok 4;;
+esac
+
+case abc in
+*****??c) echo ok 5;;
+esac
+
+case abc in
+?*****?c) echo ok 6;;
+esac
+
+case abc in
+?***?****c) echo ok 7;;
+esac
+
+case abc in
+?***?****?) echo ok 8;;
+esac
+
+case abc in
+?***?****) echo ok 9;;
+esac
+
+case abc in
+*******c) echo ok 10;;
+esac
+
+case abc in
+*******?) echo ok 11;;
+esac
+
+case abcdecdhjk in
+a*cd**?**??k) echo ok 20;;
+esac
+
+case abcdecdhjk in
+a**?**cd**?**??k) echo ok 21;;
+esac
+
+case abcdecdhjk in
+a**?**cd**?**??k***) echo ok 22;;
+esac
+
+case abcdecdhjk in
+a**?**cd**?**??***k) echo ok 23;;
+esac
+
+case abcdecdhjk in
+a**?**cd**?**??***k**) echo ok 24;;
+esac
+
+case abcdecdhjk in
+a****c**?**??*****) echo ok 25;;
+esac
+
+case '-' in
+[-abc]) echo ok 26 ;;
+esac
+
+case '-' in
+[abc-]) echo ok 27 ;;
+esac
+
+case '\' in
+\\) echo ok 28 ;;
+esac
+
+case '\' in
+[\\]) echo ok 29 ;;
+esac
+
+case '\' in
+'\') echo ok 30 ;;
+esac
+
+case '[' in
+[[]) echo ok 31 ;;
+esac
+
+# a `[' without a closing `]' is just another character to match, in the
+# bash implementation
+case '[' in
+[) echo ok 32 ;;
+esac
+
+case '[abc' in
+[*) echo 'ok 33';;
+esac
+
+# a right bracket shall lose its special meaning and represent itself in
+# a bracket expression if it occurs first in the list. -- POSIX.2 2.8.3.2
+case ']' in
+[]]) echo ok 34 ;;
+esac
+
+case '-' in
+[]-]) echo ok 35 ;;
+esac
+
+# a backslash should just escape the next character in this context
+case p in
+[a-\z]) echo ok 36 ;;
+esac
+
+# this was a bug in all versions up to bash-2.04-release
+case "/tmp" in
+[/\\]*) echo ok 37 ;;
+esac
+
+# none of these should output anything
+
+case abc in
+??**********?****?) echo bad 1;;
+esac
+
+case abc in
+??**********?****c) echo bad 2;;
+esac
+
+case abc in
+?************c****?****) echo bad 3;;
+esac
+
+case abc in
+*c*?**) echo bad 4;;
+esac
+
+case abc in
+a*****c*?**) echo bad 5;;
+esac
+
+case abc in
+a********???*******) echo bad 6;;
+esac
+
+case 'a' in
+[]) echo bad 7 ;;
+esac
+
+case '[' in
+[abc) echo bad 8;;
+esac
+
+# let's start testing the case-insensitive globbing code
+recho b*
+
+shopt -s nocaseglob
+recho b*
+
+recho [b]*
+shopt -u nocaseglob
+
+# make sure set -f works right
+set -f
+recho *
+set +f
+
+# test out the GLOBIGNORE code
+GLOBIGNORE='.*:*c:*e:?'
+recho *
+
+GLOBIGNORE='.*:*b:*d:?'
+recho *
+
+# see if GLOBIGNORE can substitute for `set -f'
+GLOBIGNORE='.*:*'
+recho *
+
+unset GLOBIGNORE
+expect '<man/man1/bash.1>'
+recho */man*/bash.*
+
+# make sure null values for GLOBIGNORE have no effect
+GLOBIGNORE=
+expect '<man/man1/bash.1>'
+recho */man*/bash.*
+
+# this is for the benefit of pure coverage, so it writes the pcv file
+# in the right place, and for gprof
+builtin cd $MYDIR
+
+rm -rf $TESTDIR
+
+exit 0
diff --git a/tests/glob1.sub b/tests/glob1.sub
new file mode 100644
index 0000000..8745cd9
--- /dev/null
+++ b/tests/glob1.sub
@@ -0,0 +1,14 @@
+# bash-2.01.1 failed this test
+FN=/tmp/bash-glob.$$
+mkdir $FN
+cd $FN
+mkdir foo
+mkdir foobar
+touch foo/bar
+touch foobar/bar
+chmod 311 foo foobar
+echo f*/bar
+
+chmod 777 foo foobar
+cd /
+rm -rf $FN
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
new file mode 100644
index 0000000..b8754de
--- /dev/null
+++ b/tests/heredoc.right
@@ -0,0 +1,64 @@
+there
+one - alpha
+two - beta
+three - gamma
+hi\
+there$a
+stuff
+hi\
+there
+EO\
+F
+hi
+hi
+tab 1
+tab 2
+tab 3
+abc
+def ghi
+jkl mno
+fff is a function
+fff ()
+{
+ ed /tmp/foo > /dev/null <<ENDOFINPUT
+/^name/d
+w
+q
+ENDOFINPUT
+
+ aa=1
+}
+fff is a function
+fff ()
+{
+ ed /tmp/foo > /dev/null <<ENDOFINPUT
+/^name/d
+w
+q
+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
new file mode 100644
index 0000000..79bf4ce
--- /dev/null
+++ b/tests/heredoc.tests
@@ -0,0 +1,100 @@
+# check order and content of multiple here docs
+
+cat << EOF1 << EOF2
+hi
+EOF1
+there
+EOF2
+
+while read line1; do
+ read line2 <&3
+ echo $line1 - $line2
+done <<EOF1 3<<EOF2
+one
+two
+three
+EOF1
+alpha
+beta
+gamma
+EOF2
+
+
+# check quoted here-doc is protected
+
+a=foo
+cat << 'EOF'
+hi\
+there$a
+stuff
+EOF
+
+# check that quoted here-documents don't have \newline processing done
+
+cat << 'EOF'
+hi\
+there
+EO\
+F
+EOF
+true
+
+# check that \newline is removed at start of here-doc
+cat << EO\
+F
+hi
+EOF
+
+# check that \newline removal works for here-doc delimiter
+cat << EOF
+hi
+EO\
+F
+
+# check operation of tab removal in here documents
+cat <<- EOF
+ tab 1
+ tab 2
+ tab 3
+ EOF
+
+# check appending of text to file from here document
+rm -f /tmp/bash-zzz
+cat > /tmp/bash-zzz << EOF
+abc
+EOF
+cat >> /tmp/bash-zzz << EOF
+def ghi
+jkl mno
+EOF
+cat /tmp/bash-zzz
+rm -f /tmp/bash-zzz
+
+# make sure command printing puts the here-document as the last redirection
+# on the line, and the function export code preserves syntactic correctness
+fff()
+{
+ ed /tmp/foo <<ENDOFINPUT >/dev/null
+/^name/d
+w
+q
+ENDOFINPUT
+aa=1
+}
+
+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!
+
+cat << EOF
+hi
+there
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/herestr.right b/tests/herestr.right
new file mode 100644
index 0000000..80b01cf
--- /dev/null
+++ b/tests/herestr.right
@@ -0,0 +1,28 @@
+abcde
+yo
+hot damn
+what a fabulous window treatment
+double"quote
+onetwothree
+first second third
+f1 ()
+{
+ cat <<< "abcde";
+ cat <<< "yo";
+ cat <<< "$a $b";
+ cat <<< 'what a fabulous window treatment';
+ cat <<< 'double"quote'
+}
+f2 ()
+{
+ cat <<< onetwothree
+}
+f3 ()
+{
+ cat <<< "$@"
+}
+echo $(echo hi)
+echo ho
+echo off to work we go
+declare -a uu='([0]="" [1]="kghfjk" [2]="jkfzuk" [3]="i
+")'
diff --git a/tests/herestr.tests b/tests/herestr.tests
new file mode 100644
index 0000000..f77b229
--- /dev/null
+++ b/tests/herestr.tests
@@ -0,0 +1,39 @@
+a=hot
+b=damn
+f1()
+{
+cat <<< "abcde"
+
+cat <<< "yo"
+
+cat <<< "$a $b"
+
+cat <<< 'what a fabulous window treatment'
+
+cat <<< 'double"quote'
+}
+
+f2()
+{
+cat <<< onetwothree
+}
+
+f3()
+{
+cat <<< "$@"
+}
+
+f1
+f2
+f3 first second third
+
+typeset -f
+
+cat <<< 'echo $(echo hi)'
+
+cat <<< "echo ho"
+
+cat <<< "echo $(echo off to work we go)"
+
+IFS="/" read -r -d $'\000' -a uu <<< /kghfjk/jkfzuk/i
+declare -p uu
diff --git a/tests/histexp.right b/tests/histexp.right
new file mode 100644
index 0000000..f1c9e9d
--- /dev/null
+++ b/tests/histexp.right
@@ -0,0 +1,129 @@
+echo $BASH_VERSION
+./histexp.tests: line 24: history: !!:z: history expansion failed
+ 1 for i in one two three; do echo $i; done
+ 2 /bin/sh -c 'echo this is $0'
+ 3 ls
+ 4 echo $BASH_VERSION
+ 1 for i in one two three; do echo $i; done
+ 2 /bin/sh -c 'echo this is $0'
+ 3 ls
+ 4 echo $BASH_VERSION
+ 5 HISTFILE=/tmp/newhistory
+ 6 echo line 2 for history
+echo line 2 for history
+echo line 2 for history
+set -H
+echo line 2 for history
+line 2 for history
+ 1 for i in one two three; do echo $i; done
+ 2 /bin/sh -c 'echo this is $0'
+ 3 ls
+ 4 echo $BASH_VERSION
+ 5 HISTFILE=/tmp/newhistory
+ 6 echo line 2 for history
+ 7 set -H
+ 8 echo line 2 for history
+a b c d e
+echo a b c d e
+a b c d e
+echo line 2 for history
+line 2 for history
+echo line 8 for history
+line 8 for history
+/bin/sh -c 'echo this is $0'
+this is /bin/sh
+echo sh
+sh
+echo /bin
+/bin
+echo e
+e
+a b c d e
+echo b c d e
+b c d e
+echo b c d
+b c d
+echo d e
+d e
+echo d e
+d e
+echo b c d
+b c d
+file.c
+echo file
+file
+echo .c
+.c
+echo 'file'
+file
+bax.c
+echo $file
+bax
+echo .c
+.c
+echo '$file'
+$file
+a b c d e
+echo 'a' 'b' 'c' 'd' 'e'
+a b c d e
+echo 'a b c d e'
+a b c d e
+foo.c foo.o foo.html foo.h
+echo bar.c foo.o foo.html foo.h
+bar.c foo.o foo.html foo.h
+echo bar.c bar.o bar.html bar.h
+bar.c bar.o bar.html bar.h
+echo xbar.c xbar.o xbar.html xbar.h
+xbar.c xbar.o xbar.html xbar.h
+echo xbar.c xbar.o xbar.html xbar.h
+xbar.c xbar.o xbar.html xbar.h
+echo xwhix.c xwhix.o xwhix.html xwhix.h
+xwhix.c xwhix.o xwhix.html xwhix.h
+echo xwhix.c xwhix.o xwhix.html xwhix.h
+echo 'xwhix'
+xwhix
+echo 'xwhix.h'
+xwhix.h
+echo 'xwhix.h'
+xwhix.h
+echo 'xwhix.h'
+xwhix.h
+ 7 set -H
+ 8 echo line 2 for history
+ 9 echo a b c d e
+ 10 echo line 2 for history
+ 11 echo line 8 for history
+ 12 /bin/sh -c 'echo this is $0'
+ 13 echo sh
+ 14 echo /bin
+ 15 echo e
+ 16 echo a b c d e
+ 17 echo b c d e
+ 18 echo b c d
+ 19 echo d e
+ 20 echo b c d
+ 21 echo file.c
+ 22 echo file
+ 23 echo .c
+ 24 echo 'file'
+ 25 echo $file.c
+ 26 echo $file
+ 27 echo .c
+ 28 echo '$file'
+ 29 echo a b c d e
+ 30 echo 'a' 'b' 'c' 'd' 'e'
+ 31 echo 'a b c d e'
+ 32 echo foo.c foo.o foo.html foo.h
+ 33 echo bar.c foo.o foo.html foo.h
+ 34 echo bar.c bar.o bar.html bar.h
+ 35 echo xbar.c xbar.o xbar.html xbar.h
+ 36 echo xwhix.c xwhix.o xwhix.html xwhix.h
+ 37 echo 'xwhix'
+ 38 echo 'xwhix.h'
+!!
+!!
+echo '!!' \!\!
+!! !!
+ok 1
+ok 2
+ok 3
diff --git a/tests/histexp.tests b/tests/histexp.tests
new file mode 100644
index 0000000..721208c
--- /dev/null
+++ b/tests/histexp.tests
@@ -0,0 +1,124 @@
+LC_ALL=C
+LANG=C
+trap 'rm /tmp/newhistory' 0
+
+file=bax
+histchars='!^#' # make sure history comment char is set correctly
+
+unset HISTFILESIZE
+
+history -c
+
+HISTFILE=history.list
+HISTCONTROL=ignoreboth
+HISTIGNORE='&:#*:history*:fc*'
+# we will end up exercising the history stifling code as a result
+HISTSIZE=32
+
+shopt -s cmdhist
+set -o history
+
+history -p '!!'
+
+# this should result in a failed history expansion error
+history -p '!!:z'
+
+history
+
+HISTFILE=/tmp/newhistory
+history -a
+
+history -w
+
+history -s "echo line 2 for history"
+history
+history -p '!e'
+history -p '!!'
+
+set -H
+!!
+!e
+
+history
+
+echo a b c d e
+!?ch?
+!-2
+^2^8
+
+!2
+
+# we're selecting /bin/sh -c ...; we want `sh'
+echo !-1:0:t
+# we're selecting /bin/sh -c ...; we want `/bin'
+echo !-2:0:h
+# we're selecting `echo a b c d e'; we want `e'
+echo !?d?:5
+
+echo a b c d e
+echo !-1:2-$
+echo !-2:2-4
+echo !-2:3*
+echo !!:*
+
+echo !?a?:2-
+
+echo file.c
+echo !!:$:r
+echo !-2:$:e
+echo !-3:$:r:q
+
+echo $file.c
+echo !!:$:r
+echo !-2:^:e
+echo !-3:$:r:q
+
+echo a b c d e
+echo !!:1-$:x
+echo !-2:1-$:q
+
+echo foo.c foo.o foo.html foo.h
+!!:s/foo/bar/
+!-2:gs/foo/bar/
+!!:gs/bar/x&/
+!-2:g&
+
+# make sure we can use any delimiter in the substitution, not just `/'
+!!:gs+bar+whix+
+
+!!:p
+
+# wow
+echo !?.o?:%:r:q
+
+!!:0 !?.h?:%:q
+!!:-$
+!:-$
+
+history
+
+# make sure single quotes inhibit history expansion
+echo '!!'
+
+# make sure backslashes can quote the history expansion character
+echo \!\!
+
+# but other expansions on the line should still be processed
+
+echo '!!' !!:*
+history -c
+unset HISTFILE
+
+# make sure that the special bash cases are not history expanded
+case p in
+[!A-Z]) echo ok 1;;
+esac
+
+var1='ok 2'
+var2=var1
+
+echo ${!var2}
+
+# Bash-2.01[.1] fails this test -- it attempts history expansion after the
+# history_expansion_char
+echo ok 3 # !1200
diff --git a/tests/history.list b/tests/history.list
new file mode 100644
index 0000000..2a4c222
--- /dev/null
+++ b/tests/history.list
@@ -0,0 +1,4 @@
+for i in one two three; do echo $i; done
+/bin/sh -c 'echo this is $0'
+ls
+echo $BASH_VERSION
diff --git a/tests/history.right b/tests/history.right
new file mode 100644
index 0000000..cb58f98
--- /dev/null
+++ b/tests/history.right
@@ -0,0 +1,146 @@
+./history.tests: line 4: history: -x: invalid option
+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] [-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
+ 4 echo $BASH_VERSION
+1 for i in one two three; do echo $i; done
+2 /bin/sh -c 'echo this is $0'
+3 ls
+4 echo $BASH_VERSION
+ for i in one two three; do echo $i; done
+ /bin/sh -c 'echo this is $0'
+ ls
+ echo $BASH_VERSION
+4 echo $BASH_VERSION
+3 ls
+2 /bin/sh -c 'echo this is $0'
+1 for i in one two three; do echo $i; done
+ echo $BASH_VERSION
+ ls
+ /bin/sh -c 'echo this is $0'
+ for i in one two three; do echo $i; done
+ 1 for i in one two three; do echo $i; done
+ 2 /bin/sh -c 'echo this is $0'
+ 3 ls
+ 4 echo $BASH_VERSION
+ 5 echo line for history
+echo line for history
+ for i in one two three; do echo $i; done
+ /bin/sh -c 'echo this is $0'
+ ls
+ echo $BASH_VERSION
+ echo line for history
+displaying $HISTFILE after history -a
+echo line for history
+HISTFILE=/tmp/newhistory
+ 1 for i in one two three; do echo $i; done
+ 2 /bin/sh -c 'echo this is $0'
+ 3 ls
+ 4 echo $BASH_VERSION
+ 5 echo line for history
+ 6 HISTFILE=/tmp/newhistory
+ 7 echo displaying \$HISTFILE after history -a
+ 8 cat $HISTFILE
+for i in one two three; do echo $i; done
+/bin/sh -c 'echo this is $0'
+ls
+echo $BASH_VERSION
+echo line for history
+HISTFILE=/tmp/newhistory
+echo displaying \$HISTFILE after history -a
+cat $HISTFILE
+ 1 for i in one two three; do echo $i; done
+ 2 /bin/sh -c 'echo this is $0'
+ 3 ls
+ 4 echo $BASH_VERSION
+ 5 echo line for history
+ 6 HISTFILE=/tmp/newhistory
+ 7 echo displaying \$HISTFILE after history -a
+ 8 cat $HISTFILE
+ 9 echo line 2 for history
+echo line 2 for history
+echo line 2 for history
+ 1 for i in one two three; do echo $i; done
+ 2 /bin/sh -c 'echo this is $0'
+ 3 ls
+ 4 echo $BASH_VERSION
+ 5 echo line for history
+ 6 HISTFILE=/tmp/newhistory
+ 7 echo displaying \$HISTFILE after history -a
+ 8 cat $HISTFILE
+ 9 echo line 2 for history
+ 10 # this should show up as one history entry
+ 11 for x in one two three; do :; done
+set -H
+echo line 2 for history
+line 2 for history
+4 echo $BASH_VERSION
+5 echo line for history
+6 HISTFILE=/tmp/newhistory
+7 echo displaying \$HISTFILE after history -a
+8 cat $HISTFILE
+9 echo line 2 for history
+10 # this should show up as one history entry
+11 for x in one two three; do :; done
+12 # just a basic test. a full test suite for history expansion should be
+13 # created
+14 set -H
+15 echo line 2 for history
+16 unset HISTSIZE
+17 unset HISTFILE
+4 echo $BASH_VERSION
+5 echo line for history
+6 HISTFILE=/tmp/newhistory
+7 echo displaying \$HISTFILE after history -a
+8 cat $HISTFILE
+./history.tests: line 75: fc: history specification out of range
+ 14 set -H
+ 15 echo line 2 for history
+ 16 unset HISTSIZE
+ 17 unset HISTFILE
+aa ab ac
+echo xx xb xc
+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
new file mode 100644
index 0000000..688095d
--- /dev/null
+++ b/tests/history.tests
@@ -0,0 +1,113 @@
+trap 'rm /tmp/newhistory' 0
+
+# bad options
+history -x
+# cannot use -r and -w at the same time
+history -r -w /dev/null
+
+# bad option
+fc -v
+
+unset HISTFILESIZE
+
+# all of these should result in an empty history list
+history -c
+history -r /dev/null
+history -n /dev/null
+history -c
+
+HISTFILE=history.list
+HISTCONTROL=ignoreboth
+HISTIGNORE='&:history*:fc*'
+HISTSIZE=32
+
+shopt -s cmdhist
+set -o history
+
+history
+
+fc -l
+fc -nl
+
+fc -lr
+fc -nlr
+
+history -s "echo line for history"
+history
+
+history -p '!!'
+
+fc -nl
+
+HISTFILE=/tmp/newhistory
+history -a
+echo displaying \$HISTFILE after history -a
+cat $HISTFILE
+
+history
+history -w
+cat $HISTFILE
+
+history -s "echo line 2 for history"
+history
+history -p '!e'
+history -p '!!'
+
+# this should show up as one history entry
+for x in one two three
+do
+ :
+done
+history
+
+# just a basic test. a full test suite for history expansion should be
+# created
+set -H
+!!
+!e
+
+unset HISTSIZE
+unset HISTFILE
+
+fc -l 4
+fc -l 4 8
+
+fc -l one=two three=four 502
+
+history 4
+
+shopt -so history
+shopt -s expand_aliases
+
+alias r="fc -s"
+
+echo aa ab ac
+
+r a=x
+r x=4 b=8
+
+# this had better fail with `no command found'
+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/ifs-posix.right b/tests/ifs-posix.right
new file mode 100644
index 0000000..f3bdccc
--- /dev/null
+++ b/tests/ifs-posix.right
@@ -0,0 +1 @@
+# tests 6856 passed 6856 failed 0
diff --git a/tests/ifs-posix.tests b/tests/ifs-posix.tests
new file mode 100644
index 0000000..cf9a898
--- /dev/null
+++ b/tests/ifs-posix.tests
@@ -0,0 +1,257 @@
+# Usage: $SHELL ifs.sh
+#
+# This script generates 6856 tests for the set(1) and read(1)
+# builtins w.r.t. IFS whitespace and non-whitespace characters.
+# Each failed test produces one line on the standard output that
+# contains the test along with the expected and actual results.
+# The last output line contains the test result counts. ordered>0
+# are the number of tests where IFS=": " produced different results
+# than IFS=" :". If a test fails the same way for IFS=": " and
+# IFS=" :" then the second output line is suppressed.
+
+TESTS=6856
+
+ksh_read=0
+echo 1 | read ksh_read
+ksh_arith=0
+eval '((ksh_arith+=1))' 2>/dev/null
+
+failed=0
+ordered=0
+passed=0
+
+split()
+{
+ i=$1 s=$2 r=$3 S='' R=''
+ for ifs in ': ' ' :'
+ do IFS=$ifs
+ set x $i
+ shift
+ IFS=' '
+ g="[$#]"
+ while :
+ do case $# in
+ 0) break ;;
+ esac
+ g="$g($1)"
+ shift
+ done
+ case $g in
+ "$s") case $ksh_arith in
+ 1) ((passed+=1)) ;;
+ *) passed=`expr $passed + 1` ;;
+ esac
+ case $S in
+ '') S=$g
+ ;;
+ "$g") ;;
+ *) case $ksh_arith in
+ 1) ((ordered+=1)) ;;
+ *) ordered=`expr $ordered + 1` ;;
+ esac
+ ;;
+ esac
+ ;;
+ "$S") case $ksh_arith in
+ 1) ((failed+=1)) ;;
+ *) failed=`expr $failed + 1` ;;
+ esac
+ ;;
+ *) case $ksh_arith in
+ 1) ((failed+=1)) ;;
+ *) failed=`expr $failed + 1` ;;
+ esac
+ case $s in
+ "$S") ;;
+ ?0*) echo "IFS=\"$ifs\"; x=\"$i\"; set x \$x; shift; echo \"[\$#]\" # expected \"$s\" got \"$g\"" ;;
+ ?1*) echo "IFS=\"$ifs\"; x=\"$i\"; set x \$x; shift; echo \"[\$#](\$1)\" # expected \"$s\" got \"$g\"" ;;
+ ?2*) echo "IFS=\"$ifs\"; x=\"$i\"; set x \$x; shift; echo \"[\$#](\$1)(\$2)\" # expected \"$s\" got \"$g\"" ;;
+ ?3*) echo "IFS=\"$ifs\"; x=\"$i\"; set x \$x; shift; echo \"[\$#](\$1)(\$2)(\$3)\" # expected \"$s\" got \"$g\"" ;;
+ *) echo TEST ERROR i="'$i'" s="'$s'" ;;
+ esac
+ case $S in
+ '') S=$g
+ ;;
+ "$g") ;;
+ *) case $ksh_arith in
+ 1) ((ordered+=1)) ;;
+ *) ordered=`expr $ordered + 1` ;;
+ esac
+ ;;
+ esac
+ esac
+ case $ksh_read in
+ 1) echo "$i" | IFS=$ifs read x y; g="($x)($y)" ;;
+ *) g=`export ifs; echo "$i" | ( IFS=$ifs; read x y; echo "($x)($y)" )` ;;
+ esac
+ case $g in
+ "$r") case $ksh_arith in
+ 1) ((passed+=1)) ;;
+ *) passed=`expr $passed + 1` ;;
+ esac
+ case $R in
+ '') R=$g
+ ;;
+ "$g") ;;
+ *) case $ksh_arith in
+ 1) ((ordered+=1)) ;;
+ *) ordered=`expr $ordered + 1` ;;
+ esac
+ ;;
+ esac
+ ;;
+ "$R") case $ksh_arith in
+ 1) ((failed+=1)) ;;
+ *) failed=`expr $failed + 1` ;;
+ esac
+ ;;
+ *) case $ksh_arith in
+ 1) ((failed+=1)) ;;
+ *) failed=`expr $failed + 1` ;;
+ esac
+ case $r in
+ "$R") ;;
+ *) echo "echo \"$i\" | ( IFS=\"$ifs\" read x y; echo \"(\$x)(\$y)\" ) # expected \"$r\" got \"$g\"" ;;
+ esac
+ case $R in
+ '') R=$g
+ ;;
+ "$g") ;;
+ *) case $ksh_arith in
+ 1) ((ordered+=1)) ;;
+ *) ordered=`expr $ordered + 1` ;;
+ esac
+ ;;
+ esac
+ ;;
+ esac
+ done
+}
+
+for str in \
+ '-' \
+ 'a' \
+ '- -' \
+ '- a' \
+ 'a -' \
+ 'a b' \
+ '- - -' \
+ '- - a' \
+ '- a -' \
+ '- a b' \
+ 'a - -' \
+ 'a - b' \
+ 'a b -' \
+ 'a b c' \
+
+do
+ IFS=' '
+ set x $str
+
+ shift
+ case $# in
+ 0) continue ;;
+ esac
+
+ f1=$1
+ case $f1 in
+ '-') f1='' ;;
+ esac
+
+ shift
+ case $# in
+ 0) for d0 in '' ' '
+ do
+ for d1 in '' ' ' ':' ' :' ': ' ' : '
+ do
+ case $f1$d1 in
+ '') split "$d0$f1$d1" "[0]" "()()" ;;
+ ' ') ;;
+ *) split "$d0$f1$d1" "[1]($f1)" "($f1)()" ;;
+ esac
+ done
+ done
+ continue
+ ;;
+ esac
+ f2=$1
+ case $f2 in
+ '-') f2='' ;;
+ esac
+
+ shift
+ case $# in
+ 0) for d0 in '' ' '
+ do
+ for d1 in ' ' ':' ' :' ': ' ' : '
+ do
+ case ' ' in
+ $f1$d1|$d1$f2) continue ;;
+ esac
+ for d2 in '' ' ' ':' ' :' ': ' ' : '
+ do
+ case $f2$d2 in
+ '') split "$d0$f1$d1$f2$d2" "[1]($f1)" "($f1)()" ;;
+ ' ') ;;
+ *) split "$d0$f1$d1$f2$d2" "[2]($f1)($f2)" "($f1)($f2)" ;;
+ esac
+ done
+ done
+ done
+ continue
+ ;;
+ esac
+ f3=$1
+ case $f3 in
+ '-') f3='' ;;
+ esac
+
+ shift
+ case $# in
+ 0) for d0 in '' ' '
+ do
+ for d1 in ':' ' :' ': ' ' : '
+ do
+ case ' ' in
+ $f1$d1|$d1$f2) continue ;;
+ esac
+ for d2 in ' ' ':' ' :' ': ' ' : '
+ do
+ case $f2$d2 in
+ ' ') continue ;;
+ esac
+ case ' ' in
+ $f2$d2|$d2$f3) continue ;;
+ esac
+ for d3 in '' ' ' ':' ' :' ': ' ' : '
+ do
+ case $f3$d3 in
+ '') split "$d0$f1$d1$f2$d2$f3$d3" "[2]($f1)($f2)" "($f1)($f2)" ;;
+ ' ') ;;
+ *) x=$f2$d2$f3$d3
+ x=${x#' '}
+ x=${x%' '}
+ split "$d0$f1$d1$f2$d2$f3$d3" "[3]($f1)($f2)($f3)" "($f1)($x)"
+ ;;
+ esac
+ done
+ done
+ done
+ done
+ continue
+ ;;
+ esac
+done
+case $ksh_arith in
+1) ((tests=passed+failed)) ;;
+*) tests=`expr $passed + $failed` ;;
+esac
+case $ordered in
+0) ordered="" ;;
+*) ordered=" ordered $ordered" ;;
+esac
+case $tests in
+$TESTS) fatal="" ;;
+*) fatal=" -- fundamental IFS error -- $TESTS tests expected"
+esac
+echo "# tests $tests passed $passed failed $failed$ordered$fatal"
diff --git a/tests/ifs.right b/tests/ifs.right
new file mode 100644
index 0000000..512f6ee
--- /dev/null
+++ b/tests/ifs.right
@@ -0,0 +1,10 @@
+a:b:c
+a:b:c
+a:b:c
+a b c d e
+a:b:c:d:e
+a b c d e
+a:b:c:d:e
+a:b:c:d:e
+a b c d e
+a b c d e
diff --git a/tests/ifs.tests b/tests/ifs.tests
new file mode 100644
index 0000000..763e2a0
--- /dev/null
+++ b/tests/ifs.tests
@@ -0,0 +1,61 @@
+OIFS="$IFS"
+IFS=":$IFS"
+eval foo="a:b:c"
+IFS="$OIFS"
+echo $foo
+
+OIFS=$IFS
+IFS=":$IFS"
+foo=$(echo a:b:c)
+IFS=$OIFS
+
+for i in $foo
+do
+ echo $i
+done
+
+OIFS=$IFS
+IFS=":$IFS"
+foo=`echo a:b:c`
+IFS=$OIFS
+
+for i in $foo
+do
+ echo $i
+done
+
+DEFIFS=$' \t\n'
+
+# local copy of IFS that shadows global version
+function f
+{
+ typeset IFS=:
+
+ echo $1
+}
+
+function ff
+{
+ echo $1
+}
+
+f a:b:c:d:e
+x=a:b:c:d:e
+echo $x
+
+IFS=: ff a:b:c:d:e
+echo $x
+
+# doesn't get word split
+IFS=$DEFIFS
+# variable assignment doesn't use new value for word splitting
+IFS=: echo $x
+# but does this time because of the eval
+IFS=: eval echo \$x
+
+# in posix mode, assignments preceding special builtins and functions are global
+set -o posix
+IFS=: export x
+echo $x
+
+IFS="$DEFIFS"
diff --git a/tests/input-line.sh b/tests/input-line.sh
new file mode 100644
index 0000000..3f66c81
--- /dev/null
+++ b/tests/input-line.sh
@@ -0,0 +1,4 @@
+echo before calling input-line.sub
+${THIS_SH} ./input-line.sub
+this line for input-line.sub
+echo finished with input-line.sub
diff --git a/tests/input-line.sub b/tests/input-line.sub
new file mode 100644
index 0000000..7bc8df2
--- /dev/null
+++ b/tests/input-line.sub
@@ -0,0 +1,2 @@
+read line
+echo line read by $0 was \`$line\'
diff --git a/tests/input.right b/tests/input.right
new file mode 100644
index 0000000..8733feb
--- /dev/null
+++ b/tests/input.right
@@ -0,0 +1,3 @@
+before calling input-line.sub
+line read by ./input-line.sub was `this line for input-line.sub'
+finished with input-line.sub
diff --git a/tests/intl.right b/tests/intl.right
new file mode 100644
index 0000000..449d5b0
--- /dev/null
+++ b/tests/intl.right
@@ -0,0 +1,13 @@
+é
+1
+AéB
+B
+B
+ok 1
+ok 2
+aéb
+0000000 141 303 251 142
+0000004
+-абвгдежзиклмноп - 16
+-абвгдежзиклмноп- 15
+-абвгд- 5
diff --git a/tests/intl.tests b/tests/intl.tests
new file mode 100644
index 0000000..cd919df
--- /dev/null
+++ b/tests/intl.tests
@@ -0,0 +1,41 @@
+export LC_ALL=en_US.UTF-8
+
+a=$'\303\251'
+
+echo "$a"
+
+echo ${#a}
+
+b=$'A\303\251B'
+
+echo "$b"
+
+echo ${b: -1}
+
+c=AeB
+
+echo ${c: -1}
+
+unset a
+a=$(printf '%b' 'A\303\251B')
+IFS=$(printf '%b' '\303\251')
+
+case "$a" in
+"A${IFS}B") echo ok 1 ;;
+*) echo bad 1 ;;
+esac
+
+set $a
+
+case $1 in
+A) echo ok 2 ;;
+*) echo bad 2 ;;
+esac
+
+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/invert.right b/tests/invert.right
new file mode 100644
index 0000000..5a9239a
--- /dev/null
+++ b/tests/invert.right
@@ -0,0 +1,10 @@
+1
+1
+1
+0
+0
+1
+0
+1
+0
+1
diff --git a/tests/invert.tests b/tests/invert.tests
new file mode 100644
index 0000000..8393d95
--- /dev/null
+++ b/tests/invert.tests
@@ -0,0 +1,19 @@
+# tests of return value inversion
+# placeholder for future expansion
+
+# user subshells (...) did this wrong in bash versions before 2.04
+
+! ( echo hello | grep h >/dev/null 2>&1 ); echo $?
+! echo hello | grep h >/dev/null 2>&1 ; echo $?
+
+! true ; echo $?
+! false; echo $?
+
+! (false) ; echo $?
+! (true); echo $?
+
+! true | false ; echo $?
+! false | true ; echo $?
+
+! (true | false) ; echo $?
+! (false | true) ; echo $?
diff --git a/tests/iquote.right b/tests/iquote.right
new file mode 100644
index 0000000..d164f10
--- /dev/null
+++ b/tests/iquote.right
@@ -0,0 +1,61 @@
+argv[1] = <xxxyyy>
+argv[1] = <xxx^?yyy>
+argv[1] = <xy>
+argv[1] = <x^?y>
+argv[1] = <-->
+argv[1] = <-^?->
+argv[1] = <>
+argv[1] = <>
+argv[1] = <^?>
+argv[1] = <^?yy>
+0x7f
+0x7f
+0x7f
+argv[1] = <^?>
+argv[1] = <^?@>
+argv[1] = <@^?@>
+argv[1] = <@^?>
+argv[1] = <^?>
+argv[1] = <^?@>
+argv[1] = <@^?@>
+argv[1] = <@^?>
+argv[1] = <1>
+argv[2] = <^?>
+argv[3] = <^?>
+argv[1] = <2>
+argv[2] = <^?a>
+argv[3] = <^?a>
+argv[1] = <2>
+argv[2] = <^?a>
+argv[3] = <^?a>
+argv[1] = <3>
+argv[2] = <^?aa>
+argv[3] = <^?aa>
+argv[1] = <>
+argv[1] = <-->
+argv[1] = <-->
+argv[1] = <^?>
+argv[1] = <-^?->
+argv[1] = <^?>
+argv[1] = <-^?->
+ok
+argv[1] = <aaa^?bbb>
+argv[1] = <ccc^?ddd>
+argv[1] = <eee^?fff>
+argv[1] = <ggg^?hhh>
+argv[1] = <aaabbb>
+argv[1] = <cccddd>
+argv[1] = <eeefff>
+argv[1] = <ggghhh>
+argv[1] = <aaa^?bbb>
+argv[1] = <ccc^?ddd>
+argv[1] = <eee^?fff>
+argv[1] = <ggg^?hhh>
+argv[1] = <aaabbb>
+argv[1] = <cccddd>
+argv[1] = <eeefff>
+argv[1] = <ggghhh>
+argv[1] = <aaa^?bbb>
+argv[1] = <ccc^?ddd>
+argv[1] = <eee^?fff>
+argv[1] = <ggg^?hhh>
diff --git a/tests/iquote.tests b/tests/iquote.tests
new file mode 100644
index 0000000..a2cdf4f
--- /dev/null
+++ b/tests/iquote.tests
@@ -0,0 +1,143 @@
+# bug in bash up to and including bash-3.0 (including patches)
+#
+# problem is conflict between CTLNUL used internally to denote quoted null
+# characters and its value (0x7f) appearing in the expansion of a variable
+#
+unset x
+recho "xxx${x}yyy"
+
+y=$'\177'
+recho "xxx${y}yyy"
+
+unset y
+
+unset undef
+
+set ""
+recho ${undef-"x$*y"}
+
+set $'\177'
+recho ${undef-"x$*y"}
+
+shift $#
+
+f()
+{
+ recho "-${*-x}-"
+}
+
+f ''
+f $'\177'
+
+unset -f f
+
+x=12345
+
+recho "${x:6:1}"
+
+x=
+recho "${x:0:1}"
+
+y=$'\177'
+recho "${y:0:1}"
+
+y=xxx$'\177'yyy
+recho "${y:3:3}"
+
+unset x y
+
+eval tmp=`printf "$'\\\\\x%x'\n" 127`
+printf "%#1x\n" "'$tmp"
+
+x=$'\177'
+printf "%#1x\n" "'$x"
+
+a=127
+eval c=\$\'\\$(printf '%o' $a)\'
+printf "%#1x\n" "'$c"
+
+recho "$c"
+recho "$c"@
+recho @"$c"@
+recho @"$c"
+
+recho "$c"
+recho "$c@"
+recho "@$c@"
+recho "@$c"
+
+unset tmp x a c
+
+qtest()
+{
+ recho ${#q} "${q}" ${q}
+}
+
+q=$'\x7f'
+qtest
+
+q=${q}a
+qtest
+
+q=$'\x7fa'
+qtest
+
+q="${q}a"
+qtest
+
+unset -f qtest
+unset q
+
+set -- ''
+recho "${*:1}"
+recho ${*:1}
+recho -${*:1}-
+recho -"${*:1}"-
+
+set $'\177'
+recho "${*:1}"
+recho "-${*:1}-"
+
+recho ${*:1}
+recho -${*:1}-
+
+shift $#
+
+DEL=`awk 'END{printf("%c", 0+127)}' </dev/null`
+T1=a\ $DEL
+T2="a $DEL"
+set -- x $(echo $T1|wc -c) $(echo $T2|wc -c); shift
+L1=$1; L2=$2
+case "$L1/$L2" in
+4/4) echo ok;;
+*) echo CTLNUL bug: L1=$L1, L2=$L2;;
+esac
+
+x=$'\177'
+recho "aaa${x}bbb"
+recho ccc"${x}"ddd
+recho eee"$x"fff
+recho ggg"$(echo $x)"hhh
+
+x=
+recho "aaa${x}bbb"
+recho ccc"${x}"ddd
+recho eee"$x"fff
+recho ggg"$(echo $x)"hhh
+
+set -- $'\177'
+recho "aaa${1}bbb"
+recho ccc"${1}"ddd
+recho eee"$1"fff
+recho ggg"$(echo $1)"hhh
+
+set -- ""
+recho "aaa${1}bbb"
+recho ccc"${1}"ddd
+recho eee"$1"fff
+recho ggg"$(echo $1)"hhh
+
+recho aaa$'\177'bbb
+recho ccc""ddd
+recho "eeefff"
+recho ggg"$(echo $'\177')"hhh
diff --git a/tests/jobs.right b/tests/jobs.right
new file mode 100644
index 0000000..a4c8a7c
--- /dev/null
+++ b/tests/jobs.right
@@ -0,0 +1,105 @@
+./jobs2.sub: line 9: fg: job 1 started without job control
+fg: 1
+Waiting for job 0
+job 0 returns 0
+Waiting for job 1
+job 1 returns 0
+Waiting for job 2
+job 2 returns 0
+Waiting for job 3
+job 3 returns 0
+Waiting for job 4
+job 4 returns 0
+Waiting for job 5
+job 5 returns 0
+Waiting for job 6
+job 6 returns 0
+Waiting for job 7
+job 7 returns 0
+[1] Running sleep 5 &
+[2] Running sleep 5 &
+[3] Running sleep 5 &
+[4]- Running sleep 5 &
+[5]+ Running ( sleep 5; exit 4 ) &
+4
+0
+i killed it
+0
+./jobs.tests: line 19: wait: %1: no such job
+./jobs.tests: line 24: fg: no job control
+wait-for-pid
+wait-errors
+./jobs.tests: line 37: wait: `1-1': not a pid or valid job spec
+./jobs.tests: line 38: wait: `-4': not a pid or valid job spec
+wait-for-background-pids
+async list wait-for-background-pids
+async list wait for child
+forked
+wait-when-no-children
+wait-for-job
+./jobs.tests: line 60: wait: %2: no such job
+127
+async list wait-for-job
+forked
+fg-bg 1
+sleep 5
+fg-bg 2
+sleep 5
+fg-bg 3
+sleep 5
+fg-bg 4
+sleep 5
+fg-bg 5
+./jobs.tests: line 87: fg: %2: no such job
+./jobs.tests: line 88: bg: job 1 already in background
+fg-bg 6
+./jobs.tests: line 95: fg: -s: invalid option
+fg: usage: fg [job_spec]
+./jobs.tests: line 96: bg: -s: invalid option
+bg: usage: bg [job_spec ...]
+./jobs.tests: line 101: disown: -s: invalid option
+disown: usage: disown [-h] [-ar] [jobspec ...]
+./jobs.tests: line 105: disown: %1: no such job
+./jobs.tests: line 108: disown: %2: no such job
+wait-for-non-child
+./jobs.tests: line 111: wait: pid 1 is not a child of this shell
+127
+3 -- 1 2 3 -- 1 - 2 - 3
+[1] Running sleep 300 &
+[2]- Running sleep 350 &
+[3]+ Running sleep 400 &
+running jobs:
+[1] Running sleep 300 &
+[2]- Running sleep 350 &
+[3]+ Running sleep 400 &
+./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:
+[2]- Running sleep 350 &
+after kill -STOP
+running jobs:
+[1] Running sleep 300 &
+[3]- Running sleep 400 &
+stopped jobs:
+[2]+ Stopped sleep 350
+after disown
+[2]+ Stopped sleep 350
+[3]- Running sleep 400 &
+running jobs:
+[3]- Running sleep 400 &
+stopped jobs:
+[2]+ Stopped sleep 350
+after kill -s CONT
+running jobs:
+[2]+ Running sleep 350 &
+[3]- Running sleep 400 &
+stopped jobs:
+after kill -STOP, backgrounding %3:
+[3]+ sleep 400 &
+killing...
+done
+after KILL -STOP, foregrounding %1
+sleep 10
+done
diff --git a/tests/jobs.tests b/tests/jobs.tests
new file mode 100644
index 0000000..e2acba5
--- /dev/null
+++ b/tests/jobs.tests
@@ -0,0 +1,185 @@
+# test out %+, jobs -p, and $! agreement in a subshell first
+${THIS_SH} ./jobs1.sub
+
+# test out fg/bg failure in a subshell
+${THIS_SH} ./jobs2.sub
+
+# test out behavior of waiting for background pids -- bug in versions
+# before 2.03
+${THIS_SH} ./jobs3.sub
+
+# test out behavior of using job control notation when job control is not
+# active
+${THIS_SH} ./jobs4.sub
+
+jobs
+echo $?
+
+# a no-such-job error, since we can use job control notation without job control
+wait %1
+
+# make sure we can't fg a job started when job control was not active
+sleep 30 &
+pid=$!
+fg %1
+# make sure the killed processes don't cause a message
+exec 5>&2
+exec 2>/dev/null
+kill -n 9 $pid
+wait # make sure we reap the processes while stderr is still redirected
+exec 2>&5
+
+echo wait-for-pid
+sleep 10 &
+wait $!
+
+echo wait-errors
+wait 1-1
+wait -- -4
+
+echo wait-for-background-pids
+sleep 5 &
+sleep 8 &
+wait
+
+echo async list wait-for-background-pids
+sleep 5 & sleep 8 &
+wait
+
+echo async list wait for child
+sleep 5 & echo forked
+wait
+
+echo wait-when-no-children
+wait
+
+set -m
+
+echo wait-for-job
+sleep 5 &
+wait %2 # this should be a no-such-job error
+echo $?
+wait %1
+
+echo async list wait-for-job
+sleep 5 & echo forked
+wait %1
+
+echo fg-bg 1
+sleep 5 &
+%1
+
+echo fg-bg 2
+sleep 5 &
+fg %%
+
+echo fg-bg 3
+sleep 5 &
+fg %s
+
+echo fg-bg 4
+sleep 5 &
+fg %?ee
+
+# these next two are error cases
+echo fg-bg 5
+sleep 15 &
+fg %2 # this should be a no-such-job error
+bg %1 # this should be a `bg background job?' error
+wait
+
+# these may someday mean to start the jobs, but not print the line
+# describing the status, but for now they are errors
+echo fg-bg 6
+sleep 5 &
+fg -s %1
+bg -s %1
+wait
+
+# someday this may mean to disown all stopped jobs, but for now it is
+# an error
+disown -s
+
+# this is an error -- the job with the pid that is the value of $! is
+# retained only until a `wait' is performed
+disown %1
+
+# this, however, is an error
+disown %2
+
+echo wait-for-non-child
+wait 1
+echo $?
+
+exit 1 | exit 2 | exit 3
+echo $? -- ${PIPESTATUS[@]} -- ${PIPESTATUS[0]} - ${PIPESTATUS[1]} - ${PIPESTATUS[2]}
+
+sleep 300 &
+sleep300pid=$!
+sleep 350 &
+sleep 400 &
+
+jobs
+
+echo running jobs:
+jobs -r
+
+# should be an error
+kill -n 1 %4
+# should be an error
+jobs %4
+echo current job:
+jobs %+
+echo previous job:
+jobs %-
+
+kill -STOP %2
+sleep 5 # give time for the shell to get the stop notification
+echo after kill -STOP
+echo running jobs:
+jobs -r
+echo stopped jobs:
+jobs -s
+
+disown %1
+
+echo after disown
+jobs
+echo running jobs:
+jobs -r
+echo stopped jobs:
+jobs -s
+
+kill -s CONT %2
+echo after kill -s CONT
+echo running jobs:
+jobs -r
+echo stopped jobs:
+jobs -s
+
+kill -STOP %3
+sleep 5 # give time for the shell to get the stop notification
+echo after kill -STOP, backgrounding %3:
+bg %3
+
+disown -h %2
+
+# make sure the killed processes don't cause a message
+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
+
+exec 2>&5
+
+sleep 10 &
+kill -STOP %1
+sleep 5 # give time for the shell to get the stop notification
+echo after KILL -STOP, foregrounding %1
+fg %1
+
+echo done
diff --git a/tests/jobs1.sub b/tests/jobs1.sub
new file mode 100644
index 0000000..aa9a372
--- /dev/null
+++ b/tests/jobs1.sub
@@ -0,0 +1,17 @@
+# make sure that jobs -p, %+, and $! all agree
+set -m
+sleep 60 &
+
+FN=/tmp/jobs-pid.$$
+
+pid1=$!
+jobs -p %+ > $FN
+pid2=$(< $FN)
+rm $FN
+
+if [ $pid1 -ne $pid2 ]; then
+ echo 'oops - $! and jobs -p %+ disagree!'
+fi
+
+exec 2>/dev/null
+kill -9 $pid1
diff --git a/tests/jobs2.sub b/tests/jobs2.sub
new file mode 100644
index 0000000..496519b
--- /dev/null
+++ b/tests/jobs2.sub
@@ -0,0 +1,13 @@
+# make sure fg and bg don't work on jobs started without job control,
+# even if they are executed when job control is active
+set +o monitor
+
+sleep 30 &
+pid=$!
+
+set -m
+fg %1
+echo fg: $?
+
+exec 2>/dev/null
+kill -9 $pid
diff --git a/tests/jobs3.sub b/tests/jobs3.sub
new file mode 100644
index 0000000..6efd58b
--- /dev/null
+++ b/tests/jobs3.sub
@@ -0,0 +1,26 @@
+#! /bin/bash
+NJOB=8
+i=0
+
+while [ $i -lt $NJOB ]
+do
+ /bin/sh -c "sleep 4; exit 0" &
+ rv=$?
+ pid=$!
+ eval bg_pid_$i=$pid
+# echo $$: Job $i: pid is $pid rv=$rv
+ i=$((i + 1))
+done
+
+
+
+i=0
+while [ $i -lt $NJOB ]
+do
+ eval wpid=\$bg_pid_$i
+ echo Waiting for job $i #'('pid $wpid')'
+ wait $wpid
+ rv=$?
+ echo job $i returns $rv
+ i=$((i + 1))
+done
diff --git a/tests/jobs4.sub b/tests/jobs4.sub
new file mode 100644
index 0000000..2eb4197
--- /dev/null
+++ b/tests/jobs4.sub
@@ -0,0 +1,24 @@
+# test being able to use job control notation in jobs/kill/wait without
+# job control active, as the SUS requires
+
+sleep 5 &
+
+sleep 5 &
+sleep 5 &
+sleep 5 &
+(sleep 5 ; exit 4) &
+
+jobs
+
+wait %%
+echo $?
+
+wait %1
+echo $?
+
+wait
+
+# the sleep is intended to give the kill time to execute before the job
+# exits
+(sleep 1 ; cat ) &
+kill -1 %% && echo i killed it || echo could not kill it
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/misc/dev-tcp.tests b/tests/misc/dev-tcp.tests
new file mode 100644
index 0000000..0f3a228
--- /dev/null
+++ b/tests/misc/dev-tcp.tests
@@ -0,0 +1,16 @@
+exec 9<>/dev/tcp/129.22.8.162/25
+
+read banner <&9
+echo "$banner"
+
+echo quit >&9
+
+read msg <&9
+echo "$msg"
+
+exec 9<&-
+
+# nifty date command that queries the date/time server
+cat < /dev/tcp/129.22.8.102/13
+
+exit 0
diff --git a/tests/misc/perf-script b/tests/misc/perf-script
new file mode 100644
index 0000000..e1172a9
--- /dev/null
+++ b/tests/misc/perf-script
@@ -0,0 +1,81 @@
+#!/bin/bash
+
+typeset -i m2 m1 M n2 n1 N m n
+typeset -i MM=5 NN=5
+
+case $# in
+ 0) :
+ ;;
+ 1) MM=$1; NN=$1
+ ;;
+ 2) MM=$1; NN=$2
+ ;;
+ *) echo 1>&2 "Usage: $0 [m [n]]"
+ ;;
+esac
+
+EMPTYLINE=: # echo
+echo 'a = { ' # mathematica
+
+let "M=1" # for (M=1; M<=MM; M++)
+while let "M <= MM"; do
+ let "N=1" # for (N=1; N<=NN; N++)
+ while let "N <= NN"; do
+
+ let "m1 = M - 1"
+ let "m2 = M + 1"
+ let "n1 = N - 1"
+ let "n2 = N + 1"
+
+
+ echo -n '{ ' # math
+ let "m=1" # for(m=1; m<=MM; m++)
+ while let "m <= MM"; do
+ let "n=1" # for(n=1; n<=NN; n++)
+ while let "n <= NN"; do
+
+ let "x = (m-m1)*(m-M)*(m-m2)"
+ let "y = (n-n1)*(n-N)*(n-n2)"
+
+ if let "(x*x + (n-N)*(n-N)) * ((m-M)*(m-M) + y*y)"; then
+ echo -n "0,"
+ else # neighbour
+ echo -n "1,"
+ fi
+
+ let "n=n+1"
+ done
+ echo -n " "; let "m=m+1" # ". "
+ done
+ echo '},'
+
+
+ let "N=N+1"
+ $EMPTYLINE
+ done
+ $EMPTYLINE
+ let "M=M+1"
+done
+
+echo '}'
+
+
+
+echo -n 'o = { '
+let "m=1"
+while let "m <= MM"; do
+ let "n=1"
+ while let "n <= NN"; do
+ echo -n "1,"
+ let "n=n+1"
+ done
+ let "m=m+1"
+done
+echo " }"
+
+
+echo 'x = LinearSolve[a,o] '
+
+exit 0
+
+
diff --git a/tests/misc/perftest b/tests/misc/perftest
new file mode 100644
index 0000000..ee3f2c6
--- /dev/null
+++ b/tests/misc/perftest
@@ -0,0 +1,10 @@
+# originally from Mike Haertel
+foo() { case $1 in a*) ;; *) ;; esac ;}
+bar() { case $1 in [abc]*) ;; *);; esac ;}
+baz() { case $1 in xyzzy) ;; *) ;; esac ;}
+for x in /usr/lib/*/*
+do
+ foo $x
+ bar $x
+ baz $x
+done
diff --git a/tests/misc/read-nchars.tests b/tests/misc/read-nchars.tests
new file mode 100644
index 0000000..40b1f98
--- /dev/null
+++ b/tests/misc/read-nchars.tests
@@ -0,0 +1,11 @@
+# interactive
+
+# from tty
+read -n 3 -p 'enter three chars: ' xyz
+echo
+echo $xyz
+
+# using readline
+read -p 'enter 3 chars: ' -e -n 3 abc
+# readline outputs a newline for us, so we don't need the extra echo
+echo $abc
diff --git a/tests/misc/redir-t2.sh b/tests/misc/redir-t2.sh
new file mode 100644
index 0000000..44b2624
--- /dev/null
+++ b/tests/misc/redir-t2.sh
@@ -0,0 +1,17 @@
+read line1
+
+echo read line 1 \"$line1\"
+
+exec 4<&0
+
+exec 0</dev/tty
+
+read line2
+
+echo line read from tty = \"$line2\"
+
+exec 0<&4
+
+read line3
+
+echo read line 3 \"$line3\"
diff --git a/tests/misc/run-r2.sh b/tests/misc/run-r2.sh
new file mode 100755
index 0000000..0321a1b
--- /dev/null
+++ b/tests/misc/run-r2.sh
@@ -0,0 +1 @@
+../../bash ./redir-t2.sh < /etc/passwd
diff --git a/tests/misc/sigint-1.sh b/tests/misc/sigint-1.sh
new file mode 100755
index 0000000..7b74c30
--- /dev/null
+++ b/tests/misc/sigint-1.sh
@@ -0,0 +1,9 @@
+echo before trap
+trap 'echo caught sigint' 2
+echo after trap
+
+for i in 1 2 3
+do
+ echo $i
+ sleep 5
+done
diff --git a/tests/misc/sigint-2.sh b/tests/misc/sigint-2.sh
new file mode 100755
index 0000000..69eaf56
--- /dev/null
+++ b/tests/misc/sigint-2.sh
@@ -0,0 +1,7 @@
+echo before loop
+
+for i in 1 2 3
+do
+ echo $i
+ sleep 5
+done
diff --git a/tests/misc/sigint-3.sh b/tests/misc/sigint-3.sh
new file mode 100755
index 0000000..2627fe6
--- /dev/null
+++ b/tests/misc/sigint-3.sh
@@ -0,0 +1,11 @@
+sleep 5 &
+sleep 5 &
+sleep 5 &
+
+echo wait 1
+wait
+
+echo wait 2
+wait
+
+exit
diff --git a/tests/misc/sigint-4.sh b/tests/misc/sigint-4.sh
new file mode 100755
index 0000000..587dd26
--- /dev/null
+++ b/tests/misc/sigint-4.sh
@@ -0,0 +1,13 @@
+trap 'echo sigint' 2
+
+sleep 5 &
+sleep 5 &
+sleep 5 &
+
+echo wait 1
+wait
+
+echo wait 2
+wait
+
+exit
diff --git a/tests/misc/test-minus-e.1 b/tests/misc/test-minus-e.1
new file mode 100644
index 0000000..77cc3f2
--- /dev/null
+++ b/tests/misc/test-minus-e.1
@@ -0,0 +1,9 @@
+touch .file
+while set -e ; test -r .file ; do
+ echo -n "stop loop? "
+ read reply
+ case "$reply" in
+ y*) rm .file non-dash-file ;;
+ esac
+ set +e
+done
diff --git a/tests/misc/test-minus-e.2 b/tests/misc/test-minus-e.2
new file mode 100644
index 0000000..f66966e
--- /dev/null
+++ b/tests/misc/test-minus-e.2
@@ -0,0 +1,11 @@
+touch .file
+set -e
+while set +e ; test -r .file ; do
+ echo -n "stop loop? [yes to quit] "
+ read reply
+ if [ "$reply" = yes ] ; then
+ rm .file non-dash-file
+ fi
+ set -e
+done
+rm -f .file
diff --git a/tests/misc/wait-bg.tests b/tests/misc/wait-bg.tests
new file mode 100644
index 0000000..95c98b0
--- /dev/null
+++ b/tests/misc/wait-bg.tests
@@ -0,0 +1,25 @@
+#! /bin/bash
+
+i=0
+while [ $i -lt $1 ]
+do
+ /bin/sh -c "sleep 4; exit 0" &
+ rv=$?
+ pid=$!
+ eval bg_pid_$i=$pid
+ echo $$: Job $i: pid is $pid rv=$rv
+ i=$((i + 1))
+done
+
+
+
+i=0
+while [ $i -lt $1 ]
+do
+ eval wpid=\$bg_pid_$i
+ echo Waiting for job $i '('pid $wpid')'
+ wait $wpid
+ rv=$?
+ echo Return value is $rv
+ i=$((i + 1))
+done
diff --git a/tests/more-exp.right b/tests/more-exp.right
new file mode 100644
index 0000000..91a375c
--- /dev/null
+++ b/tests/more-exp.right
@@ -0,0 +1,214 @@
+argv[1] = <aaa bbb ccc>
+argv[1] = <aaa bbb ccc>
+argv[1] = <baz:bar>
+argv[1] = <baz:bar>
+argv[1] = <aaa bbb ccc>
+argv[1] = <bar>
+argv[1] = <bar>
+argv[1] = <bar>
+argv[1] = <abcde>
+argv[1] = <abcde>
+argv[1] = <xyz>
+argv[1] = <a b>
+argv[2] = <c>
+argv[3] = <d>
+argv[4] = <e>
+argv[5] = <f>
+argv[1] = <a b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a b>
+argv[2] = <c>
+argv[3] = <d>
+argv[4] = <e>
+argv[5] = <f>
+argv[1] = <a b>
+argv[2] = <c>
+argv[3] = <d>
+argv[4] = <e>
+argv[5] = <f>
+argv[1] = </usr/homes/chet>
+argv[1] = <~>
+argv[1] = <~>
+argv[1] = <\~>
+argv[1] = <\ \~>
+argv[1] = <\ \ \~>
+argv[1] = </usr/homes/chet>
+argv[1] = </usr/homes/chet>
+argv[1] = </usr/homes/chet>
+argv[1] = <$HOME>
+argv[1] = <\ $HOME>
+argv[1] = <\ \ $HOME>
+argv[1] = <'bar'>
+argv[1] = <'bar'>
+argv[1] = <*@>
+argv[1] = <*@>
+argv[1] = <*@>
+argv[1] = <*@>
+argv[1] = <*@*>
+argv[1] = <*@*>
+argv[1] = <*@*>
+argv[1] = <*@*>
+argv[1] = <abcd>
+argv[1] = <efghijkl>
+argv[1] = <4>
+argv[2] = <2>
+argv[1] = <1>
+argv[1] = <bar>
+argv[1] = <2>
+argv[1] = <bar>
+argv[1] = <2>
+argv[1] = <4>
+argv[1] = <--\>
+argv[2] = <-->
+argv[1] = <--\^J-->
+argv[1] = <--+\>
+argv[2] = <+-->
+argv[1] = <--+\^J+-->
+argv[1] = <-+\>
+argv[2] = <+-\>
+argv[3] = <->
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <x>
+argv[1] = <x>
+argv[1] = <>
+argv[1] = <x>
+argv[1] = <x>
+argv[1] = <x>
+argv[1] = <x>
+argv[1] = <^?>
+argv[1] = <^?>
+argv[1] = <x>
+argv[1] = <x>
+argv[1] = <>
+argv[2] = <abd>
+argv[3] = <x>
+argv[1] = <>
+argv[2] = <abd>
+argv[3] = <>
+argv[1] = <a,b,c,d,e,f>
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <c>
+argv[4] = <d>
+argv[5] = <e>
+argv[6] = <f>
+./more-exp.tests: line 272: abc=def: command not found
+argv[1] = <a b c d e>
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <c>
+argv[4] = <d>
+argv[5] = <e>
+argv[1] = <foo)>
+argv[1] = <a>
+argv[1] = <\a>
+argv[1] = <\a>
+argv[1] = <\a>
+argv[1] = <\a>
+argv[1] = <\\a>
+argv[1] = <a>
+argv[1] = <\a>
+argv[1] = <\a>
+argv[1] = <\a>
+argv[1] = <\a>
+argv[1] = <\\a>
+argv[1] = <a>
+argv[1] = <a>
+argv[1] = <\a>
+argv[1] = <\a>
+argv[1] = <\a>
+argv[1] = <\a>
+argv[1] = <$a>
+argv[1] = <\foo>
+argv[1] = <$a>
+argv[1] = <\foo>
+argv[1] = <\$a>
+argv[1] = <\\$a>
+argv[1] = <a>
+argv[1] = <a>
+argv[1] = <\a>
+argv[1] = <\a>
+argv[1] = <\a>
+argv[1] = <\a>
+argv[1] = <G>
+argv[2] = <{>
+argv[3] = <I>
+argv[4] = <K>
+argv[5] = <}>
+argv[1] = <hi>
+argv[2] = <K>
+argv[3] = <}>
+argv[1] = <a*>
+Number of args: 0
+<${*-x}>: <x>
+<${@-x}>: <x>
+Number of args: 1
+<${*-x}>: <>
+<${@-x}>: <>
+Number of args: 2
+<${*-x}>: < >
+<${@-x}>: < >
+argv[1] = <5>
+argv[1] = <5>
+argv[1] = <5>
+argv[1] = <5>
+argv[1] = <5>
+argv[1] = <0>
+argv[1] = <0>
+argv[1] = <0>
+argv[1] = <0>
+argv[1] = <0>
+argv[1] = <0>
+argv[1] = <posparams>
+argv[1] = <posparams>
+argv[1] = <2>
+argv[1] = <0>
+argv[1] = <0>
+argv[1] = <1>
+argv[1] = <5>
+argv[1] = <5>
+argv[1] = <0>
+./more-exp.tests: line 423: ${#:}: bad substitution
+./more-exp.tests: line 425: ${#/}: bad substitution
+./more-exp.tests: line 427: ${#%}: bad substitution
+./more-exp.tests: line 429: ${#=}: bad substitution
+./more-exp.tests: line 431: ${#+}: bad substitution
+./more-exp.tests: line 433: ${#1xyz}: bad substitution
+./more-exp.tests: line 436: #: %: syntax error: operand expected (error token is "%")
+argv[1] = <0>
+argv[1] = <a+b>
+argv[1] = <+>
+argv[1] = <+>
+argv[1] = <+>
+argv[1] = <G { I >
+argv[2] = <K>
+argv[3] = <}>
+argv[1] = <hi>
+argv[2] = <K>
+argv[3] = <}>
+argv[1] = <xxx>
+argv[2] = <yyy>
+1
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <:a:>
+argv[1] = <:b:>
+argv[1] = <>
+argv[1] = <>
diff --git a/tests/more-exp.tests b/tests/more-exp.tests
new file mode 100644
index 0000000..4a3cb7f
--- /dev/null
+++ b/tests/more-exp.tests
@@ -0,0 +1,504 @@
+expect()
+{
+ echo expect "$@"
+}
+
+tool_var() {
+ eval $1=\"\${$1:-$2}\"
+ export $1
+}
+
+A="aaa bbb ccc"
+
+unset B
+
+tool_var B ${B:-"$A"}
+
+expect '<aaa bbb ccc>'
+recho "$A"
+expect '<aaa bbb ccc>'
+recho "$B"
+
+eto_prepend() {
+ eval $1=\'$2\''${'$1':+":"${'$1'}}'; export $1
+}
+
+foo=bar; export foo
+eto_prepend foo baz
+expect '<baz:bar>'
+recho $foo
+expect '<baz:bar>'
+recho ${foo-"bar"}
+
+aa='aaa bbb ccc'
+
+expect '<aaa bbb ccc>'
+recho ${zzz-"$aa"}
+expect '<bar>'
+recho ${zzz:-"bar"}
+expect '<bar>'
+recho "${zzz:-bar}"
+expect '<bar>'
+recho "${zzz:-"bar"}"
+
+var=abcde
+expect '<abcde>'
+recho "${var:-xyz}"
+expect '<abcde>'
+recho "${var:=xyz}"
+expect '<xyz>'
+recho "${var:+xyz}"
+
+set 'a b' c d e f
+expect '<a b> <c> <d> <e> <f>'
+recho ${1+"$@"}
+expect '<a b>'
+recho "${1-"$@"}"
+expect '<a> <b>'
+recho ${1-"$@"}
+expect '<a b> <c> <d> <e> <f>'
+recho "${1+$@}"
+expect '<a b> <c> <d> <e> <f>'
+recho "${1+"$@"}"
+
+HOME=/usr/homes/chet
+somevar=
+expect "<$HOME>"
+recho ${somevar:-~}
+# This changed after bash-3.0, when the tilde implementation was redone. It's
+# not backward compatible, but it's very hard to be backward-compatible here,
+# and I think the old behavior was a bug
+expect '<~>'
+recho "${somevar:-~}"
+expect '<~>'
+recho "${somevar:-"~"}"
+expect '<\~>'
+recho "${somevar:-\~}"
+expect '<\ \~>'
+recho "${somevar:-\ \~}"
+expect '<\ \ \~>'
+recho "${somevar:-\ \ \~}"
+
+expect "<$HOME>"
+recho ${somevar:-$HOME}
+expect "<$HOME>"
+recho "${somevar:-$HOME}"
+expect "<$HOME>"
+recho "${somevar:-"$HOME"}"
+expect '<$HOME>'
+recho "${somevar:-\$HOME}"
+expect '<\ $HOME>'
+recho "${somevar:-\ \$HOME}"
+expect '<\ \ $HOME>'
+recho "${somevar:-\ \ \$HOME}"
+
+foo=bar
+expect "<'bar'>"
+recho "${foo+'$foo'}"
+expect "<'bar'>"
+recho "${fox='$foo'}"
+
+P='*@*'
+expect '<*@>'
+recho "${P%"*"}"
+expect '<*@>'
+recho "${P%'*'}"
+
+expect '<*@>'
+recho ${P%"*"}
+expect '<*@>'
+recho ${P%'*'}
+
+expect '<*@*>'
+recho ${P%""}
+expect '<*@*>'
+recho ${P#""}
+
+expect '<*@*>'
+recho ${P#"$foobar"}
+expect '<*@*>'
+recho ${P%"$foobar"}
+
+s1=abcdefghijkl
+s2=efgh
+
+first=${s1/$s2*/}
+expect '<abcd>'
+recho $first
+
+last=${s1##$first}
+expect '<efghijkl>'
+recho $last
+
+shift $#
+UNAME_RELEASE=${1:-4.2MP}
+
+RELEASE=`expr "$UNAME_RELEASE" : '[^0-9]*\([0-9]*\)'` # 4
+case "$RELEASE" in
+"") RELEASE=0 ;;
+*) RELEASE=`expr "$RELEASE" + 0` ;;
+esac
+REL_LEVEL=`expr "$UNAME_RELEASE" : '[^0-9]*[0-9]*.\([0-9]*\)'` # 1
+REL_SUBLEVEL=`expr "$UNAME_RELEASE" : '[^0-9]*[0-9]*.[0-9]*.\([0-9]*\)'` # 2
+
+expect '<4> <2>'
+recho $RELEASE $REL_LEVEL $REL_SUBLEVEL
+
+b1()
+{
+ b2 ${1+"$@"}
+}
+
+b2()
+{
+ recho $*
+ recho $#
+}
+
+expect '<1>'
+b1 ''
+
+expect '<bar> <2>'
+b1 bar ''
+
+expect '<bar> <2>'
+b1 '' bar
+
+expect '<4>'
+b1 '' '' '' ''
+
+NL="\\
+"
+
+NNL="+$NL+"
+
+expect '<--\> <-->'
+recho --$NL--
+expect '<--\^J-->'
+recho "--$NL--"
+
+expect '<--+\> <+-->'
+recho --$NNL--
+expect '<--+\^J+-->'
+recho "--$NNL--"
+
+expect '<-+\> <+-\> <->'
+recho -$NNL-$NL-
+
+set ''
+expect '<xy>'
+recho "$*xy"
+expect '<xy>'
+recho "x$*y"
+expect '<xy>'
+recho "xy$*"
+expect '<xy>'
+recho x"$*"y
+expect '<xy>'
+recho xy"$*"
+expect '<xy>'
+recho "$*"xy
+expect '<>'
+recho "$*"
+expect nothing
+recho $*
+
+unset undef ; set ""
+
+expect '<>'
+recho ${undef-"$*"}
+expect '<xy>'
+recho ${undef-"x$*y"}
+expect '<xy>'
+recho ${undef-"$*xy"}
+expect '<xy>'
+recho ${undef-"xy$*"}
+expect '<xy>'
+recho ${undef-x"$*"y}
+expect '<xy>'
+recho ${undef-xy"$*"}
+expect '<xy>'
+recho ${undef-"$*"xy}
+expect '<>'
+recho "${undef-$*}"
+expect nothing
+recho ${undef-$*}
+
+expect '<>'
+recho ${undef-"$zzz"}
+expect '<x>'
+recho x${undef-"$zzz"}
+expect '<x>'
+recho x${undef-"$@"}
+expect nothing
+recho ${undef-"$@"}
+expect '<x>'
+recho ${undef-"$zzz"}x
+expect '<x>'
+recho ${undef-"$@"}x
+expect '<x>'
+recho "$@"x
+expect '<x>'
+recho "$zzz"x
+expect '<^?>'
+recho ${undef-}
+expect '<^?>'
+recho ${undef-""}
+
+yyy=""
+recho "$xxx"x
+recho "$yyy"x
+
+set "" "abd" ""
+recho "$@"x
+recho "$@"$xxx
+
+OIFS="$IFS"
+
+arg=a,b,c,d,e,f
+
+IFS=,
+
+export z=$arg
+
+eval z1=\"$arg\"
+
+IFS="$OIFS"
+
+recho $z
+recho $z1
+
+# should give an error
+abc\=def
+
+zz="a b c d e"
+declare a=$zz
+
+recho "$a"
+recho $a
+
+recho $(echo "foo$(echo ")")")
+
+# test backslash escapes
+
+recho \a
+recho \\a
+
+recho "\a"
+recho "\\a"
+
+recho '\a'
+recho '\\a'
+
+recho $(zecho \a)
+recho $(zecho \\a)
+
+recho $(zecho "\a")
+recho $(zecho "\\a")
+
+recho $(zecho '\a')
+recho $(zecho '\\a')
+
+recho `zecho \a`
+recho `zecho \\a`
+
+recho `zecho "\a"`
+recho `zecho "\\a"`
+
+recho `zecho '\a'`
+recho `zecho '\\a'`
+
+a=foo
+
+recho \$a
+recho \\$a
+
+recho "\$a"
+recho "\\$a"
+
+recho '\$a'
+recho '\\$a'
+
+recho $(zecho `zecho \a`)
+recho $(zecho `zecho \\a`)
+
+recho $(zecho `zecho "\a"`)
+recho $(zecho `zecho "\\a"`)
+
+recho $(zecho `zecho '\a'`)
+recho $(zecho `zecho '\\a'`)
+
+# should echo G { I K }
+recho ${abc:-G { I } K }
+
+abc=hi
+
+# should echo hi K }
+recho ${abc:-G { I } K }
+
+# should echo a*
+unset foo
+recho "${foo:-"a"}*"
+
+f ()
+{
+ echo "Number of args: $#"
+ echo "<\${*-x}>: <${*-x}>"
+ echo "<\${@-x}>: <${@-x}>"
+}
+
+f
+f ''
+f '' ''
+
+set 1 2 3 4 5
+
+expect '<5>'
+recho ${#}
+expect '<5>'
+recho ${#:foo}
+expect '<5>'
+recho ${#:-foo}
+expect '<5>'
+recho ${#-posparams}
+expect '<5>'
+recho ${#:-posparams}
+
+expect '<0>'
+recho ${#!}
+
+expect nothing
+recho $!
+expect nothing
+recho ${!}
+
+expect nothing
+recho $8
+expect nothing
+recho ${8}
+
+shift $#
+
+expect '<0>'
+recho ${#}
+expect '<0>'
+recho ${#:foo}
+expect '<0>'
+recho ${#:-foo}
+expect '<0>'
+recho ${#-posparams}
+expect '<0>'
+recho ${#:-posparams}
+
+expect '<posparams>'
+recho ${!-posparams}
+expect '<posparams>'
+recho ${!:-posparams}
+
+expect '<2>'
+recho ${#-}
+
+expect '<0>'
+recho ${#-posparams}
+
+expect '<0>'
+recho ${#?:-xyz}
+
+expect '<1>'
+recho ${#?}
+
+set a b c d e
+
+expect '<5>'
+recho ${#}
+expect '<5>'
+recho ${#?:-xyz}
+
+shift $#
+
+expect '<0>'
+recho ${#:-foo}
+
+expect a bad substitution error
+recho ${#:}
+expect a bad substitution error
+recho ${#/}
+expect a bad substitution error
+recho ${#%}
+expect a bad substitution error
+recho ${#=}
+expect a bad substitution error
+recho ${#+}
+expect a bad substitution error
+recho ${#1xyz}
+
+expect a math syntax error
+recho ${#:%}
+
+expect '<0>'
+recho ${#:-}
+
+set --
+unset a b
+
+x=a
+y=b
+
+IFS=+
+
+expect '<a+b>'
+recho $x+$y
+expect '<+>'
+recho $a+$b
+
+expect '<+>'
+recho + "$@"
+expect '<+>'
+recho +"$@"
+
+# variants of nested curly braces inside ${...} expressions
+
+# IFS is not the standard one
+
+expect '<G { I>' '<K>' '<}>'
+recho ${gik:-G { I } K }
+
+abc=hi
+
+expect '<hi>' '<K>' '<}>'
+recho ${abc:-G { I } K }
+
+# reset IFS to the default
+IFS='
+'
+
+# nested ${...} inside ${...} are handled specially
+unset XXX FOO BAR
+expect '<xxx>' '<yyy>'
+XXX=xxx
+FOO=${BAR:-${XXX} yyy}
+recho $FOO
+
+# this was a bug in versions of bash prior to bash-2.04-release
+set -- ''
+expect 1
+echo $#
+expect '<>'
+recho "${@}"
+expect '<>'
+recho "${@-}"
+expect '<>'
+recho "${@:-}"
+
+# this was a bug in bash-2.04, fixed in 2.05
+set -- a b
+expect '<:a:>' '<:b:>'
+for i in "${@-}"; do recho :$i:; done
+
+# I believe that ksh93 does these wrong -- we're using the rhs, so shouldn't
+# it behave the same as ""?
+set --
+expect '<>'
+recho "${@-}"
+expect '<>'
+recho "${@:-}"
diff --git a/tests/new-exp.right b/tests/new-exp.right
new file mode 100644
index 0000000..c86c546
--- /dev/null
+++ b/tests/new-exp.right
@@ -0,0 +1,542 @@
+argv[1] = <foo bar>
+argv[1] = <foo>
+argv[1] = </usr/homes/chet>
+argv[1] = </usr/homes/chet>
+argv[1] = </usr/homes/chet>
+./new-exp.tests: line 24: HOME: }: syntax error: operand expected (error token is "}")
+unset
+argv[1] = </usr/homes/chet>
+argv[1] = </usr/homes/chet>
+argv[1] = </usr/homes/chet>
+argv[1] = </usr/homes/chet>
+argv[1] = </usr/homes/chet>
+argv[1] = </usr/homes/chet>
+argv[1] = </usr/homes/chet>
+argv[1] = <*@>
+argv[1] = <*@>
+argv[1] = <@*>
+argv[1] = <)>
+argv[1] = <")">
+argv[1] = <-abcd>
+argv[2] = <->
+argv[1] = <-abcd>
+argv[2] = <->
+argv[1] = <-abcd->
+bar foo
+bar foo
+bar foo
+barfoo
+barfoo
+\x
+argv[1] = <abcd>
+argv[1] = <efg>
+argv[2] = <nop>
+argv[1] = <efg>
+argv[2] = <nop>
+argv[1] = <hijklmnop>
+argv[1] = <abcdefghijklmnop>
+argv[1] = <abcdefghijklmnop>
+argv[1] = <ab cd>
+argv[2] = <ef>
+argv[1] = <gh ij>
+argv[2] = <kl mn>
+argv[1] = <gh ij>
+argv[2] = <kl mn>
+argv[3] = <op>
+argv[1] = <ab cd>
+argv[2] = <ef>
+argv[3] = <gh ij>
+argv[4] = <kl mn>
+argv[5] = <op>
+argv[1] = </home/chet/foo//bar/abcabcabc>
+argv[1] = <home/chet/foo//bar/abcabcabc>
+argv[1] = <home>
+argv[1] = <home>
+argv[1] = <home>
+argv[1] = <home>
+argv[1] = <abcdefghijklmnop>
+argv[1] = <4>
+argv[1] = <op>
+argv[1] = <abcdefghijklmnop>
+argv[1] = <abcdefghijklmnop>
+./new-exp.tests: line 172: ABX: unbound variable
+./new-exp.tests: line 176: $6: cannot assign in this way
+argv[1] = <xxcde>
+argv[1] = <axxde>
+argv[1] = <abxyz>
+argv[1] = <abbcde>
+argv[1] = <abcde>
+argv[1] = <abcabe>
+argv[1] = <abcdlast>
+argv[1] = <abcde>
+argv[1] = <xxcd>
+argv[1] = <abxx>
+argv[1] = <xxgh>
+argv[1] = <efgh>
+argv[1] = <xxfgh>
+argv[1] = <zagh>
+argv[1] = <zaza>
+argv[1] = <zagh>
+argv[1] = <efza>
+argv[1] = <yyy>
+argv[2] = <yyy>
+argv[3] = <yyy>
+argv[4] = <yyy>
+argv[5] = <yyy>
+argv[6] = <yyy>
+argv[1] = <yyy>
+argv[2] = <yyy>
+argv[3] = <yyy>
+argv[4] = <yyy>
+argv[5] = <yyy>
+argv[6] = <yyy>
+argv[1] = <yyy>
+argv[2] = <yyy>
+argv[3] = <yyy>
+argv[4] = <yyy>
+argv[5] = <yyy>
+argv[6] = <yyy>
+argv[1] = <yyy>
+argv[2] = <efgh>
+argv[3] = <ijkl>
+argv[4] = <mnop>
+argv[5] = <qrst>
+argv[6] = <uvwx>
+argv[1] = <abxx>
+argv[2] = <efxx>
+argv[3] = <ijxx>
+argv[4] = <mnxx>
+argv[5] = <qrxx>
+argv[6] = <uvxx>
+argv[1] = <xxcd>
+argv[1] = <xxcd>
+argv[2] = <xxgh>
+argv[3] = <xxkl>
+argv[4] = <xxop>
+argv[5] = <xxst>
+argv[6] = <xxwx>
+argv[1] = <abxx>
+argv[2] = <efxx>
+argv[3] = <ijxx>
+argv[4] = <mnxx>
+argv[5] = <qrxx>
+argv[6] = <uvxx>
+argv[1] = <zaza>
+argv[1] = <ijza>
+argv[1] = <zaza>
+argv[2] = <zaza>
+argv[3] = <zaza>
+argv[4] = <zaza>
+argv[5] = <zaza>
+argv[6] = <zaza>
+argv[1] = <zacd>
+argv[2] = <zagh>
+argv[3] = <zakl>
+argv[4] = <zaop>
+argv[5] = <zast>
+argv[6] = <zawx>
+argv[1] = <yyy>
+argv[2] = <yyy>
+argv[3] = <yyy>
+argv[4] = <yyy>
+argv[5] = <yyy>
+argv[6] = <yyy>
+argv[1] = <yyy>
+argv[2] = <efgh>
+argv[3] = <ijkl>
+argv[4] = <mnop>
+argv[5] = <qrst>
+argv[6] = <uvwx>
+argv[1] = <abcd>
+argv[2] = <efgh>
+argv[3] = <ijkl>
+argv[4] = <mnop>
+argv[5] = <qrst>
+argv[6] = <uvwyyy>
+
+This
+string
+has
+multiple
+lines.
+This-string-has-multiple-lines.
+this is a test of proc subst
+this is test 2
+./new-exp2.sub: line 31: /tmp/bashtmp.x*: No such file or directory
+./new-exp2.sub: line 35: /tmp/redir-notthere: No such file or directory
+1
+argv[1] = <6>
+./new-exp.tests: line 277: ${#:}: bad substitution
+argv[1] = <'>
+argv[1] = <">
+argv[1] = <"hello">
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <abcdef>
+argv[1] = <abc def>
+argv[1] = <abcdef>
+argv[1] = <abc>
+argv[2] = <def>
+argv[1] = <abcdef>
+argv[1] = <abc def>
+argv[1] = <abcdef>
+argv[1] = <abc def>
+argv[1] = <ab>
+argv[2] = <cd>
+argv[3] = <ef>
+argv[4] = <gh>
+argv[1] = <ab>
+argv[2] = <cd>
+argv[3] = <ef>
+argv[4] = <gh>
+argv[1] = <ab>
+argv[2] = <cd>
+argv[3] = <ef>
+argv[4] = <gh>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <hijklmnopqrstuv>
+argv[1] = <pqrstuv>
+argv[1] = <uvwxyz>
+argv[1] = <abcdefghijklmnopqrstuvwxyz>
+argv[1] = <abcdefghijklmnopqrst>
+argv[1] = <klmnopq>
+argv[1] = <klmnopq>
+argv[1] = <klmnopq>
+argv[1] = <"2 3">
+argv[1] = <"2:3">
+argv[1] = <"34">
+argv[1] = <"3456">
+argv[1] = <"3456">
+argv[1] = <"3456">
+argv[1] = <^A>
+argv[2] = <^B>
+argv[3] = <^?>
+argv[1] = <^A>
+argv[2] = <^B>
+argv[3] = <^?>
+argv[1] = <^A>
+argv[2] = <^B>
+argv[3] = <^?>
+argv[1] = <^A>
+argv[2] = <^B>
+argv[3] = <^?>
+argv[1] = <one/two>
+argv[1] = <one/two>
+argv[1] = <two>
+argv[1] = <oneonetwo>
+argv[1] = <onetwo>
+argv[1] = <two>
+argv[1] = <oneonetwo>
+./new-exp.tests: line 421: -2: substring expression < 0
+argv[1] = <defghi>
+argv[1] = <efghi>
+argv[1] = <e*docrine>
+argv[1] = <e*docri*e>
+argv[1] = <endocrine>
+argv[1] = <endocrine>
+argv[1] = <endocrine>
+argv[1] = <endocrine>
+argv[1] = <endocrine>
+argv[1] = <endocrine>
+argv[1] = </usr/bin>
+argv[2] = </bin>
+argv[3] = </usr/local/bin>
+argv[4] = </usr/gnu/bin>
+argv[5] = </usr/bin/X11>
+argv[6] = </sbin>
+argv[7] = </usr/sbin>
+argv[1] = <r>
+argv[2] = <s>
+argv[3] = <t>
+argv[4] = <u>
+argv[5] = <v>
+argv[6] = <w>
+argv[7] = <x>
+argv[8] = <y>
+argv[9] = <z>
+argv[1] = <r>
+argv[2] = <s>
+argv[3] = <t>
+argv[4] = <u>
+argv[5] = <v>
+argv[6] = <w>
+argv[7] = <x>
+argv[8] = <y>
+argv[9] = <z>
+argv[1] = <r>
+argv[2] = <s>
+argv[3] = <t>
+argv[4] = <u>
+argv[5] = <v>
+argv[6] = <w>
+argv[7] = <x>
+argv[8] = <y>
+argv[9] = <z>
+argv[1] = <r>
+argv[2] = <s>
+argv[3] = <t>
+argv[4] = <u>
+argv[5] = <v>
+argv[6] = <w>
+argv[7] = <x>
+argv[8] = <y>
+argv[9] = <z>
+argv[1] = <a>
+argv[2] = <a>
+argv[3] = <a>
+argv[4] = <a>
+argv[5] = <a>
+argv[6] = <a>
+argv[7] = <a>
+argv[8] = <a>
+argv[9] = <a>
+argv[1] = <a>
+argv[2] = <a>
+argv[3] = <a>
+argv[4] = <a>
+argv[5] = <a>
+argv[6] = <a>
+argv[7] = <a>
+argv[8] = <a>
+argv[9] = <a>
+argv[1] = <r>
+argv[2] = <s>
+argv[3] = <t>
+argv[4] = <u>
+argv[5] = <v>
+argv[6] = <w>
+argv[7] = <x>
+argv[8] = <y>
+argv[9] = <z>
+argv[1] = <r>
+argv[2] = <s>
+argv[3] = <t>
+argv[4] = <u>
+argv[5] = <v>
+argv[6] = <w>
+argv[7] = <x>
+argv[8] = <y>
+argv[9] = <z>
+argv[1] = <r>
+argv[2] = <s>
+argv[3] = <t>
+argv[4] = <u>
+argv[5] = <v>
+argv[6] = <w>
+argv[7] = <x>
+argv[8] = <y>
+argv[9] = <z>
+argv[1] = <r>
+argv[2] = <s>
+argv[3] = <t>
+argv[4] = <u>
+argv[5] = <v>
+argv[6] = <w>
+argv[7] = <x>
+argv[8] = <y>
+argv[9] = <z>
+argv[1] = <r>
+argv[2] = <s>
+argv[3] = <t>
+argv[4] = <u>
+argv[5] = <v>
+argv[6] = <w>
+argv[7] = <x>
+argv[8] = <y>
+argv[9] = <z>
+argv[1] = <r>
+argv[2] = <s>
+argv[3] = <t>
+argv[4] = <u>
+argv[5] = <v>
+argv[6] = <w>
+argv[7] = <x>
+argv[8] = <y>
+argv[9] = <z>
+argv[1] = <a>
+argv[2] = <a>
+argv[3] = <a>
+argv[4] = <a>
+argv[5] = <a>
+argv[6] = <a>
+argv[7] = <a>
+argv[8] = <a>
+argv[9] = <a>
+argv[1] = <a>
+argv[2] = <a>
+argv[3] = <a>
+argv[4] = <a>
+argv[5] = <a>
+argv[6] = <a>
+argv[7] = <a>
+argv[8] = <a>
+argv[9] = <a>
+argv[1] = <r>
+argv[2] = <s>
+argv[3] = <t>
+argv[4] = <u>
+argv[5] = <v>
+argv[6] = <w>
+argv[7] = <x>
+argv[8] = <y>
+argv[9] = <z>
+argv[1] = <r>
+argv[2] = <s>
+argv[3] = <t>
+argv[4] = <u>
+argv[5] = <v>
+argv[6] = <w>
+argv[7] = <x>
+argv[8] = <y>
+argv[9] = <z>
+./new-exp.tests: line 480: $9: unbound variable
+./new-exp.tests: line 481: 9: unbound variable
+./new-exp.tests: line 482: UNSET: unbound variable
+./new-exp.tests: line 483: UNSET: unbound variable
+./new-exp.tests: line 484: UNSET: unbound variable
+./new-exp.tests: line 485: UNSET: unbound variable
+./new-exp.tests: line 486: UNSET: unbound variable
+argv[1] = <5>
+argv[1] = <#>
+argv[1] = <#>
+argv[1] = <>
+argv[1] = <_QUANTITY>
+argv[2] = <_QUART>
+argv[3] = <_QUEST>
+argv[4] = <_QUILL>
+argv[5] = <_QUOTA>
+argv[6] = <_QUOTE>
+argv[1] = <_QUANTITY>
+argv[2] = <_QUART>
+argv[3] = <_QUEST>
+argv[4] = <_QUILL>
+argv[5] = <_QUOTA>
+argv[6] = <_QUOTE>
+argv[1] = <_QUANTITY-_QUART-_QUEST-_QUILL-_QUOTA-_QUOTE>
+./new-exp3.sub: line 19: ${!_Q* }: bad substitution
+./new-exp3.sub: line 24: ${!1*}: bad substitution
+./new-exp3.sub: line 26: ${!@*}: bad substitution
+Case01---3---A:B:C---
+Case02---1---A B C::---
+Case03---3---A:B:C---
+Case04---3---A:B:C---
+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
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <c>
+argv[4] = <d>
+argv[5] = <e>
+argv[6] = <f>
+argv[7] = <g>
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <c>
+argv[4] = <d>
+argv[5] = <e>
+argv[1] = <a>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <>
+./new-exp.tests: line 525: $(($# - 2)): substring expression < 0
+argv[1] = <bin>
+argv[2] = <bin>
+argv[3] = <ucb>
+argv[4] = <bin>
+argv[5] = <.>
+argv[6] = <sbin>
+argv[7] = <sbin>
+argv[1] = </>
+argv[2] = </>
+argv[3] = </>
+argv[4] = </>
+argv[5] = </>
+argv[6] = </>
+argv[1] = <bin>
+argv[2] = <usr/bin>
+argv[3] = <usr/ucb>
+argv[4] = <usr/local/bin>
+argv[5] = <.>
+argv[6] = <sbin>
+argv[7] = <usr/sbin>
+argv[1] = </bin>
+argv[2] = </usr/bin>
+argv[3] = </usr/ucb>
+argv[4] = </usr/local/bin>
+argv[5] = <.>
+argv[6] = </sbin>
+argv[7] = </usr/sbin>
+argv[1] = </full/path/to>
+argv[1] = </>
+argv[1] = <full/path/to/x16>
+argv[1] = <x16>
+two
+one
+ne
+one
+
+one
+one
+one
+1 2 3 4 5 6 7 8 9
+9
+9
+0
+9
+8 9
+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] = <+^?>
+argv[1] = <+>
+argv[1] = <^?2>
+argv[1] = <^?2>
+argv[1] = <^?>
+argv[1] = <^?>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <12>
+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
new file mode 100644
index 0000000..8c43b66
--- /dev/null
+++ b/tests/new-exp.tests
@@ -0,0 +1,576 @@
+# must do this because posix mode causes process substitution to be disabled
+# and flagged as a syntax error, which causes the shell to exit
+set +o posix
+
+expect()
+{
+ echo expect "$@"
+}
+
+HOME=/usr/homes/chet # to make the check against new-exp.right work
+expect '<foo bar>'
+recho "${undef-"foo bar"}" # should be foo bar
+expect '<foo>'
+recho "${und="foo"}" # should be foo
+
+expect "<$HOME>"
+recho ${HOME-"}"}
+expect "<$HOME>"
+recho "${HOME-'}'}"
+expect "<$HOME>"
+recho "${HOME-"}"}"
+
+expect $0: 'HOME: }: syntax error: operand expected (error token is "}")'
+recho "${HOME:`echo }`}" # should be a math error -- bad substring substitution
+
+expect unset
+_ENV=oops
+x=${_ENV[(_$-=0)+(_=1)-_${-%%*i*}]}
+echo ${x:-unset}
+
+expect "<$HOME>"
+recho ${HOME}
+expect "<$HOME>"
+recho ${HOME:-`echo }`}
+expect "<$HOME>"
+recho ${HOME:-`echo "}"`}
+expect "<$HOME>"
+recho "${HOME:-`echo "}"`}"
+expect "<$HOME>"
+recho "$(echo "${HOME}")"
+expect "<$HOME>"
+recho "$(echo "$(echo ${HOME})")"
+expect "<$HOME>"
+recho "$(echo "$(echo "${HOME}")")"
+
+P=*@*
+expect '<*@>'
+recho "${P%"*"}" #
+expect '<*@>'
+recho "${P%'*'}" #
+expect '<@*>'
+recho "${P#\*}" # should be @*
+
+expect '<)>'
+recho "$(echo ")")" # should be )
+expect '<")">'
+recho "$(echo "\")\"")" # should be ")"
+
+foo='abcd '
+expect '<-abcd> <->'
+recho -${foo}- # should be -abcd -
+expect '<-abcd> <->'
+recho -${foo% *}- # should be -abcd -
+expect '<-abcd->'
+recho -${foo%% *}- # should be -abcd-
+
+foo=bar
+expect '<bar foo>'
+echo -n $foo' ' ; echo foo
+
+expect '<bar foo>'
+echo -n $foo" " ; echo foo
+
+expect '<bar foo>'
+echo -n "$foo " ; echo foo
+
+expect '<barfoo>'
+echo -e "$foo\c " ; echo foo
+
+expect '<barfoo>'
+echo -e $foo"\c " ; echo foo
+
+# make sure backslashes are preserved in front of characters that are not
+# valid backslash escapes
+expect '<\x>'
+echo -e '\x'
+
+# substring tests
+z=abcdefghijklmnop
+expect '<abcd>'
+recho ${z:0:4}
+
+expect '<efg> <nop>'
+recho ${z:4:3} ${z:${#z}-3:3}
+
+expect '<efg> <nop>'
+recho ${z:4:3} ${z: -3:3}
+
+expect '<hijklmnop>'
+recho ${z:7:30}
+
+expect '<abcdefghijklmnop>'
+recho ${z:0:100}
+
+expect '<abcdefghijklmnop>'
+recho ${z:0:${#z}}
+
+set 'ab cd' 'ef' 'gh ij' 'kl mn' 'op'
+expect '<ab cd> <ef>'
+recho "${@:1:2}"
+
+expect '<gh ij> <kl mn>'
+recho "${@:3:2}"
+
+expect '<gh ij> <kl mn> <op>'
+recho "${@:3:4}"
+
+expect '<ab cd> <ef> <gh ij> <kl mn> <op>'
+recho "${@:1:$#}"
+
+# code to ad-hoc parse arithmetic expressions in substring expansions was
+# broken until post-2.04
+base=/home/chet/foo//bar
+string1=$base/abcabcabc
+x=1 j=4
+
+expect '</home/chet/foo//bar/abcabcabc>'
+recho ${string1:0}
+
+expect '<home/chet/foo//bar/abcabcabc>'
+recho ${string1:1}
+
+expect '<home>'
+recho ${string1:(j?1:0):j}
+
+expect '<home>'
+recho ${string1:j?1:0:j}
+
+expect '<home>'
+recho ${string1:(j?(x?1:0):0):j}
+
+expect '<home>'
+recho ${string1:j?(x?1:0):0:j}
+
+unset base string1 x j
+
+# indirect variable references
+expect '<abcdefghijklmnop>'
+recho ${!9:-$z}
+
+ef=4
+expect '<4>'
+recho ${!2}
+
+expect '<op>'
+recho ${!#}
+
+set a b c d e
+a=
+expect '<abcdefghijklmnop>'
+recho ${a:-$z}
+expect '<abcdefghijklmnop>'
+recho ${!1:-$z}
+
+expect nothing
+recho ${a-$z}
+expect nothing
+recho ${!1-$z}
+
+set -u
+expect $0: ABX: unbound variable
+( recho ${ABX} )
+set +u
+
+expect $0: '$6: cannot assign in this way'
+recho ${6="arg6"}
+
+v=abcde
+
+# sed-like variable substitution
+expect '<xxcde>'
+recho ${v/a[a-z]/xx}
+expect '<axxde>'
+recho ${v/a??/axx}
+expect '<abxyz>'
+recho ${v/c??/xyz}
+expect '<abbcde>'
+recho ${v/#a/ab}
+expect '<abcde>'
+recho ${v/#d/ab}
+expect '<abcabe>'
+recho ${v/d/ab}
+expect '<abcdlast>'
+recho ${v/%?/last}
+expect '<abcde>'
+recho ${v/%x/last}
+
+av=(abcd efgh ijkl mnop qrst uvwx)
+
+expect '<xxcd>'
+recho ${av/??/xx}
+expect '<abxx>'
+recho ${av/%??/xx}
+expect '<xxgh>'
+recho ${av[1]/??/xx}
+expect '<efgh>'
+recho ${av[1]/%ab/xx}
+expect '<xxfgh>'
+recho ${av[1]/#?/xx}
+expect '<zagh>'
+recho ${av[1]/??/za}
+expect '<zaza>'
+recho ${av[1]//??/za}
+expect '<zagh>'
+recho ${av[1]/#??/za}
+expect '<efza>'
+recho ${av[1]/%??/za}
+
+expect '<yyy> <yyy> <yyy> <yyy> <yyy> <yyy>'
+recho ${av[@]/*/yyy}
+expect '<yyy> <yyy> <yyy> <yyy> <yyy> <yyy>'
+recho ${av[@]/#*/yyy}
+expect '<yyy> <yyy> <yyy> <yyy> <yyy> <yyy>'
+recho ${av[@]/%*/yyy}
+expect '<yyy> <efgh> <ijkl> <mnop> <qrst> <uvwx>'
+recho ${av[@]/a*/yyy}
+expect '<abxx> <efxx> <ijxx> <mnxx> <qrxx> <uvxx>'
+recho ${av[@]/%??/xx}
+
+set abcd efgh ijkl mnop qrst uvwx
+
+expect '<xxcd>'
+recho ${1/??/xx}
+expect '<xxcd> <xxgh> <xxkl> <xxop> <xxst> <xxwx>'
+recho ${@/??/xx}
+expect '<xxcd> <xxgh> <xxkl> <xxop> <xxst> <xxwx>'
+recho ${@/%??/xx}
+expect '<zaza>'
+recho ${3//??/za}
+expect '<efza>'
+recho ${3/%??/za}
+expect '<zaza> <zaza> <zaza> <zaza> <zaza> <zaza>'
+recho ${@//??/za}
+expect '<zacd> <zagh> <zakl> <zaop> <zast> <zawx>'
+recho ${@/#??/za}
+expect '<yyy> <yyy> <yyy> <yyy> <yyy> <yyy>'
+recho ${@//*/yyy}
+expect '<yyy> <efgh> <ijkl> <mnop> <qrst> <uvwx>'
+recho ${@//a*/yyy}
+expect '<abcd> <efgh> <ijkl> <mnop> <qrst> <uvwyyy>'
+recho ${@/%x*/yyy}
+
+expect a newline
+echo $abmcde
+
+# sneaky way to replace a newline in a variable value with something else
+AVAR=$'This\nstring\nhas\nmultiple\nlines.'
+echo "${AVAR}"
+
+eval BVAR=\"\${AVAR//$'\n'/-}\"
+echo "$BVAR"
+
+unset AVAR BVAR
+
+# run process substitution tests in a subshell so that syntax errors
+# caused by a shell not implementing process substitution (e.g., one
+# built on a NeXT) will not cause the whole test to exit prematurely
+${THIS_SH} ./new-exp1.sub
+
+# run the tests of $(<filename) in a subshell to avoid cluttering up
+# this script
+${THIS_SH} ./new-exp2.sub
+
+expect '<6>'
+recho ${#:-foo}
+expect $0: '${#:}: bad substitution'
+echo ${#:}
+
+expect "<'>"
+recho "'"
+expect '<">'
+recho '"'
+expect '<"hello">'
+recho "\"hello\""
+
+shift $#
+unset foo
+z=abcdef
+z1='abc def'
+
+expect '<>'
+recho ${foo:-""}
+expect nothing
+recho ${foo:-"$@"}
+expect '<>'
+recho "${foo:-$@}"
+
+# unset var
+expect '<>'
+recho ${foo:-"$zbcd"}
+expect nothing
+recho ${foo:-$zbcd}
+
+# set var
+expect '<abcdef>'
+recho ${foo:-"$z"}
+expect '<abc def>'
+recho ${foo:-"$z1"}
+
+expect '<abcdef>'
+recho ${foo:-$z}
+expect '<abc> <def>'
+recho ${foo:-$z1}
+
+expect '<abcdef>'
+recho "${foo:-$z}"
+expect '<abc def>'
+recho "${foo:-$z1}"
+
+expect '<abcdef>'
+recho "${foo:-"$z"}"
+# this disagrees with sh and ksh, but I think it is right according
+# to posix.2.
+expect '<abc def>'
+recho "${foo:-"$z1"}"
+
+set ab cd ef gh
+expect '<ab> <cd> <ef> <gh>'
+recho ${foo:-"$@"}
+expect '<ab> <cd> <ef> <gh>'
+recho "${foo:-$@}"
+expect '<ab> <cd> <ef> <gh>'
+recho "${foo:-"$@"}"
+
+shift $#
+expect nothing
+recho $xxx"$@"
+expect nothing
+recho ${foo:-$xxx"$@"}
+expect '<>'
+recho "${foo:-$xxx$@}"
+expect '<>'
+recho "${foo:-$xxx"$@"}"
+
+expect nothing
+recho $xxx"$@"
+expect nothing
+recho "$xxx$@"
+expect nothing
+recho "$@"$xxx
+
+expect '<>'
+recho $xxx""
+expect '<>'
+recho $xxx''
+expect '<>'
+recho ''$xxx
+expect '<>'
+recho ""$xxx
+
+AB='abcdefghijklmnopqrstuvwxyz'
+
+recho ${AB:7:15}
+recho ${AB:15:7}
+
+recho ${AB:20}
+
+recho ${AB:0}
+recho ${AB:0:20}
+
+recho ${AB:10:7}
+recho ${AB:10:3+4}
+recho ${AB:20/2:3+4}
+
+set 1 2 3 4 5 6
+recho \""${*:2:2}"\"
+
+IFS=:
+recho \""${*:2:2}"\"
+
+IFS=$' \t\n'
+
+z=123456
+
+recho \""${z:2:2}"\"
+recho \""${z:2}"\"
+recho \""${z:2:4}"\"
+recho \""${z:2:6}"\"
+
+set $'\1' $'\2' $'\177'
+
+recho $*
+recho $@
+
+recho ${*}
+recho ${@}
+
+xx=one/two/two
+recho ${xx%/*}
+recho ${xx/\/two}
+
+yy=oneonetwo
+recho ${yy//one}
+recho ${yy/\/one}
+
+xx=oneonetwo
+
+recho ${xx/one}
+recho ${xx//one}
+recho ${xx/\/one}
+
+# out-of-range substrings
+var=abc
+c=${var:3}
+expect nothing
+recho $c
+c=${var:4}
+expect nothing
+recho $c
+expect '<./new-exp.tests: -2: substring expression < 0>'
+c=${var:0:-2}
+
+var=abcdefghi
+c=${var:3:12}
+recho $c
+c=${var:4:20}
+recho $c
+
+# make sure null patterns work
+xxx=endocrine
+yyy=n
+unset zzz
+
+recho ${xxx/$yyy/*}
+recho ${xxx//$yyy/*}
+
+recho ${xxx/$zzz/*}
+recho ${xxx//$zzz/*}
+
+recho ${xxx//%${zzz}/}
+recho ${xxx//%${zzz}}
+recho ${xxx//#${zzz}/}
+recho ${xxx//#${zzz}}
+
+# another case that caused a core dump in bash-2.0
+XPATH=/usr/bin:/bin:/usr/local/bin:/usr/gnu/bin::/usr/bin/X11:/sbin:/usr/sbin
+
+recho ${XPATH//:/ }
+
+xx=(ar as at au av aw ax ay az)
+
+recho ${xx[@]/a/}
+recho ${xx[@]//a/}
+
+recho ${xx[*]/a/}
+recho ${xx[*]//a/}
+
+recho ${xx[@]%?}
+recho ${xx[*]%?}
+
+recho ${xx[@]#?}
+recho ${xx[*]#?}
+
+set -- ar as at au av aw ax ay az
+
+recho ${@/a/}
+recho ${@//a/}
+
+recho ${*/a/}
+recho ${*//a/}
+
+recho ${@%?}
+recho ${*%?}
+
+recho ${@#?}
+recho ${*#?}
+
+shift $#
+set -u
+( recho $9 ; echo after 1)
+( recho ${9} ; echo after 2)
+( recho $UNSET ; echo after 3)
+( recho ${UNSET} ; echo after 4)
+( recho "$UNSET" ; echo after 5)
+( recho "${UNSET}" ; echo after 6)
+( recho "${#UNSET}" ; echo after 7)
+set +u
+
+RECEIVED="12345"
+recho "${RECEIVED:$((${#RECEIVED}-1)):1}"
+RECEIVED="12345#"
+recho "${RECEIVED:$((${#RECEIVED}-1)):1}"
+RECEIVED="#"
+recho "${RECEIVED:$((${#RECEIVED}-1)):1}"
+RECEIVED=""
+recho "${RECEIVED:$((${#RECEIVED}-1)):1}"
+
+# tests of new prefix expansion ${!prefix*}
+${THIS_SH} ./new-exp3.sub
+
+# bug with indirect expansion through bash-2.05b
+${THIS_SH} ./new-exp4.sub
+
+# these caused errors and core dumps in versions before bash-2.04
+c=""
+echo ${c//${$(($#-1))}/x/}
+
+set a b c d e f g
+recho "$@"
+
+set -- ${@:1:$(($# - 2))}
+recho "$@"
+
+set a b
+recho ${@:1:$(($# - 2))}
+
+recho ${@:1:0}
+recho ${@:1:1}
+recho ${@:1:2}
+
+recho "${*:1:0}"
+
+# this is an error -- negative expression
+set a
+recho ${@:1:$(($# - 2))}
+
+XPATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:.:/sbin:/usr/sbin
+set $( IFS=: ; echo $XPATH )
+
+recho ${@##*/}
+recho ${@%%[!/]*}
+
+recho ${@#/*}
+recho ${@%*/}
+
+set /full/path/to/x16 /another/full/path
+
+recho ${1%/*}
+recho ${1%%[!/]*}
+recho ${1#*/}
+recho ${1##*/}
+
+${THIS_SH} ./new-exp5.sub
+
+unset var
+var=blah
+
+# these had better agree
+echo ${var[@]:3}
+echo ${var:3}
+echo ${var[@]/#/--}
+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-exp1.sub b/tests/new-exp1.sub
new file mode 100644
index 0000000..c015c22
--- /dev/null
+++ b/tests/new-exp1.sub
@@ -0,0 +1,11 @@
+expect()
+{
+ echo expect "$@"
+}
+
+expect this is a test of proc subst
+cat <(echo this is a test of proc subst)
+echo this is test 2 > /tmp/x
+expect this is test 2
+cat <(cat /tmp/x)
+rm -f /tmp/x
diff --git a/tests/new-exp2.sub b/tests/new-exp2.sub
new file mode 100644
index 0000000..5e922aa
--- /dev/null
+++ b/tests/new-exp2.sub
@@ -0,0 +1,36 @@
+export LC_ALL=C
+export LANG=C
+
+# test out the new $(< filename) code
+# it should be exactly equivalent to $(cat filename)
+
+FILENAME=/tmp/bashtmp.x$$
+
+trap 'rm -f $FILENAME' 0
+
+cat >$FILENAME << EOF
+line 1
+line 2
+line 3
+EOF
+
+LINES1=$(cat $FILENAME)
+LINES2=$(< $FILENAME)
+
+if [[ $LINES1 != $LINES2 ]]; then
+ echo 'whoops: $(< filename) failed'
+fi
+
+LINES2=$(< /tmp/bashtmp.x*)
+if [[ $LINES1 != $LINES2 ]]; then
+ echo 'whoops: $(< filename) with glob expansion failed'
+fi
+
+# but the glob expansion in the redirection should fail in posix mode
+set -o posix
+LINES2=$(< /tmp/bashtmp.x*)
+set +o posix
+
+# now see what happens when we try it with a non-existant file
+LINES3=$(< /tmp/redir-notthere)
+echo $?
diff --git a/tests/new-exp3.sub b/tests/new-exp3.sub
new file mode 100644
index 0000000..3107ef1
--- /dev/null
+++ b/tests/new-exp3.sub
@@ -0,0 +1,26 @@
+:
+# Set up some dummy variables beginning with _Q
+_QUANTITY=
+_QUOTA=
+_QUOTE=
+_QUILL=
+_QUEST=
+_QUART=
+
+recho ${!_Q*}
+
+IFS="-$IFS"
+
+recho ${!_Q*}
+recho "${!_Q*}"
+
+recho ${!_Y*}
+
+recho "${!_Q* }"
+
+IFS=$' \t\n'
+
+set a b c d e f g h i j k l m n o p
+recho ${!1*}
+
+recho ${!@*}
diff --git a/tests/new-exp4.sub b/tests/new-exp4.sub
new file mode 100644
index 0000000..45439a0
--- /dev/null
+++ b/tests/new-exp4.sub
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+arrayA=("A" "B" "C")
+
+arrayB=( ${arrayA[*]} )
+echo "Case01---${#arrayB[*]}---${arrayB[0]}:${arrayB[1]}:${arrayB[2]}---"
+
+arrayB=( "${arrayA[*]}" )
+echo "Case02---${#arrayB[*]}---${arrayB[0]}:${arrayB[1]}:${arrayB[2]}---"
+
+arrayB=( ${arrayA[@]} )
+echo "Case03---${#arrayB[@]}---${arrayB[0]}:${arrayB[1]}:${arrayB[2]}---"
+
+arrayB=( "${arrayA[@]}" )
+echo "Case04---${#arrayB[@]}---${arrayB[0]}:${arrayB[1]}:${arrayB[2]}---"
+
+xx="arrayA[*]"
+
+arrayB=( ${!xx} )
+echo "Case05---${#arrayB[*]}---${arrayB[0]}:${arrayB[1]}:${arrayB[2]}---"
+
+arrayB=( "${!xx}" )
+echo "Case06---${#arrayB[*]}---${arrayB[0]}:${arrayB[1]}:${arrayB[2]}---"
+
+xx="arrayA[@]"
+
+arrayB=( ${!xx} )
+echo "Case07---${#arrayB[@]}---${arrayB[0]}:${arrayB[1]}:${arrayB[2]}---"
+
+arrayB=( "${!xx}" )
+echo "Case08---${#arrayB[@]}---${arrayB[0]}:${arrayB[1]}:${arrayB[2]}---"
diff --git a/tests/new-exp5.sub b/tests/new-exp5.sub
new file mode 100644
index 0000000..0ee86e9
--- /dev/null
+++ b/tests/new-exp5.sub
@@ -0,0 +1,40 @@
+x=(one two)
+echo ${x[@]:1}
+echo ${x[@]:0:1}
+
+x=(one)
+echo ${x[0]:1}
+echo ${x[0]:0}
+echo ${x[@]:1}
+echo ${x[@]:0}
+
+echo ${x[@]: -1}
+echo ${x[@]: ${#x[@]}-1}
+
+x=(0 1 2 3 4 5 6 7 8 9)
+echo ${x[@]:1}
+
+echo ${x[@]: -1}
+echo ${x[@]: ${#x[@]}-1}
+
+set -- ${x[@]}
+
+echo $1
+echo ${@: -1}
+echo ${@: $#-1}
+
+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
new file mode 100644
index 0000000..267f0e7
--- /dev/null
+++ b/tests/nquote.right
@@ -0,0 +1,40 @@
+argv[1] = <^J^J^J>
+argv[1] = <++^J++>
+argv[1] = <>
+argv[1] = <^J^I >
+argv[1] = <abc>
+argv[1] = <^M^[^Gabc>
+argv[1] = <hello,>
+argv[2] = <world>
+argv[1] = <hello, world>
+argv[1] = <>
+argv[1] = <$hello, world>
+argv[1] = <hello, $world>
+argv[1] = <hello, "world">
+argv[1] = <hello, $"world">
+argv[1] = <hello, $"world">
+argv[1] = <$hello, chet>
+argv[1] = <hello, chet>
+ok
+'abcd'
+'abcd'
+\'abcd\'
+\'abcd\'
+argv[1] = <A\CB>
+argv[1] = <A\CB>
+argv[1] = <ab$cde>
+A\CB
+A\CB
+A\CB
+argv[1] = <hello, $"world">
+argv[1] = <hello, \$"world">
+argv[1] = <hello, $"world">
+argv[1] = <hello, $world>
+1
+1
+;foo
+argv[1] = <^I>
+argv[1] = <'A^IB'>
+hello' world
+hello world!
+hello' world!
diff --git a/tests/nquote.tests b/tests/nquote.tests
new file mode 100644
index 0000000..720c3e1
--- /dev/null
+++ b/tests/nquote.tests
@@ -0,0 +1,118 @@
+expect()
+{
+ echo expect "$@"
+}
+
+expect '<^J^J^J>'
+recho $'\n\n\n'
+
+expect '<++^J++>'
+f=$'\n'
+recho "++$f++"
+unset f
+
+z1=$''
+expect '<>'
+recho "$z1"
+
+ZIFS=$'\n'$'\t'$' '
+
+expect '<^J^I >'
+recho "$ZIFS"
+
+expect '<abc>'
+recho $'abc'
+
+expect '<^M^[^Gabc>'
+recho $'\r\e\aabc'
+
+D=$"hello"," "$"world"
+
+expect '<hello,> <world>'
+recho $D
+
+expect '<hello, world>'
+recho "$D"
+
+D=$""
+expect '<>'
+recho "$D"
+
+world=chet
+
+expect '<$hello, world>'
+recho \$"hello, world"
+
+expect '<hello, $world>'
+recho $"hello, \$world"
+
+expect '<hello, "world">'
+recho $"hello, \"world\""
+
+expect '<hello, $"world">'
+recho $"hello"', $"world"'
+
+expect '<hello, $"world">'
+recho $'hello, $"world"'
+
+expect '<$hello, chet>'
+recho \$"hello, $world"
+
+expect '<hello, chet>'
+recho $"hello, $world"
+
+z=$'\v\f\a\b'
+case "$z" in
+$'\v\f\a\b') echo ok;;
+*) echo bad;;
+esac
+
+# Dave Korn says this should be allowed and echo 'abcd'
+echo $'\'abcd\''
+
+# printf translates \' to ' ...
+printf "\'abcd\'\n"
+
+# but echo -e doesn't
+echo -e "\'abcd\'"
+echo -e "\\'abcd\\'"
+
+# and what do we do about unrecognized escape sequences?
+
+shopt -s xpg_echo
+
+recho $'A\CB'
+
+recho "A\CB"
+
+cde=c
+recho $'ab$cde'
+
+printf "%b\n" 'A\CB'
+printf 'A\CB\n'
+
+echo 'A\CB'
+
+world=chet
+
+recho $'hello, $"world"'
+recho $'hello, \$"world"'
+recho $'hello, $\"world"'
+
+recho "hello, $"world""
+
+# ansi quoting inside double-quoted command subst - bash-3.1 bug
+echo $(set -- $'a b'; echo $#)
+echo "$(set -- $'a b'; echo $#)"
+
+echo "$(echo $';foo')"
+
+args ()
+{
+ for a in "$@";do echo "'$a'";done
+}
+unset mytab
+recho "${mytab:-$'\t'}"
+recho "$( args $'A\tB' )"
+
+${THIS_SH} ./nquote1.sub
diff --git a/tests/nquote1.right b/tests/nquote1.right
new file mode 100644
index 0000000..26e16b9
--- /dev/null
+++ b/tests/nquote1.right
@@ -0,0 +1,121 @@
+argv[1] = <a>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <1>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <b>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <c>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <d>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <a>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <1>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <b>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <c>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <d>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <a>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <1>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <b>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <c>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <d>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <a>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <1>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <b>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <c>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <d>
+argv[2] = <a^Ab>
+argv[3] = <3>
+argv[1] = <e1>
+argv[2] = <v^A^A>
+argv[1] = <e2>
+argv[2] = <v^A^A>
+argv[1] = <e3>
+argv[2] = <v^A^A>
+argv[1] = <e4>
+argv[2] = <v^A^A>
+argv[1] = <a1>
+argv[2] = <uv^A^A>
+argv[1] = <a2>
+argv[2] = <uv^A^A>
+argv[1] = <a3>
+argv[2] = <uv^A^Awx>
+argv[3] = <uv^A^Awx>
+argv[1] = <a4>
+argv[2] = <uv^A^Awx>
+argv[3] = <uv^A^Awx>
+argv[1] = <p1>
+argv[2] = <uv^A^Awx>
+argv[3] = <uv^A^Awx>
+argv[1] = <p2>
+argv[2] = <uv^A^Awx>
+argv[3] = <uv^A^Awx>
+argv[1] = <p1>
+argv[2] = <uv^A^Awx>
+argv[3] = <uv^A^Awx>
+argv[1] = <p2>
+argv[2] = <uv^A^Awx uv^A^Awx>
+argv[1] = <uv^A^Awx>
+argv[1] = <uv^A^Awx>
+argv[1] = <uv^A^Awx>
+^A
+^A
+^B
+argv[1] = <f1>
+argv[2] = <v^Aw>
+argv[1] = <f2>
+argv[2] = <v^Aw>
+argv[1] = <a1>
+argv[2] = <uv^Aw>
+argv[1] = <a2>
+argv[2] = <uv^Aw>
+argv[1] = <a3>
+argv[2] = <uv^Aw>
+argv[1] = <a4>
+argv[2] = <uv^Aw>
+argv[1] = <e1>
+argv[2] = <uv^Aw>
+argv[1] = <e2>
+argv[2] = <uv^Aw>
+argv[1] = <d1>
+argv[2] = <^Aw>
+argv[1] = <d2>
+argv[2] = <^Aw>
+argv[1] = <@1>
+argv[2] = <uv^Aw^Axy>
+argv[3] = <uv^Aw^Axy>
+argv[1] = <@2>
+argv[2] = <uv^Aw^Axy>
+argv[3] = <uv^Aw^Axy>
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/nquote1.tests b/tests/nquote1.tests
new file mode 100644
index 0000000..0970e77
--- /dev/null
+++ b/tests/nquote1.tests
@@ -0,0 +1,97 @@
+a=$'a\001b'
+
+set $a
+
+b=$a
+c=$1
+d="$1"
+
+e=$'uv\001\001wx'
+
+recho a $a ${#a}
+recho 1 $1 ${#1}
+recho b $b ${#b}
+recho c $c ${#c}
+recho d $d ${#d}
+
+recho a ${a} ${#a}
+recho 1 ${1} ${#1}
+recho b ${b} ${#b}
+recho c ${c} ${#c}
+recho d ${d} ${#d}
+
+recho a "$a" ${#a}
+recho 1 "$1" ${#1}
+recho b "$b" ${#b}
+recho c "$c" ${#c}
+recho d "$d" ${#d}
+
+recho a "${a}" ${#a}
+recho 1 "${1}" ${#1}
+recho b "${b}" ${#b}
+recho c "${c}" ${#c}
+recho d "${d}" ${#d}
+
+set $e
+
+recho e1 ${e:1:3}
+recho e2 "${e:1:3}"
+recho e3 ${1:1:3}
+recho e4 "${1:1:3}"
+
+arr[0]=$e
+arr[1]=$e
+
+recho a1 ${arr:0:4}
+recho a2 "${arr:0:4}"
+
+recho a3 ${arr[@]:0:2}
+recho a4 "${arr[@]:0:2}"
+
+set $e $e
+
+recho p1 ${@:1:2}
+recho p2 "${@:1:2}"
+
+recho p1 ${*:1:2}
+recho p2 "${*:1:2}"
+
+recho $e
+
+recho 'uvwx'
+
+f='uvwx'
+
+recho $f
+
+echo -en "\01" | cat -v
+echo
+
+huhu() { echo "$1"; };
+
+huhu $(echo -en "\01") | cat -v
+huhu $(echo -en "\02") | cat -v
+
+f=$'uv\001w\001xy'
+
+set $f $f
+
+recho f1 ${f:1:3}
+recho f2 "${f:1:3}"
+
+arr[0]=$f
+arr[1]=$f
+
+recho a1 ${arr:0:4}
+recho a2 "${arr:0:4}"
+recho a3 ${arr[0]:0:4}
+recho a4 "${arr[0]:0:4}"
+
+recho e1 ${f:0:4}
+recho e2 "${f:0:4}"
+
+recho d1 ${1:2:2}
+recho d2 "${1:2:2}"
+
+recho @1 ${@:1:2}
+recho @2 "${@:1:2}"
diff --git a/tests/nquote2.right b/tests/nquote2.right
new file mode 100644
index 0000000..e7fb21e
--- /dev/null
+++ b/tests/nquote2.right
@@ -0,0 +1,76 @@
+argv[1] = <a^Ab>
+argv[1] = <uv^A^Awx>
+argv[1] = <aAb>
+argv[1] = <aAb>
+argv[1] = <uvA^Awx>
+argv[1] = <uvA^Awx>
+argv[1] = <a^AB>
+argv[1] = <a^AB>
+argv[1] = <uv^A^AWx>
+argv[1] = <uv^A^AWx>
+argv[1] = <aAb>
+argv[1] = <aAb>
+argv[1] = <uvAAwx>
+argv[1] = <uvAAwx>
+argv[1] = <a^AB>
+argv[1] = <a^AB>
+argv[1] = <uv^A^AWx>
+argv[1] = <uv^A^AWx>
+argv[1] = <uvA^Awx>
+argv[2] = <uvA^Awx>
+argv[1] = <uvA^Awx>
+argv[2] = <uvA^Awx>
+argv[1] = <uv^A^AWx>
+argv[2] = <uv^A^AWx>
+argv[1] = <uv^A^AWx>
+argv[2] = <uv^A^AWx>
+argv[1] = <uvAAwx>
+argv[2] = <uvAAwx>
+argv[1] = <uvAAwx>
+argv[2] = <uvAAwx>
+argv[1] = <uv^A^AWx>
+argv[2] = <uv^A^AWx>
+argv[1] = <uv^A^AWx>
+argv[2] = <uv^A^AWx>
+argv[1] = <a^Ab>
+argv[1] = <uv^A^Awx>
+argv[1] = <aAb>
+argv[1] = <aAb>
+argv[1] = <uvA^Awx>
+argv[1] = <uvA^Awx>
+argv[1] = <a^AB>
+argv[1] = <a^AB>
+argv[1] = <uv^A^AWx>
+argv[1] = <uv^A^AWx>
+argv[1] = <aAb>
+argv[1] = <aAb>
+argv[1] = <uvAAwx>
+argv[1] = <uvAAwx>
+argv[1] = <a^AB>
+argv[1] = <a^AB>
+argv[1] = <uv^A^AWx>
+argv[1] = <uv^A^AWx>
+argv[1] = <aAb>
+argv[2] = <uvA^Awx>
+argv[1] = <aAb>
+argv[2] = <uvA^Awx>
+argv[1] = <a^AB>
+argv[2] = <uv^A^Awx>
+argv[1] = <a^AB>
+argv[2] = <uv^A^Awx>
+argv[1] = <a^Ab>
+argv[2] = <uv^A^AWx>
+argv[1] = <a^Ab>
+argv[2] = <uv^A^AWx>
+argv[1] = <aAb>
+argv[2] = <uvAAwx>
+argv[1] = <aAb>
+argv[2] = <uvAAwx>
+argv[1] = <a^AB>
+argv[2] = <uv^A^Awx>
+argv[1] = <a^AB>
+argv[2] = <uv^A^Awx>
+argv[1] = <a^Ab>
+argv[2] = <uv^A^AWx>
+argv[1] = <a^Ab>
+argv[2] = <uv^A^AWx>
diff --git a/tests/nquote2.tests b/tests/nquote2.tests
new file mode 100644
index 0000000..c07bd9b
--- /dev/null
+++ b/tests/nquote2.tests
@@ -0,0 +1,82 @@
+a=$'a\001b'
+
+e=$'uv\001\001wx'
+
+recho $a
+recho $e
+
+recho ${a/$'\001'/A}
+recho "${a/$'\001'/A}"
+recho ${e/$'\001'/A}
+recho "${e/$'\001'/A}"
+
+recho ${a/b/B}
+recho "${a/b/B}"
+recho ${e/w/W}
+recho "${e/w/W}"
+
+recho ${a//$'\001'/A}
+recho "${a//$'\001'/A}"
+recho ${e//$'\001'/A}
+recho "${e//$'\001'/A}"
+
+recho ${a//b/B}
+recho "${a//b/B}"
+recho ${e//w/W}
+recho "${e//w/W}"
+
+# pos params pat subst
+
+set $e $e
+
+recho ${@/$'\001'/A}
+recho "${@/$'\001'/A}"
+recho ${@/w/W}
+recho "${@/w/W}"
+
+recho ${@//$'\001'/A}
+recho "${@//$'\001'/A}"
+recho ${@//w/W}
+recho "${@//w/W}"
+
+arr[0]=$a
+arr[1]=$e
+
+recho ${arr[0]}
+recho ${arr[1]}
+
+recho ${arr[0]/$'\001'/A}
+recho "${arr[0]/$'\001'/A}"
+recho ${arr[1]/$'\001'/A}
+recho "${arr[1]/$'\001'/A}"
+
+recho ${arr[0]/b/B}
+recho "${arr[0]/b/B}"
+recho ${arr[1]/w/W}
+recho "${arr[1]/w/W}"
+
+recho ${arr[0]//$'\001'/A}
+recho "${arr[0]//$'\001'/A}"
+recho ${arr[1]//$'\001'/A}
+recho "${arr[1]//$'\001'/A}"
+
+recho ${arr[0]//b/B}
+recho "${arr[0]//b/B}"
+recho ${arr[1]//w/W}
+recho "${arr[1]//w/W}"
+
+recho ${arr[@]/$'\001'/A}
+recho "${arr[@]/$'\001'/A}"
+
+recho ${arr[@]/b/B}
+recho "${arr[@]/b/B}"
+recho ${arr[@]/w/W}
+recho "${arr[@]/w/W}"
+
+recho ${arr[@]//$'\001'/A}
+recho "${arr[@]//$'\001'/A}"
+
+recho ${arr[@]//b/B}
+recho "${arr[@]//b/B}"
+recho ${arr[@]//w/W}
+recho "${arr[@]//w/W}"
diff --git a/tests/nquote3.right b/tests/nquote3.right
new file mode 100644
index 0000000..d01eecc
--- /dev/null
+++ b/tests/nquote3.right
@@ -0,0 +1,60 @@
+argv[1] = <uv^A^A>
+argv[1] = <uv^A^A>
+argv[1] = <uv^A>
+argv[1] = <uv^A>
+argv[1] = <^Ab>
+argv[1] = <^Ab>
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <uv^Aw^Axy>
+argv[1] = <uv^A>
+argv[1] = <uv^A>
+argv[1] = <^Awx>
+argv[1] = <^Awx>
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <uv^Aw^Axy>
+argv[1] = <uv^A>
+argv[1] = <uv^A>
+argv[1] = <^Awx>
+argv[1] = <^Awx>
+argv[1] = <uv^A>
+argv[1] = <uv^A>
+argv[1] = <^Awx>
+argv[1] = <^Awx>
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <uv^Aw^Axy>
+argv[1] = <uv^Aw^Axy>
+argv[1] = <uv^A>
+argv[1] = <uv^A>
+argv[1] = <^Awx>
+argv[1] = <^Awx>
+argv[1] = <uv^A>
+argv[2] = <uv^Aw>
+argv[1] = <uv^A>
+argv[2] = <uv^Aw>
+argv[1] = <^Awx>
+argv[2] = <w^Axy>
+argv[1] = <^Awx>
+argv[2] = <w^Axy>
+argv[1] = <wx>
+argv[2] = <xy>
+argv[1] = <uv^A^Awx>
+argv[2] = <uv^Aw^Axy>
+argv[1] = <uv^A>
+argv[2] = <uv^Aw>
+argv[1] = <uv^A>
+argv[2] = <uv^Aw>
+argv[1] = <^Awx>
+argv[2] = <w^Axy>
+argv[1] = <^Awx>
+argv[2] = <w^Axy>
+argv[1] = <wx>
+argv[2] = <xy>
+argv[1] = <uv^A^Awx>
+argv[2] = <uv^Aw^Axy>
diff --git a/tests/nquote3.tests b/tests/nquote3.tests
new file mode 100644
index 0000000..a83ff56
--- /dev/null
+++ b/tests/nquote3.tests
@@ -0,0 +1,85 @@
+a=$'a\001b'
+
+set $a
+
+b=$a
+c=$1
+d="$1"
+
+e=$'uv\001\001wx'
+f=$'uv\001w\001xy'
+
+set $e $e
+
+recho ${e%%??}
+recho "${e%%??}"
+
+recho ${e%%???}
+recho "${e%%???}"
+
+recho ${a#?}
+recho "${a#?}"
+
+# simple variables
+
+recho ${f##*$'\001'}
+recho "${f##*$'\001'}"
+recho ${f##*''} # literal ^A
+recho "${f##*'^A'}" # two characters, `^' and `A'
+
+recho ${e%$'\001'*}
+recho "${e%$'\001'*}"
+recho ${e#*$'\001'}
+recho "${e#*$'\001'}"
+
+# array members
+
+arr[0]=$e
+arr[1]=$f
+
+recho ${arr[1]##*$'\001'}
+recho "${arr[1]##*$'\001'}"
+recho ${arr[1]##*''} # literal ^A
+recho "${arr[1]##*'^A'}" # two characters, `^' and `A'
+
+recho ${arr[0]%$'\001'*}
+recho "${arr[0]%$'\001'*}"
+recho ${arr[0]#*$'\001'}
+recho "${arr[0]#*$'\001'}"
+
+recho ${arr%$'\001'*}
+recho "${arr%$'\001'*}"
+recho ${arr#*$'\001'}
+recho "${arr#*$'\001'}"
+
+# positional parameters
+
+set $e $f
+
+recho ${2##*$'\001'}
+recho "${2##*$'\001'}"
+recho ${2##*''} # literal ^A
+recho "${2##*''}" # literal ^A
+recho ${2##*'^A'} # two characters, `^' and `A'
+recho "${2##*'^A'}" # two characters, `^' and `A'
+
+recho ${1%$'\001'*}
+recho "${1%$'\001'*}"
+recho ${1#*$'\001'}
+recho "${1#*$'\001'}"
+
+recho ${@%$'\001'*}
+recho "${@%$'\001'*}"
+recho ${@#*$'\001'}
+recho "${@#*$'\001'}"
+recho ${@##*''} # literal ^A
+recho "${@##*'^A'}" # two characters, `^' and `A'
+
+# arrays treated as a whole
+
+recho ${arr[@]%$'\001'*}
+recho "${arr[@]%$'\001'*}"
+recho ${arr[@]#*$'\001'}
+recho "${arr[@]#*$'\001'}"
+recho ${arr[@]##*''} # literal ^A
+recho "${arr[@]##*'^A'}" # two characters, `^' and `A'
diff --git a/tests/nquote4.right b/tests/nquote4.right
new file mode 100644
index 0000000..1f7ae17
--- /dev/null
+++ b/tests/nquote4.right
@@ -0,0 +1,18 @@
+argv[1] = <ab>
+argv[1] = <abAcd>
+argv[1] = <abAcd>
+argv[1] = <ab^Dcd>
+argv[1] = <abLd>
+argv[1] = <abÞ>
+argv[1] = <abÞ>
+argv[1] = <abÍe>
+argv[1] = <ab^Lde>
+argv[1] = <¼X>
+argv[1] = <«cX>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <gX>
+argv[1] = <Ab>
+argv[1] = <>
+argv[1] = <^Abcd>
+argv[1] = <Þ>
diff --git a/tests/nquote4.tests b/tests/nquote4.tests
new file mode 100644
index 0000000..ed73467
--- /dev/null
+++ b/tests/nquote4.tests
@@ -0,0 +1,24 @@
+recho $'ab\x{}cd'
+recho $'ab\x{41}cd'
+recho $'ab\x41cd'
+
+recho $'ab\x{4}cd'
+recho $'ab\x4cd'
+
+recho $'ab\x{cde'
+
+recho $'ab\x{cde'
+recho $'ab\x{cd}e'
+recho $'ab\x{c}de'
+
+recho $'\x{abcX'
+recho $'\x{ab}cX'
+recho $'\x{}X'
+recho $'\x{X'
+recho $'\x{01234567X'
+
+recho $'\x{41}b'
+recho $'\x{}bc'
+recho $'\x{1}bcd'
+
+recho $'\x{bde'
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/posix2.right b/tests/posix2.right
new file mode 100644
index 0000000..df30c4f
--- /dev/null
+++ b/tests/posix2.right
@@ -0,0 +1,2 @@
+Testing for POSIX.2 conformance
+All tests passed
diff --git a/tests/posix2.tests b/tests/posix2.tests
new file mode 100644
index 0000000..a186e78
--- /dev/null
+++ b/tests/posix2.tests
@@ -0,0 +1,179 @@
+#! /bin/sh
+# posix-2.sh - Simple identification tests for POSIX.2 features
+# commonly missing or incorrectly implemented.
+# Time-stamp: <96/04/10 16:43:48 gildea>
+# By Stephen Gildea <gildea@x.org> March 1995
+#
+# Copyright (c) 1995 Stephen Gildea
+# Permission is hereby granted to deal in this Software without restriction.
+# THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND.
+#
+# MODIFIED BY chet@po.cwru.edu to make part of the bash test suite.
+# last change: Wed Jun 19 12:24:24 EDT 1996
+#
+# some of the tests:
+#
+# shell functions (do we care?)
+# var=${var:-val}
+# unset
+# set --
+# IFS parsing
+## not exiting with -e and failed "if", the way Ultrix does (Ultrix 4.2?)
+# "$@" expands to zero arguments if passed zero arguments
+# $SHELL -c 'echo $1' bad good
+# test -x
+# positional parameters greater than 9
+# arithmetic expansion $(( ... ))
+# getopts
+
+# For some tests we must run a sub-shell; $TESTSHELL says what to use.
+# If set, TESTSHELL must be an absolute pathname.
+# For example, on HP-UX 9, /bin/posix/sh is the supposedly-compliant shell.
+TESTSHELL=${THIS_SH:-$PWD/../bash}
+
+# these tests create temp files with names $TMPDIR/conf*
+: ${TMPDIR:=/tmp}
+
+exitval=0
+numtests=0
+
+echo "Testing for POSIX.2 conformance"
+
+newtest()
+{
+ numtests=$(($numtests + 1))
+}
+
+testfail()
+{
+ echo "$1 test failed"
+ exitval=$(($exitval + 1))
+}
+
+newtest
+empty=""
+test "${empty:-ok}" = ok || testfail "empty var colon"
+newtest
+test "${empty-bad}" = "" || testfail "got \"${empty-bad}\": empty var nocolon"
+newtest
+test "${unsetvar-ok}" = ok || testfail "unset var"
+newtest
+unset empty
+test "${empty-ok}" = ok || testfail "unset"
+
+newtest
+set -- -Z
+test "x$1" = x-Z || testfail '\"set -- arg\"'
+# this should empty the argument list
+newtest
+set --
+test $# = 0 || testfail "still $# args: \"set --\""
+
+# IFS parsing:
+newtest
+names=one/good/three
+saved_ifs="$IFS"
+IFS=/
+set $names lose
+test "$2" = good || testfail "got \"$2\": IFS parsing"
+IFS="$saved_ifs"
+
+# "$@" with 0 arguments should expand to 0 arguments
+newtest
+cat > $TMPDIR/conftest1 << EOF
+$TMPDIR/conftest2 "\$@"
+EOF
+cat > $TMPDIR/conftest2 << "EOF"
+#! /bin/sh
+echo $#
+EOF
+chmod +x $TMPDIR/conftest1 $TMPDIR/conftest2
+numargs=$($TESTSHELL $TMPDIR/conftest1)
+if [ "$?" != 0 ]; then
+ testfail 'running $@'
+else
+ test "$numargs" = 0 || testfail '"$@" got '"$numargs args: expansion w 0 args"
+fi
+rm -f $TMPDIR/conftest1 $TMPDIR/conftest2
+
+newtest
+val=$("$TESTSHELL" -c 'echo $1' csh good)
+test "$val" = good || testfail "got \"$val\": sh -c"
+
+newtest
+# do these tests in a sub-shell because failure will exit
+val=$("$TESTSHELL" -c 'echo ${10}' 0 1 2 3 4 5 6 7 8 9 ten 11 2> /dev/null)
+test "$val" = ten || testfail "accessing more than 9 positional params"
+
+a=abc_def_ghi
+export a
+newtest; val=`"$TESTSHELL" -c 'echo "${a%_*}"' 2> /dev/null`
+test "$val" = abc_def || testfail "parameter % op"
+newtest; val=`"$TESTSHELL" -c 'echo "${a%%_*}"' 2> /dev/null`
+test "$val" = abc || testfail "parameter %% op"
+newtest; val=`"$TESTSHELL" -c 'echo "${a#*_}"' 2> /dev/null`
+test "$val" = def_ghi || testfail "parameter # op"
+newtest; val=`"$TESTSHELL" -c 'echo "${a##*_}"' 2> /dev/null`
+test "$val" = ghi || testfail "parameter ## op"
+
+newtest
+"$TESTSHELL" -c 'export a=value' 2> /dev/null || testfail "export with value"
+
+newtest
+a=5; test "$(( ($a+1)/2 ))" = 3 || testfail "arithmetic expansion"
+
+# does "test" support the -x switch?
+newtest
+touch $TMPDIR/conftest
+chmod -x $TMPDIR/conftest
+test -x $TMPDIR/conftest && testfail "negative test -x"
+chmod +x $TMPDIR/conftest
+test -x $TMPDIR/conftest || testfail "positive test -x"
+rm -f $TMPDIR/conftest
+
+newtest
+test "$OPTIND" = 1 || testfail "OPTIND initial value"
+
+newtest
+getopts a: store -a aoptval
+if [ "$OPTIND" != 3 ] || [ "$store" != a ] || [ "$OPTARG" != aoptval ]; then
+ testfail "getopts"
+fi
+
+# if I change the default quoting style for variable values, these
+# next four must change
+
+newtest
+SQUOTE="'"
+val1=$(set | sed -n 's:^SQUOTE=::p')
+if [ "$val1" != "''\\'''" ]; then
+ testfail "variable quoting 1"
+fi
+
+newtest
+VTILDE='~'
+val1=$(set | sed -n 's:^VTILDE=::p')
+if [ "$val1" != "'~'" ]; then
+ testfail "variable quoting 2"
+fi
+
+newtest
+VHASH=ab#cd
+val1=$(set | sed -n 's:^VHASH=::p')
+if [ "$val1" != "ab#cd" ]; then
+ testfail "variable quoting 3"
+fi
+
+newtest
+VHASH2=#abcd
+val1=$(set | sed -n 's:^VHASH2=::p')
+if [ "$val1" != "'#abcd'" ]; then
+ testfail "variable quoting 4"
+fi
+
+if [ $exitval = 0 ]; then
+ echo "All tests passed"
+else
+ echo "$exitval of $numtests tests failed"
+fi
+exit $exitval
diff --git a/tests/posixpat.right b/tests/posixpat.right
new file mode 100644
index 0000000..deb01bf
--- /dev/null
+++ b/tests/posixpat.right
@@ -0,0 +1,42 @@
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+ok 6
+ok 7
+ok 8
+ok 9
+ok 10
+ok 11
+ok 12
+ok 13
+ok 14
+ok 15
+ok 16
+ok 17
+ok 18
+ok 19
+ok 20
+ok 21
+ok -- space
+ok -- blank
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+ok 6
+ok 7
+ok 8
+ok 9
+ok 10
+ok 11
+ok 12
+ok 13
+ok 14
+ok 15
+ok 16
+ok 1
+ok 2
+ok 3
diff --git a/tests/posixpat.tests b/tests/posixpat.tests
new file mode 100644
index 0000000..91fac3b
--- /dev/null
+++ b/tests/posixpat.tests
@@ -0,0 +1,233 @@
+# A test suite for the POSIX.2 (BRE) pattern matching code
+LC_ALL=C
+LANG=C
+
+# First, test POSIX.2 character classes
+
+case e in
+[[:xdigit:]]) echo ok 1;;
+esac
+
+case a in
+[[:alpha:]123]) echo ok 2;;
+esac
+
+case 1 in
+[[:alpha:]123]) echo ok 3;;
+esac
+
+case 9 in
+[![:alpha:]]) echo ok 4;;
+esac
+
+# invalid character class expressions are just characters to be matched
+case a in
+[:al:]) echo ok 5;;
+esac
+
+case a in
+[[:al:]) echo ok 6;;
+esac
+
+case '!' in
+[abc[:punct:][0-9]) echo ok 7;;
+esac
+
+# let's try to match the start of a valid sh identifier
+case 'PATH' in
+[_[:alpha:]]*) echo ok 8;;
+esac
+
+# let's try to match the first two characters of a valid sh identifier
+case PATH in
+[_[:alpha:]][_[:alnum:]]*) echo ok 9;;
+esac
+
+# is ^C a cntrl character?
+case $'\003' in
+[[:cntrl:]]) echo ok 10;;
+esac
+
+# how about A?
+case A in
+[[:cntrl:]]) echo oops -- cntrl ;;
+*) echo ok 11;;
+esac
+
+case 9 in
+[[:digit:]]) echo ok 12;;
+esac
+
+case X in
+[[:digit:]]) echo oops -- digit;;
+*) echo ok 13;;
+esac
+
+case $'\033' in
+[[:graph:]]) echo oops -- graph;;
+*) echo ok 14;;
+esac
+
+case $'\040' in
+[[:graph:]]) echo oops -- graph 2;;
+*) echo ok 15;;
+esac
+
+case ' ' in
+[[:graph:]]) echo oops -- graph 3;;
+*) echo ok 16;;
+esac
+
+case 'aB' in
+[[:lower:]][[:upper:]]) echo ok 17;;
+esac
+
+case $'\040' in
+[[:print:]]) echo ok 18;;
+*) echo oops -- print;;
+esac
+
+case PS3 in
+[_[:alpha:]][_[:alnum:]][_[:alnum:]]*) echo ok 19;;
+esac
+
+case a in
+[[:alpha:][:digit:]]) echo ok 20;;
+*) echo oops - skip brackpat ;;
+esac
+
+case a in
+[[:alpha:]\]) echo oops -- dangling backslash in brackpat ;;
+*) echo ok 21 ;;
+esac
+
+# what's a newline? is it a blank? a space?
+case $'\n' in
+[[:blank:]]) echo ok -- blank ;;
+[[:space:]]) echo ok -- space ;;
+*) echo oops newline ;;
+esac
+
+# OK, what's a tab? is it a blank? a space?
+case $'\t' in
+[[:blank:]]) echo ok -- blank ;;
+[[:space:]]) echo ok -- space ;;
+*) echo oops newline ;;
+esac
+
+# let's check out characters in the ASCII range
+case $'\377' in
+[[:ascii:]]) echo oops -- ascii\?;;
+esac
+
+case 9 in
+[1[:alpha:]123]) echo oops 1;;
+esac
+
+# however, an unterminated brace expression containing a valid char class
+# that matches had better fail
+case a in
+[[:alpha:]) echo oops 2;;
+esac
+
+case $'\b' in
+[[:graph:]]) echo oops 3;;
+esac
+
+case $'\b' in
+[[:print:]]) echo oops 4;;
+esac
+
+case $' ' in
+[[:punct:]]) echo oops 5;;
+esac
+
+# Next, test POSIX.2 collating symbols
+
+case 'a' in
+[[.a.]]) echo ok 1;;
+esac
+
+case '-' in
+[[.hyphen.]-9]) echo ok 2;;
+esac
+
+case 'p' in
+[[.a.]-[.z.]]) echo ok 3;;
+esac
+
+case '-' in
+[[.-.]]) echo ok 4;;
+esac
+
+case ' ' in
+[[.space.]]) echo ok 5;;
+esac
+
+case ' ' in
+[[.grave-accent.]]) echo oops - grave;;
+*) echo ok 6;;
+esac
+
+case '4' in
+[[.-.]-9]) echo ok 7;;
+esac
+
+# an invalid collating symbol cannot be the first part of a range
+case 'c' in
+[[.yyz.]-[.z.]]) echo oops - yyz;;
+*) echo ok 8;;
+esac
+
+case 'c' in
+[[.yyz.][.a.]-z]) echo ok 9;;
+esac
+
+# but when not part of a range is not an error
+case 'c' in
+[[.yyz.][.a.]-[.z.]]) echo ok 10 ;;
+esac
+
+case 'p' in
+[[.a.]-[.Z.]]) echo oops -- bad range ;;
+*) echo ok 11;;
+esac
+
+case p in
+[[.a.]-[.zz.]p]) echo ok 12;;
+*) echo oops -- bad range 2;;
+esac
+
+case p in
+[[.aa.]-[.z.]p]) echo ok 13;;
+*) echo oops -- bad range 3;;
+esac
+
+case c in
+[[.yyz.]cde]) echo ok 14;;
+esac
+
+case abc in
+[[.cb.]a-Za]*) echo ok 15;;
+esac
+
+case $'\t' in
+[[.space.][.tab.][.newline.]]) echo ok 16;;
+esac
+
+# and finally, test POSIX.2 equivalence classes
+
+case "abc" in
+[[:alpha:]][[=b=]][[:ascii:]]) echo ok 1;;
+esac
+
+case "abc" in
+[[:alpha:]][[=B=]][[:ascii:]]) echo oops -- =B=;;
+*) echo ok 2 ;;
+esac
+
+case a in
+[[=b=]) echo oops;; # an incomplete equiv class is just a string
+*) echo ok 3;;
+esac
+
diff --git a/tests/prec.right b/tests/prec.right
new file mode 100644
index 0000000..e6af552
--- /dev/null
+++ b/tests/prec.right
@@ -0,0 +1,28 @@
+`Say' echos its argument. Its return value is of no interest.
+`Truth' echos its argument and returns a TRUE result.
+`False' echos its argument and returns a FALSE result.
+
+ Truth 1 && Truth 2 || Say 3 output=12
+( Truth 1 && Truth 2 ) || Say 3 output=12
+
+ Truth 1 && False 2 || Say 3 output=123
+( Truth 1 && False 2 ) || Say 3 output=123
+
+ False 1 && Truth 2 || Say 3 output=13
+( False 1 && Truth 2 ) || Say 3 output=13
+
+ False 1 && False 2 || Say 3 output=13
+( False 1 && False 2 ) || Say 3 output=13
+
+Truth 1 || Truth 2 && Say 3 output=13
+Truth 1 || ( Truth 2 && Say 3 ) output=1
+
+Truth 1 || False 2 && Say 3 output=13
+Truth 1 || ( False 2 && Say 3 ) output=1
+
+False 1 || Truth 2 && Say 3 output=123
+False 1 || ( Truth 2 && Say 3 ) output=123
+
+False 1 || False 2 && Say 3 output=12
+False 1 || ( False 2 && Say 3 ) output=12
+
diff --git a/tests/precedence b/tests/precedence
new file mode 100755
index 0000000..9bbdb97
--- /dev/null
+++ b/tests/precedence
@@ -0,0 +1,75 @@
+# @(#)precedence_test 1.0 91/07/24 Maarten Litmaath
+# test of relative precedences for `&&' and `||' operators
+
+echo "\`Say' echos its argument. Its return value is of no interest."
+case `echo -n` in
+ '') Say () { echo -n "$*" ; } ;;
+ *) Say () { echo "$*\c" ; } ;;
+esac
+
+echo "\`Truth' echos its argument and returns a TRUE result."
+Truth () {
+ Say $1;
+ return 0;
+}
+
+echo "\`False' echos its argument and returns a FALSE result."
+False () {
+ Say $1;
+ return 1;
+}
+
+echo ""
+
+cmd1='$open $test1 && $test2 $close || $test3'
+cmd2='$test1 || $open $test2 && $test3 $close'
+
+grouping_sh=
+grouping_C='( )'
+
+test3='Say 3'
+
+for i in 1 2
+do
+ eval proto=\$cmd$i
+
+ for test1 in 'Truth 1' 'False 1'
+ do
+ for test2 in 'Truth 2' 'False 2'
+ do
+ for precedence in sh C
+ do
+ eval set x \$grouping_$precedence
+ shift
+ open=${1-' '}
+ close=${2-' '}
+ eval cmd=\""$proto"\"
+ Say "$cmd output="
+ output=`eval "$cmd"`
+ Say "$output"
+ read correct || { echo 'Input fubar. Abort.' >&2; exit 1; }
+ test "X$output" = "X$correct" || echo " correct=$correct"
+ echo ''
+ done
+
+ echo ''
+ done
+ done
+done << EOF
+12
+12
+123
+123
+13
+13
+13
+13
+13
+1
+13
+1
+123
+123
+12
+12
+EOF
diff --git a/tests/printf.right b/tests/printf.right
new file mode 100644
index 0000000..a6bb04d
--- /dev/null
+++ b/tests/printf.right
Binary files differ
diff --git a/tests/printf.tests b/tests/printf.tests
new file mode 100644
index 0000000..3dd5248
--- /dev/null
+++ b/tests/printf.tests
@@ -0,0 +1,311 @@
+LC_ALL=C
+LC_NUMERIC=C
+
+# these should output error messages -- the format is required
+printf
+printf --
+
+# these should output nothing
+printf ""
+printf -- ""
+
+# in the future this may mean to put the output into VAR, but for
+# now it is an error
+# 2005-03-15 no longer an error
+unset var
+printf -v var "%10d" $RANDOM
+echo ${#var}
+
+# this should expand escape sequences in the format string, nothing else
+printf "\tone\n"
+
+# this should not cut off output after the \c
+printf "one\ctwo\n"
+
+# and unrecognized backslash escapes should have the backslash preserverd
+printf "4\.2\n"
+
+printf "no newline " ; printf "now newline\n"
+
+# %% -> %
+printf "%%\n"
+
+# this was a bug caused by pre-processing the string for backslash escapes
+# before doing the `%' format processing -- all versions before bash-2.04
+printf "\045" ; echo
+printf "\045d\n"
+
+# simple character output
+printf "%c\n" ABCD
+
+# test simple string output
+printf "%s\n" unquoted
+
+# test quoted string output
+printf "%s %q\n" unquoted quoted
+printf "%s%10q\n" unquoted quoted
+
+printf "%q\n" 'this&that'
+
+# make sure the format string is reused to use up arguments
+printf "%d " 1 2 3 4 5; printf "\n"
+
+# make sure that extra format characters get null arguments
+printf "%s %d %d %d\n" onestring
+
+printf "%s %d %u %4.2f\n" onestring
+
+printf -- "--%s %s--\n" 4.2 ''
+printf -- "--%s %s--\n" 4.2
+
+# test %b escapes
+
+# 8 is a non-octal digit, so the `81' should be output
+printf -- "--%b--\n" '\n\081'
+
+printf -- "--%b--\n" '\t\0101'
+printf -- "--%b--\n" '\t\101'
+
+# these should all display `A7'
+echo -e "\01017"
+echo -e "\x417"
+
+printf "%b\n" '\01017'
+printf "%b\n" '\1017'
+printf "%b\n" '\x417'
+
+printf -- "--%b--\n" '\"abcd\"'
+printf -- "--%b--\n" "\'abcd\'"
+
+printf -- "--%b--\n" 'a\\x'
+
+printf -- "--%b--\n" '\x'
+
+Z1=$(printf -- "%b\n" '\a\b\e\f\r\v')
+Z2=$'\a\b\e\f\r\v'
+
+if [ "$Z1" != "$Z2" ]; then
+ echo "whoops: printf %b and $'' differ" >&2
+fi
+unset Z1 Z2
+
+printf -- "--%b--\n" ''
+printf -- "--%b--\n"
+
+# the stuff following the \c should be ignored, as well as the rest
+# of the format string
+printf -- "--%b--\n" '4.2\c5.4\n'; printf "\n"
+
+# unrecognized escape sequences should by displayed unchanged
+printf -- "--%b--\n" '4\.2'
+
+# a bare \ should not be processed as an escape sequence
+printf -- "--%b--\n" '\'
+
+# make sure extra arguments are ignored if the format string doesn't
+# actually use them
+printf "\n" 4.4 BSD
+printf " " 4.4 BSD ; printf "\n"
+
+# make sure that a fieldwidth and precision of `*' are handled right
+printf "%10.8s\n" 4.4BSD
+printf "%*.*s\n" 10 8 4.4BSD
+
+printf "%10.8q\n" 4.4BSD
+printf "%*.*q\n" 10 8 4.4BSD
+
+printf "%6b\n" 4.4BSD
+printf "%*b\n" 6 4.4BSD
+
+# we handle this crap with homemade code in printf.def
+printf "%10b\n" 4.4BSD
+printf -- "--%-10b--\n" 4.4BSD
+printf "%4.2b\n" 4.4BSD
+printf "%.3b\n" 4.4BSD
+printf -- "--%-8b--\n" 4.4BSD
+
+# test numeric conversions -- these four lines should echo identically
+printf "%d %u %i 0%o 0x%x 0x%X\n" 255 255 255 255 255 255
+printf "%d %u %i %#o %#x %#X\n" 255 255 255 255 255 255
+
+printf "%ld %lu %li 0%o 0x%x 0x%X\n" 255 255 255 255 255 255
+printf "%ld %lu %li %#o %#x %#X\n" 255 255 255 255 255 255
+
+printf "%10d\n" 42
+printf "%10d\n" -42
+
+printf "%*d\n" 10 42
+printf "%*d\n" 10 -42
+
+# test some simple floating point formats
+printf "%4.2f\n" 4.2
+printf "%#4.2f\n" 4.2
+printf "%#4.1f\n" 4.2
+
+printf "%*.*f\n" 4 2 4.2
+printf "%#*.*f\n" 4 2 4.2
+printf "%#*.*f\n" 4 1 4.2
+
+printf "%E\n" 4.2
+printf "%e\n" 4.2
+printf "%6.1E\n" 4.2
+printf "%6.1e\n" 4.2
+
+printf "%G\n" 4.2
+printf "%g\n" 4.2
+printf "%6.2G\n" 4.2
+printf "%6.2g\n" 4.2
+
+# test some of the more esoteric features of POSIX.1 printf
+printf "%d\n" "'string'"
+printf "%d\n" '"string"'
+
+printf "%#o\n" "'string'"
+printf "%#o\n" '"string"'
+
+printf "%#x\n" "'string'"
+printf "%#X\n" '"string"'
+
+printf "%6.2f\n" "'string'"
+printf "%6.2f\n" '"string"'
+
+# output from these two lines had better be the same
+printf -- "--%6.4s--\n" abcdefghijklmnopqrstuvwxyz
+printf -- "--%6.4b--\n" abcdefghijklmnopqrstuvwxyz
+
+# and these two also
+printf -- "--%12.10s--\n" abcdefghijklmnopqrstuvwxyz
+printf -- "--%12.10b--\n" abcdefghijklmnopqrstuvwxyz
+
+# tests for translating \' to ' and \\ to \
+# printf translates \' to ' in the format string...
+printf "\'abcd\'\n"
+
+# but not when the %b format specification is used
+printf "%b\n" \\\'abcd\\\'
+
+# but both translate \\ to \
+printf '\\abcd\\\n'
+printf "%b\n" '\\abcd\\'
+
+# this was reported as a bug in bash-2.03
+# these three lines should all echo `26'
+printf "%d\n" 0x1a
+printf "%d\n" 032
+printf "%d\n" 26
+
+# error messages
+
+# this should be an overflow, but error messages vary between systems
+# printf "%lu\n" 4294967296
+
+# ...but we cannot use this because some systems (SunOS4, for example),
+# happily ignore overflow conditions in strtol(3)
+#printf "%ld\n" 4294967296
+
+printf "%10"
+printf "ab%Mcd\n"
+
+# this caused an infinite loop in older versions of printf
+printf "%y" 0
+
+# these should print a warning and `0', according to POSIX.2
+printf "%d\n" GNU
+printf "%o\n" GNU
+
+# failures in all bash versions through bash-2.05
+printf "%.0s" foo
+printf "%.*s" 0 foo
+
+printf '%.0b-%.0s\n' foo bar
+printf '(%*b)(%*s)\n' -4 foo -4 bar
+
+format='%'`printf '%0100384d' 0`'d\n'
+printf $format 0
+
+# failures in all bash versions through bash-3.0 - undercounted characters
+unset vv
+printf " %s %s %s \n%n" ab cd ef vv
+echo "$vv"
+
+# this doesn't work with printf(3) on all systems
+#printf "%'s\n" foo
+
+# test cases from an austin-group list discussion
+# prints ^G as an extension
+printf '%b\n' '\7'
+
+# prints ^G
+printf '%b\n' '\0007'
+
+# prints NUL then 7
+printf '\0007\n'
+
+# prints no more than two hex digits
+printf '\x07e\n'
+
+# additional backslash escapes
+printf '\"\?\n'
+
+# failures with decimal precisions until after bash-3.1
+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/quote.right b/tests/quote.right
new file mode 100644
index 0000000..424d1a0
--- /dev/null
+++ b/tests/quote.right
@@ -0,0 +1,68 @@
+Single Quote
+foo
+bar
+foo
+bar
+foo\
+bar
+Double Quote
+foo
+bar
+foo
+bar
+foobar
+Backslash Single Quote
+foo bar
+foo bar
+foobar
+Backslash Double Quote
+foo bar
+foo bar
+foobar
+Double Quote Backslash Single Quote
+foo
+bar
+foo
+bar
+foobar
+Dollar Paren Single Quote
+foo bar
+foo bar
+foo\ bar
+Dollar Paren Double Quote
+foo bar
+foo bar
+foobar
+Double Quote Dollar Paren Single Quote
+foo
+bar
+foo
+bar
+foo\
+bar
+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>
+b
+a
+b
+c
+argv[1] = <a\>
+argv[2] = <b>
+argv[1] = <$>
+argv[2] = <bab>
+argv[1] = <$foo>
+argv[2] = <bab>
+argv[1] = <$foo>
+argv[2] = <bab>
+argv[1] = <`>
+argv[2] = <ab>
+argv[1] = <\>
+argv[2] = <ab>
+${
+argv[1] = <(")>
+argv[1] = <(")>
diff --git a/tests/quote.tests b/tests/quote.tests
new file mode 100644
index 0000000..46edea7
--- /dev/null
+++ b/tests/quote.tests
@@ -0,0 +1,111 @@
+echo "Single Quote"
+echo 'foo
+bar'
+echo 'foo
+bar'
+echo 'foo\
+bar'
+
+echo "Double Quote"
+echo "foo
+bar"
+echo "foo
+bar"
+echo "foo\
+bar"
+
+echo "Backslash Single Quote"
+echo `echo 'foo
+bar'`
+echo `echo 'foo
+bar'`
+echo `echo 'foo\
+bar'`
+
+echo "Backslash Double Quote"
+echo `echo "foo
+bar"`
+echo `echo "foo
+bar"`
+echo `echo "foo\
+bar"`
+
+echo "Double Quote Backslash Single Quote"
+echo "`echo 'foo
+bar'`"
+echo "`echo 'foo
+bar'`"
+echo "`echo 'foo\
+bar'`"
+
+echo "Dollar Paren Single Quote"
+echo $(echo 'foo
+bar')
+echo $(echo 'foo
+bar')
+echo $(echo 'foo\
+bar')
+
+echo "Dollar Paren Double Quote"
+echo $(echo "foo
+bar")
+echo $(echo "foo
+bar")
+echo $(echo "foo\
+bar")
+
+echo "Double Quote Dollar Paren Single Quote"
+echo "$(echo 'foo
+bar')"
+echo "$(echo 'foo
+bar')"
+echo "$(echo 'foo\
+bar')"
+
+# 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')
+
+a=`echo 'a b c' | sed 's/ /\\
+/g' | grep 'b'`
+echo $a
+a=`echo 'a b c' | sed 's/ /\\
+/g'`
+echo "$a"
+
+recho `echo 'a\' b`
+
+recho `echo '\$' bab`
+recho `echo '\$foo' bab`
+recho `echo '$foo' bab`
+
+recho `echo '\`' ab`
+
+recho `echo '\\' ab`
+
+echo `echo '${'`
+
+recho `echo "(\\")"`
+# produces no output
+: `: "\\""`
+# ultimate workaround
+recho `echo "(\")"`
+
diff --git a/tests/read.right b/tests/read.right
new file mode 100644
index 0000000..b463825
--- /dev/null
+++ b/tests/read.right
@@ -0,0 +1,65 @@
+a.
+-a-b-
+-a-b -
+-a b-
+-a b-
+-a-b\-
+-a b\-
+-\-a b\-
+-\ a b\-
+-\-a b\-
+-\ a b\-
+argv[1] = <^A>
+argv[1] = <^A>
+argv[1] = <^?>
+argv[1] = <^?>
+argv[1] = <abcd>
+1: x[A] y[B] z[]
+1a:
+2: x[A B]
+[A B ]
+[ A B ]
+==aa==
+====
+====
+argv[1] = < foo>
+argv[1] = < foo>
+argv[1] = <foo>
+argv[1] = < foo>
+argv[1] = <foo>
+argv[1] = <foo>
+argv[1] = < foo>
+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
+
+abcde
+./read3.sub: line 4: read: -1: invalid number
+abc
+ab
+#
+while read -u 3 var
+do
+echo "$var"
+done 3<$0
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+FOO
+argv[1] = <>
+argv[1] = <3>
+argv[1] = <>
+argv[2] = <>
+argv[3] = <>
+FOO
+ 0 0 0
+0
+0
+1
diff --git a/tests/read.tests b/tests/read.tests
new file mode 100644
index 0000000..fe27dae
--- /dev/null
+++ b/tests/read.tests
@@ -0,0 +1,98 @@
+echo " a " | (read x; echo "$x.")
+
+echo " a b " | ( read x y ; echo -"$x"-"$y"- )
+echo " a b\ " | ( read x y ; echo -"$x"-"$y"- )
+echo " a b " | ( read x ; echo -"$x"- )
+echo " a b\ " | ( read x ; echo -"$x"- )
+
+echo " a b\ " | ( read -r x y ; echo -"$x"-"$y"- )
+echo " a b\ " | ( read -r x ; echo -"$x"- )
+
+echo "\ a b\ " | ( read -r x y ; echo -"$x"-"$y"- )
+echo "\ a b\ " | ( read -r x ; echo -"$x"- )
+echo " \ a b\ " | ( read -r x y ; echo -"$x"-"$y"- )
+echo " \ a b\ " | ( read -r x ; echo -"$x"- )
+
+# make sure that CTLESC and CTLNUL are passed through correctly
+echo $'\001' | ( read var ; recho "$var" )
+echo $'\001' | ( read ; recho "$REPLY" )
+
+echo $'\177' | ( read var ; recho "$var" )
+echo $'\177' | ( read ; recho "$REPLY" )
+
+# make sure a backslash-quoted \\n still disappears from the input when
+# we're not reading in `raw' mode, and no stray CTLESC chars are left in
+# the input stream
+echo $'ab\\\ncd' | ( read ; recho "$REPLY" )
+
+echo "A B " > /tmp/IN
+unset x y z
+read x y z < /tmp/IN
+echo 1: "x[$x] y[$y] z[$z]"
+echo 1a: ${z-z not set}
+read x < /tmp/IN
+echo 2: "x[$x]"
+rm /tmp/IN
+
+# this is where the bash `read' behavior with respect to $REPLY differs
+# from ksh93
+echo "A B " > /tmp/IN
+
+read < /tmp/IN
+echo "[$REPLY]"
+
+rm /tmp/IN
+
+echo " A B " > /tmp/IN
+
+read < /tmp/IN
+echo "[$REPLY]"
+
+rm /tmp/IN
+
+# make sure that read with more variables than words sets the extra
+# variables to the empty string
+
+bvar=bvar
+cvar=cvar
+echo aa > /tmp/IN
+read avar bvar cvar < /tmp/IN
+echo =="$avar"==
+echo =="$bvar"==
+echo =="$cvar"==
+
+rm /tmp/IN
+
+# test behavior of read with various settings of IFS
+
+echo " foo" | { IFS= read line; recho "$line"; }
+
+echo " foo" | { IFS= ; read line; recho "$line"; }
+
+echo " foo" | { unset IFS ; read line; recho "$line"; }
+
+echo " foo" | { IFS=$'\n' ; read line; recho "$line"; }
+
+echo " foo" | { IFS=$' \n' ; read line; recho "$line"; }
+
+echo " foo" | { IFS=$' \t\n' ; read line; recho "$line"; }
+
+echo " foo" | { IFS=$':' ; read line; recho "$line"; }
+
+# test read -d delim behavior
+${THIS_SH} ./read1.sub
+
+# test read -t timeout behavior
+${THIS_SH} ./read2.sub
+
+# test read -n nchars behavior
+${THIS_SH} ./read3.sub
+
+# test read -u fd behavior
+${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/read1.sub b/tests/read1.sub
new file mode 100644
index 0000000..2a36449
--- /dev/null
+++ b/tests/read1.sub
@@ -0,0 +1,23 @@
+a=7
+echo 'abcdefg|xyz' | {
+ read -d '|' a
+ echo a = "${a-unset}"
+}
+
+echo xyz 123 | {
+ read -d ' ' a
+ echo a = "${a-unset}"
+}
+
+echo xyz 123 | {
+ read -d $'\n' a
+ echo a = -"${a-unset}"-
+}
+
+a=44
+echo abcd | {
+ read -d d a
+ echo a = $a
+}
+
+exit 0
diff --git a/tests/read2.sub b/tests/read2.sub
new file mode 100644
index 0000000..c4a1f77
--- /dev/null
+++ b/tests/read2.sub
@@ -0,0 +1,32 @@
+a=4
+
+read -t 2 a < /dev/tty
+estat=$?
+if [ $estat -gt 128 ]; then
+ echo timeout 1: ok
+else
+ echo $estat
+fi
+
+echo $a
+
+sleep 5 | read -t 1 a
+estat=$?
+if [ $estat -gt 128 ]; then
+ echo timeout 2: ok
+else
+ echo $estat
+fi
+
+echo $a
+
+read -t -3 a < /dev/tty
+echo $?
+
+echo $a
+
+# the above should all time out
+echo abcde | {
+ read -t 2 a
+ echo $a
+}
diff --git a/tests/read3.sub b/tests/read3.sub
new file mode 100644
index 0000000..22088cb
--- /dev/null
+++ b/tests/read3.sub
@@ -0,0 +1,19 @@
+# non-interactive
+
+# error
+read -n -1
+
+# from pipe -- should work, but doesn't change tty attributes
+echo abcdefg | {
+ read -n 3 xyz
+ echo $xyz
+}
+
+# fewer chars than specified
+echo ab | {
+ read -n 3 xyz
+ echo $xyz
+}
+
+read -n 1 < $0
+echo "$REPLY"
diff --git a/tests/read4.sub b/tests/read4.sub
new file mode 100644
index 0000000..80bc9fc
--- /dev/null
+++ b/tests/read4.sub
@@ -0,0 +1,4 @@
+while read -u 3 var
+do
+ echo "$var"
+done 3<$0
diff --git a/tests/read5.sub b/tests/read5.sub
new file mode 100644
index 0000000..58b992d
--- /dev/null
+++ b/tests/read5.sub
@@ -0,0 +1,36 @@
+IFS=: read x y z << EOF
+:::
+EOF
+recho $x
+recho "$x"
+recho $y
+recho "$y"
+recho $z
+recho "$z"
+
+if [ -z "$x" ]; then
+ echo FOO
+else
+ echo BAR
+fi
+
+IFS=: read -a A << EOF
+:::
+EOF
+
+recho ${A[0]}
+recho "${A[0]}"
+
+recho ${#A[@]}
+
+recho "${A[@]}"
+
+if [ -z "${A[0]}" ]; then
+ echo FOO
+else
+ echo BAR
+fi
+
+echo -n ${A[0]} | cat -vet
+echo -n ${A[0]} | wc
+
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
new file mode 100644
index 0000000..f816c63
--- /dev/null
+++ b/tests/redir.right
@@ -0,0 +1,141 @@
+abc
+./redir.tests: line 15: /tmp/redir-test: cannot overwrite existing file
+abc
+def
+def
+./redir.tests: line 31: $z: ambiguous redirect
+Point 1
+Point 2
+to a
+to b
+Point 3
+to a
+to a
+to b
+to b
+Point 4
+to c
+Point 5
+this is redir1.sub
+this is redir2.sub
+read line1 "ab"
+read line2 "root"
+read line3 "cd"
+read line4 "daemon"
+from stdin: aa
+to stdout
+./redir4.sub: line 32: $fd: ambiguous redirect
+./redir4.sub: line 33: $fd: ambiguous redirect
+/tmp/err-and-out:
+to stdout
+to stderr
+/tmp/err-and-out:
+to stdout
+to stderr
+0 -- 3 0
+0 -- 4 0
+ab
+cd
+ef
+gh
+ij
+kl
+0
+ab
+cd
+cd
+./redir.tests: line 154: redir1.*: No such file or directory
+# tests of ksh93-like dup-and-close redirection operators
+exec 9<$0
+
+f()
+{
+exec 5<$0
+
+exec 0<&5-
+
+while read line; do
+echo "$line"
+done
+}
+
+f
+
+typeset -f f
+
+# make sure it was closed
+read -u 5 foo
+echo after read
+
+exec 5<&0
+
+exec <&-
+
+read abcde
+
+exec 0<&9-
+read line
+echo $line
+f ()
+{
+ exec 5< $0;
+ exec 0<&5-;
+ while read line; do
+ echo "$line";
+ done
+}
+./redir5.sub: line 20: read: 5: invalid file descriptor: Bad file descriptor
+after read
+./redir5.sub: line 27: read: read error: 0: Bad file descriptor
+# tests of ksh93-like dup-and-close redirection operators
+/
+/
+/
+0
+0
+0
+before block
+after block
+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
new file mode 100644
index 0000000..37759b5
--- /dev/null
+++ b/tests/redir.tests
@@ -0,0 +1,189 @@
+: ${TMPDIR:=/tmp}
+
+export LC_ALL=C
+export LANG=C
+
+# catch-all for remaining untested redirection stuff
+set +o posix
+
+echo abc > /tmp/redir-test
+cat /tmp/redir-test
+
+set -o noclobber
+
+#this should be an error
+echo def > /tmp/redir-test
+cat /tmp/redir-test
+
+# but this should succeed
+echo def > /tmp/redir-test-2
+cat /tmp/redir-test-2
+
+# and so should this
+echo def >| /tmp/redir-test
+cat /tmp/redir-test
+
+set +o noclobber
+rm /tmp/redir-test /tmp/redir-test-2
+
+# this should be an error
+z="a b"
+cat < $z
+
+echo "Point 1"
+
+exec 3</etc/passwd
+exec 4>$TMPDIR/bash-a
+exec 5>$TMPDIR/bash-b
+echo "Point 2"
+
+echo to a 1>&4
+echo to b 1>&5
+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 $TMPDIR/bash-a
+cat $TMPDIR/bash-b
+
+exec 11<&-
+echo "Point 4"
+
+exec 6<>$TMPDIR/bash-c
+echo to c 1>&6
+cat $TMPDIR/bash-c
+echo "Point 5"
+
+rm -f $TMPDIR/bash-a $TMPDIR/bash-b $TMPDIR/bash-c
+
+#
+# Test the effect of input buffering on the shell's input
+#
+${THIS_SH} < redir1.sub
+
+# more open, close, duplicate file descriptors
+${THIS_SH} ./redir3.sub < ./redir3.in1
+
+# still more redirections
+${THIS_SH} ./redir4.sub < redir4.in1
+
+# various forms of null redirection
+testf()
+{
+ if [ -f "$1" ]; then
+ rm -f "$1"
+ else
+ echo oops -- $1 not found
+ fi
+}
+
+> $TMPDIR/null-redir-a
+testf $TMPDIR/null-redir-a
+
+$EXIT > $TMPDIR/null-redir-b
+testf $TMPDIR/null-redir-b
+
+( > $TMPDIR/null-redir-c )
+testf $TMPDIR/null-redir-c
+
+$EXIT > $TMPDIR/null-redir-d &
+wait
+testf $TMPDIR/null-redir-d
+
+exit 3 | $EXIT > $TMPDIR/null-redir-e
+echo $? -- ${PIPESTATUS[@]}
+testf $TMPDIR/null-redir-e
+
+exit 4 | > $TMPDIR/null-redir-f
+echo $? -- ${PIPESTATUS[@]}
+testf $TMPDIR/null-redir-f
+
+> $TMPDIR/null-redir-g &
+wait
+testf $TMPDIR/null-redir-g
+
+exec >$TMPDIR/null-redir-h &
+wait
+testf $TMPDIR/null-redir-h
+
+# make sure async commands don't get /dev/null as stdin when an explicit
+# input redirection is supplied
+for x in 1 2 3; do
+ { read line ; echo $line ; } &
+ wait
+ { read line ; echo $line ; } &
+ wait
+done << EOF
+ab
+cd
+ef
+gh
+ij
+kl
+EOF
+
+# make sure async commands get /dev/null as stdin in the absence of any
+# input redirection
+/bin/cat &
+wait
+echo $?
+
+# make sure that loops work OK with here documents and are not run in
+# subshells
+while read line; do
+ echo $line
+ l2=$line
+done << EOF
+ab
+cd
+EOF
+echo $l2
+
+# These should not echo anything -- bug in versions before 2.04
+( ( echo hello 1>&3 ) 3>&1 ) >/dev/null 2>&1
+
+( ( echo hello 1>&3 ) 3>&1 ) >/dev/null 2>&1 | cat
+
+# in posix mode, non-interactive shells are not allowed to perform
+# filename expansion on input redirections, even if they expand to
+# a single filename
+set -o posix
+cat < redir1.*
+
+# test ksh93 dup-and-close (move fd) redirections
+${THIS_SH} ./redir5.sub
+
+# test behavior after a write error with a builtin command
+${THIS_SH} ./redir6.sub
+
+# problem with redirections using fds bash uses internally
+: ${TMPDIR:=$TMPDIR}
+
+trap 'rm -f $TMPDIR/bash-redir-$$' 0 1 2 3 6 15
+
+echo before block
+{
+ echo before redir
+ exec 10>&1
+ echo after redir
+} > $TMPDIR/bash-redir-$$
+
+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/redir1.sub b/tests/redir1.sub
new file mode 100644
index 0000000..f1082e9
--- /dev/null
+++ b/tests/redir1.sub
@@ -0,0 +1,8 @@
+#
+# Test the effect of input buffering on the shell's input
+#
+echo this is redir1.sub
+
+exec 0< redir2.sub
+
+echo BUG: after exec in redir1.sub
diff --git a/tests/redir2.sub b/tests/redir2.sub
new file mode 100644
index 0000000..0820f70
--- /dev/null
+++ b/tests/redir2.sub
@@ -0,0 +1 @@
+echo this is redir2.sub
diff --git a/tests/redir3.in1 b/tests/redir3.in1
new file mode 100644
index 0000000..dbd1fc3
--- /dev/null
+++ b/tests/redir3.in1
@@ -0,0 +1,2 @@
+ab
+cd
diff --git a/tests/redir3.in2 b/tests/redir3.in2
new file mode 100644
index 0000000..5a1c32b
--- /dev/null
+++ b/tests/redir3.in2
@@ -0,0 +1,2 @@
+root
+daemon
diff --git a/tests/redir3.sub b/tests/redir3.sub
new file mode 100644
index 0000000..c486253
--- /dev/null
+++ b/tests/redir3.sub
@@ -0,0 +1,26 @@
+read line1
+
+echo read line1 \"$line1\"
+
+exec 4<./redir3.in2
+
+exec 5<&0
+exec 0<&4
+
+read line2
+
+echo read line2 \"$line2\"
+
+exec 0<&5
+
+read line3
+
+echo read line3 \"$line3\"
+
+exec 0<&4
+
+read line4
+
+echo read line4 \"$line4\"
+
+exec 4<&-
diff --git a/tests/redir4.in1 b/tests/redir4.in1
new file mode 100644
index 0000000..e61ef7b
--- /dev/null
+++ b/tests/redir4.in1
@@ -0,0 +1 @@
+aa
diff --git a/tests/redir4.sub b/tests/redir4.sub
new file mode 100644
index 0000000..4734455
--- /dev/null
+++ b/tests/redir4.sub
@@ -0,0 +1,56 @@
+minus=-
+
+# standard input
+fd=0
+
+exec 3<&$fd
+
+read line <&3
+echo from stdin: $line
+
+# close fd 3
+exec 3<&${minus}
+
+# should give `bad fd', but exact error messages vary
+# read line <&3
+
+# standard output
+fd=1
+
+exec 4>&$fd
+
+echo to stdout >&4
+
+exec 4>&$minus
+
+# should give `bad fd', but exact error messages vary
+# echo to stdout >&4
+
+unset fd
+
+# these are ambiguous redirects
+exec 3<&$fd
+exec 4>&$fd
+
+exec 3>&1 4>&2
+
+exec >&/tmp/err-and-out
+echo to stdout
+echo to stderr >&2
+
+exec 1>&3 2>&4
+echo /tmp/err-and-out:
+cat /tmp/err-and-out
+
+rm /tmp/err-and-out
+
+fd=/tmp/err-and-out
+exec >&$fd
+echo to stdout
+echo to stderr >&2
+
+exec 1>&3 2>&4
+echo /tmp/err-and-out:
+cat /tmp/err-and-out
+
+rm /tmp/err-and-out
diff --git a/tests/redir5.sub b/tests/redir5.sub
new file mode 100644
index 0000000..5d59d39
--- /dev/null
+++ b/tests/redir5.sub
@@ -0,0 +1,31 @@
+# tests of ksh93-like dup-and-close redirection operators
+exec 9<$0
+
+f()
+{
+exec 5<$0
+
+exec 0<&5-
+
+while read line; do
+ echo "$line"
+done
+}
+
+f
+
+typeset -f f
+
+# make sure it was closed
+read -u 5 foo
+echo after read
+
+exec 5<&0
+
+exec <&-
+
+read abcde
+
+exec 0<&9-
+read line
+echo $line
diff --git a/tests/redir6.sub b/tests/redir6.sub
new file mode 100644
index 0000000..60cc68b
--- /dev/null
+++ b/tests/redir6.sub
@@ -0,0 +1,8 @@
+cd /
+pwd
+help >&-
+pwd
+pwd
+echo $?
+echo $?
+echo $?
diff --git a/tests/redir7.sub b/tests/redir7.sub
new file mode 100644
index 0000000..3fd371c
--- /dev/null
+++ b/tests/redir7.sub
@@ -0,0 +1,69 @@
+# weird redirections that caused trouble and were fixed in post-3.0 bash
+stuff()
+{
+ c=1
+ ( sleep 5 < /dev/null >/dev/null 2>&1 & ) &
+}
+
+exec 3>&1
+eval `
+exec 4>&1 >&3 3>&-
+{
+ stuff 4>&-
+ echo "c=$c" >&4
+}`
+echo c1 is $c
+
+unset -f stuff
+
+stuff()
+{
+ c=2
+ ( sleep 5 < /dev/null >/dev/null 2>&1 & )
+}
+
+exec 3>&1
+eval `
+exec 4>&1 >&3 3>&-
+{
+ stuff 4>&-
+ echo "c=$c" >&4
+}`
+echo c2 is $c
+
+unset -f stuff
+
+stuff()
+{
+ c=3
+ { sleep 5 < /dev/null >/dev/null 2>&1 & } &
+}
+
+exec 3>&1
+eval `
+exec 4>&1 >&3 3>&-
+{
+ stuff 4>&-
+ echo "c=$c" >&4
+}`
+echo c3 is $c
+
+unset -f stuff
+
+stuff()
+{
+ c=4
+ { sleep 5 < /dev/null >/dev/null 2>&1 & }
+}
+
+exec 3>&1
+eval `
+exec 4>&1 >&3 3>&-
+{
+ stuff 4>&-
+ echo "c=$c" >&4
+}`
+echo c4 is $c
+
+# fixed in bash-3.1
+echo 'exec <&3' | ${THIS_SH} 3<&0
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/rhs-exp.right b/tests/rhs-exp.right
new file mode 100644
index 0000000..c5dca42
--- /dev/null
+++ b/tests/rhs-exp.right
@@ -0,0 +1,74 @@
+argv[1] = <TDEFAULTS = -DSELECT_VECS='&m68kcoff_vec'>
+argv[1] = <TDEFAULTS = -DSELECT_VECS=\'&m68kcoff_vec\'>
+argv[1] = <TDEFAULTS = -DSELECT_VECS=&m68kcoff_vec>
+argv[1] = <TDEFAULTS = -DSELECT_VECS="&m68kcoff_vec">
+argv[1] = <TDEFAULTS = -DSELECT_VECS=\&m68kcoff_vec\>
+argv[1] = <TDEFAULTS = -DSELECT_VECS=&m68kcoff_vec>
+argv[1] = <TDEFAULTS = -DSELECT_VECS=$selvecs>
+argv[1] = <TDEFAULTS = -DSELECT_VECS=$selvecs>
+argv[1] = <TDEFAULTS = -DSELECT_VECS='&m68kcoff_vec'>
+argv[1] = <TDEFAULTS = -DSELECT_VECS=\&m68kcoff_vec>
+argv[1] = <TDEFAULTS = -DSELECT_VECS='&m68kcoff_vec'>
+argv[1] = <TDEFAULTS>
+argv[2] = <=>
+argv[3] = <-DSELECT_VECS=$selvecs>
+argv[1] = <TDEFAULTS>
+argv[2] = <=>
+argv[3] = <-DSELECT_VECS='&m68kcoff_vec'>
+argv[1] = <TDEFAULTS>
+argv[2] = <=>
+argv[3] = <-DSELECT_VECS=&m68kcoff_vec>
+argv[1] = <TDEFAULTS>
+argv[2] = <=>
+argv[3] = <-DSELECT_VECS="&m68kcoff_vec">
+argv[1] = <TDEFAULTS>
+argv[2] = <=>
+argv[3] = <-DSELECT_VECS=\&m68kcoff_vec\>
+argv[1] = <TDEFAULTS>
+argv[2] = <=>
+argv[3] = <-DSELECT_VECS=&m68kcoff_vec>
+argv[1] = <TDEFAULTS>
+argv[2] = <=>
+argv[3] = <-DSELECT_VECS=$selvecs>
+argv[1] = <TDEFAULTS>
+argv[2] = <=>
+argv[3] = <-DSELECT_VECS=$selvecs>
+argv[1] = <TDEFAULTS>
+argv[2] = <=>
+argv[3] = <-DSELECT_VECS=$selvecs>
+argv[1] = <TDEFAULTS>
+argv[2] = <=>
+argv[3] = <-DSELECT_VECS=\&m68kcoff_vec>
+argv[1] = <TDEFAULTS>
+argv[2] = <=>
+argv[3] = <-DSELECT_VECS=\'&m68kcoff_vec\'>
+argv[1] = <TDEFAULTS = -DSELECT_VECS=p>
+argv[1] = <TDEFAULTS = -DSELECT_VECS=\p>
+argv[1] = <TDEFAULTS = -DSELECT_VECS=\>
+argv[1] = <TDEFAULTS = -DSELECT_VECS=\>
+argv[1] = <TDEFAULTS = -DSELECT_VECS=\'>
+argv[1] = <TDEFAULTS = -DSELECT_VECS='>
+argv[1] = <TDEFAULTS>
+argv[2] = <=>
+argv[3] = <-DSELECT_VECS=\p>
+argv[1] = <TDEFAULTS>
+argv[2] = <=>
+argv[3] = <-DSELECT_VECS=p>
+argv[1] = <TDEFAULTS>
+argv[2] = <=>
+argv[3] = <-DSELECT_VECS=\>
+argv[1] = <TDEFAULTS>
+argv[2] = <=>
+argv[3] = <-DSELECT_VECS=\>
+argv[1] = <TDEFAULTS>
+argv[2] = <=>
+argv[3] = <-DSELECT_VECS='>
+argv[1] = <TDEFAULTS>
+argv[2] = <=>
+argv[3] = <-DSELECT_VECS=\'>
+a*b
+ab
+a?b
+ab
+a/b
+ab
diff --git a/tests/rhs-exp.tests b/tests/rhs-exp.tests
new file mode 100644
index 0000000..d457198
--- /dev/null
+++ b/tests/rhs-exp.tests
@@ -0,0 +1,49 @@
+selvecs='&m68kcoff_vec'
+recho "TDEFAULTS = ${selvecs:+-DSELECT_VECS='$selvecs'}"
+recho "TDEFAULTS = ${selvecs:+-DSELECT_VECS=\'$selvecs\'}"
+recho "TDEFAULTS = ${selvecs:+-DSELECT_VECS="$selvecs"}"
+recho "TDEFAULTS = ${selvecs:+-DSELECT_VECS=\"$selvecs\"}"
+recho "TDEFAULTS = ${selvecs:+-DSELECT_VECS=\\$selvecs\\}"
+recho "TDEFAULTS = ${selvecs:+-DSELECT_VECS=$selvecs}"
+recho "TDEFAULTS = ${selvecs:+-DSELECT_VECS=\$selvecs}"
+recho "TDEFAULTS = ${selvecs:+-DSELECT_VECS="\$selvecs"}"
+recho "TDEFAULTS = ${selvecs:+-DSELECT_VECS='$selvecs'"$null"}"
+recho "TDEFAULTS = ${selvecs:+-DSELECT_VECS="\\$selvecs"}"
+recho "TDEFAULTS = ${selvecs:+-DSELECT_VECS="\'$selvecs\'"}"
+
+recho TDEFAULTS = ${selvecs:+-DSELECT_VECS='$selvecs'}
+recho TDEFAULTS = ${selvecs:+-DSELECT_VECS=\'$selvecs\'}
+recho TDEFAULTS = ${selvecs:+-DSELECT_VECS="$selvecs"}
+recho TDEFAULTS = ${selvecs:+-DSELECT_VECS=\"$selvecs\"}
+recho TDEFAULTS = ${selvecs:+-DSELECT_VECS=\\$selvecs\\}
+recho TDEFAULTS = ${selvecs:+-DSELECT_VECS=$selvecs}
+recho TDEFAULTS = ${selvecs:+-DSELECT_VECS=\$selvecs}
+recho TDEFAULTS = ${selvecs:+-DSELECT_VECS="\$selvecs"}
+recho TDEFAULTS = ${selvecs:+-DSELECT_VECS='$selvecs'"$null"}
+recho TDEFAULTS = ${selvecs:+-DSELECT_VECS="\\$selvecs"}
+recho TDEFAULTS = ${selvecs:+-DSELECT_VECS="\'$selvecs\'"}
+
+recho "TDEFAULTS = ${selvecs:+-DSELECT_VECS="\p"}"
+recho "TDEFAULTS = ${selvecs:+-DSELECT_VECS=\p}"
+recho "TDEFAULTS = ${selvecs:+-DSELECT_VECS="\\"}"
+recho "TDEFAULTS = ${selvecs:+-DSELECT_VECS=\\}"
+recho "TDEFAULTS = ${selvecs:+-DSELECT_VECS=\'}"
+recho "TDEFAULTS = ${selvecs:+-DSELECT_VECS="\'"}"
+
+recho TDEFAULTS = ${selvecs:+-DSELECT_VECS="\p"}
+recho TDEFAULTS = ${selvecs:+-DSELECT_VECS=\p}
+recho TDEFAULTS = ${selvecs:+-DSELECT_VECS="\\"}
+recho TDEFAULTS = ${selvecs:+-DSELECT_VECS=\\}
+recho TDEFAULTS = ${selvecs:+-DSELECT_VECS=\'}
+recho TDEFAULTS = ${selvecs:+-DSELECT_VECS="\'"}
+
+# more tests for bash-3.0 behavior
+
+var="a*b" ; echo "${var//\\*/}"
+var="a*b" ; echo "${var//\*/}"
+
+var="a?b" ; echo "${var//\\?/}"
+var="a?b" ; echo "${var//\?/}"
+
+var="a/b" ; echo "${var//\\//}"
+var="a/b" ; echo "${var//\//}"
diff --git a/tests/rsh.right b/tests/rsh.right
new file mode 100644
index 0000000..04c6971
--- /dev/null
+++ b/tests/rsh.right
@@ -0,0 +1,13 @@
+./rsh.tests: line 9: cd: restricted
+./rsh.tests: line 10: PATH: readonly variable
+./rsh.tests: line 11: SHELL: readonly variable
+./rsh.tests: line 12: /bin/sh: restricted: cannot specify `/' in command names
+./rsh.tests: line 14: .: ./source.sub3: restricted
+./rsh.tests: line 17: /tmp/restricted: restricted: cannot redirect output
+./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-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/rsh.tests b/tests/rsh.tests
new file mode 100644
index 0000000..ffdf6e5
--- /dev/null
+++ b/tests/rsh.tests
@@ -0,0 +1,33 @@
+# test restricted shell mode -- these should all be errors
+#
+# things not tested for:
+# adding builtins dynamically with enable -f
+# importing function definitions from environment
+
+set -r
+
+cd /
+PATH=$PATH:/usr/local/bin
+SHELL=/bin/sh
+/bin/sh -c 'echo /bin/sh executed'
+
+. ./source.sub3
+
+rm -f /tmp/restricted
+echo abc > /tmp/restricted
+if [ -f /tmp/restricted ]; then
+ echo oops 1 -- output
+fi
+echo abc >> /tmp/restricted
+if [ -f /tmp/restricted ]; then
+ echo oops 2 -- append
+fi
+
+command -p date
+
+set +r
+set +o restricted
+
+exec /bin/date
+
+echo $0: after exec
diff --git a/tests/run-alias b/tests/run-alias
new file mode 100644
index 0000000..6a20b06
--- /dev/null
+++ b/tests/run-alias
@@ -0,0 +1,2 @@
+${THIS_SH} ./alias.tests > /tmp/xx 2>&1
+diff /tmp/xx alias.right && rm -f /tmp/xx
diff --git a/tests/run-all b/tests/run-all
new file mode 100644
index 0000000..d3f3a0e
--- /dev/null
+++ b/tests/run-all
@@ -0,0 +1,29 @@
+#! /bin/sh
+
+PATH=.:$PATH # just to get recho/zecho/printenv if not run via `make tests'
+export PATH
+
+# unset BASH_ENV only if it is set
+[ "${BASH_ENV+set}" = "set" ] && unset BASH_ENV
+# ditto for SHELLOPTS
+#[ "${SHELLOPTS+set}" = "set" ] && unset SHELLOPTS
+
+: ${THIS_SH:=../bash}
+export THIS_SH
+
+${THIS_SH} ./version
+
+rm -f /tmp/xx
+
+echo Any output from any test, unless otherwise noted, indicates a possible anomaly
+
+for x in run-*
+do
+ case $x in
+ $0|run-minimal|run-gprof) ;;
+ *.orig|*~) ;;
+ *) echo $x ; sh $x ;;
+ esac
+done
+
+exit 0
diff --git a/tests/run-appendop b/tests/run-appendop
new file mode 100644
index 0000000..c5bffbc
--- /dev/null
+++ b/tests/run-appendop
@@ -0,0 +1,2 @@
+${THIS_SH} ./appendop.tests > /tmp/xx 2>&1
+diff /tmp/xx appendop.right && rm -f /tmp/xx
diff --git a/tests/run-arith b/tests/run-arith
new file mode 100644
index 0000000..f9f573c
--- /dev/null
+++ b/tests/run-arith
@@ -0,0 +1,2 @@
+${THIS_SH} ./arith.tests > /tmp/xx 2>&1
+diff /tmp/xx arith.right && rm -f /tmp/xx
diff --git a/tests/run-arith-for b/tests/run-arith-for
new file mode 100644
index 0000000..1d13075
--- /dev/null
+++ b/tests/run-arith-for
@@ -0,0 +1,2 @@
+${THIS_SH} ./arith-for.tests > /tmp/xx 2>&1
+diff /tmp/xx arith-for.right && rm -f /tmp/xx
diff --git a/tests/run-array b/tests/run-array
new file mode 100644
index 0000000..6fdbae4
--- /dev/null
+++ b/tests/run-array
@@ -0,0 +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-array2 b/tests/run-array2
new file mode 100644
index 0000000..dd94ec8
--- /dev/null
+++ b/tests/run-array2
@@ -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} ./array-at-star > /tmp/xx 2>&1
+diff /tmp/xx array2.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-braces b/tests/run-braces
new file mode 100644
index 0000000..53d4f1b
--- /dev/null
+++ b/tests/run-braces
@@ -0,0 +1,2 @@
+${THIS_SH} ./braces.tests > /tmp/xx
+diff /tmp/xx braces.right && rm -f /tmp/xx
diff --git a/tests/run-builtins b/tests/run-builtins
new file mode 100644
index 0000000..db88c8c
--- /dev/null
+++ b/tests/run-builtins
@@ -0,0 +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-cond b/tests/run-cond
new file mode 100644
index 0000000..6b119a6
--- /dev/null
+++ b/tests/run-cond
@@ -0,0 +1,7 @@
+echo "warning: all of these tests will fail if the conditional command has not" >&2
+echo "warning: been compiled into the shell" >&2
+echo "warning: some of these tests will fail if extended pattern matching has not" >&2
+echo "warning: been compiled into the shell" >&2
+
+${THIS_SH} ./cond.tests > /tmp/xx 2>&1
+diff /tmp/xx cond.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-cprint b/tests/run-cprint
new file mode 100644
index 0000000..5f202e4
--- /dev/null
+++ b/tests/run-cprint
@@ -0,0 +1,2 @@
+${THIS_SH} ./cprint.tests > /tmp/xx 2>&1
+diff /tmp/xx cprint.right && rm -f /tmp/xx
diff --git a/tests/run-dbg-support b/tests/run-dbg-support
new file mode 100755
index 0000000..9e9c649
--- /dev/null
+++ b/tests/run-dbg-support
@@ -0,0 +1,11 @@
+#!../bash
+#$Id: run-dbg-support,v 1.5 2002/11/14 06:08:16 rockyb Exp $
+
+TEST_NAME='dbg-support'
+TEST_FILE="/tmp/${TEST_NAME}.check"
+${THIS_SH} ./${TEST_NAME}.tests > $TEST_FILE 2>&1 < /dev/null
+set -f
+diff $TEST_FILE ${TEST_NAME}.right && rm -f $TEST_FILE
+
+# Return code tells testing mechanism whether passed or not.
+exit $?
diff --git a/tests/run-dbg-support2 b/tests/run-dbg-support2
new file mode 100755
index 0000000..f62583f
--- /dev/null
+++ b/tests/run-dbg-support2
@@ -0,0 +1,16 @@
+#!../bash
+#$Id: run-dbg-support2,v 1.3 2002/11/14 06:08:16 rockyb Exp $
+
+TEST_NAME='dbg-support2'
+TEST_FILE="/tmp/${TEST_NAME}.check"
+${THIS_SH} ./${TEST_NAME}.tests > $TEST_FILE 2>&1 < /dev/null
+set -f
+diff $TEST_FILE ${TEST_NAME}.right && rm -f $TEST_FILE
+
+# Return code tells testing mechanism whether passed or not.
+exit $?
+
+#;;; Local Variables: ***
+#;;; mode:shell-script ***
+#;;; eval: (sh-set-shell "bash") ***
+#;;; End: ***
diff --git a/tests/run-dirstack b/tests/run-dirstack
new file mode 100644
index 0000000..6390d1b
--- /dev/null
+++ b/tests/run-dirstack
@@ -0,0 +1,5 @@
+${THIS_SH} ./dstack.tests > /tmp/xx 2>&1
+diff /tmp/xx dstack.right && rm -f /tmp/xx
+
+${THIS_SH} ./dstack2.tests > /tmp/xx 2>&1
+diff /tmp/xx dstack2.right && rm -f /tmp/xx
diff --git a/tests/run-dollars b/tests/run-dollars
new file mode 100644
index 0000000..0ced414
--- /dev/null
+++ b/tests/run-dollars
@@ -0,0 +1,2 @@
+${THIS_SH} ./dollar-at-star > /tmp/xx 2>&1
+diff /tmp/xx dollar.right && rm -f /tmp/xx
diff --git a/tests/run-errors b/tests/run-errors
new file mode 100644
index 0000000..6be4e0c
--- /dev/null
+++ b/tests/run-errors
@@ -0,0 +1,2 @@
+${THIS_SH} ./errors.tests > /tmp/xx 2>&1
+diff /tmp/xx errors.right && rm -f /tmp/xx
diff --git a/tests/run-execscript b/tests/run-execscript
new file mode 100644
index 0000000..f97ab21
--- /dev/null
+++ b/tests/run-execscript
@@ -0,0 +1,9 @@
+echo "warning: the text of a system error message may vary between systems and" >&2
+echo "warning: produce diff output." >&2
+echo "warning: if the text of the error messages concerning \`notthere' or" >&2
+echo "warning: \`/tmp/bash-notthere' not being found or \`/' being a directory" >&2
+echo "warning: produce diff output, please do not consider this a test failure" >&2
+echo "warning: if diff output differing only in the location of the bash" >&2
+echo "warning: binary appears, please do not consider this a test failure" >&2
+${THIS_SH} ./execscript > /tmp/xx 2>&1
+diff /tmp/xx exec.right && rm -f /tmp/xx
diff --git a/tests/run-exp-tests b/tests/run-exp-tests
new file mode 100644
index 0000000..cbabace
--- /dev/null
+++ b/tests/run-exp-tests
@@ -0,0 +1,2 @@
+${THIS_SH} ./exp.tests | grep -v '^expect' > /tmp/xx
+diff /tmp/xx exp.right && rm -f /tmp/xx
diff --git a/tests/run-extglob b/tests/run-extglob
new file mode 100644
index 0000000..06316ad
--- /dev/null
+++ b/tests/run-extglob
@@ -0,0 +1,4 @@
+PATH=$PATH:`pwd`
+export PATH
+${THIS_SH} ./extglob.tests | grep -v '^expect' > /tmp/xx
+diff /tmp/xx extglob.right && rm -f /tmp/xx
diff --git a/tests/run-extglob2 b/tests/run-extglob2
new file mode 100644
index 0000000..0a6f728
--- /dev/null
+++ b/tests/run-extglob2
@@ -0,0 +1,4 @@
+PATH=$PATH:`pwd`
+export PATH
+${THIS_SH} ./extglob2.tests | grep -v '^expect' > /tmp/xx
+diff /tmp/xx extglob2.right && rm -f /tmp/xx
diff --git a/tests/run-extglob3 b/tests/run-extglob3
new file mode 100644
index 0000000..2675196
--- /dev/null
+++ b/tests/run-extglob3
@@ -0,0 +1,4 @@
+PATH=$PATH:`pwd`
+export PATH
+${THIS_SH} ./extglob3.tests > /tmp/xx
+diff /tmp/xx extglob3.right && rm -f /tmp/xx
diff --git a/tests/run-func b/tests/run-func
new file mode 100644
index 0000000..f449eb8
--- /dev/null
+++ b/tests/run-func
@@ -0,0 +1,5 @@
+echo "warning: if you have exported functions defined in your environment," >&2
+echo "warning: they may show up as diff output." >&2
+echo "warning: if so, please do not consider this a test failure" >&2
+${THIS_SH} ./func.tests > /tmp/xx 2>&1
+diff /tmp/xx func.right && rm -f /tmp/xx
diff --git a/tests/run-getopts b/tests/run-getopts
new file mode 100644
index 0000000..1e8b5fb
--- /dev/null
+++ b/tests/run-getopts
@@ -0,0 +1,2 @@
+${THIS_SH} ./getopts.tests > /tmp/xx 2>&1
+diff /tmp/xx getopts.right && rm -f /tmp/xx
diff --git a/tests/run-glob-test b/tests/run-glob-test
new file mode 100644
index 0000000..7a12343
--- /dev/null
+++ b/tests/run-glob-test
@@ -0,0 +1,4 @@
+PATH=$PATH:`pwd`
+export PATH
+${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-heredoc b/tests/run-heredoc
new file mode 100644
index 0000000..c4e3168
--- /dev/null
+++ b/tests/run-heredoc
@@ -0,0 +1,2 @@
+${THIS_SH} ./heredoc.tests > /tmp/xx 2>&1
+diff /tmp/xx heredoc.right && rm -f /tmp/xx
diff --git a/tests/run-herestr b/tests/run-herestr
new file mode 100644
index 0000000..8c5b36d
--- /dev/null
+++ b/tests/run-herestr
@@ -0,0 +1,2 @@
+${THIS_SH} ./herestr.tests > /tmp/xx 2>&1
+diff /tmp/xx herestr.right && rm -f /tmp/xx
diff --git a/tests/run-histexpand b/tests/run-histexpand
new file mode 100644
index 0000000..06a415b
--- /dev/null
+++ b/tests/run-histexpand
@@ -0,0 +1,4 @@
+echo "warning: all of these tests will fail if history has not been compiled" >&2
+echo "warning: into the shell" >&2
+${THIS_SH} ./histexp.tests > /tmp/xx 2>&1
+diff /tmp/xx histexp.right && rm -f /tmp/xx
diff --git a/tests/run-history b/tests/run-history
new file mode 100644
index 0000000..ea356b1
--- /dev/null
+++ b/tests/run-history
@@ -0,0 +1,4 @@
+echo "warning: all of these tests will fail if history has not been compiled" >&2
+echo "warning: into the shell" >&2
+${THIS_SH} ./history.tests > /tmp/xx 2>&1
+diff /tmp/xx history.right && rm -f /tmp/xx
diff --git a/tests/run-ifs b/tests/run-ifs
new file mode 100644
index 0000000..3f9d820
--- /dev/null
+++ b/tests/run-ifs
@@ -0,0 +1,2 @@
+${THIS_SH} ./ifs.tests > /tmp/xx 2>&1
+diff /tmp/xx ifs.right && rm -f /tmp/xx
diff --git a/tests/run-ifs-posix b/tests/run-ifs-posix
new file mode 100644
index 0000000..e578e8d
--- /dev/null
+++ b/tests/run-ifs-posix
@@ -0,0 +1,2 @@
+${THIS_SH} ./ifs-posix.tests > /tmp/xx 2>&1
+diff /tmp/xx ifs-posix.right && rm -f /tmp/xx
diff --git a/tests/run-input-test b/tests/run-input-test
new file mode 100644
index 0000000..aaa5d35
--- /dev/null
+++ b/tests/run-input-test
@@ -0,0 +1,2 @@
+${THIS_SH} < ./input-line.sh > /tmp/xx
+diff /tmp/xx input.right && rm -f /tmp/xx
diff --git a/tests/run-intl b/tests/run-intl
new file mode 100644
index 0000000..6a9234a
--- /dev/null
+++ b/tests/run-intl
@@ -0,0 +1,8 @@
+# See whether or not we can use `diff -a'
+( diff -a ./intl.right ./intl.right >/dev/null 2>&1 ) && AFLAG=-a
+
+echo "warning: some of these tests will fail if you do not have UTF-8" >&2
+echo "warning: locales installed on your system." >&2
+echo "warning: please ignore any differences consisting only of white space" >&2
+${THIS_SH} ./intl.tests > /tmp/xx
+diff $AFLAG /tmp/xx intl.right && rm -f /tmp/xx
diff --git a/tests/run-invert b/tests/run-invert
new file mode 100644
index 0000000..4949307
--- /dev/null
+++ b/tests/run-invert
@@ -0,0 +1,2 @@
+${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-iquote b/tests/run-iquote
new file mode 100644
index 0000000..61a8aa7
--- /dev/null
+++ b/tests/run-iquote
@@ -0,0 +1,2 @@
+${THIS_SH} ./iquote.tests >/tmp/xx 2>&1
+diff /tmp/xx iquote.right && rm -f /tmp/xx
diff --git a/tests/run-jobs b/tests/run-jobs
new file mode 100644
index 0000000..bfd4fa0
--- /dev/null
+++ b/tests/run-jobs
@@ -0,0 +1,7 @@
+echo "warning: some of these tests may fail if job control has not been compiled" >&2
+echo "warning: into the shell" >&2
+echo "warning: there may be a message regarding a cat process dying due to a" >&2
+echo "warning: SIGHUP. Please disregard." >&2
+
+${THIS_SH} ./jobs.tests > /tmp/xx 2>&1
+diff /tmp/xx jobs.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
new file mode 100644
index 0000000..0054cda
--- /dev/null
+++ b/tests/run-minimal
@@ -0,0 +1,36 @@
+#! /bin/sh
+#
+# run-minimal - a version of run-all for shells configured with
+# --enable-minimal-config
+#
+PATH=.:$PATH # just to get the right version of printenv
+export PATH
+
+# unset BASH_ENV only if it is set
+[ "${BASH_ENV+set}" = "set" ] && unset BASH_ENV
+# ditto for SHELLOPTS
+#[ "${SHELLOPTS+set}" = "set" ] && unset SHELLOPTS
+
+: ${THIS_SH:=../bash}
+export THIS_SH
+
+${THIS_SH} ./version.mini
+
+rm -f /tmp/xx
+
+echo Testing ${THIS_SH}
+echo Any output from any test, unless otherwise noted, indicates a possible anomaly
+for x in run-*
+do
+ case $x in
+ $0) ;;
+ *.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-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
+done
+
+exit 0
diff --git a/tests/run-more-exp b/tests/run-more-exp
new file mode 100644
index 0000000..60f55cb
--- /dev/null
+++ b/tests/run-more-exp
@@ -0,0 +1,2 @@
+${THIS_SH} ./more-exp.tests 2>&1 | grep -v '^expect' > /tmp/xx
+diff /tmp/xx more-exp.right && rm -f /tmp/xx
diff --git a/tests/run-new-exp b/tests/run-new-exp
new file mode 100644
index 0000000..2e3d7c9
--- /dev/null
+++ b/tests/run-new-exp
@@ -0,0 +1,10 @@
+echo "warning: two of these tests will fail if your OS does not support" >&2
+echo "warning: named pipes or the /dev/fd filesystem. If the tests of the" >&2
+echo "warning: process substitution mechanism fail, please do not consider" >&2
+echo "warning: this a test failure" >&2
+echo "warning: if you have exported variables beginning with the string _Q," >&2
+echo "warning: diff output may be generated. If so, please do not consider" >&2
+echo "warning: this a test failure" >&2
+
+${THIS_SH} ./new-exp.tests 2>&1 | grep -v '^expect' > /tmp/xx
+diff /tmp/xx new-exp.right && rm -f /tmp/xx
diff --git a/tests/run-nquote b/tests/run-nquote
new file mode 100644
index 0000000..006872c
--- /dev/null
+++ b/tests/run-nquote
@@ -0,0 +1,2 @@
+${THIS_SH} ./nquote.tests 2>&1 | grep -v '^expect' > /tmp/xx
+diff /tmp/xx nquote.right && rm -f /tmp/xx
diff --git a/tests/run-nquote1 b/tests/run-nquote1
new file mode 100644
index 0000000..a71740f
--- /dev/null
+++ b/tests/run-nquote1
@@ -0,0 +1,4 @@
+echo "warning: several of these tests will fail if arrays have not" >&2
+echo "warning: been compiled into the shell." >&2
+${THIS_SH} ./nquote1.tests 2>&1 | grep -v '^expect' > /tmp/xx
+diff /tmp/xx nquote1.right && rm -f /tmp/xx
diff --git a/tests/run-nquote2 b/tests/run-nquote2
new file mode 100644
index 0000000..80d1a8d
--- /dev/null
+++ b/tests/run-nquote2
@@ -0,0 +1,4 @@
+echo "warning: several of these tests will fail if arrays have not" >&2
+echo "warning: been compiled into the shell." >&2
+${THIS_SH} ./nquote2.tests 2>&1 | grep -v '^expect' > /tmp/xx
+diff /tmp/xx nquote2.right && rm -f /tmp/xx
diff --git a/tests/run-nquote3 b/tests/run-nquote3
new file mode 100644
index 0000000..45ba5f7
--- /dev/null
+++ b/tests/run-nquote3
@@ -0,0 +1,4 @@
+echo "warning: several of these tests will fail if arrays have not" >&2
+echo "warning: been compiled into the shell." >&2
+${THIS_SH} ./nquote3.tests 2>&1 | grep -v '^expect' > /tmp/xx
+diff /tmp/xx nquote3.right && rm -f /tmp/xx
diff --git a/tests/run-nquote4 b/tests/run-nquote4
new file mode 100644
index 0000000..493f4aa
--- /dev/null
+++ b/tests/run-nquote4
@@ -0,0 +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 >&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-posix2 b/tests/run-posix2
new file mode 100644
index 0000000..52eea2f
--- /dev/null
+++ b/tests/run-posix2
@@ -0,0 +1,2 @@
+${THIS_SH} ./posix2.tests 2>&1 | grep -v '^expect' > /tmp/xx
+diff /tmp/xx posix2.right && rm -f /tmp/xx
diff --git a/tests/run-posixpat b/tests/run-posixpat
new file mode 100644
index 0000000..ef2b140
--- /dev/null
+++ b/tests/run-posixpat
@@ -0,0 +1,2 @@
+${THIS_SH} ./posixpat.tests > /tmp/xx
+diff /tmp/xx posixpat.right && rm -f /tmp/xx
diff --git a/tests/run-precedence b/tests/run-precedence
new file mode 100644
index 0000000..d81a868
--- /dev/null
+++ b/tests/run-precedence
@@ -0,0 +1,2 @@
+${THIS_SH} ./precedence > /tmp/xx
+diff /tmp/xx prec.right && rm -f /tmp/xx
diff --git a/tests/run-printf b/tests/run-printf
new file mode 100644
index 0000000..4555c62
--- /dev/null
+++ b/tests/run-printf
@@ -0,0 +1,5 @@
+# See whether or not we can use `diff -a'
+( diff -a ./printf.tests ./printf.tests >/dev/null 2>&1 ) && AFLAG=-a
+
+${THIS_SH} ./printf.tests > /tmp/xx 2>&1
+diff $AFLAG /tmp/xx printf.right && rm -f /tmp/xx
diff --git a/tests/run-quote b/tests/run-quote
new file mode 100644
index 0000000..6905042
--- /dev/null
+++ b/tests/run-quote
@@ -0,0 +1,2 @@
+${THIS_SH} ./quote.tests >/tmp/xx 2>&1
+diff /tmp/xx quote.right && rm -f /tmp/xx
diff --git a/tests/run-read b/tests/run-read
new file mode 100644
index 0000000..47e4188
--- /dev/null
+++ b/tests/run-read
@@ -0,0 +1,4 @@
+echo "warning: please do not consider output differing only in the amount of" >&2
+echo "warning: white space to be an error." >&2
+${THIS_SH} ./read.tests > /tmp/xx 2>&1
+diff /tmp/xx read.right && rm -f /tmp/xx
diff --git a/tests/run-redir b/tests/run-redir
new file mode 100644
index 0000000..2be45dd
--- /dev/null
+++ b/tests/run-redir
@@ -0,0 +1,7 @@
+echo "warning: the text of a system error message may vary between systems and" >&2
+echo "warning: produce diff output." >&2
+echo "warning: if the text of an error message concerning \`redir1.*' not being" >&2
+echo "warning: found or messages concerning bad file descriptors produce diff" >&2
+echo "warning: output, please do not consider it a test failure" >&2
+${THIS_SH} ./redir.tests > /tmp/xx 2>&1
+diff /tmp/xx redir.right && rm -f /tmp/xx
diff --git a/tests/run-rhs-exp b/tests/run-rhs-exp
new file mode 100644
index 0000000..1f89d0b
--- /dev/null
+++ b/tests/run-rhs-exp
@@ -0,0 +1,2 @@
+${THIS_SH} ./rhs-exp.tests 2>&1 > /tmp/xx
+diff /tmp/xx rhs-exp.right && rm -f /tmp/xx
diff --git a/tests/run-rsh b/tests/run-rsh
new file mode 100644
index 0000000..ef23583
--- /dev/null
+++ b/tests/run-rsh
@@ -0,0 +1,2 @@
+${THIS_SH} ./rsh.tests > /tmp/xx 2>&1
+diff /tmp/xx rsh.right && rm -f /tmp/xx
diff --git a/tests/run-set-e b/tests/run-set-e
new file mode 100644
index 0000000..3389f11
--- /dev/null
+++ b/tests/run-set-e
@@ -0,0 +1,2 @@
+${THIS_SH} ./set-e.tests > /tmp/xx
+diff /tmp/xx set-e.right && rm -f /tmp/xx
diff --git a/tests/run-set-x b/tests/run-set-x
new file mode 100755
index 0000000..b999e69
--- /dev/null
+++ b/tests/run-set-x
@@ -0,0 +1,11 @@
+#!../bash
+#$Id: run-set-x,v 1.1 2002/12/09 13:12:37 rockyb Exp $
+
+TEST_NAME='set-x'
+TEST_FILE="/tmp/${TEST_NAME}.check"
+${THIS_SH} ./${TEST_NAME}.tests > $TEST_FILE 2>&1 < /dev/null
+set -f
+diff $TEST_FILE ${TEST_NAME}.right && rm -f $TEST_FILE
+
+# Return code tells testing mechanism whether passed or not.
+exit $?
diff --git a/tests/run-shopt b/tests/run-shopt
new file mode 100644
index 0000000..100a3de
--- /dev/null
+++ b/tests/run-shopt
@@ -0,0 +1,2 @@
+${THIS_SH} ./shopt.tests > /tmp/xx 2>&1
+diff /tmp/xx shopt.right && rm -f /tmp/xx
diff --git a/tests/run-strip b/tests/run-strip
new file mode 100644
index 0000000..0d32115
--- /dev/null
+++ b/tests/run-strip
@@ -0,0 +1,2 @@
+${THIS_SH} ./strip.tests > /tmp/xx
+diff /tmp/xx strip.right && rm -f /tmp/xx
diff --git a/tests/run-test b/tests/run-test
new file mode 100644
index 0000000..b2482c3
--- /dev/null
+++ b/tests/run-test
@@ -0,0 +1,4 @@
+unset GROUPS UID 2>/dev/null
+
+${THIS_SH} ./test.tests >/tmp/xx 2>&1
+diff /tmp/xx test.right && rm -f /tmp/xx
diff --git a/tests/run-tilde b/tests/run-tilde
new file mode 100644
index 0000000..b8569c1
--- /dev/null
+++ b/tests/run-tilde
@@ -0,0 +1,2 @@
+${THIS_SH} ./tilde.tests > /tmp/xx
+diff /tmp/xx tilde.right && rm -f /tmp/xx
diff --git a/tests/run-tilde2 b/tests/run-tilde2
new file mode 100644
index 0000000..4446989
--- /dev/null
+++ b/tests/run-tilde2
@@ -0,0 +1,2 @@
+${THIS_SH} ./tilde2.tests > /tmp/xx
+diff /tmp/xx tilde2.right && rm -f /tmp/xx
diff --git a/tests/run-trap b/tests/run-trap
new file mode 100644
index 0000000..14f6874
--- /dev/null
+++ b/tests/run-trap
@@ -0,0 +1,6 @@
+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-type b/tests/run-type
new file mode 100644
index 0000000..4d195b0
--- /dev/null
+++ b/tests/run-type
@@ -0,0 +1,2 @@
+${THIS_SH} ./type.tests > /tmp/xx 2>&1
+diff /tmp/xx type.right && rm -f /tmp/xx
diff --git a/tests/run-varenv b/tests/run-varenv
new file mode 100644
index 0000000..f0ce195
--- /dev/null
+++ b/tests/run-varenv
@@ -0,0 +1,2 @@
+${THIS_SH} ./varenv.sh | grep -v '^expect' > /tmp/xx
+diff /tmp/xx varenv.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
new file mode 100644
index 0000000..85a5986
--- /dev/null
+++ b/tests/set-e.right
@@ -0,0 +1,67 @@
+95
+96
+97
+98
+99
+0
+1
+2
+3
+4
+5
+6
+7
+8
+9
+1
+1
+ok
+hi
+while succeeded
+until succeeded: 4
+if succeeded
+AND list succeeded
+OR list succeeded
+! 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.tests b/tests/set-e.tests
new file mode 100644
index 0000000..8c0cfcf
--- /dev/null
+++ b/tests/set-e.tests
@@ -0,0 +1,110 @@
+if : ; then
+ set -e
+ N=95
+ while :; do
+ # expr returns 1 if expression is null or 0
+ set +e
+ N_MOD_100=`expr $N % 100`
+ set -e
+ echo $N_MOD_100
+ N=`expr $N + 1`
+ if [ $N -eq 110 ]; then
+ break
+ fi
+ done
+ set +e
+fi
+
+(
+set -e
+false
+echo bad
+)
+echo $?
+
+x=$(
+set -e
+false
+echo bad
+)
+echo $? $x
+
+# command subst should not inherit -e
+set -e
+echo $(false; echo ok)
+
+if set +e
+then
+ false
+fi
+echo hi
+
+set -e
+
+# a failing command in the compound list following a while, until, or
+# if should not cause the shell to exit
+
+while false; do
+ echo hi
+done
+echo while succeeded
+
+x=1
+until (( x == 4 )); do
+ x=4
+done
+echo until succeeded: $x
+
+if false; then
+ echo oops
+fi
+echo if succeeded
+
+# failing commands that are part of an AND or OR list should not
+# cause the shell to exit
+false && echo AND list failed
+echo AND list succeeded
+
+false || echo OR list succeeded
+
+! false
+echo ! succeeded
+
+# make sure eval preserves the state of the -e flag and `!' reserved word
+set -e
+if eval false; then
+ echo oops
+fi
+echo eval succeeded
+
+! eval false
+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
new file mode 100644
index 0000000..a41a382
--- /dev/null
+++ b/tests/set-x.right
@@ -0,0 +1,56 @@
++ (( i=0 ))
++ (( i<=5 ))
++ x=0
++ (( i++ ))
++ (( i<=5 ))
++ x=0
++ (( i++ ))
++ (( i<=5 ))
++ x=0
++ (( i++ ))
++ (( i<=5 ))
++ x=0
++ (( i++ ))
++ (( i<=5 ))
++ x=0
++ (( i++ ))
++ (( i<=5 ))
++ x=0
++ (( i++ ))
++ (( i<=5 ))
++ for i in 0 1 2
++ x=i
++ for i in 0 1 2
++ x=i
++ for i in 0 1 2
++ 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
new file mode 100755
index 0000000..648f0a9
--- /dev/null
+++ b/tests/set-x.tests
@@ -0,0 +1,20 @@
+#!../bash
+# $Id: set-x.tests,v 1.1 2002/12/09 13:12:37 rockyb Exp $
+#
+# Test that "set -x" shows what we think it should.
+#
+set -x
+for ((i=0; i<=5; i++ )) ; do
+ x=0
+done
+for i in 0 1 2 ; do
+ x=i
+done
+case x in
+ 0) x=i ;;
+ *) x=i ;;
+esac
+set +x
+
+# 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
new file mode 100644
index 0000000..7bacc0e
--- /dev/null
+++ b/tests/shopt.right
@@ -0,0 +1,259 @@
+./shopt.tests: line 2: shopt: -z: invalid option
+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
+shopt -u extdebug
+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
+shopt -u histverify
+shopt -s hostcomplete
+shopt -u huponexit
+shopt -s interactive_comments
+shopt -u lithist
+shopt -u login_shell
+shopt -u mailwarn
+shopt -u no_empty_cmd_completion
+shopt -u nocaseglob
+shopt -u nocasematch
+shopt -u nullglob
+shopt -s progcomp
+shopt -s promptvars
+shopt -u restricted_shell
+shopt -u shift_verbose
+shopt -s sourcepath
+shopt -u xpg_echo
+--
+shopt -u huponexit
+shopt -u checkwinsize
+shopt -s sourcepath
+--
+shopt -s cdspell
+shopt -s cmdhist
+shopt -s expand_aliases
+shopt -s extquote
+shopt -s force_fignore
+shopt -s hostcomplete
+shopt -s interactive_comments
+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
+shopt -u histverify
+shopt -u huponexit
+shopt -u lithist
+shopt -u login_shell
+shopt -u mailwarn
+shopt -u no_empty_cmd_completion
+shopt -u nocaseglob
+shopt -u nocasematch
+shopt -u nullglob
+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
+histverify off
+huponexit off
+lithist off
+login_shell off
+mailwarn off
+no_empty_cmd_completion off
+nocaseglob off
+nocasematch off
+nullglob off
+restricted_shell off
+shift_verbose off
+xpg_echo off
+--
+set +o allexport
+set -o braceexpand
+set -o emacs
+set +o errexit
+set +o errtrace
+set +o functrace
+set -o hashall
+set -o histexpand
+set -o history
+set +o ignoreeof
+set -o interactive-comments
+set +o keyword
+set -o monitor
+set +o noclobber
+set +o noexec
+set +o noglob
+set +o nolog
+set +o notify
+set +o nounset
+set +o onecmd
+set +o physical
+set +o pipefail
+set +o posix
+set -o privileged
+set +o verbose
+set +o vi
+set +o xtrace
+--
+allexport off
+braceexpand on
+emacs on
+errexit off
+errtrace off
+functrace off
+hashall on
+histexpand on
+history on
+ignoreeof off
+interactive-comments on
+keyword off
+monitor on
+noclobber off
+noexec off
+noglob off
+nolog off
+notify off
+nounset off
+onecmd off
+physical off
+pipefail off
+posix off
+privileged on
+verbose off
+vi off
+xtrace off
+--
+set +o allexport
+set -o braceexpand
+set -o emacs
+set +o errexit
+set +o errtrace
+set +o functrace
+set -o hashall
+set -o histexpand
+set -o history
+set +o ignoreeof
+set -o interactive-comments
+set +o keyword
+set -o monitor
+set +o noclobber
+set +o noexec
+set +o noglob
+set +o nolog
+set +o notify
+set +o nounset
+set +o onecmd
+set +o physical
+set +o pipefail
+set +o posix
+set -o privileged
+set +o verbose
+set +o vi
+set +o xtrace
+--
+set -o history
+set +o verbose
+--
+set -o braceexpand
+set -o emacs
+set -o hashall
+set -o histexpand
+set -o history
+set -o interactive-comments
+set -o monitor
+set -o privileged
+--
+set +o allexport
+set +o errexit
+set +o errtrace
+set +o functrace
+set +o ignoreeof
+set +o keyword
+set +o noclobber
+set +o noexec
+set +o noglob
+set +o nolog
+set +o notify
+set +o nounset
+set +o onecmd
+set +o physical
+set +o pipefail
+set +o posix
+set +o verbose
+set +o vi
+set +o xtrace
+--
+allexport off
+errexit off
+errtrace off
+functrace off
+ignoreeof off
+keyword off
+noclobber off
+noexec off
+noglob off
+nolog off
+notify off
+nounset off
+onecmd off
+physical off
+pipefail off
+posix off
+verbose off
+vi off
+xtrace off
+--
+./shopt.tests: line 93: shopt: xyz1: invalid shell option name
+./shopt.tests: line 94: shopt: xyz1: invalid option name
diff --git a/tests/shopt.tests b/tests/shopt.tests
new file mode 100644
index 0000000..d4f2a8b
--- /dev/null
+++ b/tests/shopt.tests
@@ -0,0 +1,94 @@
+# let's try an error message first
+shopt -z
+
+# first, set up a known environment
+shopt -u cdable_vars
+shopt -s cdspell
+shopt -u checkhash
+shopt -u checkwinsize
+shopt -s cmdhist
+shopt -u dotglob
+shopt -u execfail
+shopt -s expand_aliases
+shopt -u extglob
+shopt -u histreedit
+shopt -u histappend
+shopt -u histverify
+shopt -s hostcomplete
+shopt -u huponexit
+shopt -s interactive_comments
+shopt -u lithist
+shopt -u mailwarn
+shopt -u nocaseglob
+shopt -u nullglob
+shopt -s promptvars
+shopt -u shift_verbose
+shopt -s sourcepath
+shopt -u xpg_echo
+
+# Now, start checking the output
+builtin printf -- "--\n"
+shopt -p # list 'em all
+builtin printf -- "--\n"
+# test specific variables
+shopt -p huponexit
+shopt -p checkwinsize
+shopt -p sourcepath
+
+builtin printf -- "--\n"
+shopt -s -p
+builtin printf -- "--\n"
+shopt -u -p
+builtin printf -- "--\n"
+shopt -u
+
+# Now set up another known environment
+set +o allexport
+set -o braceexpand
+set +o errexit
+set -o hashall
+set -o histexpand
+set +o keyword
+set -o monitor
+set +o noclobber
+set +o noexec
+set +o noglob
+set +o notify
+set +o nounset
+set +o onecmd
+set +o physical
+set -o privileged
+set +o verbose
+set +o xtrace
+set -o history
+set +o ignoreeof
+set -o interactive-comments
+set +o posix
+set -o emacs
+set +o vi
+
+# list 'em all
+builtin printf -- "--\n"
+shopt -o -p
+
+builtin printf -- "--\n"
+set -o
+builtin printf -- "--\n"
+set +o
+
+# test specific variables
+builtin printf -- "--\n"
+shopt -p -o history
+shopt -p -o verbose
+
+builtin printf -- "--\n"
+shopt -s -p -o
+builtin printf -- "--\n"
+shopt -u -p -o
+builtin printf -- "--\n"
+shopt -u -o
+
+# errors
+builtin printf -- "--\n"
+shopt -p xyz1
+shopt -o -p xyz1
diff --git a/tests/source1.sub b/tests/source1.sub
new file mode 100644
index 0000000..8b8586f
--- /dev/null
+++ b/tests/source1.sub
@@ -0,0 +1 @@
+echo $AVAR
diff --git a/tests/source2.sub b/tests/source2.sub
new file mode 100644
index 0000000..7a031a1
--- /dev/null
+++ b/tests/source2.sub
@@ -0,0 +1,5 @@
+echo in source.sub2, calling return
+
+return 5
+
+echo oops -- return in source.sub2 failed
diff --git a/tests/source3.sub b/tests/source3.sub
new file mode 100644
index 0000000..4a12501
--- /dev/null
+++ b/tests/source3.sub
@@ -0,0 +1 @@
+echo "$@"
diff --git a/tests/source4.sub b/tests/source4.sub
new file mode 100644
index 0000000..717c1ab
--- /dev/null
+++ b/tests/source4.sub
@@ -0,0 +1 @@
+set -- m n o p
diff --git a/tests/source5.sub b/tests/source5.sub
new file mode 100644
index 0000000..e618809
--- /dev/null
+++ b/tests/source5.sub
@@ -0,0 +1,19 @@
+LC_ALL=en_US.UTF-8
+unset LC_ALL
+unset LANG
+export LC_ALL=C
+export LANG=C
+
+set +o posix
+
+# attempting to source a non-existant file is not an error...
+. /tmp/source-notthere
+
+echo after bad source 1
+
+set -o posix
+
+# ...unless you're in posix mode
+. /tmp/source-notthere
+
+echo after bad source 2
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/strip.right b/tests/strip.right
new file mode 100644
index 0000000..dfab897
--- /dev/null
+++ b/tests/strip.right
@@ -0,0 +1,12 @@
+''
+' ab '
+' '
+''
+''
+''
+'ababababababab'
+'ababababababab '
+'ababababababab '
+'abababa
+bababab '
+''
diff --git a/tests/strip.tests b/tests/strip.tests
new file mode 100644
index 0000000..b669b52
--- /dev/null
+++ b/tests/strip.tests
@@ -0,0 +1,22 @@
+v=`echo "" ; echo "" ; echo ""`
+echo "'$v'"
+v=`echo -n " ab "`
+echo "'$v'"
+v=`echo -n " "`
+echo "'$v'"
+v=`echo -n ""`
+echo "'$v'"
+v=`echo ""`
+echo "'$v'"
+v=`echo`
+echo "'$v'"
+v=`echo ababababababab`
+echo "'$v'"
+v=`echo "ababababababab "`
+echo "'$v'"
+v=`echo -n "ababababababab "`
+echo "'$v'"
+v=`echo -ne "abababa\nbababab "`
+echo "'$v'"
+v="`echo -e '\n\n\n\n'`"
+echo "'$v'"
diff --git a/tests/test.right b/tests/test.right
new file mode 100644
index 0000000..c5d7c90
--- /dev/null
+++ b/tests/test.right
@@ -0,0 +1,285 @@
+t -a noexist
+1
+t -a run-all
+0
+t -b run-all
+1
+t -b /dev/jb1a
+1
+t -c run-all
+1
+t -c /dev/tty
+0
+t -d run-all
+1
+t -d /etc
+0
+t -d ""
+1
+b -d ""
+1
+t -e noexist
+1
+t -e run-all
+0
+t -f noexist
+1
+t -f /dev/tty
+1
+t -f run-all
+0
+t -g run-all
+1
+t -g /tmp/test.setgid
+0
+t -k run-all
+1
+t -n ""
+1
+t -n "hello"
+0
+t -p run-all
+1
+t -r noexist
+1
+t -r /tmp/test.noread
+1
+t -r run-all
+0
+t -s noexist
+1
+t -s /dev/null
+1
+t -s run-all
+0
+t -t 20
+1
+t -t 0
+0
+t -u noexist
+1
+t -u run-all
+1
+t -u /tmp/test.setuid
+0
+t -w noexist
+1
+t -w /tmp/test.nowrite
+1
+t -w /dev/null
+0
+t -x noexist
+1
+t -x /tmp/test.exec
+0
+t -x /tmp/test.noexec
+1
+t -z ""
+0
+t -z "foo"
+1
+t "foo"
+0
+t ""
+1
+t -O /tmp/test.owner
+0
+t -S /tmp/test.socket
+1
+t -N /tmp/test.newer
+0
+t "hello" = "hello"
+0
+t "hello" = "goodbye"
+1
+t "hello" == "hello"
+0
+t "hello" == "goodbye"
+1
+t "hello" != "hello"
+1
+t "hello" != "goodbye"
+0
+t "hello" < "goodbye"
+1
+t "hello" > "goodbye"
+0
+t ! "hello" > "goodbye"
+1
+t 200 -eq 200
+0
+t 34 -eq 222
+1
+t -32 -eq 32
+1
+t 200 -ne 200
+1
+t 34 -ne 222
+0
+t 200 -gt 200
+1
+t 340 -gt 222
+0
+t 200 -ge 200
+0
+t 34 -ge 222
+1
+t 200 -lt 200
+1
+t 34 -lt 222
+0
+t 200 -le 200
+0
+t 340 -le 222
+1
+t 700 -le 1000 -a -n "1" -a "20" = "20"
+0
+t ! \( 700 -le 1000 -a -n "1" -a "20" = "20" \)
+1
+t /tmp/abc -nt /tmp/def
+1
+t /tmp/abc -ot /tmp/def
+0
+t /tmp/def -nt /tmp/abc
+0
+t /tmp/def -ot /tmp/abc
+1
+t /tmp/abc -ef /tmp/def
+1
+t /tmp/abc -ef /tmp/ghi
+0
+t -r /dev/fd/0
+0
+t -w /dev/fd/1
+0
+t -w /dev/fd/2
+0
+t -r /dev/stdin
+0
+t -w /dev/stdout
+0
+t -w /dev/stderr
+0
+t
+1
+b
+1
+t 12 -eq 34
+1
+t ! 12 -eq 34
+0
+t -n abcd -o aaa
+0
+t -n abcd -o -z aaa
+0
+t -n abcd -a aaa
+0
+t -n abcd -a -z aaa
+1
+t -o allexport
+1
+t ! -o allexport
+0
+t xx -a yy
+0
+t xx -o ""
+0
+t xx -a ""
+1
+t -X -a -X
+0
+t -X -o -X
+0
+t -X -o ""
+0
+t -X -a ""
+1
+t "" -a -X
+1
+t "" -o -X
+0
+t "" -a ""
+1
+t "" -o ""
+1
+t true -o -X
+0
+t true -a -X
+0
+t ( -E )
+0
+t ( "" )
+1
+t ! -z "$z"
+0
+t ! -n "$z"
+1
+t "$zero"
+1
+t ! "$zero"
+0
+b "$zero"
+1
+b ! "$zero"
+0
+t -G /tmp/test.group
+0
+t -h /tmp/test.symlink
+0
+t 4+3 -eq 7
+./test.tests: line 13: test: 4+3: integer expression expected
+2
+b 4-5 -eq 7
+./test.tests: line 7: [: 4+3: integer expression expected
+2
+t 9 -eq 4+5
+./test.tests: line 13: test: 4+5: integer expression expected
+2
+b 9 -eq 4+5
+./test.tests: line 7: [: 4+5: integer expression expected
+2
+t A -eq 7
+./test.tests: line 13: test: A: integer expression expected
+2
+b A -eq 7
+./test.tests: line 7: [: A: integer expression expected
+2
+t 9 -eq B
+./test.tests: line 13: test: B: integer expression expected
+2
+b 9 -eq B
+./test.tests: line 7: [: B: integer expression expected
+2
+t ( 1 = 2
+./test.tests: line 13: test: `)' expected
+2
+b ( 1 = 2
+./test.tests: line 7: [: `)' expected, found ]
+2
+./test.tests: line 13: test: a: unary operator expected
+2
+./test.tests: line 13: test: b: binary operator expected
+2
+./test.tests: line 13: test: -A: unary operator expected
+2
+./test.tests: line 13: test: too many arguments
+2
+./test.tests: line 13: test: too many arguments
+2
+./test.tests: line 406: [: missing `]'
+2
+./test.tests: line 13: test: (: unary operator expected
+2
+t -t a
+1
+t -t addsds
+1
+t -t 42
+1
+t -t /dev/tty
+1
+t -t /dev/tty4
+1
+t -t /dev/tty4444444...
+1
+1
diff --git a/tests/test.tests b/tests/test.tests
new file mode 100644
index 0000000..47ad9bb
--- /dev/null
+++ b/tests/test.tests
@@ -0,0 +1,426 @@
+if (( $UID == 0 )); then
+ echo "test-tests: the test suite should not be run as root" >&2
+fi
+
+b()
+{
+ [ "$@" ]
+ echo $?
+}
+
+t()
+{
+ test "$@"
+ echo $?
+}
+
+echo 't -a noexist'
+t -a noexist
+echo 't -a run-all'
+t -a run-all
+
+echo 't -b run-all'
+t -b run-all
+echo 't -b /dev/jb1a'
+t -b /dev/jb1a
+
+echo 't -c run-all'
+t -c run-all
+echo 't -c /dev/tty'
+t -c /dev/tty
+
+echo 't -d run-all'
+t -d run-all
+echo 't -d /etc'
+t -d /etc
+echo 't -d ""'
+t -d ""
+echo 'b -d ""'
+b -d ""
+
+echo 't -e noexist'
+t -e noexist
+echo 't -e run-all'
+t -e run-all
+
+echo 't -f noexist'
+t -f noexist
+echo 't -f /dev/tty'
+t -f /dev/tty
+echo 't -f run-all'
+t -f run-all
+
+echo 't -g run-all'
+t -g run-all
+
+touch /tmp/test.setgid
+chgrp ${GROUPS[0]} /tmp/test.setgid
+chmod ug+x /tmp/test.setgid
+chmod g+s /tmp/test.setgid
+echo 't -g /tmp/test.setgid'
+t -g /tmp/test.setgid
+rm -f /tmp/test.setgid
+
+echo 't -k run-all'
+t -k run-all
+
+echo 't -n ""'
+t -n ""
+echo 't -n "hello"'
+t -n "hello"
+
+echo 't -p run-all'
+t -p run-all
+
+echo 't -r noexist'
+t -r noexist
+
+if (( $UID != 0 )); then
+ touch /tmp/test.noread
+ chmod a-r /tmp/test.noread
+ echo 't -r /tmp/test.noread'
+ t -r /tmp/test.noread
+ rm -f /tmp/test.noread
+else
+ echo 't -r /tmp/test.noread'
+ echo 1
+fi
+
+echo 't -r run-all'
+t -r run-all
+
+echo 't -s noexist'
+t -s noexist
+echo 't -s /dev/null'
+t -s /dev/null
+echo 't -s run-all'
+t -s run-all
+
+echo 't -t 20'
+t -t 20
+echo 't -t 0'
+t -t 0 < /dev/tty
+
+echo 't -u noexist'
+t -u noexist
+
+echo 't -u run-all'
+t -u run-all
+
+touch /tmp/test.setuid
+chmod u+x /tmp/test.setuid # some systems require this to turn on setuid bit
+chmod u+s /tmp/test.setuid
+echo 't -u /tmp/test.setuid'
+t -u /tmp/test.setuid
+rm -f /tmp/test.setuid
+
+echo 't -w noexist'
+t -w noexist
+
+if (( $UID != 0 )); then
+ touch /tmp/test.nowrite
+ chmod a-w /tmp/test.nowrite
+ echo 't -w /tmp/test.nowrite'
+ t -w /tmp/test.nowrite
+ rm -f /tmp/test.nowrite
+else
+ echo 't -w /tmp/test.nowrite'
+ echo 1
+fi
+
+echo 't -w /dev/null'
+t -w /dev/null
+
+echo 't -x noexist'
+t -x noexist
+
+touch /tmp/test.exec
+chmod u+x /tmp/test.exec
+echo 't -x /tmp/test.exec'
+t -x /tmp/test.exec
+rm -f /tmp/test.exec
+
+touch /tmp/test.noexec
+chmod u-x /tmp/test.noexec
+echo 't -x /tmp/test.noexec'
+t -x /tmp/test.noexec
+rm -f /tmp/test.noexec
+
+echo 't -z ""'
+t -z ""
+echo 't -z "foo"'
+t -z "foo"
+
+echo 't "foo"'
+t "foo"
+echo 't ""'
+t ""
+
+touch /tmp/test.owner
+echo 't -O /tmp/test.owner'
+t -O /tmp/test.owner
+rm -f /tmp/test.owner
+
+touch /tmp/test.socket
+echo 't -S /tmp/test.socket'
+t -S /tmp/test.socket # false
+rm -f /tmp/test.socket
+
+touch /tmp/test.newer
+echo 't -N /tmp/test.newer'
+t -N /tmp/test.newer
+rm -f /tmp/test.newer
+
+echo 't "hello" = "hello"'
+t "hello" = "hello"
+echo 't "hello" = "goodbye"'
+t "hello" = "goodbye"
+
+echo 't "hello" == "hello"'
+t "hello" == "hello"
+echo 't "hello" == "goodbye"'
+t "hello" == "goodbye"
+
+echo 't "hello" != "hello"'
+t "hello" != "hello"
+echo 't "hello" != "goodbye"'
+t "hello" != "goodbye"
+
+echo 't "hello" < "goodbye"'
+t "hello" \< "goodbye"
+echo 't "hello" > "goodbye"'
+t "hello" \> "goodbye"
+
+echo 't ! "hello" > "goodbye"'
+t "! hello" \> "goodbye"
+
+echo 't 200 -eq 200'
+t 200 -eq 200
+echo 't 34 -eq 222'
+t 34 -eq 222
+echo 't -32 -eq 32'
+t -32 -eq 32
+
+echo 't 200 -ne 200'
+t 200 -ne 200
+echo 't 34 -ne 222'
+t 34 -ne 222
+
+echo 't 200 -gt 200'
+t 200 -gt 200
+echo 't 340 -gt 222'
+t 340 -gt 222
+
+echo 't 200 -ge 200'
+t 200 -ge 200
+echo 't 34 -ge 222'
+t 34 -ge 222
+
+echo 't 200 -lt 200'
+t 200 -lt 200
+echo 't 34 -lt 222'
+t 34 -lt 222
+
+echo 't 200 -le 200'
+t 200 -le 200
+echo 't 340 -le 222'
+t 340 -le 222
+
+echo 't 700 -le 1000 -a -n "1" -a "20" = "20"'
+t 700 -le 1000 -a -n "1" -a "20" = "20"
+echo 't ! \( 700 -le 1000 -a -n "1" -a "20" = "20" \)'
+t ! \( 700 -le 1000 -a -n "1" -a "20" = "20" \)
+
+touch /tmp/abc
+sleep 2
+touch /tmp/def
+
+echo 't /tmp/abc -nt /tmp/def'
+t /tmp/abc -nt /tmp/def
+echo 't /tmp/abc -ot /tmp/def'
+t /tmp/abc -ot /tmp/def
+echo 't /tmp/def -nt /tmp/abc'
+t /tmp/def -nt /tmp/abc
+echo 't /tmp/def -ot /tmp/abc'
+t /tmp/def -ot /tmp/abc
+
+echo 't /tmp/abc -ef /tmp/def'
+t /tmp/abc -ef /tmp/def
+ln /tmp/abc /tmp/ghi
+echo 't /tmp/abc -ef /tmp/ghi'
+t /tmp/abc -ef /tmp/ghi
+
+rm /tmp/abc /tmp/def /tmp/ghi
+
+echo 't -r /dev/fd/0'
+t -r /dev/fd/0
+echo 't -w /dev/fd/1'
+t -w /dev/fd/1
+echo 't -w /dev/fd/2'
+t -w /dev/fd/2
+
+echo 't -r /dev/stdin'
+t -r /dev/stdin
+echo 't -w /dev/stdout'
+t -w /dev/stdout
+echo 't -w /dev/stderr'
+t -w /dev/stderr
+
+echo 't'
+t
+echo 'b'
+b
+
+echo 't 12 -eq 34'
+t 12 -eq 34
+echo 't ! 12 -eq 34'
+t ! 12 -eq 34
+
+echo 't -n abcd -o aaa'
+t -n abcd -o aaa
+echo 't -n abcd -o -z aaa'
+t -n abcd -o -z aaa
+
+echo 't -n abcd -a aaa'
+t -n abcd -a aaa
+echo 't -n abcd -a -z aaa'
+t -n abcd -a -z aaa
+
+set +o allexport
+echo 't -o allexport'
+t -o allexport
+echo 't ! -o allexport'
+t ! -o allexport
+
+echo 't xx -a yy'
+t xx -a yy
+echo 't xx -o ""'
+t xx -o ""
+echo 't xx -a ""'
+t xx -a ""
+
+echo 't -X -a -X'
+t -X -a -X
+echo 't -X -o -X'
+t -X -o -X
+echo 't -X -o ""'
+t -X -o ""
+echo 't -X -a ""'
+t -X -a ""
+echo 't "" -a -X'
+t "" -a -X
+echo 't "" -o -X'
+t "" -o -X
+echo 't "" -a ""'
+t "" -a ""
+echo 't "" -o ""'
+t "" -o ""
+echo 't true -o -X'
+t true -o -X
+echo 't true -a -X'
+t true -a -X
+
+echo 't ( -E )'
+t \( -E \)
+echo 't ( "" )'
+t \( "" \)
+
+z=42
+
+echo 't ! -z "$z"'
+t ! -z "$z"
+
+echo 't ! -n "$z"'
+t ! -n "$z"
+
+zero=
+echo 't "$zero"'
+t "$zero"
+echo 't ! "$zero"'
+t ! "$zero"
+echo 'b "$zero"'
+b "$zero"
+echo 'b ! "$zero"'
+b ! "$zero"
+
+touch /tmp/test.group
+chgrp ${GROUPS[0]} /tmp/test.group
+echo 't -G /tmp/test.group'
+t -G /tmp/test.group
+rm /tmp/test.group
+
+case "${THIS_SH}" in
+/*) SHNAME=${THIS_SH} ;;
+*) SHNAME=${PWD}/${THIS_SH} ;;
+esac
+
+if ln -s ${SHNAME} /tmp/test.symlink 2>/dev/null; then
+ chgrp ${GROUPS[0]} /tmp/test.symlink 2>/dev/null
+ echo 't -h /tmp/test.symlink'
+ t -h /tmp/test.symlink
+ # some systems don't let you remove this
+ rm -f /tmp/test.symlink 2>/dev/null
+else
+ echo 't -h /tmp/test.symlink'
+ echo 0
+fi
+
+# arithmetic constant errors
+echo "t 4+3 -eq 7"
+t 4+3 -eq 7
+echo "b 4-5 -eq 7"
+b 4+3 -eq 7
+
+echo "t 9 -eq 4+5"
+t 9 -eq 4+5
+echo "b 9 -eq 4+5"
+b 9 -eq 4+5
+
+A=7
+echo "t A -eq 7"
+t A -eq 7
+echo "b A -eq 7"
+b A -eq 7
+
+B=9
+echo "t 9 -eq B"
+t 9 -eq B
+echo "b 9 -eq B"
+b 9 -eq B
+
+# badly formed expressions
+echo 't ( 1 = 2'
+t \( 1 = 2
+echo 'b ( 1 = 2'
+b \( 1 = 2
+
+# more errors
+t a b
+t a b c
+t -A v
+# too many arguments -- argument expected is also reasonable
+t 4 -eq 4 -a 2 -ne 5 -a 4 -ne
+# too many arguments
+t 4 -eq 4 -a 3 4
+
+[
+echo $?
+
+t \( \)
+
+# non-numeric arguments to `test -t' should return failure -- fix in 2.05
+echo 't -t a'
+t -t a
+echo 't -t addsds'
+t -t addsds
+echo 't -t 42'
+t -t 42
+echo 't -t /dev/tty'
+t -t /dev/tty
+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/tilde.right b/tests/tilde.right
new file mode 100644
index 0000000..fe58ae3
--- /dev/null
+++ b/tests/tilde.right
@@ -0,0 +1,25 @@
+~chet
+/usr/xyz/foo
+~chet/foo
+~chet/foo
+~chet/bar
+~chet/bar
+~chet/bar
+:~chet/
+abcd~chet
+SHELL=~/bash
+/usr/xyz/bash
+abcd:~chet
+/usr/ucb:/bin:/usr/xyz/bin:/usr/xyz/tmp/bin:/usr/bin
+/usr
+/tmp
+/bin:/usr/bin:.:/usr/xyz/bin
+/bin:/usr/bin:.:~/bin
+/bin:/usr/bin:.:/usr/xyz/bin
+/bin:/usr/bin:.:/usr/xyz/bin
+/bin:/usr/bin:.:~/bin
+/bin:/usr/bin:.:~/bin
+ok 1
+ok 2
+ok 3
+~root
diff --git a/tests/tilde.tests b/tests/tilde.tests
new file mode 100644
index 0000000..8b2bdb8
--- /dev/null
+++ b/tests/tilde.tests
@@ -0,0 +1,69 @@
+# this is needed because posix mode restricts tilde expansion to assignment
+# statements preceding a command, instead of the default of expanding all
+# assignment statements on the line (e.g., after `export'). Without this,
+# the next-to-last test fails
+set +o posix
+
+HOME=/usr/xyz
+SHELL=~/bash
+echo ~ch\et
+echo ~/"foo"
+echo "~chet"/"foo"
+echo \~chet/"foo"
+echo \~chet/bar
+echo ~\chet/bar
+echo ~chet""/bar
+echo ":~chet/"
+echo abcd~chet
+echo "SHELL=~/bash"
+echo $SHELL
+echo abcd:~chet
+path=/usr/ucb:/bin:~/bin:~/tmp/bin:/usr/bin
+echo $path
+
+cd /usr
+cd /tmp
+echo ~-
+echo ~+
+
+XPATH=/bin:/usr/bin:.
+
+# yes tilde expansion
+PPATH=$XPATH:~/bin
+echo "$PPATH"
+
+# no tilde expansion
+PPATH="$XPATH:~/bin"
+echo "$PPATH"
+
+# yes tilde expansion
+export PPATH=$XPATH:~/bin
+echo "$PPATH"
+declare -x PPATH=$XPATH:~/bin
+echo "$PPATH"
+
+# no tilde expansion
+export PPATH="$XPATH:~/bin"
+echo "$PPATH"
+declare -x PPATH="$XPATH:~/bin"
+echo "$PPATH"
+
+# more tests of tilde expansion when executing case commands
+case ~ in
+$HOME) echo ok 1;;
+*) echo bad 1 ;;
+esac
+
+case ~ in
+~) echo ok 2 ;;
+\~) echo bad 2a ;;
+*) echo bad 2b ;;
+esac
+
+case $unset in
+"") echo ok 3 ;;
+*) echo bad 3 ;;
+esac
+
+USER=root # should exist just about everywhere
+echo ~$USER
diff --git a/tests/tilde2.right b/tests/tilde2.right
new file mode 100644
index 0000000..fce0468
--- /dev/null
+++ b/tests/tilde2.right
@@ -0,0 +1,24 @@
+PATH=~/bin:/bin:/usr/bin:.
+/usr/xyz/bin:~/bin2:/bin:/usr/bin:.
+PATH=~/bin:~/bin2:/bin:/usr/bin:.
+~/bin
+~
+/usr/xyz
+~
+~
+~
+argv[1] = <\a>
+argv[1] = <\a>
+/usr/xyz/bash
+ok
+~
+~
+make -k FOO=/usr/xyz/mumble
+/usr/xyz/mumble
+HOME=~
+HOME=~
+/usr/$x/abc
+HOME=~
+/usr/$x/abc
+HOME=/usr/$x/abc
+/usr/$x/abc
diff --git a/tests/tilde2.tests b/tests/tilde2.tests
new file mode 100644
index 0000000..ff6c76f
--- /dev/null
+++ b/tests/tilde2.tests
@@ -0,0 +1,70 @@
+HOME=/usr/xyz
+XPATH=/bin:/usr/bin:.
+
+ADDPATH=PATH=~/bin:$XPATH
+
+echo $ADDPATH
+
+unset ADDPATH
+: ${ADDPATH:=~/bin:~/bin2:$XPATH}
+echo $ADDPATH
+
+unset ADDPATH
+: ${ADDPATH:=PATH=~/bin:~/bin2:$XPATH}
+echo $ADDPATH
+
+cat << !
+~/bin
+!
+
+echo "~"
+
+echo ${TPATH:-~}
+echo "${TPATH:-~}"
+echo "${TPATH:-"~"}"
+
+echo "${XPATH+~}"
+
+recho "\a"
+recho "${TPATH:-\a}"
+
+SHELL=~/bash
+echo $SHELL
+
+case $SHELL in
+~/bash) echo ok;;
+*) echo bad;;
+esac
+
+somevar=
+echo "${somevar:-~}"
+echo "${somevar:-"~"}"
+
+echo make -k FOO=~/mumble
+
+typeset FOO=~/mumble
+echo "$FOO"
+
+h=HOME=~
+echo $h
+
+export h=HOME=~
+echo $h
+
+x=1234
+HOME='/usr/$x/abc'
+
+echo ~
+
+# behavior differs here in posix mode
+set -o posix
+
+eval echo $h
+eval $h
+echo $HOME
+
+set +o posix
+
+eval echo $h
+eval $h
+echo $HOME
diff --git a/tests/trap.right b/tests/trap.right
new file mode 100644
index 0000000..c8417ac
--- /dev/null
+++ b/tests/trap.right
@@ -0,0 +1,85 @@
+subshell exit
+trap -- 'echo exiting' EXIT
+trap -- 'echo aborting' SIGHUP
+trap -- 'echo aborting' SIGINT
+trap -- 'echo aborting' SIGQUIT
+trap -- 'echo aborting' SIGABRT
+trap -- 'echo aborting' SIGTERM
+[20] debug
+debug line
+[22] debug
+trap -- 'echo exiting' EXIT
+trap -- 'echo aborting' SIGHUP
+trap -- 'echo aborting' SIGINT
+trap -- 'echo aborting' SIGQUIT
+trap -- 'echo aborting' SIGABRT
+trap -- 'echo aborting' SIGTERM
+trap -- 'echo [$LINENO] debug' DEBUG
+[24] debug
+func[16] funcdebug
+funcdebug line
+[26] debug
+trap -- 'echo exiting' EXIT
+trap -- 'echo aborting' SIGHUP
+trap -- 'echo aborting' SIGINT
+trap -- 'echo aborting' SIGQUIT
+trap -- 'echo aborting' SIGABRT
+trap -- 'echo aborting' SIGTERM
+trap -- 'echo [$LINENO] debug' DEBUG
+[28] debug
+./trap.tests[33] debug
+./trap.tests[34] debug
+func2[30] debug
+func2[31] debug
+func2debug line
+./trap.tests[36] debug
+./trap.tests[38] debug
+trap -- 'echo exiting' EXIT
+trap -- 'echo aborting' SIGHUP
+trap -- 'echo aborting' SIGINT
+trap -- 'echo aborting' SIGQUIT
+trap -- 'echo aborting' SIGABRT
+trap -- 'echo aborting' SIGTERM
+trap -- '' DEBUG
+trap -- 'echo exiting' EXIT
+trap -- 'echo aborting' SIGHUP
+trap -- 'echo aborting' SIGINT
+trap -- 'echo aborting' SIGQUIT
+trap -- 'echo aborting' SIGABRT
+trap -- 'echo aborting' SIGTERM
+trap -- 'echo exiting' EXIT
+trap -- '' SIGINT
+trap -- 'echo aborting' SIGQUIT
+trap -- 'echo aborting' SIGABRT
+trap -- 'echo aborting' SIGTERM
+0
+ERRTRAP
+ERRTRAP
+ERRTRAP
+after falses
+if negation ok
+after negation
+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
+trap -- 'echo caught a child death' SIGCHLD
+trap -- 'echo exiting' EXIT
+trap -- 'echo aborting' SIGABRT
+trap -- 'echo caught a child death' SIGCHLD
+trap -- '' SIGUSR2
+exiting
diff --git a/tests/trap.tests b/tests/trap.tests
new file mode 100644
index 0000000..ded1d70
--- /dev/null
+++ b/tests/trap.tests
@@ -0,0 +1,93 @@
+# test the trap code
+
+trap 'echo exiting' 0
+trap 'echo aborting' 1 2 3 6 15
+
+# make sure a user-specified subshell runs the exit trap, but does not
+# inherit the exit trap from a parent shell
+( trap 'echo subshell exit' 0; exit 0 )
+( exit 0 )
+
+trap
+
+func()
+{
+ trap 'echo ${FUNCNAME:-$0}[$LINENO] funcdebug' DEBUG
+ echo funcdebug line
+}
+
+trap 'echo [$LINENO] debug' DEBUG
+echo debug line
+
+trap
+
+func
+
+trap
+
+trap 'echo ${FUNCNAME:-$0}[$LINENO] debug' DEBUG
+func2()
+{
+ echo func2debug line
+}
+declare -ft func2
+func2
+
+unset -f func2
+
+trap '' DEBUG
+
+trap
+
+trap - debug
+
+trap
+
+trap - HUP
+trap hup
+trap '' INT
+trap '' int
+
+trap
+
+# exit 0 in exit trap should set exit status
+(
+set -e
+trap 'exit 0' EXIT
+false
+echo bad
+)
+echo $?
+
+# hmmm...should this set the handling to SIG_IGN for children, too?
+trap '' USR2
+./trap1.sub
+
+# test ERR trap
+./trap2.sub
+
+${THIS_SH} ./trap3.sub
+
+#
+# show that setting a trap on SIGCHLD is not disastrous.
+#
+set -o monitor
+
+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
+
+# Now reset some of the signals the shell handles specially back to
+# their default values (with or without the SIG prefix)
+trap - SIGINT QUIT TERM
+
+trap
+
+trap - SIGCHLD
+wait
+
diff --git a/tests/trap1.sub b/tests/trap1.sub
new file mode 100755
index 0000000..48f8530
--- /dev/null
+++ b/tests/trap1.sub
@@ -0,0 +1,4 @@
+# signals ignored at shell startup cannot be trapped or reset
+trap 'echo USR2' USR2
+
+trap -p USR2
diff --git a/tests/trap2.sub b/tests/trap2.sub
new file mode 100755
index 0000000..73357df
--- /dev/null
+++ b/tests/trap2.sub
@@ -0,0 +1,25 @@
+set +e
+trap 'echo ERRTRAP' ERR
+
+false
+false
+false
+
+echo after falses
+
+if ! false; then
+ echo if negation ok
+fi
+
+! false
+echo after negation
+
+while false; do
+ echo while negation ok
+done
+
+echo after while
+
+./trap2a.sub
+
+echo $(false ; echo command substitution)
diff --git a/tests/trap2a.sub b/tests/trap2a.sub
new file mode 100755
index 0000000..44d6b50
--- /dev/null
+++ b/tests/trap2a.sub
@@ -0,0 +1,3 @@
+echo before false in trap2a.sub
+false
+echo after false in trap2a.sub
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
new file mode 100644
index 0000000..a628231
--- /dev/null
+++ b/tests/type.right
@@ -0,0 +1,82 @@
+./type.tests: line 9: type: -r: invalid option
+type: usage: type [-afptP] name [name ...]
+./type.tests: line 12: type: notthere: not found
+function
+keyword
+builtin
+file
+file
+file
+func is a function
+func ()
+{
+ echo this is func
+}
+while is a shell keyword
+while is a shell keyword
+builtin is a shell builtin
+/bin/sh is /bin/sh
+func
+func is a function
+func ()
+{
+ echo this is func
+}
+while
+while is a shell keyword
+./type.tests: line 43: type: m: not found
+alias m='more'
+alias m='more'
+m is aliased to `more'
+alias
+alias m='more'
+alias m='more'
+alias m='more'
+m is aliased to `more'
+builtin
+builtin is a shell builtin
+/bin/sh
+/bin/sh is /bin/sh
+./type.tests: line 65: type: func: not found
+./type.tests: line 67: type: m: not found
+/bin/sh
+/tmp/bash
+bash is hashed (/tmp/bash)
+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
new file mode 100644
index 0000000..6caa243
--- /dev/null
+++ b/tests/type.tests
@@ -0,0 +1,93 @@
+set +o posix
+
+hash -r
+unalias -a
+
+# this should echo nothing
+type
+# this should be a usage error
+type -r ${THIS_SH}
+
+# these should behave identically
+type notthere
+command -v notthere
+
+alias m=more
+
+unset -f func 2>/dev/null
+func() { echo this is func; }
+
+type -t func
+type -t while
+type -t builtin
+type -t /bin/sh
+type -t ${THIS_SH}
+type -t mv
+
+type func
+# the following two should produce identical output
+type while
+type -a while
+type builtin
+type /bin/sh
+
+command -v func
+command -V func
+command -v while
+command -V while
+
+# the following two lines should produce the same output
+# post-3.0 patch makes command -v silent, as posix specifies
+# first test with alias expansion off (should all fail or produce no output)
+type -t m
+type m
+command -v m
+alias -p
+alias m
+
+# then test with alias expansion on
+shopt -s expand_aliases
+type m
+type -t m
+command -v m
+alias -p
+alias m
+
+command -V m
+shopt -u expand_aliases
+
+command -v builtin
+command -V builtin
+command -v /bin/sh
+command -V /bin/sh
+
+unset -f func
+type func
+unalias m
+type m
+
+hash -r
+
+hash -p /bin/sh sh
+type -p sh
+
+SHBASE=${THIS_SH##*/}
+hash -p /tmp/$SHBASE $SHBASE
+type -p $SHBASE
+type $SHBASE
+
+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/varenv.right b/tests/varenv.right
new file mode 100644
index 0000000..df8086d
--- /dev/null
+++ b/tests/varenv.right
@@ -0,0 +1,56 @@
+3 4
+5 6 7 8 9
+7 8 9
+/usr/chet
+/usr/chet
+/usr/chet
+/a/b/c
+/usr/chet
+/usr/chet 7
+/a/b/c 9 /a/b/c
+/a/b/c 9 /a/b/c
+/a/b/c /a/b/c
+1 2
+1 1
+unset
+toronto airport
+AVAR
+song by rush
+BVAR
+toronto airport
+AVAR
+AVAR
+42
+/bin:/usr/bin:/usr/local/bin:.
+avar=([0]="/bin:/usr/bin:/usr/local/bin:.")
+z=yy
+42
+declare -i ivar="10"
+unset
+declare -x ivar="42"
+hB
+braceexpand:hashall:interactive-comments
+hBP
+braceexpand:hashall:interactive-comments:physical
+declare -r SHELLOPTS="braceexpand:hashall:interactive-comments:physical"
+abcde
+20
+30
+40
+50
+|0|10|
+10
+|0|10|
+10
+|0|10|
+10
+|4|
+4
+|0|11|
+after fff3: x=4
+|0|12|
+|y|
+|y|
+a=z
+a=b
+a=z
diff --git a/tests/varenv.sh b/tests/varenv.sh
new file mode 100644
index 0000000..77776f9
--- /dev/null
+++ b/tests/varenv.sh
@@ -0,0 +1,206 @@
+#
+# varenv.sh
+#
+# Test the behavior of the shell with respect to variable and environment
+# assignments
+#
+expect()
+{
+ echo expect "$@"
+}
+
+a=1
+b=2
+c=3
+d=4
+e=5
+f=6 g=7 h=8
+
+a=3 b=4 $CHMOD $MODE $FN
+
+# This should echo "3 4" according to Posix.2
+expect "3 4"
+echo $a $b
+
+set -k
+
+# Assignment statements made when no words are left affect the shell's
+# environment
+a=5 b=6 $CHMOD c=7 $MODE d=8 $FN e=9
+
+expect "5 6 7 8 9"
+echo $a $b $c $d $e
+
+$CHMOD f=7 $MODE g=8 $FN h=9
+expect "7 8 9"
+echo $f $g $h
+
+set +k
+
+# The temporary environment does not affect variable expansion, only the
+# environment given to the command
+
+export HOME=/usr/chet
+expect $HOME
+echo $HOME
+
+expect $HOME
+HOME=/a/b/c /bin/echo $HOME
+
+expect $HOME
+echo $HOME
+
+# This should echo /a/b/c
+expect /a/b/c
+HOME=/a/b/c printenv HOME
+
+set -k
+
+# This should echo $HOME 9, NOT /a/b/c 9
+
+expect "$HOME"
+HOME=/a/b/c /bin/echo $HOME c=9
+expect "$HOME 7"
+echo $HOME $c
+
+# I claim the next two echo calls should give identical output.
+# ksh agrees, the System V.3 sh does not
+
+expect "/a/b/c 9 /a/b/c"
+HOME=/a/b/c $ECHO a=$HOME c=9
+echo $HOME $c $a
+
+expect "/a/b/c 9 /a/b/c"
+HOME=/a/b/c a=$HOME c=9
+echo $HOME $c $a
+set +k
+
+# How do assignment statements affect subsequent assignments on the same
+# line?
+expect "/a/b/c /a/b/c"
+HOME=/a/b/c a=$HOME
+echo $HOME $a
+
+# The system V.3 sh does this wrong; the last echo should output "1 1",
+# but the system V.3 sh has it output "2 2". Posix.2 says the assignment
+# statements are processed left-to-right. bash and ksh output the right
+# thing
+c=1
+d=2
+expect "1 2"
+echo $c $d
+d=$c c=$d
+expect "1 1"
+echo $c $d
+
+# just for completeness
+unset d c
+expect unset
+echo ${d-unset}
+
+# no output
+export a
+a=bcde
+export a
+/bin/true 2>/dev/null
+
+func()
+{
+ local YYZ
+
+ YYZ="song by rush"
+ echo $YYZ
+ echo $A
+}
+
+YYZ="toronto airport"
+A="AVAR"
+echo $YYZ
+echo $A
+A=BVAR func
+echo $YYZ
+echo $A
+
+export A
+# Make sure expansion doesn't use assignment statements preceding a builtin
+A=ZVAR echo $A
+
+XPATH=/bin:/usr/bin:/usr/local/bin:.
+func2()
+{
+ local z=yy
+ local -a avar=( ${XPATH//: } )
+ echo ${avar[@]}
+ local
+}
+
+avar=42
+echo $avar
+func2
+echo $avar
+
+# try to set an attribute for an unset variable; make sure it persists
+# when the variable is assigned a value
+declare -i ivar
+
+ivar=10
+
+declare -p ivar
+unset ivar
+
+# export an unset variable, make sure it is not suddenly set, but make
+# sure the export attribute persists when the variable is assigned a
+# value
+export ivar
+echo ${ivar-unset}
+
+ivar=42
+declare -p ivar
+
+# make sure set [-+]o ignoreeof and $IGNOREEOF are reflected
+unset IGNOREEOF
+set +o ignoreeof
+set -o ignoreeof
+if [ "$IGNOREEOF" -ne 10 ]; then
+ echo "./varenv.sh: set -o ignoreeof is not reflected in IGNOREEOF" >&2
+fi
+unset IGNOREEOF
+set +o ignoreeof
+
+# older versions of bash used to not reset RANDOM in subshells correctly
+[[ $RANDOM -eq $(echo $RANDOM) ]] && echo "RANDOM: problem with subshells"
+
+# make sure that shopt -o is reflected in $SHELLOPTS
+# first, get rid of things that might be set automatically via shell
+# variables
+set +o posix
+set +o ignoreeof
+set +o monitor
+echo $-
+echo ${SHELLOPTS}
+shopt -so physical
+echo $-
+echo ${SHELLOPTS}
+
+# and make sure it is readonly
+readonly -p | grep SHELLOPTS
+
+# This was an error in bash versions prior to bash-2.04. The `set -a'
+# should cause the assignment statement that's an argument to typeset
+# to create an exported variable
+unset FOOFOO
+FOOFOO=bar
+set -a
+typeset FOOFOO=abcde
+
+printenv FOOFOO
+
+# test out export behavior of variable assignments preceding builtins and
+# functions
+$THIS_SH ./varenv1.sub
+
+# more tests; bugs in bash up to version 2.05a
+$THIS_SH ./varenv2.sub
+
+# make sure variable scoping is done right
+tt() { typeset a=b;echo a=$a; };a=z;echo a=$a;tt;echo a=$a
diff --git a/tests/varenv1.sub b/tests/varenv1.sub
new file mode 100644
index 0000000..168f87b
--- /dev/null
+++ b/tests/varenv1.sub
@@ -0,0 +1,28 @@
+# test out the export behavior of variable assignments preceding `eval', `.'
+# and shell functions
+
+func()
+{
+ printenv var
+}
+
+export var=10
+echo expect 20
+var=20 eval printenv var
+
+: ${TMPDIR:=/tmp}
+TMPFILE=$TMPDIR/evalsub.$$
+
+rm -f $TMPFILE
+echo 'printenv var' > $TMPFILE
+
+echo expect 30
+var=30 . $TMPFILE
+
+rm -f $TMPFILE
+
+echo expect 40
+var=40 func
+
+echo expect 50
+var=50 command printenv var
diff --git a/tests/varenv2.sub b/tests/varenv2.sub
new file mode 100644
index 0000000..b293572
--- /dev/null
+++ b/tests/varenv2.sub
@@ -0,0 +1,44 @@
+fff()
+{
+ typeset i=0 x=10
+ echo "|$i|$x|"
+ export x
+ printenv x
+}
+
+fff2()
+{
+ echo "|$x|"
+ export x
+ printenv x
+}
+
+fff3()
+{
+ typeset i=0 x="${x-10}"
+ echo "|$i|$x|"
+}
+
+fff4()
+{
+ typeset i=0 x
+ x="${x-10}"
+ echo "|$i|$x|"
+}
+
+fff5()
+{
+ z=y typeset z
+ echo "|$z|"
+}
+
+fff
+x=10 fff
+x=1 fff
+x=4 fff2
+x=11 fff3
+echo after fff3: x=$x
+x=12 fff4
+
+fff5
+z=42 fff5
diff --git a/tests/version b/tests/version
new file mode 100644
index 0000000..bd74020
--- /dev/null
+++ b/tests/version
@@ -0,0 +1,8 @@
+echo Testing ${THIS_SH}
+
+echo version: $BASH_VERSION
+echo versinfo: ${BASH_VERSINFO[@]}
+
+echo HOSTTYPE = $HOSTTYPE
+echo OSTYPE = $OSTYPE
+echo MACHTYPE = $MACHTYPE
diff --git a/tests/version.mini b/tests/version.mini
new file mode 100644
index 0000000..72e4bf9
--- /dev/null
+++ b/tests/version.mini
@@ -0,0 +1,8 @@
+echo Testing ${THIS_SH}
+
+echo version: $BASH_VERSION
+#echo versinfo: ${BASH_VERSINFO[@]}
+
+echo HOSTTYPE = $HOSTTYPE
+echo OSTYPE = $OSTYPE
+echo MACHTYPE = $MACHTYPE
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