summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 15:38:56 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 15:38:56 +0000
commit6c20c8ed2cb9ab69a1a57ccb2b9b79969a808321 (patch)
treef63ce19d57fad3ac4a15bc26dbfbfa2b834111b5 /tests
parentInitial commit. (diff)
downloadbash-6c20c8ed2cb9ab69a1a57ccb2b9b79969a808321.tar.xz
bash-6c20c8ed2cb9ab69a1a57ccb2b9b79969a808321.zip
Adding upstream version 5.2.15.upstream/5.2.15upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'tests')
-rw-r--r--tests/COPYRIGHT9
-rw-r--r--tests/README3
-rw-r--r--tests/alias.right45
-rw-r--r--tests/alias.tests65
-rw-r--r--tests/alias1.sub33
-rw-r--r--tests/alias2.sub35
-rw-r--r--tests/alias3.sub11
-rw-r--r--tests/alias4.sub100
-rw-r--r--tests/alias5.sub28
-rw-r--r--tests/alias6.sub13
-rw-r--r--tests/appendop.right28
-rw-r--r--tests/appendop.tests100
-rw-r--r--tests/appendop1.sub28
-rw-r--r--tests/appendop2.sub31
-rw-r--r--tests/arith-for.right86
-rw-r--r--tests/arith-for.tests128
-rw-r--r--tests/arith.right263
-rw-r--r--tests/arith.tests333
-rw-r--r--tests/arith1.sub51
-rw-r--r--tests/arith2.sub58
-rw-r--r--tests/arith3.sub60
-rw-r--r--tests/arith4.sub10
-rw-r--r--tests/arith5.sub72
-rw-r--r--tests/arith6.sub65
-rw-r--r--tests/arith7.sub11
-rw-r--r--tests/arith8.sub50
-rw-r--r--tests/array-at-star120
-rw-r--r--tests/array.right787
-rw-r--r--tests/array.tests429
-rw-r--r--tests/array1.sub1
-rw-r--r--tests/array10.sub65
-rw-r--r--tests/array11.sub48
-rw-r--r--tests/array12.sub34
-rw-r--r--tests/array13.sub12
-rw-r--r--tests/array14.sub43
-rw-r--r--tests/array15.sub52
-rw-r--r--tests/array16.sub34
-rw-r--r--tests/array17.sub91
-rw-r--r--tests/array18.sub47
-rw-r--r--tests/array19.sub175
-rw-r--r--tests/array2.right74
-rw-r--r--tests/array2.sub4
-rw-r--r--tests/array20.sub47
-rw-r--r--tests/array21.sub50
-rw-r--r--tests/array22.sub59
-rw-r--r--tests/array23.sub41
-rw-r--r--tests/array24.sub60
-rw-r--r--tests/array25.sub83
-rw-r--r--tests/array26.sub131
-rw-r--r--tests/array27.sub78
-rw-r--r--tests/array28.sub30
-rw-r--r--tests/array29.sub86
-rw-r--r--tests/array3.sub9
-rw-r--r--tests/array30.sub46
-rw-r--r--tests/array4.sub45
-rw-r--r--tests/array5.sub47
-rw-r--r--tests/array6.sub128
-rw-r--r--tests/array7.sub14
-rw-r--r--tests/array8.sub36
-rw-r--r--tests/array9.sub40
-rw-r--r--tests/assoc.right400
-rw-r--r--tests/assoc.tests268
-rw-r--r--tests/assoc1.sub29
-rw-r--r--tests/assoc10.sub30
-rw-r--r--tests/assoc11.sub90
-rw-r--r--tests/assoc12.sub74
-rw-r--r--tests/assoc13.sub44
-rw-r--r--tests/assoc14.sub35
-rw-r--r--tests/assoc15.sub92
-rw-r--r--tests/assoc16.sub56
-rw-r--r--tests/assoc17.sub58
-rw-r--r--tests/assoc18.sub59
-rw-r--r--tests/assoc2.sub28
-rw-r--r--tests/assoc3.sub28
-rw-r--r--tests/assoc4.sub35
-rw-r--r--tests/assoc5.sub40
-rw-r--r--tests/assoc6.sub159
-rw-r--r--tests/assoc7.sub29
-rw-r--r--tests/assoc8.sub7
-rw-r--r--tests/assoc9.sub159
-rw-r--r--tests/attr.right37
-rw-r--r--tests/attr.tests54
-rw-r--r--tests/attr1.sub68
-rw-r--r--tests/attr2.sub37
-rw-r--r--tests/braces.right77
-rw-r--r--tests/braces.tests132
-rw-r--r--tests/builtins.right281
-rw-r--r--tests/builtins.tests286
-rw-r--r--tests/builtins1.sub14
-rw-r--r--tests/builtins2.sub10
-rw-r--r--tests/builtins3.sub14
-rw-r--r--tests/builtins4.sub57
-rw-r--r--tests/builtins5.sub83
-rw-r--r--tests/builtins6.sub81
-rw-r--r--tests/builtins7.sub38
-rw-r--r--tests/case.right63
-rw-r--r--tests/case.tests73
-rw-r--r--tests/case1.sub77
-rw-r--r--tests/case2.sub65
-rw-r--r--tests/case3.sub52
-rw-r--r--tests/case4.sub38
-rw-r--r--tests/casemod.right47
-rw-r--r--tests/casemod.tests126
-rw-r--r--tests/complete.right63
-rw-r--r--tests/complete.tests126
-rw-r--r--tests/comsub-eof.right17
-rw-r--r--tests/comsub-eof.tests13
-rw-r--r--tests/comsub-eof0.sub6
-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.sub15
-rw-r--r--tests/comsub-eof6.sub5
-rw-r--r--tests/comsub-posix.right100
-rw-r--r--tests/comsub-posix.tests286
-rw-r--r--tests/comsub-posix1.sub3
-rw-r--r--tests/comsub-posix2.sub29
-rw-r--r--tests/comsub-posix3.sub35
-rw-r--r--tests/comsub-posix5.sub70
-rw-r--r--tests/comsub-posix6.sub43
-rw-r--r--tests/comsub.right79
-rw-r--r--tests/comsub.tests84
-rw-r--r--tests/comsub1.sub73
-rw-r--r--tests/comsub2.sub8
-rw-r--r--tests/comsub3.sub44
-rw-r--r--tests/comsub4.sub40
-rw-r--r--tests/comsub5.sub51
-rw-r--r--tests/comsub6.sub40
-rw-r--r--tests/cond-regexp1.sub69
-rw-r--r--tests/cond-regexp2.sub45
-rw-r--r--tests/cond-regexp3.sub86
-rw-r--r--tests/cond.right142
-rw-r--r--tests/cond.tests232
-rw-r--r--tests/coproc.right10
-rw-r--r--tests/coproc.tests78
-rw-r--r--tests/cprint.right72
-rw-r--r--tests/cprint.tests80
-rw-r--r--tests/dbg-support.right371
-rw-r--r--tests/dbg-support.sub39
-rw-r--r--tests/dbg-support.tests148
-rw-r--r--tests/dbg-support2.right7
-rw-r--r--tests/dbg-support2.tests33
-rw-r--r--tests/dbg-support3.sub52
-rw-r--r--tests/dollar-at-star332
-rw-r--r--tests/dollar-at-star1.sub36
-rw-r--r--tests/dollar-at-star10.sub66
-rw-r--r--tests/dollar-at-star11.sub80
-rw-r--r--tests/dollar-at-star2.sub220
-rw-r--r--tests/dollar-at-star3.sub57
-rw-r--r--tests/dollar-at-star4.sub112
-rw-r--r--tests/dollar-at-star5.sub66
-rw-r--r--tests/dollar-at-star6.sub42
-rw-r--r--tests/dollar-at-star7.sub38
-rw-r--r--tests/dollar-at-star8.sub14
-rw-r--r--tests/dollar-at-star9.sub278
-rw-r--r--tests/dollar-at1.sub42
-rw-r--r--tests/dollar-at2.sub32
-rw-r--r--tests/dollar-at3.sub9
-rw-r--r--tests/dollar-at4.sub10
-rw-r--r--tests/dollar-at5.sub95
-rw-r--r--tests/dollar-at6.sub43
-rw-r--r--tests/dollar-at7.sub59
-rw-r--r--tests/dollar-star1.sub44
-rw-r--r--tests/dollar-star10.sub92
-rw-r--r--tests/dollar-star2.sub39
-rw-r--r--tests/dollar-star3.sub31
-rw-r--r--tests/dollar-star4.sub9
-rw-r--r--tests/dollar-star5.sub29
-rw-r--r--tests/dollar-star6.sub32
-rw-r--r--tests/dollar-star7.sub43
-rw-r--r--tests/dollar-star8.sub34
-rw-r--r--tests/dollar-star9.sub59
-rw-r--r--tests/dollar.right744
-rw-r--r--tests/dstack.right55
-rw-r--r--tests/dstack.tests100
-rw-r--r--tests/dstack2.right24
-rw-r--r--tests/dstack2.tests49
-rw-r--r--tests/dynvar.right7
-rw-r--r--tests/dynvar.tests102
-rw-r--r--tests/errors.right208
-rw-r--r--tests/errors.tests308
-rw-r--r--tests/errors1.sub40
-rw-r--r--tests/errors2.sub3
-rw-r--r--tests/errors3.sub7
-rw-r--r--tests/errors4.sub31
-rw-r--r--tests/errors5.sub12
-rw-r--r--tests/errors6.sub56
-rw-r--r--tests/errors7.sub30
-rw-r--r--tests/errors8.sub14
-rw-r--r--tests/errors9.sub14
-rw-r--r--tests/exec.right172
-rwxr-xr-xtests/exec1.sub1
-rw-r--r--tests/exec10.sub47
-rw-r--r--tests/exec11.sub14
-rw-r--r--tests/exec12.sub32
-rw-r--r--tests/exec13.sub34
-rw-r--r--tests/exec14.sub64
-rw-r--r--tests/exec2.sub5
-rw-r--r--tests/exec3.sub37
-rw-r--r--tests/exec4.sub8
-rw-r--r--tests/exec5.sub9
-rw-r--r--tests/exec6.sub67
-rw-r--r--tests/exec7.sub36
-rw-r--r--tests/exec8.sub1
-rw-r--r--tests/exec9.sub33
-rw-r--r--tests/execscript160
-rw-r--r--tests/exp.right419
-rw-r--r--tests/exp.tests426
-rw-r--r--tests/exp1.sub34
-rw-r--r--tests/exp10.sub39
-rw-r--r--tests/exp11.sub105
-rw-r--r--tests/exp12.sub51
-rw-r--r--tests/exp13.sub34
-rw-r--r--tests/exp2.sub12
-rw-r--r--tests/exp3.sub7
-rw-r--r--tests/exp4.sub10
-rw-r--r--tests/exp5.sub34
-rw-r--r--tests/exp6.sub43
-rw-r--r--tests/exp7.sub36
-rw-r--r--tests/exp8.sub45
-rw-r--r--tests/exp9.sub82
-rw-r--r--tests/exportfunc.right14
-rw-r--r--tests/exportfunc.tests92
-rw-r--r--tests/exportfunc1.sub34
-rw-r--r--tests/exportfunc2.sub413
-rw-r--r--tests/exportfunc3.sub38
-rw-r--r--tests/extglob.right184
-rw-r--r--tests/extglob.tests390
-rw-r--r--tests/extglob1.sub50
-rw-r--r--tests/extglob1a.sub29
-rw-r--r--tests/extglob2.right70
-rw-r--r--tests/extglob2.sub31
-rw-r--r--tests/extglob2.tests103
-rw-r--r--tests/extglob3.right27
-rw-r--r--tests/extglob3.sub37
-rw-r--r--tests/extglob3.tests69
-rw-r--r--tests/extglob4.sub45
-rw-r--r--tests/extglob5.sub31
-rw-r--r--tests/extglob6.sub43
-rw-r--r--tests/extglob7.sub97
-rw-r--r--tests/func.right169
-rw-r--r--tests/func.tests198
-rw-r--r--tests/func1.sub68
-rw-r--r--tests/func2.sub40
-rw-r--r--tests/func3.sub67
-rw-r--r--tests/func4.sub52
-rw-r--r--tests/getopts.right68
-rw-r--r--tests/getopts.tests56
-rw-r--r--tests/getopts1.sub39
-rw-r--r--tests/getopts10.sub30
-rw-r--r--tests/getopts2.sub39
-rw-r--r--tests/getopts3.sub40
-rw-r--r--tests/getopts4.sub43
-rw-r--r--tests/getopts5.sub62
-rw-r--r--tests/getopts6.sub40
-rw-r--r--tests/getopts7.sub43
-rw-r--r--tests/getopts8.sub13
-rw-r--r--tests/getopts9.sub29
-rw-r--r--tests/glob.right261
-rw-r--r--tests/glob.tests410
-rw-r--r--tests/glob1.sub30
-rw-r--r--tests/glob10.sub32
-rw-r--r--tests/glob2.sub65
-rw-r--r--tests/glob3.sub163
-rw-r--r--tests/glob4.sub41
-rw-r--r--tests/glob5.sub78
-rw-r--r--tests/glob6.sub69
-rw-r--r--tests/glob7.sub11
-rw-r--r--tests/glob8.sub31
-rw-r--r--tests/glob9.sub13
-rw-r--r--tests/globstar.right587
-rw-r--r--tests/globstar.tests56
-rw-r--r--tests/globstar1.sub34
-rw-r--r--tests/globstar2.sub97
-rw-r--r--tests/globstar3.sub37
-rw-r--r--tests/heredoc.right133
-rw-r--r--tests/heredoc.tests156
-rw-r--r--tests/heredoc1.sub29
-rw-r--r--tests/heredoc2.sub9
-rw-r--r--tests/heredoc3.sub98
-rw-r--r--tests/heredoc4.sub12
-rw-r--r--tests/heredoc5.sub41
-rw-r--r--tests/heredoc6.sub50
-rw-r--r--tests/heredoc7.sub29
-rw-r--r--tests/herestr.right38
-rw-r--r--tests/herestr.tests80
-rw-r--r--tests/herestr1.sub10
-rw-r--r--tests/histexp.right246
-rw-r--r--tests/histexp.tests158
-rw-r--r--tests/histexp1.sub36
-rw-r--r--tests/histexp2.sub14
-rw-r--r--tests/histexp3.sub57
-rw-r--r--tests/histexp4.sub36
-rw-r--r--tests/histexp5.sub41
-rw-r--r--tests/histexp6.sub37
-rw-r--r--tests/histexp7.sub18
-rw-r--r--tests/history.list4
-rw-r--r--tests/history.right299
-rw-r--r--tests/history.tests133
-rw-r--r--tests/history1.sub28
-rw-r--r--tests/history2.sub10
-rw-r--r--tests/history3.sub49
-rw-r--r--tests/history4.sub47
-rw-r--r--tests/history5.sub57
-rw-r--r--tests/history6.sub55
-rw-r--r--tests/ifs-posix.right1
-rw-r--r--tests/ifs-posix.tests270
-rw-r--r--tests/ifs.right12
-rw-r--r--tests/ifs.tests76
-rw-r--r--tests/ifs1.sub14
-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.right57
-rw-r--r--tests/intl.tests68
-rw-r--r--tests/intl1.sub11
-rw-r--r--tests/intl2.sub31
-rw-r--r--tests/intl3.sub36
-rw-r--r--tests/invert.right10
-rw-r--r--tests/invert.tests32
-rw-r--r--tests/iquote.right92
-rw-r--r--tests/iquote.tests158
-rw-r--r--tests/iquote1.sub56
-rw-r--r--tests/jobs.right120
-rw-r--r--tests/jobs.tests209
-rw-r--r--tests/jobs1.sub30
-rw-r--r--tests/jobs2.sub13
-rw-r--r--tests/jobs3.sub39
-rw-r--r--tests/jobs4.sub39
-rw-r--r--tests/jobs5.sub71
-rw-r--r--tests/jobs6.sub14
-rw-r--r--tests/jobs7.sub8
-rw-r--r--tests/lastpipe.right22
-rw-r--r--tests/lastpipe.tests74
-rw-r--r--tests/lastpipe1.sub5
-rw-r--r--tests/lastpipe2.sub43
-rw-r--r--tests/lastpipe3.sub11
-rw-r--r--tests/mapfile.data17
-rw-r--r--tests/mapfile.right170
-rw-r--r--tests/mapfile.tests62
-rw-r--r--tests/mapfile1.sub11
-rw-r--r--tests/mapfile2.sub6
-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
-rw-r--r--tests/misc/run-r2.sh1
-rw-r--r--tests/misc/sigint-1.sh9
-rw-r--r--tests/misc/sigint-2.sh7
-rw-r--r--tests/misc/sigint-3.sh11
-rw-r--r--tests/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.tests517
-rw-r--r--tests/nameref.right560
-rw-r--r--tests/nameref.tests133
-rw-r--r--tests/nameref1.sub13
-rw-r--r--tests/nameref10.sub77
-rw-r--r--tests/nameref11.sub76
-rw-r--r--tests/nameref12.sub113
-rw-r--r--tests/nameref13.sub115
-rw-r--r--tests/nameref14.sub56
-rw-r--r--tests/nameref15.sub127
-rw-r--r--tests/nameref16.sub57
-rw-r--r--tests/nameref17.sub116
-rw-r--r--tests/nameref18.sub83
-rw-r--r--tests/nameref19.sub73
-rw-r--r--tests/nameref2.sub7
-rw-r--r--tests/nameref20.sub84
-rw-r--r--tests/nameref21.sub69
-rw-r--r--tests/nameref22.sub97
-rw-r--r--tests/nameref23.sub82
-rw-r--r--tests/nameref3.sub50
-rw-r--r--tests/nameref4.sub234
-rw-r--r--tests/nameref5.sub63
-rw-r--r--tests/nameref6.sub57
-rw-r--r--tests/nameref7.sub31
-rw-r--r--tests/nameref8.sub74
-rw-r--r--tests/nameref9.sub8
-rw-r--r--tests/new-exp.right795
-rw-r--r--tests/new-exp.tests654
-rw-r--r--tests/new-exp1.sub29
-rw-r--r--tests/new-exp10.sub118
-rw-r--r--tests/new-exp11.sub59
-rw-r--r--tests/new-exp12.sub40
-rw-r--r--tests/new-exp13.sub72
-rw-r--r--tests/new-exp14.sub36
-rw-r--r--tests/new-exp15.sub29
-rw-r--r--tests/new-exp16.sub120
-rw-r--r--tests/new-exp2.sub62
-rw-r--r--tests/new-exp3.sub43
-rw-r--r--tests/new-exp4.sub43
-rw-r--r--tests/new-exp5.sub53
-rw-r--r--tests/new-exp6.sub42
-rw-r--r--tests/new-exp7.sub13
-rw-r--r--tests/new-exp8.sub129
-rw-r--r--tests/new-exp9.sub44
-rw-r--r--tests/nquote.right80
-rw-r--r--tests/nquote.tests142
-rw-r--r--tests/nquote1.right131
-rw-r--r--tests/nquote1.sub6
-rw-r--r--tests/nquote1.tests119
-rw-r--r--tests/nquote2.right76
-rw-r--r--tests/nquote2.sub42
-rw-r--r--tests/nquote2.tests95
-rw-r--r--tests/nquote3.right60
-rw-r--r--tests/nquote3.sub8
-rw-r--r--tests/nquote3.tests98
-rw-r--r--tests/nquote4.right18
-rw-r--r--tests/nquote4.sub6
-rw-r--r--tests/nquote4.tests37
-rw-r--r--tests/nquote5.right86
-rw-r--r--tests/nquote5.sub36
-rw-r--r--tests/nquote5.tests76
-rw-r--r--tests/parser.right16
-rw-r--r--tests/parser.tests6
-rw-r--r--tests/parser1.sub1
-rw-r--r--tests/posix2.right4
-rw-r--r--tests/posix2.tests206
-rw-r--r--tests/posix2syntax.sub66
-rw-r--r--tests/posixexp.right308
-rw-r--r--tests/posixexp.tests97
-rw-r--r--tests/posixexp1.sub51
-rw-r--r--tests/posixexp2.right40
-rw-r--r--tests/posixexp2.sub37
-rw-r--r--tests/posixexp2.tests60
-rw-r--r--tests/posixexp3.sub65
-rw-r--r--tests/posixexp4.sub44
-rw-r--r--tests/posixexp5.sub64
-rw-r--r--tests/posixexp6.sub70
-rw-r--r--tests/posixexp7.sub76
-rw-r--r--tests/posixexp8.sub11
-rw-r--r--tests/posixpat.right42
-rw-r--r--tests/posixpat.tests247
-rw-r--r--tests/posixpipe.right41
-rw-r--r--tests/posixpipe.tests56
-rw-r--r--tests/prec.right28
-rw-r--r--tests/precedence.tests90
-rw-r--r--tests/printf.right298
-rw-r--r--tests/printf.tests334
-rw-r--r--tests/printf1.sub348
-rw-r--r--tests/printf2.sub13
-rw-r--r--tests/printf3.sub75
-rw-r--r--tests/printf4.sub82
-rw-r--r--tests/procsub.right33
-rw-r--r--tests/procsub.tests121
-rw-r--r--tests/procsub1.sub5
-rw-r--r--tests/procsub2.sub36
-rw-r--r--tests/quote.right182
-rw-r--r--tests/quote.tests139
-rw-r--r--tests/quote1.sub62
-rw-r--r--tests/quote2.sub55
-rw-r--r--tests/quote3.sub31
-rw-r--r--tests/quote4.sub101
-rw-r--r--tests/quotearray.right152
-rw-r--r--tests/quotearray.tests164
-rw-r--r--tests/quotearray1.sub131
-rw-r--r--tests/quotearray2.sub107
-rw-r--r--tests/quotearray3.sub117
-rw-r--r--tests/quotearray4.sub116
-rw-r--r--tests/quotearray5.sub124
-rw-r--r--tests/read.right85
-rw-r--r--tests/read.tests117
-rw-r--r--tests/read1.sub37
-rw-r--r--tests/read2.sub72
-rw-r--r--tests/read3.sub38
-rw-r--r--tests/read4.sub4
-rw-r--r--tests/read5.sub48
-rw-r--r--tests/read6.sub10
-rw-r--r--tests/read7.sub66
-rw-r--r--tests/read8.sub15
-rw-r--r--tests/redir.right163
-rw-r--r--tests/redir.tests209
-rw-r--r--tests/redir1.sub8
-rw-r--r--tests/redir10.sub37
-rw-r--r--tests/redir11.sub76
-rw-r--r--tests/redir2.sub1
-rw-r--r--tests/redir3.in12
-rw-r--r--tests/redir3.in22
-rw-r--r--tests/redir3.sub39
-rw-r--r--tests/redir4.in11
-rw-r--r--tests/redir4.sub69
-rw-r--r--tests/redir5.sub44
-rw-r--r--tests/redir6.sub10
-rw-r--r--tests/redir7.sub82
-rw-r--r--tests/redir8.sub74
-rw-r--r--tests/redir9.sub63
-rw-r--r--tests/rhs-exp.right105
-rw-r--r--tests/rhs-exp.tests64
-rw-r--r--tests/rhs-exp1.sub116
-rw-r--r--tests/rsh.right19
-rw-r--r--tests/rsh.tests49
-rw-r--r--tests/rsh1.sub29
-rw-r--r--tests/rsh2.sub30
-rw-r--r--tests/run-alias2
-rw-r--r--tests/run-all64
-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-attr2
-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-complete2
-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-coproc2
-rw-r--r--tests/run-cprint2
-rw-r--r--tests/run-dbg-support9
-rw-r--r--tests/run-dbg-support29
-rw-r--r--tests/run-dirstack5
-rw-r--r--tests/run-dollars2
-rw-r--r--tests/run-dynvar2
-rw-r--r--tests/run-errors3
-rw-r--r--tests/run-execscript26
-rw-r--r--tests/run-exp-tests2
-rw-r--r--tests/run-exportfunc2
-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-test7
-rw-r--r--tests/run-globstar4
-rw-r--r--tests/run-heredoc6
-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-intl5
-rw-r--r--tests/run-invert2
-rw-r--r--tests/run-iquote2
-rw-r--r--tests/run-jobs7
-rw-r--r--tests/run-lastpipe2
-rw-r--r--tests/run-mapfile2
-rw-r--r--tests/run-minimal68
-rw-r--r--tests/run-more-exp2
-rw-r--r--tests/run-nameref4
-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-nquote48
-rw-r--r--tests/run-nquote52
-rw-r--r--tests/run-parser2
-rw-r--r--tests/run-posix22
-rw-r--r--tests/run-posixexp2
-rw-r--r--tests/run-posixexp22
-rw-r--r--tests/run-posixpat2
-rw-r--r--tests/run-posixpipe2
-rw-r--r--tests/run-precedence2
-rw-r--r--tests/run-printf7
-rw-r--r--tests/run-procsub7
-rw-r--r--tests/run-quote2
-rw-r--r--tests/run-quotearray2
-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
-rw-r--r--tests/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-varenv4
-rw-r--r--tests/run-vredir4
-rw-r--r--tests/set-e.right72
-rw-r--r--tests/set-e.tests124
-rw-r--r--tests/set-e1.sub72
-rw-r--r--tests/set-e2.sub10
-rw-r--r--tests/set-e3.sub10
-rw-r--r--tests/set-e3a.sub7
-rw-r--r--tests/set-x.right60
-rw-r--r--tests/set-x.tests38
-rw-r--r--tests/set-x1.sub38
-rw-r--r--tests/shopt.right312
-rw-r--r--tests/shopt.tests113
-rw-r--r--tests/shopt1.sub52
-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.sub32
-rw-r--r--tests/source6.sub49
-rw-r--r--tests/source7.sub53
-rw-r--r--tests/strip.right12
-rw-r--r--tests/strip.tests35
-rw-r--r--tests/test-glue-functions13
-rw-r--r--tests/test.right297
-rw-r--r--tests/test.tests456
-rw-r--r--tests/test1.sub34
-rw-r--r--tests/tilde.right28
-rw-r--r--tests/tilde.tests94
-rw-r--r--tests/tilde2.right28
-rw-r--r--tests/tilde2.tests85
-rw-r--r--tests/tilde3.sub26
-rw-r--r--tests/trap.right115
-rw-r--r--tests/trap.tests114
-rwxr-xr-xtests/trap1.sub4
-rwxr-xr-xtests/trap2.sub62
-rwxr-xr-xtests/trap2a.sub3
-rw-r--r--tests/trap3.sub9
-rw-r--r--tests/trap4.sub55
-rw-r--r--tests/trap5.sub31
-rw-r--r--tests/trap6.sub28
-rw-r--r--tests/type.right135
-rw-r--r--tests/type.tests110
-rw-r--r--tests/type1.sub10
-rw-r--r--tests/type2.sub29
-rw-r--r--tests/type3.sub34
-rw-r--r--tests/type4.sub56
-rw-r--r--tests/unicode1.sub608
-rw-r--r--tests/unicode2.sub37
-rw-r--r--tests/unicode3.sub12
-rw-r--r--tests/varenv.right277
-rw-r--r--tests/varenv.tests265
-rw-r--r--tests/varenv1.sub41
-rw-r--r--tests/varenv10.sub59
-rw-r--r--tests/varenv11.sub43
-rw-r--r--tests/varenv12.sub171
-rw-r--r--tests/varenv13.sub37
-rw-r--r--tests/varenv14.sub46
-rw-r--r--tests/varenv15.in3
-rw-r--r--tests/varenv15.sub51
-rw-r--r--tests/varenv16.sub51
-rw-r--r--tests/varenv17.sub44
-rw-r--r--tests/varenv18.sub41
-rw-r--r--tests/varenv19.sub51
-rw-r--r--tests/varenv2.sub57
-rw-r--r--tests/varenv20.sub13
-rw-r--r--tests/varenv21.sub48
-rw-r--r--tests/varenv22.sub17
-rw-r--r--tests/varenv3.sub44
-rw-r--r--tests/varenv4.sub71
-rw-r--r--tests/varenv5.sub29
-rw-r--r--tests/varenv6.sub41
-rw-r--r--tests/varenv7.sub75
-rw-r--r--tests/varenv8.sub14
-rw-r--r--tests/varenv9.sub79
-rw-r--r--tests/version13
-rw-r--r--tests/version.mini13
-rw-r--r--tests/vredir.right101
-rw-r--r--tests/vredir.tests62
-rw-r--r--tests/vredir1.sub30
-rw-r--r--tests/vredir2.sub65
-rw-r--r--tests/vredir3.sub8
-rw-r--r--tests/vredir4.sub35
-rw-r--r--tests/vredir5.sub36
-rw-r--r--tests/vredir6.sub14
-rw-r--r--tests/vredir7.sub36
-rw-r--r--tests/vredir8.sub13
668 files changed, 45150 insertions, 0 deletions
diff --git a/tests/COPYRIGHT b/tests/COPYRIGHT
new file mode 100644
index 0000000..43b39df
--- /dev/null
+++ b/tests/COPYRIGHT
@@ -0,0 +1,9 @@
+Unless otherwise stated, all files in this directory are Copyright (C)
+1991,1992,1993,1994,1995,1996,1997,1998,1999,2000,2001,2002,2003,
+2004,2005,2006,2007,2008,2009,2010,2011
+Free Software Foundation, Inc.
+
+See the file COPYING in the bash distribution root directory for copying
+and usage restrictions.
+
+The file ifs-posix.tests is Copyright (C) 2005 Glen Fowler.
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..76f3207
--- /dev/null
+++ b/tests/alias.right
@@ -0,0 +1,45 @@
+alias: 0
+alias: 0
+./alias.tests: line 38: qfoo: command not found
+quux
+hi
+bar
+value
+bar
+value
+OK
+OK
+OK
+OK
+one
+two
+three
+four
+one
+two
+three
+four
+Error: bar
+ok 1
+ok 2
+text
+whoops: nullalias
+foo
+a
+a b
+a b
+a a b
+ok 3
+ok 4
+bar
+bad
+0
+<|cat>
+foo
+bar
+baz
+foo
+bar
+baz
+<áa>
+<aá>
diff --git a/tests/alias.tests b/tests/alias.tests
new file mode 100644
index 0000000..15eac5b
--- /dev/null
+++ b/tests/alias.tests
@@ -0,0 +1,65 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# place holder for future alias testing
+shopt -s expand_aliases
+
+# alias/unalias tests originally in builtins.tests
+
+unalias -a
+# this should return success, according to POSIX.2
+alias
+echo alias: $?
+alias foo=bar
+unalias foo
+# this had better return success, according to POSIX.2
+alias
+echo alias: $?
+
+# bug in all versions through bash-2.05b
+
+unalias qfoo qbar qbaz quux 2>/dev/null
+
+alias qfoo=qbar
+alias qbar=qbaz
+alias qbaz=quux
+alias quux=qfoo
+
+qfoo
+
+unalias qfoo qbar qbaz quux
+
+unalias -a
+
+alias foo='echo '
+alias bar=baz
+alias baz=quux
+
+foo bar
+
+unalias foo bar baz
+
+# post bash-5.1 problems with compound array assignment during multiline
+# alias expansion
+alias foo='a=() b=""
+for i in 1; do echo hi; done'
+foo
+
+unalias foo
+
+${THIS_SH} ./alias1.sub
+${THIS_SH} ./alias2.sub
+${THIS_SH} ./alias3.sub
+${THIS_SH} ./alias4.sub
+${THIS_SH} ./alias5.sub
+${THIS_SH} ./alias6.sub
diff --git a/tests/alias1.sub b/tests/alias1.sub
new file mode 100644
index 0000000..9a90b2e
--- /dev/null
+++ b/tests/alias1.sub
@@ -0,0 +1,33 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+shopt -s expand_aliases
+
+alias foo=echo
+
+< /dev/null foo bar
+
+< /dev/null x=value
+echo $x
+
+< /dev/null x=newvalue foo bar
+echo $x
+
+# problem reported by Vincent Lefevre
+alias a="echo OK >&2"
+a
+> /dev/null a
+
+${THIS_SH} -c 'shopt -s expand_aliases; alias a="echo OK >&2"
+ a
+ > /dev/null a'
diff --git a/tests/alias2.sub b/tests/alias2.sub
new file mode 100644
index 0000000..e35fb76
--- /dev/null
+++ b/tests/alias2.sub
@@ -0,0 +1,35 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+THIS=alias2
+FN=$TMPDIR/$THIS.script
+
+cat > $FN <<'EOF'
+#
+(echo "$1")
+EOF
+chmod u+x $FN
+
+shopt -s expand_aliases
+
+alias foo1='$FN one; source $FN two; source $FN three; $FN four'
+
+alias foo2='$FN one
+source $FN two
+source $FN three
+$FN four'
+
+foo1
+foo2
+
+rm -f $FN
diff --git a/tests/alias3.sub b/tests/alias3.sub
new file mode 100644
index 0000000..304e926
--- /dev/null
+++ b/tests/alias3.sub
@@ -0,0 +1,11 @@
+shopt -s expand_aliases
+alias foo='oneword'
+foo_word='foo'
+#
+# Fails silently to match 'foo':
+#
+case "$foo_word"
+in
+ foo) ;;
+ *) echo bad 1;;
+esac
diff --git a/tests/alias4.sub b/tests/alias4.sub
new file mode 100644
index 0000000..0864a3c
--- /dev/null
+++ b/tests/alias4.sub
@@ -0,0 +1,100 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+shopt -s expand_aliases
+
+# from an austin-group report
+alias foo="echo 'Error:"
+foo bar'
+
+# from some FreeBSD sh tests
+
+v=1
+alias a='unalias -a
+v=2'
+eval a
+[ "$v" = 2 ] && echo ok 1
+v=1
+alias a='unalias a
+v=2'
+eval a
+[ "$v" = 2 ] && echo ok 2
+
+# make sure command doesn't ever reset anything even if it's made a keyword
+unalias -a
+alias command=command
+alias true='echo bad'
+eval 'command true'
+
+unalias -a
+alias alias0=command
+alias true='echo bad'
+eval 'alias0 true'
+
+# make sure null aliases are ok
+unalias -a
+alias nullalias=''
+alias foo='echo '
+foo nullalias text
+unalias foo
+
+# aliases shouldn't be expanded in quoted strings even when the previous word
+# is an alias whose expansion ends in a space
+alias foo="echo 'whoops: "
+foo nullalias'
+
+unalias -a
+
+# recursive alias definitions
+alias echo=echo
+eval echo foo
+
+alias echo='echo a'
+
+echo
+echo b
+eval echo b
+echo $(eval echo b)
+
+unalias -a
+
+# alias expansion when in a command position after redirections
+alias e=echo
+eval '</dev/null e ok 3'
+eval 'a=true e ok 4'
+
+alias comment=#
+comment
+
+alias long_comment='# for x in '
+long_comment text after
+
+# comment
+comment foo bar
+
+# alias ending in a tab
+alias foo="\
+ echo \"bar\" \
+ "
+
+foo
+
+alias foo=$'echo bad \t'
+foo
+
+# this should probably just echo a blank line to stdout
+alias foo='echo 0'
+foo>&2
+
+alias a='printf "<%s>\n" \'
+a|cat
diff --git a/tests/alias5.sub b/tests/alias5.sub
new file mode 100644
index 0000000..7f8e86d
--- /dev/null
+++ b/tests/alias5.sub
@@ -0,0 +1,28 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# -c commands ending with multi-line aliases; post-bash-5.0
+
+: ${THIS_SH:=./bash}
+
+${THIS_SH} -c "shopt -s expand_aliases &>/dev/null;
+alias myalias='/bin/echo foo
+echo bar
+echo baz'
+myalias"
+
+${THIS_SH} -c "shopt -s expand_aliases &>/dev/null;
+alias myalias='echo foo
+echo bar
+echo baz'
+myalias"
diff --git a/tests/alias6.sub b/tests/alias6.sub
new file mode 100644
index 0000000..d2d7daf
--- /dev/null
+++ b/tests/alias6.sub
@@ -0,0 +1,13 @@
+# make sure aliases that end in multibyte characters don't interfere with the
+# space sentinel alias expansion adds; problem through bash-5.1
+shopt -s expand_aliases
+
+LC_ALL=en_US.UTF-8
+
+alias a1='printf "<%s>\\n" áa'
+a1
+
+alias a2='printf "<%s>\\n" aá'
+a2
+
+unalias a1 a2
diff --git a/tests/appendop.right b/tests/appendop.right
new file mode 100644
index 0000000..f72696b
--- /dev/null
+++ b/tests/appendop.right
@@ -0,0 +1,28 @@
+14
+1 2 3 4 5 6
+1 2 3 4 51 6
+145
+14
+7
+42
+1 2 3 4 12
+18
+1 2 3 4 18
+1 2 7 4 5
+1 2 7 13 5 9
+14
+9
+4
+9
+16
+./appendop.tests: line 97: x: readonly variable
+declare -A foo=([two]="baz" [three]="quux" [one]="bar" )
+declare -A foo=([0]="zero" [two]="baz" [three]="quux" [one]="bar" )
+declare -A foo=([four]="four" [0]="zero" [two]="baz" [three]="quux" [one]="bar" )
+declare -ai iarr=([0]="3" [1]="2" [2]="3")
+declare -ai iarr=([0]="3" [1]="2" [2]="3" [3]="4" [4]="5" [5]="6")
+25 25
+7 7
+14
+145
+145 145
diff --git a/tests/appendop.tests b/tests/appendop.tests
new file mode 100644
index 0000000..61b38fc
--- /dev/null
+++ b/tests/appendop.tests
@@ -0,0 +1,100 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# basic cases
+a=1
+a+=4
+echo $a
+
+x=(1 2 3)
+x+=(4 5 6)
+
+echo ${x[@]}
+
+x[4]+=1
+echo ${x[@]}
+
+# trickier cases
+# post-bash-4.2: bash understands += in environment assignments preceding
+# command names
+a+=5 printenv a
+echo $a
+
+# if the integer flag is set, ksh93 appears to do arithmetic += and evaluate
+# old value as an arithmetic expression
+a=
+typeset -i a
+a+=7
+echo $a
+
+b=4+1
+typeset -i b
+b+=37
+
+echo $b
+
+unset x
+x=(1 2 3 4 5)
+
+typeset -i x
+
+x[4]+=7
+
+echo ${x[@]}
+
+unset x
+typeset -i x
+
+x=([0]=7+11)
+echo ${x[@]}
+
+unset x
+x=(1 2 3 4 5)
+
+typeset -i x
+
+#x[4]=7+11
+
+x=(1 2 3 4 [4]=7+11 )
+echo ${x[@]}
+
+x=( 1 2 [2]+=7 4 5 )
+echo ${x[@]}
+
+x+=( [3]+=9 [5]=9 )
+echo ${x[@]}
+
+unset a
+a=1
+export a+=4
+printenv a
+printenv a+
+
+unset x
+typeset -i x=4+5
+echo $x
+
+unset x
+typeset x+=4
+echo $x
+
+typeset -i x+=5
+echo $x
+
+readonly x+=7
+echo $x
+
+x+=5
+
+${THIS_SH} ./appendop1.sub
+${THIS_SH} ./appendop2.sub
diff --git a/tests/appendop1.sub b/tests/appendop1.sub
new file mode 100644
index 0000000..60e7014
--- /dev/null
+++ b/tests/appendop1.sub
@@ -0,0 +1,28 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+typeset -A foo=([one]=bar [two]=baz [three]=quux)
+typeset -p foo
+
+foo+=zero
+typeset -p foo
+
+foo+=([four]=four)
+typeset -p foo
+
+typeset -ia iarr=(2 2 3)
+iarr+=1
+typeset -p iarr
+
+iarr+=(4 5 6)
+typeset -p iarr
diff --git a/tests/appendop2.sub b/tests/appendop2.sub
new file mode 100644
index 0000000..e497beb
--- /dev/null
+++ b/tests/appendop2.sub
@@ -0,0 +1,31 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+POSIXLY_CORRECT=1
+x=2
+x+=5 eval printf '"$x "'
+echo "$x"
+
+unset x
+typeset -i x=2
+x+=5 eval printf '"$x "'
+echo "$x"
+
+a=1
+a+=4
+echo $a
+
+# idiotically, ksh93 makes these two cases differ (?)
+a+=5 printenv a
+a+=5 eval printf '"$a "'
+echo $a
diff --git a/tests/arith-for.right b/tests/arith-for.right
new file mode 100644
index 0000000..06127be
--- /dev/null
+++ b/tests/arith-for.right
@@ -0,0 +1,86 @@
+0
+1
+2
+0
+1
+2
+0
+1
+2
+0
+2
+4
+fx is a function
+fx ()
+{
+ i=0;
+ for ((1; i < 3; i++ ))
+ do
+ echo $i;
+ done;
+ for ((i=0; 1; i++ ))
+ do
+ if (( i >= 3 )); then
+ break;
+ fi;
+ echo $i;
+ done;
+ for ((i=0; i<3; 1))
+ do
+ echo $i;
+ (( i++ ));
+ done;
+ i=0;
+ for ((1; 1; 1))
+ do
+ if (( i > 2 )); then
+ break;
+ fi;
+ echo $i;
+ (( i++ ));
+ done;
+ i=0;
+ for ((1; 1; 1))
+ do
+ if (( i > 2 )); then
+ break;
+ fi;
+ echo $i;
+ (( i++ ));
+ done
+}
+0
+1
+2
+0
+1
+2
+0
+1
+2
+0
+1
+2
+0
+1
+2
+bash: -c: line 1: syntax error: arithmetic expression required
+bash: -c: line 1: syntax error: `(( i=0; "i < 3" ))'
+2
+bash: -c: line 1: syntax error: `;' unexpected
+bash: -c: line 1: syntax error: `(( i=0; i < 3; i++; 7 ))'
+2
+20
+20
+12345678 987654321 012345678 987654321 012345678 987654321 012345678 987654321 012345678 987654321 012345678
+12345678 987654321 012345678 987654321 012345678 987654321 012345678 987654321 012345678 987654321 012345678
+4
+3
+2
+1
+0
+4
+3
+2
+1
+0
diff --git a/tests/arith-for.tests b/tests/arith-for.tests
new file mode 100644
index 0000000..db913da
--- /dev/null
+++ b/tests/arith-for.tests
@@ -0,0 +1,128 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+fx()
+{
+i=0
+for (( ; i < 3; i++ ))
+do
+ echo $i
+done
+
+for (( i=0; ; i++ ))
+do
+ if (( i >= 3 )); then
+ break;
+ fi
+ echo $i
+done
+
+for (( i=0; i<3; ))
+do
+ echo $i
+ (( i++ ))
+done
+
+i=0
+for (( ; ; ))
+do
+ if (( i > 2 )); then
+ break;
+ fi
+ echo $i;
+ (( i++ ))
+done
+
+i=0
+for ((;;))
+do
+ if (( i > 2 )); then
+ break;
+ fi
+ echo $i;
+ (( i++ ))
+done
+}
+
+for (( i=0; "i < 3" ; i++ ))
+do
+ echo $i
+done
+
+i=0
+for (( ; "i < 3"; i++ ))
+do
+ echo $i
+done
+
+for (( i=0; ; i++ ))
+do
+ if (( i >= 3 )); then
+ break;
+ fi
+ echo $i
+done
+
+for ((i = 0; ;i++ ))
+do
+ echo $i
+ if (( i < 3 )); then
+ (( i++ ))
+ continue;
+ fi
+ break
+done
+
+type fx
+fx
+
+# errors
+{
+${THIS_SH} -c 'for (( i=0; "i < 3" ))
+do
+ echo $i
+done' ; echo $? ; } 2>&1 | sed 's|^.*/||'
+#echo $?
+
+{
+${THIS_SH} -c 'for (( i=0; i < 3; i++; 7 ))
+do
+ echo $i
+done' ; echo $?; } 2>&1 | sed 's|^.*/||'
+#echo $?
+
+# one-liners added in post-bash-2.04
+for ((i=0; i < 20; i++)) do : ; done
+echo $i
+
+for ((i=0; i < 20; i++)) { : ; }
+echo $i
+
+# added post-bash-4.2
+for (( i = j = k = 1; i % 9 || (j *= -1, $( ((i%9)) || printf " " >&2; echo 0), k++ <= 10); i += j ))
+do
+printf "$i"
+done
+
+echo
+
+( for (( i = j = k = 1; i % 9 || (j *= -1, $( ((i%9)) || printf " " >&2; echo 0), k++ <= 10); i += j ))
+do
+printf "$i"
+done )
+
+echo
+
+for (( i = 4; ;i--)) ; do echo $i; if (( $i == 0 )); then break; fi; done
+
+for (( i = 4;;i--)) ; do echo $i; if (( $i == 0 )); then break; fi; done
diff --git a/tests/arith.right b/tests/arith.right
new file mode 100644
index 0000000..0268781
--- /dev/null
+++ b/tests/arith.right
@@ -0,0 +1,263 @@
+163
+166
+4
+16
+8
+2
+4
+2
+2
+1
+0
+0
+0
+1
+1
+2
+-3
+-2
+1
+0
+2
+131072
+29
+33
+49
+1
+1
+0
+0
+1
+1
+1
+2
+3
+1
+58
+2
+60
+1
+256
+16
+62
+4
+29
+5
+-4
+4
+1
+32
+32
+1
+1
+32
+4
+20
+1,i+=2
+30
+1,j+=2
+20
+1,i+=2
+30
+1,j+=2
+./arith.tests: line 127: 1 ? 20 : x+=2: attempted assignment to non-variable (error token is "+=2")
+20
+6
+6,5,3
+263
+255
+255
+127
+36
+40
+10
+10
+10
+10
+10
+10
+36
+36
+62
+63
+./arith.tests: line 162: 3425#56: invalid arithmetic base (error token is "3425#56")
+./arith.tests: line 165: 2#: invalid integer constant (error token is "2#")
+./arith.tests: line 168: 7 = 43 : attempted assignment to non-variable (error token is "= 43 ")
+./arith.tests: line 169: 2#44: value too great for base (error token is "2#44")
+./arith.tests: line 170: 44 / 0 : division by 0 (error token is "0 ")
+./arith.tests: line 171: let: jv += $iv: syntax error: operand expected (error token is "$iv")
+./arith.tests: line 172: jv += $iv : syntax error: operand expected (error token is "$iv ")
+./arith.tests: line 173: let: rv = 7 + (43 * 6: missing `)' (error token is "6")
+./arith.tests: line 177: 0#4: invalid number (error token is "0#4")
+./arith.tests: line 178: 2#110#11: invalid number (error token is "2#110#11")
+abc
+def
+ghi
+ok
+6
+1
+0
+./arith.tests: line 196: 4 + : syntax error: operand expected (error token is "+ ")
+16
+./arith.tests: line 201: 4 ? : 3 + 5 : expression expected (error token is ": 3 + 5 ")
+./arith.tests: line 202: 1 ? 20 : `:' expected for conditional expression (error token is "20 ")
+./arith.tests: line 203: 4 ? 20 : : expression expected (error token is ": ")
+9
+./arith.tests: line 209: 0 && B=42 : attempted assignment to non-variable (error token is "=42 ")
+9
+./arith.tests: line 212: 1 || B=88 : attempted assignment to non-variable (error token is "=88 ")
+9
+0
+9
+0
+9
+1
+9
+7
+7
+4
+32767
+32768
+131072
+2147483647
+1
+4
+4
+5
+5
+4
+3
+3
+4
+4
+7
+./arith.tests: line 260: 7-- : syntax error: operand expected (error token is "- ")
+./arith.tests: line 262: --x=7 : attempted assignment to non-variable (error token is "=7 ")
+./arith.tests: line 263: ++x=7 : attempted assignment to non-variable (error token is "=7 ")
+./arith.tests: line 265: x++=7 : attempted assignment to non-variable (error token is "=7 ")
+./arith.tests: line 266: x--=7 : attempted assignment to non-variable (error token is "=7 ")
+4
+7
+-7
+7
+7
+2
+2
+./arith1.sub: line 15: 4-- : syntax error: operand expected (error token is "- ")
+./arith1.sub: line 16: 4++ : syntax error: operand expected (error token is "+ ")
+./arith1.sub: line 17: 4 -- : syntax error: operand expected (error token is "- ")
+./arith1.sub: line 18: 4 ++ : syntax error: operand expected (error token is "+ ")
+1
+2
+1
+2
+6
+3
+7
+4
+0
+3
+7
+2
+-2
+1
+./arith1.sub: line 48: ((: ++ : syntax error: operand expected (error token is "+ ")
+7
+7
+./arith1.sub: line 51: ((: -- : syntax error: operand expected (error token is "- ")
+7
+7
+7
+7
+1
+2
+1
+2
+1
+0
+5
+1
+6
+2
+3
+1
+4
+0
+./arith2.sub: line 46: ((: -- : syntax error: operand expected (error token is "- ")
+-7
+-7
+./arith2.sub: line 50: ((: ++ : syntax error: operand expected (error token is "+ ")
+7
+7
+-7
+-7
+7
+7
+1
+1
+4
+5
+-3
+2
+4
+5000
+5000
+1
+0
+0
+1
+2147483649
+0
+0
+0
+0
+0
+0
+-9223372036854775808
+-9223372036854775808
+-9223372036854775808
+-9223372036854775808
+-9223372036854775808
+-9223372036854775808
+-9223372036854775808
+-9223372036854775808
+-9223372036854775808
+-9223372036854775808
+9223372036854775805 9223372036854775806 9223372036854775807
+123 456
+123 456
+123 456
+123 456
+123 456
+123 456
+1
+1 2 3 4 5 6 7
+0 1 2 3 4 5 6 7
+0
+0, 0
+0, 1
+efg
+e
+efg
+e
+abcdefg
+efg
+0
+0
+0
+0
+0
+0
+0
+8 12
+./arith.tests: line 310: ((: x=9 y=41 : syntax error in expression (error token is "y=41 ")
+./arith.tests: line 314: a b: syntax error in expression (error token is "b")
+./arith.tests: line 315: ((: a b: syntax error in expression (error token is "b")
+42
+42
+42
+42
+42
+42
+./arith.tests: line 330: 'foo' : syntax error: operand expected (error token is "'foo' ")
+./arith.tests: line 333: b[c]d: syntax error in expression (error token is "d")
diff --git a/tests/arith.tests b/tests/arith.tests
new file mode 100644
index 0000000..e9ab576
--- /dev/null
+++ b/tests/arith.tests
@@ -0,0 +1,333 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+set +o posix
+declare -i iv jv
+
+iv=$(( 3 + 5 * 32 ))
+echo $iv
+iv=iv+3
+echo $iv
+iv=2
+jv=iv
+
+let "jv *= 2"
+echo $jv
+jv=$(( $jv << 2 ))
+echo $jv
+
+let jv="$jv / 2"
+echo $jv
+jv="jv >> 2"
+echo $jv
+
+iv=$((iv+ $jv))
+echo $iv
+echo $((iv -= jv))
+echo $iv
+echo $(( iv == jv ))
+echo $(( iv != $jv ))
+echo $(( iv < jv ))
+echo $(( $iv > $jv ))
+echo $(( iv <= $jv ))
+echo $(( $iv >= jv ))
+
+echo $jv
+echo $(( ~$jv ))
+echo $(( ~1 ))
+echo $(( ! 0 ))
+
+echo $(( jv % 2 ))
+echo $(( $iv % 4 ))
+
+echo $(( iv <<= 16 ))
+echo $(( iv %= 33 ))
+
+echo $(( 33 & 55 ))
+echo $(( 33 | 17 ))
+
+echo $(( iv && $jv ))
+echo $(( $iv || jv ))
+
+echo $(( iv && 0 ))
+echo $(( iv & 0 ))
+echo $(( iv && 1 ))
+echo $(( iv & 1 ))
+
+echo $(( $jv || 0 ))
+echo $(( jv | 0 ))
+echo $(( jv | 1 ))
+echo $(( $jv || 1 ))
+
+let 'iv *= jv'
+echo $iv
+echo $jv
+let "jv += $iv"
+echo $jv
+
+echo $(( jv /= iv ))
+echo $(( jv <<= 8 ))
+echo $(( jv >>= 4 ))
+
+echo $(( iv |= 4 ))
+echo $(( iv &= 4 ))
+
+echo $(( iv += (jv + 9)))
+echo $(( (iv + 4) % 7 ))
+
+# unary plus, minus
+echo $(( +4 - 8 ))
+echo $(( -4 + 8 ))
+
+# conditional expressions
+echo $(( 4<5 ? 1 : 32))
+echo $(( 4>5 ? 1 : 32))
+echo $(( 4>(2+3) ? 1 : 32))
+echo $(( 4<(2+3) ? 1 : 32))
+echo $(( (2+2)<(2+3) ? 1 : 32))
+echo $(( (2+2)>(2+3) ? 1 : 32))
+
+# bug in bash versions through bash-3.2
+S=105
+W=$((S>99?4:S>9?3:S>0?2:0))
+echo $W
+unset W S
+
+# check that the unevaluated part of the ternary operator does not do
+# evaluation or assignment
+x=i+=2
+y=j+=2
+declare -i i=1 j=1
+echo $((1 ? 20 : (x+=2)))
+echo $i,$x
+echo $((0 ? (y+=2) : 30))
+echo $j,$y
+
+x=i+=2
+y=j+=2
+declare -i i=1 j=1
+echo $((1 ? 20 : (x+=2)))
+echo $i,$x
+echo $((0 ? (y+=2) : 30))
+echo $i,$y
+
+# check precedence of assignment vs. conditional operator
+# should be an error
+declare -i x=2
+y=$((1 ? 20 : x+=2))
+
+# check precedence of assignment vs. conditional operator
+declare -i x=2
+echo $((0 ? x+=2 : 20))
+
+# associativity of assignment-operator operator
+declare -i i=1 j=2 k=3
+echo $((i += j += k))
+echo $i,$j,$k
+
+# octal, hex
+echo $(( 0x100 | 007 ))
+echo $(( 0xff ))
+echo $(( 16#ff ))
+echo $(( 16#FF/2 ))
+echo $(( 8#44 ))
+
+echo $(( 8 ^ 32 ))
+
+# other bases
+echo $(( 16#a ))
+echo $(( 32#a ))
+echo $(( 56#a ))
+echo $(( 64#a ))
+
+echo $(( 16#A ))
+echo $(( 32#A ))
+echo $(( 56#A ))
+echo $(( 64#A ))
+
+echo $(( 64#@ ))
+echo $(( 64#_ ))
+
+# weird bases
+echo $(( 3425#56 ))
+
+# missing number after base now generates an error
+echo $(( 2# ))
+
+# these should generate errors
+echo $(( 7 = 43 ))
+echo $(( 2#44 ))
+echo $(( 44 / 0 ))
+let 'jv += $iv'
+echo $(( jv += \$iv ))
+let 'rv = 7 + (43 * 6'
+
+# more errors
+declare -i i
+i=0#4
+i=2#110#11
+
+((echo abc; echo def;); echo ghi)
+
+if (((4+4) + (4 + 7))); then
+ echo ok
+fi
+
+(()) # make sure the null expression works OK
+
+a=(0 2 4 6)
+echo $(( a[1] + a[2] ))
+echo $(( (a[1] + a[2]) == a[3] ))
+(( (a[1] + a[2]) == a[3] )) ; echo $?
+
+# test pushing and popping the expression stack
+unset A
+A="4 + "
+echo $(( ( 4 + A ) + 4 ))
+A="3 + 5"
+echo $(( ( 4 + A ) + 4 ))
+
+# badly-formed conditional expressions
+echo $(( 4 ? : $A ))
+echo $(( 1 ? 20 ))
+echo $(( 4 ? 20 : ))
+
+# precedence and short-circuit evaluation
+B=9
+echo $B
+
+echo $(( 0 && B=42 ))
+echo $B
+
+echo $(( 1 || B=88 ))
+echo $B
+
+echo $(( 0 && (B=42) ))
+echo $B
+
+echo $(( (${$} - $$) && (B=42) ))
+echo $B
+
+echo $(( 1 || (B=88) ))
+echo $B
+
+# until command with (( )) command
+x=7
+
+echo $x
+until (( x == 4 ))
+do
+ echo $x
+ x=4
+done
+
+echo $x
+
+# exponentiation
+echo $(( 2**15 - 1))
+echo $(( 2**(16-1)))
+echo $(( 2**16*2 ))
+echo $(( 2**31-1))
+echo $(( 2**0 ))
+
+# {pre,post}-{inc,dec}rement and associated errors
+
+x=4
+
+echo $x
+echo $(( x++ ))
+echo $x
+echo $(( x-- ))
+echo $x
+
+echo $(( --x ))
+echo $x
+
+echo $(( ++x ))
+echo $x
+
+echo $(( ++7 ))
+echo $(( 7-- ))
+
+echo $(( --x=7 ))
+echo $(( ++x=7 ))
+
+echo $(( x++=7 ))
+echo $(( x--=7 ))
+
+echo $x
+
+echo $(( +7 ))
+echo $(( -7 ))
+
+echo $(( ++7 ))
+echo $(( --7 ))
+
+# combinations of expansions
+echo $(( "`echo 1+1`" ))
+echo $(( `echo 1+1` ))
+
+${THIS_SH} ./arith1.sub
+${THIS_SH} ./arith2.sub
+${THIS_SH} ./arith3.sub
+${THIS_SH} ./arith4.sub
+
+# make sure arithmetic expansion handles ints > 2**31 - 1 using intmax_t
+echo $(( 2147483645 + 4 ))
+
+# other tests using INTMAX_MIN and INTMAX_MAX that cause exceptions if not
+# handled correctly -- problem through bash-4.2
+${THIS_SH} ./arith5.sub
+
+# problems with suppressing evaluation present through bash-4.2
+${THIS_SH} ./arith6.sub
+
+# problems with parsing arithmetic expressions containing colons that are
+# part of word expansions such as substring extraction
+${THIS_SH} ./arith7.sub
+
+# problems with evaluation of conditional expressions
+${THIS_SH} ./arith8.sub
+
+x=4
+y=7
+
+(( x=8 , y=12 ))
+
+echo $x $y
+
+# should be an error
+(( x=9 y=41 ))
+
+# These are errors
+unset b
+echo $((a b))
+((a b))
+
+n=42
+printf "%d\n" $n
+printf "%i\n" $n
+echo $(( 8#$(printf "%o\n" $n) ))
+printf "%u\n" $n
+echo $(( 16#$(printf "%x\n" $n) ))
+echo $(( 16#$(printf "%X\n" $n) ))
+
+# allow reserved words after an arithmetic command just because
+if ((expr)) then ((expr)) fi
+
+# these are errors
+foo=1
+echo $(( 'foo' ))
+
+# causes longjmp botches through bash-2.05b
+a[b[c]d]=e
diff --git a/tests/arith1.sub b/tests/arith1.sub
new file mode 100644
index 0000000..3168fcb
--- /dev/null
+++ b/tests/arith1.sub
@@ -0,0 +1,51 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test of redone post-increment and post-decrement code
+echo $(( 4-- ))
+echo $(( 4++ ))
+echo $(( 4 -- ))
+echo $(( 4 ++ ))
+
+(( array[0]++ ))
+echo ${array}
+
+(( array[0] ++ ))
+echo ${array}
+
+(( a++ ))
+echo $a
+(( a ++ ))
+echo $a
+
+echo $(( a ++ + 4 ))
+echo $a
+
+echo $(( a+++4 ))
+echo $a
+
+echo $(( a---4 ))
+echo $a
+
+echo $(( a -- + 4 ))
+echo $a
+
+echo $(( a -- - 4 ))
+echo $a
+
+(( ++ + 7 ))
+
+(( ++ ))
+echo $(( +++7 ))
+echo $(( ++ + 7 ))
+(( -- ))
diff --git a/tests/arith2.sub b/tests/arith2.sub
new file mode 100644
index 0000000..5475012
--- /dev/null
+++ b/tests/arith2.sub
@@ -0,0 +1,58 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+echo $(( --7 ))
+echo $(( ++7 ))
+echo $(( -- 7 ))
+echo $(( ++ 7 ))
+
+((++array[0] ))
+echo $array
+(( ++ array[0] ))
+echo $array
+
+(( ++a ))
+echo $a
+(( ++ a ))
+echo $a
+
+(( --a ))
+echo $a
+(( -- a ))
+echo $a
+
+echo $(( 4 + ++a ))
+echo $a
+
+echo $(( 4+++a ))
+echo $a
+
+echo $(( 4---a ))
+echo $a
+
+echo $(( 4 - -- a ))
+echo $a
+
+(( -- ))
+echo $(( ---7 ))
+echo $(( -- - 7 ))
+
+(( ++ ))
+echo $(( ++7 ))
+echo $(( ++ + 7 ))
+
+echo $(( ++-7 ))
+echo $(( ++ - 7 ))
+
+echo $(( +--7 ))
+echo $(( -- + 7 ))
diff --git a/tests/arith3.sub b/tests/arith3.sub
new file mode 100644
index 0000000..b4b1825
--- /dev/null
+++ b/tests/arith3.sub
@@ -0,0 +1,60 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# this depends on the sequence of random numbers from the internal LCRNG
+RANDOM=42
+(( dice[RANDOM%6+1 + RANDOM%6+1]++ ))
+echo ${dice[6]}
+
+(( ++dice[RANDOM%6+1 + RANDOM%6+1] ))
+echo ${dice[7]}
+
+v=4
+DIND=20
+
+(( dice[DIND%6 + 1]=v ))
+echo ${dice[3]}
+(( dice[DIND/v]+=2 ))
+
+RANDOM=42
+
+(( dice[RANDOM%6+1 + RANDOM%6+1]+=v ))
+echo ${dice[6]}
+
+(( dice[RANDOM%6+1 + RANDOM%6+1]-=v ))
+echo ${dice[7]}
+
+(( dice[RANDOM%6+1 + RANDOM%6+1]+=2 ))
+echo ${dice[8]}
+
+(( dice[RANDOM%6+1 + RANDOM%6+1]*=2 ))
+echo ${dice[5]}
+
+unset dice1 dice2
+RANDOM=42
+
+for i in {1..5000}; do ((dice1[$RANDOM%6+1 + $RANDOM%6+1]++)); done;
+unset t; for i in ${dice1[@]}; do ((t+=i)); done; echo $t
+
+foo="${dice1[@]}"
+
+RANDOM=42
+
+for i in {1..5000}; do ((dice2[RANDOM%6+1 + RANDOM%6+1]++)); done;
+unset t; for i in ${dice2[@]}; do ((t+=i)); done; echo $t
+
+bar="${dice2[@]}"
+
+if [ "$foo" != "$bar" ]; then
+ echo "random sequences differ"
+fi
diff --git a/tests/arith4.sub b/tests/arith4.sub
new file mode 100644
index 0000000..d74defa
--- /dev/null
+++ b/tests/arith4.sub
@@ -0,0 +1,10 @@
+x=$(( !!1 ))
+echo $x
+
+x=$(( -!+1 ))
+echo $x
+
+x=$(( +--+!!0 ))
+echo $x
+
+echo $(( !!+-+-~0 ))
diff --git a/tests/arith5.sub b/tests/arith5.sub
new file mode 100644
index 0000000..7d5c779
--- /dev/null
+++ b/tests/arith5.sub
@@ -0,0 +1,72 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# a lot of this is technically undefined behavior due to signed 64-bit
+# integer overflow, but we're testing exception handling here
+
+intmax_max=$((2**63 - 1))
+intmax_min1=$((2**63))
+intmax_min2=$((-2**63))
+
+case $intmax_max in
+9223372036854775807) ;;
+*) echo "warning: your machine does not support 64-bit arithmetic using intmax_t" 2>&1 ;;
+esac
+
+# these are actually the same
+echo $(( $intmax_min1 % -1 ))
+echo $(( $intmax_min2 % -1 ))
+
+echo $(( $intmax_max % -1 ))
+
+lvalue=$intmax_min1
+(( lvalue%= -1 ))
+echo $lvalue
+
+lvalue=$intmax_min2
+(( lvalue%= -1 ))
+echo $lvalue
+
+lvalue=$intmax_max
+(( lvalue%= -1 ))
+echo $lvalue
+
+# and these
+echo $(( $intmax_min1 / -1 ))
+echo $(( $intmax_min2 / -1 ))
+
+lvalue=$intmax_min1
+(( lvalue /= -1 ))
+echo $lvalue
+
+lvalue=$intmax_min2
+(( lvalue /= -1 ))
+echo $lvalue
+
+echo $(( $intmax_min1 * -1 ))
+echo $(( $intmax_min2 * -1 ))
+
+lvalue=$intmax_min1
+(( lvalue *= -1 ))
+echo $lvalue
+
+lvalue=$intmax_min2
+(( lvalue *= -1 ))
+echo $lvalue
+
+echo $(( -${intmax_min1} ))
+echo $(( -${intmax_min2} ))
+
+foo1=$(( $intmax_max - 2 ))
+
+eval echo \{${foo1}..${intmax_max}\}
diff --git a/tests/arith6.sub b/tests/arith6.sub
new file mode 100644
index 0000000..dec8fd0
--- /dev/null
+++ b/tests/arith6.sub
@@ -0,0 +1,65 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+function reorder
+{
+ (( x[1] < x && (x=x[1], x[1]=$x) ))
+ echo "${x[@]}"
+}
+
+x=(123 456)
+reorder
+x=(456 123)
+reorder
+
+unset x
+unset -f reorder
+
+function reorder
+{
+ (( x[1] < x[0] && (x=x[1], x[1]=$x) ))
+ echo "${x[@]}"
+}
+
+x=(123 456)
+reorder
+x=(456 123)
+reorder
+
+unset x
+unset -f reorder
+
+function reorder
+{
+ (( x[1] < x[0] && (x[0]=x[1], x[1]=$x) ))
+ echo "${x[@]}"
+}
+
+x=(123 456)
+reorder
+x=(456 123)
+reorder
+
+unset -f reorder
+
+n=0 ; (( (a[n]=++n)<7&&a[0])); echo "${a[@]:1}"
+
+n=0 a="(a[n]=++n)<7&&a[0]"; ((a[0])); echo "${a[@]:1}"
+
+n=0 a="(a[n]=n++)<7&&a"; ((a)); echo "${a[@]:1}"
+
+# bugs with lvalue caching and pointer aliasing through bash-4.2
+echo $(( a=(y[0] + y[1]) & 0xff, b=(y[2] + y[3]) & 0xff, a << 8 | b))
+echo $a, $b
+((a = y[0], b = 1 ))
+echo $a, $b
diff --git a/tests/arith7.sub b/tests/arith7.sub
new file mode 100644
index 0000000..1b73ba7
--- /dev/null
+++ b/tests/arith7.sub
@@ -0,0 +1,11 @@
+PARAM=abcdefg
+
+echo ${PARAM:1 ? 4 : 2}
+echo ${PARAM:1 ? 4 : 2:1}
+
+echo ${PARAM: 4<5 ? 4 : 2}
+echo ${PARAM: 5>4 ? 4 : 2:1}
+
+echo ${PARAM:${OFFSET:-0}}
+OFFSET=4
+echo ${PARAM:${OFFSET:-0}}
diff --git a/tests/arith8.sub b/tests/arith8.sub
new file mode 100644
index 0000000..e6f1b0d
--- /dev/null
+++ b/tests/arith8.sub
@@ -0,0 +1,50 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# problems with evaluation of wrong terms in conditional expressions through
+# bash-4.4
+
+a=0 x="a=1"
+((0?x:0))
+echo $a
+unset a x
+
+a=0 x="a=1"
+((1?0:x))
+echo $a
+unset a x
+
+a=0 x="a=1"
+((0?(x):0))
+echo $a
+unset a x
+
+a=0 x="a=1"
+((0?$x:0))
+echo $a
+unset a x
+
+a=0 x="a=1"
+((0&&x))
+echo $a
+unset a x
+
+a=0 x="a=1"
+((1||x))
+echo $a
+unset a x
+
+a=0
+((0?arr[a=1]:0))
+echo $a
+unset a
diff --git a/tests/array-at-star b/tests/array-at-star
new file mode 100644
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..6227885
--- /dev/null
+++ b/tests/array.right
@@ -0,0 +1,787 @@
+
+./array.tests: line 28: syntax error near unexpected token `&'
+./array.tests: line 28: `test=(first & second)'
+1
+abcde
+abcde
+abcde bdef
+abcde bdef
+declare -a BASH_ARGC=()
+declare -a BASH_ARGV=()
+declare -a BASH_LINENO=([0]="0")
+declare -a BASH_SOURCE=([0]="./array.tests")
+declare -a DIRSTACK=()
+declare -a FUNCNAME
+declare -a a=([0]="abcde" [1]="" [2]="bdef")
+declare -a b
+declare -ar c
+abcde bdef
+abcde bdef
+abcde
+abcde
+abcde
+
+bdef
+hello world
+11
+3
+bdef hello world test expression test 2
+./array.tests: line 92: readonly: `a[5]': not a valid identifier
+declare -ar a=([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="test 2")
+declare -ar c
+declare -ar a=([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="test 2")
+declare -ar c
+readonly -a a=([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="test 2")
+readonly -a c
+a test
+declare -a BASH_ARGC=()
+declare -a BASH_ARGV=()
+declare -a BASH_LINENO=([0]="0")
+declare -a BASH_SOURCE=([0]="./array.tests")
+declare -a DIRSTACK=()
+declare -a FUNCNAME
+declare -ar a=([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="test 2")
+declare -a b=([0]="this" [1]="is" [2]="a" [3]="test" [4]="" [5]="/etc/passwd")
+declare -ar c
+declare -a d=([1]="" [2]="bdef" [5]="hello world" [6]="test" [9]="ninth element")
+declare -a e=([0]="test")
+declare -a f=([0]="" [1]="bdef" [2]="hello world" [3]="test" [4]="ninth element")
+./array.tests: line 116: a: readonly variable
+./array.tests: line 118: b[]: bad array subscript
+./array.tests: line 119: b[*]: bad array subscript
+this
+./array.tests: line 122: c[-2]: bad array subscript
+./array.tests: line 123: c: bad array subscript
+
+./array.tests: line 125: d[7]: cannot assign list to array member
+./array.tests: line 127: []=abcde: bad array subscript
+./array.tests: line 127: [*]=last: cannot assign to non-numeric index
+./array.tests: line 127: [-65]=negative: bad array subscript
+declare -a BASH_ARGC=()
+declare -a BASH_ARGV=()
+declare -a BASH_LINENO=([0]="0")
+declare -a BASH_SOURCE=([0]="./array.tests")
+declare -a DIRSTACK=()
+declare -a FUNCNAME
+declare -ar a=([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="test 2")
+declare -a b=([0]="this" [1]="is" [2]="a" [3]="test" [4]="" [5]="/etc/passwd")
+declare -ar c
+declare -a d=([1]="test test")
+declare -a e=()
+declare -a f=([0]="" [1]="bdef" [2]="hello world" [3]="test" [4]="ninth element")
+./array.tests: line 135: unset: ps1: not an array variable
+./array.tests: line 139: declare: c: cannot destroy array variables in this way
+this of
+this is a test of read using arrays
+this test
+this is a test of arrays
+declare -a BASH_ARGC=()
+declare -a BASH_ARGV=()
+declare -a BASH_LINENO=([0]="0")
+declare -a BASH_SOURCE=([0]="./array.tests")
+declare -a DIRSTACK=()
+declare -a FUNCNAME
+declare -ar a=([1]="" [2]="bdef" [5]="hello world" [6]="test expression" [15]="test 2")
+declare -a b=([0]="this" [1]="is" [2]="a" [3]="test" [4]="" [5]="/etc/passwd")
+declare -ar c
+declare -a d=([1]="test test")
+declare -a e=()
+declare -a f=([0]="" [1]="bdef" [2]="hello world" [3]="test" [4]="ninth element")
+declare -a rv=([0]="this" [1]="is" [2]="a" [3]="test" [4]="of" [5]="read" [6]="using" [7]="arrays")
+abde
+abde
+bbb
+efgh
+wxyz
+wxyz
+./array.tests
+a
+b c
+d
+e f g
+h
+./array.tests
+a
+b c
+d
+e f g
+h
+/bin /usr/bin /usr/ucb /usr/local/bin . /sbin /usr/sbin
+bin bin ucb bin . sbin sbin
+bin
+/ / / / / /
+/
+argv[1] = <bin>
+argv[1] = </>
+argv[1] = <sbin>
+argv[1] = </>
+\bin \usr/bin \usr/ucb \usr/local/bin . \sbin \usr/sbin
+\bin \usr\bin \usr\ucb \usr\local\bin . \sbin \usr\sbin
+\bin \usr\bin \usr\ucb \usr\local\bin . \sbin \usr\sbin
+4 -- 4
+7 -- 7
+55
+49
+6 -- 6
+42 14 44
+grep [ 123 ] *
+6 7 9
+6 7 9 5
+length = 3
+value = new1 new2 new3
+./array.tests: line 255: narray: unbound variable
+./array1.sub: line 1: syntax error near unexpected token `('
+./array1.sub: line 1: `printf "%s\n" -a a=(a 'b c')'
+./array2.sub: line 1: declare: `[]=asdf': not a valid identifier
+./array2.sub: line 2: a[]: bad array subscript
+./array2.sub: line 4: syntax error near unexpected token `('
+./array2.sub: line 4: `declare -a ''=(a 'b c')'
+9
+9
+
+
+7 8 9
+8 11
+8 11
+6
+6
+nordholz
+8
+8
+8
+
+a b c d e f g
+for case if then else
+<> < > !
+12 14 16 18 20
+4414758999202
+aaa bbb
+./array.tests: line 305: syntax error near unexpected token `<>'
+./array.tests: line 305: `metas=( <> < > ! )'
+./array.tests: line 306: syntax error near unexpected token `<>'
+./array.tests: line 306: `metas=( [1]=<> [2]=< [3]=> [4]=! )'
+abc 3
+case 4
+abc case if then else 5
+abc case if then else 5
+0
+case 4
+case if then else 5
+case if then else 5
+argv[1] = <0>
+argv[2] = <1>
+argv[3] = <4>
+argv[4] = <10>
+argv[1] = <0>
+argv[2] = <1>
+argv[3] = <4>
+argv[4] = <10>
+argv[1] = <0>
+argv[2] = <1>
+argv[3] = <4>
+argv[4] = <10>
+argv[1] = <0 1 4 10>
+include null element -- expect one
+one
+include unset element -- expect three five
+three five
+start at unset element -- expect five seven
+five seven
+too many elements -- expect three five seven
+three five seven
+positive offset - expect five seven
+five seven
+negative offset to unset element - expect seven
+seven
+positive offset 2 - expect seven
+seven
+negative offset 2 - expect seven
+seven
+out-of-range offset
+
+e
+4
+1 4 7 10
+'b
+b c
+$0
+declare -a A=([0]="X=a" [1]="b")
+t
+[3]=abcde r s t u v
+e
+9
+2
+a b c
+argv[1] = <-iname 'a>
+argv[2] = <-iname 'b>
+argv[3] = <-iname 'c>
+'hey'
+hey
+''hey
+'hey'
+argv[1] = <c>
+argv[2] = <d>
+argv[3] = <e>
+argv[4] = <f>
+argv[1] = <c d>
+argv[2] = <e f>
+argv[1] = <c d>
+argv[2] = <e f>
+argv[1] = <c d>
+argv[2] = <e f>
+argv[1] = <-iname 'abc>
+argv[2] = <-iname 'def>
+argv[1] = <-iname 'abc>
+argv[2] = <-iname 'def>
+argv[1] = <-iname>
+argv[2] = <abc -iname def>
+argv[1] = <-iname 'abc>
+argv[2] = <-iname 'def>
+argv[1] = <-iname>
+argv[2] = <abc -iname def>
+argv[1] = <-iname 'abc>
+argv[2] = <-iname 'def>
+argv[1] = <-iname 'abc>
+argv[2] = <-iname 'def>
+argv[1] = <-iname>
+argv[2] = <abc -iname def>
+*.* OK
+1
+a1 2 3c
+argv[1] = <var with spaces>
+argv[1] = <var with spaces>
+argv[1] = <var with spacesab>
+argv[2] = <cd>
+argv[3] = <ef>
+argv[1] = <var with spacesab>
+argv[2] = <cd>
+argv[3] = <ef>
+argv[1] = <var with spacesab>
+argv[2] = <cd>
+argv[3] = <ef>
+argv[1] = <var with spacesab>
+argv[2] = <cd>
+argv[3] = <ef>
+argv[1] = <var with spacesab>
+argv[2] = <cd>
+argv[3] = <ef>
+argv[1] = <var with spacesab>
+argv[2] = <cd>
+argv[3] = <ef>
+2
+argv[1] = <element1 with spaces>
+argv[2] = <element2 with spaces>
+argv[1] = <element1 with spaces>
+argv[2] = <element2 with spaces>
+nord!olz
+
+rdholz
+
+rdholz
+rdho
+
+
+argv[1] = <fooq//barq/>
+argv[1] = <fooq>
+argv[2] = <>
+argv[3] = <barq>
+argv[4] = <>
+argv[1] = <foo!//bar!/>
+argv[1] = <foo!>
+argv[2] = <>
+argv[3] = <bar!>
+argv[4] = <>
+argv[1] = <ooq//arq/>
+argv[1] = <ooq>
+argv[2] = <>
+argv[3] = <arq>
+argv[4] = <>
+argv[1] = <Fooq//Barq/>
+argv[1] = <Fooq>
+argv[2] = <>
+argv[3] = <Barq>
+argv[4] = <>
+argv[1] = <FOOQ//BARQ/>
+argv[1] = <FOOQ>
+argv[2] = <>
+argv[3] = <BARQ>
+argv[4] = <>
+126
+127
+128
+argv[1] = <€>
+argv[1] = <~>
+argv[2] = <^?>
+argv[3] = <€>
+argv[1] = <~>
+argv[2] = <^?>
+argv[3] = <€>
+argv[1] = <~>
+argv[2] = <^?>
+argv[3] = <€>
+Monday Tuesday Wednesday Thursday Friday Saturday Sunday
+Monday
+Monday
+Tuesday
+Monday
+Monday
+Tuesday
+Monday
+Tuesday
+Wednesday
+Monday
+Tuesday
+Wednesday
+monday, monday, tuesday
+wednesday, wednesday, thursday
+monday, monday, tuesday
+Wednesday, Wednesday, Thursday
+nday
+esday
+dnesday
+nday
+esday
+dnesday
+onday
+uesday
+ednesday
+onday
+uesday
+ednesday
+version[agent]
+version.agent
+version[agent]
+version.agent
+foo[bar] version[agent]
+bowl version.agent
+foobar] foo foo[bar]
+bleh bbb bleh
+ab]
+bar
+1
+1
+1
+1
+1
+1
+main main
+function function
+function function
+declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="5")
+declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4")
+declare -a x=([0]="0" [1]="1" [2]="2" [4]="4")
+./array14.sub: line 24: unset: [-10]: bad array subscript
+declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4")
+declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="five")
+declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="5")
+declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="foo")
+declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4" [5]="5")
+declare -a x=([0]="0" [1]="1" [2]="2" [3]="3" [4]="4four" [5]="5")
+strlen(4four) = 5
+1 2 0 3
+1 2 0 3
+1 2 0 3
+1 2 0 3
+1 2 0 3
+declare -ai arr=([0]="2" [1]="4" [2]="6")
+declare -a arr=([0]="hello" [1]="world")
+foo index 1: ok
+foo index 2: ok
+foo: implicit reference to element 0: ok
+foo: arithmetic evaluation: ok
+bar: array with element zero unset: ok
+bar: element zero: ok
+qux: unset array: ok
+qux: unset array element 0: ok
+2
+2
+2
+2
+0
+0
+1
+./array17.sub: line 43: ~: syntax error: operand expected (error token is "~")
+0
+0
+3
+3
+0
+0
+zero
+zero
+one
+one
+one
+one
+two
+two
+./array17.sub: line 89: ~ : syntax error: operand expected (error token is "~ ")
+1
+argv[1] = <>
+argv[2] = <>
+argv[3] = <>
+argv[1] = <bar>
+argv[1] = <->
+argv[2] = <->
+argv[1] = < >
+argv[1] = <qux>
+argv[1] = <->
+argv[2] = <->
+argv[1] = < >
+argv[1] = <>
+argv[2] = <>
+argv[3] = <>
+argv[1] = <bar>
+argv[1] = <->
+argv[2] = <->
+argv[1] = < >
+argv[1] = <qux>
+argv[1] = <->
+argv[2] = <->
+argv[1] = < >
+declare -a foo=([0]="( zeroind )")
+declare -a foo=([0]="zeroind")
+declare -a foo=([0]="zeroind")
+declare -a foo=([0]="[0]=bar")
+declare -a foo=([0]="[0]=bar")
+declare -a foo=([0]="[0]=bar")
+declare -- a="(1 2 3)"
+declare -a a=([0]="1" [1]="2" [2]="3")
+declare -- a="([0]=a [1]=b)"
+declare -a a=([0]="a" [1]="b")
+declare -A a=([1]="b" [0]="a" )
+declare -a var=([0]="[\$(echo" [1]="total" [2]="0)]=1" [3]="[2]=2]")
+declare -a var=([0]="[\$(echo total 0)]=1 [2]=2]")
+declare -a var=([0]="[\$(echo" [1]="total" [2]="0)]=1" [3]="[2]=2]")
+./array19.sub: line 89: total 0: syntax error in expression (error token is "0")
+declare -a var=()
+declare -al foo=([0]="abcde" [1]="two" [2]="three")
+declare -al foo=([0]="abcde")
+declare -al ar=([0]="one" [1]="two" [2]="three")
+declare -a a=([2]="foo")
+declare -a a=([2]="foo")
+declare -a a=([1]="(var)" [2]="foo")
+./array19.sub: line 128: warning: a[1]=(var): quoted compound array assignment deprecated
+declare -a a=([1]="(var)")
+declare -a a=([0]="1" [1]="2" [2]="(1 2 3)")
+declare -a a=([0]="1" [1]="2" [2]="(1 2 3)")
+declare -a a=([0]="1" [1]="2" [2]="3")
+declare -a a=([0]="1" [1]="2" [2]="3")
+declare -a a=([0]="1" [1]="2" [2]="3")
+declare -- a="a b"
+declare -- b="/scratch/bash"
+declare -- c="(1 2)"
+declare -- d="(\$a)"
+declare -- e="(\$(echo Darwin))"
+declare -a a=([0]="a b")
+declare -a b=([0]="/scratch/bash")
+declare -a c=([0]="1" [1]="2")
+declare -a d=([0]="a" [1]="b")
+declare -a e=([0]="Darwin")
+declare -A a=([0]="a b" )
+declare -A b=([0]="/scratch/bash" )
+declare -A c=([1]="2" )
+declare -A d=(["a b"]="" )
+declare -A e=([Darwin]="" )
+a+b+c
+x+b+c
+a+b+c
+x+b+c
+argv[1] = <a+b+c+d+e+f>
+argv[1] = <x+b+c+d+e+f>
+a b c
+x b c
+a b c
+x b c
+declare -a a=([1]="2" [2]="3" [3]="4")
+abcd
+unset
+declare -a a=()
+declare -A A=([four]="4" [two]="2" [three]="3" [one]="1" )
+declare -a a=()
+declare -A A=()
+declare -a foo=([0]="1" [1]="(4 5 6)" [2]="3")
+a1
+argv[1] = <>
+argv[2] = <>
+a2
+argv[1] = <y>
+argv[1] = <z>
+a3
+argv[1] = <>
+argv[2] = <x>
+a4
+argv[1] = <y>
+p1
+argv[1] = <>
+argv[2] = <>
+p2
+argv[1] = <>
+argv[2] = <x>
+p3
+argv[1] = <y>
+<X> <X> <X> <X>
+<X> <X> <X> <X>
+./array23.sub: line 22: $( echo >&2 foo ) : syntax error: operand expected (error token is "$( echo >&2 foo ) ")
+./array23.sub: line 23: $( echo >&2 foo ) : syntax error: operand expected (error token is "$( echo >&2 foo ) ")
+./array23.sub: line 24: $( echo >&2 foo ) : syntax error: operand expected (error token is "$( echo >&2 foo ) ")
+./array23.sub: line 26: $( echo >&2 foo ) : syntax error: operand expected (error token is "$( echo >&2 foo ) ")
+./array23.sub: line 30: $( echo >&2 foo ): syntax error: operand expected (error token is "$( echo >&2 foo )")
+./array23.sub: line 33: $( echo >&2 foo ): syntax error: operand expected (error token is "$( echo >&2 foo )")
+./array23.sub: line 34: $index: syntax error: operand expected (error token is "$index")
+./array23.sub: line 35: $( echo >&2 foo ): syntax error: operand expected (error token is "$( echo >&2 foo )")
+0
+0
+0
+IFS=: ${var-$*}
+abc
+def ghi
+jkl
+abc
+def ghi
+jkl
+----
+IFS=: ${var=$*}
+abc
+def ghi
+jkl
+var=abc:def ghi:jkl
+abc
+def ghi
+jkl
+var=abc:def ghi:jkl
+----
+IFS=: ${var+$*}
+abc
+def ghi
+jkl
+abc
+def ghi
+jkl
+----
+IFS= ${var-$*}
+abc
+def ghi
+jkl
+abc
+def ghi
+jkl
+----
+IFS= ${var=$*}
+abcdef ghijkl
+var=abcdef ghijkl
+abcdef ghijkl
+var=abcdef ghijkl
+----
+IFS= ${var+$*}
+abc
+def ghi
+jkl
+abc
+def ghi
+jkl
+1. indexed:
+reference:
+1. 0
+./array25.sub: line 24: ' ': syntax error: operand expected (error token is "' '")
+3. 0
+4. 0
+5. 0
+6. 0
+assignment:
+1.declare -a a=([0]="10" [1]="1")
+2.declare -a a=([0]="11" [1]="1")
+3.declare -a a=([0]="12" [1]="1")
+4.declare -a a=([0]="13" [1]="1")
+arithmetic:
+1.declare -a a=([0]="10" [1]="1")
+2.declare -a a=([0]="11" [1]="1")
+3.declare -a a=([0]="12" [1]="1")
+4.declare -a a=([0]="13" [1]="1")
+5.declare -a a=([0]="10" [1]="1")
+6.declare -a a=([0]="11" [1]="1")
+7.declare -a a=([0]="12" [1]="1")
+8.declare -a a=([0]="13" [1]="1")
+2. associative:
+reference:
+1.
+2.
+3.
+4.
+5.
+6.
+assignment:
+1.declare -A a=([1]="1" [0]="0" [" "]="10" )
+2.declare -A a=([1]="1" [0]="0" [" "]="11" )
+3.declare -A a=([1]="1" [0]="0" [" "]="12" )
+4.declare -A a=([1]="1" [0]="0" [" "]="13" )
+arithmetic:
+1.declare -A a=([1]="1" [0]="0" [" "]="10" )
+2.declare -A a=([1]="1" [0]="0" [" "]="11" )
+3.declare -A a=([1]="1" [0]="0" [" "]="12" )
+4.declare -A a=([1]="1" [0]="0" [" "]="13" )
+5.declare -A a=([1]="1" [0]="0" [" "]="10" )
+6.declare -A a=([1]="1" [0]="0" [" "]="10" ["\" \""]="11" )
+7.declare -A a=([1]="1" [0]="0" [" "]="12" ["\" \""]="11" )
+8.declare -A a=([1]="1" [0]="0" [" "]="12" ["\" \""]="13" )
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[3] = <aa>
+argv[4] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[3] = <aa>
+argv[4] = <bb>
+argv[1] = <aa+bb>
+argv[2] = <aa+bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[3] = <aa>
+argv[4] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa+bb>
+argv[1] = <xa+bb>
+argv[1] = <xa+bb>
+argv[2] = <xa+bb>
+argv[1] = <bb>
+argv[2] = <xa>
+argv[1] = <bb>
+argv[2] = <xa>
+argv[1] = <bb>
+argv[2] = <xa>
+argv[1] = <bb+xa>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xa>
+argv[2] = <bb>
+argv[1] = <xabb>
+argv[1] = <xabb>
+argv[1] = <xabb>
+argv[2] = <xabb>
+argv[1] = <bb>
+argv[2] = <xa>
+argv[1] = <bb>
+argv[2] = <xa>
+argv[1] = <bb>
+argv[2] = <xa>
+argv[1] = <bbxa>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[3] = <aa>
+argv[4] = <bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[3] = <aa>
+argv[4] = <bb>
+argv[1] = <aa+bb>
+argv[2] = <aa+bb>
+argv[1] = <aa+bb>
+argv[2] = <aa+bb>
+argv[1] = <aa>
+argv[2] = <bb>
+argv[3] = <aa>
+argv[4] = <bb>
+argv[1] = <bb>
+argv[2] = <aa>
+argv[1] = <bb>
+argv[2] = <aa>
+argv[1] = <bb>
+argv[2] = <aa>
+argv[1] = <bb+aa>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <a>
+argv[4] = <b>
+argv[1] = <a+b>
+argv[2] = <a+b>
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <a>
+argv[4] = <b>
+argv[1] = <b>
+argv[2] = <a>
+argv[1] = <b>
+argv[2] = <a>
+argv[1] = <b>
+argv[2] = <a>
+argv[1] = <b+a>
+7
+7
+declare -A A=([$'\t']="2" [" "]="2" )
+declare -A A=([$'\t']="2" ["*"]="2" [" "]="2" ["]"]="2" ["@"]="2" )
+declare -A A=([$'\t']="2" ["*"]="2" [" "]="2" ["]"]="2" ["@"]="2" )
+./array27.sub: line 52: read: `A[]]': not a valid identifier
+declare -A A=([$'\t']="X" ["*"]="X" [" "]="X" ["@"]="X" )
+./array27.sub: line 60: printf: `A[]]': not a valid identifier
+declare -A A=([$'\t']="X" ["*"]="X" [" "]="X" ["@"]="X" )
+./array27.sub: line 68: declare: `A[]]=X': not a valid identifier
+declare -A A=(["*"]="X" ["@"]="X" )
+./array27.sub: line 76: declare: `A[]]=X': not a valid identifier
+declare -A A=(["*"]="X" ["@"]="X" )
+declare -a bug4=([0]="" [1]="5" [2]="" [3]="1" [4]="")
+declare -a bug=([0]="" [1]="5" [2]="" [3]="1" [4]="")
+declare -a bug2=([0]="")
+declare -a bug3=([0]="" [1]="5" [2]="" [3]="1" [4]="")
+declare -a not_bug=([0]="no" [1]="nulls")
+declare -a workaround=([0]="")
+declare -a var=([0]=$'\001\001\001\001')
+declare -A v2=([$'\001']=$'ab\001c' )
+declare -a foo=([0]=$'\001\001\001\001')
+declare -A foo=([$'\001']=$'ab\001c' )
+declare -a foo=([0]=$'\001\001\001\001')
+declare -a foo=([0]=$'\001\001\001\001')
+declare -A foo=([v]=$'\001\001\001\001' )
+declare -A foo=([v]=$'\001\001\001\001' )
+declare -A foo=([$'\001']=$'ab\001c' )
+declare -A foo=([$'\001']=$'ab\001c' )
+foo
+declare -a a=([42]="foo")
+foo
+declare -a a=([42]="foo")
+7
+declare -ai a=([42]="7")
+42
+declare -ai a=([42]="42")
+FOO
+declare -Au A=([Darwin]="FOO" )
+FOO
+declare -Au A=(["@"]="FOO" )
diff --git a/tests/array.tests b/tests/array.tests
new file mode 100644
index 0000000..d0bb08b
--- /dev/null
+++ b/tests/array.tests
@@ -0,0 +1,429 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# this is needed so that the bad assignments (b[]=bcde, for example) do not
+# cause fatal shell errors when in posix mode
+set +o posix
+
+set +a
+# The calls to egrep -v are to filter out builtin array variables that are
+# automatically set and possibly contain values that vary.
+
+# first make sure we handle the basics
+x=()
+echo ${x[@]}
+unset x
+
+# this should be an error
+test=(first & second)
+echo $?
+unset test
+
+# make sure declare -a converts an existing variable to an array
+unset a
+a=abcde
+declare -a a
+echo ${a[0]}
+if [ "$a" != "${a[0]}" ]; then
+ echo 'array.tests: $a and $a[0] array mismatch'
+fi
+
+unset a
+a=abcde
+a[2]=bdef
+
+unset b
+declare -a b[256]
+
+unset c[2]
+unset c[*]
+
+a[1]=
+
+_ENV=/bin/true
+x=${_ENV[(_$-=0)+(_=1)-_${-%%*i*}]}
+
+declare -r c[100]
+
+echo ${a[0]} ${a[4]}
+echo ${a[@]}
+
+echo ${a[*]}
+
+# this should print out values, too
+declare -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
+
+unset a[7]
+echo ${a[*]}
+
+unset a[4]
+echo ${a[*]}
+
+echo ${a}
+echo "${a}"
+echo $a
+
+unset a[0]
+echo ${a}
+
+echo ${a[@]}
+
+a[5]="hello world"
+echo ${a[5]}
+echo ${#a[5]}
+
+echo ${#a[@]}
+
+a[4+5/2]="test expression"
+declare a["7 + 8"]="test 2"
+a[7 + 8]="test 2"
+echo ${a[@]}
+
+readonly a[5]
+readonly a
+# these two lines should output `declare' commands
+readonly -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
+declare -ar | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
+# this line should output `readonly' commands, even for arrays
+set -o posix
+readonly -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
+set +o posix
+
+declare -a d='([1]="" [2]="bdef" [5]="hello world" "test")'
+d[9]="ninth element"
+
+declare -a e[10]=test # this works in post-bash-2.05 versions
+declare -a e[10]='(test)'
+
+pass=/etc/passwd
+declare -a f='("${d[@]}")'
+b=([0]=this [1]=is [2]=a [3]=test [4]="$PS1" [5]=$pass)
+
+echo ${b[@]:2:3}
+
+declare -pa | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
+
+a[3]="this is a test"
+
+b[]=bcde
+b[*]=aaa
+echo ${b[ ]}
+
+c[-2]=4
+echo ${c[-4]}
+
+d[7]=(abdedfegeee)
+
+d=([]=abcde [1]="test test" [*]=last [-65]=negative )
+
+unset d[12]
+unset e[*]
+
+declare -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
+
+ps1='hello'
+unset ps1[2]
+unset ${ps1[2]}
+
+declare +a ps1
+declare +a c
+
+# the prompt should not print when using a here doc
+read -p "array test: " -a rv <<!
+this is a test of read using arrays
+!
+
+echo ${rv[0]} ${rv[4]}
+echo ${rv[@]}
+
+# the variable should be converted to an array when `read -a' is done
+vv=1
+read -a vv <<!
+this is a test of arrays
+!
+echo ${vv[0]} ${vv[3]}
+echo ${vv[@]}
+unset vv
+
+declare -a | egrep -v '(BASH_VERSINFO|PIPESTATUS|GROUPS)'
+
+export rv
+#set
+
+x[4]=bbb
+x=abde
+echo $x
+echo ${x[0]}
+echo ${x[4]}
+echo efgh | ( read x[1] ; echo ${x[1]} )
+echo wxyz | ( declare -a x ; read x ; echo $x ; echo ${x[0]} )
+
+# Make sure that arrays can be used to save the positional parameters verbatim
+set -- a 'b c' d 'e f g' h
+
+ARGV=( [0]=$0 "$@" )
+
+for z in "${ARGV[@]}"
+do
+ echo "$z"
+done
+
+echo "$0"
+for z in "$@"
+do
+ echo "$z"
+done
+
+# do various pattern removal and length tests
+XPATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:.:/sbin:/usr/sbin
+
+xpath=( $( IFS=: ; echo $XPATH ) )
+
+echo ${xpath[@]}
+echo ${xpath[@]##*/}
+echo ${xpath[0]##*/}
+echo ${xpath[@]%%[!/]*}
+echo ${xpath[0]%%[!/]*}
+recho ${xpath##*/}
+recho ${xpath%%[!/]*}
+recho ${xpath[5]##*/}
+recho ${xpath[5]%%[!/]*}
+
+# let's try to make it a DOS-style path
+
+zecho "${xpath[@]/\//\\}"
+zecho "${xpath[@]//\//\\}"
+zecho "${xpath[@]//[\/]/\\}"
+
+# length of the first element of the array, since array without subscript
+# is equivalent to referencing first element
+echo ${#xpath} -- ${#xpath[0]}
+
+# number of elements in the array
+nelem=${#xpath[@]}
+echo ${#xpath[@]} -- $nelem
+
+# total length of all elements in the array, including space separators
+xx="${xpath[*]}"
+echo ${#xx}
+
+# total length of all elements in the array
+xx=$( IFS='' ; echo "${xpath[*]}" )
+echo ${#xx}
+
+unset xpath[nelem-1]
+
+nelem=${#xpath[@]}
+echo ${#xpath[@]} -- $nelem
+
+# arrays and things that look like index assignments
+array=(42 [1]=14 [2]=44)
+
+array2=(grep [ 123 ] \*)
+
+echo ${array[@]}
+echo "${array2[@]}"
+
+# arrays and implicit arithmetic evaluation
+declare -i -a iarray
+
+iarray=( 2+4 1+6 7+2 )
+echo ${iarray[@]}
+
+iarray[4]=4+1
+echo ${iarray[@]}
+
+# make sure assignment using the compound assignment syntax removes all
+# of the old elements from the array value
+barray=(old1 old2 old3 old4 old5)
+barray=(new1 new2 new3)
+echo "length = ${#barray[@]}"
+echo "value = ${barray[*]}"
+
+# make sure the array code behaves correctly with respect to unset variables
+set -u
+( echo ${#narray[4]} )
+
+${THIS_SH} ./array1.sub
+${THIS_SH} ./array2.sub
+
+# some old bugs and ksh93 compatibility tests
+${THIS_SH} ./array3.sub
+
+# some compound assignment parsing problems that showed up in bash-3.1-release
+${THIS_SH} ./array4.sub
+
+set +u
+cd ${TMPDIR:=/tmp}
+
+touch 1=bar
+foo=([10]="bar")
+echo ${foo[0]}
+rm 1=bar
+
+cd $OLDPWD
+
+foo=(a b c d e f g)
+echo ${foo[@]}
+
+# quoted reserved words are ok
+foo=(\for \case \if \then \else)
+echo ${foo[@]}
+
+# quoted metacharacters are ok
+foo=( [1]='<>' [2]='<' [3]='>' [4]='!' )
+echo ${foo[@]}
+
+# numbers are just words when not in a redirection context
+foo=( 12 14 16 18 20 )
+echo ${foo[@]}
+
+foo=( 4414758999202 )
+echo ${foo[@]}
+
+# this was a bug in all versions of bash 2.x up to and including bash-2.04
+declare -a ddd=(aaa
+bbb)
+echo ${ddd[@]}
+
+# errors until post-bash-2.05a; now reserved words are OK
+foo=(a b c for case if then else)
+
+foo=(for case if then else)
+
+# errors
+metas=( <> < > ! )
+metas=( [1]=<> [2]=< [3]=> [4]=! )
+
+# various expansions that didn't really work right until post-bash-2.04
+foo='abc'
+echo ${foo[0]} ${#foo[0]}
+echo ${foo[1]} ${#foo[1]}
+echo ${foo[@]} ${#foo[@]}
+echo ${foo[*]} ${#foo[*]}
+
+foo=''
+echo ${foo[0]} ${#foo[0]}
+echo ${foo[1]} ${#foo[1]}
+echo ${foo[@]} ${#foo[@]}
+echo ${foo[*]} ${#foo[*]}
+
+# new expansions added after bash-2.05b
+x[0]=zero
+x[1]=one
+x[4]=four
+x[10]=ten
+
+recho ${!x[@]}
+recho "${!x[@]}"
+recho ${!x[*]}
+recho "${!x[*]}"
+
+# sparse array tests for code fixed in bash-3.0
+unset av
+av[1]='one'
+av[2]=''
+
+av[3]=three
+av[5]=five
+av[7]=seven
+
+echo include null element -- expect one
+echo ${av[@]:1:2} # what happens when we include a null element?
+echo include unset element -- expect three five
+echo ${av[@]:3:2} # what happens when we include an unset element?
+echo start at unset element -- expect five seven
+echo ${av[@]:4:2} # what happens when we start at an unset element?
+
+echo too many elements -- expect three five seven
+echo ${av[@]:3:5} # how about too many elements?
+
+echo positive offset - expect five seven
+echo ${av[@]:5:2}
+echo negative offset to unset element - expect seven
+echo ${av[@]: -2:2}
+
+echo positive offset 2 - expect seven
+echo ${av[@]: 6:2}
+echo negative offset 2 - expect seven
+echo ${av[@]: -1:2}
+
+echo out-of-range offset
+echo ${av[@]:12}
+
+# parsing problems and other inconsistencies not fixed until post bash-3.0
+unset x
+declare -a x=(')' $$)
+[ ${x[1]} -eq $$ ] || echo bad
+
+unset x
+declare -a x=(a b c d e)
+echo ${x[4]}
+
+z=([1]=one [4]=four [7]=seven [10]=ten)
+
+echo ${#z[@]}
+
+echo ${!z[@]}
+
+unset x
+declare -a x=(a \'b c\')
+
+echo "${x[1]}"
+
+unset x
+declare -a x=(a 'b c')
+
+echo "${x[1]}"
+
+unset x
+declare -a x=($0)
+[ "${x[@]}" = $0 ] || echo double expansion of \$0
+declare -a x=(\$0)
+echo "${x[@]}"
+
+unset A Z
+Z='a b'
+A=( X=$Z )
+declare -p A
+
+# tests for bash-3.1 problems
+${THIS_SH} ./array5.sub
+
+# tests for post-bash-3.2 problems, most fixed in bash-3.2 patches
+${THIS_SH} ./array6.sub
+${THIS_SH} ./array7.sub
+
+${THIS_SH} ./array8.sub
+${THIS_SH} ./array9.sub
+${THIS_SH} ./array10.sub
+${THIS_SH} ./array11.sub
+${THIS_SH} ./array12.sub
+${THIS_SH} ./array13.sub
+${THIS_SH} ./array14.sub
+${THIS_SH} ./array15.sub
+${THIS_SH} ./array16.sub
+${THIS_SH} ./array17.sub
+${THIS_SH} ./array18.sub
+${THIS_SH} ./array19.sub
+${THIS_SH} ./array20.sub
+${THIS_SH} ./array21.sub
+${THIS_SH} ./array22.sub
+${THIS_SH} ./array23.sub
+${THIS_SH} ./array24.sub
+${THIS_SH} ./array25.sub
+${THIS_SH} ./array26.sub
+${THIS_SH} ./array27.sub
+${THIS_SH} ./array28.sub
+${THIS_SH} ./array29.sub
+${THIS_SH} ./array30.sub
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/array10.sub b/tests/array10.sub
new file mode 100644
index 0000000..7182480
--- /dev/null
+++ b/tests/array10.sub
@@ -0,0 +1,65 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+days=({Mon,Tues,Wednes,Thurs,Fri,Satur,Sun}day)
+echo ${days[@]}
+
+typeset -i count
+
+count=0
+echo ${days[${count}]}
+echo ${days[$((count++))]}
+echo ${days[$((count++))]}
+
+count=0
+echo ${days[count]}
+echo ${days[count++]}
+echo ${days[count++]}
+
+count=0
+echo ${days[$((count++))]/foo/bar}
+echo ${days[$((count++))]/foo/bar}
+echo ${days[$((count++))]/foo/bar}
+
+count=0
+echo ${days[count++]/foo/bar}
+echo ${days[count++]/foo/bar}
+echo ${days[count++]/foo/bar}
+
+count=0
+echo "${days[${count}],,}, ${days[$((count++))],,}, ${days[$((count++))],,}"
+echo "${days[${count}],,}, ${days[$((count++))],,}, ${days[$((count++))],,}"
+
+count=0
+echo "${days[${count}],,}, ${days[$((count++))],,}, ${days[$((count++))],,}"
+echo "${days[${count}]/foo/bar}, ${days[$((count++))]/foo/bar}, ${days[$((count++))]/foo/bar}"
+
+count=0
+echo ${days[$((count++))]:2}
+echo ${days[$((count++))]:2}
+echo ${days[$((count++))]:2}
+
+count=0
+echo ${days[count++]:2}
+echo ${days[count++]:2}
+echo ${days[count++]:2}
+
+count=0
+echo ${days[$((count++))]#?}
+echo ${days[$((count++))]#?}
+echo ${days[$((count++))]#?}
+
+count=0
+echo ${days[count++]#?}
+echo ${days[count++]#?}
+echo ${days[count++]#?}
diff --git a/tests/array11.sub b/tests/array11.sub
new file mode 100644
index 0000000..5961902
--- /dev/null
+++ b/tests/array11.sub
@@ -0,0 +1,48 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# problems with associative array keys with ] and unbalanced [ ]
+# fixed after bash-4.2
+
+declare -A foo
+
+foo=(["version[agent]"]=version.agent)
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+unset foo
+declare -A foo
+foo["version[agent]"]=version.agent
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+declare foo["foo[bar]"]=bowl
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+declare -A array2["foo[bar]"]=bleh
+
+array2["foobar]"]=bleh
+array2["foo"]=bbb
+
+echo ${!array2[@]}
+echo ${array2[@]}
+
+declare -A foo
+foo=( ['ab]']=bar )
+
+echo ${!foo[@]}
+echo ${foo[@]}
diff --git a/tests/array12.sub b/tests/array12.sub
new file mode 100644
index 0000000..fbf5eeb
--- /dev/null
+++ b/tests/array12.sub
@@ -0,0 +1,34 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# problems with fix for posix interp 217 introduced in bash-4.2
+
+declare -ax array
+array[$(( $( echo -n 1001 ) - 1001 ))]=1
+
+echo ${array[0]}
+echo ${array[@]}
+
+unset 'array[0]'
+array[$( echo -n 1001 ) - 1001 ]=1
+echo ${array[0]}
+
+unset 'array[0]'
+array[$(( 1001 - $( echo -n 1001 ) ))]=1
+echo ${array[0]}
+array[$(( 1001 - $( echo -n 1001 ) ))]=1
+echo ${array[0]}
+
+unset 'array[0]'
+array[1001 - $( echo -n 1001 )]=1
+echo ${array[0]}
diff --git a/tests/array13.sub b/tests/array13.sub
new file mode 100644
index 0000000..635cb97
--- /dev/null
+++ b/tests/array13.sub
@@ -0,0 +1,12 @@
+
+func1(){
+declare -g variable='function'
+declare -g -a array=(function)
+echo ${variable} ${array[@]}
+}
+
+declare -g variable='main'
+declare -g -a array=(main)
+echo ${variable} ${array[@]}
+func1
+echo ${variable} ${array[@]}
diff --git a/tests/array14.sub b/tests/array14.sub
new file mode 100644
index 0000000..57a455a
--- /dev/null
+++ b/tests/array14.sub
@@ -0,0 +1,43 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# start at a test suite for negative indexed array subscripts -- post bash-4.2
+x=( 0 1 2 3 4 5)
+declare -p x
+
+unset 'x[-1]'
+declare -p x
+
+unset 'x[-2]'
+declare -p x
+
+unset 'x[-10]'
+
+x[-2]=3
+declare -p x
+
+x+=( five )
+declare -p x
+x[-1]=5
+declare -p x
+
+x+=( [-1]=foo )
+declare -p x
+
+x[-1]=5
+declare -p x
+
+x[-2]+=four
+declare -p x
+
+echo "strlen(${x[-2]})" = ${#x[-2]}
diff --git a/tests/array15.sub b/tests/array15.sub
new file mode 100644
index 0000000..12f5391
--- /dev/null
+++ b/tests/array15.sub
@@ -0,0 +1,52 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# fixes for make_internal_declare not handling integer attribute for arrays
+declare -ai -g foo=(1 2 xx 3)
+echo "${foo[@]}"
+
+unset foo
+declare -ai -g foo='(1 2 xx 3)'
+echo "${foo[@]}"
+
+unset foo
+declare -ia -g foo=(1 2 xx 3)
+echo "${foo[@]}"
+
+unset foo
+declare -ia -g foo='(1 2 xx 3)'
+echo "${foo[@]}"
+
+unset foo
+func()
+{
+ declare -ai -g foo=(1 2 xx 3)
+}
+
+func
+echo "${foo[@]}"
+
+unset foo
+
+# test options to declare that disable attributes that affect how values
+# are expanded
+#
+# we already handle options that set attributes specially, so we should
+# handle attributes that unset those attributes specially as well
+
+unset arr
+declare -i -a arr=(1+1 2+2 3+3)
+declare -p arr
+
+declare +i arr=(hello world)
+declare -p arr
diff --git a/tests/array16.sub b/tests/array16.sub
new file mode 100644
index 0000000..b82dbca
--- /dev/null
+++ b/tests/array16.sub
@@ -0,0 +1,34 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+foo[0]=a
+foo[1]=b
+
+[[ -v foo[1] ]] && echo foo index 1: ok
+[[ -v foo[2] ]] || echo foo index 2: ok
+
+[[ -v foo ]] && echo foo: implicit reference to element 0: ok
+
+typeset -i foo
+
+[[ -v foo[1] ]] && echo foo: arithmetic evaluation: ok
+
+typeset -a bar
+bar[1]=set
+
+[[ -v bar ]] || echo bar: array with element zero unset: ok
+[[ -v bar[0] ]] || echo bar: element zero: ok
+
+typeset -a qux
+[[ -v qux ]] || echo qux: unset array: ok
+[[ -v qux[0] ]] || echo qux: unset array element 0: ok
diff --git a/tests/array17.sub b/tests/array17.sub
new file mode 100644
index 0000000..dd0c0f6
--- /dev/null
+++ b/tests/array17.sub
@@ -0,0 +1,91 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# this shows the expansions an array subscript undergoes before being run
+# through the arithmetic evaluator
+
+b=(0 1 2 3)
+
+# array subscripts undergo variable expansion
+a=2
+echo ${b[$a]}
+
+# array subscripts undergo command substitution
+echo ${b[$(echo 2)]}
+
+c='1+1'
+d='1-+1'
+
+# array subscripts are expanded and the expanded value is treated as an
+# expression
+echo ${b[$c]}
+echo ${b[c]}
+
+echo ${b[$d]}
+echo ${b[d]}
+
+# array subscripts undergo parameter expansion
+set -- 1 2 3
+echo ${b[$1]}
+
+# array subscripts undergo tilde expansion
+HOME=2
+echo ${b[~]}
+
+# array subscripts undergo word splitting -- bug in bash versions through 4.3
+
+x='b[$d]'
+IFS=-
+echo $((x))
+IFS=$' \t\n'
+
+set -- 1 + 2
+
+x='d'
+IFS=-
+echo $((x))
+IFS=$' \t\n'
+
+# start of quoting tests; make sure that subscript is treated as double
+# quoted (inhibits word splitting) but that double quotes are silently
+# discarded through quote removal
+
+echo $(( $@ ))
+echo "$(( $@ ))"
+
+echo $(( "$x" ))
+echo $(( "x" ))
+
+unset a foo bar
+a=(zero one two three four five six seven eight nine ten)
+
+echo ${a[0]}
+echo ${a["0"]}
+
+foo=1
+echo ${a[$foo]}
+echo ${a["$foo"]}
+echo ${a[foo]}
+echo ${a["foo"]}
+
+bar=2
+echo ${a[" $bar "]}
+echo ${a[" bar "]}
+
+# tilde expansion is performed by array subscript expansion but not by posix
+# style arithmetic expansion
+
+HOME=2
+echo $(( ~ ))
+
+
diff --git a/tests/array18.sub b/tests/array18.sub
new file mode 100644
index 0000000..9503081
--- /dev/null
+++ b/tests/array18.sub
@@ -0,0 +1,47 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# arrays referenced using @ subscript and positional parameters should behave
+# the same way
+
+foo=(0 0 0); [[ -z ${foo[@]#0} ]]; echo $?
+
+recho "${foo[@]#0}"
+bar=${foo[@]#0}
+recho bar
+recho $bar
+recho -$bar-
+recho "$bar"
+
+qux="${foo[@]#0}"
+recho qux
+recho $qux
+recho -$qux-
+recho "$qux"
+
+unset foo qux bar
+
+set -- 0 0 0
+
+recho "${@#0}"
+bar=${@#0}
+recho bar
+recho $bar
+recho -$bar-
+recho "$bar"
+
+qux="${@#0}"
+recho qux
+recho $qux
+recho -$qux-
+recho "$qux"
diff --git a/tests/array19.sub b/tests/array19.sub
new file mode 100644
index 0000000..1d02f74
--- /dev/null
+++ b/tests/array19.sub
@@ -0,0 +1,175 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# tests for changes to declare and assignment statement arguments post-bash-4.3
+
+unset foo l a b
+
+l="( zeroind )"
+
+unset foo
+declare -a foo
+foo="$l"
+declare -p foo
+
+unset foo
+declare -a foo="$l"
+declare -p foo
+
+unset foo
+declare -a foo=$l
+declare -p foo
+
+b='[0]=bar'
+
+unset foo
+declare -a foo="$b"
+declare -p foo
+
+unset foo
+declare -a foo=("$b")
+declare -p foo
+
+unset foo
+declare -a foo=($b)
+declare -p foo
+
+unset a
+
+declare a='(1 2 3)'
+declare -p a
+unset a
+
+declare -a a
+declare a='(1 2 3)'
+declare -p a
+unset a
+
+declare a='([0]=a [1]=b)'
+declare -p a
+unset a
+
+declare -a a
+declare a='([0]=a [1]=b)'
+declare -p a
+unset a
+
+declare -A a
+declare a='([0]=a [1]=b)'
+declare -p a
+unset a
+unset var value
+
+value='[$(echo total 0)]=1 [2]=2]'
+
+unset var
+declare -a var
+var=($value)
+declare -p var
+
+unset var
+declare -a var=("$value")
+declare -p var
+
+unset var
+declare -a var=($value)
+declare -p var
+
+unset var
+declare -a var="($value)"
+declare -p var
+unset foo value
+
+value="AbCdE"
+
+declare -a foo
+foo=( one two three )
+
+declare -l foo="$value"
+declare -p foo
+
+unset foo
+value='(AbCdE)'
+
+declare -a foo
+foo=( one two three )
+
+declare -l foo="$value"
+declare -p foo
+unset ar
+declare -a ar=(ONE TWO THREE)
+declare -al ar=(${ar[@]})
+declare -p ar
+unset a
+
+declare -a a
+a[2]=foo
+declare -p a
+
+unset a
+declare -a a
+declare a[2]=foo
+declare -p a
+
+declare a[1]='(var)'
+declare -p a
+
+unset a
+declare a[1]='(var)'
+declare -p a
+unset a
+
+a=(1 2 3)
+a[2]='(1 2 3)'
+
+declare -p a
+
+unset a
+a=(1 2 3)
+declare a[2]='(1 2 3)'
+
+declare -p a
+
+unset a
+a=(1 2 3)
+declare a='(1 2 3)'
+
+declare -p a
+
+unset a
+a=(1 2 3)
+declare 'a=(1 2 3)'
+
+declare -p a
+
+unset a
+declare -a a='(1 2 3)'
+
+declare -p a
+unset a b c d e x y
+
+HOME=/scratch/bash
+x='a b'
+y='($(echo Darwin))'
+
+declare a=$x b=~ c='(1 2)' d='($a)' e=$y
+
+declare -p a b c d e
+
+unset a b c d e
+declare -a a=$x b=~ c='(1 2)' d='($a)' e=$y
+declare -p a b c d e
+
+unset a b c d e
+declare -A a=$x b=~ c='(1 2)' d='($a)' e=$y
+declare -p a b c d e
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..44bb7c5
--- /dev/null
+++ b/tests/array2.sub
@@ -0,0 +1,4 @@
+declare -r []=asdf
+declare -r a[]=asdf
+
+declare -a ''=(a 'b c')
diff --git a/tests/array20.sub b/tests/array20.sub
new file mode 100644
index 0000000..24dff93
--- /dev/null
+++ b/tests/array20.sub
@@ -0,0 +1,47 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# tests to make sure that $* and ${array[*]} expand consistently in `list'
+# and `scalar' contexts
+
+arr=(a b c)
+IFS=+
+
+# these two should both expand to `+' separated strings
+a=${arr[*]} ; echo "$a"
+b=${arr[*]/a/x}; echo "$b"
+
+set -- a b c
+
+# these two should both expand to `+' separated strings
+a=${*} ; echo "$a"
+b=${*/a/x}; echo "$b"
+
+# these two should both expand to `+' separated strings and it should handle
+# characters in IFS as chars in the string
+unset a b
+
+set -- 'a+b' 'c+d' 'e+f'
+a=${*} ; recho "$a"
+b=${*/a/x}; recho "$b"
+
+# now let's make sure that @ always uses space separators even in contexts
+# where we don't do word splitting
+set -- a b c
+a=${@} ; echo "$a"
+b=${@/a/x}; echo "$b"
+
+unset a b
+
+a=${arr[@]} ; echo "$a"
+b=${arr[@]/a/x}; echo "$b"
diff --git a/tests/array21.sub b/tests/array21.sub
new file mode 100644
index 0000000..97ff093
--- /dev/null
+++ b/tests/array21.sub
@@ -0,0 +1,50 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+typeset -a a
+a=(1 2 3 4)
+
+typeset -A A
+A=([one]=1 [two]=2 [three]=3 [four]=4)
+
+unset 'a[0]'
+typeset -p a
+
+scalar=abcd
+echo ${scalar[0]}
+
+unset 'scalar[0]'
+echo ${scalar-unset}
+
+unset 'a[@]'
+typeset -p a
+
+unset 'A[@]'
+typeset -p A
+
+typeset -a a
+a=(1 2 3 4)
+typeset -A A
+A=([one]=1 [two]=2 [three]=3 [four]=4)
+
+# supported, recommended way to unset all array elements
+a=()
+typeset -p a
+A=()
+typeset -p A
+
+declare -a foo
+declare foo='(1 2 3)'
+declare foo[1]='(4 5 6)'
+
+declare -p foo
diff --git a/tests/array22.sub b/tests/array22.sub
new file mode 100644
index 0000000..3374ef2
--- /dev/null
+++ b/tests/array22.sub
@@ -0,0 +1,59 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# This isn't perfect behavior, but it establishes a baseline and will provide
+# a way to detect behavior changes
+
+echo a1
+a[0]= a[1]=; recho "${a[@]:-y}"
+unset a
+
+echo a2
+a[1]=; recho "${a[@]:-y}"
+a[1]=; recho "${a[*]:-z}"
+unset a
+
+echo a3
+a[0]= a[1]=x; recho "${a[@]:-y}"
+unset a
+
+echo a4
+a[0]= a[1]=x; recho ${a[@]:+y}
+unset a
+
+echo p1
+set '' ''
+recho "${@:-y}"
+
+shift $#
+
+echo p2
+set '' x
+recho "${@:-y}"
+
+shift $#
+
+echo p3
+set '' x
+recho ${@:+y}
+
+# problems with * and null expansions dating back to bash's earliest days
+A=(''); set -- ''
+
+echo "<${A[*]:-X}>" "<${*:-X}>" "<${A:-X}>" "<${A[0]:-X}>"
+
+IFS=
+A=('' ''); set -- '' ''
+B=''
+
+echo "<${A[*]:-X}>" "<${*:-X}>" "<${B:-X}>" "<${B[*]:-X}>"
diff --git a/tests/array23.sub b/tests/array23.sub
new file mode 100644
index 0000000..02d271d
--- /dev/null
+++ b/tests/array23.sub
@@ -0,0 +1,41 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# this captures how bash and ksh93 expand indexed array subscripts in
+# various contexts. if changes are ever made, or an option added to do
+# this differently, the diffs will show up here
+
+typeset -a array
+
+index='$( echo >&2 foo )' # Literal shell code should never be evaluated unless an 'eval' is involved.
+
+echo ${array[ $index ]} # [] expands $index, results in a literal that [] does not re-evaluate.
+echo $(( $index )) # (( )) expands $index, results in a literal that (( )) does not re-evaluate.
+echo $(( array[ $index ] )) # (( )) expands $index, results in a literal that [] DOES re-evaluate.
+
+(( array[ $index ] ))
+
+typeset -a a
+
+: $(( a[$index]=5 ))
+
+#shopt -s assoc_expand_once
+echo $((1+a[$index]))
+echo $((1+a[\$index]))
+echo "1+${a[$index]}"
+
+# intermediate problems discovered while bash-5.0 was in testing
+a=0
+echo $(( a[a[0]] ))
+echo ${a[a[a[0]]]}
+echo $(( a[a[a[0]]] ))
diff --git a/tests/array24.sub b/tests/array24.sub
new file mode 100644
index 0000000..461b406
--- /dev/null
+++ b/tests/array24.sub
@@ -0,0 +1,60 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+set -- "abc" "def ghi" "jkl"
+A=("$@")
+
+IFS=':'
+
+echo 'IFS=: ${var-$*}'
+unset var; printf '%s\n' ${var-$*}
+printf '%s\n' ${var-${A[*]}}
+
+echo "----"
+echo 'IFS=: ${var=$*}'
+
+unset var; printf '%s\n' ${var=$*}
+printf 'var=%s\n' "$var"
+
+unset var; printf '%s\n' ${var=${A[*]}}
+printf 'var=%s\n' "$var"
+
+echo "----"
+echo 'IFS=: ${var+$*}'
+
+printf '%s\n' ${var+$*}
+printf '%s\n' ${var+${A[*]}}
+
+echo "----"
+echo 'IFS= ${var-$*}'
+
+IFS=''
+unset var; printf '%s\n' ${var-$*}
+unset var; printf '%s\n' ${var-${A[*]}}
+
+echo "----"
+echo 'IFS= ${var=$*}'
+
+unset var
+printf '%s\n' ${var=$*}
+printf 'var=%s\n' "$var"
+
+unset var
+printf '%s\n' ${var=${A[*]}}
+printf 'var=%s\n' "$var"
+
+echo "----"
+echo 'IFS= ${var+$*}'
+
+printf '%s\n' ${var+$*}
+printf '%s\n' ${var+${A[*]}}
diff --git a/tests/array25.sub b/tests/array25.sub
new file mode 100644
index 0000000..fe6bb34
--- /dev/null
+++ b/tests/array25.sub
@@ -0,0 +1,83 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# tests with blank subscripts, indexed and associative
+
+echo 1. indexed:
+a[0]=0 a[1]=1
+
+v=" "
+
+echo reference:
+
+echo 1. ${a[ ]}
+echo 2. ${a[' ']}
+echo 3. "${a[ ]}"
+echo 4. ${a[$v]}
+echo 5. ${a["$v"]}
+echo 6. "${a[$v]}"
+
+echo assignment:
+
+echo -n 1. ; a[ ]=10 ; typeset -p a ; a[0]=0
+echo -n 2. ; a[" "]=11 ; typeset -p a ; a[0]=0
+echo -n 3. ; a[$v]=12 ; typeset -p a ; a[0]=0
+echo -n 4. ; a["$v"]=13 ; typeset -p a ; a[0]=0
+
+echo arithmetic:
+
+echo -n 1. ; (( a[ ]=10 )); typeset -p a ; a[0]=0
+echo -n 2. ; (( a[" "]=11 )); typeset -p a ; a[0]=0
+echo -n 3. ; (( a[$v]=12 )); typeset -p a ; a[0]=0
+echo -n 4. ; (( a["$v"]=13 )); typeset -p a ; a[0]=0
+echo -n 5. ; let "a[ ]=10" ; typeset -p a ; a[0]=0
+echo -n 6. ; let "a[\" \"]=11" ; typeset -p a ; a[0]=0
+echo -n 7. ; let "a[$v]=12" ; typeset -p a ; a[0]=0
+echo -n 8. ; let "a[\"$v\"]=13" ; typeset -p a ; a[0]=0
+
+unset -v a v
+
+echo 2. associative:
+shopt -s assoc_expand_once
+
+typeset -A a
+a[0]=0 a[1]=1
+
+v=" "
+
+echo reference:
+
+echo 1. ${a[ ]}
+echo 2. ${a[' ']}
+echo 3. "${a[ ]}"
+echo 4. ${a[$v]}
+echo 5. ${a["$v"]}
+echo 6. "${a[$v]}"
+
+echo assignment:
+
+echo -n 1. ; a[ ]=10 ; typeset -p a ; a[0]=0
+echo -n 2. ; a[" "]=11 ; typeset -p a ; a[0]=0
+echo -n 3. ; a[$v]=12 ; typeset -p a ; a[0]=0
+echo -n 4. ; a["$v"]=13 ; typeset -p a ; a[0]=0
+
+echo arithmetic:
+
+echo -n 1. ; (( a[ ]=10 )); typeset -p a ; a[0]=0
+echo -n 2. ; (( a[" "]=11 )); typeset -p a ; a[0]=0
+echo -n 3. ; (( a[$v]=12 )); typeset -p a ; a[0]=0
+echo -n 4. ; (( a["$v"]=13 )); typeset -p a ; a[0]=0
+echo -n 5. ; let "a[ ]=10" ; typeset -p a ; a[0]=0
+echo -n 6. ; let "a[\" \"]=11" ; typeset -p a ; a[0]=0
+echo -n 7. ; let "a[$v]=12" ; typeset -p a ; a[0]=0
+echo -n 8. ; let "a[\"$v\"]=13" ; typeset -p a ; a[0]=0
diff --git a/tests/array26.sub b/tests/array26.sub
new file mode 100644
index 0000000..0f6cc8f
--- /dev/null
+++ b/tests/array26.sub
@@ -0,0 +1,131 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# these should produce the same results
+a=(aa bb)
+set -- aa bb
+
+IFS=+
+
+recho ${a[@]}
+recho ${a[@]:0}
+
+recho $@
+recho ${@:1}
+
+A=${a[*]} B=${a[*]:0}
+recho $* ${*:1}
+recho ${a[*]} ${a[*]:0}
+recho "$A" "$B"
+recho $A $B
+
+unset A B
+
+recho ${@/a/x}
+recho ${a[@]/a/x}
+recho "${@/a/x}"
+recho "${a[@]/a/x}"
+
+recho ${*/a/x}
+recho ${a[*]/a/x}
+recho "${*/a/x}"
+recho "${a[*]/a/x}"
+
+A=${*/a/x}
+B=${a[*]/a/x}
+
+recho "$A" "$B"
+
+unset A B
+declare -A A
+A[0]=aa
+A[1]=bb
+
+recho ${A[@]/a/x}
+recho "${A[@]/a/x}"
+recho ${A[*]/a/x}
+recho "${A[*]/a/x}"
+
+unset A
+IFS=
+
+recho ${@/a/x}
+recho ${a[@]/a/x}
+recho "${@/a/x}"
+recho "${a[@]/a/x}"
+
+recho ${*/a/x}
+recho ${a[*]/a/x}
+recho "${*/a/x}"
+recho "${a[*]/a/x}"
+
+A=${*/a/x}
+B=${a[*]/a/x}
+
+recho "$A" "$B"
+
+unset A B
+declare -A A
+A[0]=aa
+A[1]=bb
+
+recho ${A[@]/a/x}
+recho "${A[@]/a/x}"
+recho ${A[*]/a/x}
+recho "${A[*]/a/x}"
+
+unset A
+
+IFS=+
+
+recho ${a[@]}
+recho ${a[@],,}
+recho "${a[@]}"
+recho "${a[@],,}"
+
+A=${a[*]} B=${a[*],,}
+recho $* ${*,,}
+recho ${a[*]} ${a[*],,}
+recho "${a[*]}" "${a[*],,}"
+recho "$A" "$B"
+recho $A $B
+
+unset A B
+declare -A A
+A[0]=aa
+A[1]=bb
+
+recho ${A[@],,}
+recho "${A[@],,}"
+recho ${A[*],,}
+recho "${A[*],,}"
+
+unset A
+
+recho ${a[@]#?}
+recho ${@#?}
+
+A=${a[*]#?} B=${a[*]#?}
+recho ${*#?} ${a[*]#?}
+recho "$A" "$B"
+recho $A $B
+
+unset A B
+declare -A A
+A[0]=aa
+A[1]=bb
+
+recho ${A[@]#?}
+recho "${A[@]#?}"
+recho ${A[*]#?}
+recho "${A[*]#?}"
diff --git a/tests/array27.sub b/tests/array27.sub
new file mode 100644
index 0000000..e2a1e70
--- /dev/null
+++ b/tests/array27.sub
@@ -0,0 +1,78 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# tests for `problem' keys when using associative arrays and assoc_expand_once
+# deal with problems for now; this is a placeholder for if and when I fix them
+
+typeset -A a
+shopt -s assoc_expand_once
+
+k='['
+echo $(( a[$k]=7 ))
+
+k=']'
+echo $(( a[$k]=7 ))
+
+unset a
+
+declare -A A
+
+for k in $'\t' ' '; do
+ (( A[$k]=2 ))
+done
+declare -p A
+
+for k in ']' '*' '@'; do
+ (( A[$k]=2 ))
+done
+
+declare -p A
+
+unset A
+declare -A A
+for k in ']' '*' '@' $'\t' ' '; do
+ A[$k]=2
+done
+declare -p A
+
+unset A
+declare -A A
+
+for k in $'\t' ' ' ']' '*' '@'; do
+ read "A[$k]" <<< X
+done
+declare -p A
+
+unset A
+declare -A A
+
+for k in $'\t' ' ' ']' '*' '@'; do
+ printf -v "A[$k]" "%s" X
+done
+declare -p A
+
+unset A
+declare -A A
+
+for k in ']' '*' '@'; do
+ declare A[$k]=X
+done
+declare -p A
+
+unset A
+declare -A A
+
+for k in ']' '*' '@'; do
+ declare "A[$k]=X"
+done
+declare -p A
diff --git a/tests/array28.sub b/tests/array28.sub
new file mode 100644
index 0000000..e11cdb6
--- /dev/null
+++ b/tests/array28.sub
@@ -0,0 +1,30 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# tests for assigning empty string array elements without subscripts
+function foo()
+{
+ local bug=("" "5" "" 1 "")
+ declare -a bug2=("")
+ declare -ga bug3=("" "5" "" 1 "")
+ local not_bug=("no" "nulls")
+ local workaround; workaround=("")
+
+ declare -p bug bug2 bug3 not_bug workaround
+}
+
+declare -a bug4=("" "5" "" 1 "")
+declare -p bug4
+
+foo
diff --git a/tests/array29.sub b/tests/array29.sub
new file mode 100644
index 0000000..f73c2d1
--- /dev/null
+++ b/tests/array29.sub
@@ -0,0 +1,86 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Issues with CTLESC characters in array subscripts and values. Bash-5.1 and
+# earlier didn't quote them correctly and therefore halved the number of
+# CTLESCs.
+
+declare -a var
+var=( $'\x01\x01\x01\x01' )
+declare -p var
+declare -A v2
+v2=( $'\x01' ab$'\x01'c )
+declare -p v2
+
+pv()
+{
+ local -a foo
+ foo=( "${var[@]}" )
+ declare -p foo
+}
+pv
+
+unset -f pv
+pv()
+{
+ local -A foo
+ eval foo=\( "${v2[@]@k}" \)
+ declare -p foo
+}
+pv
+
+# these are wrong through bash-5.1; there is a fix tagged for bash-5.2
+# when I uncomment that fix, these results will reflect it
+
+pv1()
+{
+ local -a foo=( "${var[@]}" )
+ declare -p foo
+}
+pv1
+
+pv2()
+{
+ local -a foo=( [0]="${var[@]}" )
+ declare -p foo
+}
+pv2
+
+pv3()
+{
+ local -A foo=( v "${var[@]}" )
+ declare -p foo
+}
+pv3
+
+pv4()
+{
+ local -A foo=( [v]="${var[@]}" )
+ declare -p foo
+}
+pv4
+
+unset -f pv3 pv4
+pv3()
+{
+ local -A foo=( $'\x01' "${v2[@]}" )
+ declare -p foo
+}
+pv3
+
+pv4()
+{
+ local -A foo=( [$'\x01']="${v2[@]}" )
+ declare -p foo
+}
+pv4
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/array30.sub b/tests/array30.sub
new file mode 100644
index 0000000..14f9798
--- /dev/null
+++ b/tests/array30.sub
@@ -0,0 +1,46 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+declare -a a
+a=()
+
+echo ${a[42]=foo}
+declare -p a
+
+a=()
+echo ${a[$(echo 42)]=foo}
+declare -p a
+
+unset a
+
+declare -ai a
+a=()
+echo ${a[42]=4+3}
+declare -p a
+
+a=()
+echo ${a[$(echo 42)]=42}
+declare -p a
+
+unset a
+
+declare -A A
+declare -u A
+A=()
+echo ${A[$(echo Darwin)]=foo}
+
+declare -p A
+A=()
+
+echo ${A[@]:=foo}
+declare -p A
diff --git a/tests/array4.sub b/tests/array4.sub
new file mode 100644
index 0000000..443a0fd
--- /dev/null
+++ b/tests/array4.sub
@@ -0,0 +1,45 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# compound assignment parsing problems in bash-3.1-release
+func()
+{
+ local -a x=() y=()
+}
+
+a=() b=()
+eval foo=()
+eval foo=() bar=() qux=( "bash" )
+
+foo=( "bash" )
+eval foo=( "bash" )
+eval bar=( "bash" ) bax=( "bash" )
+
+let a=(5 + 3) b=(4 + 7)
+echo $a $b
+
+typeset -i a b
+a=(5+3) b=(4+7)
+echo $a $b
+
+let a=(4*3)/2
+echo $a
+a=(4*3)/2
+echo $a
+
+LNAME=nordholz
+echo ${LNAME}
+echo ${#LNAME}
+
+echo ${#LNAME[$(( 0 ))]}
+echo ${#LNAME[$(( 0+0 ))]}
diff --git a/tests/array5.sub b/tests/array5.sub
new file mode 100644
index 0000000..0dda696
--- /dev/null
+++ b/tests/array5.sub
@@ -0,0 +1,47 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+: ${TMPDIR:=/tmp}
+
+mkdir $TMPDIR/bash-test-$$
+cd $TMPDIR/bash-test-$$
+
+trap "cd $OLDPWD ; rm -rf $TMPDIR/bash-test-$$" 0 1 2 3 6 15
+
+touch '[3]=abcde'
+
+touch r s t u v
+
+declare -a x=(*)
+
+echo ${x[3]}
+echo ${x[@]}
+
+unset x
+x=(a b c d e)
+
+echo ${x[*]: -1}
+
+unset x[4]
+unset x[2]
+
+x[9]='9'
+
+echo ${x[*]: -1}
+
+TOOLKIT=(1 2 3 4 5 6 7 8 9 10)
+ARRAY="1"
+echo ${TOOLKIT["$ARRAY"]}
+
+exit 0
diff --git a/tests/array6.sub b/tests/array6.sub
new file mode 100644
index 0000000..2c6c350
--- /dev/null
+++ b/tests/array6.sub
@@ -0,0 +1,128 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test cases for array quoting and escaping fixed post bash-3.2-release
+
+oIFS="$IFS"
+
+a=(a b c)
+echo ${a[@]}
+
+a2=("${a[@]/#/"-iname '"}")
+recho "${a2[@]}"
+
+echo "${dbg-"'hey'"}"
+echo "${dbg-"hey"}"
+echo "${dbg-'"'hey}"
+echo "${dbg-'"hey'}"
+
+unset a a2
+
+IFS=
+a2=(${a[@]/#/"-iname '"})
+recho "${a2[@]}"
+
+IFS="$oIFS"
+unset a a2
+
+a=('a b' 'c d' 'e f')
+
+recho ${a[@]:1:2}
+recho "${a[@]:1:2}"
+
+IFS=
+recho ${a[@]:1:2}
+recho "${a[@]:1:2}"
+
+IFS="$oIFS"
+unset a a2
+
+a=(abc def)
+
+# Prevent word splitting
+#IFS=
+
+a2=("${a[@]/#/"-iname '"}")
+recho "${a2[@]}"
+
+eval a2=("${a[@]/#/\"-iname \'\"}")
+recho "${a2[@]}"
+
+eval a2=("${a[@]/#/"-iname '"}")
+recho "${a2[@]}"
+
+a2=("${a[@]/#/-iname \'}")
+recho "${a2[@]}"
+
+eval a2=("${a[@]/#/-iname \'}")
+recho "${a2[@]}"
+
+set -- abc def
+
+a2=("${@/#/"-iname '"}")
+recho "${a2[@]}"
+
+eval a2=("${@/#/\"-iname \'\"}")
+recho "${a2[@]}"
+
+eval a2=("${@/#/"-iname '"}")
+recho "${a2[@]}"
+
+unset a a2
+
+IFS=
+pat=('*.*')
+case $(ls ${pat[@]} 2>/dev/null) in
+'') echo '*.* BAD' ;;
+*) echo '*.* OK' ;;
+esac
+
+IFS="$oIFS"
+unset a a2 pat
+
+IFS=
+
+s='abc'
+
+set - ${s/b/1 2 3}
+echo $#
+echo "$1"
+
+IFS="$oIFS"
+unset s
+
+set -- ab cd ef
+foo="var with spaces"
+
+IFS=
+recho $foo
+recho "$foo"
+
+recho ${foo}"$@"
+recho ${foo}$@
+
+array=(ab cd ef)
+recho ${foo}"${array[@]}"
+recho ${foo}${array[@]}
+
+recho $(echo $foo)"$@"
+recho $(echo $foo)$@
+
+a=('word1 with spaces' 'word2 with spaces')
+set - ${a[@]/word/element}
+echo $#
+recho "$@"
+recho $@
+
+IFS="$oIFS"
+unset a a2 array foo
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..6e7e2d6
--- /dev/null
+++ b/tests/array8.sub
@@ -0,0 +1,36 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+IFS=/
+declare -a i
+
+i[0]=fooq
+i[1]=
+i[2]=barq
+i[3]=
+recho "${i[*]:0}"
+recho "${i[@]:0}"
+
+recho "${i[*]/q/!}"
+recho "${i[@]/q/!}"
+
+recho "${i[*]#?}"
+recho "${i[@]#?}"
+
+# Need to complete this with case-modifying expansion examples
+recho "${i[*]^?}"
+recho "${i[@]^?}"
+
+recho "${i[*]^^?}"
+recho "${i[@]^^?}"
+
diff --git a/tests/array9.sub b/tests/array9.sub
new file mode 100644
index 0000000..c3aa31d
--- /dev/null
+++ b/tests/array9.sub
@@ -0,0 +1,40 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+echo $(( 0x7e ))
+echo $(( 0x7f ))
+echo $(( 0x80 ))
+
+a=$'\x80'
+recho "$a"
+
+a=( $'\x7e' $'\x7f' $'\x80' )
+
+recho "${a[@]}"
+
+unset a
+a[0]=$'\x7e'
+a[1]=$'\x7f'
+a[2]=$'\x80'
+
+recho "${a[@]}"
+
+b1=$'\x7e'
+b2=$'\x7f'
+b3=$'\x80'
+
+unset a
+a=( "$b1" "$b2" "$b3" )
+
+recho "${a[@]}"
+
diff --git a/tests/assoc.right b/tests/assoc.right
new file mode 100644
index 0000000..9a1662c
--- /dev/null
+++ b/tests/assoc.right
@@ -0,0 +1,400 @@
+declare -A BASH_ALIASES=()
+declare -A BASH_CMDS=()
+declare -A fluff
+declare -A BASH_ALIASES=()
+declare -A BASH_CMDS=()
+declare -A fluff=([foo]="one" [bar]="two" )
+declare -A fluff=([foo]="one" [bar]="two" )
+declare -A fluff=([bar]="two" )
+declare -A fluff=([qux]="assigned" [bar]="newval" )
+./assoc.tests: line 39: chaff: four: must use subscript when assigning associative array
+declare -A BASH_ALIASES=()
+declare -A BASH_CMDS=()
+declare -Ai chaff=([one]="10" [zero]="5" )
+declare -Ar waste=([pid]="42134" [lineno]="41" [source]="./assoc.tests" [version]="4.0-devel" )
+declare -A wheat=([two]="b" [three]="c" [one]="a" [zero]="0" )
+declare -A chaff=(["hello world"]="flip" [one]="10" [zero]="5" )
+./assoc.tests: line 51: waste: readonly variable
+./assoc.tests: line 52: unset: waste: cannot unset: readonly variable
+declare -A chaff=(["*"]="12" ["hello world"]="flip" [one]="a" )
+flip
+argv[1] = <multiple>
+argv[2] = <words>
+argv[3] = <12>
+argv[4] = <flip>
+argv[5] = <a>
+argv[1] = <multiple words>
+argv[2] = <12>
+argv[3] = <flip>
+argv[4] = <a>
+argv[1] = <multiple>
+argv[2] = <words>
+argv[3] = <12>
+argv[4] = <flip>
+argv[5] = <a>
+argv[1] = <multiple words 12 flip a>
+./assoc.tests: line 71: declare: chaff: cannot destroy array variables in this way
+declare -A wheat=([six]="6" ["foo bar"]="qux qix" )
+argv[1] = <qux>
+argv[2] = <qix>
+argv[1] = <qux qix>
+declare -A wheat=([six]="6" ["foo bar"]="qux qix" )
+argv[1] = <2>
+argv[1] = <7>
+argv[1] = <qux>
+argv[2] = <qix>
+argv[3] = <blat>
+argv[1] = <qux qix blat>
+argv[1] = <16>
+argv[1] = <16>
+argv[1] = <6>
+argv[2] = <flix>
+argv[1] = <six>
+argv[2] = <foo>
+argv[3] = <bar>
+argv[1] = <six>
+argv[2] = <foo bar>
+8
+/usr/local/bin /bin . /usr/bin /usr/ucb /usr/sbin /bin /sbin
+bin bin . bin ucb sbin bin sbin
+bin
+/ / / / / / /
+/
+argv[1] = <bin>
+argv[1] = </>
+argv[1] = <sbin>
+argv[1] = </>
+8
+/usr/local/bin /bin . /usr/bin /usr/ucb /usr/sbin /bin /sbin
+bin bin . bin ucb sbin bin sbin
+/ / / / / / /
+8
+4 -- /bin
+^usr^local^bin ^bin . ^usr^bin ^usr^ucb ^usr^sbin ^bin ^sbin
+^usr^local^bin ^bin . ^usr^bin ^usr^ucb ^usr^sbin ^bin ^sbin
+\usr/local/bin \bin . \usr/bin \usr/ucb \usr/sbin \bin \sbin
+\usr\local\bin \bin . \usr\bin \usr\ucb \usr\sbin \bin \sbin
+\usr\local\bin \bin . \usr\bin \usr\ucb \usr\sbin \bin \sbin
+([a]=1)
+
+foo qux
+/usr/sbin/foo /usr/local/bin/qux
+hits command
+ 0 /usr/sbin/foo
+ 0 /bin/sh
+ 0 /sbin/blat
+ 0 /usr/local/bin/qux
+foo sh blat qux
+/usr/sbin/foo /bin/sh /sbin/blat /usr/local/bin/qux
+
+foo qux
+argv[1] = </usr/sbin/foo>
+argv[2] = </usr/local/bin/qux>
+argv[3] = <-l>
+alias blat='cd /blat ; echo $PWD'
+alias foo='/usr/sbin/foo'
+alias qux='/usr/local/bin/qux -l'
+alias sh='/bin/bash --login -o posix'
+blat foo sh qux
+argv[1] = <cd /blat ; echo $PWD>
+argv[2] = </usr/sbin/foo>
+argv[3] = </bin/bash --login -o posix>
+argv[4] = </usr/local/bin/qux -l>
+outside: outside
+declare -A BASH_ALIASES=()
+declare -A BASH_CMDS=()
+declare -A afoo=([six]="six" ["foo bar"]="foo quux" )
+argv[1] = <inside:>
+argv[2] = <six>
+argv[3] = <foo quux>
+outside 2: outside
+argv[1] = </barq//fooq>
+argv[1] = <>
+argv[2] = <barq>
+argv[3] = <>
+argv[4] = <fooq>
+argv[1] = </bar!//foo!>
+argv[1] = <>
+argv[2] = <bar!>
+argv[3] = <>
+argv[4] = <foo!>
+argv[1] = </arq//ooq>
+argv[1] = <>
+argv[2] = <arq>
+argv[3] = <>
+argv[4] = <ooq>
+argv[1] = </Barq//Fooq>
+argv[1] = <>
+argv[2] = <Barq>
+argv[3] = <>
+argv[4] = <Fooq>
+argv[1] = </BARQ//FOOQ>
+argv[1] = <>
+argv[2] = <BARQ>
+argv[3] = <>
+argv[4] = <FOOQ>
+abc
+def
+def
+./assoc5.sub: line 26: declare: `myarray[foo[bar]=bleh': not a valid identifier
+def bleh abc
+myarray=(["]"]="def" [foo]="bleh" ["a]a"]="abc" ["a]=test1;#a"]="123" )
+
+123
+myarray=(["]"]="def" ["a]=test2;#a"]="def" [foo]="bleh" ["a]a"]="abc" ["a]=test1;#a"]="123" )
+bar"bie
+doll
+declare -A foo=(["bar\"bie"]="doll" )
+bar"bie
+doll
+declare -A foo=(["bar\"bie"]="doll" )
+bar"bie
+doll
+declare -A foo=(["bar\"bie"]="doll" )
+bar"bie
+doll
+declare -A foo=(["bar\"bie"]="doll" )
+bar"bie
+doll
+declare -A foo=(["bar\"bie"]="doll" )
+bar'bie
+doll
+declare -A foo=(["bar'bie"]="doll" )
+bar'bie
+doll
+declare -A foo=(["bar'bie"]="doll" )
+bar'bie
+doll
+declare -A foo=(["bar'bie"]="doll" )
+bar'bie
+doll
+declare -A foo=(["bar'bie"]="doll" )
+bar'bie
+doll
+declare -A foo=(["bar'bie"]="doll" )
+bar$bie
+doll
+declare -A foo=(["bar\$bie"]="doll" )
+bar[bie
+doll
+declare -A foo=(["bar[bie"]="doll" )
+bar`bie
+doll
+declare -A foo=(["bar\`bie"]="doll" )
+bar\]bie
+doll
+declare -A foo=(["bar\\]bie"]="doll" )
+bar${foo}bie
+doll
+declare -A foo=(["bar\${foo}bie"]="doll" )
+bar
+after printf
+after use: 0
+declare -A assoc=([0]="assoc" )
+assoc
+declare -A assoc=([two]="twoless" [three]="three" [one]="onemore" )
+declare -Ar assoc=([two]="twoless" [three]="three" [one]="onemore" )
+declare -A hash=([key]="value1" )
+declare -A hash=([key]="value1 value2" )
+declare -A b=([")"]="" ["\""]="" ["]"]="" ["\\"]="" ["\`"]="" )
+declare -A b=(["]"]="" ["\`"]="" )
+declare -A dict=(["'"]="3" ["\""]="1" ["\\"]="4" ["\`"]="2" )
+declare -A dict=()
+declare -A dict=(["'"]="3" ["\""]="1" ["\\"]="4" ["\`"]="2" )
+declare -A dict=()
+4
+4
+a[$b]= 5
+declare -A a=(["80's"]="Depeche Mode" )
+./assoc9.sub: line 84: read: `a[80's]': not a valid identifier
+declare -A a
+declare -A a=(["80's"]="Depeche Mode" )
+./assoc9.sub: line 96: printf: `a[80's]': not a valid identifier
+declare -A a
+declare -A a=(["80's"]="Depeche Mode" )
+6
+1
+1+5
+declare -A a=(["\$(date >&2)"]="5" )
+declare -A myarray=([foo]="bleh" ["foo[bar"]="bleh" )
+foo
+declare -A assoc=(["\$var"]="value" )
+declare -A assoc=(["\$var"]="value" )
+declare -A assoc=(["\$var"]="value" )
+declare -A assoc=()
+./assoc9.sub: line 154: typeset: `foo[foo]bar]=bax': not a valid identifier
+foo]bar
+bip
+declare -A foo=(["foo]bar"]="bip" )
+./assoc10.sub: line 14: declare: a: cannot convert indexed to associative array
+f: declare -a a
+./assoc10.sub: line 17: declare: a: cannot convert associative to indexed array
+f: declare -A a
+
+f: declare -a a
+main: declare -- a="7"
+f: declare -A a
+main: declare -- a="42"
+declare -A a=([3]="" [1]="2" )
+declare -A foo=([d]="4" [c]="3" [b]="2" [a]="1" )
+foo=( d "4" c "3" b "2" a "1" )
+declare -A foo=(["\\"]="5" ["@"]="3" ["holy hell this works"]="4" ["a b"]="1" ["spa ces"]="2" )
+foo=( echo "\\" "5" "@" "3" "holy hell this works" "4" "a b" "1" "spa ces" "2" )
+./assoc11.sub: line 34: "": bad array subscript
+declare -A foo=([";"]="semicolon" ["]"]="def" [a=b]="assignment" ["a]a"]="abc" ["foo[bar"]="bleh" )
+foo=( ";" "semicolon" "]" "def" a=b "assignment" "a]a" "abc" "foo[bar" "bleh" )
+declare -A foo=(["'"]="squote" ["\""]="dquote" ["\\"]="bslash" ["\`"]="backquote" )
+foo=( "'" "squote" "\"" "dquote" "\\" "bslash" "\`" "backquote" )
+declare -A foo=(["bar]bie"]="doll" ["a]=test1;#a"]="123" ["bar\"bie"]="doll" )
+foo=( "bar]bie" "doll" "a]=test1;#a" "123" "bar\"bie" "doll" )
+declare -A inside=([c]="3" [b]="2" [a]="1" )
+inside=( c "3" b "2" a "1" )
+declare -A dict=(["?"]="quest" ["*"]="star" ["'"]="squote" ["\$"]="dol" ["\""]="dquote" ["\\"]="bslash" ["@"]="at" ["}"]="rbrace" ["{"]="lbrace" ["\`"]="bquote" )
+dict=( "?" "quest" "*" "star" "'" "squote" "\$" "dol" "\"" "dquote" "\\" "bslash" "@" "at" "}" "rbrace" "{" "lbrace" "\`" "bquote" )
+declare -A foo=([two]="" [one]="1" )
+foo=( two "" one "1" )
+rparen dquote rbracket bs
+declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbracket" ["\\"]="bs" )
+")" "rparen" "\"" "dquote" "]" "rbracket" "\\" "bs"
+declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbracket" ["\\"]="bs" )
+declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbracket" ["\\"]="bs" )
+declare -A a=([")"]="rparen" ["\""]="dquote" ["]"]="rbracket" ["\\"]="bs" )
+declare -Arx foo=([two]="2" [three]="3" [one]="1" )
+./assoc11.sub: line 90: foo: readonly variable
+declare -A v1=(["1 2"]="3" )
+declare -A v2=(["1 2"]="3" )
+declare -A v3=(["1 2"]="3" )
+declare -A v1=(["1 2"]="3 4 5" )
+declare -A v2=(["1 2"]="3 4 5" )
+declare -A v3=(["1 2"]="3 4 5" )
+declare -A v1=(["1 2"]="3 4 5" )
+declare -A v2=(["1 2"]="3 4 5" )
+declare -A v3=(["1 2"]="3 4 5" )
+declare -A v1=(["1 2"]="3 4 5" )
+declare -A v2=(["1 2"]="3 4 5" )
+declare -A v3=(["1 2"]="3 4 5" )
+declare -A v1=(["20 40 80"]="xtra" ["1 2"]="3 4 5" )
+declare -A v2=(["20 40 80"]="xtra" ["1 2"]="3 4 5" )
+declare -A v3=(["1 2"]="3 4 5" ["\$xtra"]="xtra" )
+declare -A v1=(["20 40 80"]="new xtra" ["1 2"]="3 4 5" )
+declare -A v2=(["20 40 80"]="new xtra" ["1 2"]="3 4 5" )
+declare -A v3=(["1 2"]="3 4 5" ["\$xtra"]="new xtra" )
+declare -A assoc=(["*"]="star" ["!"]="bang" ["@"]="at" )
+at
+star
+declare -A a=(["@"]="at" )
+./assoc13.sub: line 22: ia[@]: bad array subscript
+declare -a ia
+declare -A a=(["@"]="at2" )
+declare -A a=(["@"]=" string" )
+declare -A a=(["*"]="star2" ["@"]="at" )
+declare -A assoc=([hello]="world" ["key with spaces"]="value with spaces" [foo]="bar" [one]="1" )
+argv[1] = <world>
+argv[2] = <value with spaces>
+argv[3] = <bar>
+argv[4] = <1>
+argv[1] = <hello>
+argv[2] = <world>
+argv[3] = <key with spaces>
+argv[4] = <value with spaces>
+argv[5] = <foo>
+argv[6] = <bar>
+argv[7] = <one>
+argv[8] = <1>
+argv[1] = <world value with spaces bar 1>
+argv[1] = <hello world key with spaces value with spaces foo bar one 1>
+argv[1] = <hello>
+argv[2] = <world>
+argv[3] = <key with spaces>
+argv[4] = <value with spaces>
+argv[5] = <one>
+argv[6] = <1>
+argv[7] = <foo>
+argv[8] = <bar>
+argv[1] = <'hello'>
+argv[2] = <'world'>
+argv[3] = <'key with spaces'>
+argv[4] = <'value with spaces'>
+argv[5] = <'one'>
+argv[6] = <'1'>
+argv[7] = <'foo'>
+argv[8] = <'bar'>
+argv[1] = <'hello'>
+argv[2] = <'world'>
+argv[3] = <'key with spaces'>
+argv[4] = <'value with spaces'>
+argv[5] = <'one'>
+argv[6] = <'1'>
+argv[7] = <'foo'>
+argv[8] = <'bar'>
+declare -A clone=([hello]="world" ["key with spaces"]="value with spaces" [foo]="bar" [one]="1" )
+declare -A posparams=([hello]="world" ["key with spaces"]="value with spaces" [foo]="bar" [one]="1" )
+declare -A var=([$'\001']=$'\001\001\001\001' )
+declare -A v2=([$'\001']=$'\001\001\001\001' )
+argv[1] = <^A>
+argv[2] = <^A^A^A^A>
+declare -A foo=([$'\001']=$'\001\001\001\001' )
+declare -A var=([$'\001']=$'\001\001\001\001' )
+argv[1] = <^A>
+argv[2] = <^A^A^A^A>
+declare -A foo=([$'\001']=$'\001\001\001\001' )
+declare -A var=([$'\001']=$'\001\001\001\001' )
+argv[1] = <^A>
+argv[2] = <^A^A^A^A>
+declare -A foo=([$'\001']=$'\001\001\001\001' )
+declare -a var=([0]=$'\001\001\001\001')
+argv[1] = <$'\001\001\001\001'>
+declare -a foo=([0]=$'\001\001\001\001')
+declare -a var=([0]=$'\001\001\001\001')
+argv[1] = <$'\001\001\001\001'>
+declare -a foo=([0]=$'\001\001\001\001')
+declare -A var=([two]=$'ab\001cd' [one]=$'\001\001\001\001' )
+declare -A foo=([two]=$'ab\001cd' [one]=$'\001\001\001\001' )
+declare -A foo=([$'\001']=$'ab\001cd' )
+declare -A foo=([$'\001']=$'\001\001\001\001' )
+declare -A A=(["\$(echo Darwin ; echo stderr>&2)"]="darjeeling" [Darwin]="darjeeling" )
+stderr
+darjsharking
+darjsharking
+stderr
+darj
+darj
+stderr
+DARJEELING
+DARJEELING
+stderr
+'darjeeling'
+'darjeeling'
+stderr
+darjeel
+darjeel
+stderr
+10
+10
+stderr
+darjeeling
+darjeeling
+stderr
+set
+set
+stderr
+set
+set
+stderr
+42
+42
+declare -A A=(["]"]="rbracket" ["["]="lbracket" )
+declare -A A=()
+declare -A A=(["]"]="rbracket" ["["]="lbracket" )
+declare -A A=()
+declare -A A=(["]"]="rbracket" ["["]="lbracket" )
+declare -A A=()
+declare -A A=(["]"]="rbracket" ["["]="lbracket" )
+declare -A A=()
+declare -A A=(["]"]="rbracket" ["["]="lbracket" )
+declare -A A=()
+declare -A A=(["]"]="rbracket" ["["]="lbracket" )
+declare -A A=()
+declare -A A=(["]"]="rbracket" ["["]="lbracket" )
+declare -A A=()
+5: ok 1
diff --git a/tests/assoc.tests b/tests/assoc.tests
new file mode 100644
index 0000000..c656536
--- /dev/null
+++ b/tests/assoc.tests
@@ -0,0 +1,268 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# TEST - basic declaration and assignment
+typeset -A fluff
+declare -A
+
+fluff[foo]=one
+fluff[bar]=two
+
+declare -A
+declare -p fluff
+
+unset fluff[foo]
+declare -p fluff
+
+fluff[bar]=newval
+declare fluff[qux]=assigned
+
+declare -p fluff
+
+unset fluff
+
+# TEST - compound assignment and variable attributes
+declare -A wheat chaff
+wheat=( [zero]=0 [one]=a [two]=b [three]=c )
+
+declare -i chaff
+chaff=( [zero]=1+4 [one]=3+7 four )
+
+declare -A waste=( [pid]=42134 [version]=4.0-devel [source]=$0 [lineno]=$LINENO )
+declare -r waste
+
+declare -A
+
+declare +i chaff
+chaff[hello world]=flip
+declare -p chaff
+
+# TEST - no longer errors
+waste[stuff]=other
+unset waste
+chaff[*]=12
+chaff=( [one]=a [*]=12 )
+
+# TEST - key expansion -- no word splitting
+chaff[hello world]=flip
+declare -p chaff
+echo ${chaff[hello world]}
+
+chaff[box]="multiple words"
+
+recho ${chaff[@]}
+recho "${chaff[@]}"
+
+recho ${chaff[*]}
+recho "${chaff[*]}"
+
+unset chaff
+declare -A chaff[200]
+declare +A chaff
+
+chaff[*]=12
+chaff=( [one]=a [*]=12 )
+
+# TEST - keys and values containing spaces
+unset wheat
+declare -A wheat
+wheat=([six]=6 [foo bar]="qux qix" )
+
+declare -p wheat
+
+unset wheat
+declare -A wheat=([six]=6 [foo bar]="qux qix" )
+
+recho ${wheat[foo bar]}
+recho "${wheat[foo bar]}"
+
+declare -p wheat
+
+# TEST - basic expansions: number of elements and value length
+unset wheat
+typeset -A wheat
+wheat=([six]=6 [foo bar]="qux qix" )
+
+recho ${#wheat[@]}
+
+recho ${#wheat[foo bar]}
+
+# TEST - appending assignment operator
+unset wheat
+typeset -A wheat
+wheat=([six]=6 [foo bar]="qux qix" )
+
+wheat[foo bar]+=' blat'
+
+recho ${wheat[foo bar]}
+recho "${wheat[foo bar]}"
+unset wheat
+
+flix=9
+typeset -Ai wheat
+wheat=([six]=6 [foo bar]=flix )
+
+wheat[foo bar]+=7
+
+recho ${wheat[foo bar]}
+recho "${wheat[foo bar]}"
+unset flix wheat
+
+# TEST - index expansion: no word splitting or globbing
+typeset -A wheat
+cd ${TMPDIR:=/tmp}
+touch '[sfiri]'
+wheat=([s*]=6 [foo bar]=flix )
+
+recho ${wheat[@]}
+rm '[sfiri]'
+cd $OLDPWD
+
+# TEST -- associative array keys expansion
+unset wheat
+typeset -A wheat
+
+wheat=([six]=6 [foo bar]=flix )
+
+recho ${!wheat[@]}
+recho "${!wheat[@]}"
+
+# TEST -- associative array pattern removal
+unset xpath
+typeset -A xpath
+
+xpath=( [0]=/bin [one]=/bin [two]=/usr/bin [three]=/usr/ucb [four]=/usr/local/bin)
+xpath+=( [five]=/sbin [six]=/usr/sbin [seven]=. )
+
+echo ${#xpath[@]}
+
+echo ${xpath[@]}
+echo ${xpath[@]##*/}
+echo ${xpath[0]##*/}
+echo ${xpath[@]%%[!/]*}
+echo ${xpath[0]%%[!/]*}
+recho ${xpath##*/}
+recho ${xpath%%[!/]*}
+recho ${xpath[five]##*/}
+recho ${xpath[five]%%[!/]*}
+
+echo ${#xpath[*]}
+
+echo ${xpath[*]}
+echo ${xpath[*]##*/}
+echo ${xpath[*]%%[!/]*}
+
+# TEST -- associative array pattern substitution
+unset xpath
+typeset -A xpath
+
+xpath=( [0]=/bin [one]=/bin [two]=/usr/bin [three]=/usr/ucb [four]=/usr/local/bin)
+xpath+=( [five]=/sbin [six]=/usr/sbin [seven]=. )
+
+echo ${#xpath[@]}
+# default element is "0" (as a string)
+echo ${#xpath} -- ${xpath["0"]}
+
+echo ${xpath[@]//\//^}
+echo "${xpath[@]//\//^}" | cat -v
+
+zecho "${xpath[@]/\//\\}"
+zecho "${xpath[@]//\//\\}"
+zecho "${xpath[@]//[\/]/\\}"
+
+# test assignment to key "0"
+unset T
+declare -A T
+T='([a]=1)'
+echo "${T[@]}"
+unset T
+
+# peculiar ksh93 semantics for unsubscripted assoc variable reference
+declare -A T
+T[0]='zero'
+if [ "$T" != "${T[0]}" ]; then
+ echo 'assoc.tests: $T and ${T[0]} mismatch'
+fi
+
+${THIS_SH} ./assoc1.sub
+
+${THIS_SH} ./assoc2.sub
+
+${THIS_SH} ./assoc3.sub
+
+${THIS_SH} ./assoc4.sub
+
+${THIS_SH} ./assoc5.sub
+
+${THIS_SH} ./assoc6.sub
+
+${THIS_SH} ./assoc7.sub
+
+# test converting between scalars and assoc arrays
+unset assoc
+assoc=assoc
+declare -A assoc
+declare -p assoc
+echo ${assoc[@]}
+
+# weird syntax required to append to multiple existing array elements using
+# compound assignment syntax
+unset assoc
+declare -A assoc
+assoc=( [one]=one [two]=two [three]=three )
+assoc+=( [one]+=more [two]+=less )
+declare -p assoc
+
+readonly -A assoc
+declare -p assoc
+
+declare -A hash
+
+hash=(["key"]="value1")
+declare -p hash
+hash=(["key"]="${hash["key"]} value2")
+declare -p hash
+
+unset hash
+
+${THIS_SH} ./assoc8.sub
+
+# new shopt option to prevent multiple expansion of assoc array subscripts
+${THIS_SH} ./assoc9.sub
+
+${THIS_SH} ./assoc10.sub
+
+# test assigning associative arrays using compound key/value pair assignments
+${THIS_SH} ./assoc11.sub
+
+# more kvpair associative array assignment tests
+${THIS_SH} ./assoc12.sub
+
+# assignment to @ and *
+${THIS_SH} ./assoc13.sub
+
+# tests of the @k transformation on associative arrays
+${THIS_SH} ./assoc14.sub
+
+# tests with subscripts and values containing 0x01 (some indexed array tests too)
+${THIS_SH} ./assoc15.sub
+
+# tests with subscripts being expanded more than one in ${xxx} word expansions
+${THIS_SH} ./assoc16.sub
+
+# tests with `[' and `]' subscripts and `unset'
+${THIS_SH} ./assoc17.sub
+
+# tests with `[' and `]' subscripts and printf/read/wait builtins
+${THIS_SH} ./assoc18.sub
+
diff --git a/tests/assoc1.sub b/tests/assoc1.sub
new file mode 100644
index 0000000..99a6e22
--- /dev/null
+++ b/tests/assoc1.sub
@@ -0,0 +1,29 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+hash -r
+echo ${BASH_CMDS[@]}
+
+hash -p /usr/sbin/foo foo
+hash -p /usr/local/bin/qux qux
+
+echo ${!BASH_CMDS[@]}
+echo ${BASH_CMDS[@]}
+
+BASH_CMDS[blat]=/sbin/blat
+BASH_CMDS[sh]=/bin/sh
+
+hash
+
+echo ${!BASH_CMDS[@]}
+echo "${BASH_CMDS[@]}"
diff --git a/tests/assoc10.sub b/tests/assoc10.sub
new file mode 100644
index 0000000..5b21525
--- /dev/null
+++ b/tests/assoc10.sub
@@ -0,0 +1,30 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+f() { declare -a a; declare -A a; echo -n "$FUNCNAME: " ; declare -p a; }
+f
+
+f() { declare -A a; declare -a a; echo -n "$FUNCNAME: " ; declare -p a; }
+f
+
+echo
+
+f() { declare -a a; echo -n "$FUNCNAME: " ; declare -p a; }
+a=7
+f
+echo -n 'main: '; declare -p a
+
+f() { declare -A a; echo -n "$FUNCNAME: " ; declare -p a; }
+a=42
+f
+echo -n 'main: '; declare -p a
diff --git a/tests/assoc11.sub b/tests/assoc11.sub
new file mode 100644
index 0000000..9d9afae
--- /dev/null
+++ b/tests/assoc11.sub
@@ -0,0 +1,90 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# these tests were previously in array19.sub, but they are acceptable syntax now
+
+declare -A a
+declare a='(1 2 3)'
+declare -p a
+unset a
+
+declare -A foo
+
+v1='spa ces'
+v2=@
+
+foo=(a 1 b 2 c 3 d 4 )
+declare -p foo
+echo foo=\( ${foo[@]@K} \)
+
+foo=('a b' 1 "$v1" 2 "$v2" 3 'holy hell this works' 4 \\ 5)
+declare -p foo
+echo foo=\( echo ${foo[@]@K} \)
+
+foo=( "" null )
+
+foo=('a]a' abc ']' def $(echo 'foo[bar') bleh \; semicolon a=b assignment)
+declare -p foo
+echo foo=\( ${foo[@]@K} \)
+
+foo=('`' backquote '"' dquote "'" squote \\ bslash)
+declare -p foo
+echo foo=\( ${foo[@]@K} \)
+
+bar='a]=test1;#a'
+foo=( $bar 123 bar\"bie doll bar]bie doll )
+declare -p foo
+echo foo=\( ${foo[@]@K} \)
+
+func()
+{
+ declare -A inside=(a 1 b 2 c 3)
+ declare -p inside
+ echo inside=\( ${inside[@]@K} \)
+}
+func
+
+loaddict()
+{
+ dict=( '"' dquote '`' bquote "'" squote '\' bslash)
+ dict+=( '$' dol @ at * star \{ lbrace \} rbrace ? quest)
+
+ declare -p dict
+ echo dict=\( ${dict[@]@K} \)
+}
+declare -A dict
+loaddict
+
+foo=(one 1 two)
+declare -p foo
+echo foo=\( ${foo[@]@K} \)
+
+typeset -A a=( [\\]=bs [\"]=dquote [\)]=rparen [\]]=rbracket )
+echo ${a[@]}
+declare -p a
+
+echo ${a[@]@K}
+echo ${a[@]@A}
+
+eval "${a[@]@A}"
+declare -p a
+
+eval "a=( ${a[@]@K} )"
+declare -p a
+
+unset a foo
+readonly -A foo=( one 1 two 2 three 3 )
+
+export foo
+declare -p foo
+declare foo+=( seven 7 eight 8 )
diff --git a/tests/assoc12.sub b/tests/assoc12.sub
new file mode 100644
index 0000000..359dc0b
--- /dev/null
+++ b/tests/assoc12.sub
@@ -0,0 +1,74 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+foo='1 2'
+bar='3 4 5'
+xtra='20 40 80'
+
+declare -A v1=( $foo 3 )
+declare -p v1
+
+declare -A v2=( [$foo]=3 )
+declare -p v2
+
+declare -A v3
+v3=( $foo 3 )
+declare -p v3
+
+unset v1 v2 v3
+
+declare -A v1=( $foo $bar )
+declare -p v1
+
+declare -A v2=( [$foo]=$bar )
+declare -p v2
+
+declare -A v3
+v3=( $foo $bar )
+declare -p v3
+
+unset v1 v2 v3
+
+declare -A v1=( "$foo" $bar )
+declare -p v1
+
+declare -A v2=( ["$foo"]=$bar )
+declare -p v2
+
+declare -A v3
+v3=( "$foo" $bar )
+declare -p v3
+
+unset v1 v2 v3
+
+declare -A v1=( "$foo" "$bar" )
+declare -p v1
+
+declare -A v2=( ["$foo"]="$bar" )
+declare -p v2
+
+declare -A v3
+v3=( "$foo" "$bar" )
+declare -p v3
+
+v1+=( $xtra xtra )
+v2+=( "$xtra" xtra )
+v3+=( '$xtra' xtra )
+
+declare -p v1 v2 v3
+
+v1+=( [$xtra]='new xtra' )
+v2+=( ["$xtra"]='new xtra' )
+v3+=( ['$xtra']='new xtra' )
+
+declare -p v1 v2 v3
diff --git a/tests/assoc13.sub b/tests/assoc13.sub
new file mode 100644
index 0000000..7e66972
--- /dev/null
+++ b/tests/assoc13.sub
@@ -0,0 +1,44 @@
+# assignment to @ and *
+
+declare -A assoc
+key=@
+key2=*
+
+assoc[$key]=at
+assoc[$key2]=star
+assoc[!]=bang
+declare -p assoc
+
+echo ${assoc[$key]}
+echo ${assoc[$key2]}
+unset assoc
+
+declare -A a
+
+a[@]=at
+declare -p a
+
+declare -a ia
+ia[@]=garbage
+
+declare -p ia
+
+declare a[@]=at2
+declare -p a
+
+unset a ia
+
+declare -A a
+printf -v a[@] "%10s" string
+
+declare -p a
+unset a
+
+declare -A a
+declare a[$key2]=star
+declare a[@]=at
+declare a[*]=star2
+
+declare -p a
+unset a
+
diff --git a/tests/assoc14.sub b/tests/assoc14.sub
new file mode 100644
index 0000000..95df049
--- /dev/null
+++ b/tests/assoc14.sub
@@ -0,0 +1,35 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+declare -A assoc=(hello world "key with spaces" "value with spaces" one 1 foo bar)
+declare -p assoc
+
+recho "${assoc[@]}"
+recho "${assoc[@]@k}"
+
+recho "${assoc[*]}"
+recho "${assoc[*]@k}"
+
+set -- hello world "key with spaces" "value with spaces" one 1 foo bar
+recho "${@}"
+recho "${@@K}"
+recho "${@@k}"
+
+declare -A clone
+eval clone=\( "${assoc[@]@K}" \)
+declare -p clone
+
+declare -A posparams
+eval posparams=\( "${@@K}" \)
+declare -p posparams
diff --git a/tests/assoc15.sub b/tests/assoc15.sub
new file mode 100644
index 0000000..c47b153
--- /dev/null
+++ b/tests/assoc15.sub
@@ -0,0 +1,92 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# associative arrays first
+
+v=$'\x01'
+
+declare -A var foo v2
+var=( $'\x01' $'\x01\x01\x01\x01' )
+declare -p var
+v2=( $v $v$v$v$v )
+declare -p v2
+
+recho "${var[@]@k}"
+eval foo=\( "${var[@]@k}" \)
+declare -p foo
+
+var=(   )
+declare -p var
+
+recho "${var[@]@k}"
+eval foo=\( "${var[@]@k}" \)
+declare -p foo
+
+var=( []= )
+declare -p var
+
+recho "${var[@]@k}"
+eval foo=\( "${var[@]@k}" \)
+declare -p foo
+
+# now indexed arrays
+unset -v var foo
+
+declare -a var
+var=( [0]= )
+declare -p var
+
+declare -a foo
+recho "${var[@]@Q}"
+eval foo=\( "${var[@]@Q}" \)
+declare -p foo
+
+var=(  )
+declare -p var
+
+unset foo
+
+declare -a foo
+recho "${var[@]@Q}"
+eval foo=\( "${var[@]@Q}" \)
+declare -p foo
+
+# similar to array29.sub
+unset -v var foo v2
+
+declare -A var
+var=( one $'\x01\x01\x01\x01' two ab$'\001'cd )
+declare -p var
+
+pv()
+{
+ local -A foo
+ eval foo=\( "${var[@]@k}" \)
+ declare -p foo
+}
+pv
+
+pv1()
+{
+ local -A foo=( $'\x01' "${var[two]}" )
+ declare -p foo
+}
+pv1
+
+pv2()
+{
+ local -A foo=( [$'\x01']="${var[one]}" )
+ declare -p foo
+}
+pv2
diff --git a/tests/assoc16.sub b/tests/assoc16.sub
new file mode 100644
index 0000000..ae8296b
--- /dev/null
+++ b/tests/assoc16.sub
@@ -0,0 +1,56 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# bash versions up to and including bash-5.1 expanded these subscripts more
+# than once
+
+declare -A A
+
+A["Darwin"]=darjeeling
+A['$(echo Darwin ; echo stderr>&2)']=darjeeling
+
+declare -p A
+
+echo ${A[$(echo Darwin ; echo stderr>&2)]//eel/shark}
+echo ${A['$(echo Darwin ; echo stderr>&2)']//eel/shark}
+
+echo ${A[$(echo Darwin ; echo stderr>&2)]:0:4}
+echo ${A['$(echo Darwin ; echo stderr>&2)']:0:4}
+
+echo ${A[$(echo Darwin ; echo stderr>&2)]^^}
+echo ${A['$(echo Darwin ; echo stderr>&2)']^^}
+
+echo ${A[$(echo Darwin ; echo stderr>&2)]@Q}
+echo ${A['$(echo Darwin ; echo stderr>&2)']@Q}
+
+echo ${A[$(echo Darwin ; echo stderr>&2)]%ing}
+echo ${A['$(echo Darwin ; echo stderr>&2)']%ing}
+
+echo ${#A[$(echo Darwin ; echo stderr>&2)]}
+echo ${#A['$(echo Darwin ; echo stderr>&2)']}
+
+echo ${A[$(echo Darwin ; echo stderr>&2)]:-value}
+echo ${A['$(echo Darwin ; echo stderr>&2)']:-value}
+
+echo ${A[$(echo Darwin ; echo stderr>&2)]:+set}
+echo ${A['$(echo Darwin ; echo stderr>&2)']:+set}
+
+echo ${A[$(echo Darwin ; echo stderr>&2)]:+set}
+echo ${A['$(echo Darwin ; echo stderr>&2)']:+set}
+
+darjeeling=7*6
+Darwin=7*4
+
+echo $(( ${A[$(echo Darwin ; echo stderr>&2)]} ))
+echo $(( ${A['$(echo Darwin ; echo stderr>&2)']} ))
diff --git a/tests/assoc17.sub b/tests/assoc17.sub
new file mode 100644
index 0000000..a98aaa1
--- /dev/null
+++ b/tests/assoc17.sub
@@ -0,0 +1,58 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test behavior with `unset' and `[' and ']' subscripts
+
+declare -A A
+rkey=']'
+lkey='['
+
+A[$rkey]=rbracket
+A[$lkey]=lbracket
+declare -p A
+
+unset A[$rkey]
+unset A[$lkey]
+declare -p A
+
+A["$rkey"]=rbracket
+A["$lkey"]=lbracket
+declare -p A
+
+unset A["$rkey"]
+unset A["$lkey"]
+declare -p A
+
+A[\]]=rbracket
+A[\[]=lbracket
+declare -p A
+
+unset A[\]]
+unset A[\[]
+declare -p A
+
+A[']']=rbracket
+A['[']=lbracket
+declare -p A
+
+unset A[']']
+unset A['[']
+declare -p A
+
+A["]"]=rbracket
+A["["]=lbracket
+declare -p A
+
+unset A["]"]
+unset A["["]
+declare -p A
diff --git a/tests/assoc18.sub b/tests/assoc18.sub
new file mode 100644
index 0000000..0597609
--- /dev/null
+++ b/tests/assoc18.sub
@@ -0,0 +1,59 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# test behavior of builtins that can take array subscript arguments, make
+# sure they work in the presence of associative arrays and `problematic' keys
+# if assoc_expand_once is set
+#
+# affected builtins: printf, read, wait
+
+declare -A A
+rkey=']'
+lkey='['
+
+shopt -s assoc_expand_once
+
+printf -v A[$rkey] rbracket
+printf -v A[$lkey] lbracket
+declare -p A
+
+unset A[$rkey]
+unset A[$lkey]
+declare -p A
+
+unset A
+declare -A A
+
+read A[$rkey] <<<rbracket
+read A[$lkey] <<<lbracket
+declare -p A
+
+unset A[$rkey]
+unset A[$lkey]
+declare -p A
+
+unset A
+declare -A A
+
+{ sleep 1 ; exit 4; } &
+{ sleep 2 ; exit 5; } & bgpid1=$!
+{ sleep 4 ; exit 6; } &
+
+wait -p A[$rkey] -n %2 %3
+case "${A[$rkey]}" in
+$bgpid1) echo $?: ok 1;;
+*) echo bad 1;;
+esac
+
+exit 0
diff --git a/tests/assoc2.sub b/tests/assoc2.sub
new file mode 100644
index 0000000..470e2c9
--- /dev/null
+++ b/tests/assoc2.sub
@@ -0,0 +1,28 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+echo ${BASH_ALIASES[@]}
+
+alias foo=/usr/sbin/foo
+alias qux='/usr/local/bin/qux -l'
+
+echo ${!BASH_ALIASES[@]}
+recho ${BASH_ALIASES[@]}
+
+BASH_ALIASES[blat]='cd /blat ; echo $PWD'
+BASH_ALIASES[sh]='/bin/bash --login -o posix'
+
+alias -p
+
+echo ${!BASH_ALIASES[@]}
+recho "${BASH_ALIASES[@]}"
diff --git a/tests/assoc3.sub b/tests/assoc3.sub
new file mode 100644
index 0000000..a7eeb26
--- /dev/null
+++ b/tests/assoc3.sub
@@ -0,0 +1,28 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+foo()
+{
+ declare -A afoo=([six]="six" [foo bar]="foo quux")
+
+ declare -A
+ recho inside: "${afoo[@]}"
+}
+
+declare -A afoo=([main]=outside)
+echo outside: "${afoo[@]}"
+
+foo
+
+echo outside 2: "${afoo[@]}"
+
diff --git a/tests/assoc4.sub b/tests/assoc4.sub
new file mode 100644
index 0000000..eff9d0e
--- /dev/null
+++ b/tests/assoc4.sub
@@ -0,0 +1,35 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+IFS=/
+declare -A i
+
+i[0]=fooq
+i[1]=
+i[2]=barq
+i[3]=
+
+recho "${i[*]:0}"
+recho "${i[@]:0}"
+
+recho "${i[*]/q/!}"
+recho "${i[@]/q/!}"
+
+recho "${i[*]#?}"
+recho "${i[@]#?}"
+
+# Need to complete this with case-modifying expansion examples
+recho "${i[*]^?}"
+recho "${i[@]^?}"
+recho "${i[*]^^?}"
+recho "${i[@]^^?}"
diff --git a/tests/assoc5.sub b/tests/assoc5.sub
new file mode 100644
index 0000000..844d944
--- /dev/null
+++ b/tests/assoc5.sub
@@ -0,0 +1,40 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+declare -A myarray
+
+# this needs fixes to skipsubscript
+myarray["a]a"]="abc"
+
+echo ${myarray["a]a"]}
+
+myarray[$(echo ])]=def
+
+echo ${myarray[']']}
+echo ${myarray[\]]}
+
+declare myarray["foo[bar"]=bleh
+myarray["foo"]=bleh
+
+echo "${myarray[@]}"
+
+bar='a]=test1;#a'
+myarray[$bar]=123
+
+set | grep ^myarray=
+echo ${myarray[a]}
+
+echo "${myarray['a]=test1;#a']}"
+myarray['a]=test2;#a']="def"
+
+set | grep ^myarray=
diff --git a/tests/assoc6.sub b/tests/assoc6.sub
new file mode 100644
index 0000000..88b8eaf
--- /dev/null
+++ b/tests/assoc6.sub
@@ -0,0 +1,159 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+declare -A foo
+
+foo=([bar\"bie]=doll)
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+declare -p foo
+
+unset foo
+declare -A foo=(["bar\"bie"]="doll")
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+declare -p foo
+
+unset foo
+declare -A foo
+
+foo=(["bar\"bie"]="doll")
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+declare -p foo
+
+unset foo
+declare -A foo
+
+foo["bar\"bie"]="doll"
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+declare -p foo
+
+unset foo
+declare -A foo
+
+foo[bar\"bie]="doll"
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+declare -p foo
+
+unset foo
+declare -A foo
+
+foo=([bar\'bie]=doll)
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+declare -p foo
+
+unset foo
+declare -A foo=(["bar'bie"]="doll")
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+declare -p foo
+
+unset foo
+declare -A foo
+
+foo=(["bar'bie"]="doll")
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+declare -p foo
+
+unset foo
+declare -A foo
+
+foo["bar'bie"]="doll"
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+declare -p foo
+
+unset foo
+declare -A foo
+
+foo[bar\'bie]="doll"
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+declare -p foo
+
+unset foo
+declare -A foo
+
+foo=([bar\$bie]=doll)
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+declare -p foo
+
+unset foo
+declare -A foo=(["bar[bie"]="doll")
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+declare -p foo
+
+unset foo
+declare -A foo
+
+foo=(["bar\`bie"]="doll")
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+declare -p foo
+
+unset foo
+declare -A foo
+
+# this doesn't work right without the backslash
+foo["bar\]bie"]="doll"
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+declare -p foo
+
+unset foo
+declare -A foo
+
+foo[bar\${foo}bie]="doll"
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+declare -p foo
+
+unset foo
+declare -A foo
diff --git a/tests/assoc7.sub b/tests/assoc7.sub
new file mode 100644
index 0000000..cae57c5
--- /dev/null
+++ b/tests/assoc7.sub
@@ -0,0 +1,29 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# problem with bash versions through bash-4.2
+foo()
+{
+ declare -A hash
+ declare hash[baz]=bar #bash crashes here
+
+ echo ${hash[@]}
+}
+
+foo
+
+declare -a ary
+printf -v ary[0] "%b" ""
+echo "after printf"
+x="${ary[*]}" # segfaults here
+echo "after use: $?"
diff --git a/tests/assoc8.sub b/tests/assoc8.sub
new file mode 100644
index 0000000..83b43f4
--- /dev/null
+++ b/tests/assoc8.sub
@@ -0,0 +1,7 @@
+# warnings introduced beginning with bash-4.4-alpha
+
+var=foo; declare -A "arr$var=([x]=y)"
+
+key1=foo key2=bar
+
+declare -A a=([foo]='([bar]=baz)') "b=${a[$key1]}"
diff --git a/tests/assoc9.sub b/tests/assoc9.sub
new file mode 100644
index 0000000..f83ac6d
--- /dev/null
+++ b/tests/assoc9.sub
@@ -0,0 +1,159 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+typeset -A a=( [\\]= [\"]= [\)]= ) b
+for x in "${!a[@]}"; do b[$x]=; done
+b+=([\`]= [\]]=)
+typeset -p b
+for x in "${!a[@]}"; do
+ unset -v 'b[$x]'
+done
+typeset -p b
+
+unset -v a b
+
+loaddict()
+{
+ dict['"']=1
+ dict['`']=2
+ dict["'"]=3
+ dict['\']=4
+ declare -p dict
+}
+
+del()
+{
+ unset -v dict["$1"];
+}
+
+declare -A dict
+loaddict
+for k in "${!dict[@]}"; do del "$k"; done
+declare -p dict
+
+unset 'dict[@]'
+
+shopt -s assoc_expand_once
+declare -A dict
+loaddict
+for k in "${!dict[@]}"; do del "$k"; done
+declare -p dict
+
+unset a b dict
+
+typeset -A a
+b="80's"
+
+((++a[$b]))
+
+((++a["$b"]))
+[[ $((++a[$b])) ]]
+[[ $((++a["$b"])) ]]
+echo ${a["$b"]}
+echo ${a[$b]}
+
+let "++a[$b]"
+
+echo 'a[$b]=' "${a[$b]}"
+
+unset a b
+
+declare -A a
+b="80's"
+
+: ${a[$b]:='Depeche Mode'}
+
+declare -p a
+
+unset a b
+shopt -u assoc_expand_once
+
+typeset -A a
+b="80's"
+
+read a[$b] <<<"Depeche Mode"
+typeset -p a
+
+shopt -s assoc_expand_once
+read a[$b] <<<"Depeche Mode"
+typeset -p a
+
+unset a
+shopt -u assoc_expand_once
+
+typeset -A a
+
+printf -v a[$b] "%s" "Depeche Mode"
+typeset -p a
+
+shopt -s assoc_expand_once
+
+printf -v a[$b] "%s" "Depeche Mode"
+typeset -p a
+
+unset a
+
+declare -A a
+x='$(date >&2)'
+a[$x]=5
+
+shopt -s assoc_expand_once
+echo $((1+a[$x]))
+echo $((1+a[\$x]))
+echo "1+${a[$x]}"
+
+declare -p a
+
+shopt -s assoc_expand_once
+declare -A myarray
+
+declare myarray["foo[bar"]=bleh
+myarray["foo"]=bleh
+
+declare -p myarray
+
+key='$(date >&2)'
+declare -A aa
+aa[$key]=foo
+echo "${aa[$key]}"
+
+[[ -v aa[$key] ]] || echo bad assoc expansion
+
+shopt -u assoc_expand_once
+
+declare -A assoc
+
+var=x123
+assoc['$var']=value
+
+declare -p assoc
+
+unset "assoc[$var]"
+declare -p assoc
+
+unset 'assoc[$var]'
+declare -p assoc
+
+shopt -s assoc_expand_once
+unset 'assoc[$var]'
+declare -p assoc
+
+typeset -A foo
+
+foo["foo]bar"]=bip
+typeset foo["foo]bar"]=bax
+
+echo ${!foo[@]}
+echo ${foo[@]}
+
+declare -p foo
diff --git a/tests/attr.right b/tests/attr.right
new file mode 100644
index 0000000..d2d28b7
--- /dev/null
+++ b/tests/attr.right
@@ -0,0 +1,37 @@
+after f1:declare -ar a=([0]="1")
+./attr.tests: line 17: a: readonly variable
+after f2:declare -ar a=([0]="1")
+./attr.tests: line 18: a: readonly variable
+after f3:declare -ar a=([0]="1")
+./attr.tests: line 19: readonly: a: readonly variable
+after f4:declare -ar a=([0]="1")
+after f2:declare -ar b=([0]="2")
+after f3:declare -ar c=([0]="(3)")
+after f4:declare -ar d=([0]="4")
+declare -r m="4"
+in func:declare -r n="4"
+declare -r n="4"
+./attr1.sub: line 26: p: readonly variable
+declare -r p="1"
+./attr1.sub: line 32: r: readonly variable
+declare -ar r=([0]="1")
+./attr1.sub: line 36: r: readonly variable
+declare -ar r=([0]="1")
+./attr1.sub: line 40: r: readonly variable
+declare -ar r=([0]="1")
+./attr1.sub: line 44: readonly: r: readonly variable
+declare -ar r=([0]="1")
+declare -ar x=([0]="4")
+in func:declare -ar y=([0]="4")
+declare -ar y=([0]="4")
+in func:declare -ar z=([0]="4")
+declare -ar z=([0]="4")
+in func:declare -ar y1=([0]="4")
+declare -ar y1=([0]="4")
+in func:declare -ar z1=([0]="4")
+declare -ar z1=([0]="4")
+declare -x p="4"
+declare -ax r=([0]="4")
+declare -ax r=([0]="(5)")
+declare -ax r=([0]="6")
+declare -ax r=([0]="7")
diff --git a/tests/attr.tests b/tests/attr.tests
new file mode 100644
index 0000000..4874d9a
--- /dev/null
+++ b/tests/attr.tests
@@ -0,0 +1,54 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+a=(outside)
+
+f1() { readonly a=(1) ; }
+f2() { readonly -a a=(2) ; }
+f3() { readonly 'a=(3)' ; }
+f4() { readonly -a 'a=(4)' ; }
+
+f1
+echo -n after f1:
+declare -p a
+f2
+echo -n after f2:
+declare -p a
+f3
+echo -n after f3:
+declare -p a
+f4
+echo -n after f4:
+declare -p a
+
+b=(outside)
+c=(outside)
+d=(outside)
+
+f2() { readonly -a b=(2) ; }
+f3() { readonly 'c=(3)' ; }
+f4() { readonly -a 'd=(4)' ; }
+
+f2
+echo -n after f2:
+declare -p b
+f3
+echo -n after f3:
+declare -p c
+f4
+echo -n after f4:
+declare -p d
+
+${THIS_SH} ./attr1.sub
+${THIS_SH} ./attr2.sub
+
diff --git a/tests/attr1.sub b/tests/attr1.sub
new file mode 100644
index 0000000..4424be9
--- /dev/null
+++ b/tests/attr1.sub
@@ -0,0 +1,68 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+m=1
+readonly m=4
+declare -p m
+
+n=1
+f() { readonly n=4; echo -n in func: ; declare -p n ; }
+f
+declare -p n
+
+p=1
+readonly p
+
+readonly p=4
+declare -p p
+
+r=(1)
+readonly r
+
+f() { readonly r=(4) ; }
+f
+declare -p r
+
+f() { readonly r='(5)' ; }
+f
+declare -p r
+
+f() { readonly -a r=(6) ; }
+f
+declare -p r
+
+f() { readonly -a r='(7)' ; }
+f
+declare -p r
+
+x=(1)
+readonly x=(4)
+declare -p x
+
+y=(1)
+f() { readonly y=(4); echo -n in func: ; declare -p y; }
+f
+declare -p y
+
+z=(1)
+f() { readonly -a z=(4); echo -n in func: ; declare -p z; }
+f
+declare -p z
+
+f() { readonly y1=(4); echo -n in func: ; declare -p y1; }
+f
+declare -p y1
+
+f() { readonly -a z1=(4); echo -n in func: ; declare -p z1; }
+f
+declare -p z1
diff --git a/tests/attr2.sub b/tests/attr2.sub
new file mode 100644
index 0000000..dadca10
--- /dev/null
+++ b/tests/attr2.sub
@@ -0,0 +1,37 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+p=1
+export p
+
+export p=4
+declare -p p
+
+r=(1)
+export r
+
+f() { export r=(4) ; }
+f
+declare -p r
+
+f() { export r='(5)' ; }
+f
+declare -p r
+
+f() { export -a r=(6) ; }
+f
+declare -p r
+
+f() { export -a r='(7)' ; }
+f
+declare -p r
diff --git a/tests/braces.right b/tests/braces.right
new file mode 100644
index 0000000..4017546
--- /dev/null
+++ b/tests/braces.right
@@ -0,0 +1,77 @@
+ffc ffb ffa
+fdg feg ffg
+lxyz nxyz mxyz
+{abc,def}
+{abc}
+{a,b,c,d,e}
+x} y} {a} b} c}
+x,y {abc} trie
+/usr/ucb/ex /usr/ucb/edit /usr/lib/ex /usr/lib/how_ex
+XXXX{a,b,c}
+XXXXa XXXXb XXXXc
+{}
+{ }
+}
+{
+abcd{efgh
+foo 1 2 bar
+foo 1 2 bar
+foo 1 2 bar
+foobar foobaz.
+foobar foobaz
+bazx bazy
+vx vy
+bazx bazy
+1 2 3 4 5 6 7 8 9 10
+0..10 braces
+0 1 2 3 4 5 6 7 8 9 10 braces
+x0y x1y x2y x3y x4y x5y x6y x7y x8y x9y x10y xbracesy
+3
+x3y
+10 9 8 7 6 5 4 3 2 1
+10y 9y 8y 7y 6y 5y 4y 3y 2y 1y
+x10y x9y x8y x7y x6y x5y x4y x3y x2y x1y
+a b c d e f
+f e d c b a
+a ` _ ^ ] [ Z Y X W V U T S R Q P O N M L K J I H G F E D C B A
+A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ ] ^ _ ` a
+f
+{1..f}
+{f..1}
+01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20
+-1 -2 -3 -4 -5 -6 -7 -8 -9 -10
+-20 -19 -18 -17 -16 -15 -14 -13 -12 -11 -10 -9 -8 -7 -6 -5 -4 -3 -2 -1 0
+a-{bd}-c a-{be}-c
+a-{bdef-g-c a-{bdef-i-c
+{klklkl}1 {klklkl}2 {klklkl}3
+{x,x}
+1 3 5 7 9
+-1 -3 -5 -7 -9
+-1 -3 -5 -7 -9
+10 8 6 4 2
+10 8 6 4 2
+1 3 5 7 9 11 13 15 17 19
+1
+100 95 90 85 80 75 70 65 60 55 50 45 40 35 30 25 20 15 10 5 0
+100 95 90 85 80 75 70 65 60 55 50 45 40 35 30 25 20 15 10 5 0
+a b c d e f g h i j k l m n o p q r s t u v w x y z
+a c e g i k m o q s u w y
+z x v t r p n l j h f d b
+2147483645 2147483646 2147483647 2147483648 2147483649
+10 8 6 4 2 0
+10 8 6 4 2 0
+-50 -45 -40 -35 -30 -25 -20 -15 -10 -5 0
+{1..10.f}
+{1..ff}
+{1..10..ff}
+{1.20..2}
+{1..20..f2}
+{1..20..2f}
+{1..2f..2}
+{1..ff..2}
+{1..ff}
+{1..f}
+{1..0f}
+{1..10f}
+{1..10.f}
+{1..10.f}
diff --git a/tests/braces.tests b/tests/braces.tests
new file mode 100644
index 0000000..da0b624
--- /dev/null
+++ b/tests/braces.tests
@@ -0,0 +1,132 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+echo ff{c,b,a}
+echo f{d,e,f}g
+echo {l,n,m}xyz
+echo {abc\,def}
+echo {abc}
+
+echo \{a,b,c,d,e}
+echo {x,y,\{a,b,c}}
+echo {x\,y,\{abc\},trie}
+
+echo /usr/{ucb/{ex,edit},lib/{ex,how_ex}}
+
+echo XXXX\{`echo a b c | tr ' ' ','`\}
+eval echo XXXX\{`echo a b c | tr ' ' ','`\}
+
+echo {}
+echo { }
+echo }
+echo {
+echo abcd{efgh
+
+echo foo {1,2} bar
+echo `zecho foo {1,2} bar`
+echo $(zecho foo {1,2} bar)
+
+var=baz
+varx=vx
+vary=vy
+
+echo foo{bar,${var}.}
+echo foo{bar,${var}}
+
+echo "${var}"{x,y}
+echo $var{x,y}
+echo ${var}{x,y}
+
+unset var varx vary
+
+# new sequence brace operators
+echo {1..10}
+
+# this doesn't work yet
+echo {0..10,braces}
+# but this does
+echo {{0..10},braces}
+echo x{{0..10},braces}y
+
+echo {3..3}
+echo x{3..3}y
+echo {10..1}
+echo {10..1}y
+echo x{10..1}y
+
+echo {a..f}
+echo {f..a}
+
+echo {a..A}
+echo {A..a}
+
+echo {f..f}
+
+# mixes are incorrectly-formed brace expansions
+echo {1..f}
+echo {f..1}
+
+echo 0{1..9} {10..20}
+
+# do negative numbers work?
+echo {-1..-10}
+echo {-20..0}
+
+# weirdly-formed brace expansions -- fixed in post-bash-3.1
+echo a-{b{d,e}}-c
+
+echo a-{bdef-{g,i}-c
+
+echo {"klklkl"}{1,2,3}
+echo {"x,x"}
+
+echo {1..10..2}
+echo {-1..-10..2}
+echo {-1..-10..-2}
+
+echo {10..1..-2}
+echo {10..1..2}
+
+echo {1..20..2}
+echo {1..20..20}
+
+echo {100..0..5}
+echo {100..0..-5}
+
+echo {a..z}
+echo {a..z..2}
+echo {z..a..-2}
+
+# make sure brace expansion handles ints > 2**31 - 1 using intmax_t
+echo {2147483645..2147483649}
+
+# unwanted zero-padding -- fixed post-bash-4.0
+echo {10..0..2}
+echo {10..0..-2}
+echo {-50..-0..5}
+
+# bad
+echo {1..10.f}
+echo {1..ff}
+echo {1..10..ff}
+echo {1.20..2}
+echo {1..20..f2}
+echo {1..20..2f}
+echo {1..2f..2}
+echo {1..ff..2}
+echo {1..ff}
+echo {1..f}
+echo {1..0f}
+echo {1..10f}
+echo {1..10.f}
+echo {1..10.f}
diff --git a/tests/builtins.right b/tests/builtins.right
new file mode 100644
index 0000000..4f51d43
--- /dev/null
+++ b/tests/builtins.right
@@ -0,0 +1,281 @@
+1000
+a
+end-1
+a
+end-2
+a:x
+end-a
+b:x
+end-b
+c:x
+end-c
+end-3
+a:x
+end
+a
+b
+c
+end-1
+a
+b
+c
+end-2
+a:x
+a:y
+a:z
+end-a
+b:x
+b:y
+b:z
+end-b
+c:x
+c:y
+c:z
+end-c
+end-3
+a:x
+b:x
+c:x
+end
+$BVAR
+$BVAR
+$BVAR
+$BVAR
+foo
+bar
+xxx
+0022
+u=rwx,g=rx,o=rx
+0002
+u=rwx,g=rwx,o=rx
+umask 0002
+umask -S u=rwx,g=rwx,o=rx
+u=rwx,g=rwx,o=rwx
+enable .
+enable :
+enable break
+enable continue
+enable eval
+enable exec
+enable exit
+enable export
+enable readonly
+enable return
+enable set
+enable shift
+enable source
+enable times
+enable trap
+enable unset
+enable .
+enable :
+enable break
+enable continue
+enable eval
+enable exec
+enable exit
+enable export
+enable readonly
+enable return
+enable set
+enable shift
+enable source
+enable times
+enable trap
+enable unset
+enable -n test worked
+enable test worked
+specialname
+-specialname
+FOO=BAR
+FOO=BAR
+hash: hash table empty
+0
+AVAR
+foo
+in source.sub2, calling return
+5
+a b c
+a b c
+x y z
+a b c
+a b c
+m n o p
+a b c
+m n o p
+/tmp/bash-dir-a
+/tmp/bash-dir-a
+/tmp/bash-dir-a
+./source5.sub: line 23: /tmp/source-notthere: No such file or directory
+after bad source 1
+./source5.sub: line 30: /tmp/source-notthere: No such file or directory
+one - OK
+0
+0
+two - OK
+0
+three - OK
+0
+four - OK
+0
+abc
+def
+ghi
+after
+one.1 subshell
+two.1 subshell
+three.1 subshell
+four.1 subshell
+one.2 subshell
+two.2 subshell
+three.2 subshell
+four.2 subshell
+x29 - done
+abc
+def
+ghi
+ok
+AVAR
+foo
+foo
+AVAR
+foo
+foo
+AVAR
+foo
+declare -x foo=""
+declare -x FOO="\$\$"
+./builtins.tests: line 228: declare: FOO: not found
+declare -x FOO="\$\$"
+ok
+ok
+./builtins.tests: line 260: kill: 4096: invalid signal specification
+1
+a\n\n\nb
+a
+
+
+b
+before: f = 4
+inside
+after: f = 8 bar = 4
+declare -a c
+declare -A d
+declare -a c=([0]="4")
+declare -A c=([0]="4" )
+declare -a c=([0]="1" [1]="2" [2]="3")
+declare -A c=([two]="2" [three]="3" [one]="1" )
+declare -a c=([0]="1" [1]="2" [2]="3")
+declare -a c=([0]="1" [1]="2" [2]="3")
+unset
+unset
+assoc 1 unset
+array 1 unset
+assoc 2 unset
+array 2 unset
+unset1
+unset2
+1
+1
+1
+1
+0
+0
+assoc A unset
+array a
+assoc A
+array a
+assoc B unset
+array b unset
+assoc B unset
+array b unset
+scalar 1
+scalar 2
+scalar 3 unset
+argv[1] = <one two three>
+assoc: 3
+array: 3
+scalar: 13
+scalar: 1
+scalar: 0
+scalar: 1
+scalar: 0
+scalar: 0
+all set:
+one
+two
+f1 ()
+{
+ echo f1
+}
+f2 ()
+{
+ echo f2
+}
+all unset:
+unset1
+unset2
+./builtins6.sub: line 41: declare: f1: not found
+./builtins6.sub: line 41: declare: f2: not found
+all reset:
+one-one
+two-one
+f1 ()
+{
+ echo f1
+}
+f2 ()
+{
+ echo f2
+}
+vars unset:
+unset1
+unset2
+f1 ()
+{
+ echo f1
+}
+f2 ()
+{
+ echo f2
+}
+funcs unset:
+one-two
+two-two
+bash: line 1: notthere: No such file or directory
+one
+bash: line 1: notthere: No such file or directory
+two
+bash: line 1: .: notthere: file not found
+one
+bash: line 1: .: notthere: file not found
+0
+0
+0
+0
+argv[1] = <one>
+0
+argv[1] = <two>
+0
+three
+0
+four
+0
+./builtins7.sub: line 19: : command not found
+127
+0
+./builtins7.sub: line 27: notthere: No such file or directory
+after 1
+./builtins7.sub: line 28: notthere: No such file or directory
+after 2
+type is a shell builtin
++ command -v type
+type
++ command command -v type
+type
++ command -p command -v type
+type
++ command -p -- command -v type
+type
++ set +x
+./builtins.tests: line 284: exit: status: numeric argument required
diff --git a/tests/builtins.tests b/tests/builtins.tests
new file mode 100644
index 0000000..8eee43e
--- /dev/null
+++ b/tests/builtins.tests
@@ -0,0 +1,286 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# tests for miscellaneous builtins not tested elsewhere
+set +p
+set +o posix
+
+ulimit -S -c 0 2>/dev/null
+ulimit -c -S -- 1000 2>/dev/null
+ulimit -c 2>/dev/null
+
+# check that break breaks loops
+for i in a b c; do echo $i; break; echo bad-$i; done
+echo end-1
+for i in a b c; do echo $i; break 1; echo bad-$i; done
+echo end-2
+for i in a b c; do
+ for j in x y z; do
+ echo $i:$j
+ break
+ echo bad-$i
+ done
+ echo end-$i
+done
+echo end-3
+
+# check that break breaks nested loops
+for i in a b c; do
+ for j in x y z; do
+ echo $i:$j
+ break 2
+ echo bad-$i
+ done
+ echo end-$i
+done
+echo end
+
+# check that continue continues loops
+for i in a b c; do echo $i; continue; echo bad-$i ; done
+echo end-1
+for i in a b c; do echo $i; continue 1; echo bad-$i; done
+echo end-2
+for i in a b c; do
+ for j in x y z; do
+ echo $i:$j
+ continue
+ echo bad-$i-$j
+ done
+ echo end-$i
+done
+echo end-3
+
+# check that continue breaks out of nested loops
+for i in a b c; do
+ for j in x y z; do
+ echo $i:$j
+ continue 2
+ echo bad-$i-$j
+ done
+ echo end-$i
+done
+echo end
+
+# check that `eval' re-evaluates arguments, but `builtin' and `command' do not
+AVAR='$BVAR'
+BVAR=foo
+
+echo $AVAR
+builtin echo $AVAR
+command echo $AVAR
+eval echo \$AVAR
+eval echo $AVAR
+
+# test out eval with a temp environment
+AVAR=bar eval echo \$AVAR
+BVAR=xxx eval echo $AVAR
+
+unset -v AVAR BVAR
+
+# test umask
+mask=$(umask)
+umask 022
+umask
+umask -S
+umask -S u=rwx,g=rwx,o=rx >/dev/null # 002
+umask
+umask -S
+umask -p
+umask -p -S
+umask 0
+umask -S
+umask ${mask} # restore original mask
+
+# builtin/command without arguments should do nothing. maybe someday they will
+builtin
+command
+
+# test enable
+enable -ps
+
+enable -aps ; enable -nps
+
+enable -n test
+case "$(type -t test)" in
+builtin) echo oops -- enable -n test failed ;;
+*) echo enable -n test worked ;;
+esac
+
+enable test
+case "$(type -t test)" in
+builtin) echo enable test worked ;;
+*) echo oops -- enable test failed ;;
+esac
+
+# test options to exec
+(exec -a specialname ${THIS_SH} -c 'echo $0' )
+(exec -l -a specialname ${THIS_SH} -c 'echo $0' )
+# test `clean' environment. if /bin/sh is bash, and the script version of
+# printenv is run, there will be variables in the environment that bash
+# sets on startup. Also test code that prefixes argv[0] with a dash.
+(export FOO=BAR ; exec -c -l printenv ) | grep FOO
+(FOO=BAR exec -c printenv ) | grep FOO
+
+(export FOO=BAR ; exec printenv ) | grep FOO
+(FOO=BAR exec printenv ) | grep FOO
+
+# ok, forget everything about hashed commands
+hash -r
+hash
+
+# this had better succeed, since command -p guarantees we will find the
+# standard utilities
+command -p hash rm
+
+# check out source/.
+
+# sourcing a zero-length-file had better not be an error
+rm -f /tmp/zero-length-file
+cp /dev/null /tmp/zero-length-file
+. /tmp/zero-length-file
+echo $?
+rm /tmp/zero-length-file
+
+AVAR=AVAR
+
+. ./source1.sub
+AVAR=foo . ./source1.sub
+
+. ./source2.sub
+echo $?
+
+set -- a b c
+. ./source3.sub
+
+# make sure source with arguments does not change the shell's positional
+# parameters, but that the sourced file sees the arguments as its
+# positional parameters
+echo "$@"
+. ./source3.sub x y z
+echo "$@"
+
+# but if the sourced script sets the positional parameters explicitly, they
+# should be reflected in the calling shell's positional parameters. this
+# also tests one of the shopt options that controls source using $PATH to
+# find the script
+echo "$@"
+shopt -u sourcepath
+. source4.sub
+echo "$@"
+
+# this is complicated when the sourced scripts gets its own positional
+# parameters from arguments to `.'
+set -- a b c
+echo "$@"
+. source4.sub x y z
+echo "$@"
+
+# test out cd and $CDPATH
+${THIS_SH} ./builtins1.sub
+
+# test behavior of `.' when given a non-existent file argument
+${THIS_SH} ./source5.sub
+
+# test bugs in sourcing non-regular files, fixed post-bash-3.2
+${THIS_SH} ./source6.sub
+
+# test bugs with source called from multiline aliases and other contexts
+${THIS_SH} ./source7.sub
+
+# in posix mode, assignment statements preceding special builtins are
+# reflected in the shell environment. `.' and `eval' need special-case
+# code.
+set -o posix
+echo $AVAR
+AVAR=foo . ./source1.sub
+echo $AVAR
+
+AVAR=AVAR
+echo $AVAR
+AVAR=foo eval echo \$AVAR
+echo $AVAR
+
+AVAR=AVAR
+echo $AVAR
+AVAR=foo :
+echo $AVAR
+set +o posix
+
+# but assignment statements preceding `export' are always reflected in
+# the environment
+foo="" export foo
+declare -p foo
+unset foo
+
+# assignment statements preceding `declare' should be displayed correctly,
+# but not persist after the command
+FOO='$$' declare -p FOO
+declare -p FOO
+unset FOO
+
+# except for `declare -x', which should be equivalent to `export'
+FOO='$$' declare -x FOO
+declare -p FOO
+unset FOO
+
+# test out kill -l. bash versions prior to 2.01 did `kill -l num' wrong
+sigone=$(kill -l | sed -n 's:^ 1) *\([^ ]*\)[ ].*$:\1:p')
+
+case "$(kill -l 1)" in
+${sigone/SIG/}) echo ok;;
+*) echo oops -- kill -l failure;;
+esac
+
+# kill -l and trap -l should display exactly the same output
+sigonea=$(trap -l | sed -n 's:^ 1) *\([^ ]*\)[ ].*$:\1:p')
+
+if [ "$sigone" != "$sigonea" ]; then
+ echo oops -- kill -l and trap -l differ
+fi
+
+# POSIX.2 says that exit statuses > 128 are mapped to signal names by
+# subtracting 128 so you can find out what signal killed a process
+case "$(kill -l $(( 128 + 1)) )" in
+${sigone/SIG/}) echo ok;;
+*) echo oops -- kill -l 129 failure;;
+esac
+
+# out-of-range signal numbers should report the argument in the error
+# message, not 128 less than the argument
+kill -l 4096
+
+# kill -l NAME should return the signal number
+kill -l ${sigone/SIG/}
+
+# test behavior of shopt xpg_echo
+${THIS_SH} ./builtins2.sub
+
+# test behavior of declare -g
+${THIS_SH} ./builtins3.sub
+
+# test behavior of using declare to create variables without assigning values
+${THIS_SH} ./builtins4.sub
+
+# test behavior of set and unset array variables
+${THIS_SH} ./builtins5.sub
+
+# test behavior of unset builtin with -f and -v options
+${THIS_SH} ./builtins6.sub
+
+# test behavior of command builtin after changing it to a pseudo-keyword
+${THIS_SH} ./builtins7.sub
+
+# this must be last -- it is a fatal error
+exit status
+
+echo after bad exit
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/builtins3.sub b/tests/builtins3.sub
new file mode 100644
index 0000000..5596c56
--- /dev/null
+++ b/tests/builtins3.sub
@@ -0,0 +1,14 @@
+# declare -g added in bash-4.2
+f=4
+
+foo()
+{
+ declare -g f=8
+ declare -g bar=4
+
+ echo inside
+}
+
+echo before: f = $f
+foo
+echo after: f = $f bar = $bar
diff --git a/tests/builtins4.sub b/tests/builtins4.sub
new file mode 100644
index 0000000..058ee2c
--- /dev/null
+++ b/tests/builtins4.sub
@@ -0,0 +1,57 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+declare -a c
+declare -p c
+
+declare -A d
+declare -p d
+unset c d
+
+declare -a c
+c=4
+declare -p c
+unset c
+
+declare -A c
+c=4
+declare -p c
+unset c
+
+declare -a c
+c=(1 2 3)
+declare -p c
+unset c
+
+declare -A c
+c=([one]=1 [two]=2 [three]=3)
+declare -p c
+unset c
+
+declare -a c
+read -a c < <(echo 1 2 3)
+declare -p c
+unset c
+
+declare -a c
+mapfile -t c < <(echo 1$'\n'2$'\n'3)
+declare -p c
+unset c
+
+unset foo
+declare -A foo
+echo ${foo-unset}
+
+unset foo
+declare -a foo
+echo ${foo-unset}
diff --git a/tests/builtins5.sub b/tests/builtins5.sub
new file mode 100644
index 0000000..4fcf793
--- /dev/null
+++ b/tests/builtins5.sub
@@ -0,0 +1,83 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# a start at a test suite for what it means for an array to be set or unset and
+# how to test that state
+typeset -A A
+A[a]=1
+typeset -a a
+a[1]=1
+
+if [ -v A ]; then echo assoc 1; else echo assoc 1 unset; fi
+if [ -v a ]; then echo array 1; else echo array 1 unset; fi
+
+if [ -v "${A[@]}" ]; then echo assoc 2; else echo assoc 2 unset; fi
+if [ -v "${a[@]}" ]; then echo array 2; else echo array 2 unset; fi
+
+echo ${A-unset1}
+echo ${a-unset2}
+
+echo ${A[@]-unset3}
+echo ${a[@]-unset4}
+
+echo ${#A[@]}
+echo ${#a[@]}
+
+typeset -A B
+typeset -a b
+
+echo ${#B[@]}
+echo ${#b[@]}
+
+scalar1=foo
+scalar2=
+
+# this now checks for A[@] treating @ as a valid key - post-bash-5.1
+if [ -v A[@] ]; then echo assoc A; else echo assoc A unset; fi
+if [ -v a[@] ]; then echo array a; else echo array a unset; fi
+
+if [ ${#A[@]} -gt 0 ]; then echo assoc A; else echo assoc A unset; fi
+if [ ${#a[@]} -gt 0 ]; then echo array a; else echo array a unset; fi
+
+if [ -v B[@] ]; then echo assoc B; else echo assoc B unset; fi
+if [ -v b[@] ]; then echo array b; else echo array b unset; fi
+
+if [ ${#B[@]} -gt 0 ]; then echo assoc B; else echo assoc B unset; fi
+if [ ${#b[@]} -gt 0 ]; then echo array b; else echo array b unset; fi
+
+if [ -v scalar1[@] ]; then echo scalar 1; else echo scalar 1 unset; fi
+if [ -v scalar2[@] ]; then echo scalar 2; else echo scalar 2 unset; fi
+if [ -v scalar3[@] ]; then echo scalar 3; else echo scalar 3 unset; fi
+
+unset a A
+declare -A assoc=([one]=one [two]=two [three]=three)
+declare -a array=(one two three)
+
+scalar="one two three"
+scalar2=
+
+recho "${scalar[@]}"
+
+echo assoc: ${#assoc[@]}
+echo array: ${#array[@]}
+
+echo scalar: ${#scalar}
+echo scalar: ${#scalar[@]}
+
+echo scalar: ${#scalar2}
+echo scalar: ${#scalar2[@]}
+
+echo scalar: ${#scalar3}
+echo scalar: ${#scalar3[@]}
+
+
diff --git a/tests/builtins6.sub b/tests/builtins6.sub
new file mode 100644
index 0000000..d4fdf4a
--- /dev/null
+++ b/tests/builtins6.sub
@@ -0,0 +1,81 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+f1()
+{
+ echo f1
+}
+
+f2()
+{
+ echo f2
+}
+
+v1=one
+v2=two
+
+echo all set:
+
+echo ${v1-unset1}
+echo ${v2-unset2}
+
+declare -f -p f1 f2
+
+unset v1 f1 v2 f2
+
+echo all unset:
+
+echo ${v1-unset1}
+echo ${v2-unset2}
+
+declare -f -p f1 f2
+
+f1()
+{
+ echo f1
+}
+
+f2()
+{
+ echo f2
+}
+
+v1=one-one
+v2=two-one
+
+echo all reset:
+echo ${v1-unset1}
+echo ${v2-unset2}
+
+declare -f -p f1 f2
+
+unset -v v1 f1 v2 f2
+
+echo vars unset:
+
+echo ${v1-unset1}
+echo ${v2-unset2}
+
+declare -f -p f1 f2
+
+v1=one-two
+v2=two-two
+
+unset -f v1 f1 v2 f2
+
+echo funcs unset:
+
+echo ${v1-unset1}
+echo ${v2-unset2}
+
+declare -f f1 f2
diff --git a/tests/builtins7.sub b/tests/builtins7.sub
new file mode 100644
index 0000000..67e5e61
--- /dev/null
+++ b/tests/builtins7.sub
@@ -0,0 +1,38 @@
+: ${THIS_SH:=./bash}
+
+${THIS_SH} -c 'command . notthere ; echo one' bash
+${THIS_SH} -c '. notthere ; echo two' bash
+
+${THIS_SH} -o posix -c 'command . notthere ; echo one' bash
+${THIS_SH} -o posix -c '. notthere ; echo two' bash
+
+command ; echo $?
+command -- ; echo $?
+command -p ; echo $?
+command -p -- ; echo $?
+
+command recho one; echo $?
+command -- recho two; echo $?
+command -p echo three; echo $?
+command -p -- echo four ; echo $?
+
+command ''
+echo $?
+
+command -p
+echo $?
+
+${THIS_SH} -c 'set -e ; command false ; echo after' bash
+
+command command command -p . notthere ; echo after 1
+command -p command command . notthere ; echo after 2
+
+command -p command -V type
+
+set -x
+command -v type
+command command -v type
+command -p command -v type
+command -p -- command -v type
+set +x
+
diff --git a/tests/case.right b/tests/case.right
new file mode 100644
index 0000000..d33c8c5
--- /dev/null
+++ b/tests/case.right
@@ -0,0 +1,63 @@
+fallthrough
+to here
+and here
+retest
+and match
+no more clauses
+1.0
+./case.tests: line 42: xx: readonly variable
+1.1
+matches 1
+no
+no
+no
+no
+no
+ok
+esac
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+ok 6
+ok 7
+ok 8
+ok 9
+mysterious 1
+mysterious 2
+argv[1] = <\a\b\c\^A\d\e\f>
+argv[1] = <\a\b\c\^A\d\e\f>
+argv[1] = <abc^Adef>
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+ok 6
+ok 7
+ok 8
+--- testing: soh
+ok1ok2ok3ok4ok5
+ok1ok2ok3ok4ok5
+ok1ok2ok3ok4ok5
+ok1ok2ok3ok4ok5
+ok1ok2ok3ok4ok5
+ok1ok2ok3ok4ok5
+ok1ok2ok3ok4ok5
+--- testing: stx
+ok1ok2ok3ok4ok5
+ok1ok2ok3ok4ok5
+ok1ok2ok3ok4ok5
+ok1ok2ok3ok4ok5
+ok1ok2ok3ok4ok5
+ok1ok2ok3ok4ok5
+ok1ok2ok3ok4ok5
+--- testing: del
+ok1ok2ok3ok4ok5
+ok1ok2ok3ok4ok5
+ok1ok2ok3ok4ok5
+ok1ok2ok3ok4ok5
+ok1ok2ok3ok4ok5
+ok1ok2ok3ok4ok5
+ok1ok2ok3ok4ok5
diff --git a/tests/case.tests b/tests/case.tests
new file mode 100644
index 0000000..7ad4c68
--- /dev/null
+++ b/tests/case.tests
@@ -0,0 +1,73 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+case foo in
+bar) echo skip ;;
+foo) echo fallthrough ;&
+bax) echo to here ;&
+qux) echo and here;;
+fop) echo but not here;;
+esac
+
+case foobar in
+bar) echo skip ;;
+foo*) echo retest ;;&
+*bar) echo and match ;;&
+qux) echo but not this ;;
+esac
+
+case a in
+a) echo no more clauses;&
+esac
+
+x=0 y=1
+case 1 in
+ $((y=0)) ) ;;
+ $((x=1)) ) ;&
+ $((x=2)) ) echo $x.$y ;;
+esac
+
+unset x
+readonly xx=1
+case 1 in $((xx++)) ) echo hi1 ;; *) echo hi2; esac
+echo ${xx}.$?
+
+unset var empty
+
+var=
+case ']' in
+[$var]*[$var]) echo matches 1;;
+*) echo no match 1 ;;
+esac
+
+case abc in ( [] ) echo yes ;; ( * ) echo no ;; esac
+empty=''
+case abc in ( ["$empty"] ) echo yes ;; ( * ) echo no ;; esac
+
+case abc in ( [] | [!a-z]* ) echo yes ;; ( * ) echo no ;; esac
+empty=''
+case abc in ( ["$empty"] | [!a-z]* ) echo yes ;; ( * ) echo no ;; esac
+
+case abc in (["$empty"]|[!a-z]*) echo yes ;; (*) echo no ;; esac
+
+case " " in ( [" "] ) echo ok;; ( * ) echo no;; esac
+
+# posix issue discovered after bash-5.1 was released
+case esac in (esac) echo esac;; esac
+case k in else|done|time|esac) for f in 1 2 3 ; do :; done esac
+
+# tests of quote removal and pattern matching
+${THIS_SH} ./case1.sub
+${THIS_SH} ./case2.sub
+${THIS_SH} ./case3.sub
+${THIS_SH} ./case4.sub
diff --git a/tests/case1.sub b/tests/case1.sub
new file mode 100644
index 0000000..8077111
--- /dev/null
+++ b/tests/case1.sub
@@ -0,0 +1,77 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+x='\x'
+
+case x in
+\x) echo ok 1;;
+*) echo bad 1;;
+esac
+
+case x in
+$x) echo ok 2;;
+*) echo bad 2;;
+esac
+
+case $x in
+\x) echo bad 3;;
+\\x) echo ok 3 ;;
+*) echo bad 3.1 ;;
+esac
+
+case $x in
+\\$x) echo ok 4 ;;
+x) echo bad 4;;
+$x) echo bad 4.1 ;;
+*) echo bad 4.2;;
+esac
+
+case x in
+\\x) echo bad 5;;
+\x) echo ok 5;;
+*) echo bad 5.1;;
+esac
+
+case x in
+\\x) echo bad 6;;
+x) echo ok 6;;
+*) echo bad 6.1;;
+esac
+
+case x in
+$x) echo ok 7 ;;
+\\$x) echo bad 7 ;;
+*) echo bad 7.1 ;;
+esac
+
+case x in
+\x) echo ok 8 ;;
+\\x) echo bad 8 ;;
+*) echo bad 8.1 ;;
+esac
+
+case \x in
+\x) echo ok 9 ;;
+\\x) echo bad 9 ;;
+*) echo bad 9.1 ;;
+esac
+
+case $x in
+$x) echo oops 1 ;;
+*) echo mysterious 1 ;;
+esac
+
+case \x in
+\x) echo mysterious 2 ;;
+*) echo oops 2 ;;
+esac
diff --git a/tests/case2.sub b/tests/case2.sub
new file mode 100644
index 0000000..6c3be38
--- /dev/null
+++ b/tests/case2.sub
@@ -0,0 +1,65 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+x=$'\\a\\b\\c\\\001\\d\\e\\f'
+y='\a\b\c\\d\e\f'
+z=$'abc\001def'
+
+recho "$x"
+recho "$y"
+recho "$z"
+
+case $'abc\001def' in
+$x) echo ok 1 ;;
+*) echo oops 1;;
+esac
+
+case $z in
+$x) echo ok 2 ;;
+*) echo oops 2;;
+esac
+
+case $'abc\001def' in
+$y) echo ok 3 ;;
+*) echo oops 3;;
+esac
+
+case $z in
+$y) echo ok 4 ;;
+*) echo oops 4;;
+esac
+
+# no backslash before \001
+x=$'\\a\\b\\c\001\\d\\e\\f'
+y='\a\b\c\d\e\f'
+
+case $'abc\001def' in
+$x) echo ok 5 ;;
+*) echo oops 5;;
+esac
+
+case $z in
+$x) echo ok 6 ;;
+*) echo oops 6;;
+esac
+
+case $'abc\001def' in
+$y) echo ok 7 ;;
+*) echo oops 7;;
+esac
+
+case $z in
+$y) echo ok 8 ;;
+*) echo oops 8;;
+esac
+
diff --git a/tests/case3.sub b/tests/case3.sub
new file mode 100644
index 0000000..1e8d785
--- /dev/null
+++ b/tests/case3.sub
@@ -0,0 +1,52 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+testmatch() {
+ case $1 in
+ ( $2 ) printf ok1 ;;
+ ( * ) printf fail1 ;;
+ esac
+ case $1,$2 in
+ ( $2,"$2" ) printf ok2 ;;
+ ( * ) printf fail2 ;;
+ esac
+ case $1, in
+ ( $2, ) printf ok3 ;;
+ ( * ) printf fail3 ;;
+ esac
+ case ,$2 in
+ ( ,"$2" ) printf ok4 ;;
+ ( * ) printf fail4 ;;
+ esac
+ case "$1,$2" in
+ ( $2,"$2" ) printf ok5 ;;
+ ( * ) printf fail5 ;;
+ esac
+ echo
+}
+
+for c in $'\1' $'\2' $'\177'; do
+ echo -n "--- testing: "
+ echo "$c" | od -t a | awk 'NR==1 { print $2 } '
+ testmatch "${c}" "\\${c}"
+ testmatch "${c}x" "\\${c}\\x" # bash-git fails case 2 and 5 for $'\1'
+ testmatch "${c}x" "${c}\\x"
+ testmatch "${c}x" "${c}x"
+ testmatch "${c}x" "\\${c}x"
+ testmatch "x${c}" "\\x\\${c}"
+ testmatch "x${c}" "x\\${c}"
+done
+
+match() { case $1 in ( $2 ) ;; ( * ) return 1 ;; esac; }
+match $'? *x\1y\177z' $'??\\*\\x\\\1\\y\\\177\\z' || echo bad 6
diff --git a/tests/case4.sub b/tests/case4.sub
new file mode 100644
index 0000000..ababeb9
--- /dev/null
+++ b/tests/case4.sub
@@ -0,0 +1,38 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+shopt -s -o posix
+two="t w o"
+ten="t e
+n"
+set 1 "$two" 3 4 5 6 7 8 9 "$ten"
+
+unset IFS
+expvar="$*"
+case $* in
+"$expvar") ;;
+*) echo "failed 1" ;;
+esac
+
+case $* in
+$expvar) ;;
+*) echo "failed 2" ;;
+esac
+
+alias foo='oneword'
+foo_word='foo'
+case "$foo_word"
+in
+ foo) ;;
+ *) echo failed 3;;
+esac
diff --git a/tests/casemod.right b/tests/casemod.right
new file mode 100644
index 0000000..df12475
--- /dev/null
+++ b/tests/casemod.right
@@ -0,0 +1,47 @@
+Acknowledgement
+ACKNOWLEDGEMENT
+Oenophile
+OEnOphIlE
+aCKNOWLEDGEMENT
+acknowledgement
+oENOPHILE
+oENOPHILE
+oeNoPHiLe
+Acknowledgement Oenophile
+AcknOwlEdgEmEnt OEnOphIlE
+aCKNOWLEDGEMENT oENOPHILE
+aCKNoWLeDGeMeNT oeNoPHiLe
+aCKNOWLEDGEMENT oENOPHILE
+acknowledgement oenophile
+Oenophile Acknowledgement
+OENOPHILE ACKNOWLEDGEMENT
+Oenophile Acknowledgement
+OEnOphIlE AcknOwlEdgEmEnt
+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
+abcdexyz
+ABCDEXYZ
diff --git a/tests/casemod.tests b/tests/casemod.tests
new file mode 100644
index 0000000..56ab20d
--- /dev/null
+++ b/tests/casemod.tests
@@ -0,0 +1,126 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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^^}
+
+M1=${S1^^[aeiou]}
+M2=${U2,,[AEIOU]}
+
+#echo ${M1} ${M1~}
+#echo ${M2} ${M2~~}
+
+declare -l lower=aBcDe
+lower+=XyZ
+echo $lower
+
+declare -u upper=aBcDe
+upper+=xYZ
+echo $upper
diff --git a/tests/complete.right b/tests/complete.right
new file mode 100644
index 0000000..c8bf1dc
--- /dev/null
+++ b/tests/complete.right
@@ -0,0 +1,63 @@
+complete -f -X '!*.+(ps|PS)' gs
+complete -e printenv
+complete -f -X '!*.texi*' texi2html
+complete -g groupmod
+complete -v -S '=' typeset
+complete -c nohup
+complete -a unalias
+complete -g groupdel
+complete -A hostname telnet
+complete -v -S '=' local
+complete -v -S '=' readonly
+complete -o bashdefault -o filenames -o nospace -F _comp_cd cd
+complete -c type
+complete -f ln
+complete -f -X '!*.+(gz|tgz)' gunzip
+complete -f -X '!*.texi*' makeinfo
+complete -j -P '%' jobs
+complete -o dirnames -o filenames -o nospace -d pushd
+complete -f -X '!*.pdf' acroread
+complete -v unset
+complete -f -X '!*.+(ps|PS)' ghostview
+complete -A hostname rsh
+complete -c exec
+complete -A signal kill
+complete -c eval
+complete -f chown
+complete -f gzip
+complete -W '"${GROUPS[@]}"' newgrp
+complete -A shopt shopt
+complete -A hostname ftp
+complete -A hostname rlogin
+complete -v getopts
+complete -c nice
+complete -c gdb
+complete -j -P '%' fg
+complete -f -X '!*.dvi' dvips
+complete -f -X '!*.texi*' texi2dvi
+complete -f .
+complete -v -S '=' declare
+complete -v -S '=' export
+complete -f -X '!*.dvi' xdvi
+complete -u su
+complete -o dirnames -o filenames -o nospace -d popd
+complete -A signal trap
+complete -j -W '$(ps -x | tail +2 | cut -c1-5)' -P '%' wait
+complete -f -X '!*.Z' zmore
+complete -j -P '%' disown
+complete -f -X '!*.+(ps|PS)' gs
+complete -f -X '!*.+(ps|PS)' gv
+complete -f source
+complete -c make
+complete -A stopped -P '%' bg
+complete -f cat
+complete -d mkdir
+complete -A helptopic help
+complete -v read
+complete -c -k time
+complete -f -X '!*.Z' zcat
+complete -f -X '!*.Z' uncompress
+complete -d rmdir
+complete -f more
+complete -f -X '!*.+(gz|tgz)' gzcat
+./complete.tests: line 123: complete: notthere: no completion specification
diff --git a/tests/complete.tests b/tests/complete.tests
new file mode 100644
index 0000000..36a3983
--- /dev/null
+++ b/tests/complete.tests
@@ -0,0 +1,126 @@
+# Chet Ramey <chet.ramey@case.edu>
+#
+# Copyright 2002-2020 Chester Ramey
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# TThis program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+complete
+
+# from zsh, just for testing
+complete -A stopped -P '%' bg
+complete -j -P '%' fg jobs disown
+# this is wrong at this point
+complete -j -P '%' -W '$(ps -x | tail +2 | cut -c1-5)' wait
+complete -c type
+complete -a unalias
+complete -v getopts read unset
+complete -v -S '=' declare export local readonly typeset
+complete -f -- . source
+complete -A shopt shopt
+complete -e printenv
+
+complete -A helptopic help
+
+complete -c nohup exec nice eval
+complete -c -k time
+
+complete -A signal trap kill
+
+complete -f chown ln more cat
+complete -d mkdir rmdir
+
+complete -f -X '!*.+(gz|tgz)' gunzip gzcat zcat zmore
+complete -f -X '!*.Z' uncompress zmore zcat
+complete -f gzip
+
+complete -o dirnames -o filenames -o nospace -d pushd popd
+
+_comp_cd()
+{
+ local IFS=$' \t\n' # normalize IFS
+ local cur _skipdot _cdpath
+ local i j k
+
+ # Tilde expansion, with side effect of expanding tilde to full pathname
+ case "$2" in
+ \~*) eval cur="$2" ;;
+ *) cur=$2 ;;
+ esac
+
+ # no cdpath or absolute pathname -- straight directory completion
+ if [[ -z "${CDPATH:-}" ]] || [[ "$cur" == @(./*|../*|/*) ]]; then
+ # compgen prints paths one per line; could also use while loop
+ IFS=$'\n'
+ COMPREPLY=( $(compgen -d -- "$cur") )
+ IFS=$' \t\n'
+ # CDPATH+directories in the current directory if not in CDPATH
+ else
+ IFS=$'\n'
+ _skipdot=false
+ # preprocess CDPATH to convert null directory names to .
+ _cdpath=${CDPATH/#:/.:}
+ _cdpath=${_cdpath//::/:.:}
+ _cdpath=${_cdpath/%:/:.}
+ for i in ${_cdpath//:/$'\n'}; do
+ if [[ $i -ef . ]]; then _skipdot=true; fi
+ k="${#COMPREPLY[@]}"
+ for j in $( compgen -d -- "$i/$cur" ); do
+ COMPREPLY[k++]=${j#$i/} # cut off directory
+ done
+ done
+ $_skipdot || COMPREPLY+=( $(compgen -d -- "$cur") )
+ IFS=$' \t\n'
+ fi
+
+ # variable names if appropriate shell option set and no completions
+ if shopt -q cdable_vars && [[ ${#COMPREPLY[@]} -eq 0 ]]; then
+ COMPREPLY=( $(compgen -v -- "$cur") )
+ fi
+
+ # append slash to passed directory name that is the only completion.
+ # readline will not do this if we complete from CDPATH
+ if [[ ${#COMPREPLY[@]} -eq 1 ]]; then
+ i=${COMPREPLY[0]} # shorthand
+ if [[ "$cur" == "$i" ]] && [[ "$i" != "*/" ]]; then
+ COMPREPLY[0]+=/
+ fi
+ fi
+ return 0
+}
+
+complete -o filenames -o nospace -o bashdefault -F _comp_cd cd
+
+complete -A hostname rsh telnet rlogin ftp
+
+complete -u su
+complete -W '"${GROUPS[@]}"' newgrp
+complete -g groupdel groupmod
+
+complete -f -X '!*.+(ps|PS)' gs gv ghostview
+complete -f -X '!*.dvi' dvips xdvi
+complete -f -X '!*.pdf' acroread
+
+complete -f -X '!*.texi*' makeinfo texi2dvi texi2html
+
+complete -c gdb make
+
+complete -p gs
+complete -p
+
+complete -r xdvi
+complete -r notthere
+
+complete -r
+complete
diff --git a/tests/comsub-eof.right b/tests/comsub-eof.right
new file mode 100644
index 0000000..cd5ab69
--- /dev/null
+++ b/tests/comsub-eof.right
@@ -0,0 +1,17 @@
+./comsub-eof0.sub: line 5: warning: here-document at line 3 delimited by end-of-file (wanted `EOF')
+hi
+hi
+./comsub-eof2.sub: line 2: warning: here-document at line 1 delimited by end-of-file (wanted `EOF')
+hi
+./comsub-eof3.sub: line 4: warning: here-document at line 1 delimited by end-of-file (wanted `EOF')
+./comsub-eof3.sub: line 5: unexpected EOF while looking for matching `)'
+./comsub-eof4.sub: line 3: warning: here-document at line 1 delimited by end-of-file (wanted `EOF')
+contents
+./comsub-eof5.sub: line 4: warning: here-document at line 2 delimited by end-of-file (wanted `)')
+hi
+./comsub-eof5.sub: line 9: warning: here-document at line 7 delimited by end-of-file (wanted `EOF')
+hi
+./comsub-eof5.sub: line 15: warning: here-document at line 13 delimited by end-of-file (wanted `)')
+hi
+./comsub-eof6.sub: command substitution: line 3: unexpected EOF while looking for matching `)'
+
diff --git a/tests/comsub-eof.tests b/tests/comsub-eof.tests
new file mode 100644
index 0000000..398746a
--- /dev/null
+++ b/tests/comsub-eof.tests
@@ -0,0 +1,13 @@
+${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
+
+${THIS_SH} ./comsub-eof6.sub
diff --git a/tests/comsub-eof0.sub b/tests/comsub-eof0.sub
new file mode 100644
index 0000000..7490faa
--- /dev/null
+++ b/tests/comsub-eof0.sub
@@ -0,0 +1,6 @@
+# it's only the space before the paren that makes this an error
+# when I fix it, it will show up here
+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..4bada67
--- /dev/null
+++ b/tests/comsub-eof5.sub
@@ -0,0 +1,15 @@
+echo $(
+cat <<\)
+hi
+))
+
+echo $(
+cat <<\EOF
+hi
+EOF)
+
+# this is currently an error; if I fix it it will show up here
+echo "$(
+cat <<\)
+hi
+))"
diff --git a/tests/comsub-eof6.sub b/tests/comsub-eof6.sub
new file mode 100644
index 0000000..c0e63dd
--- /dev/null
+++ b/tests/comsub-eof6.sub
@@ -0,0 +1,5 @@
+read foo <<EOF
+$(seq 10
+EOF
+
+echo "$foo"
diff --git a/tests/comsub-posix.right b/tests/comsub-posix.right
new file mode 100644
index 0000000..037f0ed
--- /dev/null
+++ b/tests/comsub-posix.right
@@ -0,0 +1,100 @@
+abmnopyz
+abmnopyz
+ab
+
+
+abcd
+abcd
+mnop
+qrst
+sh_352.26ax
+sh_352.26ay
+sh_352.25a sh_352.25b
+sh_352.27 ) ) )
+abc
+def
+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
+x
+quoted )
+comment
+here-doc with )
+here-doc with \()
+here-doc terminated with a parenthesis
+' # or a single back- or doublequote
+line terminated with a backslash
+./comsub-posix1.sub: line 1: syntax error near unexpected token `)'
+./comsub-posix1.sub: line 1: `echo $( if x; then echo foo )'
+swap32_posix is a function
+swap32_posix ()
+{
+ local funcname=swap32_posix;
+ local arg;
+ for arg in "$@";
+ do
+ echo $((
+ ($arg & 4278190080) >> 24 |
+ ($arg & 16711680) >> 8 |
+ ($arg & 65280) << 8 |
+ ($arg & 255) << 24
+ ));
+ done
+}
+bash: -c: line 1: syntax error near unexpected token `done'
+bash: -c: line 1: `: $(case x in x) ;; x) done esac)'
+bash: -c: line 1: syntax error near unexpected token `done'
+bash: -c: line 1: `: $(case x in x) ;; x) done ;; esac)'
+bash: -c: line 1: syntax error near unexpected token `esac'
+bash: -c: line 1: `: $(case x in x) (esac) esac)'
+bash: -c: line 1: syntax error near unexpected token `in'
+bash: -c: line 1: `: $(case x in esac|in) foo;; esac)'
+bash: -c: line 1: syntax error near unexpected token `done'
+bash: -c: line 1: `: $(case x in x) ;; x) done)'
+case: -c: line 3: syntax error near unexpected token `esac'
+case: -c: line 3: `$( esac ; bar=foo ; echo "$bar")) echo bad 2;;'
+ok 2
+inside outside
+ok 3
+syntax-error: -c: line 2: syntax error near unexpected token `done'
+syntax-error: -c: line 2: `: $(case x in x) ;; x) done ;; esac)'
+yes
+
+
+
+ab cde
diff --git a/tests/comsub-posix.tests b/tests/comsub-posix.tests
new file mode 100644
index 0000000..ab7cd29
--- /dev/null
+++ b/tests/comsub-posix.tests
@@ -0,0 +1,286 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: ${HOME:=/}
+
+# 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 ab$( )cd
+echo mn$(
+)op
+echo qr$(
+
+ )st
+
+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 $(#a comment with )
+echo def)
+
+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 # followed by a comment
+)
+
+echo $(
+ case x in (x) echo x;; esac
+)
+
+echo $(
+ echo 'quoted )'
+)
+
+echo $(
+ echo comment # with )
+)
+
+echo $(
+cat <<\eof
+ here-doc with )
+eof
+)
+
+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
+)
+
+echo $(
+ echo line terminated with a backslash # \
+)
+
+${THIS_SH} ./comsub-posix1.sub
+${THIS_SH} ./comsub-posix2.sub
+${THIS_SH} ./comsub-posix3.sub
+
+#${THIS_SH} ./comsub-posix4.sub
+${THIS_SH} ./comsub-posix5.sub
+${THIS_SH} ./comsub-posix6.sub
+
+# produced a parse error through bash-4.0-beta2
+: $(echo foo)"
+"
+# produced a parse error through bash-4.1
+unset x
+x=$(
+echo yes
+# a comment with " ' \
+)
+echo $x
+unset x
+
+# fixed after bash-4.0 released
+: $(case a in a) echo ;; # comment
+esac)
+
+: $(case a in
+ a)
+ echo
+ ;; # comment
+esac)
+
+# fixed after bash-4.3 released
+testing=$(
+ echo test | while read line; do
+ case $line in
+ test) echo saw test ;;
+ *) echo other ;;
+ esac
+ done
+)
+
+# sanity check for empty comsubs
+echo $()
+echo $(
+)
+
+echo $(
+
+ )
+
+# recommended to be parsed as a nested comsub instead of arithsub
+echo $(( echo ab cde ) )
diff --git a/tests/comsub-posix1.sub b/tests/comsub-posix1.sub
new file mode 100644
index 0000000..de6f473
--- /dev/null
+++ b/tests/comsub-posix1.sub
@@ -0,0 +1,3 @@
+echo $( if x; then echo foo )
+
+echo should not see this
diff --git a/tests/comsub-posix2.sub b/tests/comsub-posix2.sub
new file mode 100644
index 0000000..d556fa9
--- /dev/null
+++ b/tests/comsub-posix2.sub
@@ -0,0 +1,29 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# problem with bash-4.x versions before bash-4.2. required posix interp
+swap32_posix()
+{
+ local funcname=swap32_posix
+ local arg
+ for arg in "$@"; do
+ echo $((
+ ($arg & 4278190080) >> 24 |
+ ($arg & 16711680) >> 8 |
+ ($arg & 65280) << 8 |
+ ($arg & 255) << 24
+ ))
+ done
+}
+
+type swap32_posix
diff --git a/tests/comsub-posix3.sub b/tests/comsub-posix3.sub
new file mode 100644
index 0000000..39262b2
--- /dev/null
+++ b/tests/comsub-posix3.sub
@@ -0,0 +1,35 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# parsing errors before bash-4.2
+
+a=$(/bin/cat << EOF | wc -l
+a
+b
+c
+EOF
+)
+
+a=$(cat << EOF | wc -l
+a
+b
+c
+EOF
+)
+
+a=$(/bin/cat << EOF
+a
+b
+c
+EOF
+)
diff --git a/tests/comsub-posix5.sub b/tests/comsub-posix5.sub
new file mode 100644
index 0000000..f10e773
--- /dev/null
+++ b/tests/comsub-posix5.sub
@@ -0,0 +1,70 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: ${THIS_SH:=./bash}
+
+# problems with recognzing `esac' after a right paren in a command substitution
+
+: $(case x in x) esac)
+: $(case x in x) ;; x) esac)
+# non-reserved word beginning with e
+: $(case x in x) ;; x) echo ;; esac)
+# reserved word beginning with e
+: $(case x in x) ;; x) eval esac ;; esac)
+
+: $(case x in x ) esac)
+: $(case x in x ) ;; x) esac)
+
+: $(case x in (x) esac)
+: $(case x in (x) ;; (x) esac)
+: $(case x in (x) ;; x) esac)
+: $(case x in (x) (echo a) esac)
+
+: $(case x in (x) (echo esac) esac)
+: $(case x in x) (echo esac) esac)
+
+# these errors should be caught sooner
+${THIS_SH} -c ': $(case x in x) ;; x) done esac)' bash
+${THIS_SH} -c ': $(case x in x) ;; x) done ;; esac)' bash
+${THIS_SH} -c ': $(case x in x) (esac) esac)' bash
+
+# these are not errors
+: $(case x in x) ;; x) eval done ;; esac)
+
+# these are just ridiculous
+: $(case x in (x) a() { echo a; } esac)
+: $(case x in (x) if :; then echo a; fi esac)
+: $(case x in (x) { echo a; } esac)
+: $(case x in (x) while false; do echo a; done esac)
+: $(case x in (x) case y in (y) echo a;; esac esac)
+: $(case x in (x) case y in (y) echo a;; esac ;; (y) foo ;; esac)
+
+: $(case x in x) a() { echo a; } esac)
+: $(case x in x) if :; then echo a; fi esac)
+: $(case x in x) { echo a; } esac)
+: $(case x in x) while false; do echo a; done esac)
+: $(case x in x) case y in (y) echo a;; esac esac)
+: $(case x in x) case y in (y) echo a;; esac ;; y) foo ;; esac)
+: $(case x in x) case y in y) echo a;; esac ;; y) foo ;; esac)
+
+: $(case ni in esac)
+: $(case in in esac)
+
+: $(case x in in|esac) foo;; esac)
+: $(case esac in (esac) echo esac;; esac)
+: $(case k in else|done|time|esac) for f in 1 2 3 ; do :; done esac)
+
+# this is an error
+${THIS_SH} -c ': $(case x in esac|in) foo;; esac)' bash
+
+${THIS_SH} -c ': $(case x in x) ;; x) done)' bash
diff --git a/tests/comsub-posix6.sub b/tests/comsub-posix6.sub
new file mode 100644
index 0000000..212ad20
--- /dev/null
+++ b/tests/comsub-posix6.sub
@@ -0,0 +1,43 @@
+: ${THIS_SH:=./bash}
+
+# comsub should not inherit PST_COMPASSIGN
+
+C=($(echo "${A[@]}" | \
+ (while read -d ' ' i; do
+ C=(${C/ ${i%% *} / })
+ done
+ echo ${C[@]})))
+
+# comsub should not inherit PST_CASEPAT
+
+${THIS_SH} -c '
+case foo in
+$( esac ; bar=foo ; echo "$bar")) echo bad 2;;
+*) echo ok 2;;
+esac
+
+echo we should not see this' case
+
+# comsub should not inherit PST_SUBSHELL
+
+${THIS_SH} -c '( case foo in
+ ( $(echo foo | cat )) echo ok 2;;
+ *) echo bad 2;;
+ esac
+
+ echo $( echo inside ) outside )' subshell
+
+# comsub should not inherit PST_REDIRLIST
+
+${THIS_SH} -c '
+{fd}</dev/null {fd2}<$(foo=/dev/null ; echo $foo) exec
+case $fd2 in
+[0-9]*) echo ok 3 ;;
+*) echo bad 3 ;;
+esac' redirlist
+
+# comsub should exit on syntax error while parsing
+${THIS_SH} -c '
+: $(case x in x) ;; x) done ;; esac)
+
+echo after syntax error' syntax-error
diff --git a/tests/comsub.right b/tests/comsub.right
new file mode 100644
index 0000000..eae8c3b
--- /dev/null
+++ b/tests/comsub.right
@@ -0,0 +1,79 @@
+./comsub.tests: line 20: 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>
+nested
+#esac
+a
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+ok 6
+xyz
+ok 7
+\/tmp\/foo\/bar
+/tmp/foo/bar
+/tmp/foo/bar
+/tmp/foo/bar
+1
+2
+3
+4
+5
+6
+5
+6
+a
+b
+c
+a
+b
+c
+1
+2
+d \
+g
+d \
+g
+d \
+g
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+ok 6
+ok 7
+ok 9
+ok 8
+ok 8
+Mon Aug 29 20:03:02 EDT 2022
+post foo
+Mon Aug 29 20:03:02 EDT 2022
+post foo1
+Mon Aug 29 20:03:02 EDT 2022
+Mon Aug 29 20:03:02 EDT 2022 after
+7
+Mon Aug 29 20:03:02 EDT 2022
+hey after x
+./comsub6.sub: line 40: syntax error near unexpected token `)'
+./comsub6.sub: line 40: `math1)'
diff --git a/tests/comsub.tests b/tests/comsub.tests
new file mode 100644
index 0000000..698ce30
--- /dev/null
+++ b/tests/comsub.tests
@@ -0,0 +1,84 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# 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')
+
+# long-standing parse error in all versions up through bash-4.3
+echo ${foo:-$(echo a{b,c})} >/dev/null
+
+# parsing problem based on recursively calling bison parser through bash-4.4
+for (( INDEX=0; INDEX<$((10-$(echo length $V_NAME))); INDEX++ ))
+do
+ :
+done
+
+# problem with four-character words followed by a metachar through bash-4.4
+comsub_foo_1()
+{
+ echo $(while true; do case $HOME in /*) echo abs ;; esac; done)
+}
+
+echo $(
+echo $(
+echo $(echo $( echo nested )
+)
+)
+)
+
+${THIS_SH} ./comsub1.sub
+${THIS_SH} ./comsub2.sub
+${THIS_SH} ./comsub3.sub
+${THIS_SH} ./comsub4.sub
+${THIS_SH} ./comsub5.sub
+${THIS_SH} ./comsub6.sub
diff --git a/tests/comsub1.sub b/tests/comsub1.sub
new file mode 100644
index 0000000..ca72243
--- /dev/null
+++ b/tests/comsub1.sub
@@ -0,0 +1,73 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: $(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)
+
+echo $( # we just took and pasted in some
+# code from another script inside a
+# command substitution
+echo xyz
+)
+
+# problem with parse_comsub through bash-4.4
+case $(echo $$'x\nx') in
+x*) echo bad 7;;
+*) echo ok 7;;
+esac
diff --git a/tests/comsub2.sub b/tests/comsub2.sub
new file mode 100644
index 0000000..d60ae6a
--- /dev/null
+++ b/tests/comsub2.sub
@@ -0,0 +1,8 @@
+qpath='\/tmp\/foo\/bar'
+
+echo "$qpath"
+
+# it's crazy that all three of these produce the same result
+printf "%s\n" ${qpath//\\/}
+printf "%s\n" ${qpath//"`printf '%s' \\`"/}
+printf "%s\n" ${qpath//`printf '%s' "\\\\\\\\"`/}
diff --git a/tests/comsub3.sub b/tests/comsub3.sub
new file mode 100644
index 0000000..757fbca
--- /dev/null
+++ b/tests/comsub3.sub
@@ -0,0 +1,44 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+x=$(
+ case 1 in
+ 1) echo 1
+ esac
+ case 2 in
+ 2) echo 2
+ esac
+)
+echo "$x"
+
+x=$(case 1 in 1) echo 3;; esac; case 2 in 2) echo 4;; esac;)
+echo "$x"
+
+x=$(case 1 in 1) echo 5;; esac; case 2 in 2) echo 6;; esac)
+echo "$x"
+
+x=$(case 1 in 1) echo 5;; esac; case 2 in 2) echo 6;; esac; for f in a b c; do echo "$f" ; done)
+echo "$x"
+
+x=$(
+ for f in a b c; do
+ echo $f
+ done
+ case 1 in
+ 1) echo 1
+ esac
+ case 2 in
+ 2) echo 2
+ esac
+)
+echo "$x"
diff --git a/tests/comsub4.sub b/tests/comsub4.sub
new file mode 100644
index 0000000..e7a1c55
--- /dev/null
+++ b/tests/comsub4.sub
@@ -0,0 +1,40 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+x=$(cat <<'EOT'
+d \
+g
+EOT
+)
+
+echo "$x"
+unset x
+
+x=$( cat <<\EOT\
+4
+d \
+g
+EOT4
+)
+
+echo "$x"
+unset x
+
+x=$( cat <<\EOT
+d \
+g
+EOT
+)
+
+echo "$x"
+
diff --git a/tests/comsub5.sub b/tests/comsub5.sub
new file mode 100644
index 0000000..cc83374
--- /dev/null
+++ b/tests/comsub5.sub
@@ -0,0 +1,51 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# this is a new feature: expanding aliases when initially parsing command
+# substitutions. required by posix, so enabled in posix mode. default mode
+# stays backwards compatible.
+
+shopt -s expand_aliases
+set -o posix
+
+alias switch=case
+
+switch foo in foo) echo ok 1;; esac
+
+echo $( switch foo in foo) echo ok 2;; esac )
+echo "$( switch foo in foo) echo ok 3;; esac )"
+
+echo $( switch foo in (foo) echo ok 4;; esac )
+echo "$( switch foo in (foo) echo ok 5;; esac )"
+
+alias nest='('
+
+echo $( nest echo ok 6 ) )
+echo "$( nest echo ok 7 ) )"
+
+alias short='echo ok 8 )'
+
+alias DO='{ '
+alias DONE='}'
+got=$(DO
+echo ok 9; DONE)
+echo "$got"
+
+echo $( short
+echo "$( short "
+
+# remember that short" won't work because you start a new quoting context
+# inside $( and the token (`short') won't be delimited by the ending double
+# quote, so there's no opportunity to perform the alias expansion that would
+# terminate the command substitution
diff --git a/tests/comsub6.sub b/tests/comsub6.sub
new file mode 100644
index 0000000..d2b02bf
--- /dev/null
+++ b/tests/comsub6.sub
@@ -0,0 +1,40 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+DATE='Mon Aug 29 20:03:02 EDT 2022'
+shopt -s expand_aliases
+
+alias foo='echo $(echo $DATE)'
+alias foo1='echo $(echo $DATE) '
+
+foo
+echo post foo
+
+foo1
+echo post foo1
+
+alias comsub0='echo $(echo $DATE'
+comsub0)
+comsub0 ) after
+
+alias math0='echo $(( 4+3 )'
+math0)
+
+alias x='VAR=$(echo hey)'
+x
+foo
+
+echo $VAR after x
+
+alias math1='echo $( date )'
+math1)
diff --git a/tests/cond-regexp1.sub b/tests/cond-regexp1.sub
new file mode 100644
index 0000000..1ba9197
--- /dev/null
+++ b/tests/cond-regexp1.sub
@@ -0,0 +1,69 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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
+
+unset pattern string
+pattern="xxx.yyy"
+string=xxxAyyy
+
+[[ $string =~ $pattern ]] && echo unquoted matches
+[[ $string =~ "$pattern" ]] && echo quoted matches
+
+# problems in pre-patched bash-4.2
+[[ "helloworld" =~ llo ]] && echo match control-a 1
+[[ "helloworld" =~ world ]] && echo match control-a 2
+[[ "helloworld" =~ world$ ]] && echo match control-a 3
+[[ "helloworld" =~  ]] && echo match control-a 4
+[[ "helloworld" =~ oworld$ ]] && echo match control-a 5
diff --git a/tests/cond-regexp2.sub b/tests/cond-regexp2.sub
new file mode 100644
index 0000000..4da0a88
--- /dev/null
+++ b/tests/cond-regexp2.sub
@@ -0,0 +1,45 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+[[ "\\" =~ ["."] ]] && echo bad 1
+
+[[ "\\" =~ "[.]" ]] && echo bad 2
+
+[[ "\\" =~ [\. ]] && echo bad 3
+
+[[ "\\" =~ [\.] ]] && echo bad 4
+
+[[ "\\" =~ [\\] ]] || echo bad 5
+
+[[ dog =~ [[=d=]].. ]] && echo ok 1
+[[ d.. =~ [[=d=]]\.\. ]] && echo ok 2
+[[ dog =~ ['[=d=]'].. ]] && echo ok 3 # dubious
+
+[[ dog =~ [[=d=]].[[=G=][=g=]] ]] && echo ok 4
+[[ dog =~ [[=d=]].[\[=G=][=g=]] ]] && echo ok 4a
+
+[[ dog =~ "d.." ]] || echo ok 5
+
+[[ dog =~ [[.d.][.D.]]o. ]] && echo ok 6
+
+[[ dog =~ ([[.d.][.D.]])o(.) ]] && echo ok 7 -- ${BASH_REMATCH[1]}
+[[ dog =~ d([[.o.][.O.]])(.) ]] && echo ok 8 -- ${BASH_REMATCH[1]}
+[[ dog =~ .([[.o.][.O.]])(.) ]] && echo ok 9
+
+[[ dog =~ 'd''o''g' ]] && echo ok 10
+
+[[ ']' =~ [']'] ]] && echo ok 11
+
+[[ a =~ ['a]'] ]] || echo ok 12
+
+[[ "\\" =~ [^]"."] ]] || echo unexpected
diff --git a/tests/cond-regexp3.sub b/tests/cond-regexp3.sub
new file mode 100644
index 0000000..d939548
--- /dev/null
+++ b/tests/cond-regexp3.sub
@@ -0,0 +1,86 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# simple expansion -- no problem, it's quote_string_for_globbing that was flawed
+c=$'\177'
+r="\\$c"
+
+recho $r
+
+# first, match some regular expressions containing ^A, ^G, ^?
+[[ $'\001' =~ $'\001' ]] ; echo $?
+[[ $'\001' =~ $'\\\001' ]] ; echo $?
+[[ $'\001' =~ $'\\[\001]' ]] ; echo $?
+
+[[ $'\a' =~ $'\a' ]] ; echo $?
+[[ $'\a' =~ $'\\\a' ]] ; echo $?
+[[ $'\a' =~ $'\\[\a]' ]] ; echo $?
+
+[[ $'\177' =~ $'\177' ]] ; echo $?
+[[ $'\177' =~ $'\\\177' ]] ; echo $?
+[[ $'\177' =~ $'\\[\177]' ]] ; echo $?
+
+# Now let's try it with variables expanding to those values
+for c in $'\001' $'\a' $'\177' ; do
+ for r in "$c" "\\$c" "\\[$c]"; do
+ [[ $c =~ $r ]];
+ printf '[[ %q =~ %q ]] -> %d\n' "$c" "$r" "$?";
+ done;
+ printf %s\\n ---
+done
+
+# try again with literals
+
+[[ '' =~ $'' ]] ; echo $?
+[[ '' =~ '\' ]] ; echo $?
+[[ '' =~ '\[]' ]] ; echo $?
+
+[[ '' =~ '' ]] ; echo $?
+[[ '' =~ '\' ]] ; echo $?
+[[ '' =~ '\[]' ]] ; echo $?
+
+[[ '' =~ $'' ]] ; echo $?
+[[ '' =~ '\' ]] ; echo $?
+[[ '' =~ '\[]' ]] ; echo $?
+
+# more expansions, but with literal non-special characters
+[[ x =~ \x ]] ; echo $?
+[[ x =~ \\x ]] ; echo $?
+
+bs='\'
+[[ x =~ ${bs}x ]] ; echo $?
+
+[[ x =~ $'\\'x ]] ; echo $?
+[[ x =~ '\'x ]] ; echo $?
+
+v='a\-b'
+[[ a-b =~ ${v} ]] ; echo $?
+[[ a-b =~ a\-b ]]; echo $?
+[[ a-b =~ a${bs}-b ]]; echo $?
+[[ a-b =~ a\\-b ]] ; echo $?
+[[ a-b =~ "a\-b" ]] ; echo $?
+
+c=$'\001'
+
+recho $c "$c"
+
+[[ $c == $c ]] && echo ok 1
+[[ $c =~ $c ]] && echo ok 2
+[[ $c =~ \\$c ]] || echo ok 3
+[[ $c =~ \\"$c" ]] || echo ok 4
+
+[[ $c =~ "\\"$c ]] || echo ok 5
+[[ $c =~ '\'$c ]] || echo ok 6
+
+[[ $c =~ "\\""$c" ]] || echo ok 7
+[[ $c =~ '\'"$c" ]] || echo ok 8
diff --git a/tests/cond.right b/tests/cond.right
new file mode 100644
index 0000000..a72a153
--- /dev/null
+++ b/tests/cond.right
@@ -0,0 +1,142 @@
+returns: 0
+returns: 0
+returns: 1
+returns: 0
+1
+0
+1
+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 122: [[: 4+: syntax error: operand expected (error token is "+")
+returns: 1
+returns: 0
+returns: 0
+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
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+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
+unquoted matches
+match control-a 1
+match control-a 2
+match control-a 3
+match control-a 4
+match control-a 5
+ok 1
+ok 2
+ok 3
+ok 4
+ok 4a
+ok 5
+ok 6
+ok 7 -- d
+ok 8 -- o
+ok 9
+ok 10
+ok 11
+ok 12
+argv[1] = <\^?>
+0
+1
+1
+0
+1
+1
+0
+1
+1
+[[ $'\001' =~ $'\001' ]] -> 0
+[[ $'\001' =~ $'\\\001' ]] -> 0
+[[ $'\001' =~ $'\\[\001]' ]] -> 1
+---
+[[ $'\a' =~ $'\a' ]] -> 0
+[[ $'\a' =~ $'\\\a' ]] -> 0
+[[ $'\a' =~ $'\\[\a]' ]] -> 1
+---
+[[ $'\177' =~ $'\177' ]] -> 0
+[[ $'\177' =~ $'\\\177' ]] -> 0
+[[ $'\177' =~ $'\\[\177]' ]] -> 1
+---
+0
+1
+1
+0
+1
+1
+0
+1
+1
+0
+1
+0
+1
+1
+0
+0
+0
+1
+1
+argv[1] = <^A>
+argv[2] = <^A>
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+ok 6
+ok 7
+ok 8
diff --git a/tests/cond.tests b/tests/cond.tests
new file mode 100644
index 0000000..c0747e9
--- /dev/null
+++ b/tests/cond.tests
@@ -0,0 +1,232 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# 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: $?
+
+# ! toggles on and off rather than just setting an `invert result' flag
+# this differs from ksh93
+[[ ! 1 -eq 1 ]]; echo $?
+[[ ! ! 1 -eq 1 ]]; echo $?
+
+[[ ! ! ! 1 -eq 1 ]]; echo $?
+[[ ! ! ! ! 1 -eq 1 ]]; echo $?
+
+# 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: $?
+
+[[ "$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
+
+match() { [[ $1 == $2 ]]; }
+match $'? *x\1y\177z' $'??\\*\\x\\\1\\y\\\177\\z' || echo bad 44
+
+foo=""
+[[ bar == *"${foo,,}"* ]] && echo ok 1
+[[ bar == *${foo,,}* ]] && echo ok 2
+
+shopt -s extquote
+bs='\'
+del=$'\177'
+[[ bar == *$bs"$del"* ]] || echo ok 3
+[[ "" == "$foo" ]] && echo ok 4
+[[ "$del" == "${foo,,}" ]] || echo ok 5
+
+# allow reserved words after a conditional command just because
+if [[ str ]] then [[ str ]] fi
+
+${THIS_SH} ./cond-regexp1.sub
+
+${THIS_SH} ./cond-regexp2.sub
+
+${THIS_SH} ./cond-regexp3.sub
diff --git a/tests/coproc.right b/tests/coproc.right
new file mode 100644
index 0000000..94b001c
--- /dev/null
+++ b/tests/coproc.right
@@ -0,0 +1,10 @@
+63 60
+a b c
+63 60
+flop
+coproc.tests: REFLECT: status 143
+63 60
+FOO
+63 60
+root
+-1 -1
diff --git a/tests/coproc.tests b/tests/coproc.tests
new file mode 100644
index 0000000..a735932
--- /dev/null
+++ b/tests/coproc.tests
@@ -0,0 +1,78 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: ${TMPDIR:=/tmp}
+TMPOUT=${TMPDIR}/coproc-wait-$BASHPID
+
+coproc { echo a b c; sleep 2; }
+
+case $COPROC_PID in
+[0-9]*) ;;
+*) echo COPROC_PID not integer ;;
+esac
+
+echo ${COPROC[@]}
+
+read LINE <&${COPROC[0]}
+echo $LINE
+
+wait $COPROC_PID
+
+coproc REFLECT { cat - ; }
+
+case $REFLECT_PID in
+[0-9]*) ;;
+*) echo REFLECT_PID not integer ;;
+esac
+
+echo ${REFLECT[@]}
+
+echo flop >&${REFLECT[1]}
+read LINE <&${REFLECT[0]}
+
+echo $LINE
+
+{ sleep 1; kill $REFLECT_PID; } &
+wait $REFLECT_PID >$TMPOUT 2>&1 || { status=$? ; echo "coproc.tests: REFLECT: status $status" ; }
+[[ $status < 128 || $status == 143 ]] || {
+ echo "coproc.tests: wait for REFLECT failed" >&2
+}
+rm -f $TMPOUT
+exec 2>&1
+
+coproc xcase -n -u
+
+case $COPROC_PID in
+[0-9]*) ;;
+*) echo COPROC_PID not integer ;;
+esac
+
+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..269136d
--- /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..e598f8c
--- /dev/null
+++ b/tests/cprint.tests
@@ -0,0 +1,80 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# a 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..6e2194a
--- /dev/null
+++ b/tests/dbg-support.right
@@ -0,0 +1,371 @@
+debug lineno: 74 main
+debug lineno: 77 main
+FUNCNAME main
+debug lineno: 81 main
+debug lineno: 30 fn1
+debug lineno: 31 fn1
+LINENO 31
+debug lineno: 32 fn1
+LINENO 32
+debug lineno: 33 fn1
+BASH_SOURCE[0] ./dbg-support.tests
+debug lineno: 34 fn1
+FUNCNAME[0] fn1
+debug lineno: 35 fn1
+debug lineno: 35 fn1 81 ./dbg-support.tests
+debug lineno: 36 fn1
+debug lineno: 36 fn1 81 main ./dbg-support.tests
+debug lineno: 37 fn1
+debug lineno: 37 fn1
+debug lineno: 38 fn1
+./dbg-support.tests: line 38: caller: foo: invalid number
+caller: usage: caller [expr]
+debug lineno: 38 fn1
+debug lineno: 30 fn1
+debug lineno: 25 print_return_trap
+debug lineno: 26 print_return_trap
+return lineno: 30 fn1
+debug lineno: 27 print_return_trap
+debug lineno: 82 main
+debug lineno: 41 fn2
+debug lineno: 42 fn2
+fn2 here. Calling fn1...
+debug lineno: 43 fn2
+debug lineno: 30 fn1
+debug lineno: 31 fn1
+LINENO 31
+debug lineno: 32 fn1
+LINENO 32
+debug lineno: 33 fn1
+BASH_SOURCE[0] ./dbg-support.tests
+debug lineno: 34 fn1
+FUNCNAME[0] fn1
+debug lineno: 35 fn1
+debug lineno: 35 fn1 43 ./dbg-support.tests
+debug lineno: 36 fn1
+debug lineno: 36 fn1 43 fn2 ./dbg-support.tests
+debug lineno: 37 fn1
+debug lineno: 37 fn1 82 main ./dbg-support.tests
+debug lineno: 38 fn1
+./dbg-support.tests: line 38: caller: foo: invalid number
+caller: usage: caller [expr]
+debug lineno: 38 fn1
+debug lineno: 30 fn1
+debug lineno: 25 print_return_trap
+debug lineno: 26 print_return_trap
+return lineno: 30 fn1
+debug lineno: 27 print_return_trap
+debug lineno: 41 fn2
+debug lineno: 25 print_return_trap
+debug lineno: 26 print_return_trap
+return lineno: 41 fn2
+debug lineno: 27 print_return_trap
+debug lineno: 83 main
+debug lineno: 46 fn3
+debug lineno: 47 fn3
+LINENO 47
+debug lineno: 48 fn3
+BASH_SOURCE[0] ./dbg-support.tests
+debug lineno: 51 fn3
+debug lineno: 52 fn3
+debug lineno: 53 fn3
+debug lineno: 53 fn3
+debug lineno: 54 fn3
+debug lineno: 55 fn3
+debug lineno: 56 fn3
+fn3 called from file `./dbg-support.tests' at line 0
+debug lineno: 53 fn3
+debug lineno: 53 fn3
+debug lineno: 54 fn3
+debug lineno: 55 fn3
+debug lineno: 55 fn3
+debug lineno: 56 fn3
+main called from file `./dbg-support.tests' at line 0
+debug lineno: 53 fn3
+debug lineno: 53 fn3
+debug lineno: 59 fn3
+debug lineno: 31 source
+SOURCED LINENO 31
+debug lineno: 32 source
+SOURCED BASH_SOURCE[0] ./dbg-support.sub
+debug lineno: 33 source
+debug lineno: 16 sourced_fn
+debug lineno: 17 sourced_fn
+debug lineno: 18 sourced_fn
+SOURCED FN LINENO 18
+debug lineno: 21 sourced_fn
+debug lineno: 22 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 24 sourced_fn
+debug lineno: 25 sourced_fn
+debug lineno: 26 sourced_fn
+FUNCNAME[0]: sourced_fn called from ./dbg-support.sub at line 33
+debug lineno: 23 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 24 sourced_fn
+debug lineno: 25 sourced_fn
+debug lineno: 26 sourced_fn
+FUNCNAME[1]: source called from ./dbg-support.tests at line 59
+debug lineno: 23 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 24 sourced_fn
+debug lineno: 25 sourced_fn
+debug lineno: 26 sourced_fn
+FUNCNAME[2]: fn3 called from ./dbg-support.tests at line 83
+debug lineno: 23 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 24 sourced_fn
+debug lineno: 25 sourced_fn
+debug lineno: 25 sourced_fn
+debug lineno: 26 sourced_fn
+FUNCNAME[3]: main called from ./dbg-support.tests at line 0
+debug lineno: 23 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 16 sourced_fn
+debug lineno: 25 print_return_trap
+debug lineno: 26 print_return_trap
+return lineno: 16 sourced_fn
+debug lineno: 27 print_return_trap
+debug lineno: 59 fn3
+debug lineno: 25 print_return_trap
+debug lineno: 26 print_return_trap
+return lineno: 59 fn3
+debug lineno: 27 print_return_trap
+debug lineno: 46 fn3
+debug lineno: 25 print_return_trap
+debug lineno: 26 print_return_trap
+return lineno: 46 fn3
+debug lineno: 27 print_return_trap
+debug lineno: 84 main
+debug lineno: 31 source
+SOURCED LINENO 31
+debug lineno: 32 source
+SOURCED BASH_SOURCE[0] ./dbg-support.sub
+debug lineno: 33 source
+debug lineno: 16 sourced_fn
+debug lineno: 17 sourced_fn
+debug lineno: 18 sourced_fn
+SOURCED FN LINENO 18
+debug lineno: 21 sourced_fn
+debug lineno: 22 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 24 sourced_fn
+debug lineno: 25 sourced_fn
+debug lineno: 26 sourced_fn
+FUNCNAME[0]: sourced_fn called from ./dbg-support.sub at line 33
+debug lineno: 23 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 24 sourced_fn
+debug lineno: 25 sourced_fn
+debug lineno: 26 sourced_fn
+FUNCNAME[1]: source called from ./dbg-support.tests at line 84
+debug lineno: 23 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 24 sourced_fn
+debug lineno: 25 sourced_fn
+debug lineno: 25 sourced_fn
+debug lineno: 26 sourced_fn
+FUNCNAME[2]: main called from ./dbg-support.tests at line 0
+debug lineno: 23 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 16 sourced_fn
+debug lineno: 25 print_return_trap
+debug lineno: 26 print_return_trap
+return lineno: 16 sourced_fn
+debug lineno: 27 print_return_trap
+debug lineno: 84 main
+debug lineno: 25 print_return_trap
+debug lineno: 26 print_return_trap
+return lineno: 84 main
+debug lineno: 27 print_return_trap
+debug lineno: 87 main
+debug lineno: 90 main
+LINENO 31
+LINENO 32
+BASH_SOURCE[0] ./dbg-support.tests
+FUNCNAME[0] fn1
+90 ./dbg-support.tests
+90 main ./dbg-support.tests
+
+./dbg-support.tests: line 38: caller: foo: invalid number
+caller: usage: caller [expr]
+
+debug lineno: 91 main
+fn2 here. Calling fn1...
+LINENO 31
+LINENO 32
+BASH_SOURCE[0] ./dbg-support.tests
+FUNCNAME[0] fn1
+43 ./dbg-support.tests
+43 fn2 ./dbg-support.tests
+91 main ./dbg-support.tests
+./dbg-support.tests: line 38: caller: foo: invalid number
+caller: usage: caller [expr]
+
+debug lineno: 92 main
+LINENO 47
+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 31
+SOURCED BASH_SOURCE[0] ./dbg-support.sub
+SOURCED FN LINENO 18
+FUNCNAME[0]: sourced_fn called from ./dbg-support.sub at line 33
+FUNCNAME[1]: source called from ./dbg-support.tests at line 59
+FUNCNAME[2]: fn3 called from ./dbg-support.tests at line 92
+FUNCNAME[3]: main called from ./dbg-support.tests at line 0
+debug lineno: 93 main
+fn4 here. Calling fn3...
+LINENO 47
+BASH_SOURCE[0] ./dbg-support.tests
+fn3 called from file `./dbg-support.tests' at line 93
+fn4 called from file `./dbg-support.tests' at line 0
+main called from file `./dbg-support.tests' at line 0
+SOURCED LINENO 31
+SOURCED BASH_SOURCE[0] ./dbg-support.sub
+SOURCED FN LINENO 18
+FUNCNAME[0]: sourced_fn called from ./dbg-support.sub at line 33
+FUNCNAME[1]: source called from ./dbg-support.tests at line 59
+FUNCNAME[2]: fn3 called from ./dbg-support.tests at line 64
+FUNCNAME[3]: fn4 called from ./dbg-support.tests at line 93
+FUNCNAME[4]: main called from ./dbg-support.tests at line 0
+debug lineno: 94 main
+SOURCED LINENO 31
+SOURCED BASH_SOURCE[0] ./dbg-support.sub
+SOURCED FN LINENO 18
+FUNCNAME[0]: sourced_fn called from ./dbg-support.sub at line 33
+FUNCNAME[1]: source called from ./dbg-support.tests at line 94
+FUNCNAME[2]: main called from ./dbg-support.tests at line 0
+return lineno: 94 main
+debug lineno: 97 main
+debug lineno: 100 main
+debug lineno: 31 source
+SOURCED LINENO 31
+debug lineno: 32 source
+SOURCED BASH_SOURCE[0] ./dbg-support.sub
+debug lineno: 33 source
+debug lineno: 16 sourced_fn
+debug lineno: 17 sourced_fn
+debug lineno: 18 sourced_fn
+SOURCED FN LINENO 18
+debug lineno: 21 sourced_fn
+debug lineno: 22 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 24 sourced_fn
+debug lineno: 25 sourced_fn
+debug lineno: 26 sourced_fn
+FUNCNAME[0]: sourced_fn called from ./dbg-support.sub at line 33
+debug lineno: 23 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 24 sourced_fn
+debug lineno: 25 sourced_fn
+debug lineno: 26 sourced_fn
+FUNCNAME[1]: source called from ./dbg-support.tests at line 100
+debug lineno: 23 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 24 sourced_fn
+debug lineno: 25 sourced_fn
+debug lineno: 25 sourced_fn
+debug lineno: 26 sourced_fn
+FUNCNAME[2]: main called from ./dbg-support.tests at line 0
+debug lineno: 23 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 16 sourced_fn
+debug lineno: 25 print_return_trap
+debug lineno: 26 print_return_trap
+return lineno: 16 sourced_fn
+debug lineno: 27 print_return_trap
+debug lineno: 100 main
+debug lineno: 25 print_return_trap
+debug lineno: 26 print_return_trap
+return lineno: 100 main
+debug lineno: 27 print_return_trap
+debug lineno: 101 main
+debug lineno: 104 main
+debug lineno: 104 main
+debug lineno: 105 main
+debug lineno: 108 main
+debug lineno: 104 main
+debug lineno: 104 main
+debug lineno: 105 main
+debug lineno: 108 main
+debug lineno: 104 main
+debug lineno: 104 main
+debug lineno: 105 main
+debug lineno: 106 main
+Hit 2
+debug lineno: 108 main
+debug lineno: 104 main
+debug lineno: 104 main
+debug lineno: 114 main
+SOURCED FN LINENO 18 FUNCNAME[0]: sourced_fn called from ./dbg-support.tests at line 114 FUNCNAME[1]: main called from ./dbg-support.tests at line 0
+debug lineno: 115 main
+SOURCED FN LINENO 18 FUNCNAME[0]: sourced_fn called from ./dbg-support.tests at line 115 FUNCNAME[1]: main called from ./dbg-support.tests at line 0
+debug lineno: 116 main
+debug lineno: 117 main
+SOURCED FN LINENO 18
+FUNCNAME[0]: sourced_fn called from ./dbg-support.tests at line 117
+FUNCNAME[1]: main called from ./dbg-support.tests at line 0
+debug lineno: 121 main
+debug lineno: 122 main
+debug lineno: 16 sourced_fn
+debug lineno: 17 sourced_fn
+debug lineno: 18 sourced_fn
+SOURCED FN LINENO 18
+debug lineno: 21 sourced_fn
+debug lineno: 22 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 24 sourced_fn
+debug lineno: 25 sourced_fn
+debug lineno: 26 sourced_fn
+FUNCNAME[0]: sourced_fn called from ./dbg-support.tests at line 122
+debug lineno: 23 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 24 sourced_fn
+debug lineno: 25 sourced_fn
+debug lineno: 25 sourced_fn
+debug lineno: 26 sourced_fn
+FUNCNAME[1]: main called from ./dbg-support.tests at line 0
+debug lineno: 23 sourced_fn
+debug lineno: 23 sourced_fn
+debug lineno: 16 sourced_fn
+debug lineno: 25 print_return_trap
+debug lineno: 26 print_return_trap
+return lineno: 16 sourced_fn
+debug lineno: 27 print_return_trap
+debug lineno: 125 main
+debug lineno: 130 main
+debug lineno: 134 main
+got it
+debug lineno: 142 main
+debug lineno: 143 main
+debug lineno: 144 main
+debug lineno: 143 main
+debug lineno: 144 main
+debug lineno: 142 main
+debug lineno: 143 main
+debug lineno: 144 main
+debug lineno: 143 main
+debug lineno: 144 main
+debug lineno: 148 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
+39 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..8c82c80
--- /dev/null
+++ b/tests/dbg-support.sub
@@ -0,0 +1,39 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# This 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 100644
index 0000000..b4a58e4
--- /dev/null
+++ b/tests/dbg-support.tests
@@ -0,0 +1,148 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+#
+# Test 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
+}
+
+#
+# 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 command 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
diff --git a/tests/dbg-support2.right b/tests/dbg-support2.right
new file mode 100644
index 0000000..5727d1f
--- /dev/null
+++ b/tests/dbg-support2.right
@@ -0,0 +1,7 @@
+lineno: 29 (18) main
+lineno: 30 (18) main
+x is 1
+lineno: 31 (18) main
+lineno: 32 (18) main
+lineno: 33 (18) main
+x is 1
diff --git a/tests/dbg-support2.tests b/tests/dbg-support2.tests
new file mode 100644
index 0000000..c33251d
--- /dev/null
+++ b/tests/dbg-support2.tests
@@ -0,0 +1,33 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# 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"
diff --git a/tests/dbg-support3.sub b/tests/dbg-support3.sub
new file mode 100644
index 0000000..146831f
--- /dev/null
+++ b/tests/dbg-support3.sub
@@ -0,0 +1,52 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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 100644
index 0000000..721eea1
--- /dev/null
+++ b/tests/dollar-at-star
@@ -0,0 +1,332 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# first, let's start with the basics
+
+recho "$@"
+recho "$*"
+
+recho $@
+recho $*
+
+foo=$*
+foo=$@
+
+foo="$*"
+foo="$@"
+
+unset -v bar
+
+foo=${bar:-$*}
+foo=${bar:-$@}
+
+foo=${bar:-"$*"}
+foo=${bar:-"$@"}
+
+foo=${!*}
+foo=${!@}
+
+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 the effect of quoting $* and $@ in an assignment context (plus
+# arrays) -- bugs through bash 4.2
+${THIS_SH} ./dollar-at-star1.sub
+
+# more tests for expanding $@ and $* in a context where there is no word
+# splitting
+${THIS_SH} ./dollar-at-star2.sub
+${THIS_SH} ./dollar-at-star3.sub
+${THIS_SH} ./dollar-at-star4.sub
+${THIS_SH} ./dollar-at-star5.sub
+${THIS_SH} ./dollar-at-star6.sub
+${THIS_SH} ./dollar-at-star7.sub
+
+# tests for expansions of $@ and ${a[@]} (vs. $* and ${a[*]}) on the RHS of
+# assignment statements with non-default IFS: $@ expands to args or array
+# members separated by spaces
+${THIS_SH} ./dollar-at-star8.sub
+
+# more tests of the expansions of $@ and $* (and their array equivalents)
+# with different values for IFS
+${THIS_SH} ./dollar-at-star9.sub
+
+# tests for expansions of "$*" and "$@" and their array equivalents when $1 == ''
+# and we're using the POSIX word expansions
+${THIS_SH} ./dollar-at-star10.sub
+${THIS_SH} ./dollar-at-star11.sub
+
+# 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
+
+# tests for inappropriate word splitting through bash-4.2
+${THIS_SH} ./dollar-at4.sub
+
+# tests for problems with "$@" preceded and followed by other quoted expansions
+# through bash-4.2
+${THIS_SH} ./dollar-at5.sub
+
+# tests for problems with "${@:1}" and other expansions with null entries
+# in positional parameters
+${THIS_SH} ./dollar-at6.sub
+
+# tests for expansions of $* when $1 == ""; problem through bash-4.2
+${THIS_SH} ./dollar-star6.sub
+
+# tests for expansions of $* (unquoted) when IFS changes (e.g., ${IFS:=-})
+# problem through bash-4.2
+${THIS_SH} ./dollar-star7.sub
+
+# tests for expansions of $* (unquoted) when IFS is null and word splitting is
+# not going to be performed.
+# problem through bash-4.4 in some parameter expansion contexts
+${THIS_SH} ./dollar-star8.sub
+
+# tests for expansions of "$@" when there are no positional parameter or when
+# $1 == '' and the expansion is preceded by something that results in a quoted
+# null string
+${THIS_SH} ./dollar-at7.sub
+
+# tests for expansions of $* when in an assignment context (no splitting) and
+# IFS is null
+${THIS_SH} ./dollar-star9.sub
+
+# more tests for expansions of $* when not splitting with IFS set or unset and
+# null strings as the positional parameters
+${THIS_SH} ./dollar-star10.sub
+
+exit 0
diff --git a/tests/dollar-at-star1.sub b/tests/dollar-at-star1.sub
new file mode 100644
index 0000000..ef15efc
--- /dev/null
+++ b/tests/dollar-at-star1.sub
@@ -0,0 +1,36 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# from dan douglas
+expassign()
+{
+ typeset -a a
+ a=("$@")
+ typeset var asn
+
+ while IFS= read -r asn; do
+ IFS=: command eval "$asn"
+ printf '%-14s... %s\n' "$asn" "$var"
+ done <<\EOF
+var=${a[*]}
+var="${a[*]}"
+var=$*
+var="$*"
+var=${a[@]}
+var="${a[@]}"
+var=$@
+var="$@"
+EOF
+}
+
+expassign one:::two three:::four
diff --git a/tests/dollar-at-star10.sub b/tests/dollar-at-star10.sub
new file mode 100644
index 0000000..6b52b01
--- /dev/null
+++ b/tests/dollar-at-star10.sub
@@ -0,0 +1,66 @@
+# checks for array variables and positional parameter expansions losing quoted
+# null string expansions -- problem through bash-5.1
+
+set -- ''
+myvar[0]=
+a="${myvar[*]}"
+
+recho "$*"
+recho "${*}"
+
+recho "${a}"
+recho "${myvar[*]}"
+
+recho "${a:+nonnull}"
+recho "${myvar[*]:+nonnull}"
+
+a="${myvar[@]}"
+
+recho "$@"
+recho "${@}"
+
+recho "${a}"
+recho "${myvar[@]}"
+
+recho "${a:+nonnull}"
+recho "${myvar[@]:+nonnull}"
+
+# check to make sure literal CTLNULs are handled correctly
+set -- $'\x7f'
+
+recho "$@"
+recho "${@}"
+recho "${@:+nonnull}"
+
+recho "$*"
+recho "${*}"
+recho "${*:+nonnull}"
+
+shift $#
+
+# these should echo nothing
+recho "${@}"
+recho "${@:+nonnull}"
+
+unset -v a
+
+# make sure that other null expansions result in null strings where appropriate
+set -- ''
+a[0]=
+
+recho "$*"$x
+recho "${*}"$x
+
+recho "$@"$x
+recho "${@}"$x
+
+recho "${a[*]}"$x
+recho "${a[@]}"$x
+
+
+recho "$@"$x
+recho "${@}"$x
+
+recho "${a[*]}"
+recho "${a[@]}"
+
diff --git a/tests/dollar-at-star11.sub b/tests/dollar-at-star11.sub
new file mode 100644
index 0000000..b7a6ec4
--- /dev/null
+++ b/tests/dollar-at-star11.sub
@@ -0,0 +1,80 @@
+a[0]='/'
+set -- /
+
+# these should all result in the empty (null) string
+
+recho "${a[0]%?}"
+recho "${a[*]%?}"
+recho "${a[@]%?}"
+
+recho "${*%?}"
+recho "${@%?}"
+
+recho "${a[0]#?}"
+recho "${a[*]#?}"
+recho "${a[@]#?}"
+
+recho "${*#?}"
+recho "${@#?}"
+
+recho "${a[0]/\//}"
+recho "${a[*]/\//}"
+recho "${a[@]/\//}"
+
+recho "${*/\//}"
+recho "${@/\//}"
+
+recho "${a[0]:1:1}"
+# these next four will all echo /
+
+# arrays are zero-based
+recho "${a[*]:0:1}"
+recho "${a[@]:0:1}"
+# but the positional parameters start at 1
+recho "${*:1:1}"
+recho "${@:1:1}"
+
+a[0]=''
+set -- ''
+
+# arrays are zero-based
+recho "${a[*]:0:1}"
+recho "${a[@]:0:1}"
+
+recho "${*:1:1}"
+recho "${@:1:1}"
+
+# these should all result in the empty (null) string, or quoted as such
+
+recho "${a[0]@Q}"
+recho "${a[*]@Q}"
+recho "${a[@]@Q}"
+
+recho "${*@Q}"
+recho "${@@Q}"
+
+recho "${a[0]@L}"
+recho "${a[*]@L}"
+recho "${a[@]@L}"
+
+recho "${*@L}"
+recho "${@@L}"
+
+# examples from the bug report
+unset -v a
+
+a[0]='/'
+for i in "${a[@]%/}"; do recho "$i"; done
+
+a[0]=''
+for i in "${a[@]}"; do recho "$i"; done
+
+a[0]='/'
+a[1]="//"
+for i in "${a[@]%/}"; do recho "$i"; done
+
+unset -v x y
+x=('/')
+y=("${x[@]%/}")
+
+echo "${#x[@]}:${#y[@]}"
diff --git a/tests/dollar-at-star2.sub b/tests/dollar-at-star2.sub
new file mode 100644
index 0000000..64ab1eb
--- /dev/null
+++ b/tests/dollar-at-star2.sub
@@ -0,0 +1,220 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+OIFS="$IFS"
+foo=' ,foo'
+set -- "$foo"
+
+if [[ $foo = ,* ]]; then echo bad 1; else echo ok 1; fi
+if [[ $@ = ,* ]]; then echo bad 2; else echo ok 2; fi
+if [[ $* = ,* ]]; then echo bad 3; else echo ok 3; fi
+if [[ ${@} = ,* ]]; then echo bad 4; else echo ok 4; fi
+if [[ ${*} = ,* ]]; then echo bad 5; else echo ok 5; fi
+if [[ $1 = ,* ]]; then echo bad 6; else echo ok 6; fi
+
+set -- ' ,foo'
+if [[ $foo = ,* ]]; then echo bad 7; else echo ok 7; fi
+if [[ $@ = ,* ]]; then echo bad 8; else echo ok 8; fi
+if [[ $* = ,* ]]; then echo bad 9; else echo ok 9; fi
+if [[ ${@} = ,* ]]; then echo bad 10; else echo ok 10; fi
+if [[ ${*} = ,* ]]; then echo bad 11; else echo ok 11; fi
+if [[ $1 = ,* ]]; then echo bad 12; else echo ok 12; fi
+
+IFS=
+if [[ $@ = ,* ]]; then echo bad 13; else echo ok 13; fi
+if [[ $* = ,* ]]; then echo bad 14; else echo ok 14; fi
+IFS="$OIFS"
+
+foo=' ,foo'
+set -- ' ' ',foo'
+
+if [[ $@ = ,* ]]; then echo bad at 1; else echo ok at 1; fi
+if [[ ${@} = ,* ]]; then echo bad at 2; else echo ok at 2; fi
+
+if [[ $* = ,* ]]; then echo bad star 1; else echo ok star 1; fi
+if [[ ${*} = ,* ]]; then echo bad star 2; else echo ok star 2; fi
+
+foo=' ,foo'
+set -- "$foo"
+
+# expand_string_for_rhs
+
+foo2=$@
+echo "$foo2"
+
+foo2=$*
+echo "$foo2"
+
+foo2="$@"
+echo "$foo2"
+
+foo2="$*"
+echo "$foo2"
+
+# expand_word_unsplit
+case $@ in
+$foo2) echo ok at 1 ;;
+*) echo bad at 1 ;;
+esac
+
+# also uses expand_word_leave_quoted
+case $@ in
+$@) echo ok at 2;;
+*) echo bad at 2;;
+esac
+
+case $@ in
+$foo) echo ok at 3 ;;
+*) echo bad at 3;;
+esac
+
+# expand_word_unsplit
+case $* in
+$foo2) echo ok star 1 ;;
+*) echo bad star 1 ;;
+esac
+
+# also uses expand_word_leave_quoted
+case $* in
+$*) echo ok star 2;;
+*) echo bad star 2;;
+esac
+
+case $* in
+$foo) echo ok star 3 ;;
+*) echo bad star 3;;
+esac
+
+case $@ in
+$*) echo ok at-star 1;;
+*) echo bad at-star 1;;
+esac
+
+case $* in
+$@) echo ok at-star 2;;
+*) echo bad at-star 2;;
+esac
+
+foo='a b c'
+set -- $foo
+
+# expand_string_for_rhs
+IFS='|'
+foo2=$@
+echo "$foo2"
+
+foo2=$*
+echo "$foo2"
+
+foo2="$@"
+echo "$foo2"
+
+foo2="$*"
+echo "$foo2"
+
+foo="a b c"
+set -- $foo
+
+if [[ $@ = $foo ]]; then echo ok at 1; else echo bad at 1; fi
+if [[ $foo = $@ ]]; then echo ok at 2; else echo bad at 2; fi
+
+case $@ in
+$@) echo ok at 3 ;;
+*) echo bad at 3 ;;
+esac
+
+case $@ in
+$foo) echo ok at 4;;
+*) echo bad at 4;;
+esac
+
+case $foo in
+$@) echo ok at 5;;
+*) echo bad at 5;;
+esac
+IFS="$OIFS"
+
+foo="a b c"
+set -- $foo
+
+IFS=:
+if [[ $@ = $foo ]]; then echo ok at 1; else echo bad at 1; fi
+if [[ $foo = $@ ]]; then echo ok at 2; else echo bad at 2; fi
+
+case $@ in
+$@) echo ok at 3 ;;
+*) echo bad at 3 ;;
+esac
+
+case $@ in
+$foo) echo ok at 4;;
+*) echo bad at 4;;
+esac
+
+case $foo in
+$@) echo ok at 5;;
+*) echo bad at 5;;
+esac
+IFS="$OIFS"
+
+foo="a b c"
+set -- $foo
+
+IFS='|'
+foo2=$@
+
+case $@ in
+$@) echo ok at 1 ;;
+*) echo bad at 1 ;;
+esac
+
+case $foo2 in
+$foo) echo ok at 2;;
+*) echo bad at 2;;
+esac
+
+case $foo in
+$foo2) echo ok at 3;;
+*) echo bad at 3;;
+esac
+
+case $foo in
+$foo) echo ok at 4;;
+*) echo bad at 4;;
+esac
+
+case $foo2 in
+$foo2) echo ok at 5;;
+*) echo bad at 5;;
+esac
+
+case $foo2 in
+$@) echo ok at 6;;
+*) echo bad at 6;;
+esac
+
+case $@ in
+$foo2) echo ok at 7;;
+*) echo bad at 7;;
+esac
+
+case $foo in
+$@) echo ok at 8;;
+*) echo bad at 8;;
+esac
+
+case $@ in
+$foo) echo ok at 9;;
+*) echo bad at 9;;
+esac
+IFS="$OIFS"
diff --git a/tests/dollar-at-star3.sub b/tests/dollar-at-star3.sub
new file mode 100644
index 0000000..da05444
--- /dev/null
+++ b/tests/dollar-at-star3.sub
@@ -0,0 +1,57 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+unset f ; f=abcd
+
+first_char=${f[@]:0:1}
+recho $first_char
+
+first_char=${f[0]:0:1}
+recho $first_char
+
+first_char=${f:0:1}
+recho $first_char
+
+first_char="${f[@]:0:1}"
+recho $first_char
+
+first_char="${f[@]:0:1}"
+recho $first_char
+
+first_char="${f[0]:0:1}"
+recho $first_char
+
+first_char="${f:0:1}"
+recho $first_char
+
+unset f;
+f=( one two three )
+first_word=${f[@]:0:1}
+recho $first_word
+
+first_word=${f[0]:0:1}
+recho $first_word
+
+first_word=${f:0:1}
+recho $first_word
+
+unset f;
+f=( one two three )
+first_word=${f[@]:0:1}
+recho $first_word
+
+set -- abc def ghi
+
+printf '<%s> ' "123 $@ 456"; echo
+printf '<%s> ' "123 $@\ 456"; echo
+
diff --git a/tests/dollar-at-star4.sub b/tests/dollar-at-star4.sub
new file mode 100644
index 0000000..9f7da8e
--- /dev/null
+++ b/tests/dollar-at-star4.sub
@@ -0,0 +1,112 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# tests for quoted and unquoted, split and unsplit expansions of $@ and $*
+# Posix interpretation 221 speaks to this issue
+
+set -- a b
+IFS=
+x=abc
+
+printf "<%s>\n" ${x#$*}
+
+a="a bc"
+echo ${a#$*}
+unset x a
+
+a=$@
+echo "$a"
+
+a=$*
+echo "$a"
+
+printf '<%s>' $@ ; echo
+
+IFS='
+'
+
+a=$@
+echo "$a"
+
+a=$*
+echo "$a"
+
+unset a
+
+unset IFS
+set a b "c d"
+printf '<%s>' $* ; echo
+printf '<%s>' ${q-$*} ; echo
+
+IFS=
+set a b "c d"
+printf '<%s>' $* ; echo
+printf '<%s>' ${q-$*} ; echo
+
+IFS=:
+set a b
+printf '<%s>' ${foo=$*} ; echo
+printf '<%s>' "${foo}" ; echo
+
+unset foo
+IFS='
+'
+printf '<%s>' ${foo=$@} ; echo
+printf '<%s>' "$foo" ; echo
+
+IFS=?
+set a c
+foo=abcd
+
+echo ${foo#"$*"}
+echo "${foo#$*}"
+
+echo "${foo#'a?c'}"
+echo "${foo#a?c}"
+
+IFS=?
+set a c
+str=a$'\001'c
+pat=a$'\001'
+echo "${str#$pat}"
+
+set a b
+IFS=:
+
+a=$@
+recho "$a"
+
+recho ${foo=$*}
+recho "$foo"
+
+unset foo
+IFS='
+'
+recho ${foo=$@}
+recho "$foo"
+
+shift $#
+unset foo x
+
+set -- a b
+x=abc
+
+IFS=
+printf "<%s>\n" ${x#$*}
+printf "<%s>\n" "${x#$*}"
+
+x=abcd
+set a c
+IFS='?'
+printf "<%s>\n" ${x#$*}
+printf "<%s>\n" "${x#$*}"
diff --git a/tests/dollar-at-star5.sub b/tests/dollar-at-star5.sub
new file mode 100644
index 0000000..d07c61a
--- /dev/null
+++ b/tests/dollar-at-star5.sub
@@ -0,0 +1,66 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# testing various combinations of quoted and unquoted expansions of $@, and
+# whether they generate empty words after expansion
+
+n() { echo "$#"; }
+
+n "$@"
+n ${foo-"$@"}
+n "${foo-$@}"
+
+n ""$@
+n """$@"
+
+n $(true)$@
+n "$(true)$@"
+n "$(true)$@"
+n "$(true)""$@"
+
+n $xxx$@
+n "$xxx$@"
+n $xxx"$@"
+n "$xxx""$@"
+
+recho $xxx"$@"
+echo after 1
+
+recho "$xxx$@"
+echo after 2
+
+recho ${foo:-$xxx"$@"}
+echo after 3
+
+# this is where these things start to differ
+echo same as 1
+recho "${foo:-$xxx"$@"}"
+echo same as 2
+recho "${foo:-$xxx$@}"
+
+echo null fields
+recho ""$@
+recho """$@"
+
+echo null fields in rhs
+echo null string with unquoted '$@'
+recho ${foo:-""$@}
+echo null string with quoted '$@'
+recho ${foo:-"""$@"}
+
+echo assignment
+recho "${foo=$@}"
+echo variable
+recho "$foo"
+echo dollar-at
+recho "${@}"
diff --git a/tests/dollar-at-star6.sub b/tests/dollar-at-star6.sub
new file mode 100644
index 0000000..09353b8
--- /dev/null
+++ b/tests/dollar-at-star6.sub
@@ -0,0 +1,42 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+OIFS="$IFS"
+arr=(a b c)
+
+recho ${arr[@]@Q}
+recho "${arr[@]@Q}"
+
+IFS="'"
+recho ${arr[@]@Q}
+recho "${arr[@]@Q}"
+IFS="$OIFS"
+
+arr=("'a'" "'b'" "'c'")
+
+IFS="'"
+recho ${arr[@]}
+recho "${arr[@]}"
+IFS="$OIFS"
+
+IFS="'"
+a="'a'"
+recho $a
+recho "$a"
+IFS="$OIFS"
+
+set -- "'a'" "'b'" "'c'"
+
+IFS="'"
+recho "${@}"
+recho "$@"
diff --git a/tests/dollar-at-star7.sub b/tests/dollar-at-star7.sub
new file mode 100644
index 0000000..e4e63b7
--- /dev/null
+++ b/tests/dollar-at-star7.sub
@@ -0,0 +1,38 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+IFS='' # testing with only empty IFS
+
+set -- this is a test
+
+printf '|%s|\n' ${1+"$@"}
+echo
+printf '|%s|\n' "${1+$@}"
+echo
+printf '|%s|\n' "$@"
+echo
+
+printf '|%s|\n' ${1-"$@"}
+printf '|%s|\n' "${1-$@}"
+
+echo
+: ${foo:="$@"}
+printf '|%s|\n' "$foo"
+
+unset foo
+: "${foo:=$@}"
+printf '|%s|\n' "$foo"
+
+unset foo
+printf '|%s|\n' ${foo-"$@"}
+printf '|%s|\n' "${foo-$@}"
diff --git a/tests/dollar-at-star8.sub b/tests/dollar-at-star8.sub
new file mode 100644
index 0000000..7e1b688
--- /dev/null
+++ b/tests/dollar-at-star8.sub
@@ -0,0 +1,14 @@
+function f {
+ typeset -a a
+ a=("$@")
+ typeset IFS=,
+ typeset a1="${a[@]} ${a[*]} $@ $* ${@} ${*}"
+ typeset a2=${a[@]}\ ${a[*]}\ $@\ $*\ ${@}\ ${*} a3 a4
+ a3="${a[@]} ${a[*]} $@ $* ${@} ${*}"
+ a4=${a[@]}\ ${a[*]}\ $@\ $*\ ${@}\ ${*}
+ unset -v IFS
+ printf '%s\n' "a1=$a1" "a2=$a2" "a3=$a3" "a4=$a4"
+}
+
+echo
+f a b c
diff --git a/tests/dollar-at-star9.sub b/tests/dollar-at-star9.sub
new file mode 100644
index 0000000..e5062f7
--- /dev/null
+++ b/tests/dollar-at-star9.sub
@@ -0,0 +1,278 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+IFS=$' \t\n' # or any other IFS
+set -- ''
+recho ${v= "$*" }
+recho "$v"
+unset -v v
+
+IFS=''
+set -- '' ''
+recho ${v= "$*" }
+recho "$v"
+unset -v v
+
+IFS=$' \t\n' # or any other IFS
+unset -v v
+
+set -- ''
+recho ${v= "$@" }
+recho "$v"
+unset v
+recho ${v= $@ }
+recho "$v"
+unset v
+recho ${v= $@"" }
+recho "$v"
+unset v
+recho ${v= ${@} }
+recho "$v"
+unset v
+recho ${v= ${@}"" }
+recho "$v"
+unset v
+
+set -- '' ''
+recho ${v= $@ }
+recho "$v"
+unset v
+recho ${v= "$@" }
+recho "$v"
+unset v
+recho "${v= $@}"
+recho "$v"
+unset v
+recho ${v= "$@"}
+recho "$v"
+unset v
+
+IFS=
+
+set -- X
+X=X
+
+recho ${0+ "$@" }
+recho ${0+ $@ }
+recho ${0+ $* }
+
+recho ${0+ "$X" }
+recho ${0+ $X }
+recho ${0+ $X }
+
+recho ${0+ "$@" }
+recho "$Y"
+unset Y
+recho ${0+ $@ }
+recho "$Y"
+unset Y
+recho ${0+ $* }
+recho "$Y"
+unset Y
+
+recho ${Y:= "$X" }
+recho "$Y"
+unset Y
+recho ${Y:= $X }
+recho "$Y"
+unset Y
+recho ${Y:= $X }
+recho "$Y"
+unset Y
+
+IFS=
+
+unset -v X Y
+
+set -- X Y
+X='X Y'
+
+recho ${0+ "$@" }
+recho ${0+ $@ }
+recho ${0+ $* }
+
+recho ${0+ "$X" }
+recho ${0+ $X }
+recho ${0+ $X }
+
+recho ${Y:= "$@" }
+recho "$Y"
+unset Y
+recho ${Y:= $@ }
+recho "$Y"
+unset Y
+recho ${Y:= $* }
+recho "$Y"
+unset Y
+
+recho ${Y:= "$X" }
+recho "$Y"
+unset Y
+recho ${Y:= $X }
+recho "$Y"
+unset Y
+recho ${Y:= $X }
+recho "$Y"
+unset Y
+
+IFS=''
+set -- ' X '
+
+unset x y
+
+x=$*
+y=${*:1}
+
+recho "$x"
+recho "$y"
+
+unset x y
+
+recho ${x=$*}
+recho ${y=${*:1}}
+
+set -- b a
+declare -A A=([b]= [a]=)
+
+x=$*
+y=${!A[*]}
+
+unset A
+
+recho "$x"
+recho "$y"
+
+unset x y
+
+recho ${x=$*}
+recho ${y=${!A[*]}}
+
+unset x y
+
+recho ${x-$*}
+recho ${y-${!A[*]}} # this isn't right yet
+
+IFS=:
+set -- a b
+ind=*
+
+unset x y
+
+x=$*
+y=${!ind}
+
+recho "$x"
+recho "$y"
+
+unset x y
+
+recho ${x-$*}
+recho ${y-${!ind}} # this isn't right yet
+
+unset x y
+
+recho ${x=$*}
+recho ${y=${!ind}}
+
+set -- ' X '
+IFS=$' \t\n'
+
+x=$*
+y=${!ind};
+
+recho "$x"
+recho "$y"
+
+IFS=''
+x=$*
+y=${!ind}
+
+recho "$x"
+recho "$y"
+
+IFS=:
+set -- a b
+ind=*
+
+unset x y
+
+recho ${x-$*}
+recho ${y-${!ind}} # this isn't right yet
+
+unset x y
+
+recho ${x=$*}
+recho ${y=${!ind}}
+
+set -- ' X '
+IFS=$' \t\n'
+
+unset x y
+
+x=$*
+y=${!ind};
+
+recho "$x"
+recho "$y"
+
+IFS=''
+x=$*
+y=${!ind}
+
+recho "$x"
+recho "$y"
+
+IFS=''
+set -- $'\177'
+
+unset -v var
+
+recho "${*:1}"
+var=${*:1}
+recho "$var"
+
+unset var
+recho ${var=${*:1}}
+recho "$var"
+
+declare -a a=($'\177')
+
+unset var
+var=${a[*]:0}
+recho "$var"
+
+unset var
+recho ${var=${a[*]:0}}
+unset var
+
+set -- $'\177'
+ind='*'
+
+recho $*
+var=${!ind}
+recho "$var"
+
+unset var
+recho ${var=${!ind}}
+recho "$var"
+
+declare -A A=([0]=$'\177')
+
+unset var
+var=${A[*]:0}
+recho "$var"
+
+# this isn't really right yet
+unset var
+recho ${var=${A[*]:0}}
+recho "$var"
diff --git a/tests/dollar-at1.sub b/tests/dollar-at1.sub
new file mode 100644
index 0000000..c5079d6
--- /dev/null
+++ b/tests/dollar-at1.sub
@@ -0,0 +1,42 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+echo_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..16defbd
--- /dev/null
+++ b/tests/dollar-at2.sub
@@ -0,0 +1,32 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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-at4.sub b/tests/dollar-at4.sub
new file mode 100644
index 0000000..c8de866
--- /dev/null
+++ b/tests/dollar-at4.sub
@@ -0,0 +1,10 @@
+set 'a b' 'c d'
+
+recho "$@"
+recho $@
+
+quoted="$@"
+unquoted=$@
+
+recho "$quoted"
+recho "$unquoted"
diff --git a/tests/dollar-at5.sub b/tests/dollar-at5.sub
new file mode 100644
index 0000000..9b26c39
--- /dev/null
+++ b/tests/dollar-at5.sub
@@ -0,0 +1,95 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+args() { printf '<%s> ' "$@"; echo; }
+
+set -- 1 2 3 4 5
+
+args "${@} ${1}"
+args "${1} ${@}"
+args "${1}${@}${1}"
+args "${1} ${@} ${1}"
+args ${1}"$@"${1}
+args "$@"${1}
+args ${1}"$@"
+
+args "$@""${1}"
+args "${1}""$@"
+
+args "${@}foo"
+args ${@}${1}
+args ${@}foo
+
+IFS=
+args "$@""${1}"
+args "${1}""$@"
+
+args ${@}${1}
+args ${1}${@}
+args ${@}foo
+
+echo second set:
+IFS=$' \t\n'
+set -- '1 2' 3 4 5
+
+args "${@} ${1}"
+args "${1} ${@}"
+
+args "${1}${@}${1}"
+args "${1} ${@} ${1}"
+args ${1}"$@"${1}
+args "$@"${1}
+args ${1}"$@"
+
+args "$@""${1}"
+args "${1}""$@"
+
+args "${@}foo"
+args ${@}${1}
+args ${@}foo
+
+IFS=
+
+args "$@""${1}"
+args "${1}""$@"
+
+args ${@}${1}
+args ${1}${@}
+args ${@}foo
+
+echo third set:
+IFS=$' \t\n'
+
+alias declare=typeset
+
+a(){ echo
+ echo '"${@:2}a3 a2" a$1 #works as long as $1 and 3 are swapped'
+ echo "${@:2}a3 a2" a$1
+ "${@:2}a3 a2" a$1
+ echo $?
+ a=("${@}");}
+b(){ echo
+ echo '"${@:2}b$1 b2" b3 #fails! why?'
+ echo "${@:2}b$1 b2" b3
+ "${@:2}b$1 b2" b3
+ echo $?
+ b=("${@}");}
+c(){ echo
+ echo '${@:2}c$1 c2 c3 #works as long as quoting omitted'
+ echo ${@:2}c$1 c2 c3
+ ${@:2}c$1 c2 c3
+ echo $?
+ c=("${@}");}
+a x set y z;declare -p a
+b x set y z;declare -p b
+c x set y z;declare -p c
diff --git a/tests/dollar-at6.sub b/tests/dollar-at6.sub
new file mode 100644
index 0000000..791fd89
--- /dev/null
+++ b/tests/dollar-at6.sub
@@ -0,0 +1,43 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+set -- '';
+
+recho "${@}" x
+recho "${@:1}" x
+
+set -- "${@:1}"
+echo "$#"
+
+set -- '' ''
+
+recho "${@:1}" x
+recho "${@:1:1}" x
+
+typeset -a A # ksh93 needs this
+A=('' '')
+recho "${A[@]:0}" x
+
+recho "${A[@]:0:1}" x
+
+recho "${A[@]:1}" x
+
+set -- ''
+
+recho "${@/foo/bar}"
+recho "${@^^[abcde]}"
+
+A=( '' )
+
+recho "${A[@]/foo/bar}"
+recho "${A[@],,[abcde]}"
diff --git a/tests/dollar-at7.sub b/tests/dollar-at7.sub
new file mode 100644
index 0000000..cde1164
--- /dev/null
+++ b/tests/dollar-at7.sub
@@ -0,0 +1,59 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+set -- ''
+
+recho 1 ''"$@"
+recho 2 """$@"
+
+recho 3 "$@""$@"
+recho 4 "$x""$@"
+
+set --
+
+echo -----
+recho 1 ''"$@"
+recho 2 """$@"
+
+recho 3 "$@""$@"
+recho 4 "$x""$@"
+
+set -- X
+
+echo ------
+recho 1 ''"${@/*}"
+recho 2 """${@/*}"
+
+recho 3 "$x""${@/*}"
+
+recho 4 ''"${@#X}"
+recho 5 """${@#X}"
+
+recho 6 "$x""${@#X}"
+
+set --
+
+echo -----
+recho 1 ''"${@/*}"
+recho 2 """${@/*}"
+
+recho 3 "$x""${@/*}"
+
+recho 4 ''"${@#X}"
+recho 5 """${@#X}"
+
+recho 6 "$x""${@#X}"
+
+echo -----
+recho 1 "$novar${*}$(echo)"
+recho 2 ''"$novar${@}$(echo)"
diff --git a/tests/dollar-star1.sub b/tests/dollar-star1.sub
new file mode 100644
index 0000000..3e5ec36
--- /dev/null
+++ b/tests/dollar-star1.sub
@@ -0,0 +1,44 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+set -- 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-star10.sub b/tests/dollar-star10.sub
new file mode 100644
index 0000000..fce9ec1
--- /dev/null
+++ b/tests/dollar-star10.sub
@@ -0,0 +1,92 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+oIFS=$IFS
+
+set -- ''
+
+unset v
+recho ${v= ''}
+recho $v
+unset v
+recho ${v=''}
+recho $v
+unset v
+recho ${v= $*}
+recho $v
+unset v
+recho ${v=$*}
+recho $v
+unset v
+recho ${v='' }
+recho $v
+unset v
+recho ${v= '' }
+recho $v
+unset v
+recho ${v=$* }
+recho $v
+unset v
+recho ${v= $* }
+recho $v
+
+unset IFS
+
+unset v
+recho ${v= ''}
+recho $v
+unset v
+recho ${v=''}
+recho $v
+unset v
+recho ${v= $*}
+recho $v
+unset v
+recho ${v=$*}
+recho $v
+unset v
+recho ${v='' }
+recho $v
+unset v
+recho ${v= '' }
+recho $v
+unset v
+recho ${v=$* }
+recho $v
+unset v
+recho ${v= $* }
+recho $v
+
+unset -v v
+IFS=$oIFS
+
+# This shouldn't output anything
+set -- '' ''
+
+unset -v v
+recho ${v=$*}
+unset -v v
+recho ${v= $*}
+unset -v v
+recho ${v=$* }
+unset -v v
+recho ${v= $* }
+
+unset -v v IFS
+recho ${v=$*}
+unset -v v
+recho ${v= $*}
+unset -v v
+recho ${v= $* }
+unset -v v
+recho ${v= $*}
diff --git a/tests/dollar-star2.sub b/tests/dollar-star2.sub
new file mode 100644
index 0000000..78e00a0
--- /dev/null
+++ b/tests/dollar-star2.sub
@@ -0,0 +1,39 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+set 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..a6ef09f
--- /dev/null
+++ b/tests/dollar-star3.sub
@@ -0,0 +1,31 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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..abd8bcc
--- /dev/null
+++ b/tests/dollar-star5.sub
@@ -0,0 +1,29 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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-star6.sub b/tests/dollar-star6.sub
new file mode 100644
index 0000000..095ec04
--- /dev/null
+++ b/tests/dollar-star6.sub
@@ -0,0 +1,32 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+recho "A${*:-w}R"
+recho "A${*-w}R"
+recho "A${*}R"
+
+set -- ""
+
+recho "A${*:-w}R"
+recho "A${*-w}R"
+recho "A${*}R"
+
+set -- $'\177'
+
+recho "A${*:+w}R"
+recho "A${*+w}R"
+recho "A${*}R"
+
+recho A${*:+w}R
+recho A${*+w}R
+recho A${*}R
diff --git a/tests/dollar-star7.sub b/tests/dollar-star7.sub
new file mode 100644
index 0000000..db352bf
--- /dev/null
+++ b/tests/dollar-star7.sub
@@ -0,0 +1,43 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# if IFS side effects in ${IFS=} assignments take place, how do you cope with
+# later changes to IFS in the same set of expansions? You've already
+# committed to using the first character of the (old) IFS to expand $* in
+# the previous expansions, and changing it to not include ' ', for instance,
+# results in the first couple of ${*} below not being split at all
+
+set -f -- a b c
+
+unset -v IFS
+printf '<%s> ' ${*}${IFS=}${*}${IFS:=-}"${*}"
+echo
+printf "after 1: IFS "
+echo "${IFS-unset}"
+recho "$*"
+
+set -f -- a 'b c' d
+unset -v IFS
+printf '<%s> ' ${*}${IFS=}${*}${IFS:=-}"${*}"
+echo
+printf "after 2: IFS "
+echo "${IFS-unset}"
+recho "$*"
+
+unset -v IFS
+recho $*
+recho "$*"
+
+IFS=' '
+recho $*
+recho "$*"
diff --git a/tests/dollar-star8.sub b/tests/dollar-star8.sub
new file mode 100644
index 0000000..e626564
--- /dev/null
+++ b/tests/dollar-star8.sub
@@ -0,0 +1,34 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+IFS=
+set "abc" "def ghi" "jkl"
+
+set ${1+$*}
+printf '<%s>\n' "$#" "$@"
+
+set "abc" "def ghi" "jkl"
+set $*
+printf '<%s>\n' "$#" "$@"
+
+printf '<%s>\n' $* ;
+printf '<%s>\n' ${q:-$*}
+printf '<%s>\n' "${q:-$*}"
+
+IFS=:
+printf '<%s>\n' $* ;
+printf '<%s>\n' ${q:-$*}
+printf '<%s>\n' "${q:-$*}"
+
+unset -v IFS
+printf '<%s>\n' $* $@
diff --git a/tests/dollar-star9.sub b/tests/dollar-star9.sub
new file mode 100644
index 0000000..d46de46
--- /dev/null
+++ b/tests/dollar-star9.sub
@@ -0,0 +1,59 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+set -- 1 2
+
+IFS=
+
+a=$* b=${*}
+c=${*/} d=${*#} e=${*%} f=${*:1}
+printf '<%s>' "$a" "$b" "$c" "$d" "$e" "$f"; echo
+
+unset a b c d e f
+: ${a=$*} ${b=${*}} ${c=${*/}}
+: ${d=${*#}} ${e=${*%}} ${f=${*:1}}
+printf '<%s>' "$a" "$b" "$c" "$d" "$e" "$f" ; echo
+
+unset f g
+f=${*,,} g=${*@Q}
+printf '<%s>' "$f" "$g" ; echo
+
+unset -v a b c d e f g
+unset var
+
+# resetting IFS here
+
+IFS=$' \t\n'
+
+printf '%s\n' "${*:1}"
+var=${*:1}; printf '%s\n' "$var"
+var="${*:1}"; printf '%s\n' "$var"
+
+unset var
+recho ${var-${*}}
+recho ${var-${*:1}}
+recho "${var-${*:1}}"
+recho ${var-"${*:1}"}
+
+unset var
+recho ${var=${*}}
+printf 'var=%s\n' "$var"
+unset var
+recho ${var=${*:1}}
+printf 'var=%s\n' "$var"
+
+a=${*:1}
+recho "$a"
+
+: ${b=${*:1}}
+recho "$b"
diff --git a/tests/dollar.right b/tests/dollar.right
new file mode 100644
index 0000000..10c5cca
--- /dev/null
+++ b/tests/dollar.right
@@ -0,0 +1,744 @@
+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
+var=${a[*]} ... one:::two:three:::four
+var="${a[*]}" ... one:::two:three:::four
+var=$* ... one:::two:three:::four
+var="$*" ... one:::two:three:::four
+var=${a[@]} ... one:::two three:::four
+var="${a[@]}" ... one:::two three:::four
+var=$@ ... one:::two three:::four
+var="$@" ... one:::two three:::four
+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 at 1
+ok at 2
+ok star 1
+ok star 2
+ ,foo
+ ,foo
+ ,foo
+ ,foo
+ok at 1
+ok at 2
+ok at 3
+ok star 1
+ok star 2
+ok star 3
+ok at-star 1
+ok at-star 2
+a b c
+a|b|c
+a b c
+a|b|c
+ok at 1
+ok at 2
+ok at 3
+ok at 4
+ok at 5
+ok at 1
+ok at 2
+ok at 3
+ok at 4
+ok at 5
+ok at 1
+ok at 2
+ok at 3
+ok at 4
+ok at 5
+ok at 6
+ok at 7
+ok at 8
+ok at 9
+argv[1] = <a>
+argv[1] = <a>
+argv[1] = <a>
+argv[1] = <a>
+argv[1] = <a>
+argv[1] = <a>
+argv[1] = <a>
+argv[1] = <one>
+argv[1] = <o>
+argv[1] = <o>
+argv[1] = <one>
+<123 abc> <def> <ghi 456>
+<123 abc> <def> <ghi\ 456>
+<c>
+a bc
+a b
+ab
+<a><b>
+a b
+a b
+<a><b><c><d>
+<a><b><c><d>
+<a><b><c d>
+<a><b><c d>
+<a><b>
+<a:b>
+<a><b>
+<a b>
+abcd
+d
+abcd
+d
+c
+argv[1] = <a b>
+argv[1] = <abcd>
+argv[1] = <abcd>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a b>
+<c>
+<c>
+<d>
+<d>
+0
+0
+1
+1
+1
+0
+0
+0
+1
+0
+0
+0
+1
+after 1
+after 2
+after 3
+same as 1
+argv[1] = <>
+same as 2
+argv[1] = <>
+null fields
+argv[1] = <>
+argv[1] = <>
+null fields in rhs
+null string with unquoted $@
+argv[1] = <>
+null string with quoted $@
+argv[1] = <>
+assignment
+argv[1] = <>
+variable
+argv[1] = <>
+dollar-at
+argv[1] = <'a'>
+argv[2] = <'b'>
+argv[3] = <'c'>
+argv[1] = <'a'>
+argv[2] = <'b'>
+argv[3] = <'c'>
+argv[1] = <>
+argv[2] = <a>
+argv[3] = <>
+argv[4] = <>
+argv[5] = <b>
+argv[6] = <>
+argv[7] = <>
+argv[8] = <c>
+argv[1] = <'a'>
+argv[2] = <'b'>
+argv[3] = <'c'>
+argv[1] = <>
+argv[2] = <a>
+argv[3] = <>
+argv[4] = <>
+argv[5] = <b>
+argv[6] = <>
+argv[7] = <>
+argv[8] = <c>
+argv[1] = <'a'>
+argv[2] = <'b'>
+argv[3] = <'c'>
+argv[1] = <>
+argv[2] = <a>
+argv[1] = <'a'>
+argv[1] = <'a'>
+argv[2] = <'b'>
+argv[3] = <'c'>
+argv[1] = <'a'>
+argv[2] = <'b'>
+argv[3] = <'c'>
+|this|
+|is|
+|a|
+|test|
+
+|this|
+|is|
+|a|
+|test|
+
+|this|
+|is|
+|a|
+|test|
+
+|this|
+|this|
+
+|this is a test|
+|this is a test|
+|this|
+|is|
+|a|
+|test|
+|this|
+|is|
+|a|
+|test|
+
+a1=a b c a,b,c a b c a,b,c a b c a,b,c
+a2=a b c a,b,c a b c a,b,c a b c a,b,c
+a3=a b c a,b,c a b c a,b,c a b c a,b,c
+a4=a b c a,b,c a b c a,b,c a b c a,b,c
+argv[1] = < >
+argv[1] = < >
+argv[1] = < >
+argv[1] = < >
+argv[1] = < >
+argv[1] = < >
+argv[1] = < >
+argv[1] = < >
+argv[1] = < >
+argv[1] = < >
+argv[1] = < >
+argv[1] = < >
+argv[1] = < >
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = <>
+argv[1] = < X >
+argv[1] = <>
+argv[1] = < X >
+argv[1] = <>
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = < X>
+argv[2] = <Y >
+argv[1] = < X>
+argv[2] = <Y >
+argv[1] = < X>
+argv[2] = <Y >
+argv[1] = < X Y >
+argv[1] = < X Y >
+argv[1] = < X Y >
+argv[1] = < X Y >
+argv[1] = < X Y >
+argv[1] = < X Y >
+argv[1] = < X Y >
+argv[1] = < XY >
+argv[1] = < XY >
+argv[1] = < X Y >
+argv[1] = < X Y >
+argv[1] = < X Y >
+argv[1] = < X Y >
+argv[1] = < X Y >
+argv[1] = < X Y >
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = <ba>
+argv[1] = <ba>
+argv[1] = <ba>
+argv[1] = <b>
+argv[2] = <a>
+argv[1] = <a:b>
+argv[1] = <a:b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = < X >
+argv[1] = <^?>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <^?>
+argv[1] = <^?>
+argv[1] = <^?>
+argv[1] = <^?>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <^?>
+argv[1] = <^?>
+argv[1] = <nonnull>
+argv[1] = <^?>
+argv[1] = <^?>
+argv[1] = <nonnull>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = </>
+argv[1] = </>
+argv[1] = </>
+argv[1] = </>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <''>
+argv[1] = <''>
+argv[1] = <''>
+argv[1] = <''>
+argv[1] = <''>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = </>
+1:1
+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
+argv[1] = <a b>
+argv[2] = <c d>
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <c>
+argv[4] = <d>
+argv[1] = <a b c d>
+argv[1] = <a b c d>
+<1> <2> <3> <4> <5 1>
+<1 1> <2> <3> <4> <5>
+<11> <2> <3> <4> <51>
+<1 1> <2> <3> <4> <5 1>
+<11> <2> <3> <4> <51>
+<1> <2> <3> <4> <51>
+<11> <2> <3> <4> <5>
+<1> <2> <3> <4> <51>
+<11> <2> <3> <4> <5>
+<1> <2> <3> <4> <5foo>
+<1> <2> <3> <4> <51>
+<1> <2> <3> <4> <5foo>
+<1> <2> <3> <4> <51>
+<11> <2> <3> <4> <5>
+<1> <2> <3> <4> <51>
+<11> <2> <3> <4> <5>
+<1> <2> <3> <4> <5foo>
+second set:
+<1 2> <3> <4> <5 1 2>
+<1 2 1 2> <3> <4> <5>
+<1 21 2> <3> <4> <51 2>
+<1 2 1 2> <3> <4> <5 1 2>
+<1> <21 2> <3> <4> <51> <2>
+<1 2> <3> <4> <51> <2>
+<1> <21 2> <3> <4> <5>
+<1 2> <3> <4> <51 2>
+<1 21 2> <3> <4> <5>
+<1 2> <3> <4> <5foo>
+<1> <2> <3> <4> <51> <2>
+<1> <2> <3> <4> <5foo>
+<1 2> <3> <4> <51 2>
+<1 21 2> <3> <4> <5>
+<1 2> <3> <4> <51 2>
+<1 21 2> <3> <4> <5>
+<1 2> <3> <4> <5foo>
+third set:
+
+"${@:2}a3 a2" a$1 #works as long as $1 and 3 are swapped
+set y za3 a2 ax
+0
+declare -a a=([0]="y" [1]="za3 a2" [2]="ax")
+
+"${@:2}b$1 b2" b3 #fails! why?
+set y zbx b2 b3
+0
+declare -a b=([0]="y" [1]="zbx b2" [2]="b3")
+
+${@:2}c$1 c2 c3 #works as long as quoting omitted
+set y zcx c2 c3
+0
+declare -a c=([0]="y" [1]="zcx" [2]="c2" [3]="c3")
+argv[1] = <>
+argv[2] = <x>
+argv[1] = <>
+argv[2] = <x>
+1
+argv[1] = <>
+argv[2] = <>
+argv[3] = <x>
+argv[1] = <>
+argv[2] = <x>
+argv[1] = <>
+argv[2] = <>
+argv[3] = <x>
+argv[1] = <>
+argv[2] = <x>
+argv[1] = <>
+argv[2] = <x>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <AwR>
+argv[1] = <AwR>
+argv[1] = <AR>
+argv[1] = <AwR>
+argv[1] = <AR>
+argv[1] = <AR>
+argv[1] = <AwR>
+argv[1] = <AwR>
+argv[1] = <A^?R>
+argv[1] = <AwR>
+argv[1] = <AwR>
+argv[1] = <A^?R>
+<a> <b> <ca> <b> <c-a-b-c>
+after 1: IFS -
+argv[1] = <a-b-c>
+<a> <b> <c> <da> <b c> <d-a-b c-d>
+after 2: IFS -
+argv[1] = <a-b c-d>
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <c>
+argv[4] = <d>
+argv[1] = <a b c d>
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <c>
+argv[4] = <d>
+argv[1] = <a b c d>
+<3>
+<abc>
+<def ghi>
+<jkl>
+<3>
+<abc>
+<def ghi>
+<jkl>
+<abc>
+<def ghi>
+<jkl>
+<abc>
+<def ghi>
+<jkl>
+<abcdef ghijkl>
+<abc>
+<def ghi>
+<jkl>
+<abc>
+<def ghi>
+<jkl>
+<abc:def ghi:jkl>
+<abc>
+<def>
+<ghi>
+<jkl>
+<abc>
+<def>
+<ghi>
+<jkl>
+argv[1] = <1>
+argv[2] = <>
+argv[1] = <2>
+argv[2] = <>
+argv[1] = <3>
+argv[2] = <>
+argv[1] = <4>
+argv[2] = <>
+-----
+argv[1] = <1>
+argv[2] = <>
+argv[1] = <2>
+argv[2] = <>
+argv[1] = <3>
+argv[1] = <4>
+argv[2] = <>
+------
+argv[1] = <1>
+argv[2] = <>
+argv[1] = <2>
+argv[2] = <>
+argv[1] = <3>
+argv[2] = <>
+argv[1] = <4>
+argv[2] = <>
+argv[1] = <5>
+argv[2] = <>
+argv[1] = <6>
+argv[2] = <>
+-----
+argv[1] = <1>
+argv[2] = <>
+argv[1] = <2>
+argv[2] = <>
+argv[1] = <3>
+argv[2] = <>
+argv[1] = <4>
+argv[2] = <>
+argv[1] = <5>
+argv[2] = <>
+argv[1] = <6>
+argv[2] = <>
+-----
+argv[1] = <1>
+argv[2] = <>
+argv[1] = <2>
+argv[2] = <>
+<12><12><12><12><12><12>
+<12><12><12><12><12><12>
+<12><'1''2'>
+1 2
+1 2
+1 2
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = <1 2>
+argv[1] = <1 2>
+argv[1] = <1>
+argv[2] = <2>
+var=1 2
+argv[1] = <1>
+argv[2] = <2>
+var=1 2
+argv[1] = <1 2>
+argv[1] = <1 2>
diff --git a/tests/dstack.right b/tests/dstack.right
new file mode 100644
index 0000000..8f9d38c
--- /dev/null
+++ b/tests/dstack.right
@@ -0,0 +1,55 @@
+./dstack.tests: line 19: pushd: /tmp/xxx-notthere: No such file or directory
+./dstack.tests: line 22: pushd: no other directory
+./dstack.tests: line 23: popd: directory stack empty
+./dstack.tests: line 26: pushd: -m: invalid number
+pushd: usage: pushd [-n] [+N | -N | dir]
+./dstack.tests: line 27: popd: -m: invalid number
+popd: usage: popd [-n] [+N | -N]
+./dstack.tests: line 28: dirs: -m: invalid number
+dirs: usage: dirs [-clpv] [+N] [-N]
+./dstack.tests: line 29: 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 71: dirs: 9: directory stack index out of range
+./dstack.tests: line 71: dirs: 9: directory stack index out of range
+./dstack.tests: line 72: pushd: +9: directory stack index out of range
+./dstack.tests: line 72: pushd: -9: directory stack index out of range
+./dstack.tests: line 73: popd: +9: directory stack index out of range
+./dstack.tests: line 73: 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..116e935
--- /dev/null
+++ b/tests/dstack.tests
@@ -0,0 +1,100 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+export LC_ALL=C
+export LANG=C
+
+dirs -c
+# error -- non-existent 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..0873319
--- /dev/null
+++ b/tests/dstack2.tests
@@ -0,0 +1,49 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+wdir=$PWD
+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]}
+
+cd "$wdir"
diff --git a/tests/dynvar.right b/tests/dynvar.right
new file mode 100644
index 0000000..e1344c6
--- /dev/null
+++ b/tests/dynvar.right
@@ -0,0 +1,7 @@
+BASHPID ok
+BASH_ARGV0 ok
+BASH_ARGV0 ok
+SECONDS ok
+EPOCHSECONDS ok
+EPOCHREALTIME ok
+echo $BASH_COMMAND
diff --git a/tests/dynvar.tests b/tests/dynvar.tests
new file mode 100644
index 0000000..ddf69ed
--- /dev/null
+++ b/tests/dynvar.tests
@@ -0,0 +1,102 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# specvar -- test some of the dynamic variables
+
+# BASHPID
+pid=$$
+bpid=$BASHPID
+subpid=$( (echo $BASHPID) )
+
+if [ "$bpid" -ne "$subpid" ]; then echo BASHPID ok; fi
+
+# BASH_ARGV0
+
+BASH_ARGV0=hello
+case $0 in
+hello) echo BASH_ARGV0 ok ;;
+*) echo "BASH_ARGV0 mismatch: $BASH_ARGV0 ($0)" >&2 ;;
+esac
+
+setarg0()
+{
+ BASH_ARGV0="$1"
+}
+
+setarg0 arg0
+case $0 in
+arg0) echo BASH_ARGV0 ok ;;
+*) echo "BASH_ARGV0 mismatch: $BASH_ARGV0 ($0)" >&2 ;;
+esac
+
+# SECONDS
+before=$SECONDS
+sleep 2
+after=$SECONDS
+
+if (( $after > $before )); then echo SECONDS ok; fi
+unset before after
+
+# EPOCHSECONDS
+
+# not exact, but should work
+# date +%s should be portable enough now
+# then try gawk, perl, python in that order
+now1=$(date +%s 2>/dev/null) D=date
+[ -z "$now1" ] &&
+{
+ now1=$(gawk 'BEGIN { print systime(); }' 2>/dev/null) D=gawk
+ [ -z "$now1" ] && now1=$(perl -e 'print time' 2>/dev/null) D=perl
+ [ -z "$now1" ] && now1=$(python -c 'import time; ts = int(time.time()); print(ts)' 2>/dev/null) D=python
+}
+now2=$EPOCHSECONDS
+
+# use a window of +-1 second
+offset=1
+if [[ -z $now1 ]]; then
+ echo "cannot get current time using date/gawk/perl/python" >&2
+elif (( $now1 - $offset <= $now2 && $now2 <= $now1 + $offset )); then
+ echo EPOCHSECONDS ok
+else
+ echo "current time via $D and EPOCHSECONDS possible mismatch|$now1|$now2|offset=$offset" >&2
+fi
+unset now1 now2 D
+
+LC_ALL=C # force decimal point to `.'
+now1=$EPOCHREALTIME
+now2=$EPOCHREALTIME
+sec1=${now1%%.*}
+sec2=${now2%%.*}
+
+msec1=${now1##*.}
+msec2=${now2##*.}
+# cut off leading zeros
+shopt -s extglob
+msec1=${msec1##*(0)}
+msec2=${msec2##*(0)}
+
+dsec=$(( $sec2 - $sec1 ))
+dmsec=$(( $msec2 - $msec1 ))
+if (( $dmsec < 0 )); then
+ dmsec=$(( dmsec + 1000000 ))
+ dsec=$(( desc - 1 ))
+fi
+
+# not a real test, but ok for a start
+if (( $dmsec < 1000000 )); then echo EPOCHREALTIME ok; fi
+
+${THIS_SH} -c 'echo $BASH_COMMAND'
+
+# FUNCNAME tested in func.tests
+# RANDOM tested in varenv.sh
+# LINENO tested in dbg-support
diff --git a/tests/errors.right b/tests/errors.right
new file mode 100644
index 0000000..0bd88ef
--- /dev/null
+++ b/tests/errors.right
@@ -0,0 +1,208 @@
+./errors.tests: line 30: alias: -x: invalid option
+alias: usage: alias [-p] [name[=value] ... ]
+./errors.tests: line 31: unalias: -x: invalid option
+unalias: usage: unalias [-a] name [name ...]
+./errors.tests: line 32: alias: hoowah: not found
+./errors.tests: line 33: unalias: hoowah: not found
+./errors.tests: line 36: `1': not a valid identifier
+declare -fr func
+./errors.tests: line 49: func: readonly function
+./errors.tests: line 52: unset: -x: invalid option
+unset: usage: unset [-f] [-v] [-n] [name ...]
+./errors.tests: line 55: unset: func: cannot unset: readonly function
+./errors.tests: line 58: declare: func: readonly function
+./errors.tests: line 62: declare: -a: invalid option
+./errors.tests: line 63: declare: -i: invalid option
+./errors.tests: line 67: unset: XPATH: cannot unset: readonly variable
+./errors.tests: line 73: unset: cannot simultaneously unset a function and a variable
+./errors.tests: line 76: declare: -z: invalid option
+declare: usage: declare [-aAfFgiIlnrtux] [name[=value] ...] or declare -p [-aAfFilnrtux] [name ...]
+./errors.tests: line 78: declare: `-z': not a valid identifier
+./errors.tests: line 79: declare: `/bin/sh': not a valid identifier
+./errors.tests: line 83: declare: cannot use `-f' to make functions
+./errors.tests: line 86: exec: -i: invalid option
+exec: usage: exec [-cl] [-a name] [command [argument ...]] [redirection ...]
+./errors.tests: line 90: export: XPATH: not a function
+./errors.tests: line 93: break: only meaningful in a `for', `while', or `until' loop
+./errors.tests: line 94: continue: only meaningful in a `for', `while', or `until' loop
+./errors.tests: line 97: shift: label: numeric argument required
+./errors.tests: line 102: shift: too many arguments
+./errors.tests: line 108: let: expression expected
+./errors.tests: line 111: local: can only be used in a function
+./errors.tests: line 114: logout: not login shell: use `exit'
+./errors.tests: line 117: hash: notthere: not found
+./errors.tests: line 120: hash: -v: invalid option
+hash: usage: hash [-lr] [-p pathname] [-dt] [name ...]
+./errors.tests: line 124: hash: hashing disabled
+./errors.tests: line 127: export: `AA[4]': not a valid identifier
+./errors.tests: line 128: readonly: `AA[4]': not a valid identifier
+./errors.tests: line 131: unset: [-2]: bad array subscript
+./errors.tests: line 135: AA: readonly variable
+./errors.tests: line 139: AA: readonly variable
+./errors.tests: line 147: shift: 5: shift count out of range
+./errors.tests: line 148: shift: -2: shift count out of range
+./errors.tests: line 151: shopt: no_such_option: invalid shell option name
+./errors.tests: line 152: shopt: no_such_option: invalid shell option name
+./errors.tests: line 155: umask: 09: octal number out of range
+./errors.tests: line 156: umask: `:': invalid symbolic mode character
+./errors.tests: line 157: umask: `:': invalid symbolic mode operator
+./errors.tests: line 160: umask: -i: invalid option
+umask: usage: umask [-p] [-S] [mode]
+./errors.tests: line 164: umask: `u': invalid symbolic mode character
+./errors.tests: line 173: VAR: readonly variable
+./errors.tests: line 176: declare: VAR: readonly variable
+./errors.tests: line 177: declare: VAR: readonly variable
+./errors.tests: line 179: declare: unset: not found
+./errors.tests: line 182: VAR: readonly variable
+comsub: -c: line 1: syntax error near unexpected token `)'
+comsub: -c: line 1: `: $( for z in 1 2 3; do )'
+comsub: -c: line 1: syntax error near unexpected token `done'
+comsub: -c: line 1: `: $( for z in 1 2 3; done )'
+./errors.tests: line 189: cd: HOME not set
+./errors.tests: line 190: cd: /tmp/xyz.bash: No such file or directory
+./errors.tests: line 192: cd: OLDPWD not set
+./errors.tests: line 193: cd: /bin/sh: Not a directory
+./errors.tests: line 195: cd: /tmp/cd-notthere: No such file or directory
+./errors.tests: line 198: .: filename argument required
+.: usage: . filename [arguments]
+./errors.tests: line 199: source: filename argument required
+source: usage: source filename [arguments]
+./errors.tests: line 202: .: -i: invalid option
+.: usage: . filename [arguments]
+./errors.tests: line 205: set: -q: invalid option
+set: usage: set [-abefhkmnptuvxBCEHPT] [-o option-name] [--] [-] [arg ...]
+./errors.tests: line 208: enable: sh: not a shell builtin
+./errors.tests: line 208: enable: bash: not a shell builtin
+./errors.tests: line 211: shopt: cannot set and unset shell options simultaneously
+./errors.tests: line 214: read: var: invalid timeout specification
+./errors.tests: line 217: read: `/bin/sh': not a valid identifier
+./errors.tests: line 220: VAR: readonly variable
+./errors.tests: line 223: readonly: -x: invalid option
+readonly: usage: readonly [-aAf] [name[=value] ...] or readonly -p
+./errors.tests: line 226: eval: -i: invalid option
+eval: usage: eval [arg ...]
+./errors.tests: line 227: command: -i: invalid option
+command: usage: command [-pVv] command [arg ...]
+./errors.tests: line 230: /bin/sh + 0: syntax error: operand expected (error token is "/bin/sh + 0")
+./errors.tests: line 231: /bin/sh + 0: syntax error: operand expected (error token is "/bin/sh + 0")
+./errors.tests: line 234: trap: NOSIG: invalid signal specification
+./errors.tests: line 237: trap: -s: invalid option
+trap: usage: trap [-lp] [[arg] signal_spec ...]
+./errors.tests: line 243: return: can only `return' from a function or sourced script
+./errors.tests: line 247: break: 0: loop count out of range
+./errors.tests: line 251: continue: 0: loop count out of range
+./errors.tests: line 256: builtin: bash: not a shell builtin
+./errors.tests: line 260: bg: no job control
+./errors.tests: line 261: fg: no job control
+./errors.tests: line 264: kill: -s: option requires an argument
+./errors.tests: line 266: kill: S: invalid signal specification
+./errors.tests: line 268: 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 273: set: trackall: invalid option name
+./errors.tests: line 277: xx: readonly variable
+1
+./errors1.sub: line 14: .: -i: invalid option
+.: usage: . filename [arguments]
+./errors1.sub: line 22: shift: -4: shift count out of range
+./errors1.sub: line 27: break: -1: loop count out of range
+after f
+./errors2.sub: line 3: ${$NO_SUCH_VAR}: bad substitution
+1
+./errors3.sub: line 5: no_such_file: No such file or directory
+TEST
+./errors3.sub: line 7: no_such_file: No such file or directory
+1
+2
+./errors4.sub: line 20: var: readonly variable
+after readonly assignment
+./errors4.sub: line 26: break: x: numeric argument required
+1
+2
+./errors4.sub: line 20: var: readonly variable
+./errors5.sub: line 6: array: unbound variable
+./errors5.sub: line 7: array: unbound variable
+./errors5.sub: line 8: array[7]: unbound variable
+./errors5.sub: line 11: 7: unbound variable
+./errors5.sub: line 12: 7: unbound variable
+after 1: 1
+after 2: 1
+after 3: 1
+4
+array after 1: 0
+
+array after 2: 0
+./errors6.sub: line 1: uvar: parameter not set
+./errors6.sub: line 1: uvar: parameter null or not set
+
+./errors6.sub: line 1: uvar: parameter null or not set
+./errors6.sub: line 38: ${-3:-${-3}}: bad substitution
+./errors6.sub: line 39: ${-3}: bad substitution
+./errors6.sub: line 40: -3: invalid variable name
+after indir: 1
+./errors6.sub: line 43: -3: invalid variable name
+
+unset
+./errors6.sub: line 50: var: invalid indirect expansion
+./errors6.sub: line 51: var: invalid indirect expansion
+./errors6.sub: line 54: invalid-ident: invalid variable name
+./errors6.sub: line 55: invalid-ident: invalid variable name
+./errors6.sub: line 56: invalid-ident: invalid variable name
+4
+array after 1: 0
+
+array after 2: 0
+./errors6.sub: line 1: uvar: parameter not set
+./errors6.sub: line 1: uvar: parameter null or not set
+
+./errors6.sub: line 1: uvar: parameter null or not set
+./errors6.sub: line 38: ${-3:-${-3}}: bad substitution
+./errors6.sub: line 39: ${-3}: bad substitution
+./errors6.sub: line 40: -3: invalid variable name
+after indir: 1
+./errors6.sub: line 43: -3: invalid variable name
+
+unset
+./errors6.sub: line 50: var: invalid indirect expansion
+./errors6.sub: line 51: var: invalid indirect expansion
+./errors6.sub: line 54: invalid-ident: invalid variable name
+./errors6.sub: line 55: invalid-ident: invalid variable name
+./errors6.sub: line 56: invalid-ident: invalid variable name
+./errors7.sub: line 21: x: readonly variable
+./errors7.sub: line 21: notthere: command not found
+after no such command: 127
+./errors7.sub: line 23: x: readonly variable
+echo builtin
+after non-special builtin: 0
+./errors7.sub: line 25: x: readonly variable
+after special builtin: 0
+./errors7.sub: line 27: x: readonly variable
+./errors7.sub: line 29: x: readonly variable
+./errors7.sub: line 21: x: readonly variable
+after no such command: 1
+./errors7.sub: line 23: x: readonly variable
+after non-special builtin: 1
+./errors7.sub: line 25: x: readonly variable
+./errors7.sub: line 27: x: readonly variable
+./errors7.sub: line 29: x: readonly variable
+./errors8.sub: eval: line 7: syntax error: unexpected end of file
+ok 1
+./errors8.sub: line 8: v: readonly variable
+ok 2
+./errors8.sub: line 9: v: readonly variable
+ok 3
+./errors8.sub: line 11: shift: 12: shift count out of range
+ok 4
+./errors8.sub: line 13: return: can only `return' from a function or sourced script
+ok 5
+./errors8.sub: line 14: set: notanoption: invalid option name
+ok 6
+DEBUG
+./errors9.sub: line 6: [[: ++: syntax error: operand expected (error token is "+")
+DEBUG
+./errors9.sub: line 8: ((: -- : syntax error: operand expected (error token is "- ")
+DEBUG
+./errors9.sub: line 10: ((: -- : syntax error: operand expected (error token is "- ")
+bash: line 1: return: can only `return' from a function or sourced script
+after return
+bash: line 1: return: can only `return' from a function or sourced script
+./errors.tests: line 305: `!!': not a valid identifier
diff --git a/tests/errors.tests b/tests/errors.tests
new file mode 100644
index 0000000..0880bb5
--- /dev/null
+++ b/tests/errors.tests
@@ -0,0 +1,308 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# These should 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
+
+# cannot use declare -f in combination with other attributes
+a() { echo a; }
+declare -f -a a
+declare -f -i b c
+
+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-existent 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; caught early so we have to run them in subshells
+${THIS_SH} -c ': $( for z in 1 2 3; do )' comsub
+${THIS_SH} -c ': $( for z in 1 2 3; done )' comsub
+
+# 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
+
+# problem with versions through bash-4.2
+readonly xx=5
+echo $((xx=5))
+echo $?
+
+${THIS_SH} ./errors1.sub
+${THIS_SH} ./errors2.sub
+${THIS_SH} ./errors3.sub
+${THIS_SH} ./errors4.sub
+${THIS_SH} -o posix ./errors4.sub
+
+${THIS_SH} ./errors5.sub
+
+${THIS_SH} ./errors6.sub
+THIS_SH="${THIS_SH} -o posix" ${THIS_SH} ./errors6.sub
+
+${THIS_SH} ./errors7.sub
+${THIS_SH} -o posix ./errors7.sub
+
+${THIS_SH} ./errors8.sub
+${THIS_SH} ./errors9.sub
+
+${THIS_SH} -c 'return ; echo after return' bash
+${THIS_SH} -o posix -c 'return ; echo after return' bash
+
+# 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/errors1.sub b/tests/errors1.sub
new file mode 100644
index 0000000..52a9e34
--- /dev/null
+++ b/tests/errors1.sub
@@ -0,0 +1,40 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+. -i /dev/tty
+
+f()
+{
+ return -1
+}
+
+set -- a b c
+shift -4
+
+f
+
+for f in 1 2 3; do
+ break -1
+done
+
+
+f()
+{
+ return -25
+}
+
+f
+echo after f
+exit -25
+
+exit -56
diff --git a/tests/errors2.sub b/tests/errors2.sub
new file mode 100644
index 0000000..79ef333
--- /dev/null
+++ b/tests/errors2.sub
@@ -0,0 +1,3 @@
+set -e
+trap 'echo $?' EXIT
+echo ${$NO_SUCH_VAR} # Bad substitution expected here
diff --git a/tests/errors3.sub b/tests/errors3.sub
new file mode 100644
index 0000000..b2ae3d7
--- /dev/null
+++ b/tests/errors3.sub
@@ -0,0 +1,7 @@
+# redirection errors with special builtins should exit the shell when in
+# Posix mode, not otherwise; being on the LHS of || or && should not make
+# a difference
+
+exec 9<no_such_file || echo TEST
+set -o posix
+exec 9<no_such_file || echo TEST
diff --git a/tests/errors4.sub b/tests/errors4.sub
new file mode 100644
index 0000000..6b40502
--- /dev/null
+++ b/tests/errors4.sub
@@ -0,0 +1,31 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test effect of assigning to readonly vars on loops and non-interactive shells
+# fatal error when in posix mode
+var=foo
+readonly var
+for num in 1 2 3 4 5; do
+ if [ $num -eq 3 ]; then
+ var=bar
+ fi
+ echo $num
+done
+echo after readonly assignment
+
+# non-numeric arguments to break are fatal errors for all non-interactive shells
+for f in 1 2 3 4 5
+do
+ break x
+done
+echo after loop
diff --git a/tests/errors5.sub b/tests/errors5.sub
new file mode 100644
index 0000000..112b2a1
--- /dev/null
+++ b/tests/errors5.sub
@@ -0,0 +1,12 @@
+array[1]=one
+array[2]=two
+
+set -u
+
+( echo ${#array} )
+( echo ${array} )
+( echo ${array[7]} )
+
+set -- 1 2 3
+( echo ${#7} )
+( echo ${7} )
diff --git a/tests/errors6.sub b/tests/errors6.sub
new file mode 100644
index 0000000..cac2c55
--- /dev/null
+++ b/tests/errors6.sub
@@ -0,0 +1,56 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# problems with non-fatal expansion errors through bash-4.3
+: ${THIS_SH:=./bash}
+
+${THIS_SH} -c 'echo ${x!y} second
+echo after 1: $?' 2>/dev/null
+
+${THIS_SH} -c 'echo ${#+} second
+echo after 2: $?' 2>/dev/null
+
+${THIS_SH} -c 'echo ${#foo%} second
+echo after 3: $?' 2>/dev/null
+
+${THIS_SH} -c 'b[0]=4 ; echo ${b[ ]}
+echo array after 1: $?' 2>/dev/null
+${THIS_SH} -c 'typeset -A v ; v["0"]=one ; echo ${v[ ]}
+echo array after 2: $?' 2>/dev/null
+
+${THIS_SH} -c 'echo ${uvar?}' ./errors6.sub
+${THIS_SH} -c 'echo ${uvar:?}' ./errors6.sub
+export uvar=
+${THIS_SH} -c 'echo ${uvar?}' ./errors6.sub
+${THIS_SH} -c 'echo ${uvar:?}' ./errors6.sub
+unset uvar
+
+echo "${-3:-${-3}}"
+echo ${-3}
+x=-3; echo ${!x}
+echo after indir: $?
+
+function ivar() { echo -n "${!1:-${1}}"; }
+ivar -3
+
+foo=bar
+echo ${!foo}
+echo ${!foo:-unset}
+
+echo ${!var:-unset}
+echo ${!var+unset}
+
+foo=invalid-ident
+echo ${!foo}
+echo ${!foo:-unset}
+echo ${!foo+unset}
diff --git a/tests/errors7.sub b/tests/errors7.sub
new file mode 100644
index 0000000..544e3e4
--- /dev/null
+++ b/tests/errors7.sub
@@ -0,0 +1,30 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: ${THIS_SH:=./bash}
+readonly x=4
+
+# in posix mode, these are all variable assignment errors, so strict conformance
+# implies that we exit after any of them. ksh93 doesn't do that. we more-or-less
+# emulate the ksh93 behavior
+
+x=8 notthere
+echo after no such command: $?
+x=8 echo echo builtin
+echo after non-special builtin: $?
+( x=8 : nosuchdir
+echo after special builtin: $? )
+( x=8 $nocmd
+echo after assignment error: $? )
+( x=8
+echo after assignment statement error: $? )
diff --git a/tests/errors8.sub b/tests/errors8.sub
new file mode 100644
index 0000000..b65e1ab
--- /dev/null
+++ b/tests/errors8.sub
@@ -0,0 +1,14 @@
+# the start of a set of tests for command keeping special builtins from
+# exiting the shell on failure
+set -o posix
+readonly v
+
+command eval '( ' || echo ok 1
+
+command export v=foo || echo ok 2
+command readonly v=foo || echo ok 3
+
+command shift 12 || echo ok 4
+
+command return 16 || echo ok 5
+command set -o notanoption || echo ok 6
diff --git a/tests/errors9.sub b/tests/errors9.sub
new file mode 100644
index 0000000..3a26704
--- /dev/null
+++ b/tests/errors9.sub
@@ -0,0 +1,14 @@
+trap 'echo DEBUG' DEBUG
+
+# make sure that the right command name appears in the error messages and
+# that the DEBUG trap doesn't overwrite it
+
+[[ ++ -gt 3 ]]
+
+(( -- ))
+
+for (( -- ; ++; -- ))
+do
+ echo bogus
+done
+
diff --git a/tests/exec.right b/tests/exec.right
new file mode 100644
index 0000000..ef02fbb
--- /dev/null
+++ b/tests/exec.right
@@ -0,0 +1,172 @@
+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
+after exec1.sub: one two three
+./execscript: line 21: 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 40: /: Is a directory
+126
+/: /: Is a directory
+126
+./execscript: line 47: .: /: is a directory
+1
+126
+0
+this is bashenv
+trap -- 'echo EXIT' EXIT
+trap -- '' SIGTERM
+trap -- 'echo USR1' SIGUSR1
+USR1
+./exec3.sub: line 27: /tmp/bash-notthere: No such file or directory
+./exec3.sub: after failed exec: 127
+trap -- 'echo EXIT' EXIT
+trap -- '' SIGTERM
+trap -- 'echo USR1' SIGUSR1
+USR1
+EXIT
+./execscript: line 71: notthere: No such file or directory
+127
+./execscript: line 74: notthere: No such file or directory
+127
+./execscript: line 77: 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
+1
+1
+1
+1
+0
+0
+0
+0
+/usr/local/bin:/usr/GNU/bin:/usr/bin:/bin:.
+cannot find cat in $TMPDIR
+cannot find cat with empty $PATH
+PATH = /usr/local/bin:/usr/GNU/bin:/usr/bin:/bin:.
+cannot find cat in $TMPDIR with hash
+cannot find cat with empty $PATH with hash
+PATH = /usr/local/bin:/usr/GNU/bin:/usr/bin:/bin:.
+trap -- 'echo foo $BASH_SUBSHELL' EXIT
+trap -- 'echo USR1 $BASHPID' SIGUSR1
+between
+trap -- 'echo foo $BASH_SUBSHELL' EXIT
+trap -- 'echo USR1 $BASHPID' SIGUSR1
+between 2
+trap -- 'echo foo $BASH_SUBSHELL' EXIT
+trap -- 'echo USR1 $BASHPID' SIGUSR1
+in subshell: 1
+in subshell pipeline: 1
+group pipeline: 1
+EXIT-group.1
+foo 0
+after
+exit code: 1
+exit code: 1
+exit code: 1
+exit code: 1
+exit code: 1
+exit code: 1
+a
+b
+c
+A
+B
+c
+d
+c
+d
+e
+x1
+x1a
+x2
+x2a
+x2b
+x3
+x3a
+x3b
+WORKS
+done
+WORKS
+WORKS
+a
+b
+c
+d
+a
+b
+c
+d
+e
+A
+B
+c
+d
+c
+d
+e
+x
+y
+z
+WORKS
+w
+x
+y
+z
+=====
+WORKS
+done
+WORKS
+a
+b
+c
+d
+a
+b
+c
+d
+e
+A
+B
+c
+d
+c
+d
+e
+x
+y
+z
+WORKS
+w
+x
+y
+z
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/exec10.sub b/tests/exec10.sub
new file mode 100644
index 0000000..db6a671
--- /dev/null
+++ b/tests/exec10.sub
@@ -0,0 +1,47 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# post bash-4.3 changes to how command -p works (avoid modifying $PATH)
+
+: ${TMPDIR=/tmp}
+xpath=/usr/local/bin:/usr/GNU/bin:/usr/bin:/bin:.
+
+# set a value of PATH we can test for; versions of bash up to and including
+# bash-4.3 would set $PATH while running command -p
+PATH=$xpath
+export PATH
+command -p sh -c 'echo $PATH'
+
+PATH=${TMPDIR}
+command -pv cat >/dev/null || echo "cannot find cat using standard path"
+command -p cat < /dev/null
+#hash
+
+PATH=$xpath
+command -pv cat >/dev/null || echo "cannot find cat using xpath"
+PATH=$TMPDIR command -pv cat >/dev/null || echo "cannot find cat using standard path with PATH=\$TMPDIR"
+PATH= command -pv cat >/dev/null || echo "cannot find cat using standard path with empty \$PATH"
+PATH=$TMPDIR command -v cat >/dev/null || echo "cannot find cat in \$TMPDIR"
+PATH= command -v cat >/dev/null || echo "cannot find cat with empty \$PATH"
+
+echo PATH = $PATH
+hash cat
+
+PATH=$xpath
+
+PATH=$TMPDIR command -pv cat >/dev/null || echo "cannot find cat using stdpath with hash"
+PATH= command -pv cat >/dev/null || echo "cannot find cat using stdpath with hash"
+PATH=$TMPDIR command -v cat >/dev/null || echo "cannot find cat in \$TMPDIR with hash"
+PATH= command -v cat >/dev/null || echo "cannot find cat with empty \$PATH with hash"
+
+echo PATH = $PATH
diff --git a/tests/exec11.sub b/tests/exec11.sub
new file mode 100644
index 0000000..9631c67
--- /dev/null
+++ b/tests/exec11.sub
@@ -0,0 +1,14 @@
+trap 'echo USR1 $BASHPID' USR1
+trap 'echo foo $BASH_SUBSHELL' 0
+
+trap | cat
+echo between
+( trap )
+echo between 2
+{ trap; } | cat
+
+( echo in subshell: $BASH_SUBSHELL )
+( echo in subshell pipeline: $BASH_SUBSHELL ) | cat
+
+{ echo group pipeline: $BASH_SUBSHELL;
+ trap 'echo EXIT-group.$BASH_SUBSHELL' EXIT; } | cat
diff --git a/tests/exec12.sub b/tests/exec12.sub
new file mode 100644
index 0000000..0d7c8b8
--- /dev/null
+++ b/tests/exec12.sub
@@ -0,0 +1,32 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: ${TMPDIR:=/var/tmp}
+TMPFILE=$TMPDIR/exitcode
+trap 'rm -f $TMPFILE' 0
+
+rm -f $TMPFILE
+set -e
+# we normalize the exit code to accommodate false returning 255 on Solaris
+exit_handler() { echo "exit code: $(( $? != 0 ))" ; touch $TMPFILE; }
+false() { ! :; }
+notfound() { nosuchcommand ; }
+syntaxerror() { !:; }
+
+main()
+{(
+ trap exit_handler 0
+ "$@" >> /dev/null 2>&1
+)}
+main "$@"
+echo "after main: should not get here"
diff --git a/tests/exec13.sub b/tests/exec13.sub
new file mode 100644
index 0000000..76e1324
--- /dev/null
+++ b/tests/exec13.sub
@@ -0,0 +1,34 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+echo x1 | ( cat & wait )
+echo x1a | ( :& cat & wait )
+
+echo x2 | for f in 1; do
+ cat & wait
+done
+echo x2a | if true; then cat & wait; fi
+echo x2b | for (( i=0; i < 1; i++ )) ; do cat & wait; done
+
+echo x3 | { cat & wait; }
+
+lambda() { cat & wait; }
+echo x3a | lambda
+
+: ${TMPDIR:=/tmp}
+SRCF=$TMPDIR/bash-src-$$
+cat > $SRCF << \EOF
+cat & wait
+EOF
+echo x3b | . $SRCF
+rm -f $SRCF
diff --git a/tests/exec14.sub b/tests/exec14.sub
new file mode 100644
index 0000000..eddd33f
--- /dev/null
+++ b/tests/exec14.sub
@@ -0,0 +1,64 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# test that optimizing command lists doesn't inappropriately short-cut commands
+
+# also includes optimizing last command in a list separated by `;'
+
+if [ -x /bin/echo ] ; then
+ binecho=/bin/echo
+elif [ -x /usr/bin/echo ]; then
+ binecho=/usr/bin/echo
+else
+ enable -n echo
+ binecho=echo
+fi
+
+export binecho
+
+: ${THIS_SH:=./bash} ${TMPDIR:=/var/tmp}
+
+${THIS_SH} -c 'trap "echo WORKS && rm $TMPDIR/x$$" EXIT && touch $TMPDIR/x$$'
+${THIS_SH} -c 'trap "echo WORKS && rm $TMPDIR/x$$" EXIT && touch $TMPDIR/x$$ ; $binecho done'
+
+( trap "echo WORKS && rm $TMPDIR/x$$" EXIT && touch $TMPDIR/x$$ )
+
+${THIS_SH} -c 'echo a && { $binecho b && $binecho c ; } && echo d'
+${THIS_SH} -c 'echo a && { $binecho b && $binecho c ; } && echo d ; $binecho e'
+
+${THIS_SH} -c 'echo A && $binecho B'
+${THIS_SH} -c '$binecho c && echo d'
+
+$THIS_SH -c '$binecho c && $binecho d && echo e'
+
+$THIS_SH -c 'trap "echo WORKS" EXIT ; $binecho x ; $binecho y ; $binecho z'
+
+${THIS_SH} -c 'echo w ; { echo x ; $binecho y; }; $binecho z'
+
+echo =====
+
+( trap "echo WORKS && rm $TMPDIR/x$$" EXIT && touch $TMPDIR/x$$ )
+( trap "echo WORKS && rm $TMPDIR/x$$" EXIT && touch $TMPDIR/x$$ ; $binecho done )
+
+( echo a && { $binecho b && $binecho c ; } && echo d )
+( echo a && { $binecho b && $binecho c ; } && echo d ; $binecho e )
+
+( echo A && $binecho B )
+( $binecho c && echo d )
+
+( $binecho c && $binecho d && echo e )
+
+( trap "echo WORKS" EXIT ; $binecho x ; $binecho y ; $binecho z )
+
+( echo w ; { echo x ; $binecho y; }; $binecho z )
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..81b53b7
--- /dev/null
+++ b/tests/exec3.sub
@@ -0,0 +1,37 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test the behavior of `execfail' not exiting an interactive shell
+# added tests for changes in 10/2021 for preserving the traps across a failed
+# exec
+
+shopt -s execfail
+
+trap 'echo EXIT' EXIT
+trap 'echo USR1' USR1
+trap '' TERM
+trap
+
+kill -s USR1 $$ # should run the trap
+
+exec /tmp/bash-notthere
+
+# make sure we're still around
+echo $0: after failed exec: $?
+
+trap
+kill -s USR1 $$ # should run the trap
+kill -s TERM $$ # should still be ignored
+
+# this should run the exit trap
+exit 0
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..dd53e74
--- /dev/null
+++ b/tests/exec6.sub
@@ -0,0 +1,67 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# 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..0c8c7ca
--- /dev/null
+++ b/tests/exec7.sub
@@ -0,0 +1,36 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# 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
+
+cd $OLDPWD
+exit 0
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/exec9.sub b/tests/exec9.sub
new file mode 100644
index 0000000..a47dfd0
--- /dev/null
+++ b/tests/exec9.sub
@@ -0,0 +1,33 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# make sure commands before the last one in the pipeline can't change $?
+false
+false | echo $?
+false
+(false) | echo $?
+
+false
+true | echo $?
+false
+(true) | echo $?
+
+true
+false | echo $?
+true
+(false) | echo $?
+
+true
+true | echo $?
+true
+(true) | echo $?
diff --git a/tests/execscript b/tests/execscript
new file mode 100644
index 0000000..2809676
--- /dev/null
+++ b/tests/execscript
@@ -0,0 +1,160 @@
+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: $?
+echo after exec1.sub: "$@"
+
+# 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 > $TMPDIR/bashenv
+export BASH_ENV=$TMPDIR/bashenv
+${THIS_SH} ./exec3.sub
+rm -f $TMPDIR/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 ${PWD}/exec8.sub
+
+${THIS_SH} ./exec9.sub
+
+${THIS_SH} ./exec10.sub
+${THIS_SH} ./exec11.sub
+
+true | `echo true` &
+
+echo after
+
+# Problem with bash at least back to version 3.0
+${THIS_SH} -c 'VAR=0; VAR=1 command exec; exit ${VAR}'
+
+# problem with bash through bash-4.1
+(
+ exec /var/empty/nosuch
+ echo bad
+) 2>/dev/null
+[ $? = 127 ] || echo FAIL: bad exit status $? at $LINENO
+
+unset FALSE
+if [ -x /bin/false ]; then
+ FALSE=/bin/false
+elif [ -x /usr/bin/false ]; then
+ FALSE=/usr/bin/false
+else
+ FALSE='command false'
+fi
+
+# problem with undoing redirections before running exit trap through bash-4.3
+
+${THIS_SH} ./exec12.sub false # function
+${THIS_SH} ./exec12.sub command false
+${THIS_SH} ./exec12.sub $FALSE
+
+${THIS_SH} ./exec12.sub notfound
+${THIS_SH} ./exec12.sub syntaxerror
+${THIS_SH} ./exec12.sub nosuchcommand
+
+# problem with fork optimization in bash-4.4-alpha
+
+$THIS_SH -c 'echo a && /bin/echo b && echo c'
+$THIS_SH -c 'echo A && /bin/echo B'
+
+$THIS_SH -c '/bin/echo c && echo d'
+$THIS_SH -c '/bin/echo c && /bin/echo d && echo e'
+
+${THIS_SH} ./exec13.sub
+${THIS_SH} ./exec14.sub
diff --git a/tests/exp.right b/tests/exp.right
new file mode 100644
index 0000000..60241a1
--- /dev/null
+++ b/tests/exp.right
@@ -0,0 +1,419 @@
+argv[1] = <^A>
+argv[1] = <^A>
+argv[1] = <^?>
+argv[1] = <^?>
+argv[1] = <^A>
+argv[1] = <^?>
+argv[1] = <bar>
+argv[1] = <^A>
+argv[1] = <^?>
+argv[1] = <^A>
+argv[1] = <^?>
+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] = <^?>
+argv[1] = <^A>
+argv[1] = <^?>
+argv[1] = <^A>
+argv[1] = <^?>
+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] = <^?>
+argv[1] = <**>
+argv[1] = <\.\./*/>
+argv[1] = <^A^?^A^?>
+argv[1] = <^A^A>
+argv[1] = <^A^?>
+argv[1] = <^A^A^?>
+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] = <a>
+argv[2] = <b>
+argv[3] = <>
+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
+ val
+val
+ val
+no arg passed
+hello
+[0;31m\]
+]
+[hello
+\[\e[0;31m\]
+
+hello
+eo
+argv[1] = <a>
+argv[1] = <a>
+argv[1] = <^?>
+argv[1] = <^?b>
+argv[1] = <b^?>
+argv[1] = <c>
+argv[1] = <c>
+argv[1] = <c>
+argv[1] = <c>
+argv[1] = <c>
+argv[1] = <c>
+argv[1] = <correct>
+argv[2] = <>
+argv[1] = <correct>
+argv[2] = <>
+argv[1] = <correct>
+argv[2] = <>
+argv[1] = <XwrongX>
+argv[2] = <>
+argv[1] = <correct>
+argv[2] = <a>
+argv[1] = <XwrongX>
+argv[2] = <a>
+argv[1] = <correct>
+argv[2] = <a>
+argv[1] = <correct>
+argv[2] = <a>
+argv[1] = <^A>
+argv[1] = <3>
+argv[2] = <^C>
+argv[3] = <^C>
+argv[4] = <^C>
+argv[1] = <^A>
+argv[1] = <XY>
+argv[2] = <YX>
+argv[1] = <XY^AYX>
+argv[1] = <XY>
+argv[2] = <Y>
+argv[1] = <XY^AY>
+argv[1] = <x^Ay^?z>
+argv[1] = <x^Ay^?z>
+declare -- var=$'x\001y\177z'
+argv[1] = <declare>
+argv[2] = <-->
+argv[3] = <var=$'x\001y\177z'>
+var=x\001y\177z$
+declare -- var="x\001y\177z"$
+argv[1] = <$'x\001y\177z'>
+argv[1] = <x^Ay^?z>
+var=$'x\001y\177z'
+./exp8.sub: line 30: xyz: syntax error: invalid arithmetic operator (error token is "z")
+declare -a array=()
+declare -a array=([0]=$'x\001y\177z')
+argv[1] = <x^Ay^?z>
+declare -a array=([0]=$'x\001y\177z')
+declare -A array=([$'x\001y\177z']=$'a\242b\002c' )
+abc
+def
+ghi
+jkl
+abc def ghi jkl
+xxabc
+def
+ghi
+jklyy
+xxabc def ghi jklyy
+abc
+def
+ghi
+jkl
+abc
+def ghi
+jkl
+abc
+def ghi
+jkl
+abc
+def ghi
+jkl
+xxabc
+def
+ghi
+jklyy
+xxabc
+def ghi
+jklyy
+abc
+def
+ghi
+jklabc
+def
+ghi
+jkl
+abc
+def ghi
+jklabc
+def ghi
+jkl
+abc:def ghi:jkl
+abc:def ghi:jkl
+abc:def ghi:jkl
+abc
+def ghi
+jkl
+abc:def ghi:jkl
+abc:def ghi:jkl
+abc
+def ghi
+jkl
+var=abc:def ghi:jkl
+abc:def ghi:jkl
+var=abc:def ghi:jkl
+abcdef ghijkl
+abcdef ghijkl
+abcdef ghijkl
+abc
+def ghi
+jkl
+abcdef ghijkl
+abcdef ghijkl
+abcdef ghijkl
+var=abcdef ghijkl
+abcdef ghijkl
+var=abcdef ghijkl
+abc
+def ghi
+jkl
+abc def ghi jkl
+abc def ghi jkl
+abc def ghi jkl
+abc
+def
+ghi
+jkl
+abc def ghi jkl
+abc def ghi jkl
+abc
+def
+ghi
+jkl
+var=abc def ghi jkl
+abc def ghi jkl
+var=abc def ghi jkl
+abc
+def ghi
+jkl
+[foo]
+[]
+[foo]
+[]
+[foo]
+[foo]
+[foo]
+[]
+[foo]
+[]
+[foo]
+[]
+< 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] = <1>
+argv[2] = <2>
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = <1 2>
+argv[1] = <a b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a b>
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = <12>
+argv[1] = <12>
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = < >
+argv[1] = < >
+argv[1] = < >
+argv[1] = < >
+argv[1] = < >
+argv[1] = <12>
+argv[1] = <12>
+argv[1] = <12>
+argv[1] = <12>
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+ok 6
+ok 7
+ok 8
+ok 9
+argv[1] = <file.o>
+argv[1] = <posix>
+argv[1] = </src/cmd>
+argv[1] = <three>
+argv[1] = </one/two/three>
+abcdefg
+abcdefg
+abcdefg
+abcdefg
+cdefg
+abcdefg
+abcde
+abcdefg
+foo
+declare -- a="foo"
+7
+declare -i a="7"
+42
+declare -- a="42"
+FOO
+declare -u A="FOO"
diff --git a/tests/exp.tests b/tests/exp.tests
new file mode 100644
index 0000000..61a39d3
--- /dev/null
+++ b/tests/exp.tests
@@ -0,0 +1,426 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# A 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 "<^?>"
+recho `echo ''`
+expect "<^?>"
+recho `echo ""`
+expect "<^A>"
+recho `echo `
+expect "<^?>"
+recho `echo `
+
+expect "bar"
+recho ${foo:-"`echo bar`"}
+expect "<^A>"
+recho ${foo:-"`echo `"}
+expect "<^?>"
+recho ${foo:-"`echo `"}
+
+expect "<^A>"
+recho "`echo `"
+expect "<^?>"
+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 "<^?>"
+recho 
+expect "<^A>"
+recho ""
+expect "<^?>"
+recho ""
+expect "<^A>"
+recho ''
+expect "<^?>"
+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] = ^?
+expect '<^A> <^?>'
+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^?^A^?>'
+recho ''
+expect '<^A^A>'
+recho ''
+expect '<^A^?>'
+recho ''
+expect '<^A^A^?>'
+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} -c 'var=a:b: ; IFS=" :" ; recho $var""' bash
+
+${THIS_SH} ./exp1.sub
+
+${THIS_SH} ./exp2.sub
+
+${THIS_SH} ./exp3.sub
+
+${THIS_SH} ./exp4.sub
+
+${THIS_SH} ./exp5.sub
+
+${THIS_SH} ./exp6.sub
+${THIS_SH} ./exp7.sub
+${THIS_SH} ./exp8.sub
+${THIS_SH} ./exp9.sub
+${THIS_SH} ./exp10.sub
+${THIS_SH} ./exp11.sub
+${THIS_SH} ./exp12.sub
+${THIS_SH} ./exp13.sub
diff --git a/tests/exp1.sub b/tests/exp1.sub
new file mode 100644
index 0000000..3dbe3d9
--- /dev/null
+++ b/tests/exp1.sub
@@ -0,0 +1,34 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# 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/exp10.sub b/tests/exp10.sub
new file mode 100644
index 0000000..42bdaf8
--- /dev/null
+++ b/tests/exp10.sub
@@ -0,0 +1,39 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+set -- ' A ' ' B '
+IFS=
+
+printf '<%s>' ${*} ${*##}
+echo
+printf '<%s>' ${*} ${*/}
+echo
+printf '<%s>' ${*} ${*,,}
+echo
+printf '<%s>' ${*} ${*:1:2}
+echo
+printf '<%s>' ${*} ${*@Q}
+echo
+
+echo -----
+
+printf '<%s>' ${@} ${@##}
+echo
+printf '<%s>' ${@} ${@/}
+echo
+printf '<%s>' ${@} ${@,,}
+echo
+printf '<%s>' ${@} ${@:1:2}
+echo
+printf '<%s>' ${@} ${@@Q}
+echo
diff --git a/tests/exp11.sub b/tests/exp11.sub
new file mode 100644
index 0000000..b3e02e0
--- /dev/null
+++ b/tests/exp11.sub
@@ -0,0 +1,105 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+set -- '1 2'
+
+unset var
+recho ${var-${*:1}}
+
+unset var
+recho ${var=$*}
+
+unset var
+recho ${var=${*:1}}
+recho "$var"
+
+# posix interp 221
+unset var
+recho ${var:-a\ b}
+
+recho ${var:=a\ b}
+recho "$var"
+
+set -- 1 2
+IFS=
+
+unset a b c
+recho $*
+recho ${a-$*}
+recho ${b-${*/}}
+recho ${c=${*/}}
+recho "$c"
+recho ${b-${*,,}}
+recho ${d-${*,,}}
+
+unset -v a b c
+IFS=$' \t\n'
+
+set -- ' '
+A=(' ')
+
+IFS=
+unset var
+var=${*@E}
+recho "$var"
+
+unset var
+var=${A[*]@E}
+recho "$var"
+
+unset var
+var=${@@E}
+recho "$var"
+
+unset var
+var=${A[@]@E}
+recho "$var"
+
+unset novar
+recho ${novar-${A[*]@E}}
+
+unset -v var novar
+IFS=$' \t\n'
+
+set -- 1 2
+A=( 1 2 )
+IFS=
+
+a=$*
+recho "$a"
+b=${*@E}
+recho "$b"
+
+unset a b
+a=${A[*]}
+recho "$a"
+b=${A[*]@E}
+recho "$b"
+
+set -- $'\t'
+A=$1
+
+IFS=$1
+[[ ${A[@]} ]] && echo ok 1
+[[ ${A[*]} ]] && echo ok 2
+[[ ${A[0]} ]] && echo ok 3
+
+IFS=$' \t\n'
+[[ ${A[@]} ]] && echo ok 4
+[[ ${A[*]} ]] && echo ok 5
+[[ ${A[0]} ]] && echo ok 6
+
+IFS=
+[[ ${A[@]} ]] && echo ok 7
+[[ ${A[*]} ]] && echo ok 8
+[[ ${A[0]} ]] && echo ok 9
diff --git a/tests/exp12.sub b/tests/exp12.sub
new file mode 100644
index 0000000..8c5005d
--- /dev/null
+++ b/tests/exp12.sub
@@ -0,0 +1,51 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# force single-byte versions of these functions
+
+export LANG=C
+
+# remove shortest trailing match
+x=file.c
+recho ${x%.c}.o
+
+# remove longest trailing match
+x=posix/src/std
+recho ${x%%/*}
+
+# remove shortest leading pattern
+x=$HOME/src/cmd
+recho ${x#$HOME}
+
+# remove longest leading pattern
+x=/one/two/three
+recho ${x##*/}
+
+# and no match thrown in for good measure
+recho ${x#nomatch}
+
+foo=abcdefg
+
+# fail
+echo ${foo%ab}
+echo ${foo%def}
+
+echo ${foo#fg}
+echo ${foo#def}
+
+# succeed
+echo ${foo#ab}
+echo ${foo#def}
+
+echo ${foo%fg}
+echo ${foo%def}
diff --git a/tests/exp13.sub b/tests/exp13.sub
new file mode 100644
index 0000000..80e1463
--- /dev/null
+++ b/tests/exp13.sub
@@ -0,0 +1,34 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+unset a
+
+echo ${a:=foo}
+declare -p a
+
+unset a
+
+declare -i a
+echo ${a:=4+3}
+declare -p a
+
+unset a
+echo ${a:=42}
+declare -p a
+
+unset a
+declare -u A
+A=
+echo ${A:=foo}
+
+declare -p A
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/exp4.sub b/tests/exp4.sub
new file mode 100644
index 0000000..d022ceb
--- /dev/null
+++ b/tests/exp4.sub
@@ -0,0 +1,10 @@
+f=" val" e=
+echo "$e"$f
+echo $e$f
+echo "$e""$f"
+
+if [[ "$1"x == x ]] ; then
+ echo "no arg passed"
+ exit 1
+fi
+echo "$1"x | cat -v
diff --git a/tests/exp5.sub b/tests/exp5.sub
new file mode 100644
index 0000000..5cf8ed7
--- /dev/null
+++ b/tests/exp5.sub
@@ -0,0 +1,34 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# expansions involving patterns
+var='[hello'
+echo "${var//[/}"
+
+red='\[\e[0;31m\]'
+printf "%s\n" "${red//\\[\\e/}"
+
+foo="${red//\\[\\e/}"
+
+# foo == [0;31m\]
+printf "%s\n" "${foo//[0;31m\\/}"
+
+echo "${var//[]/}"
+echo "${red//[]/}"
+
+v=hello
+foo='[:alpha:]'
+
+echo ${v//[[:alpha:]]/}
+echo ${v//[[:alpha]]/}
+echo ${v//[[:alpha]/}
diff --git a/tests/exp6.sub b/tests/exp6.sub
new file mode 100644
index 0000000..582617c
--- /dev/null
+++ b/tests/exp6.sub
@@ -0,0 +1,43 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+recho """"a
+recho a""""
+
+recho """"
+
+recho """"b
+recho b""""
+
+recho """"""c
+recho c""""""
+
+recho """"""c""""
+recho """"c""""""
+
+recho """"""""c
+recho c""""""""
+
+# BASH BUG: spurious DEL characters appear on empty variable interpolation.
+# BASH 4.2.8(1)-release
+
+a=''
+
+recho correct "$a" # correct empty output line
+recho correct "$a""$a" # correct empty output line
+recho correct "$a""$a""$a" # correct empty output line
+recho XwrongX "$a""$a""$a""$a" # spurious two DEL chars appear at line end
+recho correct a"$a" # correct single "a" on line
+recho XwrongX a"$a""$a" # spurious DEL char appears at line end
+recho correct a"$a$a" # correct single "a" on line
+recho correct a"$a$a$a$a" # correct single "a" on line
diff --git a/tests/exp7.sub b/tests/exp7.sub
new file mode 100644
index 0000000..a3993b5
--- /dev/null
+++ b/tests/exp7.sub
@@ -0,0 +1,36 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+IFS=$'\001'
+c=$'\001'
+c2=$'\003'
+
+IFS=$c # this is the problem line, IFS should end up being \001
+recho "$IFS"
+set -- $c2$c$c2$c$c2
+recho $# "$1" "$2" "$3"
+
+x=$c
+recho "$x"
+
+unset c c2 x
+
+c=$'Y\1Y';
+
+v=X${c}X;
+recho X${c}X
+recho "$v"
+
+v=X$c
+recho X$c
+recho "$v"
diff --git a/tests/exp8.sub b/tests/exp8.sub
new file mode 100644
index 0000000..7dd5a28
--- /dev/null
+++ b/tests/exp8.sub
@@ -0,0 +1,45 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+var=$'x\001y\177z'
+
+recho "$var"
+recho $var
+
+declare -p var
+recho $(declare -p var)
+
+echo "var=$var" | sed -n l
+echo "declare -- var=\"$var\"" | sed -n l
+
+recho ${var@Q}
+recho ${var@P}
+echo -E ${var@A}
+
+unset array
+array=( [$'x\001y\177z']=foo ) # should be error
+echo -E ${array[@]@A}
+
+unset array
+declare -a array=([0]=$'x\001y\177z')
+declare -p array
+
+unset array
+array=( "$var" )
+recho ${array[@]}
+echo -E ${array[@]@A}
+
+unset array
+declare -A array
+array=( [$'x\001y\177z']=$'a\242b\002c' )
+echo -E ${array[@]@A}
diff --git a/tests/exp9.sub b/tests/exp9.sub
new file mode 100644
index 0000000..7e4a3b6
--- /dev/null
+++ b/tests/exp9.sub
@@ -0,0 +1,82 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# expansion test cases from Posix interp 888
+
+set "abc" "def ghi" "jkl"
+unset novar
+IFS=' ' # a space
+printf '%s\n' $*
+printf '%s\n' "$*"
+printf '%s\n' xx$*yy
+printf '%s\n' "xx$*yy"
+printf '%s\n' $@
+printf '%s\n' "$@"
+printf '%s\n' ${1+"$@"}
+printf '%s\n' ${novar-"$@"}
+printf '%s\n' xx$@yy
+printf '%s\n' "xx$@yy"
+printf '%s\n' $@$@
+printf '%s\n' "$@$@"
+IFS=':'
+printf '%s\n' "$*"
+var=$*; printf '%s\n' "$var"
+var="$*"; printf '%s\n' "$var"
+unset var
+printf '%s\n' ${var-$*}
+printf '%s\n' "${var-$*}"
+printf '%s\n' ${var-"$*"}
+printf '%s\n' ${var=$*}
+printf 'var=%s\n' "$var"
+unset var
+printf '%s\n' "${var=$*}"
+printf 'var=%s\n' "$var"
+
+IFS='' # null
+printf '%s\n' "$*"
+var=$*; printf '%s\n' "$var"
+var="$*"; printf '%s\n' "$var"
+unset var
+printf '%s\n' ${var-$*}
+printf '%s\n' "${var-$*}"
+printf '%s\n' ${var-"$*"}
+printf '%s\n' ${var=$*}
+printf 'var=%s\n' "$var"
+unset var
+printf '%s\n' "${var=$*}"
+printf 'var=%s\n' "$var"
+printf '%s\n' "$@"
+
+unset IFS
+printf '%s\n' "$*"
+var=$*; printf '%s\n' "$var"
+var="$*"; printf '%s\n' "$var"
+unset var
+printf '%s\n' ${var-$*}
+printf '%s\n' "${var-$*}"
+printf '%s\n' ${var-"$*"}
+printf '%s\n' ${var=$*}
+printf 'var=%s\n' "$var"
+unset var
+printf '%s\n' "${var=$*}"
+printf 'var=%s\n' "$var"
+printf '%s\n' "$@"
+
+set --
+printf '[%s]\n' foo "$*"
+printf '[%s]\n' foo "$novar$*$(echo)"
+printf '[%s]\n' foo $@
+printf '[%s]\n' foo "$@"
+printf '[%s]\n' foo ''$@
+printf '[%s]\n' foo ''"$@"
+printf '[%s]\n' foo ''"$novar$@$(echo)"
diff --git a/tests/exportfunc.right b/tests/exportfunc.right
new file mode 100644
index 0000000..890bdfa
--- /dev/null
+++ b/tests/exportfunc.right
@@ -0,0 +1,14 @@
+exportfunc ok 1
+exportfunc ok 2
+./exportfunc.tests: line 37: cve7169-bad: No such file or directory
+./exportfunc.tests: eval: line 44: syntax error: unexpected end of file
+./exportfunc.tests: line 43: cve7169-bad2: No such file or directory
+./exportfunc1.sub: line 14: maximum here-document count exceeded
+./exportfunc.tests: line 72: HELLO_WORLD: No such file or directory
+eval ok
+./exportfunc3.sub: line 23: export: foo=bar: cannot export
+status: 1
+equals-1
+bad echo
+./exportfunc3.sub: line 36: export: /bin/echo: cannot export
+bar
diff --git a/tests/exportfunc.tests b/tests/exportfunc.tests
new file mode 100644
index 0000000..d06b1a3
--- /dev/null
+++ b/tests/exportfunc.tests
@@ -0,0 +1,92 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# normal operation
+foo()
+{
+ echo exportfunc ok 1
+}
+export -f foo
+${THIS_SH} -c foo
+unset -f foo
+foo-a ()
+{
+ echo exportfunc ok 2
+}
+export -f foo-a
+${THIS_SH} -c 'foo-a'
+
+# CVE-2014-6271
+
+env -i BASH_FUNC_foo%%='() { echo cve6271 ok; } ; echo BAD' ${THIS_SH} -c foo 2>/dev/null
+
+# CVE-2014-7169
+
+rm -f cve7169-bad
+env -i BASH_FUNC_X%%='() { (a)=>\' ${THIS_SH} -c cve7169-bad 2>/dev/null
+: < cve7169-bad
+rm -f cve7169-bad
+
+echo cve7169-bad2 > $TMPDIR/bar
+rm -f cve7169-bad2
+eval 'X() { (a)>\' ; . ./bar 2>/dev/null
+: < cve7169-bad2
+rm -f cve7169-bad2 $TMPDIR/bar
+
+# CVE-2014-7186
+${THIS_SH} ./exportfunc1.sub
+
+# CVE-2014-7187
+${THIS_SH} ./exportfunc2.sub
+
+# CVE-2014-6277
+A100=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
+A1000=${A100}
+
+for (( i = 0; i < 999; i++ ))
+do
+ A1000+=${A100}
+done
+
+env BASH_FUNC_foo%%="() { 000(){>0;}&000(){ 0;}<<0 0" ${THIS_SH} -c foo 2>/dev/null
+env BASH_FUNC_foo%%="() { 000(){>0;}&000(){ 0;}<<${A1000} 0" ${THIS_SH} -c foo 2>/dev/null
+${THIS_SH} -c "f(){ x(){ _;}; x(){ _;}<<a;}" 2>/dev/null
+unset A100 A1000
+
+# CVE-2014-6278
+
+env 'BASH_FUNC_FOO%%=() { 0;}>r[0${$(}0 {>"$(id >/dev/tty)"; }' ${THIS_SH} -c : 2>/dev/null
+
+rm -f HELLO_WORLD
+env BASH_FUNC_FOO%%='() { 0;}>r[0${$(}0 {>HELLO_WORLD; }' ${THIS_SH} -c : 2>/dev/null
+: < HELLO_WORLD
+
+env BASH_FUNC_x%%='() { _;}>_[$($())] { echo vuln;}' ${THIS_SH} -c : 2>/dev/null
+
+env -i BASH_FUNC_x%%='() { _; } >_[${ $() }] { id; }' ${THIS_SH} -c : 2>/dev/null
+
+env BASH_FUNC_x%%=$'() { _;}>_[$($())]\n{ echo vuln;}' ${THIS_SH} -c : 2>/dev/null
+eval 'x() { _;}>_[$($())] { echo vuln;}' 2>/dev/null
+
+eval 'foo() { _; } >_[${ $() }] ;{ echo eval ok; }'
+
+# other tests fixed in bash43-030 concerning function name transformation
+env $'BASH_FUNC_\nfoo%%=() { echo transform-1; }' ${THIS_SH} -c foo 2>/dev/null
+env $'BASH_FUNC_foo\n%%=() { echo transform-2; }' ${THIS_SH} -c foo 2>/dev/null
+env $'BASH_FUNC_ foo %%=() { echo transform-3; }' ${THIS_SH} -c foo 2>/dev/null
+
+unset -f foo
+env $'BASH_FUNC_#badname%%'=$'() { :; }\nfoo () { echo transform-4; } ' ${THIS_SH} -c 'foo' 2>/dev/null
+
+# tests of exported names
+${THIS_SH} ./exportfunc3.sub
diff --git a/tests/exportfunc1.sub b/tests/exportfunc1.sub
new file mode 100644
index 0000000..53b4c1f
--- /dev/null
+++ b/tests/exportfunc1.sub
@@ -0,0 +1,34 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+cat <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF
+EOF
+EOF
+EOF
+EOF
+EOF
+EOF
+EOF
+EOF
+EOF
+EOF
+EOF
+EOF
+EOF
+EOF
+EOF
+EOF
+EOF
+EOF
+
+echo after EOF
diff --git a/tests/exportfunc2.sub b/tests/exportfunc2.sub
new file mode 100644
index 0000000..cf5df57
--- /dev/null
+++ b/tests/exportfunc2.sub
@@ -0,0 +1,413 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+for x1 in ; do :
+for x2 in ; do :
+for x3 in ; do :
+for x4 in ; do :
+for x5 in ; do :
+for x6 in ; do :
+for x7 in ; do :
+for x8 in ; do :
+for x9 in ; do :
+for x10 in ; do :
+for x11 in ; do :
+for x12 in ; do :
+for x13 in ; do :
+for x14 in ; do :
+for x15 in ; do :
+for x16 in ; do :
+for x17 in ; do :
+for x18 in ; do :
+for x19 in ; do :
+for x20 in ; do :
+for x21 in ; do :
+for x22 in ; do :
+for x23 in ; do :
+for x24 in ; do :
+for x25 in ; do :
+for x26 in ; do :
+for x27 in ; do :
+for x28 in ; do :
+for x29 in ; do :
+for x30 in ; do :
+for x31 in ; do :
+for x32 in ; do :
+for x33 in ; do :
+for x34 in ; do :
+for x35 in ; do :
+for x36 in ; do :
+for x37 in ; do :
+for x38 in ; do :
+for x39 in ; do :
+for x40 in ; do :
+for x41 in ; do :
+for x42 in ; do :
+for x43 in ; do :
+for x44 in ; do :
+for x45 in ; do :
+for x46 in ; do :
+for x47 in ; do :
+for x48 in ; do :
+for x49 in ; do :
+for x50 in ; do :
+for x51 in ; do :
+for x52 in ; do :
+for x53 in ; do :
+for x54 in ; do :
+for x55 in ; do :
+for x56 in ; do :
+for x57 in ; do :
+for x58 in ; do :
+for x59 in ; do :
+for x60 in ; do :
+for x61 in ; do :
+for x62 in ; do :
+for x63 in ; do :
+for x64 in ; do :
+for x65 in ; do :
+for x66 in ; do :
+for x67 in ; do :
+for x68 in ; do :
+for x69 in ; do :
+for x70 in ; do :
+for x71 in ; do :
+for x72 in ; do :
+for x73 in ; do :
+for x74 in ; do :
+for x75 in ; do :
+for x76 in ; do :
+for x77 in ; do :
+for x78 in ; do :
+for x79 in ; do :
+for x80 in ; do :
+for x81 in ; do :
+for x82 in ; do :
+for x83 in ; do :
+for x84 in ; do :
+for x85 in ; do :
+for x86 in ; do :
+for x87 in ; do :
+for x88 in ; do :
+for x89 in ; do :
+for x90 in ; do :
+for x91 in ; do :
+for x92 in ; do :
+for x93 in ; do :
+for x94 in ; do :
+for x95 in ; do :
+for x96 in ; do :
+for x97 in ; do :
+for x98 in ; do :
+for x99 in ; do :
+for x100 in ; do :
+for x101 in ; do :
+for x102 in ; do :
+for x103 in ; do :
+for x104 in ; do :
+for x105 in ; do :
+for x106 in ; do :
+for x107 in ; do :
+for x108 in ; do :
+for x109 in ; do :
+for x110 in ; do :
+for x111 in ; do :
+for x112 in ; do :
+for x113 in ; do :
+for x114 in ; do :
+for x115 in ; do :
+for x116 in ; do :
+for x117 in ; do :
+for x118 in ; do :
+for x119 in ; do :
+for x120 in ; do :
+for x121 in ; do :
+for x122 in ; do :
+for x123 in ; do :
+for x124 in ; do :
+for x125 in ; do :
+for x126 in ; do :
+for x127 in ; do :
+for x128 in ; do :
+for x129 in ; do :
+for x130 in ; do :
+for x131 in ; do :
+for x132 in ; do :
+for x133 in ; do :
+for x134 in ; do :
+for x135 in ; do :
+for x136 in ; do :
+for x137 in ; do :
+for x138 in ; do :
+for x139 in ; do :
+for x140 in ; do :
+for x141 in ; do :
+for x142 in ; do :
+for x143 in ; do :
+for x144 in ; do :
+for x145 in ; do :
+for x146 in ; do :
+for x147 in ; do :
+for x148 in ; do :
+for x149 in ; do :
+for x150 in ; do :
+for x151 in ; do :
+for x152 in ; do :
+for x153 in ; do :
+for x154 in ; do :
+for x155 in ; do :
+for x156 in ; do :
+for x157 in ; do :
+for x158 in ; do :
+for x159 in ; do :
+for x160 in ; do :
+for x161 in ; do :
+for x162 in ; do :
+for x163 in ; do :
+for x164 in ; do :
+for x165 in ; do :
+for x166 in ; do :
+for x167 in ; do :
+for x168 in ; do :
+for x169 in ; do :
+for x170 in ; do :
+for x171 in ; do :
+for x172 in ; do :
+for x173 in ; do :
+for x174 in ; do :
+for x175 in ; do :
+for x176 in ; do :
+for x177 in ; do :
+for x178 in ; do :
+for x179 in ; do :
+for x180 in ; do :
+for x181 in ; do :
+for x182 in ; do :
+for x183 in ; do :
+for x184 in ; do :
+for x185 in ; do :
+for x186 in ; do :
+for x187 in ; do :
+for x188 in ; do :
+for x189 in ; do :
+for x190 in ; do :
+for x191 in ; do :
+for x192 in ; do :
+for x193 in ; do :
+for x194 in ; do :
+for x195 in ; do :
+for x196 in ; do :
+for x197 in ; do :
+for x198 in ; do :
+for x199 in ; do :
+for x200 in ; do :
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
+done
diff --git a/tests/exportfunc3.sub b/tests/exportfunc3.sub
new file mode 100644
index 0000000..af3125b
--- /dev/null
+++ b/tests/exportfunc3.sub
@@ -0,0 +1,38 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test function names that cannot be exported
+
+unset foo # remove from environment if necessary
+
+function foo=bar
+{
+ echo equals-1
+}
+
+export -f 'foo=bar'
+echo status: $?
+
+foo\=bar
+printenv | grep 'foo=bar'
+${THIS_SH} -c 'foo\=bar 2>/dev/null'
+
+function /bin/echo
+{
+ echo bad echo
+}
+
+/bin/echo foo
+export -f '/bin/echo'
+
+${THIS_SH} -c '/bin/echo bar'
diff --git a/tests/extglob.right b/tests/extglob.right
new file mode 100644
index 0000000..2974cec
--- /dev/null
+++ b/tests/extglob.right
@@ -0,0 +1,184 @@
+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
+a ab
+a ab
+a ab
+a
+*(.)
+a.log
+*(foo)
+*(foo|bar)
+a.log
+?(foo)
+a.log
+a.log
+*(foo).*
+*(foo|bar).*
+a.log
+a.log
+.x .y .z
+a b c
+.x .y .z a b c
+a b c
+a b c
+a b c
+a b c
+.x .y .z a b c
+.x .y .z a b c
+*
+.b a
+.b a
+a .b
+.b
+.b
+.b a
+.b a
+a .b
+.b
+.b
+dotglob: .a .foo bar
+@(.foo)
+.foo
+!(.foo)
+.a bar
+@(.foo|*)
+.a .foo bar
+!(.foo|*)
+!(.foo|*)
+@(*)
+.a .foo bar
+!(*)
+!(*)
+.*
+. .. .a .foo
+@(.*)
+. .. .a .foo
+!(.*)
+bar
+no dotglob: .a .foo bar
+@(.foo)
+.foo
+!(.foo)
+bar
+@(.foo|*)
+.foo bar
+!(.foo|*)
+!(.foo|*)
+!(bar).foo
+!(bar).foo
+*(bar).foo
+.foo
+?(bar).foo
+.foo
+.?
+.. .a
+@(.?)
+.. .a
+!(.?)
+bar
+dotglob: .a .foo bar
+@(?|.?)
+.. .a
+@(?|.*)
+. .. .a .foo
+? .*
+? . .. .a .foo
+*
+.a .foo bar
+no dotglob: .a .foo bar
+@(?|.?)
+.. .a
+@(?|.*)
+. .. .a .foo
+? .*
+? . .. .a .foo
+*
+bar
diff --git a/tests/extglob.tests b/tests/extglob.tests
new file mode 100644
index 0000000..7a7cf91
--- /dev/null
+++ b/tests/extglob.tests
@@ -0,0 +1,390 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test 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
+${THIS_SH} ./extglob1a.sub
+${THIS_SH} ./extglob3.sub
+${THIS_SH} ./extglob4.sub
+${THIS_SH} ./extglob5.sub
+${THIS_SH} ./extglob6.sub
+${THIS_SH} ./extglob7.sub
+
+exit 0
diff --git a/tests/extglob1.sub b/tests/extglob1.sub
new file mode 100644
index 0000000..c73b1ea
--- /dev/null
+++ b/tests/extglob1.sub
@@ -0,0 +1,50 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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/extglob1a.sub b/tests/extglob1a.sub
new file mode 100644
index 0000000..1470386
--- /dev/null
+++ b/tests/extglob1a.sub
@@ -0,0 +1,29 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+shopt -s extglob
+
+TESTDIR=${TMPDIR:-/tmp}/eglob-test-$$
+mkdir $TESTDIR
+builtin cd $TESTDIR || { echo $0: cannot cd to $TESTDIR >&2 ; exit 1; }
+rm -rf *
+
+touch a ab ba
+
+echo a*!(x)
+echo a!(x)
+echo a*?(x)
+echo a?(x)
+
+builtin cd $OLDPWD
+rm -rf $TESTDIR
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.sub b/tests/extglob2.sub
new file mode 100644
index 0000000..1088111
--- /dev/null
+++ b/tests/extglob2.sub
@@ -0,0 +1,31 @@
+LANG=en_US.UTF-8
+
+shopt -s extglob
+a="aaaäöü"
+a1=${a:3:3}
+
+[[ "${a}" == "${a1}" ]] || {
+ echo cond ok 1
+}
+
+case "${a//?aa}" in
+"${a1}") echo ok 1;;
+*) echo bad 1;;
+esac
+
+case "${a//\aaa}" in
+"${a1}") echo ok 2;;
+*) echo bad 2;;
+esac
+
+case "${a//aaa}" in
+"${a1}") echo ok 3;;
+*) echo bad 3;;
+esac
+
+case "${a//@(?aa)}" in
+"${a1}") echo ok 4;;
+*) echo bad 4;;
+esac
+
+exit 0
diff --git a/tests/extglob2.tests b/tests/extglob2.tests
new file mode 100644
index 0000000..187253b
--- /dev/null
+++ b/tests/extglob2.tests
@@ -0,0 +1,103 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# 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.sub b/tests/extglob3.sub
new file mode 100644
index 0000000..bf5d263
--- /dev/null
+++ b/tests/extglob3.sub
@@ -0,0 +1,37 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+shopt -s extglob
+DIR=$TMPDIR/extglob-$$
+mkdir $DIR
+cd $DIR
+
+touch a.log
+
+echo *(.)
+echo *(.)*
+echo *(foo)
+echo *(foo|bar)
+echo ?(foo)*
+echo ?(foo)
+echo *(foo)*
+echo @(|foo)*
+
+echo *(foo).*
+echo *(foo|bar).*
+
+echo !(foo)*
+echo !(foo|bar)*
+
+cd $OLDPWD
+rm -rf $DIR
diff --git a/tests/extglob3.tests b/tests/extglob3.tests
new file mode 100644
index 0000000..56f8b39
--- /dev/null
+++ b/tests/extglob3.tests
@@ -0,0 +1,69 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+shopt -s 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/extglob4.sub b/tests/extglob4.sub
new file mode 100644
index 0000000..5369cd6
--- /dev/null
+++ b/tests/extglob4.sub
@@ -0,0 +1,45 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+LANG=C
+LC_ALL=C
+
+: ${TMPDIR:=/tmp}
+GTDIR=$TMPDIR/extglob4-$$
+
+shopt -s extglob
+[ -d "${GTDIR}" ] || mkdir "${GTDIR}"
+cd "${GTDIR}" || {
+ echo "extglob4: cannot cd to ${GTDIR}"
+ exit 2
+}
+
+touch a b c .x .y .z
+echo .!(|.) # correct
+echo * # correct
+
+echo @(*|.!(|.)) # wrong, adds . and ..
+echo @(*|@(f)) # ??
+echo @(*|@(ff))
+
+echo !(f)
+echo !(f)!(f)
+
+shopt -s dotglob
+echo @(*|@(f))
+echo @(*|@(ff))
+
+cd $OLDPWD
+rm -rf $GTDIR
+
+[[ a = a*?(/)b ]] && echo bad match 1
diff --git a/tests/extglob5.sub b/tests/extglob5.sub
new file mode 100644
index 0000000..580229b
--- /dev/null
+++ b/tests/extglob5.sub
@@ -0,0 +1,31 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# globignore extglob patterns containing colons -- problem until bash-4.2
+
+: ${TMPDIR:=/tmp}
+TESTDIR=$TMPDIR/bash-globignore-$$
+[ -d "$TESTDIR" ] || mkdir "$TESTDIR"
+
+cd "$TESTDIR" || exit 2
+
+shopt -s extglob
+GLOBIGNORE='+([^[:alnum:]]):@([-.,:; _]):[![:alnum:]]'
+
+touch ';' '++'
+echo *
+
+rm ';' '++'
+
+cd $OLDPWD
+rmdir $TESTDIR
diff --git a/tests/extglob6.sub b/tests/extglob6.sub
new file mode 100644
index 0000000..5e2aafb
--- /dev/null
+++ b/tests/extglob6.sub
@@ -0,0 +1,43 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# issues with ? matching "." in certain special circumstances with dotglob set
+
+shopt -s dotglob extglob
+
+DIR=$TMPDIR/extglob-$$
+mkdir $DIR
+cd $DIR
+
+touch a .b
+
+LC_COLLATE=C # fix sort order
+
+echo @(?|.?)
+echo @(.?|?)
+echo ? .?
+
+echo .*
+echo \.*
+
+shopt -u dotglob
+
+echo @(?|.?)
+echo @(.?|?)
+echo ? .?
+
+echo .*
+echo \.*
+
+cd $OLDPWD
+rm -rf $DIR
diff --git a/tests/extglob7.sub b/tests/extglob7.sub
new file mode 100644
index 0000000..5fab9cd
--- /dev/null
+++ b/tests/extglob7.sub
@@ -0,0 +1,97 @@
+: ${TMPDIR:=/tmp}
+
+TESTDIR=$TMPDIR/glob-test-$$
+mkdir $TESTDIR || {
+ echo "$TESTDIR: cannot create" >&2
+ exit 1
+}
+cd $TESTDIR || {
+ echo "$TESTDIR: cannot cd" >&2
+ exit 1
+}
+
+LC_CTYPE=C LC_COLLATE=C
+shopt -s extglob dotglob
+shopt -u globskipdots # XXX - backwards compatibility
+touch .foo bar .a
+
+echo dotglob: .a .foo bar
+
+echo '@(.foo)'
+echo @(.foo)
+echo '!(.foo)'
+echo !(.foo)
+
+echo '@(.foo|*)'
+echo @(.foo|*)
+echo '!(.foo|*)'
+echo !(.foo|*)
+
+echo '@(*)'
+echo @(*)
+echo '!(*)'
+echo !(*)
+
+echo '.*'
+echo .*
+echo '@(.*)'
+echo @(.*)
+echo '!(.*)'
+echo !(.*)
+
+shopt -u dotglob
+
+echo no dotglob: .a .foo bar
+
+echo '@(.foo)'
+echo @(.foo)
+echo '!(.foo)'
+echo !(.foo)
+
+echo '@(.foo|*)'
+echo @(.foo|*)
+echo '!(.foo|*)'
+echo !(.foo|*)
+
+echo '!(bar).foo'
+echo !(bar).foo
+echo '*(bar).foo'
+echo *(bar).foo
+echo '?(bar).foo'
+echo ?(bar).foo
+
+echo '.?'
+echo .?
+echo '@(.?)'
+echo @(.?)
+echo '!(.?)'
+echo !(.?)
+
+shopt -s dotglob
+echo dotglob: .a .foo bar
+
+echo '@(?|.?)'
+echo @(?|.?)
+echo '@(?|.*)'
+echo @(?|.*)
+echo '? .*'
+echo ? .*
+echo '*'
+echo *
+
+shopt -u dotglob
+echo no dotglob: .a .foo bar
+
+echo '@(?|.?)'
+echo @(?|.?)
+echo '@(?|.*)'
+echo @(?|.*)
+echo '? .*'
+echo ? .*
+echo '*'
+echo *
+
+rm -f .a bar .foo
+
+cd $OLDPWD
+rm -rf $TESTDIR
diff --git a/tests/func.right b/tests/func.right
new file mode 100644
index 0000000..f4db4d1
--- /dev/null
+++ b/tests/func.right
@@ -0,0 +1,169 @@
+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 20
+5 20
+expect 2 40
+2 40
+expect 5 20
+5 20
+./func4.sub: line 23: foo: maximum function nesting level exceeded (100)
+1
+after: f = 100
+./func4.sub: line 23: foo: maximum function nesting level exceeded (100)
+1
+after: f = 100
+7
+after FUNCNEST reset: f = 201
+7
+after FUNCNEST unset: f = 201
+./func4.sub: line 23: foo: maximum function nesting level exceeded (20)
+1
+after FUNCNEST assign: f = 38
+5
diff --git a/tests/func.tests b/tests/func.tests
new file mode 100644
index 0000000..e35ec2b
--- /dev/null
+++ b/tests/func.tests
@@ -0,0 +1,198 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# since we look at functions below, remove all functions now
+funcs=$(compgen -A function)
+if [ -n "$funcs" ]; then
+ unset -f $funcs
+fi
+
+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
+
+# FUNCNEST testing
+${THIS_SH} ./func4.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..f7e84f4
--- /dev/null
+++ b/tests/func1.sub
@@ -0,0 +1,68 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# 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..9caabfc
--- /dev/null
+++ b/tests/func2.sub
@@ -0,0 +1,40 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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..5c0eac2
--- /dev/null
+++ b/tests/func3.sub
@@ -0,0 +1,67 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# test 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 20
+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/func4.sub b/tests/func4.sub
new file mode 100644
index 0000000..69f15e4
--- /dev/null
+++ b/tests/func4.sub
@@ -0,0 +1,52 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test FUNCNEST functionality -- bash-4.2
+FUNCNEST=100
+
+foo()
+{
+ (( f++ ))
+ if (( f > 200 )); then
+ return 7
+ fi
+ foo
+}
+
+f=0
+foo
+echo $?
+echo after: f = $f
+
+f=0
+foo
+echo $?
+echo after: f = $f
+
+f=0
+FUNCNEST=0
+foo
+echo $?
+echo after FUNCNEST reset: f = $f
+
+f=0
+unset FUNCNEST
+foo
+echo $?
+echo after FUNCNEST unset: f = $f
+
+FUNCNEST=20
+f=$(( FUNCNEST - 2 ))
+foo
+echo $?
+echo after FUNCNEST assign: f = $f
diff --git a/tests/getopts.right b/tests/getopts.right
new file mode 100644
index 0000000..599d830
--- /dev/null
+++ b/tests/getopts.right
@@ -0,0 +1,68 @@
+getopts: usage: getopts optstring name [arg ...]
+2
+getopts: usage: getopts optstring name [arg ...]
+2
+./getopts.tests: line 23: 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 17: getopts: `opt-var': not a valid identifier
+remaining args:
+opt: x
+opt: y
+opt: a
+opt: b
+opt: c
+opt: z
+$1 = a
+./getopts10.sub: line 16: OPTARG: readonly variable
+OPTARG = x = ?
+unset x = ?
+declare -r RO="foo"
+declare -r RO="foo"
diff --git a/tests/getopts.tests b/tests/getopts.tests
new file mode 100644
index 0000000..06cc29a
--- /dev/null
+++ b/tests/getopts.tests
@@ -0,0 +1,56 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# 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
+
+${THIS_SH} ./getopts8.sub
+${THIS_SH} ./getopts9.sub
+
+${THIS_SH} ./getopts10.sub
diff --git a/tests/getopts1.sub b/tests/getopts1.sub
new file mode 100644
index 0000000..5145879
--- /dev/null
+++ b/tests/getopts1.sub
@@ -0,0 +1,39 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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/getopts10.sub b/tests/getopts10.sub
new file mode 100644
index 0000000..49b2bfe
--- /dev/null
+++ b/tests/getopts10.sub
@@ -0,0 +1,30 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+set -- -a bb
+readonly OPTARG
+getopts :x x
+
+echo OPTARG = $OPTARG x = "$x"
+
+getopts x x
+echo ${OPTARG-unset} x = "$x"
+
+typeset -r RO=foo
+typeset -n OPTARG=RO
+
+getopts :x x
+typeset -p RO
+
+getopts x x
+typeset -p RO
diff --git a/tests/getopts2.sub b/tests/getopts2.sub
new file mode 100644
index 0000000..6bb8af5
--- /dev/null
+++ b/tests/getopts2.sub
@@ -0,0 +1,39 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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..6769c49
--- /dev/null
+++ b/tests/getopts3.sub
@@ -0,0 +1,40 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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..5fbe954
--- /dev/null
+++ b/tests/getopts4.sub
@@ -0,0 +1,43 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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..bf52310
--- /dev/null
+++ b/tests/getopts5.sub
@@ -0,0 +1,62 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#Time-stamp: <95/06/07 07:40:40 hrue@imf.unit.no>
+
+getop () {
+
+ local OPTIND=1
+ 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..d969ece
--- /dev/null
+++ b/tests/getopts6.sub
@@ -0,0 +1,40 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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..de7d7a6
--- /dev/null
+++ b/tests/getopts7.sub
@@ -0,0 +1,43 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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/getopts8.sub b/tests/getopts8.sub
new file mode 100644
index 0000000..6aeeca6
--- /dev/null
+++ b/tests/getopts8.sub
@@ -0,0 +1,13 @@
+f()
+{
+ typeset OPTIND=1
+ typeset opt
+
+ while getopts ":abcxyz" opt
+ do
+ echo opt: "$opt"
+ if [[ $opt = y ]]; then f -abc ; fi
+ done
+}
+
+f -xyz
diff --git a/tests/getopts9.sub b/tests/getopts9.sub
new file mode 100644
index 0000000..f7dcabc
--- /dev/null
+++ b/tests/getopts9.sub
@@ -0,0 +1,29 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+f()
+{
+ OPTIND=4
+
+ echo \$1 = $1
+}
+
+main()
+{
+while getopts abcdefg opt
+do
+ f $opt
+done
+}
+
+main -abc
diff --git a/tests/glob.right b/tests/glob.right
new file mode 100644
index 0000000..723ee7b
--- /dev/null
+++ b/tests/glob.right
@@ -0,0 +1,261 @@
+foo/bar foobar/bar
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+b
+argv[1] = <A£\B>
+argv[1] = <A>
+argv[1] = <B>
+argv[1] = <a£\b>
+0000000 141 243 134 142
+0000004
+ok 6
+ok 7
+invalid bracket expression
+== LANG=C ==
+[[:alpha:]
+ok 1
+[a
+[[:alpha:]
+ok 2
+ok 2.1
+ok 3
+ok 4
+== LANG=en_US.UTF-8 ==
+[[:alpha:]
+ok 1
+[a
+[[:alpha:]
+ok 2
+ok 2.1
+ok 3
+ok 4
+invalid character class
+== LANG=C ==
+p
+p
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+ok 6
+== LANG=en_US.UTF-8 ==
+p
+p
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+ok 6
+invalid collating symbols
+== LANG=C ==
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+== LANG=en_US.UTF-8 ==
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+argv[1] = <a\?>
+a\?
+argv[1] = <a\?>
+a\?
+a\a
+<define\/\
+/>
+./tmp/a/b/c ./tmp/a/b/c ./tmp/a/b/c
+./tmp/a/b/c ./tmp/a/b/c ./tmp/a/b/c
+./tmp/a/b/c
+./tmp/a/b/c
+./tmp\/a/b/c
+./tm[p]\/a/b/c
+./tmp/a/b/c
+argv[1] = <./tmp/a/*>
+argv[1] = <./tmp/a/*>
+argv[1] = <./tmp/a/b/c>
+argv[1] = <./tmp/a/*>
+argv[1] = <./tmp/a/b/c>
+argv[1] = <./t\mp/a/*>
+argv[1] = <./tmp/a/b/c>
+argv[1] = <./tmp/a/>
+argv[1] = <./tmp/a/b/>
+argv[1] = <./t\mp/a/>
+argv[1] = <./t\mp/a/b/>
+argv[1] = <./tmp/a/*>
+argv[1] = <./tmp/a/b/c>
+argv[1] = <./tmp/a>
+argv[1] = <./tmp/a/b*>
+argv[1] = <./tmp/a>
+argv[1] = <./tmp/a/b*>
+argv[1] = <./tmp/>
+argv[1] = <\$foo>
+argv[2] = <\$foo>
+argv[1] = <mixed\$foo/>
+<abcdefg>
+<\.>
+*abc.c
+searchable/\.
+searchable/\./.
+readable/\.
+readable/\./.
+searchable/\.
+readable/\.
+searchable/.
+searchable/.
+searchable/.
+1: [qwe/qwe]
+2: [qwe/
+3: [qwe/]
+4:
+5: [qwe/
+6:
+a\*b
+a\*b*
+é/*
+é/*
+a aa b bb
+.a .aa .b .bb a aa b bb
+.a .aa .b .bb
+. .. .a .aa .b .bb
+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 66: 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..02d5302
--- /dev/null
+++ b/tests/glob.tests
@@ -0,0 +1,410 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+export LC_COLLATE=C
+#
+# test the shell globbing
+#
+expect()
+{
+: # if needed, change me to echo expect "$@"
+}
+
+# First, a test that bash-2.01.1 fails
+${THIS_SH} ./glob1.sub
+${THIS_SH} ./glob2.sub
+${THIS_SH} ./glob3.sub
+${THIS_SH} ./glob4.sub
+${THIS_SH} ./glob5.sub
+${THIS_SH} ./glob6.sub
+${THIS_SH} ./glob7.sub
+${THIS_SH} ./glob8.sub
+${THIS_SH} ./glob9.sub
+${THIS_SH} ./glob10.sub
+
+MYDIR=$PWD # save where we are
+
+TESTDIR=$TMPDIR/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..27c216b
--- /dev/null
+++ b/tests/glob1.sub
@@ -0,0 +1,30 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# bash-2.01.1 failed this test
+: ${TMPDIR:=/var/tmp}
+
+FN=$TMPDIR/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 $OLDPWD
+rm -rf $FN
diff --git a/tests/glob10.sub b/tests/glob10.sub
new file mode 100644
index 0000000..7c14c0d
--- /dev/null
+++ b/tests/glob10.sub
@@ -0,0 +1,32 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# test basic behavior of globskipdots
+TDIR=/tmp/dotglob-$$
+
+{ mkdir $TDIR && cd $TDIR; } || exit 1
+
+touch a b aa bb .a .b .aa .bb
+
+echo *
+shopt -s dotglob
+echo *
+
+shopt -s globskipdots
+echo .*
+shopt -u globskipdots
+echo .*
+
+cd $OLDPWD
+rm -rf $TDIR
diff --git a/tests/glob2.sub b/tests/glob2.sub
new file mode 100644
index 0000000..09cb6d5
--- /dev/null
+++ b/tests/glob2.sub
@@ -0,0 +1,65 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+. ./test-glue-functions
+
+# this locale causes problems all over the place
+if locale -a | grep -i '^zh_HK\.big5hkscs' >/dev/null ; then
+ :
+else
+ echo "glob2.sub: warning: you do not have the zh_HK.big5hkscs locale installed;" >&2
+ echo "glob2.sub: warning: that will cause some of these tests to fail." >&2
+fi
+
+var='ab\'
+
+case $var in
+ab\\) echo ok 1;;
+*) echo bad 1;;
+esac
+
+case $var in
+$var) echo ok 2;;
+*) echo bad 2;;
+esac
+
+case $var in
+'ab\') echo ok 3;;
+*) echo bad 3;;
+esac
+
+[[ $var = $var ]] && echo ok 4
+[[ $var = $'ab\134' ]] && echo ok 5
+
+LC_ALL=zh_HK.big5hkscs
+
+read a b c <<< $'\u3b1 b c\n'
+echo $b
+unset a b c
+
+export alpha=$'\u3b1'
+
+printf -v v 'A%sB' "$alpha"
+recho "$v"
+IFS=$alpha read a b c <<<"$v"
+recho "$a"
+recho "$b"
+unset a b v
+
+recho "a${alpha}b"
+printf "%s" "a${alpha}b" | LC_ALL=C od -b | _intl_normalize_spaces
+
+a=$'\u3b1'
+[[ $a = $a ]] && echo ok 6
+
+LC_ALL=zh_HK.big5hkscs ${THIS_SH} -c $'[[ \u3b1 = \u3b1 ]]' && echo ok 7
diff --git a/tests/glob3.sub b/tests/glob3.sub
new file mode 100644
index 0000000..662c65e
--- /dev/null
+++ b/tests/glob3.sub
@@ -0,0 +1,163 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: ${TMPDIR:=/var/tmp}
+
+TESTDIR=${TMPDIR}/glob-test-$$
+mkdir ${TESTDIR}
+cd $TESTDIR || {
+ echo "$TESTDIR: cannot cd" >&2
+ exit 1
+}
+
+matchfunc()
+{
+ echo == LANG=$LANG ==
+
+ touch a p
+ echo [[:alpha:]
+ rm a p
+
+ case l in
+ [[:alpha:]) echo bad 1;;
+ *) echo ok 1;;
+ esac
+
+ touch '[a' '[x'
+ echo [[:alpha:]
+ rm '[a'
+ echo [[:alpha:]
+ rm '[x'
+
+ case [a in
+ [[:alpha:]) echo ok 2;;
+ *) echo bad 2;;
+ esac
+
+ case x in
+ [[:aeioux:]) echo bad 2.1 ;;
+ *) echo ok 2.1 ;;
+ esac
+
+ case [x in
+ [[:alpha:]) echo bad 3;;
+ *) echo ok 3;;
+ esac
+
+ # unclosed bracket char class expression just matches against ":alpha"
+ case a in
+ [[:alpha]) echo ok 4;;
+ *) echo bad 4;;
+ esac
+}
+
+echo invalid bracket expression
+export LANG=C
+matchfunc
+
+export LANG=en_US.UTF-8
+matchfunc
+
+unset -f matchfunc
+
+matchfunc()
+{
+ echo == LANG=$LANG ==
+
+ touch p
+ # quoted character classes work as if they were unquoted now
+ echo [[:alpha:]]
+ echo [[:"alpha":]]
+ rm -f p
+
+ case a] in
+ [[:aleph:]]) echo bad 1;;
+ *) echo ok 1;;
+ esac
+
+ case a in
+ [[:aleph:]]) echo bad 2;;
+ *) echo ok 2;;
+ esac
+
+ case a] in
+ [[:"alpha":]]) echo bad 3;;
+ *) echo ok 3;;
+ esac
+
+ # Posix says quoted character class names work now
+ case x in
+ [[:"alpha":]]) echo ok 4;;
+ *) echo bad 4;;
+ esac
+
+ case a in
+ [abc[:foo:]]) echo ok 5;;
+ *) echo bad 5 ;;
+ esac
+
+ case a in
+ [[:foo:]abc]) echo ok 6;;
+ *) echo bad 6 ;;
+ esac
+}
+
+echo invalid character class
+export LANG=C
+matchfunc
+
+export LANG=en_US.UTF-8
+matchfunc
+
+unset -f matchfunc
+
+matchfunc()
+{
+ echo == LANG=$LANG ==
+
+ case h in
+ [[.hyphen.]) echo bad 1;;
+ *) echo ok 1;;
+ esac
+
+ case - in
+ [[.hyphen.]]) echo ok 2;;
+ *) echo bad 2;;
+ esac
+
+ case slash in
+ [[.slash.]]) echo bad 3;;
+ *) echo ok 3;;
+ esac
+
+ case a in
+ [abc[.nonsense.]]) echo ok 4;;
+ *) echo bad 4 ;;
+ esac
+
+ case a in
+ [[.nonsense.]abc]) echo ok 5;;
+ *) echo bad 5 ;;
+ esac
+}
+
+echo invalid collating symbols
+
+export LANG=C
+matchfunc
+
+export LANG=en_US.UTF-8
+matchfunc
+
+cd $OLDPWD
+rm -rf $TESTDIR
diff --git a/tests/glob4.sub b/tests/glob4.sub
new file mode 100644
index 0000000..779c854
--- /dev/null
+++ b/tests/glob4.sub
@@ -0,0 +1,41 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: ${TMPDIR:=/var/tmp}
+
+FN=$TMPDIR/bash-glob.$$
+mkdir $FN || { echo "glob4.sub: cannot mkdir $FN" >&2 ; exit 1; }
+builtin cd $FN || { echo "glob4.sub: cannot change directory to $FN" >&2 ; exit 1; }
+rm -f *
+
+touch 'a?' aa
+
+set -- a \?; IFS=\\; var=$*;
+recho "$var"
+unset IFS; printf "%s\n" ${var}
+
+var='a\?'
+recho "$var"
+printf "%s\n" ${var}
+
+var='a\a'
+printf "%s\n" ${var}
+
+# shell's idea of a glob pattern and libglob's idea of a glob pattern have to
+# be identical
+PRE='\/'
+printf '<%s>\n' 'define'${PRE}'\
+/'
+
+builtin cd $OLDPWD
+rm -rf $FN
diff --git a/tests/glob5.sub b/tests/glob5.sub
new file mode 100644
index 0000000..a0dd623
--- /dev/null
+++ b/tests/glob5.sub
@@ -0,0 +1,78 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+[ $UID -eq 0 ] && { echo "glob5.sub: the test suite should not be run as root" >&2 ; }
+
+ORIGD=$PWD
+: ${TMPDIR:=/var/tmp}
+
+SD=$TMPDIR/bash-glob-$$
+[ -d $SD ] || mkdir $SD
+builtin cd $SD || { echo "glob5.sub: cannot change directory to $SD" >&2 ; exit 1; }
+mkdir tmp
+
+D=./tmp/a
+D1='./t\mp/a'
+
+mkdir -m700 ./tmp/a ./tmp/a/b
+touch ./tmp/a/b/c
+
+echo ./tmp/a/b/* "./tmp/a/"b/* "./tmp/a/b"/*
+
+chmod -r ./tmp/a
+echo ./tmp/a/b/* "./tmp/a/"b/* "./tmp/a/b"/*
+echo "./tmp/a/b"/*
+
+bs=\\
+echo ./tmp${bs}/a/b/*
+echo ./tmp${bs}/a/b/c
+echo ./tm[p]${bs}/a/b/c
+echo ./t${bs}mp/a/b/*
+
+recho "./tmp/a"/*
+recho "$D"/*
+recho "$D"/b/*
+
+recho $D/*
+recho $D/b/*
+recho $D1/*
+recho $D1/b/*
+recho $D/
+recho $D/b/
+recho $D1/
+recho $D1/b/
+
+recho ./t\mp/a/*
+recho ./t\mp/a/b/*
+
+recho ./tmp/a*
+recho ./tmp/a/b*
+recho ./t\mp/a*
+recho ./t\mp/a/b*
+
+recho ./t\mp/
+
+chmod +r ./tmp/a
+rm -rf ./tmp/a
+
+a='$foo'
+b='$bar'
+a=$(echo "$a" | sed 's/\$/\\$/g')
+
+recho $a "$a"
+recho 'mixed'$a/
+
+unset a b
+
+cd $ORIGD
+rm -rf $SD
diff --git a/tests/glob6.sub b/tests/glob6.sub
new file mode 100644
index 0000000..8842983
--- /dev/null
+++ b/tests/glob6.sub
@@ -0,0 +1,69 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# tests of the backslash-in-glob-patterns discussion on the austin-group ML
+[ $UID -eq 0 ] && { echo "glob6.sub: the test suite should not be run as root" >&2 ; }
+
+: ${TMPDIR:=/var/tmp}
+
+ORIG=$PWD
+GLOBDIR=$TMPDIR/bash-glob-$$
+mkdir $GLOBDIR || { echo "glob6.sub: cannot make directory $GLOBDIR" >&2 ; exit 1; }
+builtin cd $GLOBDIR || { echo "glob6.sub: cannot change directory to $GLOBDIR" >&2 ; exit 1; }
+
+# does the pattern matcher allow backslashes as escape characters and remove
+# them as part of matching?
+touch abcdefg
+pat='ab\cd*'
+printf '<%s>\n' $pat
+pat='\.'
+printf '<%s>\n' $pat
+rm abcdefg
+
+# how about when escaping pattern characters?
+touch '*abc.c'
+a='\**.c'
+printf '%s\n' $a
+rm -f '*abc.c'
+
+# how about when making the distinction between readable and searchable path
+# components?
+mkdir -m a=x searchable
+mkdir -m a=r readable
+
+p='searchable/\.'
+printf "%s\n" $p
+
+p='searchable/\./.'
+printf "%s\n" $p
+
+p='readable/\.'
+printf "%s\n" $p
+
+p='readable/\./.'
+printf "%s\n" $p
+
+printf "%s\n" 'searchable/\.'
+printf "%s\n" 'readable/\.'
+
+echo */.
+
+p='*/\.'
+echo $p
+
+echo */'.'
+
+rmdir searchable readable
+
+cd $ORIG
+rmdir $GLOBDIR
diff --git a/tests/glob7.sub b/tests/glob7.sub
new file mode 100644
index 0000000..0212b8e
--- /dev/null
+++ b/tests/glob7.sub
@@ -0,0 +1,11 @@
+# according to Posix 2.13.3, a slash in a bracket expression renders that
+# bracket expression invalid
+shopt -s nullglob
+
+echo 1: [qwe/qwe]
+echo 2: [qwe/
+echo 3: [qwe/]
+
+echo 4: [qwe\/qwe]
+echo 5: [qwe\/
+echo 6: [qwe\/]
diff --git a/tests/glob8.sub b/tests/glob8.sub
new file mode 100644
index 0000000..dca54fc
--- /dev/null
+++ b/tests/glob8.sub
@@ -0,0 +1,31 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: ${TMPDIR:=/var/tmp}
+
+TESTDIR=${TMPDIR}/glob-test-$$
+mkdir ${TESTDIR}
+cd $TESTDIR || {
+ echo "$TESTDIR: cannot cd" >&2
+ exit 1
+}
+
+trap 'cd $OLDPWD && rm -rf $TESTDIR' EXIT
+
+var='a\'
+touch 'a*b' 'a\*b'
+
+printf '%s\n' $var\*b*
+
+var1=a\\$'\001'
+printf '%s\n' $var1\*b*
diff --git a/tests/glob9.sub b/tests/glob9.sub
new file mode 100644
index 0000000..ef2af2b
--- /dev/null
+++ b/tests/glob9.sub
@@ -0,0 +1,13 @@
+LANG=en_US.UTF-8 # safest
+: ${TMPDIR:=/var/tmp}
+HOME=${TMPDIR}
+
+mkdir ~/ಇಳಿಕೆಗಳà³
+touch ~/ಇಳಿಕೆಗಳà³/{a,b}.txt
+echo ~/ಇಳಿಕೆಗಳà³/*.txt >/dev/null
+
+rm -rf ${TMPDIR}/ಇಳಿಕೆಗಳà³
+
+LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
+echo é/*
+echo 'é'/*
diff --git a/tests/globstar.right b/tests/globstar.right
new file mode 100644
index 0000000..c8211bc
--- /dev/null
+++ b/tests/globstar.right
@@ -0,0 +1,587 @@
+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
+<a>
+<a/a>
+<a/a/a>
+<a>
+<a/a>
+<a/a/a>
+<a>
+<a/a>
+<a/a/a>
+== <**/a> ==
+<a>
+<a/a>
+<a/a/a>
+<a/a/a/a>
+<a/a/b/a>
+<a/b/a>
+<a/b/a/a>
+<a/b/b/a>
+<b/a>
+<b/a/a>
+<b/a/a/a>
+<b/a/b/a>
+<b/b/a>
+<b/b/a/a>
+<b/b/b/a>
+== <a/**> ==
+<a/>
+<a/a>
+<a/a/a>
+<a/a/a/a>
+<a/a/a/b>
+<a/a/b>
+<a/a/b/a>
+<a/a/b/b>
+<a/b>
+<a/b/a>
+<a/b/a/a>
+<a/b/a/b>
+<a/b/b>
+<a/b/b/a>
+<a/b/b/b>
+== <**> ==
+<a>
+<a/a>
+<a/a/a>
+<a/a/a/a>
+<a/a/a/b>
+<a/a/b>
+<a/a/b/a>
+<a/a/b/b>
+<a/b>
+<a/b/a>
+<a/b/a/a>
+<a/b/a/b>
+<a/b/b>
+<a/b/b/a>
+<a/b/b/b>
+<b>
+<b/a>
+<b/a/a>
+<b/a/a/a>
+<b/a/a/b>
+<b/a/b>
+<b/a/b/a>
+<b/a/b/b>
+<b/b>
+<b/b/a>
+<b/b/a/a>
+<b/b/a/b>
+<b/b/b>
+<b/b/b/a>
+<b/b/b/b>
+== <**/**> ==
+<a>
+<a/a>
+<a/a/a>
+<a/a/a/a>
+<a/a/a/b>
+<a/a/b>
+<a/a/b/a>
+<a/a/b/b>
+<a/b>
+<a/b/a>
+<a/b/a/a>
+<a/b/a/b>
+<a/b/b>
+<a/b/b/a>
+<a/b/b/b>
+<b>
+<b/a>
+<b/a/a>
+<b/a/a/a>
+<b/a/a/b>
+<b/a/b>
+<b/a/b/a>
+<b/a/b/b>
+<b/b>
+<b/b/a>
+<b/b/a/a>
+<b/b/a/b>
+<b/b/b>
+<b/b/b/a>
+<b/b/b/b>
+== <**/**/**> ==
+<a>
+<a/a>
+<a/a/a>
+<a/a/a/a>
+<a/a/a/b>
+<a/a/b>
+<a/a/b/a>
+<a/a/b/b>
+<a/b>
+<a/b/a>
+<a/b/a/a>
+<a/b/a/b>
+<a/b/b>
+<a/b/b/a>
+<a/b/b/b>
+<b>
+<b/a>
+<b/a/a>
+<b/a/a/a>
+<b/a/a/b>
+<b/a/b>
+<b/a/b/a>
+<b/a/b/b>
+<b/b>
+<b/b/a>
+<b/b/a/a>
+<b/b/a/b>
+<b/b/b>
+<b/b/b/a>
+<b/b/b/b>
+== <**/**/**/**/**> ==
+<a>
+<a/a>
+<a/a/a>
+<a/a/a/a>
+<a/a/a/b>
+<a/a/b>
+<a/a/b/a>
+<a/a/b/b>
+<a/b>
+<a/b/a>
+<a/b/a/a>
+<a/b/a/b>
+<a/b/b>
+<a/b/b/a>
+<a/b/b/b>
+<b>
+<b/a>
+<b/a/a>
+<b/a/a/a>
+<b/a/a/b>
+<b/a/b>
+<b/a/b/a>
+<b/a/b/b>
+<b/b>
+<b/b/a>
+<b/b/a/a>
+<b/b/a/b>
+<b/b/b>
+<b/b/b/a>
+<b/b/b/b>
+== <**/**/a> ==
+<a>
+<a/a>
+<a/a/a>
+<a/a/a/a>
+<a/a/b/a>
+<a/b/a>
+<a/b/a/a>
+<a/b/b/a>
+<b/a>
+<b/a/a>
+<b/a/a/a>
+<b/a/b/a>
+<b/b/a>
+<b/b/a/a>
+<b/b/b/a>
+== <a/**/**> ==
+<a>
+<a/a>
+<a/a/a>
+<a/a/a/a>
+<a/a/a/b>
+<a/a/b>
+<a/a/b/a>
+<a/a/b/b>
+<a/b>
+<a/b/a>
+<a/b/a/a>
+<a/b/a/b>
+<a/b/b>
+<a/b/b/a>
+<a/b/b/b>
+== <a/**/**/**> ==
+<a>
+<a/a>
+<a/a/a>
+<a/a/a/a>
+<a/a/a/b>
+<a/a/b>
+<a/a/b/a>
+<a/a/b/b>
+<a/b>
+<a/b/a>
+<a/b/a/a>
+<a/b/a/b>
+<a/b/b>
+<a/b/b/a>
+<a/b/b/b>
+== <a/**/**/**/**> ==
+<a>
+<a/a>
+<a/a/a>
+<a/a/a/a>
+<a/a/a/b>
+<a/a/b>
+<a/a/b/a>
+<a/a/b/b>
+<a/b>
+<a/b/a>
+<a/b/a/a>
+<a/b/a/b>
+<a/b/b>
+<a/b/b/a>
+<a/b/b/b>
+== <**/a/**> ==
+<a>
+<a/a>
+<a/a>
+<a/a/a>
+<a/a/a>
+<a/a/a>
+<a/a/a/a>
+<a/a/a/a>
+<a/a/a/a>
+<a/a/a/a>
+<a/a/a/b>
+<a/a/a/b>
+<a/a/a/b>
+<a/a/b>
+<a/a/b>
+<a/a/b/a>
+<a/a/b/a>
+<a/a/b/a>
+<a/a/b/b>
+<a/a/b/b>
+<a/b>
+<a/b/a>
+<a/b/a>
+<a/b/a/a>
+<a/b/a/a>
+<a/b/a/a>
+<a/b/a/b>
+<a/b/a/b>
+<a/b/b>
+<a/b/b/a>
+<a/b/b/a>
+<a/b/b/b>
+<b/a>
+<b/a/a>
+<b/a/a>
+<b/a/a/a>
+<b/a/a/a>
+<b/a/a/a>
+<b/a/a/b>
+<b/a/a/b>
+<b/a/b>
+<b/a/b/a>
+<b/a/b/a>
+<b/a/b/b>
+<b/b/a>
+<b/b/a/a>
+<b/b/a/a>
+<b/b/a/b>
+<b/b/b/a>
+== <**/a/**/**> ==
+<a>
+<a/a>
+<a/a>
+<a/a/a>
+<a/a/a>
+<a/a/a>
+<a/a/a/a>
+<a/a/a/a>
+<a/a/a/a>
+<a/a/a/a>
+<a/a/a/b>
+<a/a/a/b>
+<a/a/a/b>
+<a/a/b>
+<a/a/b>
+<a/a/b/a>
+<a/a/b/a>
+<a/a/b/a>
+<a/a/b/b>
+<a/a/b/b>
+<a/b>
+<a/b/a>
+<a/b/a>
+<a/b/a/a>
+<a/b/a/a>
+<a/b/a/a>
+<a/b/a/b>
+<a/b/a/b>
+<a/b/b>
+<a/b/b/a>
+<a/b/b/a>
+<a/b/b/b>
+<b/a>
+<b/a/a>
+<b/a/a>
+<b/a/a/a>
+<b/a/a/a>
+<b/a/a/a>
+<b/a/a/b>
+<b/a/a/b>
+<b/a/b>
+<b/a/b/a>
+<b/a/b/a>
+<b/a/b/b>
+<b/b/a>
+<b/b/a/a>
+<b/b/a/a>
+<b/b/a/b>
+<b/b/b/a>
+== <**/a/**/**/**> ==
+<a>
+<a/a>
+<a/a>
+<a/a/a>
+<a/a/a>
+<a/a/a>
+<a/a/a/a>
+<a/a/a/a>
+<a/a/a/a>
+<a/a/a/a>
+<a/a/a/b>
+<a/a/a/b>
+<a/a/a/b>
+<a/a/b>
+<a/a/b>
+<a/a/b/a>
+<a/a/b/a>
+<a/a/b/a>
+<a/a/b/b>
+<a/a/b/b>
+<a/b>
+<a/b/a>
+<a/b/a>
+<a/b/a/a>
+<a/b/a/a>
+<a/b/a/a>
+<a/b/a/b>
+<a/b/a/b>
+<a/b/b>
+<a/b/b/a>
+<a/b/b/a>
+<a/b/b/b>
+<b/a>
+<b/a/a>
+<b/a/a>
+<b/a/a/a>
+<b/a/a/a>
+<b/a/a/a>
+<b/a/a/b>
+<b/a/a/b>
+<b/a/b>
+<b/a/b/a>
+<b/a/b/a>
+<b/a/b/b>
+<b/b/a>
+<b/b/a/a>
+<b/b/a/a>
+<b/b/a/b>
+<b/b/b/a>
+== <**/**/a/**> ==
+<a>
+<a/a>
+<a/a>
+<a/a/a>
+<a/a/a>
+<a/a/a>
+<a/a/a/a>
+<a/a/a/a>
+<a/a/a/a>
+<a/a/a/a>
+<a/a/a/b>
+<a/a/a/b>
+<a/a/a/b>
+<a/a/b>
+<a/a/b>
+<a/a/b/a>
+<a/a/b/a>
+<a/a/b/a>
+<a/a/b/b>
+<a/a/b/b>
+<a/b>
+<a/b/a>
+<a/b/a>
+<a/b/a/a>
+<a/b/a/a>
+<a/b/a/a>
+<a/b/a/b>
+<a/b/a/b>
+<a/b/b>
+<a/b/b/a>
+<a/b/b/a>
+<a/b/b/b>
+<b/a>
+<b/a/a>
+<b/a/a>
+<b/a/a/a>
+<b/a/a/a>
+<b/a/a/a>
+<b/a/a/b>
+<b/a/a/b>
+<b/a/b>
+<b/a/b/a>
+<b/a/b/a>
+<b/a/b/b>
+<b/b/a>
+<b/b/a/a>
+<b/b/a/a>
+<b/b/a/b>
+<b/b/b/a>
+a a/aa a/ab b b/bb b/bc c
+a/ b/ c/
+a/ab b b/bb
diff --git a/tests/globstar.tests b/tests/globstar.tests
new file mode 100644
index 0000000..33714b4
--- /dev/null
+++ b/tests/globstar.tests
@@ -0,0 +1,56 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: ${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
+${THIS_SH} ./globstar2.sub
+${THIS_SH} ./globstar3.sub
diff --git a/tests/globstar1.sub b/tests/globstar1.sub
new file mode 100644
index 0000000..7097f5d
--- /dev/null
+++ b/tests/globstar1.sub
@@ -0,0 +1,34 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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/globstar2.sub b/tests/globstar2.sub
new file mode 100644
index 0000000..ccf413b
--- /dev/null
+++ b/tests/globstar2.sub
@@ -0,0 +1,97 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+olddir=$PWD
+: ${TMPDIR:=/var/tmp}
+EMPTY=$TMPDIR/empty
+
+shopt -s globstar
+s()
+{
+ printf '== <%s> ==\n' "$@"
+}
+p()
+{
+ printf '<%q>\n' "$@"
+}
+
+mkdir -p $EMPTY/a/a/a
+cd $EMPTY
+
+# good
+p **
+p **/**
+p **/**/**
+
+rm -rf a
+mkdir -p $EMPTY/{a,b}/{a,b}/{a,b}/{a,b}
+cd $EMPTY
+
+# good
+s '**/a'
+p **/a
+
+# good
+s 'a/**'
+p a/**
+
+# good
+s '**'
+p **
+
+# good
+s '**/**'
+p **/**
+
+# good
+s '**/**/**'
+p **/**/**
+
+# good
+s '**/**/**/**/**'
+p **/**/**/**/**
+
+# good
+s '**/**/a'
+p **/**/a
+
+# good
+s 'a/**/**'
+p a/**/**
+
+# good
+s 'a/**/**/**'
+p a/**/**/**
+
+# good
+s 'a/**/**/**/**'
+p a/**/**/**/**
+
+# same as ksh93
+s '**/a/**'
+p **/a/**
+
+# same as ksh93
+s '**/a/**/**'
+p **/a/**/**
+
+# same as ksh93
+s '**/a/**/**/**'
+p **/a/**/**/**
+
+# good
+s '**/**/a/**'
+p **/**/a/**
+
+cd "$olddir"
+rm -rf $EMPTY
diff --git a/tests/globstar3.sub b/tests/globstar3.sub
new file mode 100644
index 0000000..771d906
--- /dev/null
+++ b/tests/globstar3.sub
@@ -0,0 +1,37 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+olddir=$PWD
+: ${TMPDIR:=/var/tmp}
+
+SCRATCH=${TMPDIR}/scratch-$$
+rm -rf $SCRATCH
+mkdir $SCRATCH || exit 1
+
+cd $SCRATCH
+
+mkdir a b
+touch a/aa a/ab
+touch b/bb b/bc
+
+ln -s a c
+
+shopt -s globstar
+
+echo **
+echo **/
+
+echo **/*b
+
+cd "$olddir"
+rm -rf $SCRATCH
diff --git a/tests/heredoc.right b/tests/heredoc.right
new file mode 100644
index 0000000..cc193f6
--- /dev/null
+++ b/tests/heredoc.right
@@ -0,0 +1,133 @@
+a
+b
+c
+a
+$PS4
+
+
+
+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 ${TMPDIR}/foo <<ENDOFINPUT > /dev/null
+/^name/d
+w
+q
+ENDOFINPUT
+
+ aa=1
+}
+fff is a function
+fff ()
+{
+ ed ${TMPDIR}/foo <<ENDOFINPUT > /dev/null
+/^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
+abc def geh
+./heredoc3.sub: line 20: warning: here-document at line 18 delimited by end-of-file (wanted `EOF')
+= here is the text =
+./heredoc3.sub: line 26: warning: here-document at line 24 delimited by end-of-file (wanted `EOF')
+this paren ) is not a problem
+./heredoc3.sub: line 32: warning: here-document at line 30 delimited by end-of-file (wanted `EOF')
+these balanced parens ( ) are not a problem
+./heredoc3.sub: line 38: warning: here-document at line 36 delimited by end-of-file (wanted `EOF')
+quoted balanced parens \( ) are not a problem either
+more text in a subshell
+some more text in a different subshell
+end
+hello
+hello
+ENDEND
+end ENDEND
+hello
+end hello
+end x*x
+helloEND
+end helloEND
+hello
+\END
+end hello<NL>\END
+./heredoc3.sub: line 98: warning: here-document at line 96 delimited by end-of-file (wanted `EOF')
+./heredoc3.sub: line 99: syntax error: unexpected end of file
+heredoc1
+EOF
+Ok:0
+argv[1] = <onetwo>
+argv[2] = <threefour>
+argv[1] = <two>
+argv[2] = <threefi>
+argv[3] = <ve>
+1: OK
+2: OK
+3: OK
+4: OK
+5: OK
+6: OK
+7: OK
+1: OK
+2: OK
+3: OK
+4: OK
+5: OK
+5: OK
+1: ${x#$'no\t'}
+2: O${x#$'no\t'O}
+3: ${x#n$'o\t'}
+4: ${x#'no '}
+5: ${x#$pat}
+6: ${y#$'not'}
+7: ${y#'not'}
+./heredoc7.sub: line 17: warning: command substitution: 1 unterminated here-document
+foo bar
+./heredoc7.sub: line 21: after: command not found
+./heredoc7.sub: line 29: warning: here-document at line 29 delimited by end-of-file (wanted `EOF')
+./heredoc7.sub: line 29: foobar: command not found
+./heredoc7.sub: line 30: EOF: command not found
+grep: *.c: No such file or directory
+comsub here-string
+./heredoc.tests: line 156: warning: here-document at line 154 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..d10a7c1
--- /dev/null
+++ b/tests/heredoc.tests
@@ -0,0 +1,156 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# basics
+cat <<EOF
+a
+b
+c
+EOF
+read x <<EOF
+a
+b
+c
+EOF
+echo "$x"
+read x y <<\EOF
+$PS4
+EOF
+echo "$x"
+
+# empty here-documents
+read x <<EOF
+EOF
+echo "$x"
+read x <<\EOF
+EOF
+echo "$x"
+read x <<EOF
+$empty
+EOF
+echo "$x"
+
+# 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 ${TMPDIR}/bash-zzz
+cat > ${TMPDIR}/bash-zzz << EOF
+abc
+EOF
+cat >> ${TMPDIR}/bash-zzz << EOF
+def ghi
+jkl mno
+EOF
+cat ${TMPDIR}/bash-zzz
+rm -f ${TMPDIR}/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 ${TMPDIR}/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
+
+# test heredocs in command substitutions
+${THIS_SH} ./heredoc2.sub
+${THIS_SH} ./heredoc3.sub
+${THIS_SH} ./heredoc4.sub
+
+# heredoc tests that use different size documents to test pipe implementation
+${THIS_SH} ./heredoc5.sub
+
+# test $'...' and $"..." quoted strings in here-documents
+${THIS_SH} ./heredoc6.sub
+
+# interaction between here-documents and command substitutions
+${THIS_SH} ./heredoc7.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..34977c5
--- /dev/null
+++ b/tests/heredoc1.sub
@@ -0,0 +1,29 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+foo()
+{
+ echo
+ cat <<END
+bar
+END
+ cat <<EOF
+qux
+EOF
+}
+
+type foo
+foo
+
+eval "$(type foo | sed 1d)"
+foo
diff --git a/tests/heredoc2.sub b/tests/heredoc2.sub
new file mode 100644
index 0000000..7e97ed8
--- /dev/null
+++ b/tests/heredoc2.sub
@@ -0,0 +1,9 @@
+TEST=$(cat <<EOF | sort -u
+abc
+geh
+def
+abc
+EOF
+)
+
+echo $TEST
diff --git a/tests/heredoc3.sub b/tests/heredoc3.sub
new file mode 100644
index 0000000..efbdf7d
--- /dev/null
+++ b/tests/heredoc3.sub
@@ -0,0 +1,98 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+SAVEPWD=$PWD
+: ${TMPDIR:=/tmp}
+cd $TMPDIR || echo "heredoc3.sub: cannot cd to $TMPDIR" >&2
+
+text=$(cat <<EOF
+here is the text
+EOF)
+
+echo = $text =
+
+unbalanced=$(cat <<EOF
+this paren ) is not a problem
+EOF)
+
+echo $unbalanced
+
+balanced=$(cat <<EOF
+these balanced parens ( ) are not a problem
+EOF)
+
+echo $balanced
+
+balanced=$(cat <<EOF
+quoted balanced parens \( ) are not a problem either
+EOF)
+
+echo $balanced
+
+(cat <<EOF
+more text in a subshell
+EOF
+)
+
+(cat <<EOF; )
+some more text in a different subshell
+EOF
+echo end
+
+# semi-weird examples posted by Wayne Pollack to austin-group mailing list
+cat <<-' END'
+ hello
+ END
+
+cat <<END
+hello
+END\
+END
+END
+echo end ENDEND
+
+cat <<' END '
+hello
+ END
+echo end hello
+
+cat <<x*x >/dev/null & touch 'x*x'
+x star x
+x*x
+wait $!
+echo end 'x*x'
+rm 'x*x'
+
+cat <<END
+hello\
+END
+END
+echo end helloEND
+
+cat <<END
+hello
+\END
+END
+echo -E end 'hello<NL>\END'
+
+# gprof
+if [ -n "$GMON_OUT_PREFIX" ]; then
+ mv ${GMON_OUT_PREFIX}.[0-9]* "$SAVEPWD" >/dev/null 2>&1
+fi
+cd "$SAVEPWD"
+
+# this has to be last -- results in a syntax error
+# doesn't currently parse because EOF is not on a line by itself -- should it?
+(cat <<EOF
+still more text in a subshell
+EOF)
diff --git a/tests/heredoc4.sub b/tests/heredoc4.sub
new file mode 100644
index 0000000..381b64a
--- /dev/null
+++ b/tests/heredoc4.sub
@@ -0,0 +1,12 @@
+cat <<EO`true`F
+heredoc1
+EO`false`F
+EO`true`F
+echo Ok:$?
+
+one=one
+four=four
+five='fi ve'
+
+recho $one`echo two three`$four
+recho `echo two three`$five
diff --git a/tests/heredoc5.sub b/tests/heredoc5.sub
new file mode 100644
index 0000000..d7b5926
--- /dev/null
+++ b/tests/heredoc5.sub
@@ -0,0 +1,41 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test here documents for sizes > 65536 (max pipe capacity I've seen),
+# 4096 < size < 65536 (for smaller pipe capacities)
+# 512 < size < 4096 (PIPE_BUF)
+#
+# There are tests in other scripts for here documents shorter than 512 bytes
+#
+# This should return the same results regardless of the pipe capacity
+
+: ${TMPDIR:=/tmp}
+FILENAME=${TMPDIR}/catfile-$$
+
+catfile()
+{
+ cat <<- EOF > $FILENAME
+ $(cat $1)
+EOF
+ cmp $FILENAME $1
+ rm -f $FILENAME
+}
+
+
+if [ -f $BUILD_DIR/y.tab.c ]; then
+ catfile $BUILD_DIR/y.tab.c
+else
+ catfile ../y.tab.c
+fi
+catfile ${BUILD_DIR}/config.h
+catfile ${BUILD_DIR}/version.h
diff --git a/tests/heredoc6.sub b/tests/heredoc6.sub
new file mode 100644
index 0000000..1d5fff0
--- /dev/null
+++ b/tests/heredoc6.sub
@@ -0,0 +1,50 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# test $'...' and $"..." strings in here documents (problem through bash-5.1)
+
+pat=$'no\t'
+x=$'no\tOK'
+y=notOK
+
+cat <<EOF
+1: ${x#$'no\t'}
+2: O${x#$'no\t'O}
+3: ${x#n$'o\t'}
+4: ${x#'no '}
+5: ${x#$pat}
+6: ${y#$'not'}
+7: ${y#'not'}
+EOF
+
+cat <<EOF
+1: ${x#$"no "}
+2: ${x#n$"o "}
+3: O${x#n$"o "O}
+4: ${x#"no "}
+5: ${y#$"not"}
+5: ${y#"not"}
+EOF
+
+# we don't perform dollar-quote expansion if the here-doc delimiter is quoted
+
+cat <<\EOF
+1: ${x#$'no\t'}
+2: O${x#$'no\t'O}
+3: ${x#n$'o\t'}
+4: ${x#'no '}
+5: ${x#$pat}
+6: ${y#$'not'}
+7: ${y#'not'}
+EOF
diff --git a/tests/heredoc7.sub b/tests/heredoc7.sub
new file mode 100644
index 0000000..4119df1
--- /dev/null
+++ b/tests/heredoc7.sub
@@ -0,0 +1,29 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# should characters outside a command substitution be interpreted as a delimiter
+# for a here-document started inside it?
+echo $(cat << EOF)
+foo
+bar
+EOF
+after
+
+# should characters inside a command substitution be interpreted as a delimiter
+# for a here-document started outside of it?
+
+cat <<EOF && grep $(
+ foobar
+EOF
+echo notthereanywhere) *.c
diff --git a/tests/herestr.right b/tests/herestr.right
new file mode 100644
index 0000000..4ac2cc6
--- /dev/null
+++ b/tests/herestr.right
@@ -0,0 +1,38 @@
+alpha
+beta
+4
+4
+
+
+
+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\n')
+foo bar
+foo bar
+qux:::::bax
+qux:::::bax
diff --git a/tests/herestr.tests b/tests/herestr.tests
new file mode 100644
index 0000000..c97fa4f
--- /dev/null
+++ b/tests/herestr.tests
@@ -0,0 +1,80 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# since we look at functions below, remove all functions now
+funcs=$(compgen -A function)
+if [ -n "$funcs" ]; then
+ unset -f $funcs
+fi
+
+# basics
+read x <<<"alpha"
+echo "$x"
+read x <<<beta
+echo "$x"
+X=4
+read x <<<$X
+echo "$x"
+read x <<<"$X"
+echo "$x"
+unset X
+
+# empty here-strings
+read x <<<""
+echo "$x"
+read x <<<"$empty"
+echo "$x"
+read x <<<$empty
+echo "$x"
+
+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
+
+${THIS_SH} ./herestr1.sub
diff --git a/tests/herestr1.sub b/tests/herestr1.sub
new file mode 100644
index 0000000..0cf8082
--- /dev/null
+++ b/tests/herestr1.sub
@@ -0,0 +1,10 @@
+# problems with word splitting unquoted here-strings present since bash-3.2
+
+x="foo bar"
+cat <<< $x # Word-splitting appears to collapse the run of whitespace
+cat <<< "$x" # Whitespace preserved, as with here doc
+
+x="qux:::::bax"
+IFS=':'
+cat <<< $x # Word-splitting appears to collapse the run of whitespace
+cat <<< "$x" # Whitespace preserved, as with here doc
diff --git a/tests/histexp.right b/tests/histexp.right
new file mode 100644
index 0000000..341252c
--- /dev/null
+++ b/tests/histexp.right
@@ -0,0 +1,246 @@
+echo $BASH_VERSION
+./histexp.tests: line 37: 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=$TMPDIR/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=$TMPDIR/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
+echo shopt a
+shopt a
+echo a b c d 2> /dev/null
+a b c d
+one two three four
+echo two ; echo four
+one two three four
+echo four ; echo two
+!
+!
+!
+!
+!
+!
+!
+!
+!
+\!
+\!
+\!
+\!
+a
+b
+c
+echo "#!/bin/bash" set -o posix
+#!/bin/bash set -o posix
+!!
+!!
+a
+echo $(echo echo a)
+echo a
+a
+echo echo a $(echo echo a)
+echo a echo a
+b
+!! $(echo !!)
+c
+echo "echo c" "$(echo echo c)"
+echo c echo c
+d
+echo "echo d" $(echo "echo d")
+echo d echo d
+e
+!! !!
+f
+!!
+f
+!!
+g
+echo "echo g"
+echo g
+g
+eval echo "echo g"
+echo g
+h
+echo \!\! `echo echo h`
+!! echo h
+i
+echo echo i `echo echo i`
+echo i echo i
+j
+echo `echo j` echo j
+j echo j
+a
+cat < <(echo echo a)
+echo a
+b
+echo echo b `echo echo b`
+echo b echo b
+c
+!
+d
+!
+e
+! !
+./histexp4.sub: line 33: !': event not found
+/tmp/Step1
+echo /$(echo tmp)/Step1
+/tmp/Step1
+echo /<(echo tmp)/Step1 > /dev/null
+/tmp/Step1
+echo $(echo /tmp)/Step1
+/tmp/Step1
+echo <(echo /tmp)/Step1 > /dev/null
+/+(one|two|three)/Step1
+echo /+(one|two|three)/Step1
+/+(one|two|three)/Step1
+/*(tmp|dev|usr)/Step1
+echo /*(tmp|dev|usr)/Step1
+/*(tmp|dev|usr)/Step1
++(/one|/two|/three)/Step1
+echo +(/one|/two|/three)/Step1
++(/one|/two|/three)/Step1
+*(/tmp|/dev|/usr)/Step1
+echo *(/tmp|/dev|/usr)/Step1
+*(/tmp|/dev|/usr)/Step1
+one
+ echo echo one
+echo one
+echo one
+echo one
+ 1 set -o histexpand
+ 2 echo one
+ 3 for f in a b c; do echo echo one; done
+ 4 history
+two
+ echo echo two
+echo two
+echo two
+echo two
+ 1 echo two
+ 2 for f in a b c; do echo echo two; done
+ 3 history
+a
+echo !!
+--between--
+echo !!
diff --git a/tests/histexp.tests b/tests/histexp.tests
new file mode 100644
index 0000000..91a36f2
--- /dev/null
+++ b/tests/histexp.tests
@@ -0,0 +1,158 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+LC_ALL=C
+LANG=C
+trap 'rm $TMPDIR/newhistory' 0
+
+file=bax
+histchars='!^#' # make sure history comment char is set correctly
+
+unset HISTFILESIZE HISTTIMEFORMAT
+
+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=$TMPDIR/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_comment_char
+echo ok 3 # !1200
+
+# bash versions through bash-4.3 fail this; they make the digit preceding the
+# > into a separate word, changing the meaning of the redirection
+shopt a b c d 2>/dev/null
+echo !shopt-1
+
+echo !shopt*
+
+# make sure a :p modifier anywhere on the line affects all history expansions
+echo one two three four
+echo !:2:p ; echo !$
+echo one two three four
+echo !$ ; echo !:2:p
+
+${THIS_SH} ./histexp1.sub
+${THIS_SH} ./histexp2.sub
+${THIS_SH} ./histexp3.sub
+${THIS_SH} ./histexp4.sub
+${THIS_SH} ./histexp5.sub
+${THIS_SH} ./histexp6.sub
+${THIS_SH} ./histexp7.sub
diff --git a/tests/histexp1.sub b/tests/histexp1.sub
new file mode 100644
index 0000000..cc2c5d1
--- /dev/null
+++ b/tests/histexp1.sub
@@ -0,0 +1,36 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+LC_ALL=C
+LANG=C
+
+set -o history
+set -H
+
+echo '!'
+echo "!"
+echo !
+
+echo "$( echo '!' )"
+echo "$( echo "!" )"
+echo "$( echo ! )"
+
+echo $( echo '!' )
+echo $( echo "!" )
+echo $( echo ! )
+
+echo "$( echo "\!" )"
+echo "\!"
+
+echo "$( echo '\!' )"
+echo '\!'
diff --git a/tests/histexp2.sub b/tests/histexp2.sub
new file mode 100644
index 0000000..bb5bfda
--- /dev/null
+++ b/tests/histexp2.sub
@@ -0,0 +1,14 @@
+LANG=C LC_ALL=C
+
+set -o history
+echo a
+echo b
+echo c
+
+set -o histexpand
+set -o posix
+
+echo "#!/bin/bash" !!
+
+echo '!!'
+echo "!!"
diff --git a/tests/histexp3.sub b/tests/histexp3.sub
new file mode 100644
index 0000000..4962436
--- /dev/null
+++ b/tests/histexp3.sub
@@ -0,0 +1,57 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+HISTFILE=${TMPDIR}/bashhist-$$
+
+set -o history
+set -o histexpand
+
+echo a
+echo $(echo !!)
+
+echo a
+echo !! $(echo !!)
+
+echo b
+echo '!!' '$(echo !!)'
+
+echo c
+echo "!!" "$(echo !!)"
+
+echo d
+echo "!!" $(echo "!!")
+
+echo e
+echo '!!' $(echo '!!')
+
+echo f
+echo '!!'
+echo f
+eval echo '!!'
+
+echo g
+echo "!!"
+echo g
+eval echo "!!"
+
+echo h
+echo \!\! `echo !!`
+
+echo i
+echo !! `echo !!`
+
+echo j
+echo `echo j` !!
+
+set +o history
+rm -f $HISTFILE # just in case
diff --git a/tests/histexp4.sub b/tests/histexp4.sub
new file mode 100644
index 0000000..9cae0e3
--- /dev/null
+++ b/tests/histexp4.sub
@@ -0,0 +1,36 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+HISTFILE=$TMPDIR/bashhist-$$
+
+set -o history
+set -o histexpand
+
+echo a
+cat < <(echo !!)
+
+echo b
+echo !! `echo !!`
+
+echo c
+echo "$(echo "!" )"
+
+echo d
+echo "$(echo '!' )"
+
+echo e
+echo '!' "!"
+echo "'!'"
+
+set +o history
+rm -f $HISTFILE
diff --git a/tests/histexp5.sub b/tests/histexp5.sub
new file mode 100644
index 0000000..9e6d01b
--- /dev/null
+++ b/tests/histexp5.sub
@@ -0,0 +1,41 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+set -o history
+set -o histexpand
+
+# command and process substitutions should be tokenized as a single word
+echo /$(echo tmp)/Step1
+echo !:*
+echo /<(echo tmp)/Step1 >/dev/null
+echo !:*
+
+# same tests at the beginning of a word
+echo $(echo /tmp)/Step1
+echo !:*
+echo <(echo /tmp)/Step1 >/dev/null
+echo !:*
+
+# so should shell extended glob patterns
+shopt -s extglob
+
+echo /+(one|two|three)/Step1
+echo !:*
+echo /*(tmp|dev|usr)/Step1
+echo !:*
+
+# same tests at the beginning of a word
+echo +(/one|/two|/three)/Step1
+echo !:*
+echo *(/tmp|/dev|/usr)/Step1
+echo !:*
diff --git a/tests/histexp6.sub b/tests/histexp6.sub
new file mode 100644
index 0000000..d52e5ea
--- /dev/null
+++ b/tests/histexp6.sub
@@ -0,0 +1,37 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+unset HISTIGNORE
+HISTFILE=$TMPDIR/bashhist-$$
+
+set -o history
+set -o histexpand
+
+echo one
+
+for f in a b c; do
+ echo !!
+done
+
+history
+history -c
+
+echo two
+for f in a b c; do
+ echo !-1
+done
+
+history
+
+set +o history
+rm -f $HISTFILE
diff --git a/tests/histexp7.sub b/tests/histexp7.sub
new file mode 100644
index 0000000..8822205
--- /dev/null
+++ b/tests/histexp7.sub
@@ -0,0 +1,18 @@
+# make sure history expansion doesn't take place while parsing command
+# substitutions
+
+set -o history
+set -o histexpand
+echo a
+
+echo $( cat <<EOF
+echo !!
+EOF
+)
+
+echo --between--
+
+cat <( cat <<'EOF'
+echo !!
+EOF
+)
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..5273de6
--- /dev/null
+++ b/tests/history.right
@@ -0,0 +1,299 @@
+./history.tests: line 17: history: -x: invalid option
+history: usage: history [-c] [-d offset] [n] or history -anrw [filename] or history -ps arg [arg...]
+./history.tests: line 19: history: cannot use more than one of -anrw
+./history.tests: line 22: 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=$TMPDIR/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=$TMPDIR/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=$TMPDIR/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=$TMPDIR/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=$TMPDIR/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=$TMPDIR/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=$TMPDIR/newhistory
+7 echo displaying \$HISTFILE after history -a
+8 cat $HISTFILE
+./history.tests: line 90: fc: no command found
+ 15 echo line 2 for history
+ 16 unset HISTSIZE
+ 17 unset HISTFILE
+ 18 # now an out-of-range error because of the one=two not found in history
+aa ab ac
+echo xx xb xc
+xx xb xc
+echo 44 48 4c
+44 48 4c
+./history.tests: line 105: 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
+5.2
+echo ${BASH_VERSION%\.*}
+5.2
+ echo ${BASH_VERSION%\.*}
+a
+b
+c
+d
+e
+ 1 echo a
+ 2 echo b
+ 3 echo c
+ 4 echo d
+ 5 echo e
+
+ 1 echo a
+ 2 echo e
+f
+g
+h
+i
+ 1 echo a
+ 2 echo e
+ 3 echo f
+ 4 echo g
+ 5 echo h
+
+./history3.sub: line 40: history: 16: history position out of range
+./history3.sub: line 41: history: 200: history position out of range
+./history3.sub: line 42: history: -20: history position out of range
+./history3.sub: line 43: history: -50: history position out of range
+./history3.sub: line 44: history: 5-0xaf: history position out of range
+ 1 echo a
+ 2 echo e
+ 3 echo f
+ 4 echo g
+ 5 echo h
+
+
+0
+1
+2
+(left
+mid
+right)
+A
+B
+
+(left
+mid
+right)
+A
+B
+
+(left
+mid
+right)
+A
+B
+
+0
+1
+2
+(left
+mid
+right)
+A
+B
+(left
+mid
+right)
+A
+B
+
+0
+1
+2
+(left
+mid
+right)
+A
+B
+(left
+mid
+right)
+A
+B
+a
+b
+./history5.sub: line 24: fc: history specification out of range
+./history5.sub: line 25: fc: no command found
+1 echo a
+2 echo b
+3 fc -0 # error
+4 fc -s -0 # error
+c
+6 echo c
+8 fc -l -0
+d
+echo d
+d
+a
+b
+c
+d
+e
+f
+4 echo d
+5 echo e
+6 echo f
+out of range 1
+6 echo f
+7 fc -l
+8 echo out of range 1
+out of range 2
+8 echo out of range 1
+9 fc -l 502 498
+10 echo out of range 2
+out of range 3
+10 echo out of range 2
+11 fc -l 498 502
+12 echo out of range 3
+out of range 4
+13 fc -l 1 99
+1
+2
+3
+4
+5
+6
+ 3 echo 3
+ 4 echo 4
+ 5 echo 5
+ 6 echo 6
+ 3 echo 3
+ 4 echo 4
+ 5 echo 5
+6
+7
+ 4 echo 4
+ 5 echo 5
+ 6 echo 6
+ 7 echo 7
+ 4 echo 4
+ 5 echo 5
+ 6 echo 6
+7
+8
+ 5 echo 5
+ 6 echo 6
+9
+10
+ 5 echo 5
+ 6 echo 6
+ 7 echo 9
+ 8 echo 10
+ 5 echo 10
diff --git a/tests/history.tests b/tests/history.tests
new file mode 100644
index 0000000..5826d13
--- /dev/null
+++ b/tests/history.tests
@@ -0,0 +1,133 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+trap 'rm $TMPDIR/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
+export HISTIGNORE
+
+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=$TMPDIR/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
+
+# now an out-of-range error because of the one=two not found in history
+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
+rm -f $TMPDIR/foohist-*
+
+${THIS_SH} ./history2.sub
+${THIS_SH} ./history3.sub
+${THIS_SH} ./history4.sub
+${THIS_SH} ./history5.sub
+${THIS_SH} ./history6.sub
diff --git a/tests/history1.sub b/tests/history1.sub
new file mode 100644
index 0000000..b67a0ef
--- /dev/null
+++ b/tests/history1.sub
@@ -0,0 +1,28 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+trap 'rm -f $HISTFILE' 0 1 2 3 6 15
+
+HISTFILE=$TMPDIR/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/history3.sub b/tests/history3.sub
new file mode 100644
index 0000000..d8a2203
--- /dev/null
+++ b/tests/history3.sub
@@ -0,0 +1,49 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: ${TMPDIR:=/tmp}
+
+set -o history
+HISTFILE=$TMPDIR/history-$$
+
+history -c
+
+echo a
+echo b
+echo c
+echo d
+echo e
+
+history ; echo
+
+history -d 2-4
+
+history
+
+echo f
+echo g
+echo h
+echo i
+history -d 6--1
+history ; echo
+
+history -d 16-40
+history -d 1-200
+history -d -20-50
+history -d 1--50
+history -d 5-0xaf
+
+history ; echo
+
+unset HISTFILE
+exit 0
diff --git a/tests/history4.sub b/tests/history4.sub
new file mode 100644
index 0000000..651374c
--- /dev/null
+++ b/tests/history4.sub
@@ -0,0 +1,47 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+HISTFILE=$TMPDIR/newhistory-$$
+export HISTFILE
+
+trap 'rm -f $HISTFILE' EXIT
+
+HISTSIZE=32
+HISTFILESIZE=32
+echo
+set -o history
+history -c
+echo 0
+echo 1
+echo 2
+echo "(left
+mid
+right)"
+echo A
+echo B
+history -w
+set +o history
+
+echo
+printf $'HISTFILE=\n\cRleft\cO\cO\cO\cO\n' | HISTSIZE= ${THIS_SH} --norc -i 2>/dev/null
+echo
+printf $'HISTFILE=\n\cRleft\cO\cO\cO\cO\n' | HISTSIZE=8 ${THIS_SH} --norc -i 2>/dev/null
+
+input="$(cat $HISTFILE)
+"$'\cP\cP\cP\cO\cO
+'
+
+echo
+printf "$input" | HISTSIZE= HISTFILE= ${THIS_SH} --norc -i 2>/dev/null
+echo
+printf "$input" | HISTSIZE=6 HISTFILE= ${THIS_SH} --norc -i 2>/dev/null
diff --git a/tests/history5.sub b/tests/history5.sub
new file mode 100644
index 0000000..245c28d
--- /dev/null
+++ b/tests/history5.sub
@@ -0,0 +1,57 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+trap 'rm -f "$OUT"' 0 1 2 3 6 15
+
+HISTFILE=$TMPDIR/fchist-$$ ; OUT=$HISTFILE
+unset HISTIGNORE HISTCONTROL
+set -o history
+
+echo a
+echo b
+
+fc -0 # error
+fc -s -0 # error
+
+fc -l
+
+echo c
+fc -l 0
+fc -l -0
+
+echo d
+fc -s 0
+
+HISTSIZE=4
+history -c
+
+echo a
+echo b
+echo c
+echo d
+echo e
+echo f
+fc -l
+
+echo out of range 1
+fc -l 502 498
+echo out of range 2
+fc -l 498 502
+echo out of range 3
+fc -l 1 99
+# other out-of-range behavior for future work
+echo out of range 4
+fc -l -20 -40
+
+unset HISTFILE # suppress writing history file
diff --git a/tests/history6.sub b/tests/history6.sub
new file mode 100644
index 0000000..a21d8d3
--- /dev/null
+++ b/tests/history6.sub
@@ -0,0 +1,55 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: ${TMPDIR:=/tmp}
+
+HISTFILE=${TMPDIR}/history-$$
+HISTSIZE=4
+HISTIGNORE="history*"
+
+set -o history
+
+history -c
+
+echo 1
+echo 2
+echo 3
+echo 4
+echo 5
+echo 6
+
+history
+
+history -d -1
+history
+
+echo 6
+echo 7
+
+history
+history -d -1
+history
+
+echo 7
+echo 8
+history -d -2--1
+history
+
+echo 9
+echo 10
+history
+history -d 5-7
+history
+
+unset HISTFILE
+exit 0
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..21a9063
--- /dev/null
+++ b/tests/ifs-posix.tests
@@ -0,0 +1,270 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# 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..465efcf
--- /dev/null
+++ b/tests/ifs.right
@@ -0,0 +1,12 @@
+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
+argv[1] = <file>
+argv[1] = <*>
diff --git a/tests/ifs.tests b/tests/ifs.tests
new file mode 100644
index 0000000..27f27dd
--- /dev/null
+++ b/tests/ifs.tests
@@ -0,0 +1,76 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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"
+
+${THIS_SH} ./ifs1.sub
diff --git a/tests/ifs1.sub b/tests/ifs1.sub
new file mode 100644
index 0000000..6ea489a
--- /dev/null
+++ b/tests/ifs1.sub
@@ -0,0 +1,14 @@
+: ${TMPDIR:=/tmp}
+dir=bashtest-$$
+
+mkdir $TMPDIR/$dir || exit 1
+touch $TMPDIR/$dir/file || exit 2
+cd $TMPDIR/$dir || exit 3
+
+IFS='?*[]'
+recho *
+
+recho "*"
+
+cd $OLDPWD
+rm -rf $TMPDIR/$dir
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..7da9919
--- /dev/null
+++ b/tests/intl.right
@@ -0,0 +1,57 @@
+é
+1
+AéB
+B
+B
+ok 1
+ok 2
+aéb
+0000000 141 303 251 142
+0000004
+-абвгдежзиклмноп - 16
+-абвгдежзиклмноп- 15
+-абвгд- 5
+1,0000
+1.0000
+1.0000
+1.0000
+1.0000
+1,0000
+1
+bytematch
+0000000 254 012
+0000002
+Passed all 1378 Unicode tests
+0000000 303 277 012
+0000003
+0000000 303 277 012
+0000003
+0000000 303 277 012
+0000003
+0000000 303 277 012
+0000003
+0000000 357 277 277 012
+0000004
+0000000 357 277 277 012
+0000004
+0000000 012
+0000001
+0000000 012
+0000001
+0000000 012
+0000001
+0000000 012
+0000001
+0000000 303 277 012
+0000003
+0000000 303 277 012
+0000003
+0000000 303 277 012
+0000003
+0000000 101 040 302 243 040 305 222 012
+0000010
+./unicode3.sub: line 5: $'5\247@3\231+\306S8\237\242\352\263': command not found
+./unicode3.sub: line 7: cd: $'5\247@3\231+\306S8\237\242\352\263': No such file or directory
+$'5\247@3\231+\306S8\237\242\352\263'
++ : $'5\247@3\231+\306S8\237\242\352\263'
++ set +x
diff --git a/tests/intl.tests b/tests/intl.tests
new file mode 100644
index 0000000..c4ff02c
--- /dev/null
+++ b/tests/intl.tests
@@ -0,0 +1,68 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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' "$*"
+
+. ./test-glue-functions
+
+printf '%s' "$*" | od -b | _intl_normalize_spaces
+
+# display differences make this problematic
+${THIS_SH} ./intl1.sub
+
+# this tests both international handling in printf and temporary environments
+${THIS_SH} ./intl2.sub
+
+# test splitting on characters instead of bytes
+${THIS_SH} ./intl3.sub
+
+${THIS_SH} ./unicode1.sub # 2>/dev/null
+${THIS_SH} ./unicode2.sub
+
+${THIS_SH} ./unicode3.sub 2>&1
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/intl2.sub b/tests/intl2.sub
new file mode 100644
index 0000000..2f3236e
--- /dev/null
+++ b/tests/intl2.sub
@@ -0,0 +1,31 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# this locale causes problems all over the place
+unset LC_ALL LC_NUMERIC
+if locale -a | grep -i '^de_DE\.UTF.*8' >/dev/null ; then
+ export LANG=de_DE.UTF-8
+else
+ echo "intl2.sub: warning: you do not have the de_DE.UTF-8 locale installed;" >&2
+ echo "intl2.sub: that will cause some of these tests to fail." >&2
+fi
+
+printf '%.4f\n' 1
+
+LANG=C printf '%.4f\n' 1
+LANG=C /usr/bin/printf '%.4f\n' 1
+
+env LANG=C printf '%.4f\n' 1
+(LANG=C; printf '%.4f\n' 1)
+
+printf '%.4f\n' 1
diff --git a/tests/intl3.sub b/tests/intl3.sub
new file mode 100644
index 0000000..56c8678
--- /dev/null
+++ b/tests/intl3.sub
@@ -0,0 +1,36 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+. ./test-glue-functions
+
+# more tests to make sure that IFS splits on characters, not bytes
+export LANG=en_US.UTF-8
+
+euro=$'\342\202\254'
+o342=$'\342'
+o202=$'\202'
+o254=$'\254'
+
+IFS=$o254
+t=+$euro+
+set -- $t
+
+echo "$#"
+
+# but matching still occurs on bytes if we don't have a valid multibyte char
+case $euro in
+*$o202*) echo bytematch ;;
+*) echo mbchar match ;;
+esac
+
+echo "${euro##*$o202}" | od -b | _intl_normalize_spaces
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..f339d41
--- /dev/null
+++ b/tests/invert.tests
@@ -0,0 +1,32 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# tests 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..9476128
--- /dev/null
+++ b/tests/iquote.right
@@ -0,0 +1,92 @@
+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>
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <xy>
+argv[1] = <x^?y>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <^?>
+argv[1] = <^? >
+argv[1] = < ^?>
+argv[1] = < ^?>
+argv[1] = < ^?>
+argv[1] = < ^?>
+argv[1] = < ^?>
+argv[1] = < ^?>
+argv[1] = < ^?>
+argv[1] = < ^?>
+argv[1] = < ^?>
+argv[1] = < ^?x>
+argv[1] = < ^?>
+argv[1] = < ^?>
+argv[1] = < ^?>
+argv[1] = < ^?x>
+argv[1] = <^?x>
+argv[1] = <^?>
+argv[1] = < ^? x>
+argv[1] = <^? x>
+argv[1] = <^? >
diff --git a/tests/iquote.tests b/tests/iquote.tests
new file mode 100644
index 0000000..8411c8a
--- /dev/null
+++ b/tests/iquote.tests
@@ -0,0 +1,158 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# 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
+
+${THIS_SH} ./iquote1.sub
diff --git a/tests/iquote1.sub b/tests/iquote1.sub
new file mode 100644
index 0000000..685a80e
--- /dev/null
+++ b/tests/iquote1.sub
@@ -0,0 +1,56 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Problems with variables that expand to 0x7f and quoted nulls in the same
+# expansion -- affects bash versions 4.0-post 4.2
+a=x
+b=
+del=$'\x7f'
+
+set ""
+
+recho ${undef-"x$*y"}
+recho "x$*y"
+recho x"$*"y
+recho x"$del"y
+
+recho ${undef-"$@"}
+recho "$@"
+recho "${@}"
+recho ${undef-"$*"}
+recho "$*"
+recho "${*}"
+
+recho "$del${a#x}"
+recho "$del ${a#x}"
+recho " $del${a#x}"
+
+recho " $del$b"
+recho " $del${b}"
+recho " $del${b#x}"
+recho " $del${a#x}"
+
+recho " $del${a%x}"
+recho " $del${a:0:0}"
+recho " $del"${a:0:0}
+recho " $del""${a:0:0}"
+recho " $del${a}"
+recho " $del"
+recho " ${del}${a:0:0}"
+recho " ${del:0:1}${a:0:0}"
+recho " ${del:0:1}${a}"
+recho "${del:0:1}${a#d}"
+recho "${del:0:1}${a#x}"
+recho " ${del:0:1} ${a}"
+recho "${del:0:1} ${a#d}"
+recho "${del:0:1} ${a#x}"
diff --git a/tests/jobs.right b/tests/jobs.right
new file mode 100644
index 0000000..0510e04
--- /dev/null
+++ b/tests/jobs.right
@@ -0,0 +1,120 @@
+./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 2 &
+[2] Running sleep 2 &
+[3] Running sleep 2 &
+[4]- Running sleep 2 &
+[5]+ Running ( sleep 2; exit 4 ) &
+4
+0
+i killed it
+12
+[1]- Running sleep 20 &
+[3]+ Running sleep 20 &
+5: ok 1
+./jobs5.sub: line 40: wait: %8: no such job
+2: ok 2
+2: ok 3
+127
+./jobs5.sub: line 71: declare: wpid: not found
+child1 exit status 0
+[1]+ Running sleep 20 &
+./jobs7.sub: line 5: fg: no current jobs
+[1]+ Running sleep 20 &
+0
+./jobs.tests: line 40: wait: %1: no such job
+./jobs.tests: line 45: fg: no job control
+wait-for-pid
+wait-errors
+./jobs.tests: line 58: wait: `1-1': not a pid or valid job spec
+./jobs.tests: line 59: 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
+posix jobs output
+[1]+ Done sleep 1
+wait-for-job
+./jobs.tests: line 84: wait: %2: no such job
+127
+async list wait-for-job
+forked
+fg-bg 1
+sleep 2
+fg-bg 2
+sleep 2
+fg-bg 3
+sleep 2
+fg-bg 4
+sleep 2
+fg-bg 5
+./jobs.tests: line 111: fg: %2: no such job
+./jobs.tests: line 112: bg: job 1 already in background
+fg-bg 6
+./jobs.tests: line 119: fg: -s: invalid option
+fg: usage: fg [job_spec]
+./jobs.tests: line 120: bg: -s: invalid option
+bg: usage: bg [job_spec ...]
+./jobs.tests: line 125: disown: -s: invalid option
+disown: usage: disown [-h] [-ar] [jobspec ... | pid ...]
+./jobs.tests: line 129: disown: %1: no such job
+./jobs.tests: line 132: disown: %2: no such job
+wait-for-non-child
+./jobs.tests: line 135: 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 152: kill: %4: no such job
+./jobs.tests: line 154: 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 4
+done
diff --git a/tests/jobs.tests b/tests/jobs.tests
new file mode 100644
index 0000000..dacdc15
--- /dev/null
+++ b/tests/jobs.tests
@@ -0,0 +1,209 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test 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
+
+# test out wait -n framework
+${THIS_SH} ./jobs5.sub
+
+# test out wait -f framework
+${THIS_SH} ./jobs6.sub
+
+${THIS_SH} ./jobs7.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 4 &
+wait $!
+
+echo wait-errors
+wait 1-1
+wait -- -4
+
+echo wait-for-background-pids
+sleep 2 &
+sleep 4 &
+wait
+
+echo async list wait-for-background-pids
+sleep 2 & sleep 4 &
+wait
+
+echo async list wait for child
+sleep 2 & echo forked
+wait
+
+echo wait-when-no-children
+wait
+
+echo posix jobs output
+${THIS_SH} -o posix -c 'sleep 1 & P=$! ; sleep 2; jobs; wait'
+
+set -m
+
+echo wait-for-job
+sleep 3 &
+wait %2 # this should be a no-such-job error
+echo $?
+wait %1
+
+echo async list wait-for-job
+sleep 2 & echo forked
+wait %1
+
+echo fg-bg 1
+sleep 2 &
+%1
+
+echo fg-bg 2
+sleep 2 &
+fg %%
+
+echo fg-bg 3
+sleep 2 &
+fg %s
+
+echo fg-bg 4
+sleep 2 &
+fg %?ee
+
+# these next two are error cases
+echo fg-bg 5
+sleep 2 &
+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 2 &
+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 3 # 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 3 # 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 4 &
+kill -STOP %1
+sleep 2 # 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..84919d9
--- /dev/null
+++ b/tests/jobs1.sub
@@ -0,0 +1,30 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# make sure that jobs -p, %+, and $! all agree
+set -m
+sleep 60 &
+
+FN=$TMPDIR/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..1337fc1
--- /dev/null
+++ b/tests/jobs3.sub
@@ -0,0 +1,39 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+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..9f1cd04
--- /dev/null
+++ b/tests/jobs4.sub
@@ -0,0 +1,39 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test being able to use job control notation in jobs/kill/wait without
+# job control active, as the SUS requires
+
+sleep 2 &
+
+sleep 2 &
+sleep 2 &
+sleep 2 &
+(sleep 2 ; 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 ) &
+# suppress any message about terminated process
+exec 2>/dev/null
+kill -1 %% && echo i killed it || echo could not kill it
diff --git a/tests/jobs5.sub b/tests/jobs5.sub
new file mode 100644
index 0000000..e348f2e
--- /dev/null
+++ b/tests/jobs5.sub
@@ -0,0 +1,71 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# framework to test new `wait -n' option that waits for any job to finish
+
+set -m
+
+sleep 20 &
+{ sleep 2; exit 12; } &
+sleep 20 &
+
+wait -n
+echo $?
+
+jobs
+disown -a
+
+{ sleep 1 ; exit 4; } &
+{ sleep 2 ; exit 5; } & bgpid1=$!
+{ sleep 4 ; exit 6; } &
+
+wait -p wvar -n %2 %3
+case "$wvar" in
+$bgpid1) echo $?: ok 1;;
+*) echo bad 1;;
+esac
+
+{ sleep 1 ; exit 2; } & bgpid2=$!
+wait -p wvar -n %8 $!
+case $wvar in
+$bgpid2) echo $?: ok 2;;
+*) echo bad 2;;
+esac
+
+disown -a
+
+{ sleep 3; exit 1; } & { sleep 1; exit 2; } & bgpid3=$!
+{ sleep 3; exit 3; } & { sleep 3; exit 4; } &
+
+wait -n -p wpid %1 %2 %3 %4
+
+case $wpid in
+$bgpid3) echo $?: ok 3;;
+*) echo bad 3 ;;
+esac
+
+disown -a
+
+unset bgpid1 bgpid2 bgpid3
+unset wpid
+
+# now that we have no jobs, make sure that wait -n -p var leaves var unset
+jobs
+wait -n -p wpid
+echo $wpid $?
+
+# make sure wait -p var does something useful without the -n option
+jobs
+wait -p wpid
+declare -p wpid
diff --git a/tests/jobs6.sub b/tests/jobs6.sub
new file mode 100644
index 0000000..9ed59ee
--- /dev/null
+++ b/tests/jobs6.sub
@@ -0,0 +1,14 @@
+# framework to test `wait -f' which forces wait until a job exits
+set -o monitor
+sleep 5 &
+child1=$!
+
+( sleep 1; kill -STOP $child1 ; sleep 1 ; kill -CONT $child1 )&
+
+child2=$!
+
+wait -f %1
+echo child1 exit status $?
+
+wait $child2
+exit 0
diff --git a/tests/jobs7.sub b/tests/jobs7.sub
new file mode 100644
index 0000000..582365f
--- /dev/null
+++ b/tests/jobs7.sub
@@ -0,0 +1,8 @@
+# make sure fg in a subshell doesn't try to start a parent's job
+set -m
+sleep 20 &
+echo $(jobs)
+echo $(fg %% ; jobs)
+# suppress any message about sleep 20 being terminated
+exec 2>/dev/null
+kill %1
diff --git a/tests/lastpipe.right b/tests/lastpipe.right
new file mode 100644
index 0000000..84e1e2e
--- /dev/null
+++ b/tests/lastpipe.right
@@ -0,0 +1,22 @@
+after 1: foo = a b c
+after 2: tot = 6
+after: 7
+last = c
+1 -- 142 1
+0 -- 0 1 0
+1 -- 0 0 1
+1 -- 0 0 1
+1 -- 0 1 0
+lastpipe1.sub returns 14
+A1
+A2
+B1
+B2
+HI
+A1
+A2
+B1
+B2
+HI -- 42 -- 0 42
+x=x
+x=x
diff --git a/tests/lastpipe.tests b/tests/lastpipe.tests
new file mode 100644
index 0000000..f9d669d
--- /dev/null
+++ b/tests/lastpipe.tests
@@ -0,0 +1,74 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+binfalse()
+{
+ $binfalse || return 1 # normalize return value
+}
+
+if [ -x /usr/bin/true ]; then
+ bintrue=/usr/bin/true
+elif [ -x /bin/true ]; then
+ bintrue=/bin/true
+else
+ bintrue=true
+fi
+if [ -x /usr/bin/false ]; then
+ binfalse=/usr/bin/false
+elif [ -x /bin/false ]; then
+ binfalse=/bin/false
+else
+ binfalse=false
+fi
+
+shopt -s lastpipe
+
+unset foo bar
+echo a b c | read foo
+echo after 1: foo = $foo
+
+unset tot
+declare -i tot
+printf "%d\n" 1 2 3 | while read foo; do tot+=$foo; done
+echo after 2: tot = $tot
+
+unset bar
+echo g h i | bar=7
+echo after: $bar
+
+unset foo last
+printf "%s\n" a b c | while read foo; do last=$foo; done
+echo last = $last
+
+exit 142 | false
+echo $? -- ${PIPESTATUS[@]}
+
+true | false | $bintrue
+echo $? -- ${PIPESTATUS[@]}
+
+true | $bintrue | false
+echo $? -- ${PIPESTATUS[@]}
+
+set -o pipefail
+true | $bintrue | false
+echo $? -- ${PIPESTATUS[@]}
+
+true | binfalse | true
+echo $? -- ${PIPESTATUS[@]}
+set +o pipefail
+
+${THIS_SH} ./lastpipe1.sub
+echo lastpipe1.sub returns $?
+
+${THIS_SH} ./lastpipe2.sub
+${THIS_SH} ./lastpipe3.sub
diff --git a/tests/lastpipe1.sub b/tests/lastpipe1.sub
new file mode 100644
index 0000000..43711e3
--- /dev/null
+++ b/tests/lastpipe1.sub
@@ -0,0 +1,5 @@
+# with lastpipe set, exit at the end of a pipeline exits
+# the calling shell
+shopt -s lastpipe
+exit 142 | exit 14
+echo after: $?
diff --git a/tests/lastpipe2.sub b/tests/lastpipe2.sub
new file mode 100644
index 0000000..a460286
--- /dev/null
+++ b/tests/lastpipe2.sub
@@ -0,0 +1,43 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+shopt -s lastpipe
+echo -e 'A\nB' | while read letter; do
+ echo -e '1\n2' | while read digit; do
+ echo $letter$digit
+ done
+done
+
+myPipefunc()
+{
+ cat | tee $TMPDIR/outfile
+}
+echo HI | myPipefunc
+
+echo -e 'A\nB' | while read letter; do
+ echo -e '1\n2' | while read digit; do
+ echo $letter$digit | myPipefunc
+ done
+done
+
+rm -f $TMPDIR/outfile
+
+unset -f myPipefunc
+myPipefunc()
+{
+ cat | read var
+ return 42
+}
+echo HI | myPipefunc
+
+echo $var -- $? -- ${PIPESTATUS[@]}
diff --git a/tests/lastpipe3.sub b/tests/lastpipe3.sub
new file mode 100644
index 0000000..b9222b8
--- /dev/null
+++ b/tests/lastpipe3.sub
@@ -0,0 +1,11 @@
+# problem in bash-5.1 running lastpipe in subshell if fd 0 is closed
+
+shopt -s lastpipe
+exec 0<&-
+
+echo x | read x
+echo x=$x
+unset x
+
+echo x | cat | read x
+echo x=$x
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..4452232
--- /dev/null
+++ b/tests/mapfile.right
@@ -0,0 +1,170 @@
+[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 [0] Abcdefghijklmnop
+
+1 [1] aBcdefghijklmnop
+
+2 [2] abCdefghijklmnop
+
+3 [3] abcDefghijklmnop
+
+4 [4] abcdEfghijklmnop
+
+5 [5] abcdeFghijklmnop
+
+6 [6] abcdefGhijklmnop
+
+7 [7] abcdefgHijklmnop
+
+8 [8] abcdefghIjklmnop
+
+9 [9] abcdefghiJklmnop
+
+10 [a] abcdefghijKlmnop
+
+11 [b] abcdefghijkLmnop
+
+12 [c] abcdefghijklMnop
+
+13 [d] abcdefghijklmNop
+
+14 [e] abcdefghijklmnOp
+
+15 [f] abcdefghijklmnoP
+
+16 a
+2 [2] abCdefghijklmnop
+
+5 [5] abcdeFghijklmnop
+
+8 [8] abcdefghIjklmnop
+
+11 [b] abcdefghijkLmnop
+
+14 [e] abcdefghijklmnOp
+
+[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
+declare -a array=([0]="a" [1]="b" [2]="c" [3]=$'\n')
+1 2 3 4 5
+foo 0 1
+
+foo 1 2
+
+foo 2 3
+
+foo 3 4
+
+foo 4 5
+
+0 abc
+1 def
+2 ghi
+3 jkl
+abc def ghi jkl
diff --git a/tests/mapfile.tests b/tests/mapfile.tests
new file mode 100644
index 0000000..c2ea7d2
--- /dev/null
+++ b/tests/mapfile.tests
@@ -0,0 +1,62 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+declare -a A
+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
+
+unset -v s array
+s=$'a\xffb\xffc\xff'
+mapfile -t -d $'\xff' array <<<"$s"
+declare -p array
+unset -v s array
+
+${THIS_SH} ./mapfile1.sub
+${THIS_SH} ./mapfile2.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/mapfile2.sub b/tests/mapfile2.sub
new file mode 100644
index 0000000..771a992
--- /dev/null
+++ b/tests/mapfile2.sub
@@ -0,0 +1,6 @@
+# test mapfile -d DELIM functionality added after bash-4.3
+
+printf "abc\0def\0ghi\0jkl\0" | {
+ mapfile -C echo -c 1 -d '' A
+ echo "${A[@]}"
+}
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 100644
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 100644
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 100644
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 100644
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 100644
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..f5f37c9
--- /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 285: 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 436: ${#:}: bad substitution
+./more-exp.tests: line 438: ${#/}: bad substitution
+./more-exp.tests: line 440: ${#%}: bad substitution
+./more-exp.tests: line 442: ${#=}: bad substitution
+./more-exp.tests: line 444: ${#+}: bad substitution
+./more-exp.tests: line 446: ${#1xyz}: bad substitution
+./more-exp.tests: line 449: #: %: 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..df12b99
--- /dev/null
+++ b/tests/more-exp.tests
@@ -0,0 +1,517 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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/nameref.right b/tests/nameref.right
new file mode 100644
index 0000000..83e9ee5
--- /dev/null
+++ b/tests/nameref.right
@@ -0,0 +1,560 @@
+one
+two
+three
+declare -n fee="flip"
+declare -n foo="bar"
+turning off nameref attribute on foo
+bar
+after +n foo bar = other
+one
+two
+one
+expect <one>
+argv[1] = <one>
+expect <two>
+argv[1] = <two>
+expect <one>
+one
+expect <one>
+one
+expect <one>
+argv[1] = <one>
+changevar: expect <two>
+argv[1] = <two>
+expect <two>
+argv[1] = <two>
+changevar: expect <three four five>
+argv[1] = <three four five>
+expect <three four five>
+argv[1] = <three four five>
+./nameref.tests: line 106: foo: readonly variable
+./nameref.tests: line 107: foo: readonly variable
+one
+one
+./nameref.tests: line 119: foo: readonly variable
+./nameref.tests: line 116: foo: readonly variable
+one
+abxde
+abxde
+one
+bar
+
+./nameref2.sub: line 5: foo: readonly variable
+
+expect <unset>
+argv[1] = <unset>
+expect <unset>
+argv[1] = <unset>
+expect <bar>
+argv[1] = <bar>
+expect <unset>
+./nameref3.sub: line 29: foo: invalid indirect expansion
+./nameref3.sub: line 34: unset: bar: cannot unset: readonly variable
+expect <two>
+two
+expect <two>
+two
+three
+unset
+four
+0
+expect <a b>
+a b
+expect <foo>
+foo
+1 3 5 7 9
+9
+1 3 42 7 9
+1 3 42 7 9
+9
+1 3 44 7 9
+unset
+expect <a b c d e>
+argv[1] = <a b c d e>
+expect <zero> <one> <seven> <three> <four>
+argv[1] = <zero>
+argv[2] = <one>
+argv[3] = <seven>
+argv[4] = <three>
+argv[5] = <four>
+16
+expect <4>
+4
+expect <4>
+4
+expect <4>
+4
+expect <one>
+one
+expect <one>
+one
+expect <one>
+one
+expect <four>
+four
+errors = 0
+1
+2
+v1: 1
+v2: 2
+ref -> first, value: I am first
+ref -> second, value: I am in the middle
+ref -> third, value: I am last
+final state: ref -> third, value: I am last
+ref -> one, value: 1
+ref -> two, value: 2
+ref -> three, value: 3
+final state: ref -> three, value: 3
+./nameref5.sub: line 56: unset: three: cannot unset: readonly variable
+ref -> one, value: 1
+ref -> two, value: 2
+ref -> three, value: 3
+final state: ref -> three, value: 3
+./nameref6.sub: line 15: typeset: x: nameref variable self references not allowed
+./nameref6.sub: line 18: typeset: x[3]: reference variable cannot be an array
+./nameref6.sub: line 25: typeset: x: reference variable cannot be an array
+the -- 1
+42 -- 0
+y -- 0
+2 -- 0
+2 -- 0
+y -- 0
+bar
+unset
+./nameref8.sub: line 16: typeset: warning: v: circular name reference
+./nameref8.sub: line 16: warning: v: circular name reference
+./nameref8.sub: line 18: warning: v: circular name reference
+inside
+inside: two
+outside:
+./nameref8.sub: line 42: typeset: warning: x: circular name reference
+./nameref8.sub: line 42: warning: x: circular name reference
+./nameref8.sub: line 44: warning: x: circular name reference
+foo
+./nameref8.sub: line 51: typeset: warning: v: circular name reference
+./nameref8.sub: line 51: warning: v: circular name reference
+./nameref8.sub: line 51: warning: v: circular name reference
+local
+./nameref8.sub: line 60: typeset: v: nameref variable self references not allowed
+./nameref8.sub: line 67: warning: x: circular name reference
+./nameref8.sub: line 68: warning: x: circular name reference
+x =
+idx2
+idX2
+idx2
+idX2
+declare -n foo="x[\$zero]"
+42
+declare -a x=([0]="4")
+declare -n foo="x[\$(echo 0)]"
+4
+comsub
+x[i=0]
+comsub
+4
+comsub
+4
+comsub
+4
+declare -n foo="somevariable"
+./nameref10.sub: line 51: typeset: somevariable: not found
+foo =
+declare -n foo="somevariable"
+declare -A somevariable=([jug]="brown" )
+declare -n foo="somevariable"
+declare -A somevariable=([jug]="brown" )
+declare -n foo="somevariable"
+./nameref10.sub: line 62: typeset: somevariable: not found
+./nameref10.sub: line 64: typeset: foo: not found
+./nameref10.sub: line 64: typeset: somevariable: not found
+declare -n foo="bar"
+./nameref10.sub: line 68: typeset: bar: not found
+declare -n foo="bar"
+./nameref10.sub: line 70: typeset: bar: not found
+declare -n foo="bar"
+declare -i bar="8"
+8
+declare -n foo="bar"
+./nameref10.sub: line 77: typeset: bar: not found
+./nameref11.sub: line 14: declare: `/': invalid variable name for name reference
+./nameref11.sub: line 15: declare: `/': invalid variable name for name reference
+./nameref11.sub: line 16: `/': not a valid identifier
+./nameref11.sub: line 17: declare: `/': not a valid identifier
+./nameref11.sub: line 18: `/': not a valid identifier
+1) /
+#? ./nameref11.sub: line 19: `/': not a valid identifier
+x
+
+./nameref11.sub: line 20: ((: `0': not a valid identifier
+./nameref11.sub: line 21: declare: `0': invalid variable name for name reference
+./nameref11.sub: line 22: declare: `/': invalid variable name for name reference
+./nameref11.sub: line 23: declare: `/': invalid variable name for name reference
+/
+./nameref11.sub: line 25: `/': not a valid identifier
+./nameref11.sub: line 26: exec: `10': not a valid identifier
+./nameref11.sub: line 26: r: cannot assign fd to variable
+./nameref11.sub: line 27: warning: r: removing nameref attribute
+63
+./nameref11.sub: line 28: declare: RO: readonly variable
+./nameref11.sub: line 28: RO: readonly variable
+./nameref11.sub: line 29: declare: `/': invalid variable name for name reference
+/
+./nameref11.sub: line 30: declare: `/': invalid variable name for name reference
+./nameref11.sub: illegal option -- h
+./nameref11.sub: line 31: getopts: `?': not a valid identifier
+./nameref11.sub: line 32: warning: r: removing nameref attribute
+declare -a r=()
+./nameref11.sub: line 33: declare: r: reference variable cannot be an array
+./nameref11.sub: line 34: printf: `/': not a valid identifier
+./nameref11.sub: line 36: `': not a valid identifier
+./nameref11.sub: line 37: declare: `': not a valid identifier
+./nameref11.sub: line 38: `': not a valid identifier
+./nameref11.sub: line 39: printf: `': not a valid identifier
+./nameref11.sub: line 40: declare: `': invalid variable name for name reference
+declare -r ROVAR="42"
+./nameref11.sub: line 45: ROVAR: readonly variable
+./nameref11.sub: line 45: ROVAR: cannot unset: readonly variable
+declare -r ROVAR="42"
+./nameref11.sub
+./nameref11.sub: line 47: `@': not a valid identifier
+./nameref11.sub
+declare -n ref="x"
+./nameref11.sub: line 52: RO: readonly variable
+declare -r RO_PID
+./nameref11.sub: line 52: RO: cannot unset: readonly variable
+declare -r RO="x"
+./nameref11.sub: line 52: declare: RO_PID: not found
+./nameref11.sub: line 54: RO2: readonly variable
+declare -r RO2="a"
+2
+./nameref11.sub: line 65: typeset: `2': invalid variable name for name reference
+2
+./nameref11.sub: line 70: typeset: `2': invalid variable name for name reference
+2
+./nameref11.sub: line 75: foo[2]: invalid indirect expansion
+./nameref11.sub: line 76: bar: invalid indirect expansion
+./nameref12.sub: line 19: declare: `/': invalid variable name for name reference
+./nameref12.sub: line 22: declare: `%': invalid variable name for name reference
+./nameref12.sub: line 26: `^': not a valid identifier
+declare -n r
+declare -a foo
+declare -a foo=([0]="7")
+./nameref12.sub: line 39: declare: `42': not a valid identifier
+./nameref12.sub: line 40: declare: x: not found
+declare -nr RO="foo"
+/
+./nameref12.sub: line 58: declare: `7*6': not a valid identifier
+./nameref12.sub: line 58: declare: foo: not found
+./nameref12.sub: line 60: `7*6': not a valid identifier
+declare -n ref="var"
+declare -n ref="var"
+./nameref12.sub: line 87: readonly: `var[0]': not a valid identifier
+declare -- var="foo"
+declare -r var2="foo"
+declare -n ref="var"
+declare -a var=([0]="foo")
+./nameref12.sub: line 104: `': not a valid identifier
+declare -n ref
+declare -- ref="global"
+declare -a var=([0]="foo2")
+./nameref12.sub: line 113: declare: global: not found
+declare -- a
+declare -n r="a"
+declare -- a
+declare -n r="a"
+0
+declare -n r="P"
+declare -n ref="var"
+declare -- a
+declare -n r="a"
+0
+declare -n r
+declare -n r
+./nameref13.sub: line 101: typeset: `12345': invalid variable name for name reference
+declare -n foo
+./nameref13.sub: line 110: typeset: `12345': invalid variable name for name reference
+declare -n foo
+declare -nx ref="var"
+var
+var
+var
+var
+foo
+foo
+foo
+foo
+before
+declare -n ref="var"
+./nameref14.sub: line 36: typeset: var: not found
+first
+declare -n ref="var"
+declare -x var="xxx"
+invalid
+declare -n ref="var"
+declare -x var="5"
+after
+declare -n ref="var"
+./nameref14.sub: line 45: typeset: var: not found
+declare -n ref="var"
+./nameref15.sub: line 14: local: warning: a: circular name reference
+./nameref15.sub: line 14: warning: a: circular name reference
+./nameref15.sub: line 14: `a[0]': not a valid identifier
+declare -a a=([0]="0")
+./nameref15.sub: line 14: local: warning: a: circular name reference
+./nameref15.sub: line 14: warning: a: circular name reference
+./nameref15.sub: line 14: warning: a: circular name reference
+declare -a a=([0]="X")
+declare -a b=([0]="X")
+./nameref15.sub: line 14: local: warning: a: circular name reference
+./nameref15.sub: line 14: warning: a: circular name reference
+./nameref15.sub: line 14: `a[0]': not a valid identifier
+declare -a b=([0]="0")
+./nameref15.sub: line 32: typeset: warning: ref: circular name reference
+./nameref15.sub: line 32: warning: ref: circular name reference
+./nameref15.sub: line 33: warning: ref: circular name reference
+./nameref15.sub: line 34: warning: ref: circular name reference
+inside X
+outside X
+before: 7
+./nameref15.sub: line 45: typeset: warning: xxx: circular name reference
+./nameref15.sub: line 45: warning: xxx: circular name reference
+./nameref15.sub: line 46: warning: xxx: circular name reference
+declare -n xxx="xxx"
+./nameref15.sub: line 48: warning: xxx: circular name reference
+xxx_func: inside: xxx = foo
+after: foo
+./nameref15.sub: line 59: typeset: ref: nameref variable self references not allowed
+./nameref15.sub: line 61: ref: nameref variable self references not allowed
+declare -n ref="re"
+declare -n ref="re"
+declare -- re="4"
+4
+declare -n foo="var[@]"
+declare -n ref="var[@]"
+./nameref15.sub: line 78: var[@]: bad array subscript
+declare -n bar="var[@]"
+./nameref15.sub: line 83: var[@]: bad array subscript
+declare -n a="b"
+declare -n b="a[1]"
+./nameref15.sub: line 91: warning: a: removing nameref attribute
+declare -a a=([1]="foo")
+declare -n b="a[1]"
+./nameref15.sub: line 96: warning: a: removing nameref attribute
+declare -a a=([1]="foo")
+declare -n b="a[1]"
+declare -n n="v"
+declare -a v=([1]="1")
+./nameref15.sub: line 112: typeset: n: not found
+declare -a v=([0]="0" [1]="1")
+declare -n n="v[1]"
+declare -a v=([0]="0")
+./nameref15.sub: line 120: warning: xref: removing nameref attribute
+declare -a xref=([1]="one")
+./nameref15.sub: line 126: warning: xref: removing nameref attribute
+declare -a xref=([1]="one")
+declare -n r1="y"
+declare -n r2="x"
+./nameref16.sub: line 25: typeset: x: not found
+./nameref16.sub: line 25: typeset: y: not found
+declare -n r1="y"
+declare -n r2="x"
+./nameref16.sub: line 34: typeset: x: not found
+./nameref16.sub: line 34: typeset: y: not found
+declare -n r1="y"
+declare -n r2="x"
+./nameref16.sub: line 46: typeset: x: not found
+./nameref16.sub: line 46: typeset: y: not found
+declare -n r1="y"
+declare -n r2="x"
+declare -- x="one"
+declare -- y="two"
+./nameref17.sub: line 21: declare: bar: not found
+./nameref17.sub: line 22: unset: foo0: cannot unset: readonly variable
+declare -nr foo0="bar"
+declare -nr foo0="bar"
+declare -- bar
+./nameref17.sub: line 27: declare: foo0: readonly variable
+./nameref17.sub: line 28: declare: foo0: readonly variable
+declare -nr foo1
+./nameref17.sub: line 37: typeset: foo1: readonly variable
+declare -nr foo1
+declare -n foo2="bar"
+declare -r bar
+./nameref17.sub: line 48: bar: readonly variable
+./nameref17.sub: line 49: typeset: bar: readonly variable
+declare -n foo2="bar"
+declare -r bar
+declare -- bar3="three"
+./nameref17.sub: line 59: unset: foo3: cannot unset: readonly variable
+./nameref17.sub: line 62: declare: bar3: readonly variable
+declare -nr foo3="bar3"
+declare -r bar3="three"
+./nameref17.sub: line 64: declare: foo3: readonly variable
+declare -nr foo4="bar4"
+declare -- bar4="four"
+./nameref17.sub: line 76: typeset: foo4: readonly variable
+declare -nr foo4="bar4"
+declare -nr foo4="bar4"
+declare -- bar4="four"
+./nameref17.sub: line 92: typeset: foo4: readonly variable
+declare -nr foo4="bar4"
+declare -nr foo4="bar4"
+declare -- bar4="four"
+declare -nr foo5
+declare -r foo5
+declare -nr foo5
+declare -r foo5
+./nameref18.sub: line 15: mapfile: `XXX[0]': not a valid identifier
+./nameref18.sub: line 16: declare: XXX[0]: not found
+./nameref18.sub: line 22: `XXX[0]': not a valid identifier
+./nameref18.sub: line 23: declare: XXX[0]: not found
+declare -n ref="XXX[0]"
+declare -a XXX=([0]="4")
+./nameref18.sub: line 37: `XXX[0]': not a valid identifier
+declare -n ref="XXX[0]"
+./nameref18.sub: line 38: declare: XXX[0]: not found
+./nameref18.sub: line 42: read: `XXX[0]': not a valid identifier
+./nameref18.sub: line 43: declare: XXX[0]: not found
+./nameref18.sub: line 48: `XXX[0]': not a valid identifier
+declare -n ref="XXX[0]"
+./nameref18.sub: line 51: `XXX[0]': not a valid identifier
+./nameref18.sub: line 51: declare: XXX[0]: not found
+declare -n ref="var[123]"
+./nameref18.sub: line 59: declare: var[123]: not found
+declare -a var=([123]="")
+declare -n ref="var[123]"
+./nameref18.sub: line 63: declare: var[123]: not found
+declare -a var=([123]="")
+declare -n ref="var[123]"
+./nameref18.sub: line 67: declare: var[123]: not found
+declare -a var=([123]="X")
+argv[1] = <1>
+argv[2] = <2>
+argv[3] = <3>
+argv[1] = <1>
+argv[2] = <2>
+argv[3] = <3>
+argv[1] = <1>
+argv[2] = <2>
+argv[3] = <3>
+argv[1] = <1>
+argv[2] = <2>
+argv[3] = <3>
+argv[1] = <1>
+argv[2] = <2>
+argv[3] = <31>
+argv[4] = <2>
+argv[5] = <3>
+declare -n foo="bar"
+declare -- foo="bar"
+./nameref19.sub: line 22: declare: bar: not found
+declare -n foo="bar"
+declare -- foo="bar"
+declare -i bar="11"
+declare -inx foo6
+declare -ix foo6
+declare -n foo="bar"
+declare -- bar="Hello World!"
+declare -- foo="bar"
+declare -- bar="Hello World!"
+declare -n foo="bar"
+declare -- bar
+declare -- foo="bar"
+declare -- bar
+8
+declare -n ivar="foo"
+declare -a v=([0]="Y")
+r: <Y>
+v: <Y>
+declare -n ref="var"
+declare -a var=([0]="X")
+declare -n ref="var"
+declare -a var=([0]="X")
+declare -n ref="var"
+./nameref20.sub: line 36: declare: var: not found
+outside:
+declare -a foo=([0]="X")
+declare -n ref="var"
+declare -a var=([0]="X")
+outside:
+./nameref20.sub: line 51: declare: ref: not found
+./nameref20.sub: line 51: declare: var: not found
+declare -n ref="var"
+declare -- var="X"
+outside:
+./nameref20.sub: line 58: declare: ref: not found
+./nameref20.sub: line 58: declare: var: not found
+declare -n ref="var"
+declare -a var=([0]="Y")
+declare -- ref="Y"
+declare -- var="X"
+declare -- ref="Y"
+declare -- ref="Y"
+./nameref20.sub: line 74: declare: var: not found
+declare -- ref="Y"
+declare -n ref="var"
+declare -A var=([2]="" )
+declare -n ref="var"
+declare -A var=([2]="" )
+declare -n ref="var"
+declare -a var=([2]="")
+declare -n ref="var"
+declare -a var=([2]="")
+declare -n ref="var"
+declare -ai var=([1]="0")
+declare -n ref="var"
+declare -ai var=([1]="0")
+declare -n ref="var"
+declare -- var="1"
+a string with spaces
+many spaces
+declare -n foo="bar[0]"
+declare -a bar=([0]=" still more spaces")
+declare -n foo="bar[0]"
+declare -a bar=([0]="spaces still more spaces")
+./nameref22.sub: line 50: declare: array: reference variable cannot be an array
+./nameref22.sub: line 53: declare: array[128]: reference variable cannot be an array
+declare -a array=([0]="one" [1]="two" [2]="three")
+declare -- array="(one two three)"
+declare -a array=([0]="one" [1]="two" [2]="three")
+./nameref22.sub: line 69: declare: `(one two three)': invalid variable name for name reference
+./nameref22.sub: line 70: declare: array: reference variable cannot be an array
+declare -a array=([0]="zero")
+./nameref22.sub: line 74: declare: array: reference variable cannot be an array
+declare -a array=([0]="one" [1]="two" [2]="three")
+./nameref22.sub: line 79: declare: array: reference variable cannot be an array
+declare -a array
+declare -ai array=([0]="one")
+declare -a array=([0]="zero")
+declare -a array=([0]="one" [1]="two" [2]="three")
+declare -ai a=([0]="5")
+declare -ai a=([0]="6")
+declare -ai a=([0]="1")
+./nameref23.sub: line 15: declare: b: not found
+declare -ai a=([0]="1")
+declare -- b="1"
+declare -ai a=([0]="1")
+declare -- b="11"
+declare -ai a=([0]="1")
+declare -- b="110"
+./nameref23.sub: line 25: declare: `1': invalid variable name for name reference
+declare -ai a=([0]="1")
+./nameref23.sub: line 27: declare: b: not found
+declare -ai a=([0]="4")
+declare -in b="a[0]"
+declare -ai a=([0]="6")
+declare -in b="a[0]"
+foo
+foo bar
+declare -a a=([0]="" [1]="foo bar")
+declare -n b="a[1]"
+foo
+foo bar
+declare -a a=([0]="" [1]="foo bar")
+declare -n b="a[1]"
+12
+16
+declare -ai a=([0]="0" [1]="16")
+12
+16
+declare -ai a=([0]="0" [1]="16")
diff --git a/tests/nameref.tests b/tests/nameref.tests
new file mode 100644
index 0000000..3a6c5d9
--- /dev/null
+++ b/tests/nameref.tests
@@ -0,0 +1,133 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# basic nameref tests
+bar=one
+flow=two
+flip=three
+
+foo=bar
+typeset -n foo
+
+typeset -n fee=flow
+
+echo ${foo}
+echo ${fee}
+
+typeset -n fee=flip
+echo ${fee}
+
+typeset -n
+
+echo turning off nameref attribute on foo
+typeset +n foo=other
+echo ${foo}
+echo after +n foo bar = $bar
+
+unset foo bar fee
+
+bar=one
+
+foo=bar
+typeset -n foo
+
+foo=two printf "%s\n" $foo
+foo=two eval 'printf "%s\n" $foo'
+
+foo=two echo $foo
+
+unset foo bar
+# other basic assignment tests
+bar=one
+
+echo "expect <one>"
+recho ${bar}
+typeset -n foo=bar
+foo=two
+
+echo "expect <two>"
+recho ${bar}
+
+# this appears to be a ksh93 bug; it doesn't unset foo here and messes up
+# later
+unset foo bar
+
+# initial tests of working inside shell functions
+echoval()
+{
+ typeset -n ref=$1
+ printf "%s\n" $ref
+}
+
+foo=bar
+bar=one
+echo "expect <$foo>"
+echoval foo
+echo "expect <$bar>"
+echoval bar
+
+unset foo bar
+changevar()
+{
+ typeset -n v=$1
+
+ shift
+ v="$@"
+ echo "changevar: expect <$@>"
+ recho "$v"
+}
+
+bar=one
+
+echo "expect <one>"
+recho ${bar}
+changevar bar two
+echo "expect <two>"
+recho $bar
+
+changevar bar three four five
+echo "expect <three four five>"
+recho "$bar"
+
+unset foo bar
+unset -n foo bar
+readonly foo=one
+typeset -n bar=foo
+bar=4
+foo=4
+
+echo $foo
+echo $bar
+
+assignvar()
+{
+ typeset -n ref=$1
+ shift
+ ref="$@"
+}
+
+readonly foo=one
+
+assignvar foo two three four
+echo $foo
+
+var=abcde
+x=var
+declare -n v=var
+# these two should display the same
+echo ${!x//c/x}
+echo ${v//c/x}
+
+for testfile in ./nameref[0-9].sub ./nameref[1-9][0-9].sub ; do
+ ${THIS_SH} "$testfile"
+done
diff --git a/tests/nameref1.sub b/tests/nameref1.sub
new file mode 100644
index 0000000..50bb25d
--- /dev/null
+++ b/tests/nameref1.sub
@@ -0,0 +1,13 @@
+# indirect referencing of a nameref returns the variable name it references
+unset foo bar
+
+bar=one
+foo=bar
+
+typeset -n foo
+
+echo ${foo}
+echo ${!foo}
+
+# this is a current incompatibility
+echo ${!foo[0]}
diff --git a/tests/nameref10.sub b/tests/nameref10.sub
new file mode 100644
index 0000000..742755b
--- /dev/null
+++ b/tests/nameref10.sub
@@ -0,0 +1,77 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# testing behavior of command substitution as one of expansions performed by
+# array subscripting; should behave the same directly as when done through
+# a nameref
+
+x[0]=42
+zero=0
+f() { typeset -n foo="$1"; declare -p foo; echo "$foo"; }
+
+f 'x[$zero]'
+
+x[$(echo 0)]=4
+declare -p x
+
+f 'x[$(echo 0)]'
+
+unset -f f
+f()
+{
+ typeset -n foo="$1";
+
+ echo "x[i=0$(echo comsub >&2)]"
+ echo "${x[i=0$(echo comsub >&2)]}"
+ echo "${!1}"
+ echo "$foo"
+}
+
+f 'x[i=0$(echo comsub >&2)]'
+
+unset -f f
+unset x
+
+# problems with unset and namerefs pointing to non-existent variables pointed
+# out after bash-4.3 released
+
+typeset -n foo=somevariable
+foo=bar
+unset foo # unsets somevariable
+typeset -p foo somevariable
+echo foo = $foo
+
+typeset -A foo # should create array variable named somevariable
+foo["jug"]="brown"
+
+typeset -p foo somevariable
+typeset -A foo='([jug]="brown" )'
+typeset -p foo somevariable
+
+unset foo
+typeset -p foo somevariable
+unset -n foo
+typeset -p foo somevariable
+
+unset bar
+typeset -n foo=bar
+typeset -p foo bar
+unset foo
+typeset -p foo bar
+typeset -i foo
+foo=4+4
+typeset -p foo bar
+echo "$foo"
+
+unset foo
+typeset -p foo bar
diff --git a/tests/nameref11.sub b/tests/nameref11.sub
new file mode 100644
index 0000000..ea14c0d
--- /dev/null
+++ b/tests/nameref11.sub
@@ -0,0 +1,76 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+r=/; declare -n r ; unset r
+declare -n r=/ ; unset -n r
+declare -n r; r=/ ; unset -n r
+declare -n r; declare r=/ ; unset -n r
+declare -n r; for r in /; do :; done ; unset -n r
+declare -n r; select r in /; do :; done <<< 1; echo x; echo $r ; unset -n r
+declare -n r; ((r=0)) ; unset -n r
+((r=0)); declare -n r ; unset -n r
+r=/ declare -n r ; unset -n r
+f() { declare -n r; }; r=/ f ; unset r
+f() { echo $r; }; declare -n r; r=/ f ; unset -n r
+declare -n r; : ${r:=/} ; unset -n r
+declare -n r; exec {r}>/dev/null ; unset -n r
+declare -n r; coproc r { :; }; echo $r ; unset r ; wait
+declare -r RO=x; r=$RO; declare -n r; x=y; declare -n RO; RO=z; declare -p RO; echo "$RO"
+s=/; declare -n r=s; declare -n s; echo $r ; unset -n r ; unset -n s
+declare -n r=s; declare -n s; s=/ ; unset -n r; unset -n s
+declare -n r; getopts x r -h ; unset r; unset -n r
+declare -n r; mapfile r < /dev/null ; declare -p r; unset r ; unset -n r
+mapfile r < /dev/null; declare -n r ; unset r ; unset -n r
+declare -n r; printf -v r / ; unset -n r
+
+declare -n r; r="" ; unset -n r
+declare -n r="" ; unset -n r
+declare -n r; : ${r=} ; unset -n r
+declare -n r; printf -v r '' ; unset -n r
+r=""; declare -n r ; unset -n r
+export r
+
+# coproc tests, since coproc sets and unsets variables
+declare -r ROVAR=42
+declare -p ROVAR; coproc ROVAR { :; }; wait; declare -p ROVAR
+
+echo ${@:0}; coproc @ { :; }; wait ; echo ${@:0}
+
+declare -n ref=x; coproc ref { :; }; wait ; declare -p ref
+unset -n ref ; unset ref
+
+declare -r RO RO_PID; coproc RO { :; }; declare -p RO_PID; wait; declare -p RO RO_PID
+
+declare -r RO2=a; declare -n ref_PID=RO2; coproc ref { :; }; wait; declare -p RO2
+
+unset x y
+set -- one two three
+
+y=2
+typeset -n x=y
+echo ${x}
+
+unset -n x
+
+typeset -n y
+echo $y
+
+unset -n y
+
+typeset -n y
+y=2
+echo ${y}
+
+declare -n foo=bar
+echo ${!foo[2]}
+echo ${!bar}
diff --git a/tests/nameref12.sub b/tests/nameref12.sub
new file mode 100644
index 0000000..199b51c
--- /dev/null
+++ b/tests/nameref12.sub
@@ -0,0 +1,113 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+declare -n r
+declare -n r
+unset -n r
+
+r=foo
+declare -n r=/
+
+r=%
+declare -n r
+unset r
+
+declare -n r
+r=^
+declare -p r
+
+unset -n r
+
+declare -n foo
+declare -a foo
+declare -p foo
+foo[0]=7
+declare -p foo
+unset foo
+
+declare -n x
+declare x=42
+declare -p x
+
+declare -n -r RO=foo
+declare -p RO
+
+unset -n r; unset r
+
+# the details of this may change; currently we put namerefs and values into
+# the tempenv if the nameref value is an invalid variable name
+f() { echo $r; }
+
+declare -n r
+r=/ ${THIS_SH} < /dev/null
+r=/ f
+
+unset -f f
+
+# the details of this may change; this will tell me when they do
+declare -n foo ; declare -i foo=7*6 ; declare -p foo
+unset -n foo
+declare -n foo ; declare -i foo ; foo=7*6 ; declare -p foo
+
+# used to be buggy
+f()
+{
+ unset var
+ declare -n ref=var
+ declare -n ref
+ declare -p ref
+}
+f
+
+unset -f f
+f()
+{
+ local var
+ declare -n ref=var
+ declare -n ref
+ declare -p ref
+}
+f
+
+unset ref; unset -n ref
+unset var
+
+var=foo
+typeset -n ref=var[0]
+readonly ref
+typeset -p var
+
+var2=foo
+typeset -n ref2=var2
+readonly ref2
+typeset -p var2
+
+unset var
+unset -n ref ref2
+
+unset var; typeset -n ref=var
+ref[0]=foo
+typeset -p ref var
+unset -n ref
+
+unset var; typeset -n ref
+ref[0]=foo
+typeset -p ref
+unset -n ref
+
+ref=global
+f() { declare -n ref=var; ref[0]=foo1; }; f
+f() { declare -n ref=var; ref[0]=foo2; }; f
+declare -p ref var
+
+declare -p global
diff --git a/tests/nameref13.sub b/tests/nameref13.sub
new file mode 100644
index 0000000..5c56428
--- /dev/null
+++ b/tests/nameref13.sub
@@ -0,0 +1,115 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+declare -nt r=a
+
+f()
+{
+ declare a
+ declare -n r=a
+ declare -p a r
+}
+
+f
+unset -f f
+
+f()
+{
+ declare a
+ declare -n r
+ r=a
+ declare -p a r
+}
+f
+echo $?
+
+unset -f f
+
+P=12345
+function foo
+{
+ typeset -n r
+ typeset -n r=P
+ typeset -p r
+}
+
+foo
+unset P foo
+
+ref=outside
+
+f()
+{
+ unset var
+ declare -n ref=var
+ declare -n ref;
+ declare -p ref;
+}
+f
+
+unset ref foo
+
+typeset -n r=a
+
+f()
+{
+ typeset a
+ typeset -n r
+ typeset -n r
+ r=a
+
+ typeset -p a r
+}
+f
+echo $?
+unset -n r
+unset -f f
+
+function foo
+{
+ typeset -n r
+ typeset -n r
+ typeset -p r
+}
+
+foo
+unset -f foo
+
+
+function foo
+{
+ typeset r
+ typeset -n r
+ typeset -p r
+}
+foo
+unset -f foo
+
+foo()
+{
+ typeset -n foo
+ typeset foo=12345
+ typeset -p foo
+}
+foo
+unset -f foo
+
+foo()
+{
+ typeset -n foo
+ typeset -n foo=12345
+ typeset -p foo
+}
+foo
+unset -f foo
+
diff --git a/tests/nameref14.sub b/tests/nameref14.sub
new file mode 100644
index 0000000..a14c440
--- /dev/null
+++ b/tests/nameref14.sub
@@ -0,0 +1,56 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# exporting namerefs and putting namerefs in temp env post bash-4.3
+
+typeset -nx ref=var;
+typeset -p ref
+
+var=foo; str=''
+printenv ref # var
+ref+=$str printenv ref # var
+ref+="$str" printenv ref # var
+ref=$ref$str printenv ref # var
+
+export ref # follows nameref and exports var
+
+printenv var # foo
+ref+=$str printenv var # foo
+ref+="$str" printenv var # foo
+ref=$ref$str printenv var # foo
+
+# none of these should change ref; should follow the nameref and export var
+unset var; unset -n ref; typeset -n ref=var
+
+echo before
+typeset -p ref var
+
+echo first
+ref=xxx typeset -p ref var
+
+echo invalid
+var= ref=5 typeset -p ref var
+
+echo after
+typeset -p ref var
+
+# ref isn't exported, so none of the printenvs should print anything
+unset var ; unset -n ref
+typeset -n ref=var;
+typeset -p ref
+
+var=foo; str=''
+printenv ref
+ref+=$str printenv ref
+ref+="$str" printenv ref
+ref=$ref$str printenv ref
diff --git a/tests/nameref15.sub b/tests/nameref15.sub
new file mode 100644
index 0000000..e9a09ee
--- /dev/null
+++ b/tests/nameref15.sub
@@ -0,0 +1,127 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+f() { local -n a=$1; a=X; }
+
+a=(0); f 'a[0]'
+while [[ -v a ]]; do declare -p a; unset a; done
+
+a=(0); f 'a'
+while [[ -v a ]]; do declare -p a; unset a; done
+
+b=(0); f 'b[0]'
+while [[ -v a ]]; do typeset -p a; unset a; done
+typeset -p b
+
+b=(0); f 'a[0]'
+while [[ -v a ]]; do typeset -p a; unset a; done
+typeset -p b
+
+add_X_echo()
+{
+ typeset -n ref=$1
+ ref+=X
+ echo inside $ref
+}
+
+ref=
+add_X_echo ref
+echo outside "$ref"
+unset ref
+
+# same test, but assigning nameref variable circular reference directly
+xxx_func()
+{
+ typeset -n xxx=xxx
+ xxx=foo
+ declare -p xxx
+ echo $FUNCNAME: inside: xxx = $xxx
+}
+
+xxx=7
+echo before: $xxx
+xxx_func
+echo after: $xxx
+
+unset xxx
+unset -f xxx_func
+
+typeset -n ref=ref
+
+typeset -n ref=re ref+=f
+typeset -p ref
+ref=4
+typeset -p ref re
+
+export ref
+printenv ref
+printenv re
+
+unset ref ; unset -n ref
+unset foo; unset -n foo
+
+typeset -n foo=var[@]
+typeset -p foo
+typeset -n ref=var ref+=[@]
+typeset -p ref
+
+ref=42
+
+typeset -n bar
+bar=var[@]
+typeset -p bar
+bar=7
+
+unset a b
+unset -n a b
+
+typeset -n a=b b
+b=a[1]
+typeset -p a b
+a=foo
+typeset -p a b
+
+unset a
+typeset -n a=b
+declare a=foo
+typeset -p a b
+
+unset n v
+unset -n n v
+
+v=(0 1)
+typeset -n n=v
+unset n[0]
+typeset -p n v
+
+unset -n n
+
+v=(0 1)
+typeset -n n=v
+unset -n n
+typeset -p n v
+
+v=(0 1)
+declare -n n=v[1]
+unset n
+declare -p n v
+
+declare -n xref
+declare -a xref[1]=one
+declare -p xref
+
+unset xref
+declare -n xref
+xref=array
+declare -a xref[1]=one
+declare -p xref
diff --git a/tests/nameref16.sub b/tests/nameref16.sub
new file mode 100644
index 0000000..d07a3a0
--- /dev/null
+++ b/tests/nameref16.sub
@@ -0,0 +1,57 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# post-bash-4.3 changes for more ksh93 compatibility when following nameref
+# chains and using typeset/declare -n to operate on nameref variables rather
+# than the variables they reference
+
+# don't follow nameref chain when using declare -n and at the global scope
+unset -n r1 r2
+
+typeset -n r1=r2
+typeset -n r2=x
+typeset -n r1=y
+
+typeset -p r1 r2 x y
+
+# same behavior when in a shell function
+foo()
+{
+ typeset -n r1=r2
+ typeset -n r2=x
+ typeset -n r1=y
+
+ typeset -p r1 r2 x y
+}
+unset -n r1 r2
+foo
+unset -f foo
+
+# same behavior when namerefs aren't chained
+unset -n r1 r2
+
+typeset -n r1=z
+typeset -n r2=x
+typeset -n r1=y
+typeset -p r1 r2 x y
+
+# same behavior when referenced variables have values
+unset -n r1 r2
+
+x=one
+y=two
+typeset -n r1=r2
+typeset -n r2=x
+typeset -n r1=y
+
+typeset -p r1 r2 x y
diff --git a/tests/nameref17.sub b/tests/nameref17.sub
new file mode 100644
index 0000000..b8c3cc7
--- /dev/null
+++ b/tests/nameref17.sub
@@ -0,0 +1,116 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test behavior of readonly namerefs and namerefs referencing readonly variables
+
+# readonly nameref variable referencing read-write global variable
+
+bar=one
+declare -rn foo0=bar
+unset foo0 # unsets bar
+declare -p bar
+unset -n foo0 # cannot unset
+declare -p foo0
+
+declare +r foo0 # modifies bar
+declare -p foo0 bar
+declare +r -n foo0 # error
+declare +n foo0 # error
+unset bar
+
+# readonly nameref variable without a value
+typeset -n foo1
+typeset -r foo1
+
+typeset -p foo1
+
+typeset foo1=bar # error
+typeset +r foo1 # no-op, follows nameref chain to nothing
+typeset -p foo1
+
+# nameref pointing to read-only global variable
+foo2=bar
+typeset -n foo2
+typeset -r foo2 # changes bar
+
+typeset -p foo2 bar
+
+foo2=bar # error?
+typeset +r foo2 # attempts to change bar, error
+typeset -p foo2 bar # nameref unchanged
+
+# read-only nameref pointing to read-only global variable
+bar3=three
+declare -rn foo3=bar3
+unset foo3 # unsets bar3
+
+bar3=three
+declare -p bar3
+unset -n foo3 # cannot unset
+
+readonly bar3
+declare +r foo3 # error attempting to reference bar3
+declare -p foo3 bar3
+declare +r -n foo3 # error
+
+# readonly nameref pointing to read-write local -- can we remove nameref attr?
+func()
+{
+ typeset bar4=four
+
+ # readonly nameref
+ typeset -n -r foo4=bar4
+
+ typeset -p foo4 bar4
+
+ typeset +n foo4
+
+ typeset -p foo4
+}
+func
+unset -f func
+
+# readonly nameref pointing to read-write global -- can we remove nameref attr?
+bar4=four
+foo4=bar4
+# readonly nameref
+typeset -n foo4
+typeset -r -n foo4
+
+typeset -p foo4 bar4
+
+typeset +n foo4
+typeset -p foo4
+
+bar4=four
+: ${foo4=bar4}
+
+typeset -p foo4 bar4
+
+# readonly local nameref without a value -- can we remove nameref attribute?
+func()
+{
+ declare -r -n foo5
+ declare -p foo5
+ declare +n foo5
+ declare -p foo5
+}
+func
+unset -f func
+
+# readonly global nameref without a value -- can we remove nameref attribute?
+declare -n foo5
+declare -r -n foo5
+declare -p foo5
+declare +n foo5
+declare -p foo5
diff --git a/tests/nameref18.sub b/tests/nameref18.sub
new file mode 100644
index 0000000..7a32877
--- /dev/null
+++ b/tests/nameref18.sub
@@ -0,0 +1,83 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+declare -n ref=XXX[0]
+mapfile ref <<< $'1\n2'
+declare -p XXX[0]
+
+unset -n ref
+
+declare -n ref=XXX[0]
+declare -A ref
+ref[foo]=bar
+declare -p XXX[0]
+
+unset -n ref
+unset XXX
+
+typeset -n ref=XXX[0]
+typeset ref=4
+
+typeset -p ref XXX
+
+unset -n ref
+unset XXX
+
+declare -n ref=XXX[0]
+ref+=([2]=x)
+declare -p ref XXX[0]
+unset -n ref
+
+declare -n ref=XXX[0]
+read -a ref <<< "A B C"
+declare -p XXX[0]
+unset -n ref
+
+declare -n ref=XXX[0]
+unset ref
+ref=()
+declare -p ref
+
+coproc ref { :; }; declare -p ${!ref}
+wait
+
+unset -n ref
+
+declare -n ref=var[123]
+unset ref
+declare ref=
+declare -p ref ${!ref} var
+
+unset ref
+declare ref+=
+declare -p ref ${!ref} var
+
+declare +t ref
+ref=X
+declare -p ref ${!ref} var
+
+unset -n ref
+unset var
+
+arr=(1 2 3)
+
+indir='arr[@]'
+declare -n ref='arr[@]'
+
+recho "${!indir}"
+recho ${!indir}
+
+recho "$ref"
+recho $ref
+
+recho "${!indir}$ref"
diff --git a/tests/nameref19.sub b/tests/nameref19.sub
new file mode 100644
index 0000000..d4b900e
--- /dev/null
+++ b/tests/nameref19.sub
@@ -0,0 +1,73 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# can we unset the nameref attribute on variables with values that reference
+# unset variables?
+
+unset bar
+declare -n foo="bar"
+declare -p foo
+
+declare +n foo
+declare -p foo bar
+
+declare -n foo
+declare -p foo
+
+# let's try removing the nameref attribute -- other attributes and assignments
+# apply to the nameref target
+
+declare +n -i foo=7+4
+declare -p foo bar
+
+unset foo bar
+
+# but if the nameref variable doesn't have a value, the attributes apply to
+# the nameref variable itself. thanks ksh93
+
+declare -n foo6
+declare -xi foo6
+declare -p foo6
+
+# and when we remove the nameref attribute, the other attributes remain
+
+declare +n foo6
+declare -p foo6
+
+unset foo6
+
+# make sure these cases continue to work
+
+# nameref referencing an existing, set variable
+declare -n foo=bar
+bar='Hello World!'
+declare -p foo bar
+declare +n foo
+declare -p foo bar
+unset foo bar
+
+# nameref referencing an existing, unset variable
+declare -n foo=bar
+declare bar
+declare -p foo bar
+declare +n foo
+declare -p foo bar
+
+# but when we add the nameref attribute, we remove other attributes
+
+declare -i ivar
+ivar=4+4
+echo $ivar
+
+declare -n ivar=foo
+declare -p ivar
diff --git a/tests/nameref2.sub b/tests/nameref2.sub
new file mode 100644
index 0000000..547cc19
--- /dev/null
+++ b/tests/nameref2.sub
@@ -0,0 +1,7 @@
+# test readonly nameref variables
+# ksh93 allows this but not typeset -rn ref=foo?
+typeset -n ref=foo
+readonly ref
+foo=4
+
+echo $ref
diff --git a/tests/nameref20.sub b/tests/nameref20.sub
new file mode 100644
index 0000000..715bc4d
--- /dev/null
+++ b/tests/nameref20.sub
@@ -0,0 +1,84 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# a collection of cases in bug reports after bash-5.0-alpha was released
+
+declare -n r=v[0]
+v=(X); r=Y
+declare -p ${!v*}
+printf "%s: <%s>\n" "r" "$r" "v" "$v"
+
+unset -n r
+unset -v v
+
+declare -n ref=var; declare -a ref
+ref=(X)
+declare -p ref var
+
+unset -n ref
+unset -v var
+
+f() { declare -n ref=var; declare ref=(X); declare -p ref var; };
+f
+
+unset -f f
+
+f() { declare -n ref=var; declare -g ref=(X); declare -p ref var; };
+
+declare -n ref=foo
+f
+echo outside:
+declare -p foo
+
+unset -n ref
+unset -v foo
+unset -f f
+
+f() { declare -n ref=var; declare -a ref; ref=(X); declare -p ref var; }
+
+f
+echo outside:
+declare -p ref var
+unset -f f
+
+f() { declare -n ref=var; declare ref; ref=X; declare -p ref var; }
+
+f
+echo outside:
+declare -p ref var
+
+unset -f f
+
+unset -n ref; unset var
+
+f()
+{
+ declare var=X; declare -n ref=var; declare ref=(Y)
+ declare -p ref var
+}
+f
+
+unset -f f
+
+declare -n ref=var
+f() { local ref=Y; declare -p ref var; local; }
+
+var=X
+f
+
+unset -v var
+f
+
+unset -n ref
+unset -f f
+
diff --git a/tests/nameref21.sub b/tests/nameref21.sub
new file mode 100644
index 0000000..08d8f56
--- /dev/null
+++ b/tests/nameref21.sub
@@ -0,0 +1,69 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# issues with local variables and local namerefs post-bash-4.4
+
+f()
+{
+ local -n ref=var
+ local -A ref=([1]=)
+# declare -p ref var
+ ref=([2]=)
+ declare -p ref var
+}
+
+unset ref var
+f
+
+unset ref; var=0
+f
+
+unset var
+unset -f f
+
+f()
+{
+ local -n ref=var
+ local -a ref=([1]=)
+ ref=([2]=)
+ declare -p ref var
+}
+
+unset ref var
+f
+
+unset ref; var=0
+f
+
+unset var
+unset -f f
+
+f() { local -n ref=var; local -i ref=([1]=); declare -p ref var; }
+
+unset var
+f
+
+var=0
+f
+
+unset var
+unset -f f
+
+f() { local -n ref=var; local ref=1; declare -p ref var; }
+
+var=0
+f
+
+unset var
+unset -f f
+
diff --git a/tests/nameref22.sub b/tests/nameref22.sub
new file mode 100644
index 0000000..4e44fbb
--- /dev/null
+++ b/tests/nameref22.sub
@@ -0,0 +1,97 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+declare -n foo=bar
+
+declare foo='a string with spaces'
+echo $foo
+
+unset foo
+declare foo+='many spaces'
+echo $foo
+
+unset foo # unsets bar
+unset -n foo
+
+declare -a bar
+declare -n foo='bar[0]'
+declare foo+=' still more spaces'
+
+declare -p foo bar
+unset -n foo
+unset bar
+
+declare -a bar
+declare -n foo='bar[0]'
+declare foo=spaces
+declare foo+=' still more spaces'
+
+declare -p foo bar
+
+unset -n foo
+unset bar
+
+ray=ray
+
+declare -a array
+array[0]=zero
+
+declare -n array
+unset array
+
+declare -n array[128]
+unset array
+
+declare -a array='(one two three)'
+declare -p array
+unset array
+
+declare array='(one two three)'
+declare -p array
+unset array
+
+declare -a ar$ray='(one two three)'
+declare -p ar$ray
+unset array
+
+declare -a array=(zero)
+declare -n array='(one two three)'
+declare -n array=three
+declare -p array
+unset array
+
+declare -n array=(one two three)
+declare -p array
+unset array
+
+declare -a array
+declare -n array=one
+declare -p array
+unset array
+
+array=one
+declare -i array[64];
+declare -p array
+unset array
+
+declare -a array=zero
+declare -p array
+unset array
+
+declare -a array
+declare array='(one two three)'
+declare -p array
+unset array
+
+
diff --git a/tests/nameref23.sub b/tests/nameref23.sub
new file mode 100644
index 0000000..358c381
--- /dev/null
+++ b/tests/nameref23.sub
@@ -0,0 +1,82 @@
+declare -ai a
+a[0]=4
+declare -n b='a[0]'
+
+b+=1 ; declare -p a
+
+declare b+=1 ; declare -p a
+
+unset a b
+unset -n b
+
+######
+declare -ai a=(1)
+declare -in b="a[0]"
+declare -p a b
+
+b+=1 ; declare -p a b
+b+=1 ; declare -p a b
+b+=0 ; declare -p a b
+
+unset a b
+
+#####
+declare -ai a=(1)
+declare -n b="1"
+declare -p a
+declare -np b
+
+unset a ; unset -n b
+
+#####
+declare -ai a=('4');
+declare -n b='a[0]';
+declare -ni b; # this should maybe not be allowed, but it is for now
+declare -p a b
+
+b+=2;
+declare -p a b
+
+unset a ; unset -n b
+
+#####
+f()
+{
+ local -a a=('' 'foo');
+ local -n b=a[1];
+ echo $b;
+ b+=\ bar;
+ echo $b;
+ declare -p a b;
+}
+f
+
+declare -a a=('' 'foo');
+declare -n b=a[1];
+echo $b;
+b+=\ bar;
+echo $b;
+declare -p a b
+
+unset a ; unset -n b
+
+unset -f f
+f()
+{
+ local -ai a=(0 12);
+ local -n b=a[1];
+ echo $b;
+ b+=4;
+ echo $b;
+ declare -p a;
+}
+f
+
+declare -ai a=(0 12);
+declare -n b=a[1];
+echo $b;
+b+=4;
+echo $b;
+declare -p a
+
+unset a ; unset -n b
diff --git a/tests/nameref3.sub b/tests/nameref3.sub
new file mode 100644
index 0000000..67cb098
--- /dev/null
+++ b/tests/nameref3.sub
@@ -0,0 +1,50 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# nameref requires changes to unset
+bar=one
+typeset -n foo=bar
+
+# normal unset unsets only variable nameref references
+# need unset -n to unset nameref itself
+unset foo
+echo "expect <unset>"
+recho ${bar-unset}
+echo "expect <unset>"
+recho ${foo-unset}
+echo "expect <bar>"
+recho ${!foo}
+unset -n foo
+echo "expect <unset>"
+recho "${!foo-unset}"
+
+readonly bar=two
+typeset -n foo=bar
+
+unset foo # this should fail because bar is readonly
+
+echo "expect <two>"
+echo ${bar-unset}
+echo "expect <two>"
+echo ${foo-unset}
+
+# one question is what happens when you unset the underlying variable
+qux=three
+typeset -n ref
+ref=qux
+
+echo $ref
+unset qux
+echo ${ref-unset}
+qux=four
+echo ${ref-unset}
diff --git a/tests/nameref4.sub b/tests/nameref4.sub
new file mode 100644
index 0000000..6367d56
--- /dev/null
+++ b/tests/nameref4.sub
@@ -0,0 +1,234 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test suite cribbed from ksh93 nameref tests
+typeset -i errors=0
+ckval()
+{
+ typeset -n one=$1
+
+ if [[ $one != $2 ]]; then
+ echo "one=$one != 2=$2"
+ (( errors++ ))
+ fi
+}
+
+ckref()
+{
+ typeset -n one=$1 two=$2
+
+ if [[ $one != $two ]]; then
+ echo "one=$one != two=$two"
+ (( errors++ ))
+ fi
+}
+
+name=first
+
+ckref name name
+
+func1()
+{
+ typeset -n color=$1
+ func2 color
+}
+
+func2()
+{
+ typeset color=$1
+ set -- ${color[@]}
+ printf "<%s>" "$@"
+ echo
+}
+
+typeset -A color
+color[apple]=red
+color[grape]=purple
+color[banana]=yellow
+
+# XXX
+#func1 color
+
+unset foo bar
+export bar=foo
+typeset -n foo=bar
+ckval foo foo
+
+# XXX - need to see if we can do checks for self-referencing at assignment
+# time
+command typeset -n xx=yy
+command typeset -n yy=xx
+echo $?
+
+unset foo bar
+unset -n foo bar
+set foo
+typeset -n bar=$1
+foo=hello
+ckval bar hello
+
+# XXX -- another self-referencing error?
+# ksh93 makes this another invalid self-reference
+unset foo
+unset -n bar
+
+bar=123
+foobar()
+{
+ typeset -n foo=bar
+ typeset -n foo=bar
+
+ ckval foo 123
+}
+
+typeset -n short=long
+short=( a b )
+echo "expect <a b>"
+echo ${long[@]}
+unset long
+unset -n short
+
+# assignment to a previously-unset variable
+typeset -n short=long
+short=foo
+echo "expect <foo>"
+echo ${long}
+unset long
+unset -n short
+
+unset foo bar
+
+# simple array references and assignments
+typeset -n foo=bar
+bar=( 1 3 5 7 9)
+echo ${foo[@]}
+echo ${foo[4]}
+foo[2]=42
+echo ${bar[@]}
+
+barfunc()
+{
+ typeset -n v=$1
+ echo ${v[@]}
+ echo ${v[4]}
+ v[2]=44
+ echo ${bar[@]}
+}
+barfunc bar
+
+unset -f foobar
+unset bar
+unset -n foo
+
+# should ref at global scope survive call to foobar()?
+unset ref x
+typeset -n ref
+x=42
+foobar()
+{
+ local xxx=3
+ ref=xxx
+ return 0
+}
+echo ${ref-unset}
+ref=x
+foobar
+ckval ref xxx
+ckval x xxx
+
+# assignment in a function to something possibly out of scope
+assignvar()
+{
+ typeset -n v=$1
+ shift
+ v="$@"
+}
+
+assignvar lex a b c d e
+echo "expect <a b c d e>"
+recho "${lex}"
+
+unset foo bar short long
+
+typeset -n foo='x[2]'
+
+x=(zero one two three four)
+foo=seven
+
+echo "expect <zero> <one> <seven> <three> <four>"
+recho "${x[@]}"
+
+unset ref x
+unset -n ref
+
+typeset -n ref
+ref=x
+# make sure nameref to a previously-unset variable creates the variable
+ref=42
+ckval x 42
+
+# make sure they work inside arithmetic expressions
+unset foo bar ref x xxx
+unset -n ref
+
+typeset -i ivar
+typeset -n iref=ivar
+
+ivar=4+3
+ckval ivar 7
+iref+=5
+ckval ivar 12
+echo $(( iref+4 ))
+(( iref=17 ))
+ckval ivar 17
+
+typeset +n iref
+unset iref ivar
+
+typeset +n foo bar
+unset foo bar
+
+# should the reference do immediate evaluation or deferred?
+set -- one two three four
+bar=4
+# XXX - what does foo get set to here?
+typeset -n foo='bar[0]'
+echo "expect <4>"
+echo ${bar[0]}
+echo "expect <4>"
+echo ${foo}
+echo "expect <4>"
+echo $foo
+ckval foo $bar
+
+# Need to add code and tests for nameref to array subscripts
+bar=(one two three four)
+
+typeset -n foo='bar[0]'
+typeset -n qux='bar[3]'
+echo "expect <one>"
+echo ${bar[0]}
+echo "expect <one>"
+echo ${foo}
+echo "expect <one>"
+echo $foo
+ckval foo $bar
+
+echo "expect <four>"
+echo $qux
+ckval qux ${bar[3]}
+
+# Need to add code and tests for `for' loop nameref variables
+
+echo errors = $errors
+exit $errors
diff --git a/tests/nameref5.sub b/tests/nameref5.sub
new file mode 100644
index 0000000..6855e99
--- /dev/null
+++ b/tests/nameref5.sub
@@ -0,0 +1,63 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# nameref variables as for loop index variables are special
+v1=1
+v2=2
+
+# simple for loop
+for v in v1 v2
+do
+ typeset -n ref=$v
+ echo $ref
+done
+unset v
+
+set -- first second third fourth fifth
+
+# unless you put a ${!v} in the for loop, ksh93 misbehaves
+typeset -n v=v1
+for v in v1 v2; do
+ echo "${!v}: $v"
+done
+unset v
+
+# example cribbed from ksh93 o'reilly book
+first="I am first"
+second="I am in the middle"
+third="I am last"
+
+typeset -n ref=first
+for ref in first second third ; do
+ echo "ref -> ${!ref}, value: $ref"
+done
+echo final state: "ref -> ${!ref}, value: $ref"
+
+readonly one=1
+readonly two=2
+readonly three=3
+
+typeset -n ref=one
+for ref in one two three; do
+ echo "ref -> ${!ref}, value: $ref"
+done
+echo final state: "ref -> ${!ref}, value: $ref"
+
+unset ref
+typeset -n ref=one
+readonly ref
+
+for ref in one two three; do
+ echo "ref -> ${!ref}, value: $ref"
+done
+echo final state: "ref -> ${!ref}, value: $ref"
diff --git a/tests/nameref6.sub b/tests/nameref6.sub
new file mode 100644
index 0000000..8497967
--- /dev/null
+++ b/tests/nameref6.sub
@@ -0,0 +1,57 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# these should be errors
+typeset -n x=x
+#echo $x -- $?
+
+typeset -n x[3]=x
+#echo $x -- $?
+
+x=(the browns suck)
+y=(one two three)
+# should be an error but not disturb the current contents of x
+# maybe rethink that later
+typeset -n x=y
+echo $x -- $?
+
+typeset -n
+
+unset x y
+
+y=42
+typeset -i x=1
+
+# the integer attribute causes arithmetic eval to be done
+# we should not allow namerefs to non-identifiers
+typeset -n x=y
+echo $x -- $?
+
+typeset +n x
+echo $x -- $?
+
+# same kind of thing
+
+unset -n x
+unset y
+
+set -- first second third
+y=2
+typeset -i x=1
+
+typeset -n x=y
+echo $x -- $?
+echo ${x} -- $?
+
+typeset +n x
+echo $x -- $?
diff --git a/tests/nameref7.sub b/tests/nameref7.sub
new file mode 100644
index 0000000..5e67ac0
--- /dev/null
+++ b/tests/nameref7.sub
@@ -0,0 +1,31 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+fn ()
+{
+ declare -n var=foo; var=bar
+}
+
+unset foo
+fn
+echo ${foo:-unset}
+
+unset -f fn
+unset foo
+fn()
+{
+ declare -n var; var=foo
+}
+
+fn
+echo ${foo:-unset}
diff --git a/tests/nameref8.sub b/tests/nameref8.sub
new file mode 100644
index 0000000..465463b
--- /dev/null
+++ b/tests/nameref8.sub
@@ -0,0 +1,74 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+function f1
+{
+ typeset -n v=$1
+
+ v=inside
+}
+
+v=global
+f1 v
+echo $v
+
+unset v
+unset -f f1
+
+function foo
+{
+ typeset x=one
+
+ typeset -n y=$1
+ y=two
+ echo inside: $x
+}
+
+foo x
+echo outside: $x
+
+function foo2
+{
+ typeset -n x=$1
+
+ x=foo
+}
+
+foo2 x
+echo $x
+
+unset -f foo
+function foo { typeset -n v=$1; v=local; }
+
+v=global
+foo v
+echo $v
+
+unset v
+
+# invalid self reference at global scope
+typeset -n v=v
+
+# can we catch a circular self-reference?
+typeset -n v=w
+typeset -n w=x
+typeset -n x=v
+
+x=4
+echo x = $x
+
+unset -n v w x
+
+# can we keep local variables invisible when we add nameref attribute?
+function f { typeset x; typeset -n x; x=y; }
+f
diff --git a/tests/nameref9.sub b/tests/nameref9.sub
new file mode 100644
index 0000000..e76c21b
--- /dev/null
+++ b/tests/nameref9.sub
@@ -0,0 +1,8 @@
+arr=( idx1 idx2 )
+i='arr[1]'
+echo ${!i}
+echo ${!i/x/X}
+
+typeset -n f='arr[1]'
+echo ${f}
+echo ${f/x/X}
diff --git a/tests/new-exp.right b/tests/new-exp.right
new file mode 100644
index 0000000..e3dc40e
--- /dev/null
+++ b/tests/new-exp.right
@@ -0,0 +1,795 @@
+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 41: 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>
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <c>
+argv[4] = <d>
+argv[1] = <a>
+argv[2] = <b c>
+argv[3] = <d>
+./new-exp.tests: line 197: ABX: unbound variable
+./new-exp.tests: line 201: $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
+a
+./new-exp2.sub: line 55: /tmp/redir-notthere: No such file or directory
+1
+
+./new-exp2.sub: line 62: 1111111111111111111111: command not found
+
+argv[1] = <6>
+./new-exp.tests: line 302: ${#:}: 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>
+argv[1] = <a>
+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>
+x
+x
+x
+xabc
+x
+x
+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 520: $9: unbound variable
+./new-exp.tests: line 521: 9: unbound variable
+./new-exp.tests: line 522: UNSET: unbound variable
+./new-exp.tests: line 523: UNSET: unbound variable
+./new-exp.tests: line 524: UNSET: unbound variable
+./new-exp.tests: line 525: UNSET: unbound variable
+./new-exp.tests: line 526: 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>
+argv[2] = <_QUART>
+argv[3] = <_QUEST>
+argv[4] = <_QUILL>
+argv[5] = <_QUOTA>
+argv[6] = <_QUOTE>
+argv[1] = <_QUANTITY-_QUART-_QUEST-_QUILL-_QUOTA-_QUOTE>
+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>
+./new-exp3.sub: line 36: ${!_Q* }: bad substitution
+./new-exp3.sub: line 41: ${!1*}: bad substitution
+./new-exp3.sub: line 43: ${!@*}: 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 546: ${$(($#-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 565: $(($# - 2)): substring expression < 0
+./new-exp.tests: line 567: -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)
+}
+start;ing0;ing1;ing2;ing3;ing4;ing5;ing6;ing7;ing8;ing9;ing10;ing11;ing12;ing13;ing14;ing15;ing16;ing17;ing18;ing19;ing20;ing21;ing22;ing23;ing24;ing25;ing26;ing27;ing28;ing29;ing30;ing31;ing32;ing33;ing34;ing35;ing36;ing37;ing38;ing39;ing40;ing41;ing42;ing43;ing44;ing45;ing46;ing47;ing48;ing49;ing50;ing51;ing52;ing53;ing54;ing55;ing56;ing57;ing58;ing59;ing60;ing61;ing62;ing63;ing64;ing65;ing66;ing67;ing68;ing69;ing70;ing71;ing72;ing73;ing74;ing75;ing76;ing77;ing78;ing79;ing80;ing81;ing82;ing83;ing84;ing85;ing86;ing87;ing88;ing89;ing90;ing91;ing92;ing93;ing94;ing95;ing96;ing97;ing98;ing99;ing100;ing101;ing102;ing103;ing104;ing105;ing106;ing107;ing108;ing109;ing110;ing111;ing112;ing113;ing114;ing115;ing116;ing117;ing118;ing119;ing120;ing121;ing122;ing123;ing124;ing125;ing126;ing127;ing128;ing129;ing130;ing131;ing132;ing133;ing134;ing135;ing136;ing137;ing138;ing139;ing140;ing141;ing142;ing143;ing144;ing145;ing146;ing147;ing148;ing149;ing150;ing151;ing152;ing153;ing154;ing155;ing156;ing157;ing158;ing159;ing160;ing161;ing162;ing163;ing164;ing165;ing166;ing167;ing168;ing169;ing170;ing171;ing172;ing173;ing174;ing175;ing176;ing177;ing178;ing179;ing180;ing181;ing182;ing183;ing184;ing185;ing186;ing187;ing188;ing189;ing190;ing191;ing192;ing193;ing194;ing195;ing196;ing197;ing198;ing199;ing200;ing201;ing202;ing203;ing204;ing205;ing206;ing207;ing208;ing209;ing210;ing211;ing212;ing213;ing214;ing215;ing216;ing217;ing218;ing219;ing220;ing221;ing222;ing223;ing224;ing225;ing226;ing227;ing228;ing229;ing230;ing231;ing232;ing233;ing234;ing235;ing236;ing237;ing238;ing239;ing240;ing241;ing242;ing243;ing244;ing245;ing246;ing247;ing248;ing249;ing250;ing251;ing252;ing253;ing254;ing255;ing256;ing257;ing258;ing259;ing260;ing261;ing262;ing263;ing264;ing265;ing266;ing267;ing268;ing269;ing270;ing271;ing272;ing273;ing274;ing275;ing276;ing277;ing278;ing279;ing280;ing281;ing282;ing283;ing284;ing285;ing286;ing287;ing288;ing289;ing290;ing291;ing292;ing293;ing294;ing295;ing296;ing297;ing298;ing299;ing300;ing301;ing302;ing303;ing304;ing305;ing306;ing307;ing308;ing309;ing310;ing311;ing312;ing313;ing314;ing315;ing316;ing317;ing318;ing319;ing320;ing321;ing322;ing323;ing324;ing325;ing326;ing327;ing328;ing329;ing330;ing331;ing332;ing333;ing334;ing335;ing336;ing337;ing338;ing339;ing340;ing341;ing342;ing343;ing344;ing345;ing346;ing347;ing348;ing349;ing350;ing351;ing352;ing353;ing354;ing355;ing356;ing357;ing358;ing359;ing360;ing361;ing362;ing363;ing364;ing365;ing366;ing367;ing368;ing369;ing370;ing371;ing372;ing373;ing374;ing375;ing376;ing377;ing378;ing379;ing380;ing381;ing382;ing383;ing384;ing385;ing386;ing387;ing388;ing389;ing390;ing391;ing392;ing393;ing394;ing395;ing396;ing397;ing398;ing399;ing400;ing401;ing402;ing403;ing404;ing405;ing406;ing407;ing408;ing409;ing410;ing411;ing412;ing413;ing414;ing415;ing416;ing417;ing418;ing419;ing420;ing421;ing422;ing423;ing424;ing425;ing426;ing427;ing428;ing429;ing430;ing431;ing432;ing433;ing434;ing435;ing436;ing437;ing438;ing439;ing440;ing441;ing442;ing443;ing444;ing445;ing446;ing447;ing448;ing449;ing450;ing451;ing452;ing453;ing454;ing455;ing456;ing457;ing458;ing459;ing460;ing461;ing462;ing463;ing464;ing465;ing466;ing467;ing468;ing469;ing470;ing471;ing472;ing473;ing474;ing475;ing476;ing477;ing478;ing479;ing480;ing481;ing482;ing483;ing484;ing485;ing486;ing487;ing488;ing489;ing490;ing491;ing492;ing493;ing494;ing495;ing496;ing497;ing498;ing499;ing500;ing501;ing502;ing503;ing504;ing505;ing506;ing507;ing508;ing509;ing510;ing511;ing512;ing513;ing514;ing515;ing516;ing517;ing518;ing519;ing520;ing521;ing522;ing523;ing524;ing525;ing526;ing527;ing528;ing529;ing530;ing531;ing532;ing533;ing534;ing535;ing536;ing537;ing538;ing539;ing540;ing541;ing542;ing543;ing544;ing545;ing546;ing547;ing548;ing549;ing550;ing551;ing552;ing553;ing554;ing555;ing556;ing557;ing558;ing559;ing560;ing561;ing562;ing563;ing564;ing565;ing566;ing567;ing568;ing569;ing570;ing571;ing572;ing573;ing574;ing575;ing576;ing577;ing578;ing579;ing580;ing581;ing582;ing583;ing584;ing585;ing586;ing587;ing588;ing589;ing590;ing591;ing592;ing593;ing594;ing595;ing596;ing597;ing598;ing599;ing600;ing601;ing602;ing603;ing604;ing605;ing606;ing607;ing608;ing609;ing610;ing611;ing612;ing613;ing614;ing615;ing616;ing617;ing618;ing619;ing620;ing621;ing622;ing623;ing624;ing625;ing626;ing627;ing628;ing629;ing630;ing631;ing632;ing633;ing634;ing635;ing636;ing637;ing638;ing639;ing640;ing641;ing642;ing643;ing644;ing645;ing646;ing647;ing648;ing649;ing650;ing651;ing652;ing653;ing654;ing655;ing656;ing657;ing658;ing659;ing660;ing661;ing662;ing663;ing664;ing665;ing666;ing667;ing668;ing669;ing670;ing671;ing672;ing673;ing674;ing675;ing676;ing677;ing678;ing679;ing680;ing681;ing682;ing683;ing684;ing685;ing686;ing687;ing688;ing689;ing690;ing691;ing692;ing693;ing694;ing695;ing696;ing697;ing698;ing699;ing700;ing701;ing702;ing703;ing704;ing705;ing706;ing707;ing708;ing709;ing710;ing711;ing712;ing713;ing714;ing715;ing716;ing717;ing718;ing719;ing720;ing721;ing722;ing723;ing724;ing725;ing726;ing727;ing728;ing729;ing730;ing731;ing732;ing733;ing734;ing735;ing736;ing737;ing738;ing739;ing740;ing741;ing742;ing743;ing744;ing745;ing746;ing747;ing748;ing749;ing750;ing751;ing752;ing753;ing754;ing755;ing756;ing757;ing758;ing759;ing760;ing761;ing762;ing763;ing764;ing765;ing766;ing767;ing768;ing769;ing770;ing771;ing772;ing773;ing774;ing775;ing776;ing777;ing778;ing779;ing780;ing781;ing782;ing783;ing784;ing785;ing786;ing787;ing788;ing789;ing790;ing791;ing792;ing793;ing794;ing795;ing796;ing797;ing798;ing799;ing800;ing801;ing802;ing803;ing804;ing805;ing806;ing807;ing808;ing809;ing810;ing811;ing812;ing813;ing814;ing815;ing816;ing817;ing818;ing819;ing820;ing821;ing822;ing823;ing824;ing825;ing826;ing827;ing828;ing829;ing830;ing831;ing832;ing833;ing834;ing835;ing836;ing837;ing838;ing839;ing840;ing841;ing842;ing843;ing844;ing845;ing846;ing847;ing848;ing849;ing850;ing851;ing852;ing853;ing854;ing855;ing856;ing857;ing858;ing859;ing860;ing861;ing862;ing863;ing864;ing865;ing866;ing867;ing868;ing869;ing870;ing871;ing872;ing873;ing874;ing875;ing876;ing877;ing878;ing879;ing880;ing881;ing882;ing883;ing884;ing885;ing886;ing887;ing888;ing889;ing890;ing891;ing892;ing893;ing894;ing895;ing896;ing897;ing898;ing899;ing900;ing901;ing902;ing903;ing904;ing905;ing906;ing907;ing908;ing909;ing910;ing911;ing912;ing913;ing914;ing915;ing916;ing917;ing918;ing919;ing920;ing921;ing922;ing923;ing924;ing925;ing926;ing927;ing928;ing929;ing930;ing931;ing932;ing933;ing934;ing935;ing936;ing937;ing938;ing939;ing940;ing941;ing942;ing943;ing944;ing945;ing946;ing947;ing948;ing949;ing950;ing951;ing952;ing953;ing954;ing955;ing956;ing957;ing958;ing959;ing960;ing961;ing962;ing963;ing964;ing965;ing966;ing967;ing968;ing969;ing970;ing971;ing972;ing973;ing974;ing975;ing976;ing977;ing978;ing979;ing980;ing981;ing982;ing983;ing984;ing985;ing986;ing987;ing988;ing989;ing990;ing991;ing992;ing993;ing994;ing995;ing996;ing997;ing998;ing999
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+start;string0;string1;string2;string3;string4;string5;string6;string7;string8;string9;string10;string11;string12;string13;string14;string15;string16;string17;string18;string19;string20;string21;string22;string23;string24;string25;string26;string27;string28;string29;string30;string31;string32;string33;string34;string35;string36;string37;string38;string39;string40;string41;string42;string43;string44;string45;string46;string47;string48;string49;string50;string51;string52;string53;string54;string55;string56;string57;string58;string59;string60;string61;string62;string63;string64;string65;string66;string67;string68;string69;string70;string71;string72;string73;string74;string75;string76;string77;string78;string79;string80;string81;string82;string83;string84;string85;string86;string87;string88;string89;string90;string91;string92;string93;string94;string95;string96;string97;string98;string99;string100;string101;string102;string103;string104;string105;string106;string107;string108;string109;string110;string111;string112;string113;string114;string115;string116;string117;string118;string119;string120;string121;string122;string123;string124;string125;string126;string127;string128;string129;string130;string131;string132;string133;string134;string135;string136;string137;string138;string139;string140;string141;string142;string143;string144;string145;string146;string147;string148;string149;string150;string151;string152;string153;string154;string155;string156;string157;string158;string159;string160;string161;string162;string163;string164;string165;string166;string167;string168;string169;string170;string171;string172;string173;string174;string175;string176;string177;string178;string179;string180;string181;string182;string183;string184;string185;string186;string187;string188;string189;string190;string191;string192;string193;string194;string195;string196;string197;string198;string199;string200;string201;string202;string203;string204;string205;string206;string207;string208;string209;string210;string211;string212;string213;string214;string215;string216;string217;string218;string219;string220;string221;string222;string223;string224;string225;string226;string227;string228;string229;string230;string231;string232;string233;string234;string235;string236;string237;string238;string239;string240;string241;string242;string243;string244;string245;string246;string247;string248;string249;string250;string251;string252;string253;string254;string255;string256;string257;string258;string259;string260;string261;string262;string263;string264;string265;string266;string267;string268;string269;string270;string271;string272;string273;string274;string275;string276;string277;string278;string279;string280;string281;string282;string283;string284;string285;string286;string287;string288;string289;string290;string291;string292;string293;string294;string295;string296;string297;string298;string299;string300;string301;string302;string303;string304;string305;string306;string307;string308;string309;string310;string311;string312;string313;string314;string315;string316;string317;string318;string319;string320;string321;string322;string323;string324;string325;string326;string327;string328;string329;string330;string331;string332;string333;string334;string335;string336;string337;string338;string339;string340;string341;string342;string343;string344;string345;string346;string347;string348;string349;string350;string351;string352;string353;string354;string355;string356;string357;string358;string359;string360;string361;string362;string363;string364;string365;string366;string367;string368;string369;string370;string371;string372;string373;string374;string375;string376;string377;string378;string379;string380;string381;string382;string383;string384;string385;string386;string387;string388;string389;string390;string391;string392;string393;string394;string395;string396;string397;string398;string399;string400;string401;string402;string403;string404;string405;string406;string407;string408;string409;string410;string411;string412;string413;string414;string415;string416;string417;string418;string419;string420;string421;string422;string423;string424;string425;string426;string427;string428;string429;string430;string431;string432;string433;string434;string435;string436;string437;string438;string439;string440;string441;string442;string443;string444;string445;string446;string447;string448;string449;string450;string451;string452;string453;string454;string455;string456;string457;string458;string459;string460;string461;string462;string463;string464;string465;string466;string467;string468;string469;string470;string471;string472;string473;string474;string475;string476;string477;string478;string479;string480;string481;string482;string483;string484;string485;string486;string487;string488;string489;string490;string491;string492;string493;string494;string495;string496;string497;string498;string499;string500;string501;string502;string503;string504;string505;string506;string507;string508;string509;string510;string511;string512;string513;string514;string515;string516;string517;string518;string519;string520;string521;string522;string523;string524;string525;string526;string527;string528;string529;string530;string531;string532;string533;string534;string535;string536;string537;string538;string539;string540;string541;string542;string543;string544;string545;string546;string547;string548;string549;string550;string551;string552;string553;string554;string555;string556;string557;string558;string559;string560;string561;string562;string563;string564;string565;string566;string567;string568;string569;string570;string571;string572;string573;string574;string575;string576;string577;string578;string579;string580;string581;string582;string583;string584;string585;string586;string587;string588;string589;string590;string591;string592;string593;string594;string595;string596;string597;string598;string599;string600;string601;string602;string603;string604;string605;string606;string607;string608;string609;string610;string611;string612;string613;string614;string615;string616;string617;string618;string619;string620;string621;string622;string623;string624;string625;string626;string627;string628;string629;string630;string631;string632;string633;string634;string635;string636;string637;string638;string639;string640;string641;string642;string643;string644;string645;string646;string647;string648;string649;string650;string651;string652;string653;string654;string655;string656;string657;string658;string659;string660;string661;string662;string663;string664;string665;string666;string667;string668;string669;string670;string671;string672;string673;string674;string675;string676;string677;string678;string679;string680;string681;string682;string683;string684;string685;string686;string687;string688;string689;string690;string691;string692;string693;string694;string695;string696;string697;string698;string699;string700;string701;string702;string703;string704;string705;string706;string707;string708;string709;string710;string711;string712;string713;string714;string715;string716;string717;string718;string719;string720;string721;string722;string723;string724;string725;string726;string727;string728;string729;string730;string731;string732;string733;string734;string735;string736;string737;string738;string739;string740;string741;string742;string743;string744;string745;string746;string747;string748;string749;string750;string751;string752;string753;string754;string755;string756;string757;string758;string759;string760;string761;string762;string763;string764;string765;string766;string767;string768;string769;string770;string771;string772;string773;string774;string775;string776;string777;string778;string779;string780;string781;string782;string783;string784;string785;string786;string787;string788;string789;string790;string791;string792;string793;string794;string795;string796;string797;string798;string799;string800;string801;string802;string803;string804;string805;string806;string807;string808;string809;string810;string811;string812;string813;string814;string815;string816;string817;string818;string819;string820;string821;string822;string823;string824;string825;string826;string827;string828;string829;string830;string831;string832;string833;string834;string835;string836;string837;string838;string839;string840;string841;string842;string843;string844;string845;string846;string847;string848;string849;string850;string851;string852;string853;string854;string855;string856;string857;string858;string859;string860;string861;string862;string863;string864;string865;string866;string867;string868;string869;string870;string871;string872;string873;string874;string875;string876;string877;string878;string879;string880;string881;string882;string883;string884;string885;string886;string887;string888;string889;string890;string891;string892;string893;string894;string895;string896;string897;string898;string899;string900;string901;string902;string903;string904;string905;string906;string907;string908;string909;string910;string911;string912;string913;string914;string915;string916;string917;string918;string919;string920;string921;string922;string923;string924;string925;string926;string927;string928;string929;string930;string931;string932;string933;string934;string935;string936;string937;string938;string939;string940;string941;string942;string943;string944;string945;string946;string947;string948;string949;string950;string951;string952;string953;string954;string955;string956;string957;string958;string959;string960;string961;string962;string963;string964;string965;string966;string967;string968;string969;string970;string971;string972;string973;string974;string975;string976;string977;string978;string979;string980;string981;string982;string983;string984;string985;string986;string987;string988;string989;string990;string991;string992;string993;string994;string995;string996;string997;string998;string999
+start;ing0;ing1;ing2;ing3;ing4;ing5;ing6;ing7;ing8;ing9;ing10;ing11;ing12;ing13;ing14;ing15;ing16;ing17;ing18;ing19;ing20;ing21;ing22;ing23;ing24;ing25;ing26;ing27;ing28;ing29;ing30;ing31;ing32;ing33;ing34;ing35;ing36;ing37;ing38;ing39;ing40;ing41;ing42;ing43;ing44;ing45;ing46;ing47;ing48;ing49;ing50;ing51;ing52;ing53;ing54;ing55;ing56;ing57;ing58;ing59;ing60;ing61;ing62;ing63;ing64;ing65;ing66;ing67;ing68;ing69;ing70;ing71;ing72;ing73;ing74;ing75;ing76;ing77;ing78;ing79;ing80;ing81;ing82;ing83;ing84;ing85;ing86;ing87;ing88;ing89;ing90;ing91;ing92;ing93;ing94;ing95;ing96;ing97;ing98;ing99;ing100;ing101;ing102;ing103;ing104;ing105;ing106;ing107;ing108;ing109;ing110;ing111;ing112;ing113;ing114;ing115;ing116;ing117;ing118;ing119;ing120;ing121;ing122;ing123;ing124;ing125;ing126;ing127;ing128;ing129;ing130;ing131;ing132;ing133;ing134;ing135;ing136;ing137;ing138;ing139;ing140;ing141;ing142;ing143;ing144;ing145;ing146;ing147;ing148;ing149;ing150;ing151;ing152;ing153;ing154;ing155;ing156;ing157;ing158;ing159;ing160;ing161;ing162;ing163;ing164;ing165;ing166;ing167;ing168;ing169;ing170;ing171;ing172;ing173;ing174;ing175;ing176;ing177;ing178;ing179;ing180;ing181;ing182;ing183;ing184;ing185;ing186;ing187;ing188;ing189;ing190;ing191;ing192;ing193;ing194;ing195;ing196;ing197;ing198;ing199;ing200;ing201;ing202;ing203;ing204;ing205;ing206;ing207;ing208;ing209;ing210;ing211;ing212;ing213;ing214;ing215;ing216;ing217;ing218;ing219;ing220;ing221;ing222;ing223;ing224;ing225;ing226;ing227;ing228;ing229;ing230;ing231;ing232;ing233;ing234;ing235;ing236;ing237;ing238;ing239;ing240;ing241;ing242;ing243;ing244;ing245;ing246;ing247;ing248;ing249;ing250;ing251;ing252;ing253;ing254;ing255;ing256;ing257;ing258;ing259;ing260;ing261;ing262;ing263;ing264;ing265;ing266;ing267;ing268;ing269;ing270;ing271;ing272;ing273;ing274;ing275;ing276;ing277;ing278;ing279;ing280;ing281;ing282;ing283;ing284;ing285;ing286;ing287;ing288;ing289;ing290;ing291;ing292;ing293;ing294;ing295;ing296;ing297;ing298;ing299;ing300;ing301;ing302;ing303;ing304;ing305;ing306;ing307;ing308;ing309;ing310;ing311;ing312;ing313;ing314;ing315;ing316;ing317;ing318;ing319;ing320;ing321;ing322;ing323;ing324;ing325;ing326;ing327;ing328;ing329;ing330;ing331;ing332;ing333;ing334;ing335;ing336;ing337;ing338;ing339;ing340;ing341;ing342;ing343;ing344;ing345;ing346;ing347;ing348;ing349;ing350;ing351;ing352;ing353;ing354;ing355;ing356;ing357;ing358;ing359;ing360;ing361;ing362;ing363;ing364;ing365;ing366;ing367;ing368;ing369;ing370;ing371;ing372;ing373;ing374;ing375;ing376;ing377;ing378;ing379;ing380;ing381;ing382;ing383;ing384;ing385;ing386;ing387;ing388;ing389;ing390;ing391;ing392;ing393;ing394;ing395;ing396;ing397;ing398;ing399;ing400;ing401;ing402;ing403;ing404;ing405;ing406;ing407;ing408;ing409;ing410;ing411;ing412;ing413;ing414;ing415;ing416;ing417;ing418;ing419;ing420;ing421;ing422;ing423;ing424;ing425;ing426;ing427;ing428;ing429;ing430;ing431;ing432;ing433;ing434;ing435;ing436;ing437;ing438;ing439;ing440;ing441;ing442;ing443;ing444;ing445;ing446;ing447;ing448;ing449;ing450;ing451;ing452;ing453;ing454;ing455;ing456;ing457;ing458;ing459;ing460;ing461;ing462;ing463;ing464;ing465;ing466;ing467;ing468;ing469;ing470;ing471;ing472;ing473;ing474;ing475;ing476;ing477;ing478;ing479;ing480;ing481;ing482;ing483;ing484;ing485;ing486;ing487;ing488;ing489;ing490;ing491;ing492;ing493;ing494;ing495;ing496;ing497;ing498;ing499;ing500;ing501;ing502;ing503;ing504;ing505;ing506;ing507;ing508;ing509;ing510;ing511;ing512;ing513;ing514;ing515;ing516;ing517;ing518;ing519;ing520;ing521;ing522;ing523;ing524;ing525;ing526;ing527;ing528;ing529;ing530;ing531;ing532;ing533;ing534;ing535;ing536;ing537;ing538;ing539;ing540;ing541;ing542;ing543;ing544;ing545;ing546;ing547;ing548;ing549;ing550;ing551;ing552;ing553;ing554;ing555;ing556;ing557;ing558;ing559;ing560;ing561;ing562;ing563;ing564;ing565;ing566;ing567;ing568;ing569;ing570;ing571;ing572;ing573;ing574;ing575;ing576;ing577;ing578;ing579;ing580;ing581;ing582;ing583;ing584;ing585;ing586;ing587;ing588;ing589;ing590;ing591;ing592;ing593;ing594;ing595;ing596;ing597;ing598;ing599;ing600;ing601;ing602;ing603;ing604;ing605;ing606;ing607;ing608;ing609;ing610;ing611;ing612;ing613;ing614;ing615;ing616;ing617;ing618;ing619;ing620;ing621;ing622;ing623;ing624;ing625;ing626;ing627;ing628;ing629;ing630;ing631;ing632;ing633;ing634;ing635;ing636;ing637;ing638;ing639;ing640;ing641;ing642;ing643;ing644;ing645;ing646;ing647;ing648;ing649;ing650;ing651;ing652;ing653;ing654;ing655;ing656;ing657;ing658;ing659;ing660;ing661;ing662;ing663;ing664;ing665;ing666;ing667;ing668;ing669;ing670;ing671;ing672;ing673;ing674;ing675;ing676;ing677;ing678;ing679;ing680;ing681;ing682;ing683;ing684;ing685;ing686;ing687;ing688;ing689;ing690;ing691;ing692;ing693;ing694;ing695;ing696;ing697;ing698;ing699;ing700;ing701;ing702;ing703;ing704;ing705;ing706;ing707;ing708;ing709;ing710;ing711;ing712;ing713;ing714;ing715;ing716;ing717;ing718;ing719;ing720;ing721;ing722;ing723;ing724;ing725;ing726;ing727;ing728;ing729;ing730;ing731;ing732;ing733;ing734;ing735;ing736;ing737;ing738;ing739;ing740;ing741;ing742;ing743;ing744;ing745;ing746;ing747;ing748;ing749;ing750;ing751;ing752;ing753;ing754;ing755;ing756;ing757;ing758;ing759;ing760;ing761;ing762;ing763;ing764;ing765;ing766;ing767;ing768;ing769;ing770;ing771;ing772;ing773;ing774;ing775;ing776;ing777;ing778;ing779;ing780;ing781;ing782;ing783;ing784;ing785;ing786;ing787;ing788;ing789;ing790;ing791;ing792;ing793;ing794;ing795;ing796;ing797;ing798;ing799;ing800;ing801;ing802;ing803;ing804;ing805;ing806;ing807;ing808;ing809;ing810;ing811;ing812;ing813;ing814;ing815;ing816;ing817;ing818;ing819;ing820;ing821;ing822;ing823;ing824;ing825;ing826;ing827;ing828;ing829;ing830;ing831;ing832;ing833;ing834;ing835;ing836;ing837;ing838;ing839;ing840;ing841;ing842;ing843;ing844;ing845;ing846;ing847;ing848;ing849;ing850;ing851;ing852;ing853;ing854;ing855;ing856;ing857;ing858;ing859;ing860;ing861;ing862;ing863;ing864;ing865;ing866;ing867;ing868;ing869;ing870;ing871;ing872;ing873;ing874;ing875;ing876;ing877;ing878;ing879;ing880;ing881;ing882;ing883;ing884;ing885;ing886;ing887;ing888;ing889;ing890;ing891;ing892;ing893;ing894;ing895;ing896;ing897;ing898;ing899;ing900;ing901;ing902;ing903;ing904;ing905;ing906;ing907;ing908;ing909;ing910;ing911;ing912;ing913;ing914;ing915;ing916;ing917;ing918;ing919;ing920;ing921;ing922;ing923;ing924;ing925;ing926;ing927;ing928;ing929;ing930;ing931;ing932;ing933;ing934;ing935;ing936;ing937;ing938;ing939;ing940;ing941;ing942;ing943;ing944;ing945;ing946;ing947;ing948;ing949;ing950;ing951;ing952;ing953;ing954;ing955;ing956;ing957;ing958;ing959;ing960;ing961;ing962;ing963;ing964;ing965;ing966;ing967;ing968;ing969;ing970;ing971;ing972;ing973;ing974;ing975;ing976;ing977;ing978;ing979;ing980;ing981;ing982;ing983;ing984;ing985;ing986;ing987;ing988;ing989;ing990;ing991;ing992;ing993;ing994;ing995;ing996;ing997;ing998;ing999
+start;string0;string1;string2;string3;string4;string5;string6;string7;string8;string9;string10;string11;string12;string13;string14;string15;string16;string17;string18;string19;string20;string21;string22;string23;string24;string25;string26;string27;string28;string29;string30;string31;string32;string33;string34;string35;string36;string37;string38;string39;string40;string41;string42;string43;string44;string45;string46;string47;string48;string49;string50;string51;string52;string53;string54;string55;string56;string57;string58;string59;string60;string61;string62;string63;string64;string65;string66;string67;string68;string69;string70;string71;string72;string73;string74;string75;string76;string77;string78;string79;string80;string81;string82;string83;string84;string85;string86;string87;string88;string89;string90;string91;string92;string93;string94;string95;string96;string97;string98;string99;string100;string101;string102;string103;string104;string105;string106;string107;string108;string109;string110;string111;string112;string113;string114;string115;string116;string117;string118;string119;string120;string121;string122;string123;string124;string125;string126;string127;string128;string129;string130;string131;string132;string133;string134;string135;string136;string137;string138;string139;string140;string141;string142;string143;string144;string145;string146;string147;string148;string149;string150;string151;string152;string153;string154;string155;string156;string157;string158;string159;string160;string161;string162;string163;string164;string165;string166;string167;string168;string169;string170;string171;string172;string173;string174;string175;string176;string177;string178;string179;string180;string181;string182;string183;string184;string185;string186;string187;string188;string189;string190;string191;string192;string193;string194;string195;string196;string197;string198;string199;string200;string201;string202;string203;string204;string205;string206;string207;string208;string209;string210;string211;string212;string213;string214;string215;string216;string217;string218;string219;string220;string221;string222;string223;string224;string225;string226;string227;string228;string229;string230;string231;string232;string233;string234;string235;string236;string237;string238;string239;string240;string241;string242;string243;string244;string245;string246;string247;string248;string249;string250;string251;string252;string253;string254;string255;string256;string257;string258;string259;string260;string261;string262;string263;string264;string265;string266;string267;string268;string269;string270;string271;string272;string273;string274;string275;string276;string277;string278;string279;string280;string281;string282;string283;string284;string285;string286;string287;string288;string289;string290;string291;string292;string293;string294;string295;string296;string297;string298;string299;string300;string301;string302;string303;string304;string305;string306;string307;string308;string309;string310;string311;string312;string313;string314;string315;string316;string317;string318;string319;string320;string321;string322;string323;string324;string325;string326;string327;string328;string329;string330;string331;string332;string333;string334;string335;string336;string337;string338;string339;string340;string341;string342;string343;string344;string345;string346;string347;string348;string349;string350;string351;string352;string353;string354;string355;string356;string357;string358;string359;string360;string361;string362;string363;string364;string365;string366;string367;string368;string369;string370;string371;string372;string373;string374;string375;string376;string377;string378;string379;string380;string381;string382;string383;string384;string385;string386;string387;string388;string389;string390;string391;string392;string393;string394;string395;string396;string397;string398;string399;string400;string401;string402;string403;string404;string405;string406;string407;string408;string409;string410;string411;string412;string413;string414;string415;string416;string417;string418;string419;string420;string421;string422;string423;string424;string425;string426;string427;string428;string429;string430;string431;string432;string433;string434;string435;string436;string437;string438;string439;string440;string441;string442;string443;string444;string445;string446;string447;string448;string449;string450;string451;string452;string453;string454;string455;string456;string457;string458;string459;string460;string461;string462;string463;string464;string465;string466;string467;string468;string469;string470;string471;string472;string473;string474;string475;string476;string477;string478;string479;string480;string481;string482;string483;string484;string485;string486;string487;string488;string489;string490;string491;string492;string493;string494;string495;string496;string497;string498;string499;string500;string501;string502;string503;string504;string505;string506;string507;string508;string509;string510;string511;string512;string513;string514;string515;string516;string517;string518;string519;string520;string521;string522;string523;string524;string525;string526;string527;string528;string529;string530;string531;string532;string533;string534;string535;string536;string537;string538;string539;string540;string541;string542;string543;string544;string545;string546;string547;string548;string549;string550;string551;string552;string553;string554;string555;string556;string557;string558;string559;string560;string561;string562;string563;string564;string565;string566;string567;string568;string569;string570;string571;string572;string573;string574;string575;string576;string577;string578;string579;string580;string581;string582;string583;string584;string585;string586;string587;string588;string589;string590;string591;string592;string593;string594;string595;string596;string597;string598;string599;string600;string601;string602;string603;string604;string605;string606;string607;string608;string609;string610;string611;string612;string613;string614;string615;string616;string617;string618;string619;string620;string621;string622;string623;string624;string625;string626;string627;string628;string629;string630;string631;string632;string633;string634;string635;string636;string637;string638;string639;string640;string641;string642;string643;string644;string645;string646;string647;string648;string649;string650;string651;string652;string653;string654;string655;string656;string657;string658;string659;string660;string661;string662;string663;string664;string665;string666;string667;string668;string669;string670;string671;string672;string673;string674;string675;string676;string677;string678;string679;string680;string681;string682;string683;string684;string685;string686;string687;string688;string689;string690;string691;string692;string693;string694;string695;string696;string697;string698;string699;string700;string701;string702;string703;string704;string705;string706;string707;string708;string709;string710;string711;string712;string713;string714;string715;string716;string717;string718;string719;string720;string721;string722;string723;string724;string725;string726;string727;string728;string729;string730;string731;string732;string733;string734;string735;string736;string737;string738;string739;string740;string741;string742;string743;string744;string745;string746;string747;string748;string749;string750;string751;string752;string753;string754;string755;string756;string757;string758;string759;string760;string761;string762;string763;string764;string765;string766;string767;string768;string769;string770;string771;string772;string773;string774;string775;string776;string777;string778;string779;string780;string781;string782;string783;string784;string785;string786;string787;string788;string789;string790;string791;string792;string793;string794;string795;string796;string797;string798;string799;string800;string801;string802;string803;string804;string805;string806;string807;string808;string809;string810;string811;string812;string813;string814;string815;string816;string817;string818;string819;string820;string821;string822;string823;string824;string825;string826;string827;string828;string829;string830;string831;string832;string833;string834;string835;string836;string837;string838;string839;string840;string841;string842;string843;string844;string845;string846;string847;string848;string849;string850;string851;string852;string853;string854;string855;string856;string857;string858;string859;string860;string861;string862;string863;string864;string865;string866;string867;string868;string869;string870;string871;string872;string873;string874;string875;string876;string877;string878;string879;string880;string881;string882;string883;string884;string885;string886;string887;string888;string889;string890;string891;string892;string893;string894;string895;string896;string897;string898;string899;string900;string901;string902;string903;string904;string905;string906;string907;string908;string909;string910;string911;string912;string913;string914;string915;string916;string917;string918;string919;string920;string921;string922;string923;string924;string925;string926;string927;string928;string929;string930;string931;string932;string933;string934;string935;string936;string937;string938;string939;string940;string941;string942;string943;string944;string945;string946;string947;string948;string949;string950;string951;string952;string953;string954;string955;string956;string957;string958;string959;string960;string961;string962;string963;string964;string965;string966;string967;string968;string969;string970;string971;string972;string973;string974;string975;string976;string977;string978;string979;string980;string981;string982;string983;string984;string985;string986;string987;string988;string989;string990;string991;string992;string993;string994;string995;string996;string997;string998;string999
+start;string0;string1;string2;string3;string4;string5;string6;string7;string8;string9;string10;string11;string12;string13;string14;string15;string16;string17;string18;string19;string20;string21;string22;string23;string24;string25;string26;string27;string28;string29;string30;string31;string32;string33;string34;string35;string36;string37;string38;string39;string40;string41;string42;string43;string44;string45;string46;string47;string48;string49;string50;string51;string52;string53;string54;string55;string56;string57;string58;string59;string60;string61;string62;string63;string64;string65;string66;string67;string68;string69;string70;string71;string72;string73;string74;string75;string76;string77;string78;string79;string80;string81;string82;string83;string84;string85;string86;string87;string88;string89;string90;string91;string92;string93;string94;string95;string96;string97;string98;string99;string100;string101;string102;string103;string104;string105;string106;string107;string108;string109;string110;string111;string112;string113;string114;string115;string116;string117;string118;string119;string120;string121;string122;string123;string124;string125;string126;string127;string128;string129;string130;string131;string132;string133;string134;string135;string136;string137;string138;string139;string140;string141;string142;string143;string144;string145;string146;string147;string148;string149;string150;string151;string152;string153;string154;string155;string156;string157;string158;string159;string160;string161;string162;string163;string164;string165;string166;string167;string168;string169;string170;string171;string172;string173;string174;string175;string176;string177;string178;string179;string180;string181;string182;string183;string184;string185;string186;string187;string188;string189;string190;string191;string192;string193;string194;string195;string196;string197;string198;string199;string200;string201;string202;string203;string204;string205;string206;string207;string208;string209;string210;string211;string212;string213;string214;string215;string216;string217;string218;string219;string220;string221;string222;string223;string224;string225;string226;string227;string228;string229;string230;string231;string232;string233;string234;string235;string236;string237;string238;string239;string240;string241;string242;string243;string244;string245;string246;string247;string248;string249;string250;string251;string252;string253;string254;string255;string256;string257;string258;string259;string260;string261;string262;string263;string264;string265;string266;string267;string268;string269;string270;string271;string272;string273;string274;string275;string276;string277;string278;string279;string280;string281;string282;string283;string284;string285;string286;string287;string288;string289;string290;string291;string292;string293;string294;string295;string296;string297;string298;string299;string300;string301;string302;string303;string304;string305;string306;string307;string308;string309;string310;string311;string312;string313;string314;string315;string316;string317;string318;string319;string320;string321;string322;string323;string324;string325;string326;string327;string328;string329;string330;string331;string332;string333;string334;string335;string336;string337;string338;string339;string340;string341;string342;string343;string344;string345;string346;string347;string348;string349;string350;string351;string352;string353;string354;string355;string356;string357;string358;string359;string360;string361;string362;string363;string364;string365;string366;string367;string368;string369;string370;string371;string372;string373;string374;string375;string376;string377;string378;string379;string380;string381;string382;string383;string384;string385;string386;string387;string388;string389;string390;string391;string392;string393;string394;string395;string396;string397;string398;string399;string400;string401;string402;string403;string404;string405;string406;string407;string408;string409;string410;string411;string412;string413;string414;string415;string416;string417;string418;string419;string420;string421;string422;string423;string424;string425;string426;string427;string428;string429;string430;string431;string432;string433;string434;string435;string436;string437;string438;string439;string440;string441;string442;string443;string444;string445;string446;string447;string448;string449;string450;string451;string452;string453;string454;string455;string456;string457;string458;string459;string460;string461;string462;string463;string464;string465;string466;string467;string468;string469;string470;string471;string472;string473;string474;string475;string476;string477;string478;string479;string480;string481;string482;string483;string484;string485;string486;string487;string488;string489;string490;string491;string492;string493;string494;string495;string496;string497;string498;string499;string500;string501;string502;string503;string504;string505;string506;string507;string508;string509;string510;string511;string512;string513;string514;string515;string516;string517;string518;string519;string520;string521;string522;string523;string524;string525;string526;string527;string528;string529;string530;string531;string532;string533;string534;string535;string536;string537;string538;string539;string540;string541;string542;string543;string544;string545;string546;string547;string548;string549;string550;string551;string552;string553;string554;string555;string556;string557;string558;string559;string560;string561;string562;string563;string564;string565;string566;string567;string568;string569;string570;string571;string572;string573;string574;string575;string576;string577;string578;string579;string580;string581;string582;string583;string584;string585;string586;string587;string588;string589;string590;string591;string592;string593;string594;string595;string596;string597;string598;string599;string600;string601;string602;string603;string604;string605;string606;string607;string608;string609;string610;string611;string612;string613;string614;string615;string616;string617;string618;string619;string620;string621;string622;string623;string624;string625;string626;string627;string628;string629;string630;string631;string632;string633;string634;string635;string636;string637;string638;string639;string640;string641;string642;string643;string644;string645;string646;string647;string648;string649;string650;string651;string652;string653;string654;string655;string656;string657;string658;string659;string660;string661;string662;string663;string664;string665;string666;string667;string668;string669;string670;string671;string672;string673;string674;string675;string676;string677;string678;string679;string680;string681;string682;string683;string684;string685;string686;string687;string688;string689;string690;string691;string692;string693;string694;string695;string696;string697;string698;string699;string700;string701;string702;string703;string704;string705;string706;string707;string708;string709;string710;string711;string712;string713;string714;string715;string716;string717;string718;string719;string720;string721;string722;string723;string724;string725;string726;string727;string728;string729;string730;string731;string732;string733;string734;string735;string736;string737;string738;string739;string740;string741;string742;string743;string744;string745;string746;string747;string748;string749;string750;string751;string752;string753;string754;string755;string756;string757;string758;string759;string760;string761;string762;string763;string764;string765;string766;string767;string768;string769;string770;string771;string772;string773;string774;string775;string776;string777;string778;string779;string780;string781;string782;string783;string784;string785;string786;string787;string788;string789;string790;string791;string792;string793;string794;string795;string796;string797;string798;string799;string800;string801;string802;string803;string804;string805;string806;string807;string808;string809;string810;string811;string812;string813;string814;string815;string816;string817;string818;string819;string820;string821;string822;string823;string824;string825;string826;string827;string828;string829;string830;string831;string832;string833;string834;string835;string836;string837;string838;string839;string840;string841;string842;string843;string844;string845;string846;string847;string848;string849;string850;string851;string852;string853;string854;string855;string856;string857;string858;string859;string860;string861;string862;string863;string864;string865;string866;string867;string868;string869;string870;string871;string872;string873;string874;string875;string876;string877;string878;string879;string880;string881;string882;string883;string884;string885;string886;string887;string888;string889;string890;string891;string892;string893;string894;string895;string896;string897;string898;string899;string900;string901;string902;string903;string904;string905;string906;string907;string908;string909;string910;string911;string912;string913;string914;string915;string916;string917;string918;string919;string920;string921;string922;string923;string924;string925;string926;string927;string928;string929;string930;string931;string932;string933;string934;string935;string936;string937;string938;string939;string940;string941;string942;string943;string944;string945;string946;string947;string948;string949;string950;string951;string952;string953;string954;string955;string956;string957;string958;string959;string960;string961;string962;string963;string964;string965;string966;string967;string968;string969;string970;string971;string972;string973;string974;string975;string976;string977;string978;string979;string980;string981;string982;string983;string984;string985;string986;string987;string988;string989;string990;string991;string992;string993;string994;string995;string996;string997;string998;string999
+ing999
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+art;string0;string1;string2;string3;string4;string5;string6;string7;string8;string9;string10;string11;string12;string13;string14;string15;string16;string17;string18;string19;string20;string21;string22;string23;string24;string25;string26;string27;string28;string29;string30;string31;string32;string33;string34;string35;string36;string37;string38;string39;string40;string41;string42;string43;string44;string45;string46;string47;string48;string49;string50;string51;string52;string53;string54;string55;string56;string57;string58;string59;string60;string61;string62;string63;string64;string65;string66;string67;string68;string69;string70;string71;string72;string73;string74;string75;string76;string77;string78;string79;string80;string81;string82;string83;string84;string85;string86;string87;string88;string89;string90;string91;string92;string93;string94;string95;string96;string97;string98;string99;string100;string101;string102;string103;string104;string105;string106;string107;string108;string109;string110;string111;string112;string113;string114;string115;string116;string117;string118;string119;string120;string121;string122;string123;string124;string125;string126;string127;string128;string129;string130;string131;string132;string133;string134;string135;string136;string137;string138;string139;string140;string141;string142;string143;string144;string145;string146;string147;string148;string149;string150;string151;string152;string153;string154;string155;string156;string157;string158;string159;string160;string161;string162;string163;string164;string165;string166;string167;string168;string169;string170;string171;string172;string173;string174;string175;string176;string177;string178;string179;string180;string181;string182;string183;string184;string185;string186;string187;string188;string189;string190;string191;string192;string193;string194;string195;string196;string197;string198;string199;string200;string201;string202;string203;string204;string205;string206;string207;string208;string209;string210;string211;string212;string213;string214;string215;string216;string217;string218;string219;string220;string221;string222;string223;string224;string225;string226;string227;string228;string229;string230;string231;string232;string233;string234;string235;string236;string237;string238;string239;string240;string241;string242;string243;string244;string245;string246;string247;string248;string249;string250;string251;string252;string253;string254;string255;string256;string257;string258;string259;string260;string261;string262;string263;string264;string265;string266;string267;string268;string269;string270;string271;string272;string273;string274;string275;string276;string277;string278;string279;string280;string281;string282;string283;string284;string285;string286;string287;string288;string289;string290;string291;string292;string293;string294;string295;string296;string297;string298;string299;string300;string301;string302;string303;string304;string305;string306;string307;string308;string309;string310;string311;string312;string313;string314;string315;string316;string317;string318;string319;string320;string321;string322;string323;string324;string325;string326;string327;string328;string329;string330;string331;string332;string333;string334;string335;string336;string337;string338;string339;string340;string341;string342;string343;string344;string345;string346;string347;string348;string349;string350;string351;string352;string353;string354;string355;string356;string357;string358;string359;string360;string361;string362;string363;string364;string365;string366;string367;string368;string369;string370;string371;string372;string373;string374;string375;string376;string377;string378;string379;string380;string381;string382;string383;string384;string385;string386;string387;string388;string389;string390;string391;string392;string393;string394;string395;string396;string397;string398;string399;string400;string401;string402;string403;string404;string405;string406;string407;string408;string409;string410;string411;string412;string413;string414;string415;string416;string417;string418;string419;string420;string421;string422;string423;string424;string425;string426;string427;string428;string429;string430;string431;string432;string433;string434;string435;string436;string437;string438;string439;string440;string441;string442;string443;string444;string445;string446;string447;string448;string449;string450;string451;string452;string453;string454;string455;string456;string457;string458;string459;string460;string461;string462;string463;string464;string465;string466;string467;string468;string469;string470;string471;string472;string473;string474;string475;string476;string477;string478;string479;string480;string481;string482;string483;string484;string485;string486;string487;string488;string489;string490;string491;string492;string493;string494;string495;string496;string497;string498;string499;string500;string501;string502;string503;string504;string505;string506;string507;string508;string509;string510;string511;string512;string513;string514;string515;string516;string517;string518;string519;string520;string521;string522;string523;string524;string525;string526;string527;string528;string529;string530;string531;string532;string533;string534;string535;string536;string537;string538;string539;string540;string541;string542;string543;string544;string545;string546;string547;string548;string549;string550;string551;string552;string553;string554;string555;string556;string557;string558;string559;string560;string561;string562;string563;string564;string565;string566;string567;string568;string569;string570;string571;string572;string573;string574;string575;string576;string577;string578;string579;string580;string581;string582;string583;string584;string585;string586;string587;string588;string589;string590;string591;string592;string593;string594;string595;string596;string597;string598;string599;string600;string601;string602;string603;string604;string605;string606;string607;string608;string609;string610;string611;string612;string613;string614;string615;string616;string617;string618;string619;string620;string621;string622;string623;string624;string625;string626;string627;string628;string629;string630;string631;string632;string633;string634;string635;string636;string637;string638;string639;string640;string641;string642;string643;string644;string645;string646;string647;string648;string649;string650;string651;string652;string653;string654;string655;string656;string657;string658;string659;string660;string661;string662;string663;string664;string665;string666;string667;string668;string669;string670;string671;string672;string673;string674;string675;string676;string677;string678;string679;string680;string681;string682;string683;string684;string685;string686;string687;string688;string689;string690;string691;string692;string693;string694;string695;string696;string697;string698;string699;string700;string701;string702;string703;string704;string705;string706;string707;string708;string709;string710;string711;string712;string713;string714;string715;string716;string717;string718;string719;string720;string721;string722;string723;string724;string725;string726;string727;string728;string729;string730;string731;string732;string733;string734;string735;string736;string737;string738;string739;string740;string741;string742;string743;string744;string745;string746;string747;string748;string749;string750;string751;string752;string753;string754;string755;string756;string757;string758;string759;string760;string761;string762;string763;string764;string765;string766;string767;string768;string769;string770;string771;string772;string773;string774;string775;string776;string777;string778;string779;string780;string781;string782;string783;string784;string785;string786;string787;string788;string789;string790;string791;string792;string793;string794;string795;string796;string797;string798;string799;string800;string801;string802;string803;string804;string805;string806;string807;string808;string809;string810;string811;string812;string813;string814;string815;string816;string817;string818;string819;string820;string821;string822;string823;string824;string825;string826;string827;string828;string829;string830;string831;string832;string833;string834;string835;string836;string837;string838;string839;string840;string841;string842;string843;string844;string845;string846;string847;string848;string849;string850;string851;string852;string853;string854;string855;string856;string857;string858;string859;string860;string861;string862;string863;string864;string865;string866;string867;string868;string869;string870;string871;string872;string873;string874;string875;string876;string877;string878;string879;string880;string881;string882;string883;string884;string885;string886;string887;string888;string889;string890;string891;string892;string893;string894;string895;string896;string897;string898;string899;string900;string901;string902;string903;string904;string905;string906;string907;string908;string909;string910;string911;string912;string913;string914;string915;string916;string917;string918;string919;string920;string921;string922;string923;string924;string925;string926;string927;string928;string929;string930;string931;string932;string933;string934;string935;string936;string937;string938;string939;string940;string941;string942;string943;string944;string945;string946;string947;string948;string949;string950;string951;string952;string953;string954;string955;string956;string957;string958;string959;string960;string961;string962;string963;string964;string965;string966;string967;string968;string969;string970;string971;string972;string973;string974;string975;string976;string977;string978;string979;string980;string981;string982;string983;string984;string985;string986;string987;string988;string989;string990;string991;string992;string993;string994;string995;string996;string997;string998;string999
+start;string0;string1;string2;string3;string4;string5;string6;string7;string8;string9;string10;string11;string12;string13;string14;string15;string16;string17;string18;string19;string20;string21;string22;string23;string24;string25;string26;string27;string28;string29;string30;string31;string32;string33;string34;string35;string36;string37;string38;string39;string40;string41;string42;string43;string44;string45;string46;string47;string48;string49;string50;string51;string52;string53;string54;string55;string56;string57;string58;string59;string60;string61;string62;string63;string64;string65;string66;string67;string68;string69;string70;string71;string72;string73;string74;string75;string76;string77;string78;string79;string80;string81;string82;string83;string84;string85;string86;string87;string88;string89;string90;string91;string92;string93;string94;string95;string96;string97;string98;string99;string100;string101;string102;string103;string104;string105;string106;string107;string108;string109;string110;string111;string112;string113;string114;string115;string116;string117;string118;string119;string120;string121;string122;string123;string124;string125;string126;string127;string128;string129;string130;string131;string132;string133;string134;string135;string136;string137;string138;string139;string140;string141;string142;string143;string144;string145;string146;string147;string148;string149;string150;string151;string152;string153;string154;string155;string156;string157;string158;string159;string160;string161;string162;string163;string164;string165;string166;string167;string168;string169;string170;string171;string172;string173;string174;string175;string176;string177;string178;string179;string180;string181;string182;string183;string184;string185;string186;string187;string188;string189;string190;string191;string192;string193;string194;string195;string196;string197;string198;string199;string200;string201;string202;string203;string204;string205;string206;string207;string208;string209;string210;string211;string212;string213;string214;string215;string216;string217;string218;string219;string220;string221;string222;string223;string224;string225;string226;string227;string228;string229;string230;string231;string232;string233;string234;string235;string236;string237;string238;string239;string240;string241;string242;string243;string244;string245;string246;string247;string248;string249;string250;string251;string252;string253;string254;string255;string256;string257;string258;string259;string260;string261;string262;string263;string264;string265;string266;string267;string268;string269;string270;string271;string272;string273;string274;string275;string276;string277;string278;string279;string280;string281;string282;string283;string284;string285;string286;string287;string288;string289;string290;string291;string292;string293;string294;string295;string296;string297;string298;string299;string300;string301;string302;string303;string304;string305;string306;string307;string308;string309;string310;string311;string312;string313;string314;string315;string316;string317;string318;string319;string320;string321;string322;string323;string324;string325;string326;string327;string328;string329;string330;string331;string332;string333;string334;string335;string336;string337;string338;string339;string340;string341;string342;string343;string344;string345;string346;string347;string348;string349;string350;string351;string352;string353;string354;string355;string356;string357;string358;string359;string360;string361;string362;string363;string364;string365;string366;string367;string368;string369;string370;string371;string372;string373;string374;string375;string376;string377;string378;string379;string380;string381;string382;string383;string384;string385;string386;string387;string388;string389;string390;string391;string392;string393;string394;string395;string396;string397;string398;string399;string400;string401;string402;string403;string404;string405;string406;string407;string408;string409;string410;string411;string412;string413;string414;string415;string416;string417;string418;string419;string420;string421;string422;string423;string424;string425;string426;string427;string428;string429;string430;string431;string432;string433;string434;string435;string436;string437;string438;string439;string440;string441;string442;string443;string444;string445;string446;string447;string448;string449;string450;string451;string452;string453;string454;string455;string456;string457;string458;string459;string460;string461;string462;string463;string464;string465;string466;string467;string468;string469;string470;string471;string472;string473;string474;string475;string476;string477;string478;string479;string480;string481;string482;string483;string484;string485;string486;string487;string488;string489;string490;string491;string492;string493;string494;string495;string496;string497;string498;string499;string500;string501;string502;string503;string504;string505;string506;string507;string508;string509;string510;string511;string512;string513;string514;string515;string516;string517;string518;string519;string520;string521;string522;string523;string524;string525;string526;string527;string528;string529;string530;string531;string532;string533;string534;string535;string536;string537;string538;string539;string540;string541;string542;string543;string544;string545;string546;string547;string548;string549;string550;string551;string552;string553;string554;string555;string556;string557;string558;string559;string560;string561;string562;string563;string564;string565;string566;string567;string568;string569;string570;string571;string572;string573;string574;string575;string576;string577;string578;string579;string580;string581;string582;string583;string584;string585;string586;string587;string588;string589;string590;string591;string592;string593;string594;string595;string596;string597;string598;string599;string600;string601;string602;string603;string604;string605;string606;string607;string608;string609;string610;string611;string612;string613;string614;string615;string616;string617;string618;string619;string620;string621;string622;string623;string624;string625;string626;string627;string628;string629;string630;string631;string632;string633;string634;string635;string636;string637;string638;string639;string640;string641;string642;string643;string644;string645;string646;string647;string648;string649;string650;string651;string652;string653;string654;string655;string656;string657;string658;string659;string660;string661;string662;string663;string664;string665;string666;string667;string668;string669;string670;string671;string672;string673;string674;string675;string676;string677;string678;string679;string680;string681;string682;string683;string684;string685;string686;string687;string688;string689;string690;string691;string692;string693;string694;string695;string696;string697;string698;string699;string700;string701;string702;string703;string704;string705;string706;string707;string708;string709;string710;string711;string712;string713;string714;string715;string716;string717;string718;string719;string720;string721;string722;string723;string724;string725;string726;string727;string728;string729;string730;string731;string732;string733;string734;string735;string736;string737;string738;string739;string740;string741;string742;string743;string744;string745;string746;string747;string748;string749;string750;string751;string752;string753;string754;string755;string756;string757;string758;string759;string760;string761;string762;string763;string764;string765;string766;string767;string768;string769;string770;string771;string772;string773;string774;string775;string776;string777;string778;string779;string780;string781;string782;string783;string784;string785;string786;string787;string788;string789;string790;string791;string792;string793;string794;string795;string796;string797;string798;string799;string800;string801;string802;string803;string804;string805;string806;string807;string808;string809;string810;string811;string812;string813;string814;string815;string816;string817;string818;string819;string820;string821;string822;string823;string824;string825;string826;string827;string828;string829;string830;string831;string832;string833;string834;string835;string836;string837;string838;string839;string840;string841;string842;string843;string844;string845;string846;string847;string848;string849;string850;string851;string852;string853;string854;string855;string856;string857;string858;string859;string860;string861;string862;string863;string864;string865;string866;string867;string868;string869;string870;string871;string872;string873;string874;string875;string876;string877;string878;string879;string880;string881;string882;string883;string884;string885;string886;string887;string888;string889;string890;string891;string892;string893;string894;string895;string896;string897;string898;string899;string900;string901;string902;string903;string904;string905;string906;string907;string908;string909;string910;string911;string912;string913;string914;string915;string916;string917;string918;string919;string920;string921;string922;string923;string924;string925;string926;string927;string928;string929;string930;string931;string932;string933;string934;string935;string936;string937;string938;string939;string940;string941;string942;string943;string944;string945;string946;string947;string948;string949;string950;string951;string952;string953;string954;string955;string956;string957;string958;string959;string960;string961;string962;string963;string964;string965;string966;string967;string968;string969;string970;string971;string972;string973;string974;string975;string976;string977;string978;string979;string980;string981;string982;string983;string984;string985;string986;string987;string988;string989;string990;string991;string992;string993;string994;string995;string996;string997;string998;string9
+start;ing0;ing1;ing2;ing3;ing4;ing5;ing6;ing7;ing8;ing9;ing10;ing11;ing12;ing13;ing14;ing15;ing16;ing17;ing18;ing19;ing20;ing21;ing22;ing23;ing24;ing25;ing26;ing27;ing28;ing29;ing30;ing31;ing32;ing33;ing34;ing35;ing36;ing37;ing38;ing39;ing40;ing41;ing42;ing43;ing44;ing45;ing46;ing47;ing48;ing49;ing50;ing51;ing52;ing53;ing54;ing55;ing56;ing57;ing58;ing59;ing60;ing61;ing62;ing63;ing64;ing65;ing66;ing67;ing68;ing69;ing70;ing71;ing72;ing73;ing74;ing75;ing76;ing77;ing78;ing79;ing80;ing81;ing82;ing83;ing84;ing85;ing86;ing87;ing88;ing89;ing90;ing91;ing92;ing93;ing94;ing95;ing96;ing97;ing98;ing99;ing100;ing101;ing102;ing103;ing104;ing105;ing106;ing107;ing108;ing109;ing110;ing111;ing112;ing113;ing114;ing115;ing116;ing117;ing118;ing119;ing120;ing121;ing122;ing123;ing124;ing125;ing126;ing127;ing128;ing129;ing130;ing131;ing132;ing133;ing134;ing135;ing136;ing137;ing138;ing139;ing140;ing141;ing142;ing143;ing144;ing145;ing146;ing147;ing148;ing149;ing150;ing151;ing152;ing153;ing154;ing155;ing156;ing157;ing158;ing159;ing160;ing161;ing162;ing163;ing164;ing165;ing166;ing167;ing168;ing169;ing170;ing171;ing172;ing173;ing174;ing175;ing176;ing177;ing178;ing179;ing180;ing181;ing182;ing183;ing184;ing185;ing186;ing187;ing188;ing189;ing190;ing191;ing192;ing193;ing194;ing195;ing196;ing197;ing198;ing199;ing200;ing201;ing202;ing203;ing204;ing205;ing206;ing207;ing208;ing209;ing210;ing211;ing212;ing213;ing214;ing215;ing216;ing217;ing218;ing219;ing220;ing221;ing222;ing223;ing224;ing225;ing226;ing227;ing228;ing229;ing230;ing231;ing232;ing233;ing234;ing235;ing236;ing237;ing238;ing239;ing240;ing241;ing242;ing243;ing244;ing245;ing246;ing247;ing248;ing249;ing250;ing251;ing252;ing253;ing254;ing255;ing256;ing257;ing258;ing259;ing260;ing261;ing262;ing263;ing264;ing265;ing266;ing267;ing268;ing269;ing270;ing271;ing272;ing273;ing274;ing275;ing276;ing277;ing278;ing279;ing280;ing281;ing282;ing283;ing284;ing285;ing286;ing287;ing288;ing289;ing290;ing291;ing292;ing293;ing294;ing295;ing296;ing297;ing298;ing299;ing300;ing301;ing302;ing303;ing304;ing305;ing306;ing307;ing308;ing309;ing310;ing311;ing312;ing313;ing314;ing315;ing316;ing317;ing318;ing319;ing320;ing321;ing322;ing323;ing324;ing325;ing326;ing327;ing328;ing329;ing330;ing331;ing332;ing333;ing334;ing335;ing336;ing337;ing338;ing339;ing340;ing341;ing342;ing343;ing344;ing345;ing346;ing347;ing348;ing349;ing350;ing351;ing352;ing353;ing354;ing355;ing356;ing357;ing358;ing359;ing360;ing361;ing362;ing363;ing364;ing365;ing366;ing367;ing368;ing369;ing370;ing371;ing372;ing373;ing374;ing375;ing376;ing377;ing378;ing379;ing380;ing381;ing382;ing383;ing384;ing385;ing386;ing387;ing388;ing389;ing390;ing391;ing392;ing393;ing394;ing395;ing396;ing397;ing398;ing399;ing400;ing401;ing402;ing403;ing404;ing405;ing406;ing407;ing408;ing409;ing410;ing411;ing412;ing413;ing414;ing415;ing416;ing417;ing418;ing419;ing420;ing421;ing422;ing423;ing424;ing425;ing426;ing427;ing428;ing429;ing430;ing431;ing432;ing433;ing434;ing435;ing436;ing437;ing438;ing439;ing440;ing441;ing442;ing443;ing444;ing445;ing446;ing447;ing448;ing449;ing450;ing451;ing452;ing453;ing454;ing455;ing456;ing457;ing458;ing459;ing460;ing461;ing462;ing463;ing464;ing465;ing466;ing467;ing468;ing469;ing470;ing471;ing472;ing473;ing474;ing475;ing476;ing477;ing478;ing479;ing480;ing481;ing482;ing483;ing484;ing485;ing486;ing487;ing488;ing489;ing490;ing491;ing492;ing493;ing494;ing495;ing496;ing497;ing498;ing499;ing500;ing501;ing502;ing503;ing504;ing505;ing506;ing507;ing508;ing509;ing510;ing511;ing512;ing513;ing514;ing515;ing516;ing517;ing518;ing519;ing520;ing521;ing522;ing523;ing524;ing525;ing526;ing527;ing528;ing529;ing530;ing531;ing532;ing533;ing534;ing535;ing536;ing537;ing538;ing539;ing540;ing541;ing542;ing543;ing544;ing545;ing546;ing547;ing548;ing549;ing550;ing551;ing552;ing553;ing554;ing555;ing556;ing557;ing558;ing559;ing560;ing561;ing562;ing563;ing564;ing565;ing566;ing567;ing568;ing569;ing570;ing571;ing572;ing573;ing574;ing575;ing576;ing577;ing578;ing579;ing580;ing581;ing582;ing583;ing584;ing585;ing586;ing587;ing588;ing589;ing590;ing591;ing592;ing593;ing594;ing595;ing596;ing597;ing598;ing599;ing600;ing601;ing602;ing603;ing604;ing605;ing606;ing607;ing608;ing609;ing610;ing611;ing612;ing613;ing614;ing615;ing616;ing617;ing618;ing619;ing620;ing621;ing622;ing623;ing624;ing625;ing626;ing627;ing628;ing629;ing630;ing631;ing632;ing633;ing634;ing635;ing636;ing637;ing638;ing639;ing640;ing641;ing642;ing643;ing644;ing645;ing646;ing647;ing648;ing649;ing650;ing651;ing652;ing653;ing654;ing655;ing656;ing657;ing658;ing659;ing660;ing661;ing662;ing663;ing664;ing665;ing666;ing667;ing668;ing669;ing670;ing671;ing672;ing673;ing674;ing675;ing676;ing677;ing678;ing679;ing680;ing681;ing682;ing683;ing684;ing685;ing686;ing687;ing688;ing689;ing690;ing691;ing692;ing693;ing694;ing695;ing696;ing697;ing698;ing699;ing700;ing701;ing702;ing703;ing704;ing705;ing706;ing707;ing708;ing709;ing710;ing711;ing712;ing713;ing714;ing715;ing716;ing717;ing718;ing719;ing720;ing721;ing722;ing723;ing724;ing725;ing726;ing727;ing728;ing729;ing730;ing731;ing732;ing733;ing734;ing735;ing736;ing737;ing738;ing739;ing740;ing741;ing742;ing743;ing744;ing745;ing746;ing747;ing748;ing749;ing750;ing751;ing752;ing753;ing754;ing755;ing756;ing757;ing758;ing759;ing760;ing761;ing762;ing763;ing764;ing765;ing766;ing767;ing768;ing769;ing770;ing771;ing772;ing773;ing774;ing775;ing776;ing777;ing778;ing779;ing780;ing781;ing782;ing783;ing784;ing785;ing786;ing787;ing788;ing789;ing790;ing791;ing792;ing793;ing794;ing795;ing796;ing797;ing798;ing799;ing800;ing801;ing802;ing803;ing804;ing805;ing806;ing807;ing808;ing809;ing810;ing811;ing812;ing813;ing814;ing815;ing816;ing817;ing818;ing819;ing820;ing821;ing822;ing823;ing824;ing825;ing826;ing827;ing828;ing829;ing830;ing831;ing832;ing833;ing834;ing835;ing836;ing837;ing838;ing839;ing840;ing841;ing842;ing843;ing844;ing845;ing846;ing847;ing848;ing849;ing850;ing851;ing852;ing853;ing854;ing855;ing856;ing857;ing858;ing859;ing860;ing861;ing862;ing863;ing864;ing865;ing866;ing867;ing868;ing869;ing870;ing871;ing872;ing873;ing874;ing875;ing876;ing877;ing878;ing879;ing880;ing881;ing882;ing883;ing884;ing885;ing886;ing887;ing888;ing889;ing890;ing891;ing892;ing893;ing894;ing895;ing896;ing897;ing898;ing899;ing900;ing901;ing902;ing903;ing904;ing905;ing906;ing907;ing908;ing909;ing910;ing911;ing912;ing913;ing914;ing915;ing916;ing917;ing918;ing919;ing920;ing921;ing922;ing923;ing924;ing925;ing926;ing927;ing928;ing929;ing930;ing931;ing932;ing933;ing934;ing935;ing936;ing937;ing938;ing939;ing940;ing941;ing942;ing943;ing944;ing945;ing946;ing947;ing948;ing949;ing950;ing951;ing952;ing953;ing954;ing955;ing956;ing957;ing958;ing959;ing960;ing961;ing962;ing963;ing964;ing965;ing966;ing967;ing968;ing969;ing970;ing971;ing972;ing973;ing974;ing975;ing976;ing977;ing978;ing979;ing980;ing981;ing982;ing983;ing984;ing985;ing986;ing987;ing988;ing989;ing990;ing991;ing992;ing993;ing994;ing995;ing996;ing997;ing998;ing999
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+start;string0;string1;string2;string3;string4;string5;string6;string7;string8;string9;string10;string11;string12;string13;string14;string15;string16;string17;string18;string19;string20;string21;string22;string23;string24;string25;string26;string27;string28;string29;string30;string31;string32;string33;string34;string35;string36;string37;string38;string39;string40;string41;string42;string43;string44;string45;string46;string47;string48;string49;string50;string51;string52;string53;string54;string55;string56;string57;string58;string59;string60;string61;string62;string63;string64;string65;string66;string67;string68;string69;string70;string71;string72;string73;string74;string75;string76;string77;string78;string79;string80;string81;string82;string83;string84;string85;string86;string87;string88;string89;string90;string91;string92;string93;string94;string95;string96;string97;string98;string99;string100;string101;string102;string103;string104;string105;string106;string107;string108;string109;string110;string111;string112;string113;string114;string115;string116;string117;string118;string119;string120;string121;string122;string123;string124;string125;string126;string127;string128;string129;string130;string131;string132;string133;string134;string135;string136;string137;string138;string139;string140;string141;string142;string143;string144;string145;string146;string147;string148;string149;string150;string151;string152;string153;string154;string155;string156;string157;string158;string159;string160;string161;string162;string163;string164;string165;string166;string167;string168;string169;string170;string171;string172;string173;string174;string175;string176;string177;string178;string179;string180;string181;string182;string183;string184;string185;string186;string187;string188;string189;string190;string191;string192;string193;string194;string195;string196;string197;string198;string199;string200;string201;string202;string203;string204;string205;string206;string207;string208;string209;string210;string211;string212;string213;string214;string215;string216;string217;string218;string219;string220;string221;string222;string223;string224;string225;string226;string227;string228;string229;string230;string231;string232;string233;string234;string235;string236;string237;string238;string239;string240;string241;string242;string243;string244;string245;string246;string247;string248;string249;string250;string251;string252;string253;string254;string255;string256;string257;string258;string259;string260;string261;string262;string263;string264;string265;string266;string267;string268;string269;string270;string271;string272;string273;string274;string275;string276;string277;string278;string279;string280;string281;string282;string283;string284;string285;string286;string287;string288;string289;string290;string291;string292;string293;string294;string295;string296;string297;string298;string299;string300;string301;string302;string303;string304;string305;string306;string307;string308;string309;string310;string311;string312;string313;string314;string315;string316;string317;string318;string319;string320;string321;string322;string323;string324;string325;string326;string327;string328;string329;string330;string331;string332;string333;string334;string335;string336;string337;string338;string339;string340;string341;string342;string343;string344;string345;string346;string347;string348;string349;string350;string351;string352;string353;string354;string355;string356;string357;string358;string359;string360;string361;string362;string363;string364;string365;string366;string367;string368;string369;string370;string371;string372;string373;string374;string375;string376;string377;string378;string379;string380;string381;string382;string383;string384;string385;string386;string387;string388;string389;string390;string391;string392;string393;string394;string395;string396;string397;string398;string399;string400;string401;string402;string403;string404;string405;string406;string407;string408;string409;string410;string411;string412;string413;string414;string415;string416;string417;string418;string419;string420;string421;string422;string423;string424;string425;string426;string427;string428;string429;string430;string431;string432;string433;string434;string435;string436;string437;string438;string439;string440;string441;string442;string443;string444;string445;string446;string447;string448;string449;string450;string451;string452;string453;string454;string455;string456;string457;string458;string459;string460;string461;string462;string463;string464;string465;string466;string467;string468;string469;string470;string471;string472;string473;string474;string475;string476;string477;string478;string479;string480;string481;string482;string483;string484;string485;string486;string487;string488;string489;string490;string491;string492;string493;string494;string495;string496;string497;string498;string499;string500;string501;string502;string503;string504;string505;string506;string507;string508;string509;string510;string511;string512;string513;string514;string515;string516;string517;string518;string519;string520;string521;string522;string523;string524;string525;string526;string527;string528;string529;string530;string531;string532;string533;string534;string535;string536;string537;string538;string539;string540;string541;string542;string543;string544;string545;string546;string547;string548;string549;string550;string551;string552;string553;string554;string555;string556;string557;string558;string559;string560;string561;string562;string563;string564;string565;string566;string567;string568;string569;string570;string571;string572;string573;string574;string575;string576;string577;string578;string579;string580;string581;string582;string583;string584;string585;string586;string587;string588;string589;string590;string591;string592;string593;string594;string595;string596;string597;string598;string599;string600;string601;string602;string603;string604;string605;string606;string607;string608;string609;string610;string611;string612;string613;string614;string615;string616;string617;string618;string619;string620;string621;string622;string623;string624;string625;string626;string627;string628;string629;string630;string631;string632;string633;string634;string635;string636;string637;string638;string639;string640;string641;string642;string643;string644;string645;string646;string647;string648;string649;string650;string651;string652;string653;string654;string655;string656;string657;string658;string659;string660;string661;string662;string663;string664;string665;string666;string667;string668;string669;string670;string671;string672;string673;string674;string675;string676;string677;string678;string679;string680;string681;string682;string683;string684;string685;string686;string687;string688;string689;string690;string691;string692;string693;string694;string695;string696;string697;string698;string699;string700;string701;string702;string703;string704;string705;string706;string707;string708;string709;string710;string711;string712;string713;string714;string715;string716;string717;string718;string719;string720;string721;string722;string723;string724;string725;string726;string727;string728;string729;string730;string731;string732;string733;string734;string735;string736;string737;string738;string739;string740;string741;string742;string743;string744;string745;string746;string747;string748;string749;string750;string751;string752;string753;string754;string755;string756;string757;string758;string759;string760;string761;string762;string763;string764;string765;string766;string767;string768;string769;string770;string771;string772;string773;string774;string775;string776;string777;string778;string779;string780;string781;string782;string783;string784;string785;string786;string787;string788;string789;string790;string791;string792;string793;string794;string795;string796;string797;string798;string799;string800;string801;string802;string803;string804;string805;string806;string807;string808;string809;string810;string811;string812;string813;string814;string815;string816;string817;string818;string819;string820;string821;string822;string823;string824;string825;string826;string827;string828;string829;string830;string831;string832;string833;string834;string835;string836;string837;string838;string839;string840;string841;string842;string843;string844;string845;string846;string847;string848;string849;string850;string851;string852;string853;string854;string855;string856;string857;string858;string859;string860;string861;string862;string863;string864;string865;string866;string867;string868;string869;string870;string871;string872;string873;string874;string875;string876;string877;string878;string879;string880;string881;string882;string883;string884;string885;string886;string887;string888;string889;string890;string891;string892;string893;string894;string895;string896;string897;string898;string899;string900;string901;string902;string903;string904;string905;string906;string907;string908;string909;string910;string911;string912;string913;string914;string915;string916;string917;string918;string919;string920;string921;string922;string923;string924;string925;string926;string927;string928;string929;string930;string931;string932;string933;string934;string935;string936;string937;string938;string939;string940;string941;string942;string943;string944;string945;string946;string947;string948;string949;string950;string951;string952;string953;string954;string955;string956;string957;string958;string959;string960;string961;string962;string963;string964;string965;string966;string967;string968;string969;string970;string971;string972;string973;string974;string975;string976;string977;string978;string979;string980;string981;string982;string983;string984;string985;string986;string987;string988;string989;string990;string991;string992;string993;string994;string995;string996;string997;string998;string999
+start;ing0;ing1;ing2;ing3;ing4;ing5;ing6;ing7;ing8;ing9;ing10;ing11;ing12;ing13;ing14;ing15;ing16;ing17;ing18;ing19;ing20;ing21;ing22;ing23;ing24;ing25;ing26;ing27;ing28;ing29;ing30;ing31;ing32;ing33;ing34;ing35;ing36;ing37;ing38;ing39;ing40;ing41;ing42;ing43;ing44;ing45;ing46;ing47;ing48;ing49;ing50;ing51;ing52;ing53;ing54;ing55;ing56;ing57;ing58;ing59;ing60;ing61;ing62;ing63;ing64;ing65;ing66;ing67;ing68;ing69;ing70;ing71;ing72;ing73;ing74;ing75;ing76;ing77;ing78;ing79;ing80;ing81;ing82;ing83;ing84;ing85;ing86;ing87;ing88;ing89;ing90;ing91;ing92;ing93;ing94;ing95;ing96;ing97;ing98;ing99;ing100;ing101;ing102;ing103;ing104;ing105;ing106;ing107;ing108;ing109;ing110;ing111;ing112;ing113;ing114;ing115;ing116;ing117;ing118;ing119;ing120;ing121;ing122;ing123;ing124;ing125;ing126;ing127;ing128;ing129;ing130;ing131;ing132;ing133;ing134;ing135;ing136;ing137;ing138;ing139;ing140;ing141;ing142;ing143;ing144;ing145;ing146;ing147;ing148;ing149;ing150;ing151;ing152;ing153;ing154;ing155;ing156;ing157;ing158;ing159;ing160;ing161;ing162;ing163;ing164;ing165;ing166;ing167;ing168;ing169;ing170;ing171;ing172;ing173;ing174;ing175;ing176;ing177;ing178;ing179;ing180;ing181;ing182;ing183;ing184;ing185;ing186;ing187;ing188;ing189;ing190;ing191;ing192;ing193;ing194;ing195;ing196;ing197;ing198;ing199;ing200;ing201;ing202;ing203;ing204;ing205;ing206;ing207;ing208;ing209;ing210;ing211;ing212;ing213;ing214;ing215;ing216;ing217;ing218;ing219;ing220;ing221;ing222;ing223;ing224;ing225;ing226;ing227;ing228;ing229;ing230;ing231;ing232;ing233;ing234;ing235;ing236;ing237;ing238;ing239;ing240;ing241;ing242;ing243;ing244;ing245;ing246;ing247;ing248;ing249;ing250;ing251;ing252;ing253;ing254;ing255;ing256;ing257;ing258;ing259;ing260;ing261;ing262;ing263;ing264;ing265;ing266;ing267;ing268;ing269;ing270;ing271;ing272;ing273;ing274;ing275;ing276;ing277;ing278;ing279;ing280;ing281;ing282;ing283;ing284;ing285;ing286;ing287;ing288;ing289;ing290;ing291;ing292;ing293;ing294;ing295;ing296;ing297;ing298;ing299;ing300;ing301;ing302;ing303;ing304;ing305;ing306;ing307;ing308;ing309;ing310;ing311;ing312;ing313;ing314;ing315;ing316;ing317;ing318;ing319;ing320;ing321;ing322;ing323;ing324;ing325;ing326;ing327;ing328;ing329;ing330;ing331;ing332;ing333;ing334;ing335;ing336;ing337;ing338;ing339;ing340;ing341;ing342;ing343;ing344;ing345;ing346;ing347;ing348;ing349;ing350;ing351;ing352;ing353;ing354;ing355;ing356;ing357;ing358;ing359;ing360;ing361;ing362;ing363;ing364;ing365;ing366;ing367;ing368;ing369;ing370;ing371;ing372;ing373;ing374;ing375;ing376;ing377;ing378;ing379;ing380;ing381;ing382;ing383;ing384;ing385;ing386;ing387;ing388;ing389;ing390;ing391;ing392;ing393;ing394;ing395;ing396;ing397;ing398;ing399;ing400;ing401;ing402;ing403;ing404;ing405;ing406;ing407;ing408;ing409;ing410;ing411;ing412;ing413;ing414;ing415;ing416;ing417;ing418;ing419;ing420;ing421;ing422;ing423;ing424;ing425;ing426;ing427;ing428;ing429;ing430;ing431;ing432;ing433;ing434;ing435;ing436;ing437;ing438;ing439;ing440;ing441;ing442;ing443;ing444;ing445;ing446;ing447;ing448;ing449;ing450;ing451;ing452;ing453;ing454;ing455;ing456;ing457;ing458;ing459;ing460;ing461;ing462;ing463;ing464;ing465;ing466;ing467;ing468;ing469;ing470;ing471;ing472;ing473;ing474;ing475;ing476;ing477;ing478;ing479;ing480;ing481;ing482;ing483;ing484;ing485;ing486;ing487;ing488;ing489;ing490;ing491;ing492;ing493;ing494;ing495;ing496;ing497;ing498;ing499;ing500;ing501;ing502;ing503;ing504;ing505;ing506;ing507;ing508;ing509;ing510;ing511;ing512;ing513;ing514;ing515;ing516;ing517;ing518;ing519;ing520;ing521;ing522;ing523;ing524;ing525;ing526;ing527;ing528;ing529;ing530;ing531;ing532;ing533;ing534;ing535;ing536;ing537;ing538;ing539;ing540;ing541;ing542;ing543;ing544;ing545;ing546;ing547;ing548;ing549;ing550;ing551;ing552;ing553;ing554;ing555;ing556;ing557;ing558;ing559;ing560;ing561;ing562;ing563;ing564;ing565;ing566;ing567;ing568;ing569;ing570;ing571;ing572;ing573;ing574;ing575;ing576;ing577;ing578;ing579;ing580;ing581;ing582;ing583;ing584;ing585;ing586;ing587;ing588;ing589;ing590;ing591;ing592;ing593;ing594;ing595;ing596;ing597;ing598;ing599;ing600;ing601;ing602;ing603;ing604;ing605;ing606;ing607;ing608;ing609;ing610;ing611;ing612;ing613;ing614;ing615;ing616;ing617;ing618;ing619;ing620;ing621;ing622;ing623;ing624;ing625;ing626;ing627;ing628;ing629;ing630;ing631;ing632;ing633;ing634;ing635;ing636;ing637;ing638;ing639;ing640;ing641;ing642;ing643;ing644;ing645;ing646;ing647;ing648;ing649;ing650;ing651;ing652;ing653;ing654;ing655;ing656;ing657;ing658;ing659;ing660;ing661;ing662;ing663;ing664;ing665;ing666;ing667;ing668;ing669;ing670;ing671;ing672;ing673;ing674;ing675;ing676;ing677;ing678;ing679;ing680;ing681;ing682;ing683;ing684;ing685;ing686;ing687;ing688;ing689;ing690;ing691;ing692;ing693;ing694;ing695;ing696;ing697;ing698;ing699;ing700;ing701;ing702;ing703;ing704;ing705;ing706;ing707;ing708;ing709;ing710;ing711;ing712;ing713;ing714;ing715;ing716;ing717;ing718;ing719;ing720;ing721;ing722;ing723;ing724;ing725;ing726;ing727;ing728;ing729;ing730;ing731;ing732;ing733;ing734;ing735;ing736;ing737;ing738;ing739;ing740;ing741;ing742;ing743;ing744;ing745;ing746;ing747;ing748;ing749;ing750;ing751;ing752;ing753;ing754;ing755;ing756;ing757;ing758;ing759;ing760;ing761;ing762;ing763;ing764;ing765;ing766;ing767;ing768;ing769;ing770;ing771;ing772;ing773;ing774;ing775;ing776;ing777;ing778;ing779;ing780;ing781;ing782;ing783;ing784;ing785;ing786;ing787;ing788;ing789;ing790;ing791;ing792;ing793;ing794;ing795;ing796;ing797;ing798;ing799;ing800;ing801;ing802;ing803;ing804;ing805;ing806;ing807;ing808;ing809;ing810;ing811;ing812;ing813;ing814;ing815;ing816;ing817;ing818;ing819;ing820;ing821;ing822;ing823;ing824;ing825;ing826;ing827;ing828;ing829;ing830;ing831;ing832;ing833;ing834;ing835;ing836;ing837;ing838;ing839;ing840;ing841;ing842;ing843;ing844;ing845;ing846;ing847;ing848;ing849;ing850;ing851;ing852;ing853;ing854;ing855;ing856;ing857;ing858;ing859;ing860;ing861;ing862;ing863;ing864;ing865;ing866;ing867;ing868;ing869;ing870;ing871;ing872;ing873;ing874;ing875;ing876;ing877;ing878;ing879;ing880;ing881;ing882;ing883;ing884;ing885;ing886;ing887;ing888;ing889;ing890;ing891;ing892;ing893;ing894;ing895;ing896;ing897;ing898;ing899;ing900;ing901;ing902;ing903;ing904;ing905;ing906;ing907;ing908;ing909;ing910;ing911;ing912;ing913;ing914;ing915;ing916;ing917;ing918;ing919;ing920;ing921;ing922;ing923;ing924;ing925;ing926;ing927;ing928;ing929;ing930;ing931;ing932;ing933;ing934;ing935;ing936;ing937;ing938;ing939;ing940;ing941;ing942;ing943;ing944;ing945;ing946;ing947;ing948;ing949;ing950;ing951;ing952;ing953;ing954;ing955;ing956;ing957;ing958;ing959;ing960;ing961;ing962;ing963;ing964;ing965;ing966;ing967;ing968;ing969;ing970;ing971;ing972;ing973;ing974;ing975;ing976;ing977;ing978;ing979;ing980;ing981;ing982;ing983;ing984;ing985;ing986;ing987;ing988;ing989;ing990;ing991;ing992;ing993;ing994;ing995;ing996;ing997;ing998;ing999
+start;string0;string1;string2;string3;string4;string5;string6;string7;string8;string9;string10;string11;string12;string13;string14;string15;string16;string17;string18;string19;string20;string21;string22;string23;string24;string25;string26;string27;string28;string29;string30;string31;string32;string33;string34;string35;string36;string37;string38;string39;string40;string41;string42;string43;string44;string45;string46;string47;string48;string49;string50;string51;string52;string53;string54;string55;string56;string57;string58;string59;string60;string61;string62;string63;string64;string65;string66;string67;string68;string69;string70;string71;string72;string73;string74;string75;string76;string77;string78;string79;string80;string81;string82;string83;string84;string85;string86;string87;string88;string89;string90;string91;string92;string93;string94;string95;string96;string97;string98;string99;string100;string101;string102;string103;string104;string105;string106;string107;string108;string109;string110;string111;string112;string113;string114;string115;string116;string117;string118;string119;string120;string121;string122;string123;string124;string125;string126;string127;string128;string129;string130;string131;string132;string133;string134;string135;string136;string137;string138;string139;string140;string141;string142;string143;string144;string145;string146;string147;string148;string149;string150;string151;string152;string153;string154;string155;string156;string157;string158;string159;string160;string161;string162;string163;string164;string165;string166;string167;string168;string169;string170;string171;string172;string173;string174;string175;string176;string177;string178;string179;string180;string181;string182;string183;string184;string185;string186;string187;string188;string189;string190;string191;string192;string193;string194;string195;string196;string197;string198;string199;string200;string201;string202;string203;string204;string205;string206;string207;string208;string209;string210;string211;string212;string213;string214;string215;string216;string217;string218;string219;string220;string221;string222;string223;string224;string225;string226;string227;string228;string229;string230;string231;string232;string233;string234;string235;string236;string237;string238;string239;string240;string241;string242;string243;string244;string245;string246;string247;string248;string249;string250;string251;string252;string253;string254;string255;string256;string257;string258;string259;string260;string261;string262;string263;string264;string265;string266;string267;string268;string269;string270;string271;string272;string273;string274;string275;string276;string277;string278;string279;string280;string281;string282;string283;string284;string285;string286;string287;string288;string289;string290;string291;string292;string293;string294;string295;string296;string297;string298;string299;string300;string301;string302;string303;string304;string305;string306;string307;string308;string309;string310;string311;string312;string313;string314;string315;string316;string317;string318;string319;string320;string321;string322;string323;string324;string325;string326;string327;string328;string329;string330;string331;string332;string333;string334;string335;string336;string337;string338;string339;string340;string341;string342;string343;string344;string345;string346;string347;string348;string349;string350;string351;string352;string353;string354;string355;string356;string357;string358;string359;string360;string361;string362;string363;string364;string365;string366;string367;string368;string369;string370;string371;string372;string373;string374;string375;string376;string377;string378;string379;string380;string381;string382;string383;string384;string385;string386;string387;string388;string389;string390;string391;string392;string393;string394;string395;string396;string397;string398;string399;string400;string401;string402;string403;string404;string405;string406;string407;string408;string409;string410;string411;string412;string413;string414;string415;string416;string417;string418;string419;string420;string421;string422;string423;string424;string425;string426;string427;string428;string429;string430;string431;string432;string433;string434;string435;string436;string437;string438;string439;string440;string441;string442;string443;string444;string445;string446;string447;string448;string449;string450;string451;string452;string453;string454;string455;string456;string457;string458;string459;string460;string461;string462;string463;string464;string465;string466;string467;string468;string469;string470;string471;string472;string473;string474;string475;string476;string477;string478;string479;string480;string481;string482;string483;string484;string485;string486;string487;string488;string489;string490;string491;string492;string493;string494;string495;string496;string497;string498;string499;string500;string501;string502;string503;string504;string505;string506;string507;string508;string509;string510;string511;string512;string513;string514;string515;string516;string517;string518;string519;string520;string521;string522;string523;string524;string525;string526;string527;string528;string529;string530;string531;string532;string533;string534;string535;string536;string537;string538;string539;string540;string541;string542;string543;string544;string545;string546;string547;string548;string549;string550;string551;string552;string553;string554;string555;string556;string557;string558;string559;string560;string561;string562;string563;string564;string565;string566;string567;string568;string569;string570;string571;string572;string573;string574;string575;string576;string577;string578;string579;string580;string581;string582;string583;string584;string585;string586;string587;string588;string589;string590;string591;string592;string593;string594;string595;string596;string597;string598;string599;string600;string601;string602;string603;string604;string605;string606;string607;string608;string609;string610;string611;string612;string613;string614;string615;string616;string617;string618;string619;string620;string621;string622;string623;string624;string625;string626;string627;string628;string629;string630;string631;string632;string633;string634;string635;string636;string637;string638;string639;string640;string641;string642;string643;string644;string645;string646;string647;string648;string649;string650;string651;string652;string653;string654;string655;string656;string657;string658;string659;string660;string661;string662;string663;string664;string665;string666;string667;string668;string669;string670;string671;string672;string673;string674;string675;string676;string677;string678;string679;string680;string681;string682;string683;string684;string685;string686;string687;string688;string689;string690;string691;string692;string693;string694;string695;string696;string697;string698;string699;string700;string701;string702;string703;string704;string705;string706;string707;string708;string709;string710;string711;string712;string713;string714;string715;string716;string717;string718;string719;string720;string721;string722;string723;string724;string725;string726;string727;string728;string729;string730;string731;string732;string733;string734;string735;string736;string737;string738;string739;string740;string741;string742;string743;string744;string745;string746;string747;string748;string749;string750;string751;string752;string753;string754;string755;string756;string757;string758;string759;string760;string761;string762;string763;string764;string765;string766;string767;string768;string769;string770;string771;string772;string773;string774;string775;string776;string777;string778;string779;string780;string781;string782;string783;string784;string785;string786;string787;string788;string789;string790;string791;string792;string793;string794;string795;string796;string797;string798;string799;string800;string801;string802;string803;string804;string805;string806;string807;string808;string809;string810;string811;string812;string813;string814;string815;string816;string817;string818;string819;string820;string821;string822;string823;string824;string825;string826;string827;string828;string829;string830;string831;string832;string833;string834;string835;string836;string837;string838;string839;string840;string841;string842;string843;string844;string845;string846;string847;string848;string849;string850;string851;string852;string853;string854;string855;string856;string857;string858;string859;string860;string861;string862;string863;string864;string865;string866;string867;string868;string869;string870;string871;string872;string873;string874;string875;string876;string877;string878;string879;string880;string881;string882;string883;string884;string885;string886;string887;string888;string889;string890;string891;string892;string893;string894;string895;string896;string897;string898;string899;string900;string901;string902;string903;string904;string905;string906;string907;string908;string909;string910;string911;string912;string913;string914;string915;string916;string917;string918;string919;string920;string921;string922;string923;string924;string925;string926;string927;string928;string929;string930;string931;string932;string933;string934;string935;string936;string937;string938;string939;string940;string941;string942;string943;string944;string945;string946;string947;string948;string949;string950;string951;string952;string953;string954;string955;string956;string957;string958;string959;string960;string961;string962;string963;string964;string965;string966;string967;string968;string969;string970;string971;string972;string973;string974;string975;string976;string977;string978;string979;string980;string981;string982;string983;string984;string985;string986;string987;string988;string989;string990;string991;string992;string993;string994;string995;string996;string997;string998;string999
+start;string0;string1;string2;string3;string4;string5;string6;string7;string8;string9;string10;string11;string12;string13;string14;string15;string16;string17;string18;string19;string20;string21;string22;string23;string24;string25;string26;string27;string28;string29;string30;string31;string32;string33;string34;string35;string36;string37;string38;string39;string40;string41;string42;string43;string44;string45;string46;string47;string48;string49;string50;string51;string52;string53;string54;string55;string56;string57;string58;string59;string60;string61;string62;string63;string64;string65;string66;string67;string68;string69;string70;string71;string72;string73;string74;string75;string76;string77;string78;string79;string80;string81;string82;string83;string84;string85;string86;string87;string88;string89;string90;string91;string92;string93;string94;string95;string96;string97;string98;string99;string100;string101;string102;string103;string104;string105;string106;string107;string108;string109;string110;string111;string112;string113;string114;string115;string116;string117;string118;string119;string120;string121;string122;string123;string124;string125;string126;string127;string128;string129;string130;string131;string132;string133;string134;string135;string136;string137;string138;string139;string140;string141;string142;string143;string144;string145;string146;string147;string148;string149;string150;string151;string152;string153;string154;string155;string156;string157;string158;string159;string160;string161;string162;string163;string164;string165;string166;string167;string168;string169;string170;string171;string172;string173;string174;string175;string176;string177;string178;string179;string180;string181;string182;string183;string184;string185;string186;string187;string188;string189;string190;string191;string192;string193;string194;string195;string196;string197;string198;string199;string200;string201;string202;string203;string204;string205;string206;string207;string208;string209;string210;string211;string212;string213;string214;string215;string216;string217;string218;string219;string220;string221;string222;string223;string224;string225;string226;string227;string228;string229;string230;string231;string232;string233;string234;string235;string236;string237;string238;string239;string240;string241;string242;string243;string244;string245;string246;string247;string248;string249;string250;string251;string252;string253;string254;string255;string256;string257;string258;string259;string260;string261;string262;string263;string264;string265;string266;string267;string268;string269;string270;string271;string272;string273;string274;string275;string276;string277;string278;string279;string280;string281;string282;string283;string284;string285;string286;string287;string288;string289;string290;string291;string292;string293;string294;string295;string296;string297;string298;string299;string300;string301;string302;string303;string304;string305;string306;string307;string308;string309;string310;string311;string312;string313;string314;string315;string316;string317;string318;string319;string320;string321;string322;string323;string324;string325;string326;string327;string328;string329;string330;string331;string332;string333;string334;string335;string336;string337;string338;string339;string340;string341;string342;string343;string344;string345;string346;string347;string348;string349;string350;string351;string352;string353;string354;string355;string356;string357;string358;string359;string360;string361;string362;string363;string364;string365;string366;string367;string368;string369;string370;string371;string372;string373;string374;string375;string376;string377;string378;string379;string380;string381;string382;string383;string384;string385;string386;string387;string388;string389;string390;string391;string392;string393;string394;string395;string396;string397;string398;string399;string400;string401;string402;string403;string404;string405;string406;string407;string408;string409;string410;string411;string412;string413;string414;string415;string416;string417;string418;string419;string420;string421;string422;string423;string424;string425;string426;string427;string428;string429;string430;string431;string432;string433;string434;string435;string436;string437;string438;string439;string440;string441;string442;string443;string444;string445;string446;string447;string448;string449;string450;string451;string452;string453;string454;string455;string456;string457;string458;string459;string460;string461;string462;string463;string464;string465;string466;string467;string468;string469;string470;string471;string472;string473;string474;string475;string476;string477;string478;string479;string480;string481;string482;string483;string484;string485;string486;string487;string488;string489;string490;string491;string492;string493;string494;string495;string496;string497;string498;string499;string500;string501;string502;string503;string504;string505;string506;string507;string508;string509;string510;string511;string512;string513;string514;string515;string516;string517;string518;string519;string520;string521;string522;string523;string524;string525;string526;string527;string528;string529;string530;string531;string532;string533;string534;string535;string536;string537;string538;string539;string540;string541;string542;string543;string544;string545;string546;string547;string548;string549;string550;string551;string552;string553;string554;string555;string556;string557;string558;string559;string560;string561;string562;string563;string564;string565;string566;string567;string568;string569;string570;string571;string572;string573;string574;string575;string576;string577;string578;string579;string580;string581;string582;string583;string584;string585;string586;string587;string588;string589;string590;string591;string592;string593;string594;string595;string596;string597;string598;string599;string600;string601;string602;string603;string604;string605;string606;string607;string608;string609;string610;string611;string612;string613;string614;string615;string616;string617;string618;string619;string620;string621;string622;string623;string624;string625;string626;string627;string628;string629;string630;string631;string632;string633;string634;string635;string636;string637;string638;string639;string640;string641;string642;string643;string644;string645;string646;string647;string648;string649;string650;string651;string652;string653;string654;string655;string656;string657;string658;string659;string660;string661;string662;string663;string664;string665;string666;string667;string668;string669;string670;string671;string672;string673;string674;string675;string676;string677;string678;string679;string680;string681;string682;string683;string684;string685;string686;string687;string688;string689;string690;string691;string692;string693;string694;string695;string696;string697;string698;string699;string700;string701;string702;string703;string704;string705;string706;string707;string708;string709;string710;string711;string712;string713;string714;string715;string716;string717;string718;string719;string720;string721;string722;string723;string724;string725;string726;string727;string728;string729;string730;string731;string732;string733;string734;string735;string736;string737;string738;string739;string740;string741;string742;string743;string744;string745;string746;string747;string748;string749;string750;string751;string752;string753;string754;string755;string756;string757;string758;string759;string760;string761;string762;string763;string764;string765;string766;string767;string768;string769;string770;string771;string772;string773;string774;string775;string776;string777;string778;string779;string780;string781;string782;string783;string784;string785;string786;string787;string788;string789;string790;string791;string792;string793;string794;string795;string796;string797;string798;string799;string800;string801;string802;string803;string804;string805;string806;string807;string808;string809;string810;string811;string812;string813;string814;string815;string816;string817;string818;string819;string820;string821;string822;string823;string824;string825;string826;string827;string828;string829;string830;string831;string832;string833;string834;string835;string836;string837;string838;string839;string840;string841;string842;string843;string844;string845;string846;string847;string848;string849;string850;string851;string852;string853;string854;string855;string856;string857;string858;string859;string860;string861;string862;string863;string864;string865;string866;string867;string868;string869;string870;string871;string872;string873;string874;string875;string876;string877;string878;string879;string880;string881;string882;string883;string884;string885;string886;string887;string888;string889;string890;string891;string892;string893;string894;string895;string896;string897;string898;string899;string900;string901;string902;string903;string904;string905;string906;string907;string908;string909;string910;string911;string912;string913;string914;string915;string916;string917;string918;string919;string920;string921;string922;string923;string924;string925;string926;string927;string928;string929;string930;string931;string932;string933;string934;string935;string936;string937;string938;string939;string940;string941;string942;string943;string944;string945;string946;string947;string948;string949;string950;string951;string952;string953;string954;string955;string956;string957;string958;string959;string960;string961;string962;string963;string964;string965;string966;string967;string968;string969;string970;string971;string972;string973;string974;string975;string976;string977;string978;string979;string980;string981;string982;string983;string984;string985;string986;string987;string988;string989;string990;string991;string992;string993;string994;string995;string996;string997;string998;string999
+ing999
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+art;string0;string1;string2;string3;string4;string5;string6;string7;string8;string9;string10;string11;string12;string13;string14;string15;string16;string17;string18;string19;string20;string21;string22;string23;string24;string25;string26;string27;string28;string29;string30;string31;string32;string33;string34;string35;string36;string37;string38;string39;string40;string41;string42;string43;string44;string45;string46;string47;string48;string49;string50;string51;string52;string53;string54;string55;string56;string57;string58;string59;string60;string61;string62;string63;string64;string65;string66;string67;string68;string69;string70;string71;string72;string73;string74;string75;string76;string77;string78;string79;string80;string81;string82;string83;string84;string85;string86;string87;string88;string89;string90;string91;string92;string93;string94;string95;string96;string97;string98;string99;string100;string101;string102;string103;string104;string105;string106;string107;string108;string109;string110;string111;string112;string113;string114;string115;string116;string117;string118;string119;string120;string121;string122;string123;string124;string125;string126;string127;string128;string129;string130;string131;string132;string133;string134;string135;string136;string137;string138;string139;string140;string141;string142;string143;string144;string145;string146;string147;string148;string149;string150;string151;string152;string153;string154;string155;string156;string157;string158;string159;string160;string161;string162;string163;string164;string165;string166;string167;string168;string169;string170;string171;string172;string173;string174;string175;string176;string177;string178;string179;string180;string181;string182;string183;string184;string185;string186;string187;string188;string189;string190;string191;string192;string193;string194;string195;string196;string197;string198;string199;string200;string201;string202;string203;string204;string205;string206;string207;string208;string209;string210;string211;string212;string213;string214;string215;string216;string217;string218;string219;string220;string221;string222;string223;string224;string225;string226;string227;string228;string229;string230;string231;string232;string233;string234;string235;string236;string237;string238;string239;string240;string241;string242;string243;string244;string245;string246;string247;string248;string249;string250;string251;string252;string253;string254;string255;string256;string257;string258;string259;string260;string261;string262;string263;string264;string265;string266;string267;string268;string269;string270;string271;string272;string273;string274;string275;string276;string277;string278;string279;string280;string281;string282;string283;string284;string285;string286;string287;string288;string289;string290;string291;string292;string293;string294;string295;string296;string297;string298;string299;string300;string301;string302;string303;string304;string305;string306;string307;string308;string309;string310;string311;string312;string313;string314;string315;string316;string317;string318;string319;string320;string321;string322;string323;string324;string325;string326;string327;string328;string329;string330;string331;string332;string333;string334;string335;string336;string337;string338;string339;string340;string341;string342;string343;string344;string345;string346;string347;string348;string349;string350;string351;string352;string353;string354;string355;string356;string357;string358;string359;string360;string361;string362;string363;string364;string365;string366;string367;string368;string369;string370;string371;string372;string373;string374;string375;string376;string377;string378;string379;string380;string381;string382;string383;string384;string385;string386;string387;string388;string389;string390;string391;string392;string393;string394;string395;string396;string397;string398;string399;string400;string401;string402;string403;string404;string405;string406;string407;string408;string409;string410;string411;string412;string413;string414;string415;string416;string417;string418;string419;string420;string421;string422;string423;string424;string425;string426;string427;string428;string429;string430;string431;string432;string433;string434;string435;string436;string437;string438;string439;string440;string441;string442;string443;string444;string445;string446;string447;string448;string449;string450;string451;string452;string453;string454;string455;string456;string457;string458;string459;string460;string461;string462;string463;string464;string465;string466;string467;string468;string469;string470;string471;string472;string473;string474;string475;string476;string477;string478;string479;string480;string481;string482;string483;string484;string485;string486;string487;string488;string489;string490;string491;string492;string493;string494;string495;string496;string497;string498;string499;string500;string501;string502;string503;string504;string505;string506;string507;string508;string509;string510;string511;string512;string513;string514;string515;string516;string517;string518;string519;string520;string521;string522;string523;string524;string525;string526;string527;string528;string529;string530;string531;string532;string533;string534;string535;string536;string537;string538;string539;string540;string541;string542;string543;string544;string545;string546;string547;string548;string549;string550;string551;string552;string553;string554;string555;string556;string557;string558;string559;string560;string561;string562;string563;string564;string565;string566;string567;string568;string569;string570;string571;string572;string573;string574;string575;string576;string577;string578;string579;string580;string581;string582;string583;string584;string585;string586;string587;string588;string589;string590;string591;string592;string593;string594;string595;string596;string597;string598;string599;string600;string601;string602;string603;string604;string605;string606;string607;string608;string609;string610;string611;string612;string613;string614;string615;string616;string617;string618;string619;string620;string621;string622;string623;string624;string625;string626;string627;string628;string629;string630;string631;string632;string633;string634;string635;string636;string637;string638;string639;string640;string641;string642;string643;string644;string645;string646;string647;string648;string649;string650;string651;string652;string653;string654;string655;string656;string657;string658;string659;string660;string661;string662;string663;string664;string665;string666;string667;string668;string669;string670;string671;string672;string673;string674;string675;string676;string677;string678;string679;string680;string681;string682;string683;string684;string685;string686;string687;string688;string689;string690;string691;string692;string693;string694;string695;string696;string697;string698;string699;string700;string701;string702;string703;string704;string705;string706;string707;string708;string709;string710;string711;string712;string713;string714;string715;string716;string717;string718;string719;string720;string721;string722;string723;string724;string725;string726;string727;string728;string729;string730;string731;string732;string733;string734;string735;string736;string737;string738;string739;string740;string741;string742;string743;string744;string745;string746;string747;string748;string749;string750;string751;string752;string753;string754;string755;string756;string757;string758;string759;string760;string761;string762;string763;string764;string765;string766;string767;string768;string769;string770;string771;string772;string773;string774;string775;string776;string777;string778;string779;string780;string781;string782;string783;string784;string785;string786;string787;string788;string789;string790;string791;string792;string793;string794;string795;string796;string797;string798;string799;string800;string801;string802;string803;string804;string805;string806;string807;string808;string809;string810;string811;string812;string813;string814;string815;string816;string817;string818;string819;string820;string821;string822;string823;string824;string825;string826;string827;string828;string829;string830;string831;string832;string833;string834;string835;string836;string837;string838;string839;string840;string841;string842;string843;string844;string845;string846;string847;string848;string849;string850;string851;string852;string853;string854;string855;string856;string857;string858;string859;string860;string861;string862;string863;string864;string865;string866;string867;string868;string869;string870;string871;string872;string873;string874;string875;string876;string877;string878;string879;string880;string881;string882;string883;string884;string885;string886;string887;string888;string889;string890;string891;string892;string893;string894;string895;string896;string897;string898;string899;string900;string901;string902;string903;string904;string905;string906;string907;string908;string909;string910;string911;string912;string913;string914;string915;string916;string917;string918;string919;string920;string921;string922;string923;string924;string925;string926;string927;string928;string929;string930;string931;string932;string933;string934;string935;string936;string937;string938;string939;string940;string941;string942;string943;string944;string945;string946;string947;string948;string949;string950;string951;string952;string953;string954;string955;string956;string957;string958;string959;string960;string961;string962;string963;string964;string965;string966;string967;string968;string969;string970;string971;string972;string973;string974;string975;string976;string977;string978;string979;string980;string981;string982;string983;string984;string985;string986;string987;string988;string989;string990;string991;string992;string993;string994;string995;string996;string997;string998;string999
+start;string0;string1;string2;string3;string4;string5;string6;string7;string8;string9;string10;string11;string12;string13;string14;string15;string16;string17;string18;string19;string20;string21;string22;string23;string24;string25;string26;string27;string28;string29;string30;string31;string32;string33;string34;string35;string36;string37;string38;string39;string40;string41;string42;string43;string44;string45;string46;string47;string48;string49;string50;string51;string52;string53;string54;string55;string56;string57;string58;string59;string60;string61;string62;string63;string64;string65;string66;string67;string68;string69;string70;string71;string72;string73;string74;string75;string76;string77;string78;string79;string80;string81;string82;string83;string84;string85;string86;string87;string88;string89;string90;string91;string92;string93;string94;string95;string96;string97;string98;string99;string100;string101;string102;string103;string104;string105;string106;string107;string108;string109;string110;string111;string112;string113;string114;string115;string116;string117;string118;string119;string120;string121;string122;string123;string124;string125;string126;string127;string128;string129;string130;string131;string132;string133;string134;string135;string136;string137;string138;string139;string140;string141;string142;string143;string144;string145;string146;string147;string148;string149;string150;string151;string152;string153;string154;string155;string156;string157;string158;string159;string160;string161;string162;string163;string164;string165;string166;string167;string168;string169;string170;string171;string172;string173;string174;string175;string176;string177;string178;string179;string180;string181;string182;string183;string184;string185;string186;string187;string188;string189;string190;string191;string192;string193;string194;string195;string196;string197;string198;string199;string200;string201;string202;string203;string204;string205;string206;string207;string208;string209;string210;string211;string212;string213;string214;string215;string216;string217;string218;string219;string220;string221;string222;string223;string224;string225;string226;string227;string228;string229;string230;string231;string232;string233;string234;string235;string236;string237;string238;string239;string240;string241;string242;string243;string244;string245;string246;string247;string248;string249;string250;string251;string252;string253;string254;string255;string256;string257;string258;string259;string260;string261;string262;string263;string264;string265;string266;string267;string268;string269;string270;string271;string272;string273;string274;string275;string276;string277;string278;string279;string280;string281;string282;string283;string284;string285;string286;string287;string288;string289;string290;string291;string292;string293;string294;string295;string296;string297;string298;string299;string300;string301;string302;string303;string304;string305;string306;string307;string308;string309;string310;string311;string312;string313;string314;string315;string316;string317;string318;string319;string320;string321;string322;string323;string324;string325;string326;string327;string328;string329;string330;string331;string332;string333;string334;string335;string336;string337;string338;string339;string340;string341;string342;string343;string344;string345;string346;string347;string348;string349;string350;string351;string352;string353;string354;string355;string356;string357;string358;string359;string360;string361;string362;string363;string364;string365;string366;string367;string368;string369;string370;string371;string372;string373;string374;string375;string376;string377;string378;string379;string380;string381;string382;string383;string384;string385;string386;string387;string388;string389;string390;string391;string392;string393;string394;string395;string396;string397;string398;string399;string400;string401;string402;string403;string404;string405;string406;string407;string408;string409;string410;string411;string412;string413;string414;string415;string416;string417;string418;string419;string420;string421;string422;string423;string424;string425;string426;string427;string428;string429;string430;string431;string432;string433;string434;string435;string436;string437;string438;string439;string440;string441;string442;string443;string444;string445;string446;string447;string448;string449;string450;string451;string452;string453;string454;string455;string456;string457;string458;string459;string460;string461;string462;string463;string464;string465;string466;string467;string468;string469;string470;string471;string472;string473;string474;string475;string476;string477;string478;string479;string480;string481;string482;string483;string484;string485;string486;string487;string488;string489;string490;string491;string492;string493;string494;string495;string496;string497;string498;string499;string500;string501;string502;string503;string504;string505;string506;string507;string508;string509;string510;string511;string512;string513;string514;string515;string516;string517;string518;string519;string520;string521;string522;string523;string524;string525;string526;string527;string528;string529;string530;string531;string532;string533;string534;string535;string536;string537;string538;string539;string540;string541;string542;string543;string544;string545;string546;string547;string548;string549;string550;string551;string552;string553;string554;string555;string556;string557;string558;string559;string560;string561;string562;string563;string564;string565;string566;string567;string568;string569;string570;string571;string572;string573;string574;string575;string576;string577;string578;string579;string580;string581;string582;string583;string584;string585;string586;string587;string588;string589;string590;string591;string592;string593;string594;string595;string596;string597;string598;string599;string600;string601;string602;string603;string604;string605;string606;string607;string608;string609;string610;string611;string612;string613;string614;string615;string616;string617;string618;string619;string620;string621;string622;string623;string624;string625;string626;string627;string628;string629;string630;string631;string632;string633;string634;string635;string636;string637;string638;string639;string640;string641;string642;string643;string644;string645;string646;string647;string648;string649;string650;string651;string652;string653;string654;string655;string656;string657;string658;string659;string660;string661;string662;string663;string664;string665;string666;string667;string668;string669;string670;string671;string672;string673;string674;string675;string676;string677;string678;string679;string680;string681;string682;string683;string684;string685;string686;string687;string688;string689;string690;string691;string692;string693;string694;string695;string696;string697;string698;string699;string700;string701;string702;string703;string704;string705;string706;string707;string708;string709;string710;string711;string712;string713;string714;string715;string716;string717;string718;string719;string720;string721;string722;string723;string724;string725;string726;string727;string728;string729;string730;string731;string732;string733;string734;string735;string736;string737;string738;string739;string740;string741;string742;string743;string744;string745;string746;string747;string748;string749;string750;string751;string752;string753;string754;string755;string756;string757;string758;string759;string760;string761;string762;string763;string764;string765;string766;string767;string768;string769;string770;string771;string772;string773;string774;string775;string776;string777;string778;string779;string780;string781;string782;string783;string784;string785;string786;string787;string788;string789;string790;string791;string792;string793;string794;string795;string796;string797;string798;string799;string800;string801;string802;string803;string804;string805;string806;string807;string808;string809;string810;string811;string812;string813;string814;string815;string816;string817;string818;string819;string820;string821;string822;string823;string824;string825;string826;string827;string828;string829;string830;string831;string832;string833;string834;string835;string836;string837;string838;string839;string840;string841;string842;string843;string844;string845;string846;string847;string848;string849;string850;string851;string852;string853;string854;string855;string856;string857;string858;string859;string860;string861;string862;string863;string864;string865;string866;string867;string868;string869;string870;string871;string872;string873;string874;string875;string876;string877;string878;string879;string880;string881;string882;string883;string884;string885;string886;string887;string888;string889;string890;string891;string892;string893;string894;string895;string896;string897;string898;string899;string900;string901;string902;string903;string904;string905;string906;string907;string908;string909;string910;string911;string912;string913;string914;string915;string916;string917;string918;string919;string920;string921;string922;string923;string924;string925;string926;string927;string928;string929;string930;string931;string932;string933;string934;string935;string936;string937;string938;string939;string940;string941;string942;string943;string944;string945;string946;string947;string948;string949;string950;string951;string952;string953;string954;string955;string956;string957;string958;string959;string960;string961;string962;string963;string964;string965;string966;string967;string968;string969;string970;string971;string972;string973;string974;string975;string976;string977;string978;string979;string980;string981;string982;string983;string984;string985;string986;string987;string988;string989;string990;string991;string992;string993;string994;string995;string996;string997;string998;string9
+zbcd
+axd
+axxd
+axxd
+zzzz
+zbcd
+axd
+axxd
+axxd
+zzzz
+a Value = 1 2 3 4 5
+a Sub = 0 1 2 3 4
+b Value = a b c d e
+b Sub = 0 1 2 3 4
+c Value = 10 20 40 80
+c Sub = 0 2 4 8
+<1> <2> <3> <4> <5>
+<10> <20> <40> <80>
+<>
+<>
+<>
+<>
+<'ab '\''cd'\'' ef'>
+bash: line 1: ${x@C}: bad substitution
+<'ab'> <'cd ef'> <''> <'gh'>
+<'ab' 'cd ef' '' 'gh'>
+<'ab'> <'cd> <ef'> <''> <'gh'>
+<'ab'> <'cd> <ef'> <''> <'gh'>
+<'ab cd'>
+<'4'> <'ab cd'>
+<>
+argv[1] = <host(2)[5.2]$ >
+<
+>
+<' \t\n'>
+<
+>
+<$' \t\n'>
+declare -r x='ab '\''cd'\'' ef'
+set -- 'ab' 'cd ef' '' 'gh'
+declare -a A=([0]="ab" [1]="cd ef" [2]="" [3]="gh")
+declare -a B=()
+declare -A A=([four]="de" [two]="b c" [three]="" [one]="1" )
+r
+a
+A
+ir
+a b c d e
+5
+a5b
+i
+declare -i foo
+A
+declare -A foo
+./new-exp10.sub: line 118: ${V@}: bad substitution
+abcxxxdef
+abcådef
+ḅć
+Ã¥
+prependḅć
+Ã¥append
+prependå
+ḅćappend
+Ã¥
+ḅć
+ḅć
+ḅć
+Ã¥
+Ã¥
+Ã¥
+ḅć
+Ã¥
+Ã¥
+ḅć
+ḅć
+HELLO;1 foo;2 foo;
+PASS;1 foo;2 foo;
+after: PASS
+'zzz'
+'zzz'
+declare -rl VAR1
+declare -rl VAR1
+declare -rl VAR1
+declare -rl VAR1
+rl
+rl
+rl
+rl
+declare -arl VAR3
+declare -arl VAR3
+declare -arl VAR3
+declare -arl VAR3
+arl
+arl
+arl
+arl
+one
+one
+'aaa'
+'aaa' 'bbb'
+./new-exp13.sub: line 56: aaa bbb: invalid variable name
+aaa bbb
+0 1
+'aaa'
+'aaa' 'bbb'
+'aaa' 'bbb'
+'aaa' 'bbb'
+a bbb
+aaa bb
+'string'
+'string'
+'value with spaces'
+'value with spaces'
+'a b' 'c d' 'e f'
+'a b' 'c d' 'e f'
+0 "zero" 1 "one" 2 "two" 3 "three"
+0 "zero z" 1 "one o" 2 "two t" 3 "three t"
+argv[1] = <0>
+argv[2] = <zero z>
+argv[3] = <1>
+argv[4] = <one o>
+argv[5] = <2>
+argv[6] = <two t>
+argv[7] = <3>
+argv[8] = <three t>
+declare -a foo=()
+ai
+declare -ai foo
+bash: line 1: foo: unbound variable
+ai
+declare -ai foo
+bash: line 1: !bar: unbound variable
+a
+a
+a
+a
+/homes/chetdefg
+/homes/chetdefg
+~defg
+defg
+defg
+defg
+$'&' $'&' $'&' $'&' $'&' $'&' $'&'
+$'a' $'b' $'c' $'d' $'e' $'f' $'g'
+a b c d e f g
+a b c d e f g
+& & & & & & &
+& & & & & & &
+& & & & & & &
+\& \& \& \& \& \& \&
+a a a a a a a
+3 3 3 3 3 3 3
+abc defg
+abc defg
+& defg
+& defg
+& defg
+\& defg
+\abc defg
+abcdefg
+&defg
+\abcdefg
+\&defg
+\&defg
+\abcdefg
+\\&defg
+&defg
+&defg
+\&defg
+\&defg
+\\&defg
+letx&yee
+letx&yee
+letxssyee
+letxssyee
+letx\&yee
+letx\&yee
+letx&yee
+letx&yee
+let\&ee
+let\\ssee
+let\ssee
+let\ssee
+let\&ee
+let\&ee
+let&ee
+let&ee
+twoone
+&twoone
+onetwo
+one&two
+two
+&two
+otwone
+&twone
+argv[1] = </>
+argv[1] = </>
+
+./new-exp.tests: line 1: ABXD: parameter unset
diff --git a/tests/new-exp.tests b/tests/new-exp.tests
new file mode 100644
index 0000000..c542313
--- /dev/null
+++ b/tests/new-exp.tests
@@ -0,0 +1,654 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+if (( $UID == 0 )); then
+ echo "new-exp.tests: the test suite should not be run as root" >&2
+fi
+
+# 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 -- a 'b c' d
+unset foo
+foo=@
+expect '<a> <b> <c> <d>'
+recho ${!foo}
+expect '<a> <b c> <d>'
+recho "${!foo}"
+
+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
+# as of bash-4.2, negative LENGTH means offset from the end
+c=${var:0:-2}
+expect '<a>'
+recho $c
+
+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}}
+
+# make sure null strings are replaced appropriately
+unset var
+var=
+echo "${var/#/x}"
+echo "${var/*/x}"
+echo "${var//*/x}"
+
+var=abc
+echo "${var/#/x}"
+echo "${var/*/x}"
+echo "${var//*/x}"
+unset var
+
+# 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))}
+set a b c d e
+recho ${@: -3:-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
+
+${THIS_SH} ./new-exp8.sub
+
+# tests to check whether things like indirect expansion of a variable whose
+# value is 'anothervar[@]' stop working
+${THIS_SH} ./new-exp9.sub
+
+# new parameter transformation `@' expansion operator
+${THIS_SH} ./new-exp10.sub
+
+# parameter substring replacement and removal operators with multibyte chars
+${THIS_SH} ./new-exp11.sub
+
+# indirect expansion with arrays and local variables
+${THIS_SH} ./new-exp12.sub
+
+# more indirect expansion and parameter transformation issues
+${THIS_SH} ./new-exp13.sub
+
+# new K parameter transformation operator
+${THIS_SH} ./new-exp14.sub
+
+# ongoing work with a/A parameter transformations and `nounset'
+${THIS_SH} ./new-exp15.sub
+
+# pattern substitution with `&' (quoted and unquoted) in the replacement string
+${THIS_SH} ./new-exp16.sub
+
+
+# problems with stray CTLNUL in bash-4.0-alpha
+unset a
+a=/a
+recho "/${a%/*}"
+recho "/${a///a/}"
+
+patfunc()
+{
+ echo ${1##*"${1##*}"}
+}
+patfunc foo
+
+# caused core dumps because of bad bracket expression parsing in bash-5.0
+eval : $'${x/#[0\xef\xbf\xbd\\Z[:]]}'
+
+expect $0: 'ABXD: parameter unset'
+${THIS_SH} -c 'recho ${ABXD:?"parameter unset"}' $0
diff --git a/tests/new-exp1.sub b/tests/new-exp1.sub
new file mode 100644
index 0000000..d29b93c
--- /dev/null
+++ b/tests/new-exp1.sub
@@ -0,0 +1,29 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+FN=${TMPDIR}/bashtest-$$
+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 > $FN
+expect this is test 2
+cat <(cat $FN)
+rm -f $FN
+
+foo=
+expect a
+cat ${foo:-<(echo a)}
diff --git a/tests/new-exp10.sub b/tests/new-exp10.sub
new file mode 100644
index 0000000..5b199d4
--- /dev/null
+++ b/tests/new-exp10.sub
@@ -0,0 +1,118 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# new framework for parameter transformations, post bash-4.3
+
+printf "<%s>" "${x@Q}" ; echo
+printf "<%s>" "${x@E}" ; echo
+printf "<%s>" "${x@P}" ; echo
+printf "<%s>" "${x@A}" ; echo
+
+x="ab 'cd' ef"
+printf "<%s> " "${x@Q}" ; echo
+
+# this needs to be run in a subshell because invalid transformation operators
+# are now treated as substitution errors, fatal in non-interactive shells
+${THIS_SH} -c 'x=abcdef ; printf "<%s>" "${x@C}"' bash
+
+# if unquoted, normal word splitting happens
+set -- ab 'cd ef' '' gh
+printf "<%s> " "${@@Q}" ; echo
+printf "<%s> " "${*@Q}" ; echo
+printf "<%s> " ${@@Q} ; echo
+printf "<%s> " ${*@Q} ; echo
+
+y[0]=4
+y[1]='ab cd'
+
+printf "<%s> " "${y[1]@Q}" ; echo
+printf "<%s> " "${y[@]@Q}" ; echo # mksh doesn't like @ or * or arrays subscripted with them
+
+printf "<%s> " "${z@Q}" ; echo # empty string?
+
+recho ${z@Q} # this disappears
+
+#
+HOST=host
+SHELL_LEVEL=2
+NPS1='\[\]${HOST}($SHELL_LEVEL)[\v]\$ '
+
+recho "${NPS1@P}"
+
+#
+D=' \t\n'
+printf "<%s>" "${D@E}" ; echo
+printf "<%s>" "${D@Q}" ; echo
+
+E=$' \t\n'
+printf "<%s>" "${E@E}" ; echo
+printf "<%s>" "${E@Q}" ; echo
+
+declare x
+declare -r x="ab 'cd' ef"
+printf "%s" "${x@A}" ; echo
+
+set -- ab 'cd ef' '' gh
+printf "%s " "${@@A}" ; echo
+
+A=( "$@" )
+printf "%s " "${A[@]@A}" ; echo
+B=()
+printf "%s " "${B[@]@A}" ; echo
+
+unset A
+declare -A A
+A=( [one]=1 [two]='b c' [three]='' [four]=de )
+printf "%s " "${A[@]@A}" ; echo
+
+unset X
+declare X
+declare -r X="ab 'cd' ef"
+printf "%s" "${X@a}" ; echo
+
+set -- 1 2 3 4
+
+unset A
+A=( "$@" )
+printf "%s " "${A@a}" ; echo
+
+unset A
+declare -A A
+A=( [one]=1 [two]='b c' [three]='' [four]=de )
+printf "%s " "${A@a}" ; echo
+
+declare -ir Y=0
+printf "%s" "${Y@a}" ; echo
+
+# make sure we still handle ${#@} and ${@} as posix requires
+set -- a b c d e
+echo ${@}
+echo ${#@}
+echo a${#@}b
+
+# new feature in bash-5.0: display attributes of even unset variables
+unset -v foo
+
+declare -i foo
+echo ${foo@a}
+
+declare -p foo
+
+unset foo
+declare -A foo
+echo ${foo@a}
+
+declare -p foo
+
+V=42
+echo ${V@} # error
diff --git a/tests/new-exp11.sub b/tests/new-exp11.sub
new file mode 100644
index 0000000..6a9edd5
--- /dev/null
+++ b/tests/new-exp11.sub
@@ -0,0 +1,59 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# pattern matching and replacement operators with multibyte characters
+
+LANG=en_US.UTF-8
+
+s1='abcådef'
+s2='Ã¥'
+s3='ḅć'
+
+s23=${s2}${s3}
+
+echo ${s1/$s2/xxx}
+echo ${s1/$s3/xxx}
+
+echo ${s23/#$s2/}
+echo ${s23/%$s3/}
+
+echo ${s23/#$s2/prepend}
+echo ${s23/%$s3/append}
+
+echo ${s2/#/prepend}
+echo ${s3/%/append}
+
+echo ${s2/#/}
+echo ${s3/%/}
+
+recho ${s2/$s2/}
+recho ${s3/$s3/}
+
+# posix pattern replacements
+
+echo ${s23##$s2}
+echo ${s23#$s2}
+
+echo ${s23%%$s3}
+echo ${s23%$s3}
+
+# fail
+
+echo ${s2/#ab/xx}
+echo ${s3/%ab/xx}
+
+echo ${s2#ab}
+echo ${s2##ab}
+
+echo ${s3%ab}
+echo ${s3%%ab}
diff --git a/tests/new-exp12.sub b/tests/new-exp12.sub
new file mode 100644
index 0000000..1fbd5d6
--- /dev/null
+++ b/tests/new-exp12.sub
@@ -0,0 +1,40 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# make sure indirect expansion for arrays uses the closest-scope instance
+# of the resulting variable name
+
+array_1=("PASS")
+array_2=("1 foo" "2 foo")
+
+unsafe_fn ()
+{
+ local array_1=('HELLO')
+ local a=("${!1}") b=("${!2}")
+ printf '%s;' "${a[@]}" "${b[@]}"
+ printf '\n'
+}
+
+safe_fn ()
+{
+ local a=("${!1}") b=("${!2}")
+ local array_1=('FAIL')
+ printf '%s;' "${a[@]}" "${b[@]}"
+ printf '\n'
+}
+
+unsafe_fn 'array_1[@]' 'array_2[@]'
+safe_fn 'array_1[@]' 'array_2[@]'
+
+echo after: ${array_1[@]}
diff --git a/tests/new-exp13.sub b/tests/new-exp13.sub
new file mode 100644
index 0000000..7e8ed32
--- /dev/null
+++ b/tests/new-exp13.sub
@@ -0,0 +1,72 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+declare -lr VAR1
+declare -lr VAR2=zzz
+declare -alr VAR3
+
+var=VAR2
+
+echo ${!var@Q}
+echo ${VAR2@Q}
+
+echo ${VAR1@A}
+echo ${VAR1[@]@A}
+echo "${VAR1@A}"
+echo "${VAR1[@]@A}"
+
+echo "${VAR1[@]@a}"
+echo ${VAR1[@]@a}
+echo "${VAR1@a}"
+echo ${VAR1@a}
+
+echo ${VAR3@A}
+echo ${VAR3[@]@A}
+echo "${VAR3@A}"
+echo "${VAR3[@]@A}"
+
+echo "${VAR3[@]@a}"
+echo ${VAR3[@]@a}
+echo "${VAR3@a}"
+echo ${VAR3@a}
+
+var=one
+
+echo ${var}
+echo ${var[@]}
+
+VAR4=(aaa bbb)
+
+varname=VAR4
+
+echo ${!varname[@]@Q}
+
+echo ${VAR4[@]@Q}
+echo ${!VAR4[@]@Q}
+
+echo ${VAR4[@]}
+echo ${!VAR4[@]}
+
+VAR5=(aaa bbb)
+varname="VAR5[@]"
+
+echo "${VAR5@Q}"
+echo "${VAR5[@]@Q}"
+
+echo "${!varname@Q}"
+echo "${!varname[@]@Q}"
+
+# caused core dumps through bash-5.0
+echo "${!varname##aa}"
+echo "${!varname[@]%b}"
diff --git a/tests/new-exp14.sub b/tests/new-exp14.sub
new file mode 100644
index 0000000..92f51ea
--- /dev/null
+++ b/tests/new-exp14.sub
@@ -0,0 +1,36 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# test the other uses of the 'K' transform operator and its sibling 'k'
+# the associative array tests are performed separately, since that was the
+# original motivation for this feature
+foo=string
+bar='value with spaces'
+
+set -- 'a b' 'c d' 'e f'
+
+echo ${foo@K}
+echo ${foo@k}
+echo ${bar@K}
+echo ${bar@k}
+
+echo ${@@K}
+echo "${@@K}"
+
+foo=( zero one two three )
+echo ${foo[@]@K}
+
+foo=( 'zero z' 'one o' 'two t' 'three t' )
+echo ${foo[@]@K}
+recho "${foo[@]@k}"
diff --git a/tests/new-exp15.sub b/tests/new-exp15.sub
new file mode 100644
index 0000000..f8b9ed8
--- /dev/null
+++ b/tests/new-exp15.sub
@@ -0,0 +1,29 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+: ${THIS_SH:=./bash}
+
+${THIS_SH} -c 'declare -a foo=() ; declare -p foo' bash
+
+${THIS_SH} -c 'declare -ia foo=() ; echo ${foo@a} ; echo ${foo@A}' bash
+${THIS_SH} -uc 'declare -ia foo=() ; echo ${foo@a} ; echo ${foo@A}' bash
+
+${THIS_SH} -c 'declare -ia foo=() ; bar=foo; echo ${!bar@a} ; echo ${!bar@A}' bash
+${THIS_SH} -uc 'declare -ia foo=() ; bar=foo; echo ${!bar@a} ; echo ${!bar@A}' bash
+
+${THIS_SH} -c 'declare -a foo=( [1]=one ) ; echo ${foo@a}' bash
+${THIS_SH} -uc 'declare -a foo=( [1]=one ) ; echo ${foo@a}' bash
+
+${THIS_SH} -c 'declare -a foo=( [1]=one ) ; bar=foo; echo ${!bar@a}' bash
+${THIS_SH} -uc 'declare -a foo=( [1]=one ) ; bar=foo; echo ${!bar@a}' bash
diff --git a/tests/new-exp16.sub b/tests/new-exp16.sub
new file mode 100644
index 0000000..2ed751d
--- /dev/null
+++ b/tests/new-exp16.sub
@@ -0,0 +1,120 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+HOME=/homes/chet
+string=abcdefg
+set -- a b c
+
+shopt -u patsub_replacement
+
+# verify existing behavior
+echo ${string/abc/~}
+echo "${string/abc/~}"
+echo ${string/abc/"~"}
+
+echo ${string/abc/$notthere}
+echo "${string/abc/$notthere}"
+echo "${string/abc/"$notthere"}"
+
+echo ${string//?/\$\'&\' }
+
+shopt -s patsub_replacement
+
+echo ${string//?/\$\'&\' }
+
+echo ${string//?/& }
+echo "${string//?/& }"
+
+echo ${string//?/\& }
+echo "${string//?/\& }"
+echo ${string//?/"& "}
+echo ${string//?/"\& "}
+
+echo "${string//?/"a "}"
+echo "${string//?/"$# "}"
+
+echo ${string/abc/& }
+echo "${string/abc/& }"
+echo ${string/abc/"& "}
+
+echo ${string/abc/\& }
+echo "${string/abc/\& }"
+echo ${string/abc/"\& "}
+echo ${string/abc/\\& }
+
+rep='\\&'
+
+echo "${string/abc/&}"
+echo ${string/abc/\&}
+echo "${string/abc/\\&}"
+echo ${string/abc/"\\&"}
+echo "${string/abc/"\\&"}"
+echo ${string/abc/$rep}
+echo ${string/abc/"$rep"}
+
+shopt -u patsub_replacement
+
+echo "${string/abc/&}"
+echo ${string/abc/\&}
+echo "${string/abc/\\&}"
+echo "${string/abc/"\\&"}"
+echo ${string/abc/"$rep"}
+
+shopt -s patsub_replacement
+
+repl='x&y'
+r2='x\&y'
+var='letssee'
+
+pat=ss
+
+echo ${var//$pat/"$repl"}
+echo "${var//$pat/"$repl"}"
+echo ${var//$pat/$repl}
+echo "${var//$pat/$repl}"
+
+echo ${var//$pat/"$r2"}
+echo "${var//$pat/"$r2"}"
+echo ${var//$pat/$r2}
+echo "${var//$pat/$r2}"
+
+r2='\\&'
+r3='\&'
+
+echo ${var//$pat/\\\&}
+echo ${var//$pat/\\$r2}
+echo ${var//$pat/\\&}
+echo ${var//$pat/$r2}
+
+echo ${var//$pat/"\&"}
+echo ${var//$pat/"$r3"}
+echo ${var//$pat/"&"}
+echo ${var//$pat/$r3}
+
+# these cases provide the same functionality as sed when given a BRE like
+# `^' or `$', or when passed a null input line
+one=one
+null=
+
+echo ${one/#/&two}
+echo ${one/#/\&two}
+
+echo ${one/%/&two}
+echo ${one/%/\&two}
+
+echo ${null/#/&two}
+echo ${null/#/\&two}
+
+echo ${one/#?/&two}
+echo ${one/#?/\&two}
diff --git a/tests/new-exp2.sub b/tests/new-exp2.sub
new file mode 100644
index 0000000..8dfe788
--- /dev/null
+++ b/tests/new-exp2.sub
@@ -0,0 +1,62 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+export LC_ALL=C
+export LANG=C
+
+# test out the new $(< filename) code
+# it should be exactly equivalent to $(cat filename)
+
+FILENAME=$TMPDIR/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=$(< $TMPDIR/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
+exec 3>&2
+exec 2>/dev/null
+LINES2=$(< $TMPDIR/bashtmp.x*)
+exec 2>&3
+if [[ $LINES2 -gt 0 ]]; then
+ echo "whoops: redirection glob expansion should be disabled in posix mode" >&2
+fi
+set +o posix
+
+# now see what happens when we try it with a non-existent file
+rm -f /tmp/redir-notthere
+LINES3=$(< /tmp/redir-notthere)
+echo $?
+
+# These were bugs through bash-4.2
+{ : "$({xxxxxxxxxxxxxxxxxxxx}</dev/stdin)"; } <<<'hi'
+echo ${xxxxxxxxxxxxxxxxxxxx}
+
+{ echo "$(1111111111111111111111</dev/stdin)"; } <<<'hi'
diff --git a/tests/new-exp3.sub b/tests/new-exp3.sub
new file mode 100644
index 0000000..a0c6586
--- /dev/null
+++ b/tests/new-exp3.sub
@@ -0,0 +1,43 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+:
+# Set up some dummy variables beginning with _Q
+_QUANTITY=
+_QUOTA=
+_QUOTE=
+_QUILL=
+_QUEST=
+_QUART=
+
+recho ${!_Q*}
+recho ${!_Q@} # compatibility
+
+IFS="-$IFS"
+
+recho ${!_Q*}
+recho "${!_Q*}"
+
+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..e491f5c
--- /dev/null
+++ b/tests/new-exp4.sub
@@ -0,0 +1,43 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+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..cb203a7
--- /dev/null
+++ b/tests/new-exp5.sub
@@ -0,0 +1,53 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+x=(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..83b041a
--- /dev/null
+++ b/tests/new-exp6.sub
@@ -0,0 +1,42 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# 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/new-exp8.sub b/tests/new-exp8.sub
new file mode 100644
index 0000000..9effec5
--- /dev/null
+++ b/tests/new-exp8.sub
@@ -0,0 +1,129 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+pat1='str'
+pat2='[^;]'
+pat3='[[:alnum:]_]'
+pat4='[[:alnum:]][[fu]b'
+pat5='?tr'
+pat6='?tr\'
+pat7='[[:alnum:]]_'
+pat8='*tr'
+
+declare z="start"
+declare NUM=1000
+
+#----------------------------------
+# create a long string with ';'
+#----------------------------------
+for ((i=0; i<$NUM; i++)); do
+ z="$z;string$i"
+done
+
+#z="$z;string;foo"
+
+#------------------------------
+# delete everything except ';'
+#------------------------------
+
+# try different patterns here
+x="${z//$pat1}"
+echo $x
+x="${z//$pat2}"
+echo $x
+x="${z//$pat3}"
+echo $x
+x="${z//$pat4}"
+echo $x
+x="${z//$pat5}"
+echo $x
+x="${z//$pat6}"
+echo $x
+x="${z//$pat7}"
+echo $x
+x="${z//$pat8}"
+echo $x
+
+
+declare z="start"
+declare NUM=1000
+
+#----------------------------------
+# create a long string with ';'
+#----------------------------------
+for ((i=0; i<$NUM; i++)); do
+ z="$z;string$i"
+done
+
+#z="$z;string;foo"
+
+#------------------------------
+# delete everything except ';'
+#------------------------------
+
+# try different patterns here
+x="${z//[^;]}"
+echo $x
+x="${z/#[^;][^;]}"
+echo $x
+x="${z/%[^;][^;]}"
+echo $x
+
+export LANG=C LC_ALL=C LC_CTYPE=C
+
+# try different patterns here
+x="${z//$pat1}"
+echo $x
+x="${z//$pat2}"
+echo $x
+x="${z//$pat3}"
+echo $x
+x="${z//$pat4}"
+echo $x
+x="${z//$pat5}"
+echo $x
+x="${z//$pat6}"
+echo $x
+x="${z//$pat7}"
+echo $x
+x="${z//$pat8}"
+echo $x
+
+# try different patterns here
+x="${z//[^;]}"
+echo $x
+x="${z/#[^;][^;]}"
+echo $x
+x="${z/%[^;][^;]}"
+echo $x
+
+# post-bash-4.3 changes to make pattern replacement honor nocasematch variable
+unset string
+string=abcd
+
+shopt -s nocasematch
+
+echo ${string//A/z}
+echo ${string//BC/x}
+echo ${string//[BC]/x}
+echo ${string//[bC]/x}
+echo ${string//?/z}
+
+LC_ALL=C
+echo ${string//A/z}
+echo ${string//BC/x}
+echo ${string//[BC]/x}
+echo ${string//[bC]/x}
+echo ${string//?/z}
+
+
diff --git a/tests/new-exp9.sub b/tests/new-exp9.sub
new file mode 100644
index 0000000..799f192
--- /dev/null
+++ b/tests/new-exp9.sub
@@ -0,0 +1,44 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+indirarray()
+{
+ local intermediary
+ local sub
+
+ intermediary="${1}[@]"
+ local -a leftValue=("${!intermediary}")
+
+ local -a leftSub
+ eval leftSub=(\"\${!${1}[@]}\")
+
+ echo "$1" Value = ${leftValue[@]}
+ echo "$1" Sub = ${leftSub[@]}
+}
+
+a=(1 2 3 4 5)
+b=(a b c d e)
+
+c=([0]=10 [2]=20 [4]=40 [8]=80)
+
+indirarray a
+indirarray b
+indirarray c
+
+ref=a
+tmp="$ref[@]"
+printf "<%s> " "${!tmp}"; echo # Iterate whole array.
+
+ref=c
+tmp="$ref[@]"
+printf "<%s> " "${!tmp}"; echo # Iterate whole array.
diff --git a/tests/nquote.right b/tests/nquote.right
new file mode 100644
index 0000000..31c35c3
--- /dev/null
+++ b/tests/nquote.right
@@ -0,0 +1,80 @@
+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'>
+argv[1] = <a^Ib^Ic>
+argv[1] = <$'a\tb\tc'>
+ AD
+E
+hello' world
+hello world!
+hello' world!
+' | '
+' | '
+x | x
+x | x
+' | '
+' | '
+' | '
+' | '
+' | '
+' | '
+x | x
+'
+$'\''
+'
+'abcd'
+$'\'abcd\''
+'
+1
+argv[1] = <^?>
+0000000 del nl
+0000002
+0000000 esc fs gs rs us del nl
+0000007
+\q
+foo
+./nquote4.sub: line 6: quux: command not found
+argv[1] = <a^A)b>
+argv[1] = <a^Ab>
+argv[1] = <^A>
+argv[1] = <\^A>
+0000000 a $ ' \ 0 1 ' b \n a 001 b \n
+0000015
+0000000 a $ ' \ 0 1 ' b \n a 001 b \n
+0000015
+0000000 A \n A \n
+0000004
diff --git a/tests/nquote.tests b/tests/nquote.tests
new file mode 100644
index 0000000..e4d1a56
--- /dev/null
+++ b/tests/nquote.tests
@@ -0,0 +1,142 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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' )"
+
+# tests for $'...' not being expanded when inside double quotes
+recho $'a\tb\tc'
+recho "$'a\tb\tc'"
+
+# tests for $'...' being expanded in command substitution, and when
+echo "$(echo $'\t\t\101\104\n\105')"
+
+${THIS_SH} ./nquote1.sub
+${THIS_SH} ./nquote2.sub
+${THIS_SH} ./nquote3.sub
+${THIS_SH} ./nquote4.sub
+${THIS_SH} ./nquote5.sub
diff --git a/tests/nquote1.right b/tests/nquote1.right
new file mode 100644
index 0000000..45389ef
--- /dev/null
+++ b/tests/nquote1.right
@@ -0,0 +1,131 @@
+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>
+argv[1] = <aa1>
+argv[2] = <uv^A^A>
+argv[1] = <aa2>
+argv[2] = <uv^A^A>
+argv[1] = <aa3>
+argv[2] = <uv^A^Awx>
+argv[3] = <uv^A^Awx>
+argv[1] = <aa4>
+argv[2] = <uv^A^Awx>
+argv[3] = <uv^A^Awx>
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..679976c
--- /dev/null
+++ b/tests/nquote1.tests
@@ -0,0 +1,119 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+a=$'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}"
+
+declare -A assoc
+assoc=( [0]=$e [1]=$e )
+
+recho aa1 ${assoc:0:4}
+recho aa2 "${assoc:0:4}"
+
+recho aa3 ${assoc[@]:0:2}
+recho aa4 "${assoc[@]:0: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.sub b/tests/nquote2.sub
new file mode 100644
index 0000000..bfe2b19
--- /dev/null
+++ b/tests/nquote2.sub
@@ -0,0 +1,42 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+t() {
+ printf '%s | %s\n' "$1" "$2"
+ }
+ v="'" # v <- '
+
+ #--
+ t "${v/$'\''/$'\''}" "'"
+ t ${v/$'\''/$'\''} "'"
+ t "${v/$'\''/x}" "x"
+ t ${v/$'\''/x} "x"
+ t "${v/x/$'\''}" "'"
+ t ${v/x/$'\''} "'"
+ t "${v/x/$'\x5c\''}" "'"
+ t ${v/x/$'\x5c\''} "'"
+ t "${v/\'/\'}" "'"
+ t ${v/\'/\'} "'"
+ t ${v/\'/x} "x"
+
+echo "'"
+echo "$'\''"
+
+echo $'\''
+
+echo $'\'abcd\''
+echo "$'\'abcd\''"
+
+v=1
+echo ${v/1/\'}
+echo ${v/\'/2}
diff --git a/tests/nquote2.tests b/tests/nquote2.tests
new file mode 100644
index 0000000..e3af99a
--- /dev/null
+++ b/tests/nquote2.tests
@@ -0,0 +1,95 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+a=$'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.sub b/tests/nquote3.sub
new file mode 100644
index 0000000..d1480c0
--- /dev/null
+++ b/tests/nquote3.sub
@@ -0,0 +1,8 @@
+. ./test-glue-functions
+
+recho $'\c?'
+
+echo $'\c?' | od -t a | _intl_normalize_spaces
+echo $'\c[\c\\\c]\c^\c_\c?' | od -t a | _intl_normalize_spaces
+
+echo $'\q'
diff --git a/tests/nquote3.tests b/tests/nquote3.tests
new file mode 100644
index 0000000..44b51c4
--- /dev/null
+++ b/tests/nquote3.tests
@@ -0,0 +1,98 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+a=$'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.sub b/tests/nquote4.sub
new file mode 100644
index 0000000..0d4a495
--- /dev/null
+++ b/tests/nquote4.sub
@@ -0,0 +1,6 @@
+# make sure aliases containing new-style single quotes are expanded correctly
+
+shopt -s expand_aliases
+alias foo=$'echo foo\n\nquux\n'
+
+foo
diff --git a/tests/nquote4.tests b/tests/nquote4.tests
new file mode 100644
index 0000000..5c67705
--- /dev/null
+++ b/tests/nquote4.tests
@@ -0,0 +1,37 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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.sub b/tests/nquote5.sub
new file mode 100644
index 0000000..97cbadc
--- /dev/null
+++ b/tests/nquote5.sub
@@ -0,0 +1,36 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+. test-glue-functions
+
+recho $( echo a$'\01)'b )
+recho $( echo ab )
+recho $( echo \ )
+recho $( echo \\ )
+
+LC_CTYPE=C
+od -c <<EOF | _intl_normalize_spaces
+a$'\01'b
+ab
+EOF
+
+od -c <<EOF | _intl_normalize_spaces
+${none-a$'\01'b}
+${none-ab}
+EOF
+
+V=Aa$'\01'b
+od -c <<EOF | _intl_normalize_spaces
+${V%a$'\01'b}
+${V%ab}
+EOF
diff --git a/tests/nquote5.tests b/tests/nquote5.tests
new file mode 100644
index 0000000..ca0308d
--- /dev/null
+++ b/tests/nquote5.tests
@@ -0,0 +1,76 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+a=$'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/parser.right b/tests/parser.right
new file mode 100644
index 0000000..3a01004
--- /dev/null
+++ b/tests/parser.right
@@ -0,0 +1,16 @@
+AAA
+bash5: line 1: `invalid-name': not a valid identifier
+in
+in
+in
+in
+bash5: -c: line 1: syntax error near unexpected token `)'
+bash5: -c: line 1: `case x in esac) echo done; esac'
+in
+bash5: -c: line 1: syntax error near unexpected token `do'
+bash5: -c: line 1: `case in do do) echo in; esac'
+bash5: -c: line 1: syntax error near unexpected token `('
+bash5: -c: line 1: `for()'
+in
+done
+ok 1
diff --git a/tests/parser.tests b/tests/parser.tests
new file mode 100644
index 0000000..6e020a4
--- /dev/null
+++ b/tests/parser.tests
@@ -0,0 +1,6 @@
+# catch-all for parsing problems that don't fit anywhere else
+
+# this has to be in a separate file to get desired EOF behavior
+${THIS_SH} ./parser1.sub
+
+${THIS_SH} ./posix2syntax.sub
diff --git a/tests/parser1.sub b/tests/parser1.sub
new file mode 100644
index 0000000..5031931
--- /dev/null
+++ b/tests/parser1.sub
@@ -0,0 +1 @@
+eval "array=(foo bar)" ; echo AAA\
diff --git a/tests/posix2.right b/tests/posix2.right
new file mode 100644
index 0000000..5d3f734
--- /dev/null
+++ b/tests/posix2.right
@@ -0,0 +1,4 @@
+Testing for POSIX.2 conformance
+./posix2.tests: eval: line 199: syntax error near unexpected token `)'
+./posix2.tests: eval: line 199: `case esac in esac) ;; *) echo "case esac test 4";; esac'
+All tests passed
diff --git a/tests/posix2.tests b/tests/posix2.tests
new file mode 100644
index 0000000..0f5fce1
--- /dev/null
+++ b/tests/posix2.tests
@@ -0,0 +1,206 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# 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
+
+# these are Posix.2 shell grammar rule 4, problems through bash-4.3
+newtest
+case esac in (foo|esac) ;; *) testfail "case esac test 1" ;; esac
+newtest
+case esac in foo|esac) ;; *) testfail "case esac test 2" ;; esac
+
+# POSIX.2 grammar rule 4 problem through bash-5.1
+newtest
+eval 'case esac in (esac) ;; *) testfail "case esac test 3" ;; esac'
+
+# these are supposed to be syntax errors
+newtest
+eval 'case esac in esac) ;; *) echo "case esac test 4";; esac' && testfail 'case esac test 4'
+
+if [ $exitval = 0 ]; then
+ echo "All tests passed"
+else
+ echo "$exitval of $numtests tests failed"
+fi
+exit $exitval
diff --git a/tests/posix2syntax.sub b/tests/posix2syntax.sub
new file mode 100644
index 0000000..39af9a5
--- /dev/null
+++ b/tests/posix2syntax.sub
@@ -0,0 +1,66 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: ${THIS_SH:=./bash}
+bashname=bash${BASH_VERSION%%.*}
+
+# tests for Posix grammar special cases
+
+# Posix grammar rule 5
+${THIS_SH} -c 'for invalid-name in a b c; do echo error; done' $bashname
+
+# Posix grammar rule 6: third word in FOR or SELECT
+for i; do echo; done; echo in
+for i; do echo in; done
+for i do echo in; done
+
+select i; do echo; done; echo in
+select i; do echo in; done; echo in
+select i do echo in; done; echo in
+
+# Posix grammar rule 4: when PATTERN == ESAC, return ESAC
+${THIS_SH} -c 'case x in esac) echo done; esac' $bashname
+
+# Posix grammar rule 6: third word in CASE
+${THIS_SH} -c 'case in in in) echo in; esac;' $bashname
+${THIS_SH} -c 'case in do do) echo in; esac' $bashname
+
+# Posix grammar rule 8: function NAME
+${THIS_SH} -o posix -c 'for()
+{
+echo function for;
+}' $bashname
+
+for for in for; do echo in; echo done; done
+
+${THIS_SH} -c 'for (( i = 0; i < 5; i++ )) do : ; done' $bashname
+${THIS_SH} -c 'for (( i = 0; i < 5; i++ )) { : ; }' $bashname
+
+# bug report: IN turning on unwanted alias expansion
+${THIS_SH} -o posix -c '
+alias foo='two words'
+foo_word='foo'
+case "$foo_word"
+in
+ foo) echo "bad 1";;
+esac' $bashname
+
+${THIS_SH} -o posix -c '
+alias foo='oneword'
+foo_word='foo'
+case "$foo_word"
+in
+ foo) echo "ok 1";;
+esac' $bashname
+
+
diff --git a/tests/posixexp.right b/tests/posixexp.right
new file mode 100644
index 0000000..7204b96
--- /dev/null
+++ b/tests/posixexp.right
@@ -0,0 +1,308 @@
+a
+b
+a b
+argv[1] = <a>
+argv[2] = <b>
+argv[3] = <x>
+argv[4] = <a>
+argv[5] = <b>
+argv[1] = <a\ b>
+argv[2] = <x>
+argv[3] = <a\ b>
+argv[1] = <foo 'bar' baz>
+argv[1] = <a b c d>
+argv[1] = <a b c d>
+argv[1] = <foo ax{{{}b c d{} bar>
+argv[2] = <}>
+argv[3] = <baz>
+argv[1] = <'foo'>
+argv[1] = <'foo'>
+argv[1] = <$a>
+argv[1] = <'foo'>
+argv[1] = <foo*bar>
+argv[1] = <foo*bar>
+argv[1] = <foo*bar'}>
+argv[1] = <x'>
+<.> <x> <.> <> <.> <x> <.>
+<x> <.> <w> <.> <x> <.> <w> <.>
+<x> <.> <w> <.> <x> <.> <w> <.>
+<x> <.> <w> <.> <x> <.> <w> <.>
+<.> <w> <.> <> <.> <w> <.>
+<.> <w> <.> <> <.> <w> <.>
+<x> <.> <x> <.> <x> <.> <x> <.>
+<x> <.> <w> <.> <x> <.> <w> <.>
+<x> <.> <w> <.> <x> <.> <w> <.>
+<x> <.> <w> <.> <x> <.> <w> <.>
+argv[1] = <'bar>
+argv[1] = <foo 'bar baz>
+argv[1] = <}z>
+argv[1] = <''z}>
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = <1 2>
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = <1 2>
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = <1 2>
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = <1 2>
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = <1 2>
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = <1>
+argv[2] = <2>
+argv[1] = <12>
+argv[1] = <1 2>
+argv[1] = <1 2>
+argv[1] = <1 2>
+argv[1] = <1 2>
+argv[1] = <1 2>
+argv[1] = <1 2>
+argv[1] = <12>
+argv[1] = <12>
+argv[1] = <12>
+argv[1] = <12>
+argv[1] = <12>
+argv[1] = <12>
+argv[1] = <1 2>
+argv[1] = <1 2>
+argv[1] = <12>
+argv[1] = <12>
+normal IFS
+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>
+null IFS
+argv[1] = < abc>
+argv[2] = <def ghi>
+argv[3] = <jkl >
+argv[1] = < abc def ghi jkl >
+argv[1] = < abc>
+argv[2] = <def ghi>
+argv[3] = <jkl >
+non-standard IFS
+argv[1] = < abc>
+argv[2] = <def ghi>
+argv[3] = <jkl >
+argv[1] = < abc def ghi jkl >
+argv[1] = < abc def ghi jkl >
+unset IFS
+argv[1] = < abc>
+argv[2] = <def ghi>
+argv[3] = <jkl >
+argv[1] = < abc def ghi jkl >
+argv[1] = < abc def ghi jkl >
+
+001: IFS = (unset): unset -v foo; set -- ${foo=$*}
+soh stx etx del / soh stx etx del
+
+002: IFS = (unset): unset -v foo; set -- ${foo="$*"}
+soh stx etx del / soh stx etx del
+
+003: IFS = (unset): unset -v foo; set -- "${foo=$*}"
+soh stx etx del / soh stx etx del
+
+004: IFS = (unset): foo=; set -- ${foo:=$*}
+soh stx etx del / soh stx etx del
+
+005: IFS = (unset): foo=; set -- ${foo:="$*"}
+soh stx etx del / soh stx etx del
+
+006: IFS = (unset): foo=; set -- "${foo:=$*}"
+soh stx etx del / soh stx etx del
+
+007: IFS = (unset): unset -v foo; set -- ${foo=$@}
+soh stx etx del / soh stx etx del
+
+008: IFS = (unset): unset -v foo; set -- ${foo="$@"}
+soh stx etx del / soh stx etx del
+
+009: IFS = (unset): unset -v foo; set -- "${foo=$@}"
+soh stx etx del / soh stx etx del
+
+010: IFS = (unset): foo=; set -- ${foo:=$@}
+soh stx etx del / soh stx etx del
+
+011: IFS = (unset): foo=; set -- ${foo:="$@"}
+soh stx etx del / soh stx etx del
+
+012: IFS = (unset): foo=; set -- "${foo:=$@}"
+soh stx etx del / soh stx etx del
+
+013: IFS = (null): unset -v foo; set -- ${foo=$*}
+soh stx etx del / soh stx etx del
+
+014: IFS = (null): unset -v foo; set -- ${foo="$*"}
+soh stx etx del / soh stx etx del
+
+015: IFS = (null): unset -v foo; set -- "${foo=$*}"
+soh stx etx del / soh stx etx del
+
+016: IFS = (null): foo=; set -- ${foo:=$*}
+soh stx etx del / soh stx etx del
+
+017: IFS = (null): foo=; set -- ${foo:="$*"}
+soh stx etx del / soh stx etx del
+
+018: IFS = (null): foo=; set -- "${foo:=$*}"
+soh stx etx del / soh stx etx del
+
+019: IFS = (null): unset -v foo; set -- ${foo=$@}
+soh stx etx del / soh stx etx del
+
+020: IFS = (null): unset -v foo; set -- ${foo="$@"}
+soh stx etx del / soh stx etx del
+
+021: IFS = (null): unset -v foo; set -- "${foo=$@}"
+soh stx etx del / soh stx etx del
+
+022: IFS = (null): foo=; set -- ${foo:=$@}
+soh stx etx del / soh stx etx del
+
+023: IFS = (null): foo=; set -- ${foo:="$@"}
+soh stx etx del / soh stx etx del
+
+024: IFS = (null): foo=; set -- "${foo:=$@}"
+soh stx etx del / soh stx etx del
+
+025: IFS = x: unset -v foo; set -- ${foo=$*}
+soh stx etx del / soh stx etx del
+
+026: IFS = x: unset -v foo; set -- ${foo="$*"}
+soh stx etx del / soh stx etx del
+
+027: IFS = x: unset -v foo; set -- "${foo=$*}"
+soh stx etx del / soh stx etx del
+
+028: IFS = x: foo=; set -- ${foo:=$*}
+soh stx etx del / soh stx etx del
+
+029: IFS = x: foo=; set -- ${foo:="$*"}
+soh stx etx del / soh stx etx del
+
+030: IFS = x: foo=; set -- "${foo:=$*}"
+soh stx etx del / soh stx etx del
+
+031: IFS = x: unset -v foo; set -- ${foo=$@}
+soh stx etx del / soh stx etx del
+
+032: IFS = x: unset -v foo; set -- ${foo="$@"}
+soh stx etx del / soh stx etx del
+
+033: IFS = x: unset -v foo; set -- "${foo=$@}"
+soh stx etx del / soh stx etx del
+
+034: IFS = x: foo=; set -- ${foo:=$@}
+soh stx etx del / soh stx etx del
+
+035: IFS = x: foo=; set -- ${foo:="$@"}
+soh stx etx del / soh stx etx del
+
+036: IFS = x: foo=; set -- "${foo:=$@}"
+soh stx etx del / soh stx etx del
+
+037: IFS = sp ht nl: unset -v foo; set -- ${foo=$*}
+soh stx etx del / soh stx etx del
+
+038: IFS = sp ht nl: unset -v foo; set -- ${foo="$*"}
+soh stx etx del / soh stx etx del
+
+039: IFS = sp ht nl: unset -v foo; set -- "${foo=$*}"
+soh stx etx del / soh stx etx del
+
+040: IFS = sp ht nl: foo=; set -- ${foo:=$*}
+soh stx etx del / soh stx etx del
+
+041: IFS = sp ht nl: foo=; set -- ${foo:="$*"}
+soh stx etx del / soh stx etx del
+
+042: IFS = sp ht nl: foo=; set -- "${foo:=$*}"
+soh stx etx del / soh stx etx del
+
+043: IFS = sp ht nl: unset -v foo; set -- ${foo=$@}
+soh stx etx del / soh stx etx del
+
+044: IFS = sp ht nl: unset -v foo; set -- ${foo="$@"}
+soh stx etx del / soh stx etx del
+
+045: IFS = sp ht nl: unset -v foo; set -- "${foo=$@}"
+soh stx etx del / soh stx etx del
+
+046: IFS = sp ht nl: foo=; set -- ${foo:=$@}
+soh stx etx del / soh stx etx del
+
+047: IFS = sp ht nl: foo=; set -- ${foo:="$@"}
+soh stx etx del / soh stx etx del
+
+048: IFS = sp ht nl: foo=; set -- "${foo:=$@}"
+soh stx etx del / soh stx etx del
+argv[1] = <^A^B^C^?>
+argv[1] = <^A^B^C^?>
+argv[1] = <^A^B^C^?>
+argv[1] = <^A^B^C^?>
+argv[1] = <^A^B^C^?>
+argv[1] = <^A^B^C^?>
+argv[1] = <^A^B^C^?>
+argv[1] = <^A^B^C^?>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a>
+argv[2] = <b>
+argv[1] = <a>
+argv[2] = <b>
+[ abc def ghi jkl / abc def ghi jkl ]
+[ abc def ghi jkl ]
+[ abc def ghi jkl / abc def ghi jkl / abc def ghi jkl ]
+1: OK
+2: $'not'
+3: OK
+4: OK
+5: tOK
+OK
+OK
+$'not'
+OK
+tOK
+6: $'not\ttoo\nbad'
+OKa ' b
+OKa ' b
+7: OK
+8: OKa ' b
+9: OKa " b
+10: OKa " b
+tOK
+tOK
+tOK
+tOK
+./posixexp7.sub: line 69: ${'x1'%'t'}: bad substitution
+./posixexp7.sub: line 70: ${'x1'%'t'}: bad substitution
+./posixexp7.sub: line 73: ${'x1'%'t'}: bad substitution
+./posixexp7.sub: line 74: ${'x1'%'t'}: bad substitution
+"A"
+A
+argv[1] = <"A">
+argv[1] = <A>
+argv[1] = <A>
+./posixexp.tests: line 97: unexpected EOF while looking for matching `}'
diff --git a/tests/posixexp.tests b/tests/posixexp.tests
new file mode 100644
index 0000000..d8f6644
--- /dev/null
+++ b/tests/posixexp.tests
@@ -0,0 +1,97 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+unset a
+printf "%s\n" ${a:=a\ b}
+echo "$a"
+
+unset v
+recho ${v=a\ b} x ${v=c\ d}
+
+unset v
+recho "${v=a\ b}" x "${v=c\ d}"
+
+unset a v
+
+recho "foo ${IFS+'bar'} baz"
+recho "a ${IFS+b c} d"
+
+recho "a ${IFS+"b c"} d"
+
+u=x
+recho "foo ${IFS+a$u{{{\}b} c ${IFS+d{}} bar" ${IFS-e{}} baz
+
+a=foo
+recho "${IFS+'$a'}"
+recho "${IFS+"'$a'"}"
+
+recho ${IFS+'$a'}
+recho ${IFS+"'$a'"}
+
+unset a u
+x='foo*bar'
+
+recho "${x##"}"}"
+recho "${x##'}'}"
+recho "${x##'}"
+
+recho "${x:-'}'}"
+
+foo="x'a'y"
+recho "${foo%*'a'*}"
+unset x
+
+unset u
+v=w
+printf '<%s> ' ${u+x} . ${v+x} . "${u+x}" . "${v+x}" .; echo
+printf '<%s> ' ${u-x} . ${v-x} . "${u-x}" . "${v-x}" .; echo
+printf '<%s> ' ${u=x} . ${v=x} . "${u=x}" . "${v=x}" .; echo
+printf '<%s> ' ${u?x} . ${v?x} . "${u?x}" . "${v?x}" .; echo
+printf '<%s> ' ${u#x} . ${v#x} . "${u#x}" . "${v#x}" .; echo
+printf '<%s> ' ${u%x} . ${v%x} . "${u%x}" . "${v%x}" .; echo
+printf '<%s> ' ${u:+x} . ${v:+x} . "${u:+x}" . "${v:+x}" .; echo
+printf '<%s> ' ${u:-x} . ${v:-x} . "${u:-x}" . "${v:-x}" .; echo
+printf '<%s> ' ${u:=x} . ${v:=x} . "${u:=x}" . "${v:=x}" .; echo
+printf '<%s> ' ${u:?x} . ${v:?x} . "${u:?x}" . "${v:?x}" .; echo
+# these are invalid substitution operators
+#printf '<%s> ' ${u:#x} . ${v:#x} . "${u:#x}" . "${v:#x}" .; echo
+#printf '<%s> ' ${u:%x} . ${v:%x} . "${u:%x}" . "${v:%x}" .; echo
+
+unset foo
+set -o posix
+
+recho "${IFS+'bar}"
+recho "foo ${IFS+'bar} baz"
+
+recho ${IFS+'}'z}
+recho "${IFS+'}'z}"
+
+: ${TMPDIR:=/var/tmp}
+rm -f $TMPDIR/sh
+cp ${THIS_SH} $TMPDIR/sh
+THIS_SH=$TMPDIR/sh ${THIS_SH} ./posixexp1.sub || echo "sh posixexp1.sub: test $? failed"
+${THIS_SH} ./posixexp1.sub || echo "bash posixexp1.sub: test $? failed"
+
+THIS_SH=$TMPDIR/sh ${THIS_SH} ./posixexp2.sub || echo "sh posixexp2.sub: test $? failed"
+rm -f $TMPDIR/sh
+
+${THIS_SH} ./posixexp3.sub
+${THIS_SH} ./posixexp4.sub
+${THIS_SH} ./posixexp5.sub
+${THIS_SH} ./posixexp6.sub
+${THIS_SH} ./posixexp7.sub
+${THIS_SH} ./posixexp8.sub
+
+# this will be an error
+foo=bar
+echo "${foo:-"a}"
diff --git a/tests/posixexp1.sub b/tests/posixexp1.sub
new file mode 100644
index 0000000..c0d6861
--- /dev/null
+++ b/tests/posixexp1.sub
@@ -0,0 +1,51 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# $FreeBSD: src/tools/regression/bin/sh/expansion/set-u1.0,v 1.2 2010/10/12 18:20:38 obrien Exp $
+
+${THIS_SH} -uc 'unset foo; echo ${foo}' 2>/dev/null && exit 1
+${THIS_SH} -uc 'unset foo; echo $foo' 2>/dev/null && exit 1
+${THIS_SH} -uc 'foo=; echo $foo' >/dev/null || exit 2
+${THIS_SH} -uc 'foo=1; echo $foo' >/dev/null || exit 3
+# -/+/= are unaffected by set -u
+${THIS_SH} -uc 'unset foo; echo ${foo-}' >/dev/null || exit 4
+${THIS_SH} -uc 'unset foo; echo ${foo+}' >/dev/null || exit 5
+${THIS_SH} -uc 'unset foo; echo ${foo=}' >/dev/null || exit 6
+# length/trimming are affected
+${THIS_SH} -uc 'unset foo; echo ${#foo}' 2>/dev/null && exit 7
+${THIS_SH} -uc 'foo=; echo ${#foo}' >/dev/null || exit 8
+${THIS_SH} -uc 'unset foo; echo ${foo#?}' 2>/dev/null && exit 9
+${THIS_SH} -uc 'foo=1; echo ${foo#?}' >/dev/null || exit 10
+${THIS_SH} -uc 'unset foo; echo ${foo##?}' 2>/dev/null && exit 11
+${THIS_SH} -uc 'foo=1; echo ${foo##?}' >/dev/null || exit 12
+${THIS_SH} -uc 'unset foo; echo ${foo%?}' 2>/dev/null && exit 13
+${THIS_SH} -uc 'foo=1; echo ${foo%?}' >/dev/null || exit 14
+${THIS_SH} -uc 'unset foo; echo ${foo%%?}' 2>/dev/null && exit 15
+${THIS_SH} -uc 'foo=1; echo ${foo%%?}' >/dev/null || exit 16
+
+${THIS_SH} -uc 'echo $!' 2>/dev/null && exit 17
+${THIS_SH} -uc ':& echo $!' >/dev/null || exit 18
+${THIS_SH} -uc 'echo $#' >/dev/null || exit 19
+${THIS_SH} -uc 'echo $1' 2>/dev/null && exit 20
+${THIS_SH} -uc 'echo $1' ${THIS_SH} xnotthere >/dev/null || exit 21
+${THIS_SH} -uc 'echo $2' ${THIS_SH} xnotthere 2>/dev/null && exit 22
+${THIS_SH} -uc 'echo $2' ${THIS_SH} xnotthere ynotthere >/dev/null || exit 23
+
+${THIS_SH} -uc 'echo $! ; exit 24' 2>/dev/null
+${THIS_SH} -uc 'echo ${!} ; exit 25' 2>/dev/null
+${THIS_SH} -uc 'echo ${!,} ; exit 26' 2>/dev/null
+
+${THIS_SH} -uc 'echo ${!-ok 27} >/dev/null || exit 27'
+${THIS_SH} -uc 'echo ${2-ok 28} >/dev/null || exit 28'
+
+exit 0
diff --git a/tests/posixexp2.right b/tests/posixexp2.right
new file mode 100644
index 0000000..08d3901
--- /dev/null
+++ b/tests/posixexp2.right
@@ -0,0 +1,40 @@
+1 }z
+2 ''z}
+3 foo 'bar baz
+4 foo b c baz
+5 foo b c baz
+6 }z
+7 }z
+8 ""z}
+9 "}"z
+10 foo bar} baz
+11 ''z}
+12 }z
+13 }z
+14 }z
+15 <foo abx{ {{{}b c d{} bar> <}> <baz> .
+16 hi there
+17 hi there
+18 hi there
+19 hi there
+20 hi there
+21 hi there
+22 hi there
+23 hi there
+24 'value'
+25 'value'
+26 $key
+27 'value'
+28 'x ~ x''x}"x}" #
+29 <foo> <abx{ {{> <{}b> <c> <d{}> <bar> <}> <baz> .
+30 <foo> <b\
+ar> <baz> .
+32 <foo> <bar> <baz> .
+33 <foo 'bar' baz> .
+34 <foo bar baz> .
+35 <a> <b> <x> <a> <b> .
+36 <a\ b> <x> <a\ b> .
+37 <a b> <x> <c d> .
+38 xay / x'a'y .
+39 x' / x' .
+40 < b c> .
diff --git a/tests/posixexp2.sub b/tests/posixexp2.sub
new file mode 100644
index 0000000..5c46192
--- /dev/null
+++ b/tests/posixexp2.sub
@@ -0,0 +1,37 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+x=a\ b
+[ "$x" = "${x?}" ] || exit 1
+set -- ${x?}
+{ [ "$#" = 2 ] && [ "$1" = a ] && [ "$2" = b ]; } || exit 1
+unset x
+(echo ${x?abcdefg}) 2>&1 | grep abcdefg >/dev/null || exit 1
+${THIS_SH} -c 'unset foo; echo ${foo?}' 2>/dev/null && exit 2
+${THIS_SH} -c 'foo=; echo ${foo:?}' 2>/dev/null && exit 3
+${THIS_SH} -c 'foo=; echo ${foo?}' >/dev/null || exit 4
+${THIS_SH} -c 'foo=1; echo ${foo:?}' >/dev/null || exit 5
+${THIS_SH} -c 'echo ${!?}' 2>/dev/null && exit 6
+${THIS_SH} -c ':& echo ${!?}' >/dev/null || exit 7
+${THIS_SH} -c 'echo ${#?}' >/dev/null || exit 8
+${THIS_SH} -c 'echo ${*?}' 2>/dev/null && exit 9
+${THIS_SH} -c 'echo ${*?}' ${THIS_SH} x >/dev/null || exit 10
+${THIS_SH} -c 'echo ${1?}' 2>/dev/null && exit 11
+${THIS_SH} -c 'echo ${1?}' ${THIS_SH} x >/dev/null || exit 12
+${THIS_SH} -c 'echo ${2?}' ${THIS_SH} x 2>/dev/null && exit 13
+${THIS_SH} -c 'echo ${2?}' ${THIS_SH} x y >/dev/null || exit 14
+
+${THIS_SH} -c $'echo $(( x+ )) \n exit 0' ${THIS_SH} 2>/dev/null && exit 15
+
+exit 0
diff --git a/tests/posixexp2.tests b/tests/posixexp2.tests
new file mode 100644
index 0000000..5f2392b
--- /dev/null
+++ b/tests/posixexp2.tests
@@ -0,0 +1,60 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# From mksh
+
+set -o posix ; shopt -u xpg_echo
+
+(echo 1 ${IFS+'}'z}) 2>&- || echo failed in 1
+(echo 2 "${IFS+'}'z}") 2>&- || echo failed in 2
+(echo 3 "foo ${IFS+'bar} baz") 2>&- || echo failed in 3
+(echo -n '4 '; printf '%s\n' "foo ${IFS+"b c"} baz") 2>&- || echo failed in 4
+(echo -n '5 '; printf '%s\n' "foo ${IFS+b c} baz") 2>&- || echo failed in 5
+(echo 6 ${IFS+"}"z}) 2>&- || echo failed in 6
+(echo 7 "${IFS+"}"z}") 2>&- || echo failed in 7
+(echo 8 "${IFS+\"}\"z}") 2>&- || echo failed in 8
+(echo 9 "${IFS+\"\}\"z}") 2>&- || echo failed in 9
+(echo 10 foo ${IFS+'bar} baz'}) 2>&- || echo failed in 10
+(echo 11 "$(echo "${IFS+'}'z}")") 2>&- || echo failed in 11
+(echo 12 "$(echo ${IFS+'}'z})") 2>&- || echo failed in 12
+(echo 13 ${IFS+\}z}) 2>&- || echo failed in 13
+(echo 14 "${IFS+\}z}") 2>&- || echo failed in 14
+u=x; (echo -n '15 '; printf '<%s> ' "foo ${IFS+a"b$u{ {"{{\}b} c ${IFS+d{}} bar" ${IFS-e{}} baz; echo .) 2>&- || echo failed in 15
+l=t; (echo 16 ${IFS+h`echo -n i ${IFS+$l}h`ere}) 2>&- || echo failed in 16
+l=t; (echo 17 ${IFS+h$(echo -n i ${IFS+$l}h)ere}) 2>&- || echo failed in 17
+l=t; (echo 18 "${IFS+h`echo -n i ${IFS+$l}h`ere}") 2>&- || echo failed in 18
+l=t; (echo 19 "${IFS+h$(echo -n i ${IFS+$l}h)ere}") 2>&- || echo failed in 19
+l=t; (echo 20 ${IFS+h`echo -n i "${IFS+$l}"h`ere}) 2>&- || echo failed in 20
+l=t; (echo 21 ${IFS+h$(echo -n i "${IFS+$l}"h)ere}) 2>&- || echo failed in 21
+l=t; (echo 22 "${IFS+h`echo -n i "${IFS+$l}"h`ere}") 2>&- || echo failed in 22
+l=t; (echo 23 "${IFS+h$(echo -n i "${IFS+$l}"h)ere}") 2>&- || echo failed in 23
+key=value; (echo -n '24 '; printf '%s\n' "${IFS+'$key'}") 2>&- || echo failed in 24
+key=value; (echo -n '25 '; printf '%s\n' "${IFS+"'$key'"}") 2>&- || echo failed in 25 # ksh93: “'$key'â€
+key=value; (echo -n '26 '; printf '%s\n' ${IFS+'$key'}) 2>&- || echo failed in 26
+key=value; (echo -n '27 '; printf '%s\n' ${IFS+"'$key'"}) 2>&- || echo failed in 27
+(echo -n '28 '; printf '%s\n' "${IFS+"'"x ~ x'}'x"'}"x}" #') 2>&- || echo failed in 28
+u=x; (echo -n '29 '; printf '<%s> ' foo ${IFS+a"b$u{ {"{ {\}b} c ${IFS+d{}} bar ${IFS-e{}} baz; echo .) 2>&- || echo failed in 29
+(echo -n '30 '; printf '<%s> ' ${IFS+foo 'b\
+ar' baz}; echo .) 2>&- || (echo failed in 30; echo failed in 31)
+(echo -n '32 '; printf '<%s> ' ${IFS+foo "b\
+ar" baz}; echo .) 2>&- || echo failed in 32
+(echo -n '33 '; printf '<%s> ' "${IFS+foo 'b\
+ar' baz}"; echo .) 2>&- || echo failed in 33
+(echo -n '34 '; printf '<%s> ' "${IFS+foo "b\
+ar" baz}"; echo .) 2>&- || echo failed in 34
+(echo -n '35 '; printf '<%s> ' ${v=a\ b} x ${v=c\ d}; echo .) 2>&- || echo failed in 35
+(echo -n '36 '; printf '<%s> ' "${v=a\ b}" x "${v=c\ d}"; echo .) 2>&- || echo failed in 36
+(echo -n '37 '; printf '<%s> ' ${v-a\ b} x ${v-c\ d}; echo .) 2>&- || echo failed in 37
+(echo 38 ${IFS+x'a'y} / "${IFS+x'a'y}" .) 2>&- || echo failed in 38
+foo="x'a'y"; (echo 39 ${foo%*'a'*} / "${foo%*'a'*}" .) 2>&- || echo failed in 39
+foo="a b c"; (echo -n '40 '; printf '<%s> ' "${foo#a}"; echo .) 2>&- || echo failed in 40
diff --git a/tests/posixexp3.sub b/tests/posixexp3.sub
new file mode 100644
index 0000000..343adfe
--- /dev/null
+++ b/tests/posixexp3.sub
@@ -0,0 +1,65 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+set -- 1 2
+
+unset var
+recho ${var-$@}
+recho ${var-"$@"}
+recho ${var-$*}
+recho ${var-"$*"}
+
+unset -v a b c d
+recho ${a=$@}
+recho "$a"
+recho ${b="$@"}
+recho "$b"
+recho ${c=$*}
+recho "$c"
+recho ${d="$*"}
+recho "$d"
+
+IFS=
+unset var
+recho ${var-$@}
+recho ${var-"$@"}
+recho ${var-$*}
+recho ${var-"$*"}
+
+unset -v a b c d
+# Posix interp 221
+# there should never be any word splitting because IFS is null
+recho ${a=$@}
+recho "$a"
+recho $a
+recho ${b="$@"}
+recho "$b"
+recho $b
+recho ${c=$*}
+recho "$c"
+recho $c
+recho ${d="$*"}
+recho "$d"
+recho $d
+
+unset -v a b c d
+a=$@
+recho $a
+b="$@"
+recho $b
+c=$*
+recho $c
+d="$*"
+recho $d
+
+unset -v parameter a b c d
diff --git a/tests/posixexp4.sub b/tests/posixexp4.sub
new file mode 100644
index 0000000..9d48b2f
--- /dev/null
+++ b/tests/posixexp4.sub
@@ -0,0 +1,44 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+set -- ' abc' 'def ghi' 'jkl '
+
+echo normal IFS
+recho $@
+: ${var=$@}
+recho $var
+unset -v var
+recho ${var-$@}
+
+echo null IFS
+IFS=
+recho $@
+: ${var=$@}
+recho $var
+unset -v var
+recho ${var-$@}
+
+echo non-standard IFS
+IFS=:
+recho $@
+: ${var=$@}
+recho $var
+unset -v var
+recho ${var-$@} # this is inconsistent
+
+echo unset IFS
+recho $@
+: ${var=$@}
+recho $var
+unset -v var
+recho ${var-$@}
diff --git a/tests/posixexp5.sub b/tests/posixexp5.sub
new file mode 100644
index 0000000..b0e1c03
--- /dev/null
+++ b/tests/posixexp5.sub
@@ -0,0 +1,64 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test suite contribution from Martijn Dekker
+
+defaultIFS=$IFS
+set -o errexit -o noglob
+(set -o pipefail) 2>/dev/null && set -o pipefail
+teststring=$(printf '\1\2\3\177')
+n=0
+
+trim_od() {
+ od -t a | sed -n '1 { s/^0*[[:blank:]]*//; s/[[:blank:]]*$//; p; }'
+}
+
+doTest() {
+ set -- "$teststring"
+ eval "$testcmd"
+ case ${IFS+s}${IFS:+n} in
+ ( sn ) i=$(printf %s "$IFS" | trim_od) ;;
+ ( s ) i='(null)' ;;
+ ( '' ) i='(unset)' ;;
+ ( * ) echo 'internal error!' >&2; exit 125 ;;
+ esac
+ printf '\n%03d: IFS = %s: %s\n' "$((n+=1))" "$i" "$testcmd"
+ printf %s "$*${foo+/}${foo-}" | trim_od
+}
+
+doAllTests() {
+ for testcmd in \
+ 'unset -v foo; set -- ${foo=$*}' \
+ 'unset -v foo; set -- ${foo="$*"}' \
+ 'unset -v foo; set -- "${foo=$*}"' \
+ \
+ 'foo=; set -- ${foo:=$*}' \
+ 'foo=; set -- ${foo:="$*"}' \
+ 'foo=; set -- "${foo:=$*}"' \
+ \
+ 'unset -v foo; set -- ${foo=$@}' \
+ 'unset -v foo; set -- ${foo="$@"}' \
+ 'unset -v foo; set -- "${foo=$@}"' \
+ \
+ 'foo=; set -- ${foo:=$@}' \
+ 'foo=; set -- ${foo:="$@"}' \
+ 'foo=; set -- "${foo:=$@}"'
+ do
+ doTest "$testcmd"
+ done
+}
+
+unset -v IFS; doAllTests
+IFS=''; doAllTests
+IFS='x'; doAllTests
+IFS=$defaultIFS; doAllTests
diff --git a/tests/posixexp6.sub b/tests/posixexp6.sub
new file mode 100644
index 0000000..b89b87f
--- /dev/null
+++ b/tests/posixexp6.sub
@@ -0,0 +1,70 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+var=$'\01\02\03\177'
+
+bar=${unset:-$var}
+recho "$bar"
+unset -v bar
+bar=${unset:-"$var"}
+recho "$bar"
+
+foo=${parameter:=$var}
+
+recho "$foo"
+recho "$parameter"
+
+unset -v foo parameter
+
+foo=${parameter:="$var"}
+
+recho "$foo"
+recho "$parameter"
+
+unset -v foo parameter
+
+foo="${parameter:=$var}"
+
+recho "$foo"
+recho "$parameter"
+
+unset -v foo parameter
+
+recho ${parameter:=a\ b}
+unset -v parameter
+
+recho ${parameter:="a b"}
+unset -v parameter
+
+v='a b'
+
+recho ${parameter:=$v}
+unset -v parameter
+
+recho ${parameter:="$v"}
+unset -v parameter
+
+# unsetting IFS here
+
+set " abc " " def ghi " "jkl "
+unset -v IFS var
+var=${var-$*}/${var-$*}
+printf '[%s]\n' "$var"
+
+unset -v var
+: ${var=$*}
+printf '[%s]\n' "$var"
+
+unset -v var
+: ${var:=$*/$*/${var-$*}}
+printf '[%s]\n' "$var"
diff --git a/tests/posixexp7.sub b/tests/posixexp7.sub
new file mode 100644
index 0000000..4e3fa00
--- /dev/null
+++ b/tests/posixexp7.sub
@@ -0,0 +1,76 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test the effect of quotes on the WORD in the posix pattern removal operators
+#
+x=notOK
+x1=not
+
+cat <<EOF
+1: ${x#$'not'}
+2: $'not'
+3: ${x#"not"}
+4: ${x#'not'}
+5: ${x#${x1%'t'}}
+EOF
+
+echo "${x#'not'}"
+echo "${x#$'not'}"
+
+echo "$'not'"
+echo "${x#"not"}"
+echo "${x#${x1%'t'}}"
+
+cat <<EOF
+6: $'not\ttoo\nbad'
+EOF
+
+x=OK$'a\t\'\tb'
+echo OK$'a\t\'\tb'
+echo "$x"
+
+cat <<EOF
+7: ${x%$'a\t\'\tb'}
+8: ${x#$'a\t\'\tb'}
+EOF
+
+x=OK'a " b'
+
+cat <<EOF
+9: ${x#'a " b'}
+10: ${x#$'a " b'}
+EOF
+
+x=notOK
+x1=not
+
+# extquote makes these work
+echo "${x#${$'x1'%$'t'}}"
+cat <<EOF
+${x#${$'x1'%$'t'}}
+EOF
+echo "${x#${$'x1'%'t'}}"
+cat <<EOF
+${x#${$'x1'%'t'}}
+EOF
+
+# syntax errors
+
+echo "${x#${'x1'%'t'}}"
+cat <<EOF
+${x#${'x1'%'t'}}
+EOF
+echo "${x#${'x1'%$'t'}}"
+cat <<EOF
+${x#${'x1'%$'t'}}
+EOF
diff --git a/tests/posixexp8.sub b/tests/posixexp8.sub
new file mode 100644
index 0000000..383851c
--- /dev/null
+++ b/tests/posixexp8.sub
@@ -0,0 +1,11 @@
+P=A
+
+cat << EOF
+${P+\"$P\"}
+${P+"$P"}
+EOF
+
+recho "${P+\"$P\"}"
+
+recho "${P+"$P"}"
+recho ${P+"$P"}
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..5a7bafd
--- /dev/null
+++ b/tests/posixpat.tests
@@ -0,0 +1,247 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# A 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
+
+case a in
+[:al:]) echo ok 5;;
+esac
+
+# invalid character class expressions are no longer just characters to be
+# matched
+case a in
+[[:al:]) echo bad 6;;
+*) 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/posixpipe.right b/tests/posixpipe.right
new file mode 100644
index 0000000..8f6c9cb
--- /dev/null
+++ b/tests/posixpipe.right
@@ -0,0 +1,41 @@
+1
+0
+a
+real 0.00
+user 0.00
+sys 0.00
+1
+a
+real 0.00
+user 0.00
+sys 0.00
+1
+tfunc is a function
+tfunc ()
+{
+ time
+}
+1
+0
+1
+a
+real 0.00
+user 0.00
+sys 0.00
+0
+a
+real 0.00
+user 0.00
+sys 0.00
+0
+a
+real 0.00
+user 0.00
+sys 0.00
+0
+1
+0
+a
+real 0.00
+user 0.00
+sys 0.00
diff --git a/tests/posixpipe.tests b/tests/posixpipe.tests
new file mode 100644
index 0000000..fa8febe
--- /dev/null
+++ b/tests/posixpipe.tests
@@ -0,0 +1,56 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Test timed and negated pipelines in bash-4.2 and later
+export TIMEFORMAT=$'real %2R\nuser %2U\nsys %2S'
+
+!
+echo $?
+
+! !
+echo $?
+
+time ! echo a
+echo $?
+
+! time echo a
+echo $?
+
+tfunc()
+{
+ time
+}
+
+type tfunc
+
+! true
+echo $?
+! ! true
+echo $?
+! ! ! true
+echo $?
+
+time time echo a
+echo $?
+
+time time -p echo a
+echo $?
+time -p time echo a
+echo $?
+
+!
+echo $?
+! !
+echo $?
+
+time -p -- echo a
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.tests b/tests/precedence.tests
new file mode 100644
index 0000000..111bd23
--- /dev/null
+++ b/tests/precedence.tests
@@ -0,0 +1,90 @@
+# @(#)precedence_test 1.0 91/07/24 Maarten Litmaath
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# test of 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..b032dcb
--- /dev/null
+++ b/tests/printf.right
@@ -0,0 +1,298 @@
+printf: usage: printf [-v var] format [arguments]
+printf: usage: printf [-v var] format [arguments]
+10
+ one
+one\ctwo
+4\.2
+no newline now newline
+%
+%
+%d
+A
+unquoted
+unquoted quoted
+unquoted quoted
+this\&that
+1 2 3 4 5
+onestring 0 0 0
+onestring 0 0 0.00
+--4.2 --
+--4.2 --
+--
+^@81--
+-- A--
+-- A--
+A7
+A7
+A7
+A7
+A7
+--\"abcd\"--
+--\'abcd\'--
+--a\x--
+./printf.tests: line 95: printf: missing hex digit for \x
+--\x--
+----
+----
+--4.2
+--4\.2--
+--\--
+
+
+ 4.4BSD
+ 4.4BSD
+ 4.4BSD
+ 4.4BSD
+4.4BSD
+4.4BSD
+ 4.4BSD
+--4.4BSD --
+ 4.
+4.4
+--4.4BSD --
+255 255 255 0377 0xff 0xFF
+255 255 255 0377 0xff 0XFF
+255 255 255 0377 0xff 0xFF
+255 255 255 0377 0xff 0XFF
+ 42
+ -42
+ 42
+ -42
+4.20
+4.20
+ 4.2
+4.20
+4.20
+ 4.2
+4.200000E+00
+4.200000e+00
+4.2E+00
+4.2e+00
+4.2
+4.2
+ 4.2
+ 4.2
+115
+115
+0163
+0163
+0x73
+0X73
+115.00
+115.00
+-- abcd--
+-- abcd--
+-- abcdefghij--
+-- abcdefghij--
+'abcd'
+\'abcd\'
+\abcd\
+\abcd\
+26
+26
+26
+./printf.tests: line 219: printf: `%10': missing format character
+./printf.tests: line 220: printf: `M': invalid format character
+ab./printf.tests: line 223: printf: `y': invalid format character
+./printf.tests: line 226: printf: GNU: invalid number
+0
+./printf.tests: line 227: printf: GNU: invalid number
+0
+-
+(foo )(bar )
+0
+ ab cd ef
+13
+^G
+^G
+^@7
+^Ge
+"?
+00001
+00001
+ 1
+1
+0
+0
+ 0
+ 0
+4
+4
+ 4
+ 4
+0.000000
+0.000000
+0.00
+0.00
+4.000000
+4.000000
+4.00
+4.00
+0.000000E+00
+0.000000e+00
+0.00E+00
+0.00e+00
+4.000000E+00
+4.000000e+00
+4.00E+00
+4.00e+00
+9B3A59A5
+q
+''
+''
+s
+
+
+b
+
+
+xx
+xx
+< >< >
+ one
+one\ctwo
+4\.2
+no newline now newline
+%
+%
+%d
+A
+unquoted
+unquoted quoted
+unquoted quoted
+this\&that
+1 2 3 4 5
+onestring 0 0 0
+onestring 0 0 0.00
+--4.2 --
+--4.2 --
+-- A--
+-- A--
+A7
+A7
+A7
+--\"abcd\"--
+--\'abcd\'--
+--a\x--
+./printf1.sub: line 107: printf: missing hex digit for \x
+--\x--
+----
+----
+--4.2
+--4\.2--
+--\--
+
+
+ 4.4BSD
+ 4.4BSD
+ 4.4BSD
+ 4.4BSD
+4.4BSD
+4.4BSD
+ 4.4BSD
+--4.4BSD --
+ 4.
+4.4
+--4.4BSD --
+255 255 255 0377 0xff 0xFF
+255 255 255 0377 0xff 0XFF
+255 255 255 0377 0xff 0xFF
+255 255 255 0377 0xff 0XFF
+ 42
+ -42
+ 42
+ -42
+4.20
+4.20
+ 4.2
+4.20
+4.20
+ 4.2
+4.200000E+00
+4.200000e+00
+4.2E+00
+4.2e+00
+4.2
+4.2
+ 4.2
+ 4.2
+115
+115
+0163
+0163
+0x73
+0X73
+115.00
+115.00
+-- abcd--
+-- abcd--
+-- abcdefghij--
+-- abcdefghij--
+'abcd'
+\'abcd\'
+\abcd\
+\abcd\
+26
+26
+26
+./printf1.sub: line 293: printf: `%10': missing format character
+./printf1.sub: line 294: printf: `M': invalid format character
+./printf1.sub: line 297: printf: `y': invalid format character
+./printf1.sub: line 300: printf: GNU: invalid number
+0
+./printf1.sub: line 302: printf: GNU: invalid number
+0
+-
+(foo )(bar )
+0
+ ab cd ef
+13
+^G
+^G
+^Ge
+"?
+16:09:15
+./printf3.sub: line 27: printf: warning: `Z': invalid time format specification
+%(abde)Z
+30-May-2010 16:09:15
+05/30/10 15:09:15
+current time: 2010-05-30 04:09:15 PM
+epoch time: 1969-12-31 07:00:00 PM -0500
+random time: 2010-05-30 04:09:15 PM -0400
+local time: Sun May 30 16:09:15 EDT 2010
+Sun May 30 16:09:15 EDT 2010 date-style time
+05/30/10 (foo) 16:09:15 date-style time
+x 123x
+x 123x
+x 123x
+x 123x
+x 123x
+x 123x
+x 123.00x
+x 123.00x
+x 123.00x
+x 123.00x
+x123 x
+x123 x
+x+00001e+02x
+x+00001e+02x
+x+000000123x
+x+000000123x
+x+00001e+02x
+x+00001e+02x
+x +123x
+x +123x
+x +123x
+x +123x
+x 7bx
+x 7bx
+x+123 x
+x+123 x
+x+123 x
+x+123 x
+-123.000000
+-123.000000
+x +123x
+x +123x
+x +123x
+x +123x
diff --git a/tests/printf.tests b/tests/printf.tests
new file mode 100644
index 0000000..df37e47
--- /dev/null
+++ b/tests/printf.tests
@@ -0,0 +1,334 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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"
+
+# make sure that missing arguments are always handled like the empty string
+printf "<%3s><%3b>\n"
+
+# tests variable assignment with -v
+${THIS_SH} ./printf1.sub
+
+${THIS_SH} ./printf2.sub
+
+${THIS_SH} ./printf3.sub
+
+${THIS_SH} ./printf4.sub
diff --git a/tests/printf1.sub b/tests/printf1.sub
new file mode 100644
index 0000000..2cbbc6a
--- /dev/null
+++ b/tests/printf1.sub
@@ -0,0 +1,348 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+LC_ALL=C
+LC_NUMERIC=C
+
+unset vv
+
+# this should expand escape sequences in the format string, nothing else
+printf -v vv "\tone\n"
+printf "%s" "$vv"
+
+# this should not cut off output after the \c
+printf -v vv "one\ctwo\n"
+printf "%s" "$vv"
+
+# and unrecognized backslash escapes should have the backslash preserved
+printf -v vv "4\.2\n"
+printf "%s" "$vv"
+
+printf -v vv "no newline " ; printf "%s" "$vv" ; printf -v vv "now newline\n"
+printf "%s" "$vv"
+
+# %% -> %
+printf -v vv "%%\n"
+printf "%s" "$vv"
+
+# 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 -v vv "\045"
+printf "%s" "$vv"
+echo
+printf -v vv "\045d\n"
+printf "%s" "$vv"
+
+# simple character output
+printf -v vv "%c\n" ABCD
+printf "%s" "$vv"
+
+# test simple string output
+printf -v vv "%s\n" unquoted
+printf "%s" "$vv"
+
+# test quoted string output
+printf -v vv "%s %q\n" unquoted quoted
+printf "%s" "$vv"
+printf -v vv "%s%10q\n" unquoted quoted
+printf "%s" "$vv"
+
+printf -v vv "%q\n" 'this&that'
+printf "%s" "$vv"
+
+# make sure the format string is reused to use up arguments
+printf -v vv "%d " 1 2 3 4 5
+printf "%s" "$vv"
+echo
+
+# make sure that extra format characters get null arguments
+printf -v vv "%s %d %d %d\n" onestring
+printf "%s" "$vv"
+
+printf -v vv "%s %d %u %4.2f\n" onestring
+printf "%s" "$vv"
+
+printf -v vv -- "--%s %s--\n" 4.2 ''
+printf "%s" "$vv"
+printf -v vv -- "--%s %s--\n" 4.2
+printf "%s" "$vv"
+
+# test %b escapes
+
+# 8 is a non-octal digit, so the `81' should be output
+#printf -v vv -- "--%b--\n" '\n\081'
+#printf "%s" "$vv"
+
+printf -v vv -- "--%b--\n" '\t\0101'
+printf "%s" "$vv"
+printf -v vv -- "--%b--\n" '\t\101'
+printf "%s" "$vv"
+
+# these should all display `A7'
+printf -v vv "%b\n" '\01017'
+printf "%s" "$vv"
+printf -v vv "%b\n" '\1017'
+printf "%s" "$vv"
+printf -v vv "%b\n" '\x417'
+printf "%s" "$vv"
+
+printf -v vv -- "--%b--\n" '\"abcd\"'
+printf "%s" "$vv"
+printf -v vv -- "--%b--\n" "\'abcd\'"
+printf "%s" "$vv"
+
+printf -v vv -- "--%b--\n" 'a\\x'
+printf "%s" "$vv"
+
+printf -v vv -- "--%b--\n" '\x'
+printf "%s" "$vv"
+
+Z1=$(printf -- "%b\n" '\a\b\e\f\r\v')
+Z2=$'\a\b\e\f\r\v'
+
+if [ "$Z1" != "$Z2" ]; then
+ printf "%s" "whoops: printf -v vv %b and $'' differ" >&2
+fi
+unset Z1 Z2
+
+printf -v vv -- "--%b--\n" ''
+printf "%s" "$vv"
+printf -v vv -- "--%b--\n"
+printf "%s" "$vv"
+
+# the stuff following the \c should be ignored, as well as the rest
+# of the format string
+printf -v vv -- "--%b--\n" '4.2\c5.4\n'
+printf "%s" "$vv"
+echo
+
+# unrecognized escape sequences should by displayed unchanged
+printf -v vv -- "--%b--\n" '4\.2'
+printf "%s" "$vv"
+
+# a bare \ should not be processed as an escape sequence
+printf -v vv -- "--%b--\n" '\'
+printf "%s" "$vv"
+
+# make sure extra arguments are ignored if the format string doesn't
+# actually use them
+printf -v vv "\n" 4.4 BSD
+printf "%s" "$vv"
+printf -v vv " " 4.4 BSD
+printf "%s" "$vv"
+echo
+
+# make sure that a fieldwidth and precision of `*' are handled right
+printf -v vv "%10.8s\n" 4.4BSD
+printf "%s" "$vv"
+printf -v vv "%*.*s\n" 10 8 4.4BSD
+printf "%s" "$vv"
+
+printf -v vv "%10.8q\n" 4.4BSD
+printf "%s" "$vv"
+printf -v vv "%*.*q\n" 10 8 4.4BSD
+printf "%s" "$vv"
+
+printf -v vv "%6b\n" 4.4BSD
+printf "%s" "$vv"
+printf -v vv "%*b\n" 6 4.4BSD
+printf "%s" "$vv"
+
+# we handle this crap with homemade code in printf -v vv.def
+printf -v vv "%10b\n" 4.4BSD
+printf "%s" "$vv"
+printf -v vv -- "--%-10b--\n" 4.4BSD
+printf "%s" "$vv"
+printf -v vv "%4.2b\n" 4.4BSD
+printf "%s" "$vv"
+printf -v vv "%.3b\n" 4.4BSD
+printf "%s" "$vv"
+printf -v vv -- "--%-8b--\n" 4.4BSD
+printf "%s" "$vv"
+
+# test numeric conversions -- these four lines should printf "%s" identically
+printf -v vv "%d %u %i 0%o 0x%x 0x%X\n" 255 255 255 255 255 255
+printf "%s" "$vv"
+printf -v vv "%d %u %i %#o %#x %#X\n" 255 255 255 255 255 255
+printf "%s" "$vv"
+
+printf -v vv "%ld %lu %li 0%o 0x%x 0x%X\n" 255 255 255 255 255 255
+printf "%s" "$vv"
+printf -v vv "%ld %lu %li %#o %#x %#X\n" 255 255 255 255 255 255
+printf "%s" "$vv"
+
+printf -v vv "%10d\n" 42
+printf "%s" "$vv"
+printf -v vv "%10d\n" -42
+printf "%s" "$vv"
+
+printf -v vv "%*d\n" 10 42
+printf "%s" "$vv"
+printf -v vv "%*d\n" 10 -42
+printf "%s" "$vv"
+
+# test some simple floating point formats
+printf -v vv "%4.2f\n" 4.2
+printf "%s" "$vv"
+printf -v vv "%#4.2f\n" 4.2
+printf "%s" "$vv"
+printf -v vv "%#4.1f\n" 4.2
+printf "%s" "$vv"
+
+printf -v vv "%*.*f\n" 4 2 4.2
+printf "%s" "$vv"
+printf -v vv "%#*.*f\n" 4 2 4.2
+printf "%s" "$vv"
+printf -v vv "%#*.*f\n" 4 1 4.2
+printf "%s" "$vv"
+
+printf -v vv "%E\n" 4.2
+printf "%s" "$vv"
+printf -v vv "%e\n" 4.2
+printf "%s" "$vv"
+printf -v vv "%6.1E\n" 4.2
+printf "%s" "$vv"
+printf -v vv "%6.1e\n" 4.2
+printf "%s" "$vv"
+
+printf -v vv "%G\n" 4.2
+printf "%s" "$vv"
+printf -v vv "%g\n" 4.2
+printf "%s" "$vv"
+printf -v vv "%6.2G\n" 4.2
+printf "%s" "$vv"
+printf -v vv "%6.2g\n" 4.2
+printf "%s" "$vv"
+
+# test some of the more esoteric features of POSIX.1 printf -v vv
+printf -v vv "%d\n" "'string'"
+printf "%s" "$vv"
+printf -v vv "%d\n" '"string"'
+printf "%s" "$vv"
+
+printf -v vv "%#o\n" "'string'"
+printf "%s" "$vv"
+printf -v vv "%#o\n" '"string"'
+printf "%s" "$vv"
+
+printf -v vv "%#x\n" "'string'"
+printf "%s" "$vv"
+printf -v vv "%#X\n" '"string"'
+printf "%s" "$vv"
+
+printf -v vv "%6.2f\n" "'string'"
+printf "%s" "$vv"
+printf -v vv "%6.2f\n" '"string"'
+printf "%s" "$vv"
+
+# output from these two lines had better be the same
+printf -v vv -- "--%6.4s--\n" abcdefghijklmnopqrstuvwxyz
+printf "%s" "$vv"
+printf -v vv -- "--%6.4b--\n" abcdefghijklmnopqrstuvwxyz
+printf "%s" "$vv"
+
+# and these two also
+printf -v vv -- "--%12.10s--\n" abcdefghijklmnopqrstuvwxyz
+printf "%s" "$vv"
+printf -v vv -- "--%12.10b--\n" abcdefghijklmnopqrstuvwxyz
+printf "%s" "$vv"
+
+# tests for translating \' to ' and \\ to \
+# printf -v vv translates \' to ' in the format string...
+printf -v vv "\'abcd\'\n"
+printf "%s" "$vv"
+
+# but not when the %b format specification is used
+printf -v vv "%b\n" \\\'abcd\\\'
+printf "%s" "$vv"
+
+# but both translate \\ to \
+printf -v vv '\\abcd\\\n'
+printf "%s" "$vv"
+printf -v vv "%b\n" '\\abcd\\'
+printf "%s" "$vv"
+
+# this was reported as a bug in bash-2.03
+# these three lines should all printf "%s" `26'
+printf -v vv "%d\n" 0x1a
+printf "%s" "$vv"
+printf -v vv "%d\n" 032
+printf "%s" "$vv"
+printf -v vv "%d\n" 26
+printf "%s" "$vv"
+
+# error messages
+
+# this should be an overflow, but error messages vary between systems
+# printf -v vv "%lu\n" 4294967296
+
+# ...but we cannot use this because some systems (SunOS4, for example),
+# happily ignore overflow conditions in strtol(3)
+#printf -v vv "%ld\n" 4294967296
+
+printf -v vv "%10"
+printf -v vv "ab%Mcd\n"
+
+# this caused an infinite loop in older versions of printf -v vv
+printf -v vv "%y" 0
+
+# these should print a warning and `0', according to POSIX.2
+printf -v vv "%d\n" GNU
+printf "%s" "$vv"
+printf -v vv "%o\n" GNU
+printf "%s" "$vv"
+
+# failures in all bash versions through bash-2.05
+printf -v vv "%.0s" foo
+printf "%s" "$vv"
+printf -v vv "%.*s" 0 foo
+printf "%s" "$vv"
+
+printf -v vv '%.0b-%.0s\n' foo bar
+printf "%s" "$vv"
+printf -v vv '(%*b)(%*s)\n' -4 foo -4 bar
+printf "%s" "$vv"
+
+format='%'`printf '%0100384d' 0`'d\n'
+printf -v vv $format 0
+printf "%s" "$vv"
+
+# failures in all bash versions through bash-3.0 - undercounted characters
+unset vv
+printf -v vv " %s %s %s \n%n" ab cd ef vvv
+printf "%s" "$vv"
+echo $vvv
+
+# this doesn't work with printf -v vv(3) on all systems
+#printf -v vv "%'s\n" foo
+
+# test cases from an austin-group list discussion
+# prints ^G as an extension
+printf -v vv '%b\n' '\7'
+printf "%s" "$vv"
+
+# prints ^G
+printf -v vv '%b\n' '\0007'
+printf "%s" "$vv"
+
+# prints NUL then 7
+#printf -v vv '\0007\n'
+#printf "%s" "$vv"
+
+# prints no more than two hex digits
+printf -v vv '\x07e\n'
+printf "%s" "$vv"
+
+# additional backslash escapes
+printf -v vv '\"\?\n'
+printf "%s" "$vv"
diff --git a/tests/printf2.sub b/tests/printf2.sub
new file mode 100644
index 0000000..94a2bb1
--- /dev/null
+++ b/tests/printf2.sub
@@ -0,0 +1,13 @@
+unset LC_ALL LC_CTYPE
+
+export LANG=C
+case $(printf %d\\n \'A) in
+65) ;;
+*) echo "printf2.sub: character conversion failed" >&2 ;;
+esac
+
+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/printf3.sub b/tests/printf3.sub
new file mode 100644
index 0000000..4c54aa1
--- /dev/null
+++ b/tests/printf3.sub
@@ -0,0 +1,75 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+LC_ALL=C
+LANG=C
+
+SHELLSTART=$(date +%s)
+SECS=1275250155
+export TZ=EST5EDT
+
+case $SHELLSTART in
+*s*) SHELLSTART=$EPOCHSECONDS ; DATESECS=false ;; # take a shot
+*) DATESECS=true ;;
+esac
+
+printf "%()T\n" $SECS
+printf "%(abde)Z\n" -1
+
+printf "%(%e-%b-%Y %T)T\n" $SECS
+
+printf -v v1 "%(%e-%b-%Y %T)T\n" $( $DATESECS && date +%s || echo $EPOCHSECONDS )
+printf -v v2 "%(%e-%b-%Y %T)T\n" -1
+
+case $v1 in
+$v2) ;;
+*) echo "current time and -1 possible mismatch|$v1|$v2|" >&2 ;;
+esac
+unset v1 v2
+
+v1=$(date +%s)
+printf -v v2 "%(%s)T" -1
+
+case $v1 in
+$v2) ;;
+*) echo "current time mismatch:$v1|$v2|" >&2 ;;
+esac
+unset v1 v2
+
+printf "%(%x %X)T\n" $(( $SECS - 3600 ))
+
+printf -v v1 "%(%F %r)T\n" $SHELLSTART
+printf -v v2 "%(%F %r)T\n" -2
+
+case $v1 in
+$v2) ;;
+*) echo "shell start time and -2 possible mismatch|$v1|$v2|" >&2 ;;
+esac
+unset v1 v2
+
+printf "current time: %(%F %r)T\n" $SECS
+
+printf "epoch time: %(%F %r %z)T\n" 0
+printf "random time: %(%F %r %z)T\n" $SECS
+
+printf "local time: %(%a %b %e %H:%M:%S %Z %Y)T\n" $SECS
+
+# test fieldwidth, justification, precision
+printf "%-40.50(%a %b %e %H:%M:%S %Z %Y)T date-style time\n" $SECS
+
+# test fieldwidth, justification, precision, embedded parens
+printf "%-40.50(%x (foo) %X)T date-style time\n" $SECS
+
+# problem introduced in bash-4.2 patch 5
+unset TZ
+printf '%(%Y-%m-%d %H:%M:%S %Z)T\n' >/dev/null
diff --git a/tests/printf4.sub b/tests/printf4.sub
new file mode 100644
index 0000000..ed4c538
--- /dev/null
+++ b/tests/printf4.sub
@@ -0,0 +1,82 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# Problems with padding, field widths, and `+' through bash-4.2
+
+printf "x%10.0fx\n" 123
+printf -v foo "x%10.0fx" 123
+echo "$foo"
+
+printf "x%10.0fx\n" 123
+printf -v foo "x%10.0fx" 123
+echo "$foo"
+
+printf "x%10.fx\n" 123
+printf -v foo "x%10.fx" 123
+echo "$foo"
+
+printf "x%10.2fx\n" 123
+printf -v foo "x%10.2fx" 123
+echo "$foo"
+
+printf "x%10.02fx\n" 123
+printf -v foo "x%10.02fx" 123
+echo "$foo"
+
+printf "x%-010.0fx\n" 123
+printf -v foo "x%-010.0fx" 123
+echo "$foo"
+
+printf "x%+010.0ex\n" 123
+printf -v foo "x%+010.0ex" 123
+echo "$foo"
+
+printf "x%+010.0fx\n" 123
+printf -v foo "x%+010.0fx" 123
+echo "$foo"
+
+printf "x%+010.0gx\n" 123
+printf -v foo "x%+010.0gx" 123
+echo "$foo"
+
+printf "x%+010.0dx\n" 123
+printf -v foo "x%+010.0dx" 123
+echo "$foo"
+
+printf "x%+010.0ldx\n" 123
+printf -v foo "x%+010.0ldx" 123
+echo "$foo"
+
+printf "x%+010.0xx\n" 123
+printf -v foo "x%+010.0xx" 123
+echo "$foo"
+
+printf "x%-+10.0fx\n" 123
+printf -v foo "x%-+10.0fx" 123
+echo "$foo"
+
+printf "x%-+10.0dx\n" 123
+printf -v foo "x%-+10.0dx" 123
+echo "$foo"
+
+printf "%f\n" -123
+printf -v foo "%f" -123
+echo "$foo"
+
+printf "x%+10.0fx\n" 123
+printf -v foo "x%+10.0fx" 123
+echo "$foo"
+
+printf "x%+10.0dx\n" 123
+printf -v foo "x%+10.0dx" 123
+echo "$foo"
diff --git a/tests/procsub.right b/tests/procsub.right
new file mode 100644
index 0000000..c6471c5
--- /dev/null
+++ b/tests/procsub.right
@@ -0,0 +1,33 @@
+test1
+foo
+test2
+test4
+8
+test5
+test6
+test7
+test8
+test8a
+test9
+hi
+bye
+l8r
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+intern
+1
+0
+0
+0
+0
+extern
+1
+0
+0
+0
+0
+123
+bar1
+ouch
+bar2
+foo
+subshell
diff --git a/tests/procsub.tests b/tests/procsub.tests
new file mode 100644
index 0000000..946d2c2
--- /dev/null
+++ b/tests/procsub.tests
@@ -0,0 +1,121 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# process substitution constructs that have caused problems in the past
+. ./test-glue-functions
+
+eval cat <(echo test1)
+eval "echo foo;cat" <(echo test2)
+
+# this doesn't work, and it never should have
+#unset f
+#f=<(echo test3); cat "$f"
+
+unset f
+eval f=<(echo test4) "; cat \$f"
+
+unset f
+
+FN=$TMPDIR/bashtest-procsub-$$
+cat >"$FN" <<EOF
+echo "test 12" | wc -c | _cut_leading_spaces
+cat "\$1"
+EOF
+
+source "$FN" <(echo test5)
+rm -f "$FN"
+unset FN
+
+cat <( echo test6 ) <( echo test7 )
+cat <( echo test8 ; sleep 2; echo test8a ) <( echo test9 )
+
+# Zev Weiss 11/7/2012
+fn() { cat | cat "$1"; }
+fn <(:) < /dev/null
+
+unset -f fn
+
+f1(){
+ cat $1
+ date >/dev/null
+}
+f2(){
+ date >/dev/null
+ cat $1
+}
+cat <(echo hi)
+f1 <(echo bye)
+f2 <(echo l8r)
+
+unset -f f1 f2
+
+# set up conditions for test
+ulimit -n 256
+
+bug()
+{
+c=$(ulimit -n)
+let c+=100
+while let c--
+do
+ while read -ru3 x
+ do
+ echo -n :
+ done 3< <(echo x)
+done
+echo
+}
+
+bug
+unset -f bug
+
+count_lines()
+{
+ wc -l < $1
+
+ case "$1" in
+ *sh-np*) [ -e "$1" ] || { echo 0; echo 0; echo 0; echo 0; return; } ;;
+ *) ;;
+ esac
+
+ wc -l < $1
+ wc -l < $1
+ true | wc -l < $1
+ wc -l < $1
+}
+
+echo intern
+count_lines <(date) | _cut_leading_spaces
+unset -f count_lines
+
+echo extern
+FN=$TMPDIR/bashtest-$$
+cat >$FN << \EOF
+wc -l < $1
+case $1 in *sh-np*) [ -e $1 ] || { echo 0; echo 0; echo 0; echo 0; return; } ;; esac
+wc -l < $1
+wc -l < $1
+true | wc -l < $1
+wc -l < $1
+EOF
+
+${THIS_SH} -c "source $FN <(date)" | _cut_leading_spaces
+rm -f $FN
+
+moo() { ls -l "$1" >/dev/null; ls -l "$1" >/dev/null; }; moo >(true)
+moo() { ls -al "$1" >/dev/null; (true); ls -al "$1" >/dev/null; }; moo >(true)
+
+unset -f moo
+
+${THIS_SH} ./procsub1.sub
+${THIS_SH} ./procsub2.sub
diff --git a/tests/procsub1.sub b/tests/procsub1.sub
new file mode 100644
index 0000000..0e68f3b
--- /dev/null
+++ b/tests/procsub1.sub
@@ -0,0 +1,5 @@
+# make sure we can wait for the last process substitution, since it sets $!
+cat <(exit 123) >/dev/null
+
+wait "$!"
+echo $?
diff --git a/tests/procsub2.sub b/tests/procsub2.sub
new file mode 100644
index 0000000..75ad2d0
--- /dev/null
+++ b/tests/procsub2.sub
@@ -0,0 +1,36 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# test whether or not we remove FIFOs and close pipe file descriptors too
+# aggressively
+
+ouch()
+{
+ while read foo; do echo "$foo"; done < <(echo bar1)
+ cat "$1"
+}
+
+ouch <(echo ouch )
+
+ouch2()
+{
+ { cat; } < <(echo bar2)
+ cat "$1"
+}
+
+exec 4< <(echo subshell)
+ouch2 <(echo foo )
+
+read var <&4
+echo $var
diff --git a/tests/quote.right b/tests/quote.right
new file mode 100644
index 0000000..303e685
--- /dev/null
+++ b/tests/quote.right
@@ -0,0 +1,182 @@
+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] = <(")>
+string \
+string \
+string \
+string \
+string \
+string \}
+'weferfds'\''dsfsdf'
+'weferfdsdsfsdf'
+'weferfds'\''dsfsdf'
+'weferfds'\\dsfsdf'
+testdd ddtest
+testdd '\''ddtest
+testdddding
+testdddding
+test'ing
+test'ing
+test'string
+a'b'c
+foo b c baz
+foo 'bar baz
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[2] = <>
+argv[1] = <>
+argv[2] = <>
+argv[1] = <>
+=====
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[2] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[2] = <>
+=====
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[2] = <>
+argv[1] = <>
+argv[2] = <>
+argv[1] = <>
+=====
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[1] = <>
+argv[2] = <>
+argv[1] = <>
+argv[2] = <>
+argv[1] = <>
+argv[1] = <4>
+argv[2] = <>
+argv[1] = <ab>
+argv[2] = <>
+argv[1] = <ab>
+argv[2] = <>
+argv[1] = <ab>
+argv[2] = <>
+argv[1] = <ab>
+argv[2] = <>
+argv[1] = <ab ''>
+argv[1] = <ab >
+argv[1] = <ab ''>
+argv[1] = <ab >
+0
+1
+1
+1
+1
+1
+1
+1
+2
+2
+2
+2
+0
+1
+1
+1
+1
+1
+1
+1
+2
+2
+2
+2
+0
+0
+0
+2
+2
+4
+4
+3
+argv[1] = <^?>
+argv[1] = <^?>
+argv[1] = <^?>
+argv[1] = <^?>
+argv[1] = <^?>
+argv[1] = <^?>
diff --git a/tests/quote.tests b/tests/quote.tests
new file mode 100644
index 0000000..0a0b4af
--- /dev/null
+++ b/tests/quote.tests
@@ -0,0 +1,139 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+echo "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 "(\")"`
+
+# various strings ending in backslashes
+
+echo 'string \'
+echo "string \\"
+
+echo string\ \\
+
+echo ${foo:-'string \'}
+echo "${foo:-string \\}"
+echo ${foo:-string \\\}}
+
+${THIS_SH} ./quote1.sub
+${THIS_SH} ./quote2.sub
+${THIS_SH} ./quote3.sub
+${THIS_SH} ./quote4.sub
diff --git a/tests/quote1.sub b/tests/quote1.sub
new file mode 100644
index 0000000..86f9786
--- /dev/null
+++ b/tests/quote1.sub
@@ -0,0 +1,62 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# inconsistency with quoted pattern substitution patterns through bash-4.2
+# fixed in a ksh93-compatible (and Posix-compatible, in general) way
+# NOT backwards compatible
+
+test="weferfds'dsfsdf"
+
+# why does this work, this list was born of frustration, I tried
+# everything I could think of.
+echo \'${test//"'"/\'\\\'\'}\'" "
+
+#but none of the following
+
+echo "'${test//"'"/}'"
+
+echo "'${test//"'"/"'\\''"}'"
+
+printf "%s\n" "'${test//"'"/\'\\'\'}'"
+
+#echo "'${test//'/}'" # hangs waiting for '
+#echo "'${test//"'"/'\\''}'" # hangs waiting for '
+
+unset test
+test=teststrtest
+echo "${test//str/"dd dd"}"
+echo ${test//str/"dd '\''dd"}
+
+unset test
+test=teststring
+
+echo "${test//str/"dddd"}"
+
+echo ${test//str/"dddd"}
+
+echo ${test//str/"'"}
+
+echo "${test//str/"'"}"
+
+#echo "${test//str/'}" # hangs
+
+test=test\'string
+echo "${test//"'"/"'"}"
+
+x="a'b'c"; echo "${x//\'/\'}"
+
+printf '%s\n' "foo ${IFS+"b c"} baz"
+
+# this is where the default behavior differs from posix
+set -o posix
+echo "foo ${IFS+'bar} baz"
diff --git a/tests/quote2.sub b/tests/quote2.sub
new file mode 100644
index 0000000..1012b8f
--- /dev/null
+++ b/tests/quote2.sub
@@ -0,0 +1,55 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+x=x
+e=
+
+recho ${x:+""}
+recho ${x:+ ""}
+recho ${x:+"" }
+recho ${x:+"$e"}
+recho ${x:+ "$e"}
+recho ${x:+"$e""$e"""}
+recho ${x:+"$e""$e"""}
+recho ${x:+"$e" "$e"""}
+recho ${x:+"$e""$e" ""}
+recho ${x:+ "$e""$e"""}
+
+echo =====
+recho ${x:+''}
+recho ${x:+ ''}
+recho ${x:+'' }
+recho ${x:+'' ''}
+
+recho ${x:+$e''}
+recho ${x:+''$e}
+
+recho ${x:+''$e $e''}
+
+echo =====
+recho ${x:+"$(:)"}
+recho ${x:+ "$(:)"}
+recho ${x:+"$(:)""$(:)"""}
+recho ${x:+"$(:)""$(:)"""}
+recho ${x:+"$(:)" "$(:)"""}
+recho ${x:+"$(:)""$(:)" ""}
+recho ${x:+ "$(:)""$(:)"""}
+
+echo =====
+recho ${x:+"`:`"}
+recho ${x:+ "`:`"}
+recho ${x:+"`:`""`:`"""}
+recho ${x:+"`:`""`:`"""}
+recho ${x:+"`:`" "`:`"""}
+recho ${x:+"`:`""`:`" ""}
+recho ${x:+ "`:`""`:`"""}
diff --git a/tests/quote3.sub b/tests/quote3.sub
new file mode 100644
index 0000000..54bc5ed
--- /dev/null
+++ b/tests/quote3.sub
@@ -0,0 +1,31 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# new tests
+x=4
+sp=' '
+
+# word
+recho ${x}${sp}''
+
+# unquoted
+recho ${x+ab "$y"}
+recho ${x+ab ''}
+recho ${x+ab "$( : )"}
+recho ${x+ab "${yy}"}
+
+# quoted
+recho "${x+ab ''}"
+recho "${x+ab ""}"
+recho "${x+ab '${yy}'}"
+recho "${x+ab "${yy}"}"
diff --git a/tests/quote4.sub b/tests/quote4.sub
new file mode 100644
index 0000000..ab534c8
--- /dev/null
+++ b/tests/quote4.sub
@@ -0,0 +1,101 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+n() { echo $#; }
+
+set --
+
+n "$@"
+
+# should be 1
+n "$@"''
+n ''"$@"
+n ''"$@"''
+
+set -- ''
+
+n "$@"
+# should be 1
+n "$@"''
+n ''"$@"
+n ''"$@"''
+
+set -- '' ''
+
+n "$@"
+# should be 2
+n ''"$@"
+# should be 2
+n "$@"''
+# should be 2
+n ''"$@"''
+
+x=x
+
+set --
+
+n ${x+"$@"}
+
+# should be 1
+n ${x+"$@"''}
+n ${x+''"$@"}
+n ${x+''"$@"''}
+
+set -- ''
+
+n ${x+"$@"}
+# should be 1
+n ${x+"$@"''}
+n ${x+''"$@"}
+n ${x+''"$@"''}
+
+set -- '' ''
+
+n ${x+"$@"}
+# should be 2
+n ${x+''"$@"}
+# should be 2
+n ${x+"$@"''}
+# should be 2
+n ${x+''"$@"''}
+
+
+set --
+
+n "$@" "$@"
+n "$@""$@"
+
+n ${x+"$@" "$@"}
+
+set -- ''
+
+n ${x+"$@" "$@"}
+n "$@" "$@"
+
+set -- '' ''
+
+n ${x+"$@" "$@"}
+n "$@" "$@"
+n "$@""$@"
+
+# new tests
+unset -v x
+v=$'\177'
+
+recho ''$'\177'''
+recho $'\177'''
+recho ''$'\177'
+
+recho ''$v''
+recho ''$v
+recho $v''
diff --git a/tests/quotearray.right b/tests/quotearray.right
new file mode 100644
index 0000000..e689365
--- /dev/null
+++ b/tests/quotearray.right
@@ -0,0 +1,152 @@
+declare -A assoc=(["x],b[\$(echo uname >&2)"]="1" )
+declare -A assoc=(["\$key"]="1" ["x],b[\$(echo uname >&2)"]="1" )
+declare -A assoc=(["\$key"]="1" ["x],b[\$(echo uname >&2)"]="2" )
+./quotearray.tests: line 31: ((: 'assoc[x\],b\[\$(echo uname >&2)]++' : syntax error: operand expected (error token is "'assoc[x\],b\[\$(echo uname >&2)]++' ")
+declare -A assoc=(["\$key"]="1" ["x],b[\$(echo uname >&2)"]="2" )
+./quotearray.tests: line 34: ((: 'assoc[x\],b\[\$(echo uname >&2)]'++ : syntax error: operand expected (error token is "'assoc[x\],b\[\$(echo uname >&2)]'++ ")
+declare -A assoc=(["\$key"]="1" ["x],b[\$(echo uname >&2)"]="2" )
+declare -A assoc=(["\$key"]="1" ["x],b[\$(echo uname >&2)"]="3" )
+4
+klmnopqrst
+klmnopqrst
+klmno
+klmnopqrst
+declare -A A=(["\$(echo %)"]="5" [%]="10" ["]"]="10" )
+declare -A A=(["~"]="42" )
+42
+declare -A A=(["~"]="43" )
+42
+declare -A A=(["~"]="43" ["~0"]="43" )
+12
+declare -a a=([0]="12" [1]="42")
+2
+2
+declare -Ai assoc=(["']"]="3" ["\$var"]="1" )
+105
+declare -A assoc=(["\` echo >&2 foo\`"]="42" ["\$( echo >&2 bar)"]="63" )
+./quotearray.tests: line 140: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
+./quotearray.tests: line 144: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
+1
+./quotearray.tests: line 147: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
+1
+./quotearray.tests: line 150: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
+1
+./quotearray.tests: line 153: x],b[$(echo uname >&2): syntax error: invalid arithmetic operator (error token is "],b[$(echo uname >&2)")
+1
+declare -A assoc
+0
+0
+1
+0
+0
+0
+declare -A assoc=(["\` echo >&2 foo\`"]="128" [0]="0" ["]"]="12" ["x],b[\$(echo uname >&2)"]="42" ["~"]="42" ["\$( echo 2>& date)"]="foo" )
+foo
+0
+0
+./quotearray1.sub: line 68: 0\],b\[1: syntax error: invalid arithmetic operator (error token is "\],b\[1")
+declare -a array
+0
+0
+0
+0
+1
+1
+declare -A aa=(["\$( echo 2>& date)"]="foo" )
+foo
+0
+1
+1
+./quotearray1.sub: line 113: test: aa[$(echo: binary operator expected
+2
+[[ -v assoc[a] ]]; $?=0
+[[ -v assoc["] ]]; $?=0
+declare -A assoc=(["\""]="123" [a]="123" )
+declare -A a=([1]="1" [0]="0" [" "]="11" )
+7
+7
+declare -A A=([$'\t']="2" [" "]="2" )
+declare -A A=([$'\t']="2" ["*"]="2" [" "]="2" ["]"]="2" ["@"]="2" )
+./quotearray2.sub: line 54: read: `A[]]': not a valid identifier
+declare -A A=([$'\t']="X" ["*"]="X" [" "]="X" ["@"]="X" )
+./quotearray2.sub: line 62: printf: `A[]]': not a valid identifier
+declare -A A=([$'\t']="X" ["*"]="X" [" "]="X" ["@"]="X" )
+./quotearray2.sub: line 70: declare: `A[]]=X': not a valid identifier
+declare -A A=(["*"]="X" ["@"]="X" )
+./quotearray2.sub: line 78: declare: `A[]]=X': not a valid identifier
+declare -A A=(["*"]="X" ["@"]="X" )
+./quotearray2.sub: line 89: let: assoc[x],b[$(echo: bad array subscript (error token is "b[$(echo")
+declare -A assoc
+declare -A assoc=(["\$(echo foo)"]="1" )
+0
+declare -A assoc=(["\$var"]="value" )
+declare -A assoc=(["\$var"]="value" )
+declare -A assoc=(["\$var"]="value" )
+declare -A assoc=()
+declare -A a=(["\$(echo foo)"]="1" )
+declare -A a=()
+declare -A a=(["\$(echo foo)"]="1" )
+declare -A a=(["\$(echo foo)"]="1" )
+declare -A assoc=(["!"]="bang" )
+1
+1
+declare -A assoc=(["!"]="bang" ["@"]="at" )
+declare -A assoc=(["!"]="bang" )
+declare -a array=([0]="1" [1]="2" [2]="3")
+declare -a array=()
+./quotearray3.sub: line 98: declare: array: not found
+declare -A map=(["foo\$(uname >/dev/tty)bar"]="1" )
+1
+declare -A map=()
+$(DOESNOTEXIST)
+declare -A blah=()
+declare -A assoc=(["*"]="star" ["!"]="bang" ["@"]="at" )
+declare -A assoc=(["*"]="star" ["!"]="bang" )
+declare -A assoc=(["!"]="bang" )
+./quotearray4.sub: line 41: declare: assoc: not found
+declare -A assoc=(["*"]="star" ["!"]="bang" ["@"]="at" )
+declare -A assoc=(["*"]="star" ["!"]="bang" )
+declare -A assoc=(["!"]="bang" )
+declare -A assoc=(["*"]="star" ["!"]="bang" )
+declare -A assoc=(["!"]="bang" )
+star bang at
+star bang at
+0
+0
+0
+1
+1
+declare -A assoc=(["*"]="star" ["!"]="bang" ["@"]=" key" )
+===
+1
+1
+declare -a array=([0]="1" [1]="2" [2]="3")
+1 2 3
+1 2 3
+0
+0
+./quotearray4.sub: line 115: array[@]: bad array subscript
+declare -a array=([0]="1" [1]="2" [2]="3")
+./quotearray5.sub: line 27: unset: `a[$(echo': not a valid identifier
+./quotearray5.sub: line 27: unset: `foo)]': not a valid identifier
+declare -A a=()
+declare -A a=()
+declare -A a=()
+-----
+declare -A a=(["\$(echo foo)"]="1" )
+declare -A a=()
+declare -A a=()
+declare -A a=()
+-----
+declare -A a=()
+declare -A a=()
+declare -A a=()
+----------
+declare -A a=([.]="v1" )
+declare -A a=([.]="v1" )
+-----
+declare -A a=([.]="v1" )
+declare -A a=([.]="v1" )
+-----
+declare -A a=([.]="v1" )
+declare -A a=([.]="v1" )
diff --git a/tests/quotearray.tests b/tests/quotearray.tests
new file mode 100644
index 0000000..e1ed83b
--- /dev/null
+++ b/tests/quotearray.tests
@@ -0,0 +1,164 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# a set of tests for associative arrays in arithmetic contexts
+
+declare -A assoc
+key='x],b[$(echo uname >&2)'
+
+(( assoc[$key]++ ))
+declare -p assoc
+
+(( assoc['$key']++ ))
+declare -p assoc
+
+(( assoc["$key"]++ ))
+declare -p assoc
+
+declare -A assoc
+
+(( 'assoc[$key]++' ))
+declare -p assoc
+
+(( 'assoc[$key]'++ ))
+declare -p assoc
+
+(( "assoc[$key]++" ))
+declare -p assoc
+
+unset assoc
+
+typeset -A a
+b="80's"
+
+((++a[$b]))
+
+((++a["$b"]))
+[[ $((++a[$b])) ]]
+[[ $((++a["$b"])) ]]
+
+echo ${a[$b]}
+unset a
+
+declare -A A
+
+string=abcdefghijklmnopqrstuvwxyz
+
+echo ${string:10:10}
+k1='%'
+k2='$(echo %)'
+
+A[%]=10
+A[']']=10
+A[$k2]=5
+
+k3=']'
+
+echo ${string:A[%]:A[$k1]}
+echo ${string:A[%]:A[$k2]}
+echo ${string:A[%]:A[$k3]}
+
+declare -p A
+
+unset A string key
+
+key='~'
+
+declare -A A
+A[$key]=42
+
+declare -p A
+
+echo $(( A[$key]++ ))
+declare -p A
+
+key='~0'
+A[$key]=42
+echo $(( A[$key]++ ))
+declare -p A
+
+declare -a a
+key='~-2'
+a[0]=12
+a[$key]=42
+echo $(( a[7<(4+2)] ))
+
+declare -p a
+
+unset A a key
+
+declare -A A
+declare -a a
+
+sString="devel packager's guide"
+i=2
+
+A["$sString"]=$i
+a[$i]=$sString
+
+echo "${A[${a[i]}]}"
+echo ${A["${a[i]}"]}
+
+unset A a
+
+#LANG=C
+unset var assoc
+var=\'\]
+declare -Ai assoc
+assoc[$var]=1
+assoc[$var]+=1
+((assoc['$var']++))
+((assoc[$var]++))
+typeset -p assoc
+
+unset assoc
+
+declare -A assoc
+key1='` echo >&2 foo`'
+key2='$( echo >&2 bar)'
+
+assoc[$key1]=42
+assoc[$key2]=63
+
+echo $(( assoc[$key1] + assoc[$key2] ))
+declare -p assoc
+unset assoc
+
+declare -a a
+key='x],b[$(echo uname >&2)'
+a[$key]=42
+
+expr='a[$key]'
+
+(( $expr ))
+echo $?
+
+echo $(( $expr ))
+echo $?
+
+echo $(( expr ))
+echo $?
+
+(( expr ))
+echo $?
+
+${THIS_SH} ./quotearray1.sub
+${THIS_SH} ./quotearray2.sub
+${THIS_SH} ./quotearray3.sub
+
+# behavior of builtins with array subscripts @ and *
+${THIS_SH} ./quotearray4.sub
+
+# behavior of unset with quoted and unquoted array arguments
+${THIS_SH} ./quotearray5.sub
diff --git a/tests/quotearray1.sub b/tests/quotearray1.sub
new file mode 100644
index 0000000..19741b1
--- /dev/null
+++ b/tests/quotearray1.sub
@@ -0,0 +1,131 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# arithmetic operators for conditional commands and arithmetic commands
+
+declare -A assoc
+declare -a index
+
+key='x],b[$(echo uname >&2)'
+key1=']'
+key2='` echo >&2 foo`'
+key3='~'
+key4='7<(4+2)'
+key5='$( echo 2>& date)'
+key6='$(echo foo)'
+
+[[ -n assoc[$key] ]]
+declare -p assoc
+
+assoc[$key]=42
+assoc[$key1]=12
+assoc[$key2]=128
+assoc[$key3]=42
+assoc[0]=0
+
+[[ assoc[$key] -eq assoc[$key] ]]
+echo $?
+
+[[ assoc[$key] -gt assoc[$key1] ]]
+echo $?
+
+[[ assoc[$key2] -lt assoc[$key] ]]
+echo $?
+
+[[ assoc[$key] -eq assoc[$key3] ]]
+echo $?
+
+[[ index[7<(4+2)] -le assoc[0] ]]
+echo $?
+[[ index[$key4] -le assoc[0] ]]
+echo $?
+
+assoc[$key5]=foo
+declare -p assoc
+
+echo "${assoc[$key5]}"
+
+[[ -v assoc[$key5] ]]
+echo $?
+[[ -v assoc[$key] ]]
+echo $?
+
+unset assoc
+
+declare -a array
+index='0],b[1';
+((array[$index]++))
+
+declare -p array
+
+unset array
+
+declare -A assoc
+
+assoc[$key]=42
+assoc[$key4]=42
+
+[[ -v assoc[$key] ]]
+echo $?
+[[ -v assoc["$key"] ]]
+echo $?
+
+[[ -v assoc[$key4] ]]
+echo $?
+[[ -v assoc["$key4"] ]]
+echo $?
+
+[[ -v assoc['$key'] ]]
+echo $?
+[[ -v assoc['$key4'] ]]
+echo $?
+
+unset -v assoc
+
+declare -A aa
+aa[$key5]=foo
+
+declare -p aa
+echo "${aa[$key5]}"
+
+[[ -v aa[$key5] ]]
+echo $?
+
+[[ -v aa[$key] ]]
+echo $?
+
+aa[$key6]=42
+# this still performs expansion
+test -v aa["$key6"]
+echo $?
+# should be an error
+test -v aa[$key6]
+echo $?
+
+unset aa key
+
+declare -A assoc
+
+mytest ()
+{
+ assoc["$1"]=123
+ [[ -v assoc["$1"] ]]
+ printf '[[ -v assoc[%s] ]]; $?=%s\n' "$1" "$?"
+}
+
+mytest 'a'
+mytest '"'
+declare -p assoc
+unset -v assoc
+unset -f mytest
diff --git a/tests/quotearray2.sub b/tests/quotearray2.sub
new file mode 100644
index 0000000..056f8ca
--- /dev/null
+++ b/tests/quotearray2.sub
@@ -0,0 +1,107 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# assoc_expand_once for builtins
+
+typeset -A a
+a[0]=0 a[1]=1
+
+let "a[\" \"]=11" ; typeset -p a ; a[0]=0
+
+unset a
+
+# tests for `problem' keys when using associative arrays and assoc_expand_once
+# deal with problems for now; this is a placeholder for if and when I fix them
+
+typeset -A a
+
+k='['
+echo $(( a[$k]=7 ))
+
+k=']'
+echo $(( a[$k]=7 ))
+
+unset a
+
+declare -A A
+
+for k in $'\t' ' '; do
+ (( A[$k]=2 ))
+done
+declare -p A
+
+for k in ']' '*' '@'; do
+ (( A[$k]=2 ))
+done
+
+declare -p A
+
+unset A
+declare -A A
+
+for k in $'\t' ' ' ']' '*' '@'; do
+ read "A[$k]" <<< X
+done
+declare -p A
+
+unset A
+declare -A A
+
+for k in $'\t' ' ' ']' '*' '@'; do
+ printf -v "A[$k]" "%s" X
+done
+declare -p A
+
+unset A
+declare -A A
+
+for k in ']' '*' '@'; do
+ declare A[$k]=X
+done
+declare -p A
+
+unset A
+declare -A A
+
+for k in ']' '*' '@'; do
+ declare "A[$k]=X"
+done
+declare -p A
+
+unset A
+
+# this isn't right yet, but changes will show up here
+shopt -s assoc_expand_once
+declare -A assoc
+key='x],b[$(echo uname >&2)'
+
+let assoc[$key]++
+declare -p assoc
+
+unset assoc
+
+typeset -A assoc
+at=@
+
+key='$(echo foo)'
+
+assoc[$key]=1
+declare -p assoc
+
+shopt -s assoc_expand_once
+test -v assoc["$key"] ; echo $?
+
+unset assoc
+shopt -u assoc_expand_once
+
diff --git a/tests/quotearray3.sub b/tests/quotearray3.sub
new file mode 100644
index 0000000..65f950d
--- /dev/null
+++ b/tests/quotearray3.sub
@@ -0,0 +1,117 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# assoc_expand_once and unset builtin, which is treated specially
+
+declare -A assoc
+
+var=x123
+assoc['$var']=value
+declare -p assoc
+
+shopt -u assoc_expand_once
+unset "assoc[$var]"
+declare -p assoc
+
+unset 'assoc[$var]'
+declare -p assoc
+
+assoc['$var']=value
+shopt -s assoc_expand_once
+unset 'assoc[$var]'
+declare -p assoc
+
+unset assoc
+shopt -u assoc_expand_once
+
+declare -A a
+a['$(echo foo)']=1
+
+unset 'a[$(echo foo)]'
+declare -p a
+
+key='$(echo foo)'
+a[$key]=1
+
+unset 'a[$key]'
+declare -p a
+
+a[$key]=1
+unset "a[$key]"
+declare -p a
+
+a[$key]=1
+unset a[$key]
+declare -p a
+
+unset a
+
+typeset -A assoc
+key=@
+
+assoc[@]=at
+assoc[!]=bang
+
+# this should only unset the element with key `@'
+unset -v assoc[$key]
+typeset -p assoc
+
+# this should check for assoc[@] and return 1
+test -v assoc[$key]
+echo $?
+
+# this should too
+[[ -v assoc[$key] ]]
+echo $?
+
+unset assoc array
+
+declare -A assoc
+declare -a array
+
+assoc=([@]=at [!]=bang)
+declare -p assoc
+
+unset assoc[@]
+declare -p assoc
+
+array=(1 2 3)
+declare -p array
+
+# right now, this still unsets the entire array
+unset array[@]
+declare -p array
+
+BASH_COMPAT=51
+unset array[@]
+declare -p array
+
+declare -A map; key='foo$(uname >/dev/tty)bar'; map[$key]=1
+declare -p map
+echo ${map["$key"]}
+
+unset map["$key"]
+declare -p map
+unset map
+
+declare -A blah
+blah['$(DOESNOTEXIST)']=broken
+for i in "${!blah[@]}"; do echo "$i"; done
+
+for i in "${!blah[@]}"; do unset blah["$i"]; done
+declare -p blah
+unset blah
+
+
+
diff --git a/tests/quotearray4.sub b/tests/quotearray4.sub
new file mode 100644
index 0000000..964aac7
--- /dev/null
+++ b/tests/quotearray4.sub
@@ -0,0 +1,116 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# tests for builtins handling associative array keys `*' and `@', with some
+# indexed array tests as well (backwards compatible)
+
+# derived from test cases posted to bug-bash by myoga.murase@gmail.com
+
+declare -A assoc
+declare -a array
+
+assoc[@]=at
+assoc[*]=star
+assoc[!]=bang
+
+key=@
+
+iref='array[@]'
+aref='assoc[@]'
+
+declare -p assoc
+
+unset assoc[@]
+declare -p assoc
+
+unset assoc[*]
+declare -p assoc
+
+unset assoc
+declare -p assoc
+
+declare -A assoc
+assoc[@]=at
+assoc[*]=star
+assoc[!]=bang
+
+declare -p assoc
+
+unset assoc["$key"]
+declare -p assoc
+
+unset assoc["*"]
+declare -p assoc
+
+assoc[@]=at assoc[*]=star
+
+unset assoc['@']
+declare -p assoc
+
+unset assoc['*']
+
+declare -p assoc
+
+assoc[@]=at assoc[*]=star
+echo ${!aref}
+
+declare -n nref=$aref
+echo ${nref}
+unset -n nref
+
+# for associative arrays, test -v treats @ and * as keys
+
+test -v 'assoc[@]'
+echo $?
+test -v assoc[$key]
+echo $?
+[[ -v assoc[$key] ]]
+echo $?
+
+unset -v 'assoc[@]'
+
+test -v 'assoc[@]'
+echo $?
+[[ -v assoc[@] ]]
+echo $?
+
+assoc[@]=at
+
+printf -v assoc[@] "%10s" key
+declare -p assoc
+
+echo ===
+array=()
+test -v array[@]
+echo $?
+[[ -v array[@] ]]
+echo $?
+
+array=(1 2 3)
+declare -p array
+
+echo ${!iref}
+declare -n nref=$iref
+
+echo $nref
+unset -n nref
+
+# but for indexed arrays, test -v treats @ and * as standing for the entire array
+test -v 'array[@]'
+echo $?
+[[ -v array[@] ]]
+echo $?
+
+printf -v array[@] "%-10s" key
+declare -p array
diff --git a/tests/quotearray5.sub b/tests/quotearray5.sub
new file mode 100644
index 0000000..5366a99
--- /dev/null
+++ b/tests/quotearray5.sub
@@ -0,0 +1,124 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# a set of tests for unset to try to ensure that subscripts are only expanded
+# once. Derived from tests submitted by konsolebox@gmail.com
+
+declare -A a
+key='$(echo foo)'
+
+# Here the tokens are valid array references and pass that fact to unset
+# post-expansion
+
+# This solves the surprise expansion issues.
+
+a[$key]=1
+unset -v a[$key] # this performs normal word splitting
+unset -v a["$key"] # prevent word splitting
+declare -p a # Displays no element
+
+a['$key']=2
+unset -v a['$key']
+declare -p a # Displays no element
+
+a["foo"]=3
+unset -v a["foo"]
+declare -p a # Displays no element
+
+echo -----
+
+# Here the tokens are "strings". They expand and keep the
+# original behavior and allows existing scripts to not break.
+# It also allows nref or iref references to be transparently
+# referenced in it.
+
+# the quotes prevent the arguments from being recognized as valid array
+# references before word expansion. since unset doesn't know to treat
+# them specially, they're treated as in previous versions and expansion
+# is performed as part of evaluating the subscript
+
+a[$key]=1
+declare -p a
+unset 'a[$key]' # Transforms to a[$key] after expansion
+declare -p a # Displays no element
+
+a['$key']=2
+unset "a['\$key']" # Transforms to a['$key'] after expansion
+declare -p a # Displays no element
+
+a["foo"]=3
+unset 'a["foo"]' # Transforms to a["foo"] after expansion
+declare -p a # Displays no element
+
+echo -----
+
+# The update also keeps compatibility with already existing behavior of
+# unset when assoc_expand_once is enabled, but only for quoted tokens.
+
+a=()
+shopt -s assoc_expand_once
+
+a[$key]=1
+unset "a[$key]"
+declare -p a # Displays no element
+
+a['$key']=2
+unset "a[\$key]"
+declare -p a # Displays no element
+
+a["foo"]=3
+unset "a[foo]"
+declare -p a # Displays no element
+
+echo ----------
+
+# For unsetting '@' and all elements:
+
+key=@
+
+declare -A a=(@ v0 . v1)
+unset a[$key]
+declare -p a # Displays 'declare -A a=([.]="v1" )'
+
+declare -A a=(@ v0 . v1)
+unset a[@]
+declare -p a # same behavior
+
+echo -----
+
+# these are quoted strings and unset doesn't treat them specially
+
+unset a
+shopt -u assoc_expand_once
+
+declare -A a=(@ v0 . v1)
+unset 'a[$key]'
+declare -p a # Displays 'declare -A a=([.]="v1" )'
+
+declare -A a=(@ v0 . v1)
+unset 'a[@]'
+declare -p a # same behavior
+
+echo -----
+
+unset a
+shopt -s assoc_expand_once
+
+declare -A a=(@ v0 . v1)
+unset "a[$key]" # $key is expanded
+declare -p a # Displays 'declare -A a=([.]="v1" )'
+
+declare -A a=(@ v0 . v1)
+unset 'a[@]'
+declare -p a # same behavior
diff --git a/tests/read.right b/tests/read.right
new file mode 100644
index 0000000..e21fcb5
--- /dev/null
+++ b/tests/read.right
@@ -0,0 +1,85 @@
+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
+xyz
+a = xyz
+a = -xyz 123-
+a = abc
+timeout 1: ok
+unset or null 1
+timeout 2: ok
+unset or null 2
+timeout 3: ok
+unset or null 3
+./read2.sub: line 45: read: -3: invalid timeout specification
+1
+
+abcde
+abcde
+./read3.sub: line 17: read: -1: invalid number
+abc
+defg
+ab
+abc
+#
+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
+timeout 1: ok
+unset or null 1
+timeout 2: ok
+unset or null 2
+timeout 3: ok
+unset or null 3
+timeout 4: ok
+abcde
+abcde
+
+one
+two three four
+one
+two three four
diff --git a/tests/read.tests b/tests/read.tests
new file mode 100644
index 0000000..6132b6f
--- /dev/null
+++ b/tests/read.tests
@@ -0,0 +1,117 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+echo " 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 " > $TMPDIR/IN
+unset x y z
+read x y z < $TMPDIR/IN
+echo 1: "x[$x] y[$y] z[$z]"
+echo 1a: ${z-z not set}
+read x < $TMPDIR/IN
+echo 2: "x[$x]"
+rm $TMPDIR/IN
+
+# this is where the bash `read' behavior with respect to $REPLY differs
+# from ksh93
+echo "A B " > $TMPDIR/IN
+
+read < $TMPDIR/IN
+echo "[$REPLY]"
+
+rm $TMPDIR/IN
+
+echo " A B " > $TMPDIR/IN
+
+read < $TMPDIR/IN
+echo "[$REPLY]"
+
+rm $TMPDIR/IN
+
+# make sure that read with more variables than words sets the extra
+# variables to the empty string
+
+bvar=bvar
+cvar=cvar
+echo aa > $TMPDIR/IN
+read avar bvar cvar < $TMPDIR/IN
+echo =="$avar"==
+echo =="$bvar"==
+echo =="$cvar"==
+
+rm $TMPDIR/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
+
+# test behavior of readline timeouts
+${THIS_SH} ./read7.sub
+
+# test behavior of read -n and read -d on regular files
+${THIS_SH} ./read8.sub
diff --git a/tests/read1.sub b/tests/read1.sub
new file mode 100644
index 0000000..cf00398
--- /dev/null
+++ b/tests/read1.sub
@@ -0,0 +1,37 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+a=7
+echo 'abcdefg|xyz' | {
+ read -d '|' a
+ echo a = "${a-unset}"
+ cat - # make sure we don't read too much
+}
+
+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..d353011
--- /dev/null
+++ b/tests/read2.sub
@@ -0,0 +1,72 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: ${TMPDIR:=/var/tmp}
+
+a=4
+
+read -t 1 a < /dev/tty
+estat=$?
+if [ $estat -gt 128 ]; then
+ echo timeout 1: ok
+else
+ echo $estat
+fi
+echo ${a:-unset or null 1}
+
+read -t 0.000001 a < /dev/tty
+estat=$?
+if [ $estat -gt 128 ]; then
+ echo timeout 2: ok
+else
+ echo $estat
+fi
+echo ${a:-unset or null 2}
+
+sleep 1 | read -t 0.25 a
+estat=$?
+if [ $estat -gt 128 ]; then
+ echo timeout 3: ok
+else
+ echo $estat
+fi
+echo ${a:-unset or null 3}
+
+read -t -3 a < /dev/tty
+echo $?
+
+echo $a
+
+# the above should all time out
+echo abcde | {
+ read -t 0.5 a
+ echo $a
+}
+
+read -t .0001 a <<<abcde
+echo $a
+
+# this is the original test that prompted the change to sh_timers
+cd $TMPDIR
+rm -f a.pipe
+mkfifo a.pipe
+exec 9<> a.pipe
+rm -f a.pipe
+
+for c in {0..2000}; do
+ (eval "echo {0..$c}" & read -u 9 -t 0.0001) >/dev/null
+ printf $'ok %d' "$c" >/dev/null
+done
+
+cd $OLDPWD
+rm -f $TMPDIR/a.pipe # paranoia
diff --git a/tests/read3.sub b/tests/read3.sub
new file mode 100644
index 0000000..8a24040
--- /dev/null
+++ b/tests/read3.sub
@@ -0,0 +1,38 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# non-interactive
+
+# error
+read -n -1
+
+# from pipe -- should work, but doesn't change tty attributes
+echo abcdefg | {
+ read -n 3 xyz
+ echo $xyz
+ cat - # make sure we don't read too much
+}
+
+# fewer chars than specified
+echo ab | {
+ read -n 3 xyz
+ echo $xyz
+}
+
+echo abc | {
+ read -N 4 -d$'\n' foo
+ echo $foo
+}
+
+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..e42a5be
--- /dev/null
+++ b/tests/read5.sub
@@ -0,0 +1,48 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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 | ( IFS=$' \t\n' ; while read line; do echo $line; done; )
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/read7.sub b/tests/read7.sub
new file mode 100644
index 0000000..553070f
--- /dev/null
+++ b/tests/read7.sub
@@ -0,0 +1,66 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test behavior of native readline timeouts
+
+# turn off bracketed paste to avoid spurious output
+bind 'set enable-bracketed-paste off' 2>/dev/null
+
+read -t 0.00001 -e var
+estat=$?
+if [ $estat -gt 128 ]; then
+ echo timeout 1: ok
+else
+ echo $estat
+fi
+echo ${var:-unset or null 1}
+
+read -e -t 0.1 var
+estat=$?
+if [ $estat -gt 128 ]; then
+ echo timeout 2: ok
+else
+ echo $estat
+fi
+echo ${var:-unset or null 2}
+
+read -e -t 1 var < /dev/tty
+estat=$?
+if [ $estat -gt 128 ]; then
+ echo timeout 3: ok
+else
+ echo $estat
+fi
+echo ${var:-unset or null 3}
+
+sleep 1 | read -t 0.25 -e a
+estat=$?
+if [ $estat -gt 128 ]; then
+ echo timeout 4: ok
+else
+ echo $estat
+fi
+
+# the above should all time out
+echo abcde | {
+ read -e -t 0.5 a
+ echo $a
+}
+
+read -e -t .0001 a <<<abcde
+echo $a
+
+set -o posix
+read -t 0.1 a </dev/tty
+echo $a
+
diff --git a/tests/read8.sub b/tests/read8.sub
new file mode 100644
index 0000000..d5b7af8
--- /dev/null
+++ b/tests/read8.sub
@@ -0,0 +1,15 @@
+tmpf=$TMPDIR/tmp-$$
+printf "%s\n" "one two three four" > $tmpf
+
+# make sure we rewind the input properly when reading a specific number of
+# characters or using a non-standard delimiter from a regular file
+
+exec <$tmpf
+read -n 4 input && echo "$input"
+cat -
+
+exec <$tmpf
+read -d ' ' input && echo "$input"
+cat -
+
+rm -f $tmpf
diff --git a/tests/redir.right b/tests/redir.right
new file mode 100644
index 0000000..8db1041
--- /dev/null
+++ b/tests/redir.right
@@ -0,0 +1,163 @@
+abc
+./redir.tests: line 28: /tmp/redir-test: cannot overwrite existing file
+abc
+def
+def
+./redir.tests: line 44: $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 45: $fd: ambiguous redirect
+./redir4.sub: line 46: $fd: ambiguous redirect
+err-and-out:
+to stdout
+to stderr
+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 170: redir1.*: No such file or directory
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# tests 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 2>&1 | grep -q 'invalid file descriptor'
+echo after read
+
+exec 5<&0
+
+exec <&-
+
+read abcde 2>&1 | grep -q 'read error'
+
+exec 0<&9-
+read line
+echo $line
+f ()
+{
+ exec 5< $0;
+ exec 0<&5-;
+ while read line; do
+ echo "$line";
+ done
+}
+after read
+# This program is free software: you can redistribute it and/or modify
+/
+/
+/
+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
+::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
+1
+7
+after: 42
+./redir11.sub: line 53: $(ss= declare -i ss): ambiguous redirect
+after: 42
+a+=3
+foo
+foo
+./redir11.sub: line 75: 42: No such file or directory
+42
diff --git a/tests/redir.tests b/tests/redir.tests
new file mode 100644
index 0000000..63bd4d3
--- /dev/null
+++ b/tests/redir.tests
@@ -0,0 +1,209 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: ${TMPDIR:=/tmp}
+
+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"
+
+# clean up before running scripts
+exec 4>&- 5>&- 6<&-
+
+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
+
+${THIS_SH} ./redir10.sub
+
+${THIS_SH} ./redir11.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/redir10.sub b/tests/redir10.sub
new file mode 100644
index 0000000..7b1d682
--- /dev/null
+++ b/tests/redir10.sub
@@ -0,0 +1,37 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# Out of file descriptors, because it forgets to close redirection. Only
+# happens in a shell function. Problem through bash-4.2.
+
+ulimit -n 128
+
+bug()
+{
+c=`ulimit -n`
+let c+=100
+while let c--
+do
+ while read -ru3 x
+ do
+ echo -n :
+ done 3< <(echo x)
+
+done
+}
+
+bug
+echo
+
+exit 0
diff --git a/tests/redir11.sub b/tests/redir11.sub
new file mode 100644
index 0000000..d417cdb
--- /dev/null
+++ b/tests/redir11.sub
@@ -0,0 +1,76 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# make sure redirections do not have access to the temporary environment, even
+# in subshells and command substitutions
+
+a=1
+a=4 b=7 ss=4 echo $a
+
+# use grep to avoid differences due to different system error messages
+a=42
+a=2 echo foo 2>&1 >&$a | { grep -q '\$a: Bad file' || echo 'redir11 bad 1'; }
+a=2 echo foo 2>&1 >&$(echo $a) | { grep -q 'Bad file' || echo 'redir11 bad 2'; }
+
+foo()
+{
+ local -i a
+ local v=0 x=1
+ a+=3
+ echo $a
+}
+
+a=4 b=7 ss=4 declare -i ss
+a=4 b=7 foo
+echo after: $a
+
+unset a
+a=4 echo foo 2>&1 >&$(foo) | { grep -q 'Bad file' || echo 'redir11 bad 3'; }
+a=1 echo foo 2>&1 >&$(foo) | { grep -q 'Bad file' || echo 'redir11 bad 4'; }
+a=1 echo foo 2>&1 >&$(a=4 foo) | { grep -q 'Bad file' || echo 'redir11 bad 5'; }
+echo foo 2>&1 >&$(a=4 foo) | { grep -q 'Bad file' || echo 'redir11 bad 6'; }
+
+a=42
+a=2 echo foo 2>&1 >&$a | { grep -q 'Bad file' || echo 'redir11 bad 7'; }
+a=2 echo foo 2>&1 >&$(echo $a) | { grep -q 'Bad file' || echo 'redir11 bad 8'; }
+
+unset -f foo
+foo()
+{
+ local -i a
+ local v=0 x=1
+ a+=3
+ echo $a >&$(ss= declare -i ss)
+}
+
+a=4 b=7 foo
+echo after: $a
+
+unset a
+typeset -i a
+a=4 eval echo $(echo a+=3)
+a=2
+a=9 echo foo >&$(echo $a)
+a=2
+a=9 eval echo foo >&$(echo $a)
+a=2
+a=9 eval echo foo '2>&1 >&$(echo $a)' | { grep -q 'Bad file' || echo 'redir11 bad 9'; }
+
+# double expansion of filenames when used in redirection error messages
+# present in bash versions back to at least bash-1.13
+# this is executed in the tests subdirectory of the source directory, so there
+# definitely should not be a file named `42'
+
+unset foo
+: <$((foo+=42))
+echo $foo
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..b9fd0fd
--- /dev/null
+++ b/tests/redir3.sub
@@ -0,0 +1,39 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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..a482985
--- /dev/null
+++ b/tests/redir4.sub
@@ -0,0 +1,69 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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 >&${TMPDIR}/err-and-out
+echo to stdout
+echo to stderr >&2
+
+exec 1>&3 2>&4
+echo err-and-out:
+cat ${TMPDIR}/err-and-out
+
+rm ${TMPDIR}/err-and-out
+
+fd=${TMPDIR}/err-and-out
+exec >&$fd
+echo to stdout
+echo to stderr >&2
+
+exec 1>&3 2>&4
+echo err-and-out:
+cat ${TMPDIR}/err-and-out
+
+rm ${TMPDIR}/err-and-out
diff --git a/tests/redir5.sub b/tests/redir5.sub
new file mode 100644
index 0000000..fa0f0c0
--- /dev/null
+++ b/tests/redir5.sub
@@ -0,0 +1,44 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# tests 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 2>&1 | grep -q 'invalid file descriptor'
+echo after read
+
+exec 5<&0
+
+exec <&-
+
+read abcde 2>&1 | grep -q 'read error'
+
+exec 0<&9-
+read line
+echo $line
diff --git a/tests/redir6.sub b/tests/redir6.sub
new file mode 100644
index 0000000..c735e52
--- /dev/null
+++ b/tests/redir6.sub
@@ -0,0 +1,10 @@
+cd /
+pwd
+help >&-
+pwd
+pwd
+echo $?
+echo $?
+echo $?
+
+cd $OLDPWD
diff --git a/tests/redir7.sub b/tests/redir7.sub
new file mode 100644
index 0000000..65ca473
--- /dev/null
+++ b/tests/redir7.sub
@@ -0,0 +1,82 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# 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..d2d700c
--- /dev/null
+++ b/tests/redir8.sub
@@ -0,0 +1,74 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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
+
+cd $OLDPWD
+exit 0
diff --git a/tests/redir9.sub b/tests/redir9.sub
new file mode 100644
index 0000000..9050a94
--- /dev/null
+++ b/tests/redir9.sub
@@ -0,0 +1,63 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: ${TMPDIR:=/tmp}
+
+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..4ce6743
--- /dev/null
+++ b/tests/rhs-exp.right
@@ -0,0 +1,105 @@
+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
+argv[1] = <bc>
+argv[1] = <bc>
+argv[1] = <ab>
+argv[1] = <ab>
+argv[1] = <bc>
+argv[1] = <bc>
+argv[1] = <c>
+argv[1] = <ab>
+argv[1] = <ab>
+argv[1] = <aacc>
+argv[1] = <aacc>
+argv[1] = <aabbcc>
+argv[1] = <aabbcc>
+argv[1] = <Oenophile>
+argv[1] = <OEnOphIlE>
+argv[1] = <>
+argv[1] = <abc>
+argv[1] = <''>
+argv[1] = <>
+good 1
+good 2
+good 3
+good 4
+good 5
+ok 1
+ok 2
+ok 3
+ok 4
+ok 5
+ok 6
+ok 7
diff --git a/tests/rhs-exp.tests b/tests/rhs-exp.tests
new file mode 100644
index 0000000..6abdd2a
--- /dev/null
+++ b/tests/rhs-exp.tests
@@ -0,0 +1,64 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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//\//}"
+
+${THIS_SH} ./rhs-exp1.sub
diff --git a/tests/rhs-exp1.sub b/tests/rhs-exp1.sub
new file mode 100644
index 0000000..b194bf0
--- /dev/null
+++ b/tests/rhs-exp1.sub
@@ -0,0 +1,116 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# fixes for bugs in bash-4.2 regarding empty strings in expand_string_for_rhs
+
+f=abc
+recho ${f##""a}
+recho ${f##"$v"a}
+
+recho ${f%%""c}
+recho ${f%%"$v"c}
+
+recho ${f//""a}
+recho ${f//"$v"a}
+
+recho ${f/""a""b/}
+recho ${f/""c/}
+recho ${f/"$v"c/}
+
+unset foo empty
+foo=aabbcc
+
+recho ${foo/bb/}
+recho ${foo/bb/$empty}
+
+recho ${foo/}
+recho ${empty/}
+
+recho ${foo/ }
+recho ${empty/ }
+unset foo empty
+
+S2=oenophile
+
+recho ${S2^"$v"[aeiou]}
+recho ${S2^^"$v"[aeiou]}
+
+recho ${foo:-""}
+recho ${foo:-""abc}
+
+recho "${foo:-''}"
+recho "${foo:-}"
+
+if [[ $var == "" ]]; then
+ echo good 1
+fi
+
+if [[ "$var"X == ""X ]]; then
+ echo good 2
+fi
+
+if [ "$var"X == ""X"" ]; then
+ echo good 3
+fi
+
+if [ X"" == X ]; then
+ echo good 4
+fi
+
+if [[ X"" == X ]]; then
+ echo good 5
+fi
+
+case x"" in
+ x) echo 'ok 1'
+ ;;
+ x??) echo 'this would be really odd'
+ ;;
+ x?) echo 'does this prove anything?'
+ echo x""x
+ ;;
+ *) echo 'no match'
+ ;;
+esac
+
+if [[ x"" == x ]]; then
+ echo ok 2
+fi
+
+if [[ x"" == x"" ]]; then
+ echo ok 3
+else
+ echo bad 3
+fi
+
+case x"" in
+x"") echo ok 4 ;;
+*) echo bad 4;;
+esac
+
+if [[ x"" == x"" ]]; then
+ echo ok 5
+else
+ echo bad 5
+fi
+
+case x"" in
+"x") echo ok 6 ;;
+*) echo bad 6;;
+esac
+
+case x"" in
+"x") echo CTLNUL 7 ;;
+x) echo ok 7 ;;
+*) echo bad 7 ;;
+esac
diff --git a/tests/rsh.right b/tests/rsh.right
new file mode 100644
index 0000000..5f64049
--- /dev/null
+++ b/tests/rsh.right
@@ -0,0 +1,19 @@
+./rsh1.sub: line 22: /bin/sh: restricted
+./rsh1.sub: line 24: sh: not found
+./rsh1.sub: line 25: a: command not found
+./rsh2.sub: line 23: hash: /bin/sh: restricted
+./rsh2.sub: line 25: hash: sh: not found
+./rsh2.sub: line 26: a: command not found
+./rsh.tests: line 25: cd: restricted
+./rsh.tests: line 26: PATH: readonly variable
+./rsh.tests: line 27: SHELL: readonly variable
+./rsh.tests: line 28: /bin/sh: restricted: cannot specify `/' in command names
+./rsh.tests: line 30: .: ./source.sub3: restricted
+./rsh.tests: line 33: /tmp/restricted: restricted: cannot redirect output
+./rsh.tests: line 37: /tmp/restricted: restricted: cannot redirect output
+./rsh.tests: line 42: command: -p: restricted
+./rsh.tests: line 44: set: +r: invalid option
+set: usage: set [-abefhkmnptuvxBCEHPT] [-o option-name] [--] [-] [arg ...]
+./rsh.tests: line 45: set: restricted: invalid option name
+./rsh.tests: line 47: exec: restricted
+./rsh.tests: after exec
diff --git a/tests/rsh.tests b/tests/rsh.tests
new file mode 100644
index 0000000..0d06fa1
--- /dev/null
+++ b/tests/rsh.tests
@@ -0,0 +1,49 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test restricted shell mode -- these should all be errors
+#
+# things not tested for:
+# adding builtins dynamically with enable -f
+# importing function definitions from environment
+
+${THIS_SH} ./rsh1.sub
+${THIS_SH} ./rsh2.sub
+
+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/rsh1.sub b/tests/rsh1.sub
new file mode 100644
index 0000000..1539d74
--- /dev/null
+++ b/tests/rsh1.sub
@@ -0,0 +1,29 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+cd ${TMPDIR:-/tmp}
+cp /bin/sh .
+
+PATH=/rbin:/usr/local/rbin
+hash -p /bin/rm rm
+
+set -r
+
+BASH_CMDS[x]=/bin/sh
+
+BASH_CMDS[a]="sh"
+a -c 'echo hello'
+
+rm -f sh a
+
+exit 0
diff --git a/tests/rsh2.sub b/tests/rsh2.sub
new file mode 100644
index 0000000..7259dfb
--- /dev/null
+++ b/tests/rsh2.sub
@@ -0,0 +1,30 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+cd ${TMPDIR:-/tmp}
+cp /bin/sh .
+ln sh a
+
+PATH=/rbin:/usr/local/rbin
+hash -p /bin/rm rm
+
+set -r
+
+hash -p /bin/sh sh
+
+hash -p sh a
+a -c 'echo hello'
+
+rm -f sh a
+
+exit 0
diff --git a/tests/run-alias b/tests/run-alias
new file mode 100644
index 0000000..3b4f4dc
--- /dev/null
+++ b/tests/run-alias
@@ -0,0 +1,2 @@
+${THIS_SH} ./alias.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} alias.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-all b/tests/run-all
new file mode 100644
index 0000000..1f74923
--- /dev/null
+++ b/tests/run-all
@@ -0,0 +1,64 @@
+#! /bin/sh
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+: ${TMPDIR:=/tmp}
+export TMPDIR
+
+# basic /bin/sh syntax
+SUFFIX=`${THIS_SH} -c 'echo $(( $RANDOM + $BASHPID ))'`
+
+BASH_TSTOUT=${TMPDIR}/bashtst-$SUFFIX # for now
+export BASH_TSTOUT
+
+trap 'rm -f $BASH_TSTOUT ; exit' 1 2 3 15
+trap 'rm -f $BASH_TSTOUT' 0
+
+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
+# can't reliably do it for SHELLOPTS; SHELLOPTS is readonly in bash
+if [ "${BASH_VERSION+set}" = "set" ]; then
+ export -n SHELLOPTS # just make sure its not exported
+ set +o posix
+ typeset -p SHELLOPTS
+else
+ [ "${SHELLOPTS+set}" = "set" ] && unset SHELLOPTS 2>/dev/null
+fi
+
+: ${THIS_SH:=../bash}
+export THIS_SH
+
+: ${BUILD_DIR:=..}
+export BUILD_DIR
+
+${THIS_SH} ./version
+
+rm -f ${BASH_TSTOUT}
+
+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 ; rm -f ${BASH_TSTOUT} ;;
+ esac
+done
+
+exit 0
diff --git a/tests/run-appendop b/tests/run-appendop
new file mode 100644
index 0000000..2d756f8
--- /dev/null
+++ b/tests/run-appendop
@@ -0,0 +1,2 @@
+${THIS_SH} ./appendop.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} appendop.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-arith b/tests/run-arith
new file mode 100644
index 0000000..0786b4f
--- /dev/null
+++ b/tests/run-arith
@@ -0,0 +1,2 @@
+${THIS_SH} ./arith.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} arith.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-arith-for b/tests/run-arith-for
new file mode 100644
index 0000000..085715e
--- /dev/null
+++ b/tests/run-arith-for
@@ -0,0 +1,2 @@
+${THIS_SH} ./arith-for.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} arith-for.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-array b/tests/run-array
new file mode 100644
index 0000000..6c5ec27
--- /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 > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} array.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-array2 b/tests/run-array2
new file mode 100644
index 0000000..54852ec
--- /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 > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} array2.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-assoc b/tests/run-assoc
new file mode 100644
index 0000000..7fef234
--- /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 > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} assoc.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-attr b/tests/run-attr
new file mode 100644
index 0000000..948b9e1
--- /dev/null
+++ b/tests/run-attr
@@ -0,0 +1,2 @@
+${THIS_SH} ./attr.tests 2>&1 | grep -v '^expect' > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} attr.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-braces b/tests/run-braces
new file mode 100644
index 0000000..554e218
--- /dev/null
+++ b/tests/run-braces
@@ -0,0 +1,2 @@
+${THIS_SH} ./braces.tests > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} braces.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-builtins b/tests/run-builtins
new file mode 100644
index 0000000..69644f2
--- /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 > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} builtins.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-case b/tests/run-case
new file mode 100644
index 0000000..1560ee2
--- /dev/null
+++ b/tests/run-case
@@ -0,0 +1,2 @@
+${THIS_SH} ./case.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} case.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-casemod b/tests/run-casemod
new file mode 100644
index 0000000..9b58764
--- /dev/null
+++ b/tests/run-casemod
@@ -0,0 +1,2 @@
+${THIS_SH} ./casemod.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} casemod.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-complete b/tests/run-complete
new file mode 100644
index 0000000..f1cef84
--- /dev/null
+++ b/tests/run-complete
@@ -0,0 +1,2 @@
+${THIS_SH} ./complete.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} complete.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-comsub b/tests/run-comsub
new file mode 100644
index 0000000..4c3d1cf
--- /dev/null
+++ b/tests/run-comsub
@@ -0,0 +1,2 @@
+${THIS_SH} ./comsub.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} comsub.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-comsub-eof b/tests/run-comsub-eof
new file mode 100644
index 0000000..0733b2d
--- /dev/null
+++ b/tests/run-comsub-eof
@@ -0,0 +1,2 @@
+${THIS_SH} ./comsub-eof.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} comsub-eof.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-comsub-posix b/tests/run-comsub-posix
new file mode 100644
index 0000000..520cb44
--- /dev/null
+++ b/tests/run-comsub-posix
@@ -0,0 +1,2 @@
+${THIS_SH} ./comsub-posix.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} comsub-posix.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-cond b/tests/run-cond
new file mode 100644
index 0000000..603e739
--- /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 > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} cond.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-coproc b/tests/run-coproc
new file mode 100644
index 0000000..02c5c92
--- /dev/null
+++ b/tests/run-coproc
@@ -0,0 +1,2 @@
+${THIS_SH} ./coproc.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} coproc.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-cprint b/tests/run-cprint
new file mode 100644
index 0000000..82d2c2a
--- /dev/null
+++ b/tests/run-cprint
@@ -0,0 +1,2 @@
+${THIS_SH} ./cprint.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} cprint.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-dbg-support b/tests/run-dbg-support
new file mode 100644
index 0000000..af64517
--- /dev/null
+++ b/tests/run-dbg-support
@@ -0,0 +1,9 @@
+
+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 100644
index 0000000..375c32f
--- /dev/null
+++ b/tests/run-dbg-support2
@@ -0,0 +1,9 @@
+
+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 $?
diff --git a/tests/run-dirstack b/tests/run-dirstack
new file mode 100644
index 0000000..e6b42d4
--- /dev/null
+++ b/tests/run-dirstack
@@ -0,0 +1,5 @@
+${THIS_SH} ./dstack.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} dstack.right && rm -f ${BASH_TSTOUT}
+
+${THIS_SH} ./dstack2.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} dstack2.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-dollars b/tests/run-dollars
new file mode 100644
index 0000000..dc5d623
--- /dev/null
+++ b/tests/run-dollars
@@ -0,0 +1,2 @@
+${THIS_SH} ./dollar-at-star > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} dollar.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-dynvar b/tests/run-dynvar
new file mode 100644
index 0000000..26c5434
--- /dev/null
+++ b/tests/run-dynvar
@@ -0,0 +1,2 @@
+${THIS_SH} ./dynvar.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} dynvar.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-errors b/tests/run-errors
new file mode 100644
index 0000000..29417cd
--- /dev/null
+++ b/tests/run-errors
@@ -0,0 +1,3 @@
+unset OLDPWD # make sure shell doesn't inherit OLDPWD
+${THIS_SH} ./errors.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} errors.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-execscript b/tests/run-execscript
new file mode 100644
index 0000000..c3ed53e
--- /dev/null
+++ b/tests/run-execscript
@@ -0,0 +1,26 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+echo "warning: the text of a system error message may vary between systems and" >&2
+echo "warning: produce diff output." >&2
+echo "warning: UNIX versions number signals 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
+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 > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} exec.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-exp-tests b/tests/run-exp-tests
new file mode 100644
index 0000000..78cf754
--- /dev/null
+++ b/tests/run-exp-tests
@@ -0,0 +1,2 @@
+${THIS_SH} ./exp.tests 2>&1 | grep -v '^expect' > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} exp.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-exportfunc b/tests/run-exportfunc
new file mode 100644
index 0000000..7b207fa
--- /dev/null
+++ b/tests/run-exportfunc
@@ -0,0 +1,2 @@
+${THIS_SH} ./exportfunc.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} exportfunc.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-extglob b/tests/run-extglob
new file mode 100644
index 0000000..149e34a
--- /dev/null
+++ b/tests/run-extglob
@@ -0,0 +1,4 @@
+PATH=$PATH:`pwd`
+export PATH
+${THIS_SH} ./extglob.tests | grep -v '^expect' > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} extglob.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-extglob2 b/tests/run-extglob2
new file mode 100644
index 0000000..71d3d80
--- /dev/null
+++ b/tests/run-extglob2
@@ -0,0 +1,4 @@
+PATH=$PATH:`pwd`
+export PATH
+${THIS_SH} ./extglob2.tests | grep -v '^expect' > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} extglob2.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-extglob3 b/tests/run-extglob3
new file mode 100644
index 0000000..6ebd674
--- /dev/null
+++ b/tests/run-extglob3
@@ -0,0 +1,4 @@
+PATH=$PATH:`pwd`
+export PATH
+${THIS_SH} ./extglob3.tests > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} extglob3.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-func b/tests/run-func
new file mode 100644
index 0000000..a804364
--- /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 > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} func.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-getopts b/tests/run-getopts
new file mode 100644
index 0000000..4cfc592
--- /dev/null
+++ b/tests/run-getopts
@@ -0,0 +1,2 @@
+${THIS_SH} ./getopts.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} getopts.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-glob-test b/tests/run-glob-test
new file mode 100644
index 0000000..246501c
--- /dev/null
+++ b/tests/run-glob-test
@@ -0,0 +1,7 @@
+PATH=$PATH:`pwd`
+export PATH
+
+( diff -a glob.right glob.right >/dev/null 2>&1 ) && AFLAG=-a
+
+${THIS_SH} ./glob.tests > ${BASH_TSTOUT} 2>&1
+diff ${AFLAG} ${BASH_TSTOUT} glob.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-globstar b/tests/run-globstar
new file mode 100644
index 0000000..3aa01ed
--- /dev/null
+++ b/tests/run-globstar
@@ -0,0 +1,4 @@
+PATH=$PATH:`pwd`
+export PATH
+${THIS_SH} ./globstar.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} globstar.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-heredoc b/tests/run-heredoc
new file mode 100644
index 0000000..b655c4f
--- /dev/null
+++ b/tests/run-heredoc
@@ -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} ./heredoc.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} heredoc.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-herestr b/tests/run-herestr
new file mode 100644
index 0000000..d6def9c
--- /dev/null
+++ b/tests/run-herestr
@@ -0,0 +1,2 @@
+${THIS_SH} ./herestr.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} herestr.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-histexpand b/tests/run-histexpand
new file mode 100644
index 0000000..a0fc331
--- /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 > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} histexp.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-history b/tests/run-history
new file mode 100644
index 0000000..f4fa466
--- /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 > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} history.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-ifs b/tests/run-ifs
new file mode 100644
index 0000000..394d998
--- /dev/null
+++ b/tests/run-ifs
@@ -0,0 +1,2 @@
+${THIS_SH} ./ifs.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} ifs.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-ifs-posix b/tests/run-ifs-posix
new file mode 100644
index 0000000..895c2e2
--- /dev/null
+++ b/tests/run-ifs-posix
@@ -0,0 +1,2 @@
+${THIS_SH} ./ifs-posix.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} ifs-posix.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-input-test b/tests/run-input-test
new file mode 100644
index 0000000..412587c
--- /dev/null
+++ b/tests/run-input-test
@@ -0,0 +1,2 @@
+${THIS_SH} < ./input-line.sh > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} input.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-intl b/tests/run-intl
new file mode 100644
index 0000000..8234f28
--- /dev/null
+++ b/tests/run-intl
@@ -0,0 +1,5 @@
+# See whether or not we can use `diff -a'
+( diff -a ./intl.right ./intl.right >/dev/null 2>&1 ) && AFLAG=-a
+
+${THIS_SH} ./intl.tests > ${BASH_TSTOUT}
+diff $AFLAG ${BASH_TSTOUT} intl.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-invert b/tests/run-invert
new file mode 100644
index 0000000..b2bd06e
--- /dev/null
+++ b/tests/run-invert
@@ -0,0 +1,2 @@
+${THIS_SH} ./invert.tests 2>&1 | grep -v '^expect' > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} invert.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-iquote b/tests/run-iquote
new file mode 100644
index 0000000..4fca94a
--- /dev/null
+++ b/tests/run-iquote
@@ -0,0 +1,2 @@
+${THIS_SH} ./iquote.tests >${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} iquote.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-jobs b/tests/run-jobs
new file mode 100644
index 0000000..8429b0d
--- /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 > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} jobs.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-lastpipe b/tests/run-lastpipe
new file mode 100644
index 0000000..2edf5c4
--- /dev/null
+++ b/tests/run-lastpipe
@@ -0,0 +1,2 @@
+${THIS_SH} ./lastpipe.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} lastpipe.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-mapfile b/tests/run-mapfile
new file mode 100644
index 0000000..e5d1b38
--- /dev/null
+++ b/tests/run-mapfile
@@ -0,0 +1,2 @@
+${THIS_SH} ./mapfile.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} mapfile.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-minimal b/tests/run-minimal
new file mode 100644
index 0000000..0c3a2e5
--- /dev/null
+++ b/tests/run-minimal
@@ -0,0 +1,68 @@
+#! /bin/sh
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# run-minimal - a version of run-all for shells configured with
+# --enable-minimal-config
+#
+
+: ${TMPDIR:=/tmp}
+export TMPDIR
+
+# basic /bin/sh syntax
+SUFFIX=`${THIS_SH} -c 'echo $(( $RANDOM + $BASHPID ))'`
+
+BASH_TSTOUT=${TMPDIR}/bashtst-$SUFFIX # for now
+export BASH_TSTOUT
+
+trap 'rm -f $BASH_TSTOUT' 0
+
+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
+
+: ${BUILD_DIR:=..}
+export BUILD_DIR
+
+${THIS_SH} ./version.mini
+
+rm -f "$BASH_TSTOUT"
+
+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|run-posixpipe) echo $x ; sh $x ;;
+ run-precedence|run-quote|run-read|run-rhs-exp|run-strip|run-tilde) echo $x ; sh $x ;;
+ run-dynvar|run-iquote) echo $x ; sh $x ;;
+ run-type|run-comsub-eof|run-comsub-posix) echo $x ; sh $x ;;
+ *) ;;
+ esac
+ rm -f "$BASH_TSTOUT"
+done
+
+exit 0
diff --git a/tests/run-more-exp b/tests/run-more-exp
new file mode 100644
index 0000000..0424a2f
--- /dev/null
+++ b/tests/run-more-exp
@@ -0,0 +1,2 @@
+${THIS_SH} ./more-exp.tests 2>&1 | grep -v '^expect' > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} more-exp.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-nameref b/tests/run-nameref
new file mode 100644
index 0000000..b73e1b8
--- /dev/null
+++ b/tests/run-nameref
@@ -0,0 +1,4 @@
+echo "warning: some of these tests will fail if arrays have not" >&2
+echo "warning: been compiled into the shell" >&2
+${THIS_SH} ./nameref.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} nameref.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-new-exp b/tests/run-new-exp
new file mode 100644
index 0000000..8777c7b
--- /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' > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} new-exp.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-nquote b/tests/run-nquote
new file mode 100644
index 0000000..03954b8
--- /dev/null
+++ b/tests/run-nquote
@@ -0,0 +1,2 @@
+${THIS_SH} ./nquote.tests 2>&1 | grep -v '^expect' > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} nquote.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-nquote1 b/tests/run-nquote1
new file mode 100644
index 0000000..bd9e939
--- /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' > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} nquote1.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-nquote2 b/tests/run-nquote2
new file mode 100644
index 0000000..4648d3e
--- /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' > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} nquote2.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-nquote3 b/tests/run-nquote3
new file mode 100644
index 0000000..4a3e32a
--- /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' > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} nquote3.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-nquote4 b/tests/run-nquote4
new file mode 100644
index 0000000..985c311
--- /dev/null
+++ b/tests/run-nquote4
@@ -0,0 +1,8 @@
+# See whether or not we can use `diff -a'
+( diff -a ./nquote4.right ./nquote4.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
+
+${THIS_SH} ./nquote4.tests > ${BASH_TSTOUT} 2>&1
+diff ${AFLAG} ${BASH_TSTOUT} nquote4.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-nquote5 b/tests/run-nquote5
new file mode 100644
index 0000000..1d4c4aa
--- /dev/null
+++ b/tests/run-nquote5
@@ -0,0 +1,2 @@
+${THIS_SH} ./nquote5.tests 2>&1 | grep -v '^expect' > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} nquote5.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-parser b/tests/run-parser
new file mode 100644
index 0000000..ea1ec49
--- /dev/null
+++ b/tests/run-parser
@@ -0,0 +1,2 @@
+${THIS_SH} ./parser.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} parser.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-posix2 b/tests/run-posix2
new file mode 100644
index 0000000..cfa9571
--- /dev/null
+++ b/tests/run-posix2
@@ -0,0 +1,2 @@
+${THIS_SH} ./posix2.tests 2>&1 | grep -v '^expect' > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} posix2.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-posixexp b/tests/run-posixexp
new file mode 100644
index 0000000..827b0e4
--- /dev/null
+++ b/tests/run-posixexp
@@ -0,0 +1,2 @@
+${THIS_SH} ./posixexp.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} posixexp.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-posixexp2 b/tests/run-posixexp2
new file mode 100644
index 0000000..1e6b2d9
--- /dev/null
+++ b/tests/run-posixexp2
@@ -0,0 +1,2 @@
+${THIS_SH} ./posixexp2.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} posixexp2.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-posixpat b/tests/run-posixpat
new file mode 100644
index 0000000..8937948
--- /dev/null
+++ b/tests/run-posixpat
@@ -0,0 +1,2 @@
+${THIS_SH} ./posixpat.tests > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} posixpat.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-posixpipe b/tests/run-posixpipe
new file mode 100644
index 0000000..5f099e2
--- /dev/null
+++ b/tests/run-posixpipe
@@ -0,0 +1,2 @@
+${THIS_SH} ./posixpipe.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} posixpipe.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-precedence b/tests/run-precedence
new file mode 100644
index 0000000..06ac343
--- /dev/null
+++ b/tests/run-precedence
@@ -0,0 +1,2 @@
+${THIS_SH} ./precedence.tests > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} prec.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-printf b/tests/run-printf
new file mode 100644
index 0000000..e242787
--- /dev/null
+++ b/tests/run-printf
@@ -0,0 +1,7 @@
+# See whether or not we can use `diff -a'
+#( diff -a ./printf.tests ./printf.tests >/dev/null 2>&1 ) && AFLAG=-a
+
+# use cat -v (and assume it's there) to make control chars visible
+${THIS_SH} ./printf.tests 2>&1 | cat -v > ${BASH_TSTOUT}
+#diff $AFLAG ${BASH_TSTOUT} printf.right && rm -f ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} printf.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-procsub b/tests/run-procsub
new file mode 100644
index 0000000..796faaa
--- /dev/null
+++ b/tests/run-procsub
@@ -0,0 +1,7 @@
+echo "warning: all of these tests will fail if process substitution has not" >&2
+echo "warning: been compiled into the shell or if the OS does not provide" >&2
+echo "warning: FIFOs or /dev/fd. Some tests may fail if the OS does not" >&2
+echo "warning: provide FIFOs." >&2
+
+${THIS_SH} ./procsub.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} procsub.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-quote b/tests/run-quote
new file mode 100644
index 0000000..2543666
--- /dev/null
+++ b/tests/run-quote
@@ -0,0 +1,2 @@
+${THIS_SH} ./quote.tests >${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} quote.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-quotearray b/tests/run-quotearray
new file mode 100644
index 0000000..06e5e6e
--- /dev/null
+++ b/tests/run-quotearray
@@ -0,0 +1,2 @@
+${THIS_SH} ./quotearray.tests >${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} quotearray.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-read b/tests/run-read
new file mode 100644
index 0000000..5ec07e2
--- /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 > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} read.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-redir b/tests/run-redir
new file mode 100644
index 0000000..071af6e
--- /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 > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} redir.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-rhs-exp b/tests/run-rhs-exp
new file mode 100644
index 0000000..de8ae0e
--- /dev/null
+++ b/tests/run-rhs-exp
@@ -0,0 +1,2 @@
+${THIS_SH} ./rhs-exp.tests 2>&1 > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} rhs-exp.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-rsh b/tests/run-rsh
new file mode 100644
index 0000000..6770699
--- /dev/null
+++ b/tests/run-rsh
@@ -0,0 +1,2 @@
+${THIS_SH} ./rsh.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} rsh.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-set-e b/tests/run-set-e
new file mode 100644
index 0000000..eed17fa
--- /dev/null
+++ b/tests/run-set-e
@@ -0,0 +1,2 @@
+${THIS_SH} ./set-e.tests > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} set-e.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-set-x b/tests/run-set-x
new file mode 100644
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..02c43e7
--- /dev/null
+++ b/tests/run-shopt
@@ -0,0 +1,2 @@
+${THIS_SH} ./shopt.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} shopt.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-strip b/tests/run-strip
new file mode 100644
index 0000000..46a9da9
--- /dev/null
+++ b/tests/run-strip
@@ -0,0 +1,2 @@
+${THIS_SH} ./strip.tests > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} strip.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-test b/tests/run-test
new file mode 100644
index 0000000..d68791c
--- /dev/null
+++ b/tests/run-test
@@ -0,0 +1,4 @@
+unset GROUPS UID 2>/dev/null
+
+${THIS_SH} ./test.tests >${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} test.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-tilde b/tests/run-tilde
new file mode 100644
index 0000000..9460225
--- /dev/null
+++ b/tests/run-tilde
@@ -0,0 +1,2 @@
+${THIS_SH} ./tilde.tests > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} tilde.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-tilde2 b/tests/run-tilde2
new file mode 100644
index 0000000..fa7e7d6
--- /dev/null
+++ b/tests/run-tilde2
@@ -0,0 +1,2 @@
+${THIS_SH} ./tilde2.tests > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} tilde2.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-trap b/tests/run-trap
new file mode 100644
index 0000000..e3331ed
--- /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 > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} trap.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-type b/tests/run-type
new file mode 100644
index 0000000..499cb4e
--- /dev/null
+++ b/tests/run-type
@@ -0,0 +1,2 @@
+${THIS_SH} ./type.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} type.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-varenv b/tests/run-varenv
new file mode 100644
index 0000000..be394cc
--- /dev/null
+++ b/tests/run-varenv
@@ -0,0 +1,4 @@
+echo "warning: some of these tests will fail if arrays have not" >&2
+echo "warning: been compiled into the shell" >&2
+${THIS_SH} ./varenv.tests 2>&1 | grep -v '^expect' > ${BASH_TSTOUT}
+diff ${BASH_TSTOUT} varenv.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/run-vredir b/tests/run-vredir
new file mode 100644
index 0000000..2bdc1b8
--- /dev/null
+++ b/tests/run-vredir
@@ -0,0 +1,4 @@
+echo "warning: the text of a system error message may vary between systems and" >&2
+echo "warning: produce diff output." >&2
+${THIS_SH} ./vredir.tests > ${BASH_TSTOUT} 2>&1
+diff ${BASH_TSTOUT} vredir.right && rm -f ${BASH_TSTOUT}
diff --git a/tests/set-e.right b/tests/set-e.right
new file mode 100644
index 0000000..e2a9f2c
--- /dev/null
+++ b/tests/set-e.right
@@ -0,0 +1,72 @@
+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
+A:
+B:
+ehB
+C:
+D:
diff --git a/tests/set-e.tests b/tests/set-e.tests
new file mode 100644
index 0000000..3e0d669
--- /dev/null
+++ b/tests/set-e.tests
@@ -0,0 +1,124 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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
+${THIS_SH} ./set-e3.sub
diff --git a/tests/set-e1.sub b/tests/set-e1.sub
new file mode 100644
index 0000000..cdd4d63
--- /dev/null
+++ b/tests/set-e1.sub
@@ -0,0 +1,72 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# 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-e3.sub b/tests/set-e3.sub
new file mode 100644
index 0000000..db176b1
--- /dev/null
+++ b/tests/set-e3.sub
@@ -0,0 +1,10 @@
+foo()
+{
+ echo A:
+ . ./set-e3a.sub
+ echo D:
+}
+
+# should run all the way through; foo being called in a context where set -e
+# is ignored means that that condition persists through sourcing the file
+foo && true
diff --git a/tests/set-e3a.sub b/tests/set-e3a.sub
new file mode 100644
index 0000000..5d008e7
--- /dev/null
+++ b/tests/set-e3a.sub
@@ -0,0 +1,7 @@
+echo B:
+
+set -e
+echo $-
+false
+
+echo C:
diff --git a/tests/set-x.right b/tests/set-x.right
new file mode 100644
index 0000000..259602e
--- /dev/null
+++ b/tests/set-x.right
@@ -0,0 +1,60 @@
++ (( 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
++ foo=one
++ foo+=two
++ echo onetwo
+onetwo
++ 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 100644
index 0000000..3723552
--- /dev/null
+++ b/tests/set-x.tests
@@ -0,0 +1,38 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# $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
+
+foo=one
+foo+=two
+echo $foo
+
+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..cb7fa82
--- /dev/null
+++ b/tests/set-x1.sub
@@ -0,0 +1,38 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: ${TMPDIR:=/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..d617c1d
--- /dev/null
+++ b/tests/shopt.right
@@ -0,0 +1,312 @@
+./shopt.tests: line 15: shopt: -z: invalid option
+shopt: usage: shopt [-pqsu] [-o] [optname ...]
+--
+shopt -u autocd
+shopt -u assoc_expand_once
+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 compat41
+shopt -u compat42
+shopt -u compat43
+shopt -u compat44
+shopt -s complete_fullquote
+shopt -u direxpand
+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 -s globasciiranges
+shopt -s globskipdots
+shopt -u globstar
+shopt -u gnu_errfmt
+shopt -u histappend
+shopt -u histreedit
+shopt -u histverify
+shopt -s hostcomplete
+shopt -u huponexit
+shopt -u inherit_errexit
+shopt -s interactive_comments
+shopt -u lastpipe
+shopt -u lithist
+shopt -u localvar_inherit
+shopt -u localvar_unset
+shopt -u login_shell
+shopt -u mailwarn
+shopt -u no_empty_cmd_completion
+shopt -u nocaseglob
+shopt -u nocasematch
+shopt -u noexpand_translation
+shopt -u nullglob
+shopt -s patsub_replacement
+shopt -s progcomp
+shopt -u progcomp_alias
+shopt -s promptvars
+shopt -u restricted_shell
+shopt -u shift_verbose
+shopt -s sourcepath
+shopt -u varredir_close
+shopt -u xpg_echo
+--
+shopt -u huponexit
+shopt -u checkwinsize
+shopt -s sourcepath
+--
+shopt -s cdspell
+shopt -s cmdhist
+shopt -s complete_fullquote
+shopt -s expand_aliases
+shopt -s extquote
+shopt -s force_fignore
+shopt -s globasciiranges
+shopt -s globskipdots
+shopt -s hostcomplete
+shopt -s interactive_comments
+shopt -s patsub_replacement
+shopt -s progcomp
+shopt -s promptvars
+shopt -s sourcepath
+--
+shopt -u autocd
+shopt -u assoc_expand_once
+shopt -u cdable_vars
+shopt -u checkhash
+shopt -u checkjobs
+shopt -u checkwinsize
+shopt -u compat31
+shopt -u compat32
+shopt -u compat40
+shopt -u compat41
+shopt -u compat42
+shopt -u compat43
+shopt -u compat44
+shopt -u direxpand
+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 inherit_errexit
+shopt -u lastpipe
+shopt -u lithist
+shopt -u localvar_inherit
+shopt -u localvar_unset
+shopt -u login_shell
+shopt -u mailwarn
+shopt -u no_empty_cmd_completion
+shopt -u nocaseglob
+shopt -u nocasematch
+shopt -u noexpand_translation
+shopt -u nullglob
+shopt -u progcomp_alias
+shopt -u restricted_shell
+shopt -u shift_verbose
+shopt -u varredir_close
+shopt -u xpg_echo
+--
+autocd off
+assoc_expand_once off
+cdable_vars off
+checkhash off
+checkjobs off
+checkwinsize off
+compat31 off
+compat32 off
+compat40 off
+compat41 off
+compat42 off
+compat43 off
+compat44 off
+direxpand 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
+inherit_errexit off
+lastpipe off
+lithist off
+localvar_inherit off
+localvar_unset off
+login_shell off
+mailwarn off
+no_empty_cmd_completion off
+nocaseglob off
+nocasematch off
+noexpand_translation off
+nullglob off
+progcomp_alias off
+restricted_shell off
+shift_verbose off
+varredir_close 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 106: shopt: xyz1: invalid shell option name
+./shopt.tests: line 107: shopt: xyz1: invalid option name
+28c28
+< globskipdots off
+---
+> globskipdots on
+expand_aliases on
+expand_aliases on
diff --git a/tests/shopt.tests b/tests/shopt.tests
new file mode 100644
index 0000000..c31870c
--- /dev/null
+++ b/tests/shopt.tests
@@ -0,0 +1,113 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# 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
+
+${THIS_SH} ./shopt1.sub
+
+# test whether or not temporary variable assignments that manipulate posix
+# mode restore the previous state or the default non-posix state
+${THIS_SH} -c 'shopt -s expand_aliases ; shopt expand_aliases ; POSIXLY_CORRECT=y true ; shopt expand_aliases'
diff --git a/tests/shopt1.sub b/tests/shopt1.sub
new file mode 100644
index 0000000..8c1150f
--- /dev/null
+++ b/tests/shopt1.sub
@@ -0,0 +1,52 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# verify all shopt options are reset properly when the shell is reinitialized
+
+: ${TMPDIR:=/var/tmp} ${THIS_SH:=$PWD/bash}
+
+t1=$(mktemp)
+t2=$(mktemp)
+
+if [ ! -e "$t1" ] ; then
+ S1=$RANDOM
+ S2=$RANDOM
+ t1=$TMPDIR/s-$S1
+ t2=$TMPDIR/s-$S2
+ touch "$t1" "$t2"
+fi
+
+chmod +x "$t1" "$t2"
+
+echo "shopt" > "$t1"
+
+echo "#!${THIS_SH}" > "$t2"
+echo "shopt" >> "$t2"
+
+for o in $(compgen -A shopt)
+do
+ case $o in
+ extdebug) ;;
+ *) shopt -s $o ;;
+ esac
+done
+diff <("$t1") <("$t2")
+
+for o in $(compgen -A shopt)
+do
+ shopt -u $o;
+done
+diff <("$t1") <("$t2")
+
+rm "$t1" "$t2"
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..4149c11
--- /dev/null
+++ b/tests/source5.sub
@@ -0,0 +1,32 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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-existent 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..2437292
--- /dev/null
+++ b/tests/source6.sub
@@ -0,0 +1,49 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# tests 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
+if [ -e /dev/stdin ]; then
+echo "echo three - OK" | . /dev/stdin
+echo $?
+else
+# no /dev/stdin, just fake it
+echo "three - OK" ; echo 0
+fi
+
+# 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/source7.sub b/tests/source7.sub
new file mode 100644
index 0000000..474a66f
--- /dev/null
+++ b/tests/source7.sub
@@ -0,0 +1,53 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+shopt -s expand_aliases
+
+: ${TMPDIR:=/var/tmp}
+
+echo '((echo abc; echo def;); echo ghi)' > $TMPDIR/x28-$$
+. $TMPDIR/x28-$$
+rm -f $TMPDIR/x28-$$
+
+echo after
+
+TMPFILE=$TMPDIR/x29-$$
+
+echo "#! ${THIS_SH}" >$TMPFILE
+cat >> $TMPFILE << \EOF
+
+(echo -n "$1 "; echo subshell)
+EOF
+chmod 755 $TMPFILE
+
+alias foo1='$TMPFILE one.1; source $TMPFILE two.1; source $TMPFILE three.1; $TMPFILE four.1'
+alias foo2='$TMPFILE one.2;
+source $TMPFILE two.2;
+source $TMPFILE three.2;
+$TMPFILE four.2;
+'
+
+foo1
+foo2
+
+echo x29 - done
+rm -f $TMPFILE
+
+# this is also treated similarly to an alias expansion internally
+((echo abc; echo def;); echo ghi)
+
+if (((4+4) + (4 + 7))); then
+ echo ok
+fi
+
+(()) # make sure the null expression works OK
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..b16705f
--- /dev/null
+++ b/tests/strip.tests
@@ -0,0 +1,35 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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-glue-functions b/tests/test-glue-functions
new file mode 100644
index 0000000..07ad821
--- /dev/null
+++ b/tests/test-glue-functions
@@ -0,0 +1,13 @@
+# shell functions to include in multiple test files
+
+# squeeze out blanks to avoid white space differences in od implementations
+_intl_normalize_spaces()
+{
+ sed -e 's/[[:space:]]\{1,\}/ /g' -e 's/[[:space:]]*$//'
+}
+
+# avoid whitespace differences in wc implementations
+_cut_leading_spaces()
+{
+ sed -e 's/^[ ]*//g'
+}
diff --git a/tests/test.right b/tests/test.right
new file mode 100644
index 0000000..4be22f4
--- /dev/null
+++ b/tests/test.right
@@ -0,0 +1,297 @@
+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 -v unset
+1
+t -v set
+0
+t -v set
+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 ! ! "$z"
+0
+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 26: test: 4+3: integer expression expected
+2
+b 4-5 -eq 7
+./test.tests: line 20: [: 4+3: integer expression expected
+2
+t 9 -eq 4+5
+./test.tests: line 26: test: 4+5: integer expression expected
+2
+b 9 -eq 4+5
+./test.tests: line 20: [: 4+5: integer expression expected
+2
+t A -eq 7
+./test.tests: line 26: test: A: integer expression expected
+2
+b A -eq 7
+./test.tests: line 20: [: A: integer expression expected
+2
+t 9 -eq B
+./test.tests: line 26: test: B: integer expression expected
+2
+b 9 -eq B
+./test.tests: line 20: [: B: integer expression expected
+2
+t ( 1 = 2
+./test.tests: line 26: test: `)' expected
+2
+b ( 1 = 2
+./test.tests: line 20: [: `)' expected, found ]
+2
+./test.tests: line 26: test: a: unary operator expected
+2
+./test.tests: line 26: test: b: binary operator expected
+2
+./test.tests: line 26: test: -A: unary operator expected
+2
+./test.tests: line 26: test: syntax error: `-ne' unexpected
+2
+./test.tests: line 26: test: too many arguments
+2
+./test.tests: line 434: [: missing `]'
+2
+./test.tests: line 26: 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
+t -p /dev/fd/6
+1
+t -p /dev/fd/6
+0
diff --git a/tests/test.tests b/tests/test.tests
new file mode 100644
index 0000000..df4b850
--- /dev/null
+++ b/tests/test.tests
@@ -0,0 +1,456 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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 ; sleep 1; echo "hello" > /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
+
+# test set or unset shell options
+set +o allexport
+echo 't -o allexport'
+t -o allexport
+echo 't ! -o allexport'
+t ! -o allexport
+
+#test set or unset shell variables
+unset unset
+echo 't -v unset'
+t -v unset
+set=
+echo 't -v set'
+t -v set
+set=set
+echo 't -v set'
+t -v set
+
+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"
+
+echo 't ! ! "$z"'
+t ! ! "$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 ' '
+
+${THIS_SH} ./test1.sub
diff --git a/tests/test1.sub b/tests/test1.sub
new file mode 100644
index 0000000..d25e0dc
--- /dev/null
+++ b/tests/test1.sub
@@ -0,0 +1,34 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# some systems, like old SunOS, have stat on /dev/fd/N and fstat(N, ...)
+# return different results
+: ${TMPDIR:=/tmp}
+
+trap 'rm -f ${TMPDIR}/pipe' 0 1 2 3 6 15
+
+exec 6>&-
+echo "t -p /dev/fd/6"
+test -p /dev/fd/6
+echo $?
+
+rm -f ${TMPDIR}/pipe 2>/dev/null
+mkfifo ${TMPDIR}/pipe
+cat < ${TMPDIR}/pipe &
+exec 6>&-
+exec 6>${TMPDIR}/pipe
+echo "t -p /dev/fd/6"
+test -p /dev/fd/6
+echo $?
+exec 2>/dev/null # disable process termination message
+kill $! 2>/dev/null
diff --git a/tests/tilde.right b/tests/tilde.right
new file mode 100644
index 0000000..1301c0b
--- /dev/null
+++ b/tests/tilde.right
@@ -0,0 +1,28 @@
+~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
+foo=bar:/usr/xyz
+foo=bar:~
diff --git a/tests/tilde.tests b/tests/tilde.tests
new file mode 100644
index 0000000..20268a7
--- /dev/null
+++ b/tests/tilde.tests
@@ -0,0 +1,94 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+wdir=$PWD
+# 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"
+
+printf "%q\n" '~'
+
+# 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
+
+cd "$wdir"
+
+# this test is incomplete; should also test assignment statements (tilde3.sub)
+echo foo=bar:~
+set -o posix
+echo foo=bar:~
+
+exit 0
diff --git a/tests/tilde2.right b/tests/tilde2.right
new file mode 100644
index 0000000..f383e3a
--- /dev/null
+++ b/tests/tilde2.right
@@ -0,0 +1,28 @@
+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
+foo=/home/xyz:/home/xyz
+/home/xyz:/home/xyz
+foo=~:~
+/home/xyz:/home/xyz
diff --git a/tests/tilde2.tests b/tests/tilde2.tests
new file mode 100644
index 0000000..d2415cb
--- /dev/null
+++ b/tests/tilde2.tests
@@ -0,0 +1,85 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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
+
+$THIS_SH ./tilde3.sub
diff --git a/tests/tilde3.sub b/tests/tilde3.sub
new file mode 100644
index 0000000..c35ea50
--- /dev/null
+++ b/tests/tilde3.sub
@@ -0,0 +1,26 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# regression test for tilde expansion following unquoted colons in posix mode
+
+HOME=/home/xyz
+
+echo foo=~:~
+foo=~:~
+printf "%s\n" $foo
+
+set -o posix
+
+echo foo=~:~
+foo=~:~
+printf "%s\n" $foo
diff --git a/tests/trap.right b/tests/trap.right
new file mode 100644
index 0000000..4338ff4
--- /dev/null
+++ b/tests/trap.right
@@ -0,0 +1,115 @@
+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
+[33] debug
+debug line
+[35] 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
+[37] debug
+func[29] funcdebug
+funcdebug line
+./trap.tests[39] funcdebug
+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 ${FUNCNAME:-$0}[$LINENO] funcdebug' DEBUG
+./trap.tests[41] funcdebug
+./trap.tests[46] debug
+./trap.tests[47] debug
+func2[43] debug
+func2[44] debug
+func2debug line
+./trap.tests[49] debug
+./trap.tests[51] 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
+trap -- '' SIGUSR2
+ERRTRAP
+ERRTRAP
+ERRTRAP
+after falses
+if negation ok
+after negation
+after while
+before false in trap2a.sub
+after false in trap2a.sub
+command substitution
+ERRTRAP
+ERRTRAP
+bar
+ERRTRAP
+ERRTRAP
+ERRTRAP
+ERRTRAP
+ERRTRAP
++[6] echo 1
+1
++[7] echo 2
+2
++[8] false
++[8] false
++[8] false
+++[8] echo trap: 8
+trap: 8
++[9] echo 4
+4
+exit subshell 1
+current shell
+exit subshell 2
+current shell
+current shell
+current shell
+outside 1
+outside 2
+outside 3
+outside 4
+sleep 2
+wait $!
+exit
+in trap EXIT
+sleep 2
+wait $!
+exit
+in trap EXIT
+fn
+after 1
+fn
+after 2
+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
+exiting
diff --git a/tests/trap.tests b/tests/trap.tests
new file mode 100644
index 0000000..4f808be
--- /dev/null
+++ b/tests/trap.tests
@@ -0,0 +1,114 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test 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
+trap - USR2
+
+# test ERR trap
+./trap2.sub
+
+${THIS_SH} ./trap3.sub
+
+${THIS_SH} ./trap4.sub
+
+# This doesn't work right on all Unix versions
+#${THIS_SH} ./trap5.sub
+
+# Return trap issues
+${THIS_SH} ./trap6.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..bd9a76b
--- /dev/null
+++ b/tests/trap2.sub
@@ -0,0 +1,62 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+set +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)
+
+# test behavior of failed commands following `command' builtin
+command false
+
+(command false)
+command false | echo bar
+
+(false)
+
+exit 42 | command false
+
+command command command false
+
+unset FALSE
+if [ -x /bin/false ]; then
+ FALSE=/bin/false
+elif [ -x /usr/bin/false ]; then
+ FALSE=/usr/bin/false
+else
+ FALSE='command false'
+fi
+
+command $FALSE
+command command command $FALSE
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..1490a76
--- /dev/null
+++ b/tests/trap3.sub
@@ -0,0 +1,9 @@
+PS4='+[$LINENO] '
+trap 'echo trap: $LINENO' ERR
+
+set -x
+
+echo 1
+echo 2
+false | false | false
+echo 4
diff --git a/tests/trap4.sub b/tests/trap4.sub
new file mode 100644
index 0000000..c84b54e
--- /dev/null
+++ b/tests/trap4.sub
@@ -0,0 +1,55 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# make sure subshells at the end of pipelines run any exit traps they set
+
+: | { trap 'echo exit subshell 1' EXIT; exit; }; echo current shell
+
+: | { trap 'echo exit subshell 2' EXIT; exit; }; echo current shell
+
+: | { trap 'echo exit subshell 3' EXIT; exit; } | : ; echo current shell
+
+: | { trap 'echo exit subshell 4' EXIT; exit; } | : ; echo current shell
+
+trap 'echo inherited exit trap' EXIT
+: | { exit; } ; echo outside 1
+: | ( exit; ) ; echo outside 2
+: | { exit; } | : ; echo outside 3
+: | ( exit; ) | : ; echo outside 4
+
+trap - EXIT
+
+# make sure group commands that are not at the beginning or end of pipelines
+# run an EXIT trap, with and without the exit builtin
+echo ignored |
+{
+ trap 'echo "in trap EXIT">&2' EXIT
+ sleep 4 &
+ echo 'sleep 2'>&2
+ sleep 2
+ echo 'wait $!'>&2
+ wait $!
+ echo 'exit'>&2
+ exit
+} | cat
+
+echo ignored |
+{
+ trap 'echo "in trap EXIT">&2' EXIT
+ sleep 4 &
+ echo 'sleep 2'>&2
+ sleep 2
+ echo 'wait $!'>&2
+ wait $!
+ echo 'exit'>&2
+} | cat
diff --git a/tests/trap5.sub b/tests/trap5.sub
new file mode 100644
index 0000000..826b794
--- /dev/null
+++ b/tests/trap5.sub
@@ -0,0 +1,31 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# make sure process substitution runs the exit trap
+[[ -n $(< <(trap "cat /dev/fd/0" EXIT)) ]] <<<works && echo works || echo "fail :("
+
+read foo < <(trap "echo bar" EXIT)
+echo $foo
+
+cat <(trap "echo bar" EXIT)
+
+trap "echo bar" EXIT #should proc subst inherit this?
+cat <(echo foo ; exit 0;)
+
+trap - 0
+trap
+
+cat <(echo foo; trap "echo bar" EXIT)
+
+trap "echo bar" EXIT #should proc subst inherit this?
+cat <(echo foo)
diff --git a/tests/trap6.sub b/tests/trap6.sub
new file mode 100644
index 0000000..7268558
--- /dev/null
+++ b/tests/trap6.sub
@@ -0,0 +1,28 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+set -o functrace
+fn() { return; }
+
+trap "echo fn ; fn" RETURN
+
+fn
+echo after 1
+
+unset -f fn
+
+fn() { eval return; }
+fn
+echo after 2
+
+unset -f fn
diff --git a/tests/type.right b/tests/type.right
new file mode 100644
index 0000000..bbc228e
--- /dev/null
+++ b/tests/type.right
@@ -0,0 +1,135 @@
+./type.tests: line 22: type: -r: invalid option
+type: usage: type [-afptP] name [name ...]
+./type.tests: line 25: 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 56: 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 78: type: func: not found
+./type.tests: line 80: type: m: not found
+/bin/sh
+/tmp/bash
+bash is hashed (/tmp/bash)
+file
+hits command
+ 1 /bin/sh
+ 3 /tmp/bash
+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
+foo is a function
+foo ()
+{
+ rm -f a b c;
+ for f in a b c;
+ do
+ cat <<-EOF >> ${f}
+file
+EOF
+
+ done
+ grep . a b c
+}
+a:file
+b:file
+c:file
+bb is a function
+bb ()
+{
+ ( cat <<EOF
+foo
+bar
+EOF
+ )
+ echo after subshell
+}
+mkcoprocs is a function
+mkcoprocs ()
+{
+ coproc a {
+ cat <<EOF1
+producer 1
+EOF1
+
+ }
+ coproc b {
+ cat <<EOF2
+producer 2
+EOF2
+
+ }
+ echo "coprocs created"
+}
+mkcoprocs is a function
+mkcoprocs ()
+{
+ coproc COPROC ( b cat <<EOF
+heredoc
+body
+EOF
+ )
+ echo "coprocs created"
+}
diff --git a/tests/type.tests b/tests/type.tests
new file mode 100644
index 0000000..fd39c18
--- /dev/null
+++ b/tests/type.tests
@@ -0,0 +1,110 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+set +o posix
+
+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
+
+${THIS_SH} type3.sub
+
+${THIS_SH} type4.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..34977c5
--- /dev/null
+++ b/tests/type2.sub
@@ -0,0 +1,29 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+foo()
+{
+ echo
+ cat <<END
+bar
+END
+ cat <<EOF
+qux
+EOF
+}
+
+type foo
+foo
+
+eval "$(type foo | sed 1d)"
+foo
diff --git a/tests/type3.sub b/tests/type3.sub
new file mode 100644
index 0000000..1a95de3
--- /dev/null
+++ b/tests/type3.sub
@@ -0,0 +1,34 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+cd ${TMPDIR:-/tmp}
+
+foo() {
+ rm -f a b c
+ for f in a b c; do
+ cat <<-EOF >> ${f}
+ file
+ EOF
+ done
+ grep . a b c
+}
+
+type foo
+
+eval "$(type foo | sed 1d)"
+foo
+
+rm -f a b c
+
+cd $OLDPWD
+exit 0
diff --git a/tests/type4.sub b/tests/type4.sub
new file mode 100644
index 0000000..937f998
--- /dev/null
+++ b/tests/type4.sub
@@ -0,0 +1,56 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+bb()
+{
+ (
+ cat << EOF
+foo
+bar
+EOF
+ )
+ echo after subshell
+}
+
+type bb
+
+
+mkcoprocs()
+{
+ coproc a { cat <<EOF1
+producer 1
+EOF1
+}
+coproc b { cat << EOF2
+producer 2
+EOF2
+}
+
+echo "coprocs created"
+}
+
+type mkcoprocs
+
+unset -f mkcoprocs
+
+mkcoprocs()
+{
+ coproc ( b cat << EOF
+heredoc
+body
+EOF
+ )
+echo "coprocs created"
+}
+
+type mkcoprocs
diff --git a/tests/unicode1.sub b/tests/unicode1.sub
new file mode 100644
index 0000000..713ab40
--- /dev/null
+++ b/tests/unicode1.sub
@@ -0,0 +1,608 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+unset LC_ALL
+
+ErrorCnt=0
+TestCnt=0
+
+ function check_valid_var_name {
+ case "${1:?Missing Variable Name}" in
+ [!a-zA-Z_]* | *[!a-zA-Z_0-9]* ) return 3;;
+ esac
+ }
+ # get_array_element VariableName ArrayName ArrayElement
+ function get_array_element {
+ check_valid_var_name "${1:?Missing Variable Name}" || return $?
+ check_valid_var_name "${2:?Missing Array Name}" || return $?
+ eval "${1}"'="${'"${2}"'["${3:?Missing Array Index}"]}"'
+ }
+ # unset_array_element VarName ArrayName
+ function get_array_element_cnt {
+ check_valid_var_name "${1:?Missing Variable Name}" || return $?
+ check_valid_var_name "${2:?Missing Array Name}" || return $?
+ eval "${1}"'="${#'"${2}"'[@]}"'
+ }
+
+
+function TestCodePage {
+ local TargetCharset="${1:?Missing Test charset}"
+ local EChar RChar TCnt
+ get_array_element_cnt TCnt "${2:?Missing Array Name}"
+ for (( x=1 ; x<${TCnt} ; x++ )); do
+ get_array_element EChar "${2}" ${x}
+ if [ -n "${EChar}" ]; then
+ let TestCnt+=1
+ printf -v UVal '\\U%08x' "${x}"
+ LC_CTYPE=${TargetCharset} printf -v RChar "${UVal}" 2>/dev/null
+ if [ "${EChar}" != "${RChar}" ]; then
+ let ErrorCnt+=1
+ printf "${TargetCharset}: Error Encoding U+%08X to ${TL} [ \"%q\" != \"%q\" ]\n" "${x}" "${EChar}" "${RChar}"
+ fi
+ fi
+ done
+}
+
+
+#for ((x=1;x<255;x++)); do printf ' [0x%04x]=$'\''\%03o'\' $x $x ; [ $(($x%5)) = 0 ] && echo; done
+fr_FR_ISO_8859_1=(
+ [0x0001]=$'\001' [0x0002]=$'\002' [0x0003]=$'\003' [0x0004]=$'\004' [0x0005]=$'\005'
+ [0x0006]=$'\006' [0x0007]=$'\007' [0x0008]=$'\010' [0x0009]=$'\011' [0x000a]=$'\012'
+ [0x000b]=$'\013' [0x000c]=$'\014' [0x000d]=$'\015' [0x000e]=$'\016' [0x000f]=$'\017'
+ [0x0010]=$'\020' [0x0011]=$'\021' [0x0012]=$'\022' [0x0013]=$'\023' [0x0014]=$'\024'
+ [0x0015]=$'\025' [0x0016]=$'\026' [0x0017]=$'\027' [0x0018]=$'\030' [0x0019]=$'\031'
+ [0x001a]=$'\032' [0x001b]=$'\033' [0x001c]=$'\034' [0x001d]=$'\035' [0x001e]=$'\036'
+ [0x001f]=$'\037' [0x0020]=$'\040' [0x0021]=$'\041' [0x0022]=$'\042' [0x0023]=$'\043'
+ [0x0024]=$'\044' [0x0025]=$'\045' [0x0026]=$'\046' [0x0027]=$'\047' [0x0028]=$'\050'
+ [0x0029]=$'\051' [0x002a]=$'\052' [0x002b]=$'\053' [0x002c]=$'\054' [0x002d]=$'\055'
+ [0x002e]=$'\056' [0x002f]=$'\057' [0x0030]=$'\060' [0x0031]=$'\061' [0x0032]=$'\062'
+ [0x0033]=$'\063' [0x0034]=$'\064' [0x0035]=$'\065' [0x0036]=$'\066' [0x0037]=$'\067'
+ [0x0038]=$'\070' [0x0039]=$'\071' [0x003a]=$'\072' [0x003b]=$'\073' [0x003c]=$'\074'
+ [0x003d]=$'\075' [0x003e]=$'\076' [0x003f]=$'\077' [0x0040]=$'\100' [0x0041]=$'\101'
+ [0x0042]=$'\102' [0x0043]=$'\103' [0x0044]=$'\104' [0x0045]=$'\105' [0x0046]=$'\106'
+ [0x0047]=$'\107' [0x0048]=$'\110' [0x0049]=$'\111' [0x004a]=$'\112' [0x004b]=$'\113'
+ [0x004c]=$'\114' [0x004d]=$'\115' [0x004e]=$'\116' [0x004f]=$'\117' [0x0050]=$'\120'
+ [0x0051]=$'\121' [0x0052]=$'\122' [0x0053]=$'\123' [0x0054]=$'\124' [0x0055]=$'\125'
+ [0x0056]=$'\126' [0x0057]=$'\127' [0x0058]=$'\130' [0x0059]=$'\131' [0x005a]=$'\132'
+ [0x005b]=$'\133' [0x005c]=$'\134' [0x005d]=$'\135' [0x005e]=$'\136' [0x005f]=$'\137'
+ [0x0060]=$'\140' [0x0061]=$'\141' [0x0062]=$'\142' [0x0063]=$'\143' [0x0064]=$'\144'
+ [0x0065]=$'\145' [0x0066]=$'\146' [0x0067]=$'\147' [0x0068]=$'\150' [0x0069]=$'\151'
+ [0x006a]=$'\152' [0x006b]=$'\153' [0x006c]=$'\154' [0x006d]=$'\155' [0x006e]=$'\156'
+ [0x006f]=$'\157' [0x0070]=$'\160' [0x0071]=$'\161' [0x0072]=$'\162' [0x0073]=$'\163'
+ [0x0074]=$'\164' [0x0075]=$'\165' [0x0076]=$'\166' [0x0077]=$'\167' [0x0078]=$'\170'
+ [0x0079]=$'\171' [0x007a]=$'\172' [0x007b]=$'\173' [0x007c]=$'\174' [0x007d]=$'\175'
+ [0x007e]=$'\176' [0x007f]=$'\177' [0x0080]=$'\200' [0x0081]=$'\201' [0x0082]=$'\202'
+ [0x0083]=$'\203' [0x0084]=$'\204' [0x0085]=$'\205' [0x0086]=$'\206' [0x0087]=$'\207'
+ [0x0088]=$'\210' [0x0089]=$'\211' [0x008a]=$'\212' [0x008b]=$'\213' [0x008c]=$'\214'
+ [0x008d]=$'\215' [0x008e]=$'\216' [0x008f]=$'\217' [0x0090]=$'\220' [0x0091]=$'\221'
+ [0x0092]=$'\222' [0x0093]=$'\223' [0x0094]=$'\224' [0x0095]=$'\225' [0x0096]=$'\226'
+ [0x0097]=$'\227' [0x0098]=$'\230' [0x0099]=$'\231' [0x009a]=$'\232' [0x009b]=$'\233'
+ [0x009c]=$'\234' [0x009d]=$'\235' [0x009e]=$'\236' [0x009f]=$'\237' [0x00a0]=$'\240'
+ [0x00a1]=$'\241' [0x00a2]=$'\242' [0x00a3]=$'\243' [0x00a4]=$'\244' [0x00a5]=$'\245'
+ [0x00a6]=$'\246' [0x00a7]=$'\247' [0x00a8]=$'\250' [0x00a9]=$'\251' [0x00aa]=$'\252'
+ [0x00ab]=$'\253' [0x00ac]=$'\254' [0x00ad]=$'\255' [0x00ae]=$'\256' [0x00af]=$'\257'
+ [0x00b0]=$'\260' [0x00b1]=$'\261' [0x00b2]=$'\262' [0x00b3]=$'\263' [0x00b4]=$'\264'
+ [0x00b5]=$'\265' [0x00b6]=$'\266' [0x00b7]=$'\267' [0x00b8]=$'\270' [0x00b9]=$'\271'
+ [0x00ba]=$'\272' [0x00bb]=$'\273' [0x00bc]=$'\274' [0x00bd]=$'\275' [0x00be]=$'\276'
+ [0x00bf]=$'\277' [0x00c0]=$'\300' [0x00c1]=$'\301' [0x00c2]=$'\302' [0x00c3]=$'\303'
+ [0x00c4]=$'\304' [0x00c5]=$'\305' [0x00c6]=$'\306' [0x00c7]=$'\307' [0x00c8]=$'\310'
+ [0x00c9]=$'\311' [0x00ca]=$'\312' [0x00cb]=$'\313' [0x00cc]=$'\314' [0x00cd]=$'\315'
+ [0x00ce]=$'\316' [0x00cf]=$'\317' [0x00d0]=$'\320' [0x00d1]=$'\321' [0x00d2]=$'\322'
+ [0x00d3]=$'\323' [0x00d4]=$'\324' [0x00d5]=$'\325' [0x00d6]=$'\326' [0x00d7]=$'\327'
+ [0x00d8]=$'\330' [0x00d9]=$'\331' [0x00da]=$'\332' [0x00db]=$'\333' [0x00dc]=$'\334'
+ [0x00dd]=$'\335' [0x00de]=$'\336' [0x00df]=$'\337' [0x00e0]=$'\340' [0x00e1]=$'\341'
+ [0x00e2]=$'\342' [0x00e3]=$'\343' [0x00e4]=$'\344' [0x00e5]=$'\345' [0x00e6]=$'\346'
+ [0x00e7]=$'\347' [0x00e8]=$'\350' [0x00e9]=$'\351' [0x00ea]=$'\352' [0x00eb]=$'\353'
+ [0x00ec]=$'\354' [0x00ed]=$'\355' [0x00ee]=$'\356' [0x00ef]=$'\357' [0x00f0]=$'\360'
+ [0x00f1]=$'\361' [0x00f2]=$'\362' [0x00f3]=$'\363' [0x00f4]=$'\364' [0x00f5]=$'\365'
+ [0x00f6]=$'\366' [0x00f7]=$'\367' [0x00f8]=$'\370' [0x00f9]=$'\371' [0x00fa]=$'\372'
+ [0x00fb]=$'\373' [0x00fc]=$'\374' [0x00fd]=$'\375' [0x00fe]=$'\376'
+)
+
+# this locale causes problems all over the place
+if locale -a | grep -i '^fr_FR\.ISO8859.*1$' >/dev/null ; then
+ TestCodePage fr_FR.ISO8859-1 fr_FR_ISO_8859_1
+else
+ echo "unicode1.sub: warning: you do not have the fr_FR.ISO8859-1 locale installed;" >&2
+ echo "unicode1.sub: that will cause some of these tests to be skipped." >&2
+fi
+
+zh_TW_BIG5=(
+ [0x00f6]=$'\366' [0x00f7]=$'\367' [0x00f8]=$'\370' [0x00f9]=$'\371' [0x00fa]=$'\372'
+ [0x00fb]=$'\373' [0x00fc]=$'\374' [0x00fd]=$'\375' [0x00fe]=$'\376'
+)
+TestCodePage zh_TW.BIG5 zh_TW_BIG5
+
+jp_JP_SHIFT_JIS=(
+ [0x0001]=$'\x01' # START OF HEADING
+ [0x0002]=$'\x02' # START OF TEXT
+ [0x0003]=$'\x03' # END OF TEXT
+ [0x0004]=$'\x04' # END OF TRANSMISSION
+ [0x0005]=$'\x05' # ENQUIRY
+ [0x0006]=$'\x06' # ACKNOWLEDGE
+ [0x0007]=$'\x07' # BELL
+ [0x0008]=$'\x08' # BACKSPACE
+ [0x0009]=$'\x09' # HORIZONTAL TABULATION
+ [0x000A]=$'\x0A' # LINE FEED
+ [0x000B]=$'\x0B' # VERTICAL TABULATION
+ [0x000C]=$'\x0C' # FORM FEED
+ [0x000D]=$'\x0D' # CARRIAGE RETURN
+ [0x000E]=$'\x0E' # SHIFT OUT
+ [0x000F]=$'\x0F' # SHIFT IN
+ [0x0010]=$'\x10' # DATA LINK ESCAPE
+ [0x0011]=$'\x11' # DEVICE CONTROL ONE
+ [0x0012]=$'\x12' # DEVICE CONTROL TWO
+ [0x0013]=$'\x13' # DEVICE CONTROL THREE
+ [0x0014]=$'\x14' # DEVICE CONTROL FOUR
+ [0x0015]=$'\x15' # NEGATIVE ACKNOWLEDGE
+ [0x0016]=$'\x16' # SYNCHRONOUS IDLE
+ [0x0017]=$'\x17' # END OF TRANSMISSION BLOCK
+ [0x0018]=$'\x18' # CANCEL
+ [0x0019]=$'\x19' # END OF MEDIUM
+ [0x001A]=$'\x1A' # SUBSTITUTE
+ [0x001B]=$'\x1B' # ESCAPE
+ [0x001C]=$'\x1C' # FILE SEPARATOR
+ [0x001D]=$'\x1D' # GROUP SEPARATOR
+ [0x001E]=$'\x1E' # RECORD SEPARATOR
+ [0x001F]=$'\x1F' # UNIT SEPARATOR
+ [0x0020]=$'\x20' # SPACE
+ [0x0021]=$'\x21' # EXCLAMATION MARK
+ [0x0022]=$'\x22' # QUOTATION MARK
+ [0x0023]=$'\x23' # NUMBER SIGN
+ [0x0024]=$'\x24' # DOLLAR SIGN
+ [0x0025]=$'\x25' # PERCENT SIGN
+ [0x0026]=$'\x26' # AMPERSAND
+ [0x0027]=$'\x27' # APOSTROPHE
+ [0x0028]=$'\x28' # LEFT PARENTHESIS
+ [0x0029]=$'\x29' # RIGHT PARENTHESIS
+ [0x002A]=$'\x2A' # ASTERISK
+ [0x002B]=$'\x2B' # PLUS SIGN
+ [0x002C]=$'\x2C' # COMMA
+ [0x002D]=$'\x2D' # HYPHEN-MINUS
+ [0x002E]=$'\x2E' # FULL STOP
+ [0x002F]=$'\x2F' # SOLIDUS
+ [0x0030]=$'\x30' # DIGIT ZERO
+ [0x0031]=$'\x31' # DIGIT ONE
+ [0x0032]=$'\x32' # DIGIT TWO
+ [0x0033]=$'\x33' # DIGIT THREE
+ [0x0034]=$'\x34' # DIGIT FOUR
+ [0x0035]=$'\x35' # DIGIT FIVE
+ [0x0036]=$'\x36' # DIGIT SIX
+ [0x0037]=$'\x37' # DIGIT SEVEN
+ [0x0038]=$'\x38' # DIGIT EIGHT
+ [0x0039]=$'\x39' # DIGIT NINE
+ [0x003A]=$'\x3A' # COLON
+ [0x003B]=$'\x3B' # SEMICOLON
+ [0x003C]=$'\x3C' # LESS-THAN SIGN
+ [0x003D]=$'\x3D' # EQUALS SIGN
+ [0x003E]=$'\x3E' # GREATER-THAN SIGN
+ [0x003F]=$'\x3F' # QUESTION MARK
+ [0x0040]=$'\x40' # COMMERCIAL AT
+ [0x0041]=$'\x41' # LATIN CAPITAL LETTER A
+ [0x0042]=$'\x42' # LATIN CAPITAL LETTER B
+ [0x0043]=$'\x43' # LATIN CAPITAL LETTER C
+ [0x0044]=$'\x44' # LATIN CAPITAL LETTER D
+ [0x0045]=$'\x45' # LATIN CAPITAL LETTER E
+ [0x0046]=$'\x46' # LATIN CAPITAL LETTER F
+ [0x0047]=$'\x47' # LATIN CAPITAL LETTER G
+ [0x0048]=$'\x48' # LATIN CAPITAL LETTER H
+ [0x0049]=$'\x49' # LATIN CAPITAL LETTER I
+ [0x004A]=$'\x4A' # LATIN CAPITAL LETTER J
+ [0x004B]=$'\x4B' # LATIN CAPITAL LETTER K
+ [0x004C]=$'\x4C' # LATIN CAPITAL LETTER L
+ [0x004D]=$'\x4D' # LATIN CAPITAL LETTER M
+ [0x004E]=$'\x4E' # LATIN CAPITAL LETTER N
+ [0x004F]=$'\x4F' # LATIN CAPITAL LETTER O
+ [0x0050]=$'\x50' # LATIN CAPITAL LETTER P
+ [0x0051]=$'\x51' # LATIN CAPITAL LETTER Q
+ [0x0052]=$'\x52' # LATIN CAPITAL LETTER R
+ [0x0053]=$'\x53' # LATIN CAPITAL LETTER S
+ [0x0054]=$'\x54' # LATIN CAPITAL LETTER T
+ [0x0055]=$'\x55' # LATIN CAPITAL LETTER U
+ [0x0056]=$'\x56' # LATIN CAPITAL LETTER V
+ [0x0057]=$'\x57' # LATIN CAPITAL LETTER W
+ [0x0058]=$'\x58' # LATIN CAPITAL LETTER X
+ [0x0059]=$'\x59' # LATIN CAPITAL LETTER Y
+ [0x005A]=$'\x5A' # LATIN CAPITAL LETTER Z
+ [0x005B]=$'\x5B' # LEFT SQUARE BRACKET
+ [0x005C]=$'\x5C' # REVERSE SOLIDUS (YEN SIGN)
+ [0x005D]=$'\x5D' # RIGHT SQUARE BRACKET
+ [0x005E]=$'\x5E' # CIRCUMFLEX ACCENT
+ [0x005F]=$'\x5F' # LOW LINE
+ [0x0060]=$'\x60' # GRAVE ACCENT
+ [0x0061]=$'\x61' # LATIN SMALL LETTER A
+ [0x0062]=$'\x62' # LATIN SMALL LETTER B
+ [0x0063]=$'\x63' # LATIN SMALL LETTER C
+ [0x0064]=$'\x64' # LATIN SMALL LETTER D
+ [0x0065]=$'\x65' # LATIN SMALL LETTER E
+ [0x0066]=$'\x66' # LATIN SMALL LETTER F
+ [0x0067]=$'\x67' # LATIN SMALL LETTER G
+ [0x0068]=$'\x68' # LATIN SMALL LETTER H
+ [0x0069]=$'\x69' # LATIN SMALL LETTER I
+ [0x006A]=$'\x6A' # LATIN SMALL LETTER J
+ [0x006B]=$'\x6B' # LATIN SMALL LETTER K
+ [0x006C]=$'\x6C' # LATIN SMALL LETTER L
+ [0x006D]=$'\x6D' # LATIN SMALL LETTER M
+ [0x006E]=$'\x6E' # LATIN SMALL LETTER N
+ [0x006F]=$'\x6F' # LATIN SMALL LETTER O
+ [0x0070]=$'\x70' # LATIN SMALL LETTER P
+ [0x0071]=$'\x71' # LATIN SMALL LETTER Q
+ [0x0072]=$'\x72' # LATIN SMALL LETTER R
+ [0x0073]=$'\x73' # LATIN SMALL LETTER S
+ [0x0074]=$'\x74' # LATIN SMALL LETTER T
+ [0x0075]=$'\x75' # LATIN SMALL LETTER U
+ [0x0076]=$'\x76' # LATIN SMALL LETTER V
+ [0x0077]=$'\x77' # LATIN SMALL LETTER W
+ [0x0078]=$'\x78' # LATIN SMALL LETTER X
+ [0x0079]=$'\x79' # LATIN SMALL LETTER Y
+ [0x007A]=$'\x7A' # LATIN SMALL LETTER Z
+ [0x007B]=$'\x7B' # LEFT CURLY BRACKET
+ [0x007C]=$'\x7C' # VERTICAL LINE
+ [0x007D]=$'\x7D' # RIGHT CURLY BRACKET
+ [0x007E]=$'\x7E' # TILDE
+ [0x007F]=$'\x7F' # DELETE
+ [0xFF61]=$'\xA1' # HALFWIDTH IDEOGRAPHIC FULL STOP
+ [0xFF62]=$'\xA2' # HALFWIDTH LEFT CORNER BRACKET
+ [0xFF63]=$'\xA3' # HALFWIDTH RIGHT CORNER BRACKET
+ [0xFF64]=$'\xA4' # HALFWIDTH IDEOGRAPHIC COMMA
+ [0xFF65]=$'\xA5' # HALFWIDTH KATAKANA MIDDLE DOT
+ [0xFF66]=$'\xA6' # HALFWIDTH KATAKANA LETTER WO
+ [0xFF67]=$'\xA7' # HALFWIDTH KATAKANA LETTER SMALL A
+ [0xFF68]=$'\xA8' # HALFWIDTH KATAKANA LETTER SMALL I
+ [0xFF69]=$'\xA9' # HALFWIDTH KATAKANA LETTER SMALL U
+ [0xFF6A]=$'\xAA' # HALFWIDTH KATAKANA LETTER SMALL E
+ [0xFF6B]=$'\xAB' # HALFWIDTH KATAKANA LETTER SMALL O
+ [0xFF6C]=$'\xAC' # HALFWIDTH KATAKANA LETTER SMALL YA
+ [0xFF6D]=$'\xAD' # HALFWIDTH KATAKANA LETTER SMALL YU
+ [0xFF6E]=$'\xAE' # HALFWIDTH KATAKANA LETTER SMALL YO
+ [0xFF6F]=$'\xAF' # HALFWIDTH KATAKANA LETTER SMALL TU
+ [0xFF70]=$'\xB0' # HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK
+ [0xFF71]=$'\xB1' # HALFWIDTH KATAKANA LETTER A
+ [0xFF72]=$'\xB2' # HALFWIDTH KATAKANA LETTER I
+ [0xFF73]=$'\xB3' # HALFWIDTH KATAKANA LETTER U
+ [0xFF74]=$'\xB4' # HALFWIDTH KATAKANA LETTER E
+ [0xFF75]=$'\xB5' # HALFWIDTH KATAKANA LETTER O
+ [0xFF76]=$'\xB6' # HALFWIDTH KATAKANA LETTER KA
+ [0xFF77]=$'\xB7' # HALFWIDTH KATAKANA LETTER KI
+ [0xFF78]=$'\xB8' # HALFWIDTH KATAKANA LETTER KU
+ [0xFF79]=$'\xB9' # HALFWIDTH KATAKANA LETTER KE
+ [0xFF7A]=$'\xBA' # HALFWIDTH KATAKANA LETTER KO
+ [0xFF7B]=$'\xBB' # HALFWIDTH KATAKANA LETTER SA
+ [0xFF7C]=$'\xBC' # HALFWIDTH KATAKANA LETTER SI
+ [0xFF7D]=$'\xBD' # HALFWIDTH KATAKANA LETTER SU
+ [0xFF7E]=$'\xBE' # HALFWIDTH KATAKANA LETTER SE
+ [0xFF7F]=$'\xBF' # HALFWIDTH KATAKANA LETTER SO
+ [0xFF80]=$'\xC0' # HALFWIDTH KATAKANA LETTER TA
+ [0xFF81]=$'\xC1' # HALFWIDTH KATAKANA LETTER TI
+ [0xFF82]=$'\xC2' # HALFWIDTH KATAKANA LETTER TU
+ [0xFF83]=$'\xC3' # HALFWIDTH KATAKANA LETTER TE
+ [0xFF84]=$'\xC4' # HALFWIDTH KATAKANA LETTER TO
+ [0xFF85]=$'\xC5' # HALFWIDTH KATAKANA LETTER NA
+ [0xFF86]=$'\xC6' # HALFWIDTH KATAKANA LETTER NI
+ [0xFF87]=$'\xC7' # HALFWIDTH KATAKANA LETTER NU
+ [0xFF88]=$'\xC8' # HALFWIDTH KATAKANA LETTER NE
+ [0xFF89]=$'\xC9' # HALFWIDTH KATAKANA LETTER NO
+ [0xFF8A]=$'\xCA' # HALFWIDTH KATAKANA LETTER HA
+ [0xFF8B]=$'\xCB' # HALFWIDTH KATAKANA LETTER HI
+ [0xFF8C]=$'\xCC' # HALFWIDTH KATAKANA LETTER HU
+ [0xFF8D]=$'\xCD' # HALFWIDTH KATAKANA LETTER HE
+ [0xFF8E]=$'\xCE' # HALFWIDTH KATAKANA LETTER HO
+ [0xFF8F]=$'\xCF' # HALFWIDTH KATAKANA LETTER MA
+ [0xFF90]=$'\xD0' # HALFWIDTH KATAKANA LETTER MI
+ [0xFF91]=$'\xD1' # HALFWIDTH KATAKANA LETTER MU
+ [0xFF92]=$'\xD2' # HALFWIDTH KATAKANA LETTER ME
+ [0xFF93]=$'\xD3' # HALFWIDTH KATAKANA LETTER MO
+ [0xFF94]=$'\xD4' # HALFWIDTH KATAKANA LETTER YA
+ [0xFF95]=$'\xD5' # HALFWIDTH KATAKANA LETTER YU
+ [0xFF96]=$'\xD6' # HALFWIDTH KATAKANA LETTER YO
+ [0xFF97]=$'\xD7' # HALFWIDTH KATAKANA LETTER RA
+ [0xFF98]=$'\xD8' # HALFWIDTH KATAKANA LETTER RI
+ [0xFF99]=$'\xD9' # HALFWIDTH KATAKANA LETTER RU
+ [0xFF9A]=$'\xDA' # HALFWIDTH KATAKANA LETTER RE
+ [0xFF9B]=$'\xDB' # HALFWIDTH KATAKANA LETTER RO
+ [0xFF9C]=$'\xDC' # HALFWIDTH KATAKANA LETTER WA
+ [0xFF9D]=$'\xDD' # HALFWIDTH KATAKANA LETTER N
+ [0xFF9E]=$'\xDE' # HALFWIDTH KATAKANA VOICED SOUND MARK
+ [0xFF9F]=$'\xDF' # HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
+)
+
+#TestCodePage ja_JP.SHIFT_JIS jp_JP_SHIFT_JIS
+if locale -a | grep -i '^ja_JP.SJIS' >/dev/null ; then
+ TestCodePage ja_JP.SJIS jp_JP_SHIFT_JIS
+else
+ echo "unicode1.sub: warning: you do not have the ja_JP.SJIS locale installed;" >&2
+ echo "unicode1.sub: that will cause some of these tests to be skipped." >&2
+fi
+
+#for ((x=1;x<1000;x++)); do printf ' [0x%04x]=%-11q' "$x" "$(printf "$(printf '\\U%08x' $x)")" ; [ $(($x%5)) = 0 ] && echo; done
+C_UTF_8=(
+ [0x0001]=$'\001' [0x0002]=$'\002' [0x0003]=$'\003' [0x0004]=$'\004' [0x0005]=$'\005'
+ [0x0006]=$'\006' [0x0007]=$'\a' [0x0008]=$'\b' [0x0009]=$'\t' [0x000a]=''
+ [0x000b]=$'\v' [0x000c]=$'\f' [0x000d]=$'\r' [0x000e]=$'\016' [0x000f]=$'\017'
+ [0x0010]=$'\020' [0x0011]=$'\021' [0x0012]=$'\022' [0x0013]=$'\023' [0x0014]=$'\024'
+ [0x0015]=$'\025' [0x0016]=$'\026' [0x0017]=$'\027' [0x0018]=$'\030' [0x0019]=$'\031'
+ [0x001a]=$'\032' [0x001b]=$'\E' [0x001c]=$'\034' [0x001d]=$'\035' [0x001e]=$'\036'
+ [0x001f]=$'\037' [0x0020]=\ [0x0021]=\! [0x0022]=\" [0x0023]=\#
+ [0x0024]=\$ [0x0025]=% [0x0026]=\& [0x0027]=\' [0x0028]=\(
+ [0x0029]=\) [0x002a]=\* [0x002b]=+ [0x002c]=\, [0x002d]=-
+ [0x002e]=. [0x002f]=/ [0x0030]=0 [0x0031]=1 [0x0032]=2
+ [0x0033]=3 [0x0034]=4 [0x0035]=5 [0x0036]=6 [0x0037]=7
+ [0x0038]=8 [0x0039]=9 [0x003a]=: [0x003b]=\; [0x003c]=\<
+ [0x003d]== [0x003e]=\> [0x003f]=\? [0x0040]=@ [0x0041]=A
+ [0x0042]=B [0x0043]=C [0x0044]=D [0x0045]=E [0x0046]=F
+ [0x0047]=G [0x0048]=H [0x0049]=I [0x004a]=J [0x004b]=K
+ [0x004c]=L [0x004d]=M [0x004e]=N [0x004f]=O [0x0050]=P
+ [0x0051]=Q [0x0052]=R [0x0053]=S [0x0054]=T [0x0055]=U
+ [0x0056]=V [0x0057]=W [0x0058]=X [0x0059]=Y [0x005a]=Z
+ [0x005b]=\[ [0x005c]=\\ [0x005d]=\] [0x005e]=\^ [0x005f]=_
+ [0x0060]=\` [0x0061]=a [0x0062]=b [0x0063]=c [0x0064]=d
+ [0x0065]=e [0x0066]=f [0x0067]=g [0x0068]=h [0x0069]=i
+ [0x006a]=j [0x006b]=k [0x006c]=l [0x006d]=m [0x006e]=n
+ [0x006f]=o [0x0070]=p [0x0071]=q [0x0072]=r [0x0073]=s
+ [0x0074]=t [0x0075]=u [0x0076]=v [0x0077]=w [0x0078]=x
+ [0x0079]=y [0x007a]=z [0x007b]=\{ [0x007c]=\| [0x007d]=\}
+ [0x007e]="~" [0x007f]=$'\177' [0x0080]=$'\302\200' [0x0081]=$'\302\201' [0x0082]=$'\302\202'
+ [0x0083]=$'\302\203' [0x0084]=$'\302\204' [0x0085]=$'\302\205' [0x0086]=$'\302\206' [0x0087]=$'\302\207'
+ [0x0088]=$'\302\210' [0x0089]=$'\302\211' [0x008a]=$'\302\212' [0x008b]=$'\302\213' [0x008c]=$'\302\214'
+ [0x008d]=$'\302\215' [0x008e]=$'\302\216' [0x008f]=$'\302\217' [0x0090]=$'\302\220' [0x0091]=$'\302\221'
+ [0x0092]=$'\302\222' [0x0093]=$'\302\223' [0x0094]=$'\302\224' [0x0095]=$'\302\225' [0x0096]=$'\302\226'
+ [0x0097]=$'\302\227' [0x0098]=$'\302\230' [0x0099]=$'\302\231' [0x009a]=$'\302\232' [0x009b]=$'\302\233'
+ [0x009c]=$'\302\234' [0x009d]=$'\302\235' [0x009e]=$'\302\236' [0x009f]=$'\302\237' [0x00a0]=$'\302\240'
+ [0x00a1]=$'\302\241' [0x00a2]=$'\302\242' [0x00a3]=$'\302\243' [0x00a4]=$'\302\244' [0x00a5]=$'\302\245'
+ [0x00a6]=$'\302\246' [0x00a7]=$'\302\247' [0x00a8]=$'\302\250' [0x00a9]=$'\302\251' [0x00aa]=$'\302\252'
+ [0x00ab]=$'\302\253' [0x00ac]=$'\302\254' [0x00ad]=$'\302\255' [0x00ae]=$'\302\256' [0x00af]=$'\302\257'
+ [0x00b0]=$'\302\260' [0x00b1]=$'\302\261' [0x00b2]=$'\302\262' [0x00b3]=$'\302\263' [0x00b4]=$'\302\264'
+ [0x00b5]=$'\302\265' [0x00b6]=$'\302\266' [0x00b7]=$'\302\267' [0x00b8]=$'\302\270' [0x00b9]=$'\302\271'
+ [0x00ba]=$'\302\272' [0x00bb]=$'\302\273' [0x00bc]=$'\302\274' [0x00bd]=$'\302\275' [0x00be]=$'\302\276'
+ [0x00bf]=$'\302\277' [0x00c0]=$'\303\200' [0x00c1]=$'\303\201' [0x00c2]=$'\303\202' [0x00c3]=$'\303\203'
+ [0x00c4]=$'\303\204' [0x00c5]=$'\303\205' [0x00c6]=$'\303\206' [0x00c7]=$'\303\207' [0x00c8]=$'\303\210'
+ [0x00c9]=$'\303\211' [0x00ca]=$'\303\212' [0x00cb]=$'\303\213' [0x00cc]=$'\303\214' [0x00cd]=$'\303\215'
+ [0x00ce]=$'\303\216' [0x00cf]=$'\303\217' [0x00d0]=$'\303\220' [0x00d1]=$'\303\221' [0x00d2]=$'\303\222'
+ [0x00d3]=$'\303\223' [0x00d4]=$'\303\224' [0x00d5]=$'\303\225' [0x00d6]=$'\303\226' [0x00d7]=$'\303\227'
+ [0x00d8]=$'\303\230' [0x00d9]=$'\303\231' [0x00da]=$'\303\232' [0x00db]=$'\303\233' [0x00dc]=$'\303\234'
+ [0x00dd]=$'\303\235' [0x00de]=$'\303\236' [0x00df]=$'\303\237' [0x00e0]=$'\303\240' [0x00e1]=$'\303\241'
+ [0x00e2]=$'\303\242' [0x00e3]=$'\303\243' [0x00e4]=$'\303\244' [0x00e5]=$'\303\245' [0x00e6]=$'\303\246'
+ [0x00e7]=$'\303\247' [0x00e8]=$'\303\250' [0x00e9]=$'\303\251' [0x00ea]=$'\303\252' [0x00eb]=$'\303\253'
+ [0x00ec]=$'\303\254' [0x00ed]=$'\303\255' [0x00ee]=$'\303\256' [0x00ef]=$'\303\257' [0x00f0]=$'\303\260'
+ [0x00f1]=$'\303\261' [0x00f2]=$'\303\262' [0x00f3]=$'\303\263' [0x00f4]=$'\303\264' [0x00f5]=$'\303\265'
+ [0x00f6]=$'\303\266' [0x00f7]=$'\303\267' [0x00f8]=$'\303\270' [0x00f9]=$'\303\271' [0x00fa]=$'\303\272'
+ [0x00fb]=$'\303\273' [0x00fc]=$'\303\274' [0x00fd]=$'\303\275' [0x00fe]=$'\303\276' [0x00ff]=$'\303\277'
+ [0x0100]=$'\304\200' [0x0101]=$'\304\201' [0x0102]=$'\304\202' [0x0103]=$'\304\203' [0x0104]=$'\304\204'
+ [0x0105]=$'\304\205' [0x0106]=$'\304\206' [0x0107]=$'\304\207' [0x0108]=$'\304\210' [0x0109]=$'\304\211'
+ [0x010a]=$'\304\212' [0x010b]=$'\304\213' [0x010c]=$'\304\214' [0x010d]=$'\304\215' [0x010e]=$'\304\216'
+ [0x010f]=$'\304\217' [0x0110]=$'\304\220' [0x0111]=$'\304\221' [0x0112]=$'\304\222' [0x0113]=$'\304\223'
+ [0x0114]=$'\304\224' [0x0115]=$'\304\225' [0x0116]=$'\304\226' [0x0117]=$'\304\227' [0x0118]=$'\304\230'
+ [0x0119]=$'\304\231' [0x011a]=$'\304\232' [0x011b]=$'\304\233' [0x011c]=$'\304\234' [0x011d]=$'\304\235'
+ [0x011e]=$'\304\236' [0x011f]=$'\304\237' [0x0120]=$'\304\240' [0x0121]=$'\304\241' [0x0122]=$'\304\242'
+ [0x0123]=$'\304\243' [0x0124]=$'\304\244' [0x0125]=$'\304\245' [0x0126]=$'\304\246' [0x0127]=$'\304\247'
+ [0x0128]=$'\304\250' [0x0129]=$'\304\251' [0x012a]=$'\304\252' [0x012b]=$'\304\253' [0x012c]=$'\304\254'
+ [0x012d]=$'\304\255' [0x012e]=$'\304\256' [0x012f]=$'\304\257' [0x0130]=$'\304\260' [0x0131]=$'\304\261'
+ [0x0132]=$'\304\262' [0x0133]=$'\304\263' [0x0134]=$'\304\264' [0x0135]=$'\304\265' [0x0136]=$'\304\266'
+ [0x0137]=$'\304\267' [0x0138]=$'\304\270' [0x0139]=$'\304\271' [0x013a]=$'\304\272' [0x013b]=$'\304\273'
+ [0x013c]=$'\304\274' [0x013d]=$'\304\275' [0x013e]=$'\304\276' [0x013f]=$'\304\277' [0x0140]=$'\305\200'
+ [0x0141]=$'\305\201' [0x0142]=$'\305\202' [0x0143]=$'\305\203' [0x0144]=$'\305\204' [0x0145]=$'\305\205'
+ [0x0146]=$'\305\206' [0x0147]=$'\305\207' [0x0148]=$'\305\210' [0x0149]=$'\305\211' [0x014a]=$'\305\212'
+ [0x014b]=$'\305\213' [0x014c]=$'\305\214' [0x014d]=$'\305\215' [0x014e]=$'\305\216' [0x014f]=$'\305\217'
+ [0x0150]=$'\305\220' [0x0151]=$'\305\221' [0x0152]=$'\305\222' [0x0153]=$'\305\223' [0x0154]=$'\305\224'
+ [0x0155]=$'\305\225' [0x0156]=$'\305\226' [0x0157]=$'\305\227' [0x0158]=$'\305\230' [0x0159]=$'\305\231'
+ [0x015a]=$'\305\232' [0x015b]=$'\305\233' [0x015c]=$'\305\234' [0x015d]=$'\305\235' [0x015e]=$'\305\236'
+ [0x015f]=$'\305\237' [0x0160]=$'\305\240' [0x0161]=$'\305\241' [0x0162]=$'\305\242' [0x0163]=$'\305\243'
+ [0x0164]=$'\305\244' [0x0165]=$'\305\245' [0x0166]=$'\305\246' [0x0167]=$'\305\247' [0x0168]=$'\305\250'
+ [0x0169]=$'\305\251' [0x016a]=$'\305\252' [0x016b]=$'\305\253' [0x016c]=$'\305\254' [0x016d]=$'\305\255'
+ [0x016e]=$'\305\256' [0x016f]=$'\305\257' [0x0170]=$'\305\260' [0x0171]=$'\305\261' [0x0172]=$'\305\262'
+ [0x0173]=$'\305\263' [0x0174]=$'\305\264' [0x0175]=$'\305\265' [0x0176]=$'\305\266' [0x0177]=$'\305\267'
+ [0x0178]=$'\305\270' [0x0179]=$'\305\271' [0x017a]=$'\305\272' [0x017b]=$'\305\273' [0x017c]=$'\305\274'
+ [0x017d]=$'\305\275' [0x017e]=$'\305\276' [0x017f]=$'\305\277' [0x0180]=$'\306\200' [0x0181]=$'\306\201'
+ [0x0182]=$'\306\202' [0x0183]=$'\306\203' [0x0184]=$'\306\204' [0x0185]=$'\306\205' [0x0186]=$'\306\206'
+ [0x0187]=$'\306\207' [0x0188]=$'\306\210' [0x0189]=$'\306\211' [0x018a]=$'\306\212' [0x018b]=$'\306\213'
+ [0x018c]=$'\306\214' [0x018d]=$'\306\215' [0x018e]=$'\306\216' [0x018f]=$'\306\217' [0x0190]=$'\306\220'
+ [0x0191]=$'\306\221' [0x0192]=$'\306\222' [0x0193]=$'\306\223' [0x0194]=$'\306\224' [0x0195]=$'\306\225'
+ [0x0196]=$'\306\226' [0x0197]=$'\306\227' [0x0198]=$'\306\230' [0x0199]=$'\306\231' [0x019a]=$'\306\232'
+ [0x019b]=$'\306\233' [0x019c]=$'\306\234' [0x019d]=$'\306\235' [0x019e]=$'\306\236' [0x019f]=$'\306\237'
+ [0x01a0]=$'\306\240' [0x01a1]=$'\306\241' [0x01a2]=$'\306\242' [0x01a3]=$'\306\243' [0x01a4]=$'\306\244'
+ [0x01a5]=$'\306\245' [0x01a6]=$'\306\246' [0x01a7]=$'\306\247' [0x01a8]=$'\306\250' [0x01a9]=$'\306\251'
+ [0x01aa]=$'\306\252' [0x01ab]=$'\306\253' [0x01ac]=$'\306\254' [0x01ad]=$'\306\255' [0x01ae]=$'\306\256'
+ [0x01af]=$'\306\257' [0x01b0]=$'\306\260' [0x01b1]=$'\306\261' [0x01b2]=$'\306\262' [0x01b3]=$'\306\263'
+ [0x01b4]=$'\306\264' [0x01b5]=$'\306\265' [0x01b6]=$'\306\266' [0x01b7]=$'\306\267' [0x01b8]=$'\306\270'
+ [0x01b9]=$'\306\271' [0x01ba]=$'\306\272' [0x01bb]=$'\306\273' [0x01bc]=$'\306\274' [0x01bd]=$'\306\275'
+ [0x01be]=$'\306\276' [0x01bf]=$'\306\277' [0x01c0]=$'\307\200' [0x01c1]=$'\307\201' [0x01c2]=$'\307\202'
+ [0x01c3]=$'\307\203' [0x01c4]=$'\307\204' [0x01c5]=$'\307\205' [0x01c6]=$'\307\206' [0x01c7]=$'\307\207'
+ [0x01c8]=$'\307\210' [0x01c9]=$'\307\211' [0x01ca]=$'\307\212' [0x01cb]=$'\307\213' [0x01cc]=$'\307\214'
+ [0x01cd]=$'\307\215' [0x01ce]=$'\307\216' [0x01cf]=$'\307\217' [0x01d0]=$'\307\220' [0x01d1]=$'\307\221'
+ [0x01d2]=$'\307\222' [0x01d3]=$'\307\223' [0x01d4]=$'\307\224' [0x01d5]=$'\307\225' [0x01d6]=$'\307\226'
+ [0x01d7]=$'\307\227' [0x01d8]=$'\307\230' [0x01d9]=$'\307\231' [0x01da]=$'\307\232' [0x01db]=$'\307\233'
+ [0x01dc]=$'\307\234' [0x01dd]=$'\307\235' [0x01de]=$'\307\236' [0x01df]=$'\307\237' [0x01e0]=$'\307\240'
+ [0x01e1]=$'\307\241' [0x01e2]=$'\307\242' [0x01e3]=$'\307\243' [0x01e4]=$'\307\244' [0x01e5]=$'\307\245'
+ [0x01e6]=$'\307\246' [0x01e7]=$'\307\247' [0x01e8]=$'\307\250' [0x01e9]=$'\307\251' [0x01ea]=$'\307\252'
+ [0x01eb]=$'\307\253' [0x01ec]=$'\307\254' [0x01ed]=$'\307\255' [0x01ee]=$'\307\256' [0x01ef]=$'\307\257'
+ [0x01f0]=$'\307\260' [0x01f1]=$'\307\261' [0x01f2]=$'\307\262' [0x01f3]=$'\307\263' [0x01f4]=$'\307\264'
+ [0x01f5]=$'\307\265' [0x01f6]=$'\307\266' [0x01f7]=$'\307\267' [0x01f8]=$'\307\270' [0x01f9]=$'\307\271'
+ [0x01fa]=$'\307\272' [0x01fb]=$'\307\273' [0x01fc]=$'\307\274' [0x01fd]=$'\307\275' [0x01fe]=$'\307\276'
+ [0x01ff]=$'\307\277' [0x0200]=$'\310\200' [0x0201]=$'\310\201' [0x0202]=$'\310\202' [0x0203]=$'\310\203'
+ [0x0204]=$'\310\204' [0x0205]=$'\310\205' [0x0206]=$'\310\206' [0x0207]=$'\310\207' [0x0208]=$'\310\210'
+ [0x0209]=$'\310\211' [0x020a]=$'\310\212' [0x020b]=$'\310\213' [0x020c]=$'\310\214' [0x020d]=$'\310\215'
+ [0x020e]=$'\310\216' [0x020f]=$'\310\217' [0x0210]=$'\310\220' [0x0211]=$'\310\221' [0x0212]=$'\310\222'
+ [0x0213]=$'\310\223' [0x0214]=$'\310\224' [0x0215]=$'\310\225' [0x0216]=$'\310\226' [0x0217]=$'\310\227'
+ [0x0218]=$'\310\230' [0x0219]=$'\310\231' [0x021a]=$'\310\232' [0x021b]=$'\310\233' [0x021c]=$'\310\234'
+ [0x021d]=$'\310\235' [0x021e]=$'\310\236' [0x021f]=$'\310\237' [0x0220]=$'\310\240' [0x0221]=$'\310\241'
+ [0x0222]=$'\310\242' [0x0223]=$'\310\243' [0x0224]=$'\310\244' [0x0225]=$'\310\245' [0x0226]=$'\310\246'
+ [0x0227]=$'\310\247' [0x0228]=$'\310\250' [0x0229]=$'\310\251' [0x022a]=$'\310\252' [0x022b]=$'\310\253'
+ [0x022c]=$'\310\254' [0x022d]=$'\310\255' [0x022e]=$'\310\256' [0x022f]=$'\310\257' [0x0230]=$'\310\260'
+ [0x0231]=$'\310\261' [0x0232]=$'\310\262' [0x0233]=$'\310\263' [0x0234]=$'\310\264' [0x0235]=$'\310\265'
+ [0x0236]=$'\310\266' [0x0237]=$'\310\267' [0x0238]=$'\310\270' [0x0239]=$'\310\271' [0x023a]=$'\310\272'
+ [0x023b]=$'\310\273' [0x023c]=$'\310\274' [0x023d]=$'\310\275' [0x023e]=$'\310\276' [0x023f]=$'\310\277'
+ [0x0240]=$'\311\200' [0x0241]=$'\311\201' [0x0242]=$'\311\202' [0x0243]=$'\311\203' [0x0244]=$'\311\204'
+ [0x0245]=$'\311\205' [0x0246]=$'\311\206' [0x0247]=$'\311\207' [0x0248]=$'\311\210' [0x0249]=$'\311\211'
+ [0x024a]=$'\311\212' [0x024b]=$'\311\213' [0x024c]=$'\311\214' [0x024d]=$'\311\215' [0x024e]=$'\311\216'
+ [0x024f]=$'\311\217' [0x0250]=$'\311\220' [0x0251]=$'\311\221' [0x0252]=$'\311\222' [0x0253]=$'\311\223'
+ [0x0254]=$'\311\224' [0x0255]=$'\311\225' [0x0256]=$'\311\226' [0x0257]=$'\311\227' [0x0258]=$'\311\230'
+ [0x0259]=$'\311\231' [0x025a]=$'\311\232' [0x025b]=$'\311\233' [0x025c]=$'\311\234' [0x025d]=$'\311\235'
+ [0x025e]=$'\311\236' [0x025f]=$'\311\237' [0x0260]=$'\311\240' [0x0261]=$'\311\241' [0x0262]=$'\311\242'
+ [0x0263]=$'\311\243' [0x0264]=$'\311\244' [0x0265]=$'\311\245' [0x0266]=$'\311\246' [0x0267]=$'\311\247'
+ [0x0268]=$'\311\250' [0x0269]=$'\311\251' [0x026a]=$'\311\252' [0x026b]=$'\311\253' [0x026c]=$'\311\254'
+ [0x026d]=$'\311\255' [0x026e]=$'\311\256' [0x026f]=$'\311\257' [0x0270]=$'\311\260' [0x0271]=$'\311\261'
+ [0x0272]=$'\311\262' [0x0273]=$'\311\263' [0x0274]=$'\311\264' [0x0275]=$'\311\265' [0x0276]=$'\311\266'
+ [0x0277]=$'\311\267' [0x0278]=$'\311\270' [0x0279]=$'\311\271' [0x027a]=$'\311\272' [0x027b]=$'\311\273'
+ [0x027c]=$'\311\274' [0x027d]=$'\311\275' [0x027e]=$'\311\276' [0x027f]=$'\311\277' [0x0280]=$'\312\200'
+ [0x0281]=$'\312\201' [0x0282]=$'\312\202' [0x0283]=$'\312\203' [0x0284]=$'\312\204' [0x0285]=$'\312\205'
+ [0x0286]=$'\312\206' [0x0287]=$'\312\207' [0x0288]=$'\312\210' [0x0289]=$'\312\211' [0x028a]=$'\312\212'
+ [0x028b]=$'\312\213' [0x028c]=$'\312\214' [0x028d]=$'\312\215' [0x028e]=$'\312\216' [0x028f]=$'\312\217'
+ [0x0290]=$'\312\220' [0x0291]=$'\312\221' [0x0292]=$'\312\222' [0x0293]=$'\312\223' [0x0294]=$'\312\224'
+ [0x0295]=$'\312\225' [0x0296]=$'\312\226' [0x0297]=$'\312\227' [0x0298]=$'\312\230' [0x0299]=$'\312\231'
+ [0x029a]=$'\312\232' [0x029b]=$'\312\233' [0x029c]=$'\312\234' [0x029d]=$'\312\235' [0x029e]=$'\312\236'
+ [0x029f]=$'\312\237' [0x02a0]=$'\312\240' [0x02a1]=$'\312\241' [0x02a2]=$'\312\242' [0x02a3]=$'\312\243'
+ [0x02a4]=$'\312\244' [0x02a5]=$'\312\245' [0x02a6]=$'\312\246' [0x02a7]=$'\312\247' [0x02a8]=$'\312\250'
+ [0x02a9]=$'\312\251' [0x02aa]=$'\312\252' [0x02ab]=$'\312\253' [0x02ac]=$'\312\254' [0x02ad]=$'\312\255'
+ [0x02ae]=$'\312\256' [0x02af]=$'\312\257' [0x02b0]=$'\312\260' [0x02b1]=$'\312\261' [0x02b2]=$'\312\262'
+ [0x02b3]=$'\312\263' [0x02b4]=$'\312\264' [0x02b5]=$'\312\265' [0x02b6]=$'\312\266' [0x02b7]=$'\312\267'
+ [0x02b8]=$'\312\270' [0x02b9]=$'\312\271' [0x02ba]=$'\312\272' [0x02bb]=$'\312\273' [0x02bc]=$'\312\274'
+ [0x02bd]=$'\312\275' [0x02be]=$'\312\276' [0x02bf]=$'\312\277' [0x02c0]=$'\313\200' [0x02c1]=$'\313\201'
+ [0x02c2]=$'\313\202' [0x02c3]=$'\313\203' [0x02c4]=$'\313\204' [0x02c5]=$'\313\205' [0x02c6]=$'\313\206'
+ [0x02c7]=$'\313\207' [0x02c8]=$'\313\210' [0x02c9]=$'\313\211' [0x02ca]=$'\313\212' [0x02cb]=$'\313\213'
+ [0x02cc]=$'\313\214' [0x02cd]=$'\313\215' [0x02ce]=$'\313\216' [0x02cf]=$'\313\217' [0x02d0]=$'\313\220'
+ [0x02d1]=$'\313\221' [0x02d2]=$'\313\222' [0x02d3]=$'\313\223' [0x02d4]=$'\313\224' [0x02d5]=$'\313\225'
+ [0x02d6]=$'\313\226' [0x02d7]=$'\313\227' [0x02d8]=$'\313\230' [0x02d9]=$'\313\231' [0x02da]=$'\313\232'
+ [0x02db]=$'\313\233' [0x02dc]=$'\313\234' [0x02dd]=$'\313\235' [0x02de]=$'\313\236' [0x02df]=$'\313\237'
+ [0x02e0]=$'\313\240' [0x02e1]=$'\313\241' [0x02e2]=$'\313\242' [0x02e3]=$'\313\243' [0x02e4]=$'\313\244'
+ [0x02e5]=$'\313\245' [0x02e6]=$'\313\246' [0x02e7]=$'\313\247' [0x02e8]=$'\313\250' [0x02e9]=$'\313\251'
+ [0x02ea]=$'\313\252' [0x02eb]=$'\313\253' [0x02ec]=$'\313\254' [0x02ed]=$'\313\255' [0x02ee]=$'\313\256'
+ [0x02ef]=$'\313\257' [0x02f0]=$'\313\260' [0x02f1]=$'\313\261' [0x02f2]=$'\313\262' [0x02f3]=$'\313\263'
+ [0x02f4]=$'\313\264' [0x02f5]=$'\313\265' [0x02f6]=$'\313\266' [0x02f7]=$'\313\267' [0x02f8]=$'\313\270'
+ [0x02f9]=$'\313\271' [0x02fa]=$'\313\272' [0x02fb]=$'\313\273' [0x02fc]=$'\313\274' [0x02fd]=$'\313\275'
+ [0x02fe]=$'\313\276' [0x02ff]=$'\313\277' [0x0300]=$'\314\200' [0x0301]=$'\314\201' [0x0302]=$'\314\202'
+ [0x0303]=$'\314\203' [0x0304]=$'\314\204' [0x0305]=$'\314\205' [0x0306]=$'\314\206' [0x0307]=$'\314\207'
+ [0x0308]=$'\314\210' [0x0309]=$'\314\211' [0x030a]=$'\314\212' [0x030b]=$'\314\213' [0x030c]=$'\314\214'
+ [0x030d]=$'\314\215' [0x030e]=$'\314\216' [0x030f]=$'\314\217' [0x0310]=$'\314\220' [0x0311]=$'\314\221'
+ [0x0312]=$'\314\222' [0x0313]=$'\314\223' [0x0314]=$'\314\224' [0x0315]=$'\314\225' [0x0316]=$'\314\226'
+ [0x0317]=$'\314\227' [0x0318]=$'\314\230' [0x0319]=$'\314\231' [0x031a]=$'\314\232' [0x031b]=$'\314\233'
+ [0x031c]=$'\314\234' [0x031d]=$'\314\235' [0x031e]=$'\314\236' [0x031f]=$'\314\237' [0x0320]=$'\314\240'
+ [0x0321]=$'\314\241' [0x0322]=$'\314\242' [0x0323]=$'\314\243' [0x0324]=$'\314\244' [0x0325]=$'\314\245'
+ [0x0326]=$'\314\246' [0x0327]=$'\314\247' [0x0328]=$'\314\250' [0x0329]=$'\314\251' [0x032a]=$'\314\252'
+ [0x032b]=$'\314\253' [0x032c]=$'\314\254' [0x032d]=$'\314\255' [0x032e]=$'\314\256' [0x032f]=$'\314\257'
+ [0x0330]=$'\314\260' [0x0331]=$'\314\261' [0x0332]=$'\314\262' [0x0333]=$'\314\263' [0x0334]=$'\314\264'
+ [0x0335]=$'\314\265' [0x0336]=$'\314\266' [0x0337]=$'\314\267' [0x0338]=$'\314\270' [0x0339]=$'\314\271'
+ [0x033a]=$'\314\272' [0x033b]=$'\314\273' [0x033c]=$'\314\274' [0x033d]=$'\314\275' [0x033e]=$'\314\276'
+ [0x033f]=$'\314\277' [0x0340]=$'\315\200' [0x0341]=$'\315\201' [0x0342]=$'\315\202' [0x0343]=$'\315\203'
+ [0x0344]=$'\315\204' [0x0345]=$'\315\205' [0x0346]=$'\315\206' [0x0347]=$'\315\207' [0x0348]=$'\315\210'
+ [0x0349]=$'\315\211' [0x034a]=$'\315\212' [0x034b]=$'\315\213' [0x034c]=$'\315\214' [0x034d]=$'\315\215'
+ [0x034e]=$'\315\216' [0x034f]=$'\315\217' [0x0350]=$'\315\220' [0x0351]=$'\315\221' [0x0352]=$'\315\222'
+ [0x0353]=$'\315\223' [0x0354]=$'\315\224' [0x0355]=$'\315\225' [0x0356]=$'\315\226' [0x0357]=$'\315\227'
+ [0x0358]=$'\315\230' [0x0359]=$'\315\231' [0x035a]=$'\315\232' [0x035b]=$'\315\233' [0x035c]=$'\315\234'
+ [0x035d]=$'\315\235' [0x035e]=$'\315\236' [0x035f]=$'\315\237' [0x0360]=$'\315\240' [0x0361]=$'\315\241'
+ [0x0362]=$'\315\242' [0x0363]=$'\315\243' [0x0364]=$'\315\244' [0x0365]=$'\315\245' [0x0366]=$'\315\246'
+ [0x0367]=$'\315\247' [0x0368]=$'\315\250' [0x0369]=$'\315\251' [0x036a]=$'\315\252' [0x036b]=$'\315\253'
+ [0x036c]=$'\315\254' [0x036d]=$'\315\255' [0x036e]=$'\315\256' [0x036f]=$'\315\257' [0x0370]=$'\315\260'
+ [0x0371]=$'\315\261' [0x0372]=$'\315\262' [0x0373]=$'\315\263' [0x0374]=$'\315\264' [0x0375]=$'\315\265'
+ [0x0376]=$'\315\266' [0x0377]=$'\315\267' [0x0378]=$'\315\270' [0x0379]=$'\315\271' [0x037a]=$'\315\272'
+ [0x037b]=$'\315\273' [0x037c]=$'\315\274' [0x037d]=$'\315\275' [0x037e]=$'\315\276' [0x037f]=$'\315\277'
+ [0x0380]=$'\316\200' [0x0381]=$'\316\201' [0x0382]=$'\316\202' [0x0383]=$'\316\203' [0x0384]=$'\316\204'
+ [0x0385]=$'\316\205' [0x0386]=$'\316\206' [0x0387]=$'\316\207' [0x0388]=$'\316\210' [0x0389]=$'\316\211'
+ [0x038a]=$'\316\212' [0x038b]=$'\316\213' [0x038c]=$'\316\214' [0x038d]=$'\316\215' [0x038e]=$'\316\216'
+ [0x038f]=$'\316\217' [0x0390]=$'\316\220' [0x0391]=$'\316\221' [0x0392]=$'\316\222' [0x0393]=$'\316\223'
+ [0x0394]=$'\316\224' [0x0395]=$'\316\225' [0x0396]=$'\316\226' [0x0397]=$'\316\227' [0x0398]=$'\316\230'
+ [0x0399]=$'\316\231' [0x039a]=$'\316\232' [0x039b]=$'\316\233' [0x039c]=$'\316\234' [0x039d]=$'\316\235'
+ [0x039e]=$'\316\236' [0x039f]=$'\316\237' [0x03a0]=$'\316\240' [0x03a1]=$'\316\241' [0x03a2]=$'\316\242'
+ [0x03a3]=$'\316\243' [0x03a4]=$'\316\244' [0x03a5]=$'\316\245' [0x03a6]=$'\316\246' [0x03a7]=$'\316\247'
+ [0x03a8]=$'\316\250' [0x03a9]=$'\316\251' [0x03aa]=$'\316\252' [0x03ab]=$'\316\253' [0x03ac]=$'\316\254'
+ [0x03ad]=$'\316\255' [0x03ae]=$'\316\256' [0x03af]=$'\316\257' [0x03b0]=$'\316\260' [0x03b1]=$'\316\261'
+ [0x03b2]=$'\316\262' [0x03b3]=$'\316\263' [0x03b4]=$'\316\264' [0x03b5]=$'\316\265' [0x03b6]=$'\316\266'
+ [0x03b7]=$'\316\267' [0x03b8]=$'\316\270' [0x03b9]=$'\316\271' [0x03ba]=$'\316\272' [0x03bb]=$'\316\273'
+ [0x03bc]=$'\316\274' [0x03bd]=$'\316\275' [0x03be]=$'\316\276' [0x03bf]=$'\316\277' [0x03c0]=$'\317\200'
+ [0x03c1]=$'\317\201' [0x03c2]=$'\317\202' [0x03c3]=$'\317\203' [0x03c4]=$'\317\204' [0x03c5]=$'\317\205'
+ [0x03c6]=$'\317\206' [0x03c7]=$'\317\207' [0x03c8]=$'\317\210' [0x03c9]=$'\317\211' [0x03ca]=$'\317\212'
+ [0x03cb]=$'\317\213' [0x03cc]=$'\317\214' [0x03cd]=$'\317\215' [0x03ce]=$'\317\216' [0x03cf]=$'\317\217'
+ [0x03d0]=$'\317\220' [0x03d1]=$'\317\221' [0x03d2]=$'\317\222' [0x03d3]=$'\317\223' [0x03d4]=$'\317\224'
+ [0x03d5]=$'\317\225' [0x03d6]=$'\317\226' [0x03d7]=$'\317\227' [0x03d8]=$'\317\230' [0x03d9]=$'\317\231'
+ [0x03da]=$'\317\232' [0x03db]=$'\317\233' [0x03dc]=$'\317\234' [0x03dd]=$'\317\235' [0x03de]=$'\317\236'
+ [0x03df]=$'\317\237' [0x03e0]=$'\317\240' [0x03e1]=$'\317\241' [0x03e2]=$'\317\242' [0x03e3]=$'\317\243'
+ [0x03e4]=$'\317\244' [0x03e5]=$'\317\245' [0x03e6]=$'\317\246' [0x03e7]=$'\317\247'
+
+
+ [0x1000]=$'\341\200\200' [0x1001]=$'\341\200\201' [0x1002]=$'\341\200\202' [0x1003]=$'\341\200\203' [0x1004]=$'\341\200\204'
+ [0x1005]=$'\341\200\205' [0x1006]=$'\341\200\206' [0x1007]=$'\341\200\207' [0x1008]=$'\341\200\210' [0x1009]=$'\341\200\211'
+ [0x100a]=$'\341\200\212' [0x100b]=$'\341\200\213' [0x100c]=$'\341\200\214' [0x100d]=$'\341\200\215' [0x100e]=$'\341\200\216'
+ [0x100f]=$'\341\200\217' [0x1010]=$'\341\200\220' [0x1011]=$'\341\200\221' [0x1012]=$'\341\200\222' [0x1013]=$'\341\200\223'
+ [0x1014]=$'\341\200\224' [0x1015]=$'\341\200\225' [0x1016]=$'\341\200\226' [0x1017]=$'\341\200\227' [0x1018]=$'\341\200\230'
+ [0x1019]=$'\341\200\231' [0x101a]=$'\341\200\232' [0x101b]=$'\341\200\233' [0x101c]=$'\341\200\234' [0x101d]=$'\341\200\235'
+ [0x101e]=$'\341\200\236' [0x101f]=$'\341\200\237' [0x1020]=$'\341\200\240' [0x1021]=$'\341\200\241' [0x1022]=$'\341\200\242'
+ [0x1023]=$'\341\200\243' [0x1024]=$'\341\200\244' [0x1025]=$'\341\200\245' [0x1026]=$'\341\200\246' [0x1027]=$'\341\200\247'
+ [0x1028]=$'\341\200\250' [0x1029]=$'\341\200\251' [0x102a]=$'\341\200\252' [0x102b]=$'\341\200\253' [0x102c]=$'\341\200\254'
+ [0x102d]=$'\341\200\255' [0x102e]=$'\341\200\256' [0x102f]=$'\341\200\257' [0x1030]=$'\341\200\260' [0x1031]=$'\341\200\261'
+ [0x1032]=$'\341\200\262' [0x1033]=$'\341\200\263' [0x1034]=$'\341\200\264' [0x1035]=$'\341\200\265' [0x1036]=$'\341\200\266'
+ [0x1037]=$'\341\200\267' [0x1038]=$'\341\200\270' [0x1039]=$'\341\200\271' [0x103a]=$'\341\200\272' [0x103b]=$'\341\200\273'
+ [0x103c]=$'\341\200\274' [0x103d]=$'\341\200\275' [0x103e]=$'\341\200\276' [0x103f]=$'\341\200\277' [0x1040]=$'\341\201\200'
+ [0x1041]=$'\341\201\201' [0x1042]=$'\341\201\202' [0x1043]=$'\341\201\203' [0x1044]=$'\341\201\204' [0x1045]=$'\341\201\205'
+ [0x1046]=$'\341\201\206' [0x1047]=$'\341\201\207' [0x1048]=$'\341\201\210' [0x1049]=$'\341\201\211' [0x104a]=$'\341\201\212'
+ [0x104b]=$'\341\201\213' [0x104c]=$'\341\201\214' [0x104d]=$'\341\201\215' [0x104e]=$'\341\201\216' [0x104f]=$'\341\201\217'
+
+ [0x10000]=$'\360\220\200\200' [0x10001]=$'\360\220\200\201' [0x10002]=$'\360\220\200\202' [0x10003]=$'\360\220\200\203' [0x10004]=$'\360\220\200\204'
+ [0x10005]=$'\360\220\200\205' [0x10006]=$'\360\220\200\206' [0x10007]=$'\360\220\200\207' [0x10008]=$'\360\220\200\210' [0x10009]=$'\360\220\200\211'
+ [0x1000a]=$'\360\220\200\212' [0x1000b]=$'\360\220\200\213' [0x1000c]=$'\360\220\200\214' [0x1000d]=$'\360\220\200\215' [0x1000e]=$'\360\220\200\216'
+ [0x1000f]=$'\360\220\200\217' [0x10010]=$'\360\220\200\220' [0x10011]=$'\360\220\200\221' [0x10012]=$'\360\220\200\222' [0x10013]=$'\360\220\200\223'
+ [0x10014]=$'\360\220\200\224' [0x10015]=$'\360\220\200\225' [0x10016]=$'\360\220\200\226' [0x10017]=$'\360\220\200\227' [0x10018]=$'\360\220\200\230'
+ [0x10019]=$'\360\220\200\231' [0x1001a]=$'\360\220\200\232' [0x1001b]=$'\360\220\200\233' [0x1001c]=$'\360\220\200\234' [0x1001d]=$'\360\220\200\235'
+ [0x1001e]=$'\360\220\200\236' [0x1001f]=$'\360\220\200\237' [0x10020]=$'\360\220\200\240' [0x10021]=$'\360\220\200\241' [0x10022]=$'\360\220\200\242'
+ [0x10023]=$'\360\220\200\243' [0x10024]=$'\360\220\200\244' [0x10025]=$'\360\220\200\245' [0x10026]=$'\360\220\200\246' [0x10027]=$'\360\220\200\247'
+ [0x10028]=$'\360\220\200\250' [0x10029]=$'\360\220\200\251' [0x1002a]=$'\360\220\200\252' [0x1002b]=$'\360\220\200\253' [0x1002c]=$'\360\220\200\254'
+ [0x1002d]=$'\360\220\200\255' [0x1002e]=$'\360\220\200\256' [0x1002f]=$'\360\220\200\257' [0x10030]=$'\360\220\200\260' [0x10031]=$'\360\220\200\261'
+ [0x10032]=$'\360\220\200\262' [0x10033]=$'\360\220\200\263' [0x10034]=$'\360\220\200\264' [0x10035]=$'\360\220\200\265' [0x10036]=$'\360\220\200\266'
+ [0x10037]=$'\360\220\200\267' [0x10038]=$'\360\220\200\270' [0x10039]=$'\360\220\200\271' [0x1003a]=$'\360\220\200\272' [0x1003b]=$'\360\220\200\273'
+ [0x1003c]=$'\360\220\200\274' [0x1003d]=$'\360\220\200\275' [0x1003e]=$'\360\220\200\276' [0x1003f]=$'\360\220\200\277' [0x10040]=$'\360\220\201\200'
+ [0x10041]=$'\360\220\201\201' [0x10042]=$'\360\220\201\202' [0x10043]=$'\360\220\201\203' [0x10044]=$'\360\220\201\204' [0x10045]=$'\360\220\201\205'
+ [0x10046]=$'\360\220\201\206' [0x10047]=$'\360\220\201\207' [0x10048]=$'\360\220\201\210' [0x10049]=$'\360\220\201\211' [0x1004a]=$'\360\220\201\212'
+ [0x1004b]=$'\360\220\201\213' [0x1004c]=$'\360\220\201\214' [0x1004d]=$'\360\220\201\215' [0x1004e]=$'\360\220\201\216' [0x1004f]=$'\360\220\201\217'
+
+ [0x1000000]=$'\371\200\200\200\200' [0x1000001]=$'\371\200\200\200\201' [0x1000002]=$'\371\200\200\200\202' [0x1000003]=$'\371\200\200\200\203' [0x1000004]=$'\371\200\200\200\204'
+ [0x1000005]=$'\371\200\200\200\205' [0x1000006]=$'\371\200\200\200\206' [0x1000007]=$'\371\200\200\200\207' [0x1000008]=$'\371\200\200\200\210' [0x1000009]=$'\371\200\200\200\211'
+ [0x100000a]=$'\371\200\200\200\212' [0x100000b]=$'\371\200\200\200\213' [0x100000c]=$'\371\200\200\200\214' [0x100000d]=$'\371\200\200\200\215' [0x100000e]=$'\371\200\200\200\216'
+ [0x100000f]=$'\371\200\200\200\217' [0x1000010]=$'\371\200\200\200\220' [0x1000011]=$'\371\200\200\200\221' [0x1000012]=$'\371\200\200\200\222' [0x1000013]=$'\371\200\200\200\223'
+ [0x1000014]=$'\371\200\200\200\224' [0x1000015]=$'\371\200\200\200\225' [0x1000016]=$'\371\200\200\200\226' [0x1000017]=$'\371\200\200\200\227' [0x1000018]=$'\371\200\200\200\230'
+ [0x1000019]=$'\371\200\200\200\231' [0x100001a]=$'\371\200\200\200\232' [0x100001b]=$'\371\200\200\200\233' [0x100001c]=$'\371\200\200\200\234' [0x100001d]=$'\371\200\200\200\235'
+ [0x100001e]=$'\371\200\200\200\236' [0x100001f]=$'\371\200\200\200\237' [0x1000020]=$'\371\200\200\200\240' [0x1000021]=$'\371\200\200\200\241' [0x1000022]=$'\371\200\200\200\242'
+ [0x1000023]=$'\371\200\200\200\243' [0x1000024]=$'\371\200\200\200\244' [0x1000025]=$'\371\200\200\200\245' [0x1000026]=$'\371\200\200\200\246' [0x1000027]=$'\371\200\200\200\247'
+ [0x1000028]=$'\371\200\200\200\250' [0x1000029]=$'\371\200\200\200\251' [0x100002a]=$'\371\200\200\200\252' [0x100002b]=$'\371\200\200\200\253' [0x100002c]=$'\371\200\200\200\254'
+ [0x100002d]=$'\371\200\200\200\255' [0x100002e]=$'\371\200\200\200\256' [0x100002f]=$'\371\200\200\200\257' [0x1000030]=$'\371\200\200\200\260' [0x1000031]=$'\371\200\200\200\261'
+ [0x1000032]=$'\371\200\200\200\262' [0x1000033]=$'\371\200\200\200\263' [0x1000034]=$'\371\200\200\200\264' [0x1000035]=$'\371\200\200\200\265' [0x1000036]=$'\371\200\200\200\266'
+ [0x1000037]=$'\371\200\200\200\267' [0x1000038]=$'\371\200\200\200\270' [0x1000039]=$'\371\200\200\200\271' [0x100003a]=$'\371\200\200\200\272' [0x100003b]=$'\371\200\200\200\273'
+ [0x100003c]=$'\371\200\200\200\274' [0x100003d]=$'\371\200\200\200\275' [0x100003e]=$'\371\200\200\200\276' [0x100003f]=$'\371\200\200\200\277' [0x1000040]=$'\371\200\200\201\200'
+ [0x1000041]=$'\371\200\200\201\201' [0x1000042]=$'\371\200\200\201\202' [0x1000043]=$'\371\200\200\201\203' [0x1000044]=$'\371\200\200\201\204' [0x1000045]=$'\371\200\200\201\205'
+ [0x1000046]=$'\371\200\200\201\206' [0x1000047]=$'\371\200\200\201\207' [0x1000048]=$'\371\200\200\201\210' [0x1000049]=$'\371\200\200\201\211' [0x100004a]=$'\371\200\200\201\212'
+ [0x100004b]=$'\371\200\200\201\213' [0x100004c]=$'\371\200\200\201\214' [0x100004d]=$'\371\200\200\201\215' [0x100004e]=$'\371\200\200\201\216' [0x100004f]=$'\371\200\200\201\217'
+
+ [0x70000000]=$'\375\260\200\200\200\200' [0x70000001]=$'\375\260\200\200\200\201' [0x70000002]=$'\375\260\200\200\200\202' [0x70000003]=$'\375\260\200\200\200\203'
+ [0x70000004]=$'\375\260\200\200\200\204' [0x70000005]=$'\375\260\200\200\200\205' [0x70000006]=$'\375\260\200\200\200\206' [0x70000007]=$'\375\260\200\200\200\207' [0x70000008]=$'\375\260\200\200\200\210'
+ [0x70000009]=$'\375\260\200\200\200\211' [0x7000000a]=$'\375\260\200\200\200\212' [0x7000000b]=$'\375\260\200\200\200\213' [0x7000000c]=$'\375\260\200\200\200\214' [0x7000000d]=$'\375\260\200\200\200\215'
+ [0x7000000e]=$'\375\260\200\200\200\216' [0x7000000f]=$'\375\260\200\200\200\217' [0x70000010]=$'\375\260\200\200\200\220' [0x70000011]=$'\375\260\200\200\200\221' [0x70000012]=$'\375\260\200\200\200\222'
+ [0x70000013]=$'\375\260\200\200\200\223' [0x70000014]=$'\375\260\200\200\200\224' [0x70000015]=$'\375\260\200\200\200\225' [0x70000016]=$'\375\260\200\200\200\226' [0x70000017]=$'\375\260\200\200\200\227'
+ [0x70000018]=$'\375\260\200\200\200\230' [0x70000019]=$'\375\260\200\200\200\231' [0x7000001a]=$'\375\260\200\200\200\232' [0x7000001b]=$'\375\260\200\200\200\233' [0x7000001c]=$'\375\260\200\200\200\234'
+ [0x7000001d]=$'\375\260\200\200\200\235' [0x7000001e]=$'\375\260\200\200\200\236' [0x7000001f]=$'\375\260\200\200\200\237' [0x70000020]=$'\375\260\200\200\200\240' [0x70000021]=$'\375\260\200\200\200\241'
+ [0x70000022]=$'\375\260\200\200\200\242' [0x70000023]=$'\375\260\200\200\200\243' [0x70000024]=$'\375\260\200\200\200\244' [0x70000025]=$'\375\260\200\200\200\245' [0x70000026]=$'\375\260\200\200\200\246'
+ [0x70000027]=$'\375\260\200\200\200\247' [0x70000028]=$'\375\260\200\200\200\250' [0x70000029]=$'\375\260\200\200\200\251' [0x7000002a]=$'\375\260\200\200\200\252' [0x7000002b]=$'\375\260\200\200\200\253'
+ [0x7000002c]=$'\375\260\200\200\200\254' [0x7000002d]=$'\375\260\200\200\200\255' [0x7000002e]=$'\375\260\200\200\200\256' [0x7000002f]=$'\375\260\200\200\200\257' [0x70000030]=$'\375\260\200\200\200\260'
+ [0x70000031]=$'\375\260\200\200\200\261' [0x70000032]=$'\375\260\200\200\200\262' [0x70000033]=$'\375\260\200\200\200\263' [0x70000034]=$'\375\260\200\200\200\264' [0x70000035]=$'\375\260\200\200\200\265'
+ [0x70000036]=$'\375\260\200\200\200\266' [0x70000037]=$'\375\260\200\200\200\267' [0x70000038]=$'\375\260\200\200\200\270' [0x70000039]=$'\375\260\200\200\200\271' [0x7000003a]=$'\375\260\200\200\200\272'
+ [0x7000003b]=$'\375\260\200\200\200\273' [0x7000003c]=$'\375\260\200\200\200\274' [0x7000003d]=$'\375\260\200\200\200\275' [0x7000003e]=$'\375\260\200\200\200\276' [0x7000003f]=$'\375\260\200\200\200\277'
+ [0x70000040]=$'\375\260\200\200\201\200' [0x70000041]=$'\375\260\200\200\201\201' [0x70000042]=$'\375\260\200\200\201\202' [0x70000043]=$'\375\260\200\200\201\203' [0x70000044]=$'\375\260\200\200\201\204'
+ [0x70000045]=$'\375\260\200\200\201\205' [0x70000046]=$'\375\260\200\200\201\206' [0x70000047]=$'\375\260\200\200\201\207' [0x70000048]=$'\375\260\200\200\201\210' [0x70000049]=$'\375\260\200\200\201\211'
+ [0x7000004a]=$'\375\260\200\200\201\212' [0x7000004b]=$'\375\260\200\200\201\213' [0x7000004c]=$'\375\260\200\200\201\214' [0x7000004d]=$'\375\260\200\200\201\215' [0x7000004e]=$'\375\260\200\200\201\216'
+
+
+
+ )
+TestCodePage en_US.UTF-8 C_UTF_8
+
+if [ ${ErrorCnt} -gt 0 ]; then
+ echo "Failed ${ErrorCnt} of ${TestCnt} Unicode tests"
+else
+ echo "Passed all ${TestCnt} Unicode tests"
+fi
diff --git a/tests/unicode2.sub b/tests/unicode2.sub
new file mode 100644
index 0000000..16dd604
--- /dev/null
+++ b/tests/unicode2.sub
@@ -0,0 +1,37 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+. ./test-glue-functions
+
+export LANG=en_US.UTF-8
+
+printf '%s\n' "$(printf '\uff')" | od -b | _intl_normalize_spaces
+printf '%s\n' $'\uff' | od -b | _intl_normalize_spaces
+
+printf '\uff'\\n | od -b | _intl_normalize_spaces
+echo $'\uff' | od -b | _intl_normalize_spaces
+
+printf '\uffff'\\n | od -b | _intl_normalize_spaces
+echo $'\uffff' | od -b | _intl_normalize_spaces
+
+printf '\Ufffffffe'\\n | od -b | _intl_normalize_spaces
+echo $'\Ufffffffe' | od -b | _intl_normalize_spaces
+
+printf '\Uffffffff'\\n | od -b | _intl_normalize_spaces
+echo $'\Uffffffff' | od -b | _intl_normalize_spaces
+
+LC_CTYPE=C printf '\uff'\\n | od -b | _intl_normalize_spaces
+LC_CTYPE=ru_RU.CP1251 printf '\uff'\\n | od -b | _intl_normalize_spaces
+LC_CTYPE=en_US.UTF-8 printf '\uff'\\n | od -b | _intl_normalize_spaces
+
+echo -e '\u0041 \u00a3 \u0152' | od -b | _intl_normalize_spaces
diff --git a/tests/unicode3.sub b/tests/unicode3.sub
new file mode 100644
index 0000000..cb1b873
--- /dev/null
+++ b/tests/unicode3.sub
@@ -0,0 +1,12 @@
+export LANG=en_US.UTF-8 # make sure
+
+cd $TMPDIR # try to avoid NFS artifacts
+payload=$'\065\247\100\063\231\053\306\123\070\237\242\352\263'
+"$payload"
+
+cd "$payload"
+printf %q "$payload"
+echo
+
+set -x ; : "$payload" ; set +x
+cd $OLDPWD
diff --git a/tests/varenv.right b/tests/varenv.right
new file mode 100644
index 0000000..f6bd1b5
--- /dev/null
+++ b/tests/varenv.right
@@ -0,0 +1,277 @@
+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:.
+declare -a avar=([0]="/bin:/usr/bin:/usr/local/bin:.")
+declare -- 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:b:c:d
+a-b-c-d
+a:b:c:d
+g: ,
+f: ,
+FIN: asdf fdsa, asdf fdsa
+g: v = , w =
+f: v = , w =
+FIN: v = two, w = one
+./varenv4.sub: line 67: bbb: unique: cannot convert indexed to associative array
+./varenv4.sub: line 67: declare: unique: cannot convert indexed to associative array
+after bbb: 1
+declare -Ar FOOBAR=([foo]="bar" )
+declare -Ar FOOBAR=([foo]="bar" )
+declare -ar FOOBAR2=([0]="bar")
+declare -ar FOOBAR2=([0]="bar")
+F OUTSIDE
+F OUTSIDE
+declare -ar outside=()
+declare -ir outside1="1"
+tempenv = foo
+0
+declare -ar myvar=([0]="0")
+1
+declare -ir myvar="1"
+declare -rx tempvar1='foo'
+declare -rx tempvar2='qux'
+./varenv7.sub: line 57: local: var: readonly variable
+inside: outside
+outside: outside
+local: unset1 unset2
+abc
+abc
+:1
+:2
+after: ----
+global:1
+global:2
+after: --global--
+after: ----
+x = :1:2
+in o1 (readonly modifying local scalars):
+declare -r i1="a b c"
+declare -r j1="1 2 3"
+after o1:
+./varenv9.sub: line 28: declare: i1: not found
+./varenv9.sub: line 28: declare: j1: not found
+in o2 (readonly setting global scalars):
+declare -r i2="a b c"
+declare -r j2="1 2 3"
+after o2:
+declare -r i2="a b c"
+declare -r j2="1 2 3"
+./varenv9.sub: line 46: unset: i2: cannot unset: readonly variable
+./varenv9.sub: line 46: unset: j2: cannot unset: readonly variable
+in o3 (readonly modifying locals, converting to arrays):
+declare -ar i3=([0]="a" [1]="b" [2]="c")
+declare -ar j3=([0]="1" [1]="2" [2]="3")
+after o3:
+./varenv9.sub: line 61: declare: i3: not found
+./varenv9.sub: line 61: declare: j3: not found
+in o4 (readonly setting global array variables):
+declare -ar i4=([0]="a" [1]="b" [2]="c")
+declare -ar j4=([0]="1" [1]="2" [2]="3")
+after o4:
+declare -ar i4=([0]="a" [1]="b" [2]="c")
+declare -ar j4=([0]="1" [1]="2" [2]="3")
+./varenv9.sub: line 79: unset: i4: cannot unset: readonly variable
+./varenv9.sub: line 79: unset: j4: cannot unset: readonly variable
+main: unset
+inner: res unset
+outer: res: X Y
+main: after first call: X
+inner: X
+outer: res: X Y
+main: after second call: X
+func: null or unset
+after func: x = outside
+./varenv11.sub: line 17: local: qux: readonly variable
+./varenv11.sub: line 18: qux: readonly variable
+./varenv11.sub: line 18: local: qux: readonly variable
+declare -A foo=([zero]="zero" [one]="one" )
+declare -a bar=([0]="zero" [1]="one")
+declare -A foo=([one]="one" [zero]="zero" )
+declare -a bar=([0]="zero" [1]="one")
+./varenv11.sub: line 42: a: readonly variable
+foo=abc
+func1: var =
+
+func1: var =
+
+inside: declare -- foo
+outside:
+declare -x foo="abc"
+inside: declare -x var="value"
+outside: declare -- var="one"
+inside: declare -x var="value"
+outside: declare -- var="outside"
+inside: declare -x var="inside"
+outside: declare -- var="outside"
+outside 1.0: var=one
+outside 1.1: var=one
+inside func: var=two
+outside 2.0: var=<unset>
+inside func: var=two
+outside 2.1: var=global
+inside func1: var=value
+outside 3.0: var=value
+inside func2: var=global
+outside 4.0: var=outside
+foo: hello world
+after foo: var=global
+bar: hello world
+after bar: var=global
+./varenv13.sub: line 16: `var[0]': not a valid identifier
+./varenv13.sub: line 16: `var[@]': not a valid identifier
+./varenv13.sub: line 14: declare: var: not found
+declare -A var=([0]="X" ["@"]="Y" )
+help
+./varenv13.sub: line 35: `var[0]': not a valid identifier
+1
+declare -A var=([0]="X" )
+declare -A var=([Y]="Y" )
+declare -A var=([Y]="Y" )
+declare -A var=()
+declare -A var=()
+./varenv14.sub: line 31: f: var: cannot convert indexed to associative array
+./varenv14.sub: line 31: declare: var: cannot convert indexed to associative array
+declare -a var=([0]="12")
+declare -a a=([0]="X")
+declare -a s=([0]="X")
+declare -a a=([0]="X" [1]="Y")
+declare -a s=([0]="X" [1]="Y")
+declare -a a=([0]="XY")
+declare -a s=([0]="XY")
+f: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
+f1: after: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
+done: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100
+f3:1
+f3:2
+f3:3
+f3:4
+f3:5
+f3:6
+f3:7
+f3:8
+f3:9
+f3:10
+f3:11
+f3:12
+f3:13
+f3:14
+f3:15
+f3:16
+f3:17
+f3:18
+f3:19
+f3:20
+before source: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
+varenv15.in: before set: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
+varenv15.in: after set: 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
+after source 1: 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
+varenv15.in: before set: one two three four five six seven eight nine ten
+varenv15.in: after set: 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
+after source 2: 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
+foo=showfoo environment foo=showfoo
+foo=showfoo environment foo=showfoo
+foo=showfoo environment foo=showfoo
+outside: foo=<unset>
+
+posix mode
+foo=showfoo environment foo=showfoo
+outside 1.0: foo=<unset>
+foo=showfoo environment foo=showfoo
+foo=showfoo environment foo=showfoo
+outside 1.1: foo=<unset>
+foo=<unset> environment foo=
+outside 2.0: foo=<unset>
+foo=foo environment foo=foo
+foo=<unset> environment foo=
+outside 2.1: foo=<unset>
+declare -- var="global"
+declare -- var
+declare -- var="local"
+declare -- var="global"
+declare -- var="local"
+declare -- var
+declare -- var="local"
+declare -- var
+declare -- var="local"
+declare -- var
+declare -- var="local"
+declare -- var="f1"
+declare -- var="local"
+declare -a arr=([0]="zero" [1]="one" [2]="two" [3]="three" [4]="four" [5]="five")
+declare -a arr=([0]="zero" [1]="one" [2]="two")
+declare -a arr=([0]="three" [1]="four" [2]="five")
+declare -a arr=([0]="zero" [1]="one" [2]="two")
+ddd 0
+aaa 1 2 3
+bbb 4 5 6
+ccc 7 8 9
+declare -a x=([0]="one" [1]="two" [2]="three")
+./varenv19.sub: line 51: declare: x: not found
+declare -x v="x"
+declare -x v="t"
+declare -- v
+declare -x v
+ignoreeof on
+ignoreeof off
+ignoreeof on
+10
+match 1
+trap -- 'echo trap:$FUNCNAME' EXIT
+trap:f
+trap -- 'echo trap:$FUNCNAME' EXIT
+trap:f
+trap -- 'echo trap:$FUNCNAME' EXIT
+trap:f
+trap -- 'echo trap:$FUNCNAME' EXIT
+trap:f
+a=z
+a=b
+a=z
diff --git a/tests/varenv.tests b/tests/varenv.tests
new file mode 100644
index 0000000..68c619e
--- /dev/null
+++ b/tests/varenv.tests
@@ -0,0 +1,265 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# 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
+
+# more tests; bugs in bash IFS scoping up through version 4.2
+$THIS_SH ./varenv3.sub
+
+# scoping problems with declare -g through bash-4.2
+${THIS_SH} ./varenv4.sub
+
+# more scoping and declaration problems with -g and arrays through bash-4.2
+${THIS_SH} ./varenv5.sub
+
+# variable scoping in the presence of nameref
+${THIS_SH} ./varenv6.sub
+
+# variable declaration problems with arrays and readonly local variables
+${THIS_SH} ./varenv7.sub
+
+# variable visibility problems with process substitution subshells in
+# redirections
+${THIS_SH} ./varenv8.sub
+
+# make sure that builtins like readonly and export modify local array variables
+# if executed in shell functions, like they modify local scalar variables
+${THIS_SH} ./varenv9.sub
+
+# more tests of unset and local variables with dynamic scoping
+${THIS_SH} ./varenv10.sub
+
+# tests of compound assignments in function scope
+${THIS_SH} ./varenv11.sub
+
+# temporary environment variable propagation and scoping in posix mode
+${THIS_SH} ./varenv12.sub
+
+# temporary environment and invalid shell identifier names
+${THIS_SH} ./varenv13.sub
+
+# localvar_inherit
+${THIS_SH} ./varenv14.sub
+${THIS_SH} ./varenv15.sub
+${THIS_SH} ./varenv16.sub
+${THIS_SH} ./varenv17.sub
+${THIS_SH} ./varenv18.sub
+${THIS_SH} ./varenv19.sub
+${THIS_SH} ./varenv20.sub
+${THIS_SH} ./varenv21.sub
+${THIS_SH} ./varenv22.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..8def153
--- /dev/null
+++ b/tests/varenv1.sub
@@ -0,0 +1,41 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# 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/varenv10.sub b/tests/varenv10.sub
new file mode 100644
index 0000000..aa0175a
--- /dev/null
+++ b/tests/varenv10.sub
@@ -0,0 +1,59 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+#
+# various tests of unset when applied to variables at different local scopes
+#
+# function unsetting variable at previous local scope, uncovering global
+
+inner()
+{
+ unset res
+ echo ${FUNCNAME}: ${res-res unset}
+ if [[ $1 == "set" ]]; then
+ res[0]="X"
+ res[1]="Y"
+ fi
+}
+
+outer()
+{
+ local res=
+ inner "$1"
+ echo ${FUNCNAME}: "res: ${res[@]}"
+}
+
+echo main: ${res-unset}
+outer set
+echo main: after first call: ${res-unset}
+outer dontset
+echo main: after second call: ${res-unset}
+
+unset -f outer inner
+unset res
+
+# local scope, unset variable at the same scope as local declaration
+func()
+{
+ typeset x=4
+
+ unset x
+ echo ${FUNCNAME}: ${x:-null or unset}
+}
+
+x=outside
+func
+echo after func: x = $x
+
+unset -f func
+unset x
diff --git a/tests/varenv11.sub b/tests/varenv11.sub
new file mode 100644
index 0000000..638aa2c
--- /dev/null
+++ b/tests/varenv11.sub
@@ -0,0 +1,43 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# couple of errors here
+func()
+{
+ local qux=7
+ local qux=(one two)
+ local what=(zero one two)
+}
+
+readonly qux=42
+func
+
+func2()
+{
+ declare -gA foo=([zero]=zero [one]=one)
+ declare -ga bar=(zero one)
+}
+
+foo=help
+bar=me
+
+func2
+
+declare -p foo bar
+unset foo bar
+func2
+declare -p foo bar
+
+readonly a=7
+a=(1 2 3)
+
diff --git a/tests/varenv12.sub b/tests/varenv12.sub
new file mode 100644
index 0000000..92b3692
--- /dev/null
+++ b/tests/varenv12.sub
@@ -0,0 +1,171 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+set -o posix
+
+fn() { foo=abc : ; typeset +x foo; printenv|grep ^foo=; }
+
+fn
+unset -v foo
+unset -f fn
+
+func1() {
+ var=1
+ var=2 : # or 'var=2 return', or another special builtin
+ unset -v var
+ echo $FUNCNAME: var = $var
+}
+func2() {
+ func1
+ unset -v var # bug: fails silently
+}
+func1
+echo ${var+"BUG: still set 1"}
+
+unset var
+func2
+echo ${var+"BUG: still set 2"}
+
+unset -v var
+unset -f func1 func2
+
+fn() { foo=abc : ; typeset +x foo; echo -n 'inside: ' ; declare -p foo; }
+fn
+echo outside:
+declare -p foo
+
+unset -v foo
+unset -f fn
+
+func()
+{
+ var=value declare -x var
+ echo -n 'inside: ' ; declare -p var
+}
+
+var=one
+func
+echo -n 'outside: ' ; declare -p var
+
+unset -v var
+unset -f func
+
+# this will probably change behavior; export shouldn't behave like this when
+# not in posix mode and the sequencing is probably wrong in posix mode. since
+# export is a special builtin, the variable assignment should modify the
+# local variable, as if a standalone assignment statement had been executed
+# (posix modifying "the current execution environment") leaving the global
+# variable unchanged. all shells, including bash, modify the local variable;
+# bash was the only one that propagates the value out to the calling
+# environment, but no longer does so.
+
+func()
+{
+ local var=inside
+ var=value export var
+ echo -n 'inside: ' ; declare -p var
+}
+
+var=outside
+func
+echo -n 'outside: ' ; declare -p var
+
+unset -v var
+unset -f func
+
+func()
+{
+ local var=local
+ var=inside :
+ echo -n 'inside: ' ; declare -p var
+}
+
+var=outside
+func
+echo -n 'outside: ' ; declare -p var
+
+unset -v var
+unset -f func
+
+func()
+{
+ echo -n 'inside func: ' ; echo "var=${var-<unset>}"
+}
+
+unset -v var
+var=one :
+echo -n 'outside 1.0: ' ; echo "var=${var-<unset>}"
+
+unset -v var
+var=one eval ':'
+echo -n 'outside 1.1: ' ; echo "var=${var-<unset>}"
+
+unset -v var
+
+var=two func
+echo -n 'outside 2.0: ' ; echo "var=${var-<unset>}"
+var=global
+var=two func
+echo -n 'outside 2.1: ' ; echo "var=${var-<unset>}"
+
+unset -v var
+unset -f func
+
+func1()
+{
+ var=value export var
+ echo -n 'inside func1: ' ; echo "var=${var-<unset>}"
+}
+
+var=outside
+func1
+echo -n 'outside 3.0: ' ; echo "var=${var-<unset>}"
+
+unset -v var
+unset -f func1
+
+func2()
+{
+ local var=local
+ var=global :
+ echo -n 'inside func2: ' ; echo "var=${var-<unset>}"
+}
+
+var=outside
+func2
+echo -n 'outside 4.0: ' ; echo "var=${var-<unset>}"
+
+unset -v var
+unset -f fecho foo bar
+
+fecho() {
+ echo $var
+}
+
+foo() {
+ local var="foo: bye bye"
+ var="foo: hello world" fecho
+}
+
+bar() {
+ var="bar: hello world" fecho
+}
+
+var=global
+var=outside foo
+echo after foo: var=$var
+var=global
+var=outside bar
+echo after bar: var=$var
+
+unset -v var
diff --git a/tests/varenv13.sub b/tests/varenv13.sub
new file mode 100644
index 0000000..1fa7d5b
--- /dev/null
+++ b/tests/varenv13.sub
@@ -0,0 +1,37 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+f() { declare -p ${!var*} | grep ^var; declare -p var ; }
+
+var[0]=X var[@]=Y f
+
+unset -f f
+unset -v var
+
+typeset -A var
+
+f() { declare -p ${!var*}; }
+
+# this is no longer an error
+var[0]=X var[@]=Y
+f
+
+: ${THIS_SH:=./bash}
+env 'v[0]=help' ${THIS_SH} -c 'printenv "v[0]"'
+
+unset -v var
+
+f() { test -v 'var[0]'; echo $?; }
+var[0]=X f
+
+unset -v var
diff --git a/tests/varenv14.sub b/tests/varenv14.sub
new file mode 100644
index 0000000..091c470
--- /dev/null
+++ b/tests/varenv14.sub
@@ -0,0 +1,46 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# testing framework for local variable inheritance
+
+shopt -s localvar_inherit
+declare -A var
+
+f() { declare var+=([0]=X); declare -p var; }
+f
+
+f() { declare var=([Y]=Y); declare -p var; }; f
+f() { declare var+=([Y]=Y); declare -p var; }; f
+f() { declare var+=(); declare -p var; }; f
+f() { declare var=(); declare -p var; }; f
+
+unset -f f
+unset -v var
+
+declare -a var=( [0]=12 )
+f() { declare -A var+=([0]=X); declare -p var; }
+f
+
+unset -f f
+unset a s
+
+a=(X) s=X
+
+f() { local -a a s; declare -p a s; }
+f
+
+f() { local a+=(Y) s+=(Y); declare -p a s; }
+f
+
+f() { local -a a+=Y s+=Y; declare -p a s; }
+f
diff --git a/tests/varenv15.in b/tests/varenv15.in
new file mode 100644
index 0000000..e635b12
--- /dev/null
+++ b/tests/varenv15.in
@@ -0,0 +1,3 @@
+echo varenv15.in: before set: "$@"
+set -- 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
+echo varenv15.in: after set: "$@"
diff --git a/tests/varenv15.sub b/tests/varenv15.sub
new file mode 100644
index 0000000..4c9ef0e
--- /dev/null
+++ b/tests/varenv15.sub
@@ -0,0 +1,51 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# check saving and restoring positional parameters around function calls
+
+f()
+{
+ echo $FUNCNAME: "$@"
+}
+
+f1()
+{
+ f {1..50}
+ echo $FUNCNAME: after: $@
+}
+
+set -- {1..100}
+
+f1 {1..20}
+echo done: $@
+
+f3()
+{
+ echo $FUNCNAME:$1
+ shift
+ if [ $# -le 0 ]; then
+ return
+ fi
+ f3 "$@"
+}
+
+f3 {1..20}
+
+# now let's try source with and without positional parameters
+
+set -- {1..20}
+echo before source: "$@"
+. ./varenv15.in
+echo after source 1: "$@"
+. ./varenv15.in one two three four five six seven eight nine ten
+echo after source 2: "$@"
diff --git a/tests/varenv16.sub b/tests/varenv16.sub
new file mode 100644
index 0000000..847926c
--- /dev/null
+++ b/tests/varenv16.sub
@@ -0,0 +1,51 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test whether or not temporary environment assignments are exported
+# in posix mode. works now, posix says it will not work in the future
+
+show2()
+{
+ printf %s "foo=${foo-<unset>}"
+ echo -n ' environment foo='
+ printenv foo || echo
+}
+
+showfoo()
+{
+ local foo
+
+ foo=showfoo show2
+}
+
+unset foo
+showfoo
+foo=foo showfoo
+showfoo
+echo outside: "foo=${foo-<unset>}"
+
+echo ; echo 'posix mode'
+set -o posix
+unset foo
+showfoo
+echo outside 1.0: "foo=${foo-<unset>}"
+foo=foo showfoo
+showfoo
+echo outside 1.1: "foo=${foo-<unset>}"
+
+unset foo
+show2
+echo outside 2.0: "foo=${foo-<unset>}"
+foo=foo show2
+show2
+echo outside 2.1: "foo=${foo-<unset>}"
diff --git a/tests/varenv17.sub b/tests/varenv17.sub
new file mode 100644
index 0000000..1f9278c
--- /dev/null
+++ b/tests/varenv17.sub
@@ -0,0 +1,44 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# testing -I and local variable inheritance
+var=global
+
+f()
+{
+ local $1 var
+ declare -p var
+
+ var=local
+ declare -p var
+}
+
+declare -I var
+declare -p var
+
+f
+f -I
+unset var
+f
+f -I
+
+f1()
+{
+ var=$FUNCNAME
+
+ f
+ f -I
+}
+
+f1
diff --git a/tests/varenv18.sub b/tests/varenv18.sub
new file mode 100644
index 0000000..4ad7f1a
--- /dev/null
+++ b/tests/varenv18.sub
@@ -0,0 +1,41 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+arr=(zero one two)
+four=four
+
+f()
+{
+ local -a arr=( "${arr[@]}" )
+ arr+=(three four five)
+ declare -p arr
+}
+f
+declare -p arr
+
+f1()
+{
+ local -a arr=(three $four five)
+ declare -p arr
+}
+f1
+
+set -u
+name='arr[@]'
+f2()
+{
+ local -a arr=("${!name}")
+ declare -p arr
+}
+f2
diff --git a/tests/varenv19.sub b/tests/varenv19.sub
new file mode 100644
index 0000000..753f508
--- /dev/null
+++ b/tests/varenv19.sub
@@ -0,0 +1,51 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# variable attribute inheritance problems without specifying -a or -A
+
+function aaa() {
+ local x='1 2 3'
+ echo "aaa ${x}"
+}
+
+function bbb {
+ local x
+ x=(4 5 6)
+ echo "bbb ${x[*]}"
+}
+
+ccc()
+{
+ local x=(7 8 9)
+ echo "ccc ${x[*]}"
+}
+
+function ddd
+{
+ local -r x='0'
+ echo "ddd ${x}"
+ aaa
+ bbb
+ ccc
+}
+
+ddd
+
+f()
+{
+ local x=(one two three)
+ declare -p x
+}
+f
+declare -p x
diff --git a/tests/varenv2.sub b/tests/varenv2.sub
new file mode 100644
index 0000000..0fde5b2
--- /dev/null
+++ b/tests/varenv2.sub
@@ -0,0 +1,57 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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/varenv20.sub b/tests/varenv20.sub
new file mode 100644
index 0000000..5fba8c4
--- /dev/null
+++ b/tests/varenv20.sub
@@ -0,0 +1,13 @@
+# tests of local variables with the same name as variables passed in the
+# temporary environment
+
+f() { local v=x; local -p; }
+v=t f
+
+f() { local v; declare -p v; }
+v=t f
+
+f() { local v=x; unset v; declare -p v; }
+v=g
+f
+v=t f
diff --git a/tests/varenv21.sub b/tests/varenv21.sub
new file mode 100644
index 0000000..613e475
--- /dev/null
+++ b/tests/varenv21.sub
@@ -0,0 +1,48 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# test behavior of `local -' inside shell functions
+
+IGNOREEOF=0
+shopt -o ignoreeof
+
+f()
+{
+ local -
+ set +o ignoreeof
+ shopt -o ignoreeof
+}
+
+f
+shopt -o ignoreeof
+echo $IGNOREEOF
+
+unset -f f
+
+f()
+{
+ local -
+ set -m -H +B
+ set -u
+}
+
+before="$-|$SHELLOPTS"
+f
+after="$-|$SHELLOPTS"
+
+case "$after" in
+$before) echo match 1 ;;
+*) echo bad 1 ;;
+esac
+
+unset -f f
diff --git a/tests/varenv22.sub b/tests/varenv22.sub
new file mode 100644
index 0000000..6d42bb5
--- /dev/null
+++ b/tests/varenv22.sub
@@ -0,0 +1,17 @@
+# test behavior of FUNCNAME in and out of parse_and_execute scenarios
+
+# in parse_and_execute
+${THIS_SH} -c 'trap "echo trap:\$FUNCNAME" EXIT ; trap ; f() { exit; } ; f' bash
+
+${THIS_SH} << \EOF
+eval "trap 'echo trap:\$FUNCNAME' EXIT ; trap; f() { exit; } ; f"
+EOF
+
+# not in parse_and_execute
+${THIS_SH} << \EOF
+trap 'echo trap:$FUNCNAME' EXIT ; trap; f() { exit; } ; f
+EOF
+
+# this has to be last
+trap 'echo trap:$FUNCNAME' EXIT ; trap; f() { exit; } ; f
+
diff --git a/tests/varenv3.sub b/tests/varenv3.sub
new file mode 100644
index 0000000..854e483
--- /dev/null
+++ b/tests/varenv3.sub
@@ -0,0 +1,44 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+oifs=$IFS
+
+inner () {
+#recho inner: "$IFS" >&2
+ echo a/b/c/d
+ exit 0
+}
+
+outer() {
+#recho outer: "$IFS" >&2
+for i in 1; do
+ IFS=/ read m v k a < <(IFS=$oifs inner)
+
+echo $m:$v:$k:$a
+done
+}
+
+outer
+unset m k v a b c d
+
+for j in 1; do
+ IFS=: read a b c d
+done < <(outer)
+
+echo $a-$b-$c-$d
+unset m k v a b c d
+
+IFS=: read a b c d < <(outer)
+
+echo $a:$b:$c:$d
diff --git a/tests/varenv4.sub b/tests/varenv4.sub
new file mode 100644
index 0000000..9735b61
--- /dev/null
+++ b/tests/varenv4.sub
@@ -0,0 +1,71 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+f()
+{
+ local -a v
+ local -a w
+
+ g
+ echo "f: ${v[@]}, ${w[@]}"
+}
+
+g()
+{
+ aux=v
+ declare -ga "$aux=( asdf fdsa )"
+ declare -ga w=( asdf fdsa )
+
+ echo "g: ${v[@]}, ${w[@]}"
+}
+
+f
+echo "FIN: ${v[@]}, ${w[@]}"
+
+unset v w
+unset -f f g
+
+f()
+{
+ local v
+ local w
+
+ g
+ echo f: v = $v, w = $w
+}
+
+g()
+{
+ aux=v
+ declare -g w=one
+ declare -g "$aux=two"
+
+ echo g: v = $v, w = $w
+}
+
+f
+echo FIN: v = $v, w = $w
+
+# problem with error return propagation through bash-4.3
+unset -f aaa bbb
+unset unique
+
+aaa() {
+ declare -g -a unique=()
+}
+bbb() {
+ declare -g -A unique=()
+}
+aaa
+bbb
+echo after bbb: $?
diff --git a/tests/varenv5.sub b/tests/varenv5.sub
new file mode 100644
index 0000000..b6eb70c
--- /dev/null
+++ b/tests/varenv5.sub
@@ -0,0 +1,29 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+function foobar {
+ declare -rgA FOOBAR=([foo]=bar)
+ declare -p FOOBAR
+}
+foobar
+declare -p FOOBAR
+
+unset -f foobar
+
+foobar() {
+ declare -rga FOOBAR2=([foo]=bar)
+ declare -p FOOBAR2
+}
+
+foobar
+declare -p FOOBAR2
diff --git a/tests/varenv6.sub b/tests/varenv6.sub
new file mode 100644
index 0000000..8cf21f7
--- /dev/null
+++ b/tests/varenv6.sub
@@ -0,0 +1,41 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+f()
+{
+ local str=F
+ g str
+}
+
+g()
+{
+ local -n ref=$1
+ printf "%s " "$ref"
+ ref=G
+}
+
+str=OUTSIDE;
+f
+
+printf "%s\n" "$str"
+
+unset -f f g
+unset str
+
+f() { local -a arr=(F); g arr; };
+
+g() { local -n ref=$1; printf "%s " "${ref[0]}"; ref=(G); };
+
+arr=(OUTSIDE);
+f;
+printf "%s\n" "${arr[0]}"
diff --git a/tests/varenv7.sub b/tests/varenv7.sub
new file mode 100644
index 0000000..4b25960
--- /dev/null
+++ b/tests/varenv7.sub
@@ -0,0 +1,75 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+foo()
+{
+ local -a myvar=()
+ local -r myvar=0
+
+ echo "${myvar[@]}"
+ declare -p myvar
+}
+
+foo2()
+{
+ local -i myvar=0
+ local -r myvar=1
+
+ echo "${myvar}"
+ declare -p myvar
+}
+
+declare -a outside=()
+declare -r outside
+declare -p outside
+
+outside1=1
+declare -ir outside1
+declare -p outside1
+
+tempenv=foo declare -r tempenv
+echo tempenv = $tempenv
+
+foo
+foo2
+
+tempvar1=foo declare -r tempvar1
+echo ${tempvar1@A}
+
+tempvar2=bar declare -r tempvar2=qux
+echo ${tempvar2@A}
+
+unset foo
+readonly var=outside
+
+func()
+{
+ local var=inside
+ echo "inside: $var"
+}
+
+func
+echo outside: $var
+
+unset -f f
+unset VAR1 VAR2
+export VAR1=abc VAR2=abc
+
+f()
+{
+ local VAR1; local VAR2
+ echo local: ${VAR1-unset1} ${VAR2-unset2}
+ printenv VAR1 ; printenv VAR2
+}
+
+f
diff --git a/tests/varenv8.sub b/tests/varenv8.sub
new file mode 100644
index 0000000..cad2c6e
--- /dev/null
+++ b/tests/varenv8.sub
@@ -0,0 +1,14 @@
+FOO=bar cat < <(echo $FOO:1; echo $FOO:2)
+echo after: --${FOO}--
+
+unset FOO
+FOO=global
+
+FOO=bar cat < <(echo $FOO:1; echo $FOO:2)
+echo after: --${FOO}--
+
+unset FOO
+FOO=bar read x < <(echo -n $FOO:1; echo $FOO:2)
+echo after: --${FOO}--
+echo x = $x
+
diff --git a/tests/varenv9.sub b/tests/varenv9.sub
new file mode 100644
index 0000000..5837aa5
--- /dev/null
+++ b/tests/varenv9.sub
@@ -0,0 +1,79 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# case 1: readonly modifying local scalar variables
+o1() {
+ local i1 j1
+ readonly i1=$1
+ readonly j1="1 2 3"
+
+ echo "in o1 (readonly modifying local scalars):"
+ declare -p i1
+ declare -p j1
+}
+
+o1 "a b c"
+
+echo after o1:
+declare -p i1 j1
+
+unset i1 j1
+
+# case 2: readonly setting global scalar variables
+o2() {
+ readonly i2=$1
+ readonly j2="1 2 3"
+
+ echo "in o2 (readonly setting global scalars):"
+ declare -p i2
+ declare -p j2
+}
+
+o2 "a b c"
+echo after o2:
+declare -p i2 j2
+
+unset i2 j2
+
+# case 3: readonly modifying local variables, converting to arrays
+o3() {
+ local i3 j3
+ readonly i3=($1)
+ readonly j3=(1 2 3)
+
+ echo "in o3 (readonly modifying locals, converting to arrays):"
+ declare -p i3
+ declare -p j3
+}
+
+o3 "a b c"
+echo after o3:
+declare -p i3 j3
+
+unset i3 j3
+
+# case 4: readonly setting global array variables
+o4() {
+ readonly i4=($1)
+ readonly j4=(1 2 3)
+
+ echo "in o4 (readonly setting global array variables):"
+ declare -p i4
+ declare -p j4
+}
+
+o4 "a b c"
+echo after o4:
+declare -p i4 j4
+
+unset i4 j4
diff --git a/tests/version b/tests/version
new file mode 100644
index 0000000..9ad08f7
--- /dev/null
+++ b/tests/version
@@ -0,0 +1,13 @@
+if (( $UID == 0 )); then
+ echo "${THIS_SH}: the test suite should not be run as root" >&2
+ echo
+fi
+
+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..637565e
--- /dev/null
+++ b/tests/version.mini
@@ -0,0 +1,13 @@
+if (( $UID == 0 )); then
+ echo "${THIS_SH}: the test suite should not be run as root" >&2
+ echo
+fi
+
+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..6465595
--- /dev/null
+++ b/tests/vredir.right
@@ -0,0 +1,101 @@
+10
+foo 1
+foo 2
+foo 3
+bar is a function
+bar ()
+{
+ exec {v}> $TMPFILE;
+ echo $v
+}
+./vredir.tests: line 19: v: readonly variable
+./vredir.tests: line 19: v: cannot assign fd to variable
+42
+bar is a function
+bar ()
+{
+ exec {v}> $TMPFILE;
+ echo $v
+}
+10
+line 1
+line 2
+line 3
+bar is a function
+bar ()
+{
+ exec {v}<<EOF
+line 1
+line 2
+line 3
+EOF
+
+ echo $v
+}
+10
+foo 1
+foo 2
+foo 3
+10
+/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
+10 11
+a
+a
+swizzle is a function
+swizzle ()
+{
+ fd0=0;
+ fd1=1;
+ exec {stdin}<&$fd0;
+ exec {stdout}>&$fd1
+}
+12 10
+a
+a
+swizzle is a function
+swizzle ()
+{
+ exec {fd0}<&0;
+ exec {fd1}>&1;
+ exec {stdin}<&$fd0-;
+ exec {stdout}>&$fd1-
+}
+ok 1
+./vredir6.sub: redirection error: cannot duplicate fd: Invalid argument
+./vredir6.sub: line 13: /dev/null: Invalid argument
+unset
+12 10
+a
+a
+swizzle is a function
+swizzle ()
+{
+ exec {fd[0]}<&0;
+ exec {fd[1]}>&1;
+ exec {stdin}<&${fd[0]}-;
+ exec {stdout}>&${fd[1]}-
+}
+./vredir8.sub: line 12: $fd: Bad file descriptor
diff --git a/tests/vredir.tests b/tests/vredir.tests
new file mode 100644
index 0000000..bd4cb77
--- /dev/null
+++ b/tests/vredir.tests
@@ -0,0 +1,62 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: ${TMPDIR:=/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 2>&1 >&$v | { grep -q '\$v: Bad' || echo 'bad foo 1'; }
+echo foo 2 2>&1 >&$v | { grep -q '\$v: Bad' || echo 'bad foo 2'; }
+echo foo 3 2>&1 >&$v | { grep -q '\$v: Bad' || echo 'bad foo 3'; }
+
+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
+
+${THIS_SH} ./vredir6.sub
+
+${THIS_SH} ./vredir7.sub
+${THIS_SH} ./vredir8.sub
+
+exit 0
diff --git a/tests/vredir1.sub b/tests/vredir1.sub
new file mode 100644
index 0000000..484f313
--- /dev/null
+++ b/tests/vredir1.sub
@@ -0,0 +1,30 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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..4f9e7bb
--- /dev/null
+++ b/tests/vredir2.sub
@@ -0,0 +1,65 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+: ${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..f861bcf
--- /dev/null
+++ b/tests/vredir4.sub
@@ -0,0 +1,35 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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..beb45ac
--- /dev/null
+++ b/tests/vredir5.sub
@@ -0,0 +1,36 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+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
diff --git a/tests/vredir6.sub b/tests/vredir6.sub
new file mode 100644
index 0000000..224b96a
--- /dev/null
+++ b/tests/vredir6.sub
@@ -0,0 +1,14 @@
+unset v
+exec {v}</dev/null
+
+if (( v >= 10 )); then echo ok 1; else echo bad 1; fi
+
+exec {v}<&-
+
+ulimit -n 6
+
+exec </dev/null
+
+unset v
+exec {v}</dev/null
+echo ${v-unset}
diff --git a/tests/vredir7.sub b/tests/vredir7.sub
new file mode 100644
index 0000000..0f76f40
--- /dev/null
+++ b/tests/vredir7.sub
@@ -0,0 +1,36 @@
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+swizzle()
+{
+exec {fd[0]}<&0
+exec {fd[1]}>&1
+
+exec {stdin}<&${fd[0]}-
+exec {stdout}>&${fd[1]}-
+}
+
+swizzle
+
+echo $stdin $stdout
+
+read line <&$stdin <<EOF
+a
+EOF
+
+echo $line
+echo $line >&$stdout
+
+type swizzle
+
+exit 0
diff --git a/tests/vredir8.sub b/tests/vredir8.sub
new file mode 100644
index 0000000..e87b45b
--- /dev/null
+++ b/tests/vredir8.sub
@@ -0,0 +1,13 @@
+# test varredir_close
+
+: {fd}<>/dev/null
+
+echo redir 1 >&$fd
+exec {fd}>&-
+
+shopt -s varredir_close
+
+: {fd}<>/dev/tty
+
+echo redir 2 >&$fd
+exec {fd}>&-