OSDN Git Service

Upgrade to mksh R55.
[android-x86/external-mksh.git] / src / check.t
index 9c86afd..93c614f 100644 (file)
@@ -1,9 +1,9 @@
-# $MirOS: src/bin/mksh/check.t,v 1.659 2014/10/03 17:32:09 tg Exp $
-# OpenBSD src/regress/bin/ksh updated: 2013/12/02 20:39:44
+# $MirOS: src/bin/mksh/check.t,v 1.775 2017/04/12 17:38:41 tg Exp $
+# -*- mode: sh -*-
 #-
 # Copyright © 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-#            2011, 2012, 2013, 2014
-#      Thorsten Glaser <tg@mirbsd.org>
+#            2011, 2012, 2013, 2014, 2015, 2016, 2017
+#      mirabilos <m@mirbsd.org>
 #
 # Provided that these terms and disclaimer and all copyright notices
 # are retained or reproduced in an accompanying document, permission
 # http://www.research.att.com/~gsf/public/ifs.sh
 #
 # More testsuites at:
-# http://www.freebsd.org/cgi/cvsweb.cgi/src/tools/regression/bin/test/regress.sh?rev=HEAD
+# http://svnweb.freebsd.org/base/head/bin/test/tests/legacy_test.sh?view=co&content-type=text%2Fplain
+#
+# Integrated testsuites from:
+# (2013/12/02 20:39:44) http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/regress/bin/ksh/?sortby=date
 
 expected-stdout:
-       @(#)MIRBSD KSH R50 2014/10/03
+       @(#)MIRBSD KSH R55 2017/04/12
 description:
        Check version of shell.
 stdin:
        echo $KSH_VERSION
 name: KSH_VERSION
-category: shell:legacy-no
+category: !shell:legacy-yes,!shell:textmode-yes
 ---
 expected-stdout:
-       @(#)LEGACY KSH R50 2014/10/03
+       @(#)LEGACY KSH R55 2017/04/12
 description:
        Check version of legacy shell.
 stdin:
        echo $KSH_VERSION
 name: KSH_VERSION-legacy
-category: shell:legacy-yes
+category: !shell:legacy-no,!shell:textmode-yes
+---
+expected-stdout:
+       @(#)MIRBSD KSH R55 2017/04/12 +TEXTMODE
+description:
+       Check version of shell.
+stdin:
+       echo $KSH_VERSION
+name: KSH_VERSION-textmode
+category: !shell:legacy-yes,!shell:textmode-no
+---
+expected-stdout:
+       @(#)LEGACY KSH R55 2017/04/12 +TEXTMODE
+description:
+       Check version of legacy shell.
+stdin:
+       echo $KSH_VERSION
+name: KSH_VERSION-legacy-textmode
+category: !shell:legacy-no,!shell:textmode-no
 ---
 name: selftest-1
 description:
@@ -89,23 +110,6 @@ category: disabled
 stdin:
        set
 ---
-name: selftest-legacy
-description:
-       Check some things in the LEGACY KSH
-category: shell:legacy-yes
-stdin:
-       set +o emacs
-       set +o vi
-       [[ "$(set +o) -o" = *"-o emacs -o"* ]] && echo 1=emacs
-       [[ "$(set +o) -o" = *"-o vi -o"* ]] && echo 1=vi
-       set -o emacs
-       set -o vi
-       [[ "$(set +o) -o" = *"-o emacs -o"* ]] && echo 2=emacs
-       [[ "$(set +o) -o" = *"-o vi -o"* ]] && echo 2=vi
-expected-stdout:
-       2=emacs
-       2=vi
----
 name: selftest-direct-builtin-call
 description:
        Check that direct builtin calls work
@@ -116,6 +120,26 @@ stdin:
 expected-stdout:
        -c echo  foo
 ---
+name: selftest-pathsep-unix
+description:
+       Check that $PATHSEP is set correctly.
+category: !os:os2
+stdin:
+       PATHSEP=.; export PATHSEP
+       "$__progname" -c 'print -r -- $PATHSEP'
+expected-stdout:
+       :
+---
+name: selftest-pathsep-dospath
+description:
+       Check that $PATHSEP is set correctly.
+category: os:os2
+stdin:
+       PATHSEP=.; export PATHSEP
+       "$__progname" -c 'print -r -- $PATHSEP'
+expected-stdout:
+       ;
+---
 name: alias-1
 description:
        Check that recursion is detected/avoided in aliases.
@@ -196,7 +220,7 @@ description:
 stdin:
        alias X='case '
        alias Y=Z
-       X Y in 'Y') echo is y ;; Z) echo is z ; esac
+       X Y in 'Y') echo is y ;; Z) echo is z ;; esac
 expected-stdout:
        is z
 ---
@@ -229,7 +253,7 @@ time-limit: 3
 stdin:
        print '#!'"$__progname"'\necho tf' >lq
        chmod +x lq
-       PATH=$PWD:$PATH
+       PATH=$PWD$PATHSEP$PATH
        alias lq=lq
        lq
        echo = now
@@ -254,6 +278,55 @@ stdin:
 expected-stdout:
        hello world
 ---
+name: alias-11
+description:
+       Check that special argument handling still applies with escaped aliases
+stdin:
+       alias local1='\typeset'
+       alias local2='\\builtin typeset'
+       function fooa {
+               local1 x=$1 y=z
+               print -r -- "$x,$y"
+       }
+       function foob {
+               local2 x=$1 y=z
+               print -r -- "$x,$y"
+       }
+       x=1 y=2; fooa 'bar - baz'
+       x=1 y=2; foob 'bar - baz'
+expected-stdout:
+       bar - baz,z
+       bar - baz,z
+---
+name: alias-12
+description:
+       Something weird from Martijn Dekker
+stdin:
+       alias echo=print
+       x() { echo a; (echo b); x=$(echo c); }
+       typeset -f x
+       alias OPEN='{' CLOSE='};'
+       { OPEN echo hi1; CLOSE }
+       var=`{ OPEN echo hi2; CLOSE }` && echo "$var"
+       var=$({ OPEN echo hi3; CLOSE }) && echo "$var"
+expected-stdout:
+       x() {
+               \print a 
+               ( \print b ) 
+               x=$(\print c ) 
+       } 
+       hi1
+       hi2
+       hi3
+---
+name: arith-compound
+description:
+       Check that arithmetic expressions are compound constructs
+stdin:
+       { ! (( 0$(cat >&2) )) <<<1; } <<<2
+expected-stderr:
+       1
+---
 name: arith-lazy-1
 description:
        Check that only one side of ternary operator is evaluated
@@ -316,6 +389,62 @@ expected-stdout:
        2
        0
 ---
+name: arith-lazy-5-arr-n
+description: Check lazy evaluation with side effects
+stdin:
+       a=0; echo "$((0&&b[a++],a))"
+expected-stdout:
+       0
+---
+name: arith-lazy-5-arr-p
+description: Check lazy evaluation with side effects
+stdin:
+       a=0; echo "$((0&&(b[a++]),a))"
+expected-stdout:
+       0
+---
+name: arith-lazy-5-str-n
+description: Check lazy evaluation with side effects
+stdin:
+       a=0 b=a++; ((0&&b)); echo $a
+expected-stdout:
+       0
+---
+name: arith-lazy-5-str-p
+description: Check lazy evaluation with side effects
+stdin:
+       a=0 b=a++; ((0&&(b))); echo $a
+expected-stdout:
+       0
+---
+name: arith-lazy-5-tern-l-n
+description: Check lazy evaluation with side effects
+stdin:
+       a=0; echo "$((0?b[a++]:999,a))"
+expected-stdout:
+       0
+---
+name: arith-lazy-5-tern-l-p
+description: Check lazy evaluation with side effects
+stdin:
+       a=0; echo "$((0?(b[a++]):999,a))"
+expected-stdout:
+       0
+---
+name: arith-lazy-5-tern-r-n
+description: Check lazy evaluation with side effects
+stdin:
+       a=0; echo "$((1?999:b[a++],a))"
+expected-stdout:
+       0
+---
+name: arith-lazy-5-tern-r-p
+description: Check lazy evaluation with side effects
+stdin:
+       a=0; echo "$((1?999:(b[a++]),a))"
+expected-stdout:
+       0
+---
 name: arith-ternary-prec-1
 description:
        Check precedence of ternary operator vs assignment
@@ -335,6 +464,18 @@ stdin:
 expected-stdout:
        20
 ---
+name: arith-prec-1
+description:
+       Prove arithmetic expressions with embedded parameter
+       substitutions cannot be parsed ahead of time
+stdin:
+       a='3 + 4'
+       print 1 $((2 * a)) .
+       print 2 $((2 * $a)) .
+expected-stdout:
+       1 14 .
+       2 10 .
+---
 name: arith-div-assoc-1
 description:
        Check associativity of division operator
@@ -459,6 +600,9 @@ stdin:
        va[1975973142]=right
        va[4123456789]=wrong
        echo x7 ${va[#4123456789%2147483647]}
+       # make sure multiple calculations don't interfere with each other
+       let '# mca = -4 % -2' ' mcb = -4 % -2'
+       echo x8 $mca $mcb
 expected-stdout:
        x1 -1 4294967295
        x2 -171510507 4123456789
@@ -467,6 +611,7 @@ expected-stdout:
        x5 -171510507 4123456789
        x6 1975973142 1975973142
        x7 right
+       x8 -4 0
 ---
 name: arith-limit32-1
 description:
@@ -856,6 +1001,8 @@ stdin:
            echo end-$i
        done
        echo end-3
+       for i in a b c; do echo $i; eval break; echo bad-$i; done
+       echo end-4
 expected-stdout:
        a
        end-1
@@ -868,6 +1015,8 @@ expected-stdout:
        c:x
        end-c
        end-3
+       a
+       end-4
 ---
 name: break-2
 description:
@@ -937,6 +1086,8 @@ stdin:
            echo end-$i
        done
        echo end-3
+       for i in a b c; do echo $i; eval continue; echo bad-$i ; done
+       echo end-4
 expected-stdout:
        a
        b
@@ -959,6 +1110,10 @@ expected-stdout:
        c:z
        end-c
        end-3
+       a
+       b
+       c
+       end-4
 ---
 name: continue-2
 description:
@@ -1182,7 +1337,7 @@ need-pass: no
 # the mv command fails on Cygwin
 # Hurd aborts the testsuite (permission denied)
 # QNX does not find subdir to cd into
-category: !os:cygwin,!os:gnu,!os:msys,!os:nto,!nosymlink
+category: !os:cygwin,!os:gnu,!os:msys,!os:nto,!os:os390,!nosymlink
 file-setup: file 644 "x"
        mkdir noread noread/target noread/target/subdir
        ln -s noread link
@@ -1283,6 +1438,7 @@ stdin:
        (echo 38 ${IFS+x'a'y} / "${IFS+x'a'y}" .) 2>/dev/null || echo failed in 38
        foo="x'a'y"; (echo 39 ${foo%*'a'*} / "${foo%*'a'*}" .) 2>/dev/null || echo failed in 39
        foo="a b c"; (echo -n '40 '; ./pfs "${foo#a}"; echo .) 2>/dev/null || echo failed in 40
+       (foo() { return 100; }; foo; echo 41 ${#+${#:+${#?}}\ \}\}\}}) 2>/dev/null || echo failed in 41
 expected-stdout:
        1 }z
        2 ''z}
@@ -1324,6 +1480,7 @@ expected-stdout:
        38 xay / x'a'y .
        39 x' / x' .
        40 < b c> .
+       41 3 }}}
 ---
 name: expand-unglob-dblq
 description:
@@ -1372,6 +1529,7 @@ stdin:
                (echo "$1 QSTN brac foo ${v:?a$u{{{\}b} c ${v:?d{}} baz") 2>/dev/null || \
                    echo "$1 QSTN brac -> error"
        }
+       : '}}}' '}}}' '}}}' '}}}' '}}}' '}}}' '}}}' '}}}'
        tl_norm 1 -
        tl_norm 2 ''
        tl_norm 3 x
@@ -1502,6 +1660,7 @@ stdin:
                (echo $1 QSTN brac foo ${v:?a$u{{{\}b} c ${v:?d{}} baz) 2>/dev/null || \
                    echo "$1 QSTN brac -> error"
        }
+       : '}}}' '}}}' '}}}' '}}}' '}}}' '}}}' '}}}' '}}}'
        tl_norm 1 -
        tl_norm 2 ''
        tl_norm 3 x
@@ -1609,7 +1768,7 @@ expected-exit: 1
 ---
 name: expand-weird-1
 description:
-       Check corner case of trim expansion vs. $# vs. ${#var}
+       Check corner cases of trim expansion vs. $# vs. ${#var} vs. ${var?}
 stdin:
        set 1 2 3 4 5 6 7 8 9 10 11
        echo ${#}       # value of $#
@@ -1617,23 +1776,59 @@ stdin:
        echo ${##1}     # $# trimmed 1
        set 1 2 3 4 5 6 7 8 9 10 11 12
        echo ${##1}
+       (exit 0)
+       echo $? = ${#?} .
+       (exit 111)
+       echo $? = ${#?} .
 expected-stdout:
        11
        2
        1
        2
+       0 = 1 .
+       111 = 3 .
 ---
 name: expand-weird-2
 description:
-       Check corner case of ${var?} vs. ${#var}
-stdin:
-       (exit 0)
-       echo $? = ${#?} .
-       (exit 111)
-       echo $? = ${#?} .
-expected-stdout:
-       0 = 1 .
-       111 = 3 .
+       Check more substitution and extension corner cases
+stdin:
+       :& set -C; pid=$$; sub=$!; flg=$-; set -- i; exec 3>x.tmp
+       #echo "D: !=$! #=$# \$=$$ -=$- ?=$?"
+       echo >&3 3 = s^${!-word} , ${#-word} , p^${$-word} , f^${--word} , ${?-word} .
+       echo >&3 4 = ${!+word} , ${#+word} , ${$+word} , ${-+word} , ${?+word} .
+       echo >&3 5 = s^${!=word} , ${#=word} , p^${$=word} , f^${-=word} , ${?=word} .
+       echo >&3 6 = s^${!?word} , ${#?word} , p^${$?word} , f^${-?word} , ${??word} .
+       echo >&3 7 = sl^${#!} , ${##} , pl^${#$} , fl^${#-} , ${#?} .
+       echo >&3 8 = sw^${%!} , ${%#} , pw^${%$} , fw^${%-} , ${%?} .
+       echo >&3 9 = ${!!} , s^${!#} , ${!$} , s^${!-} , s^${!?} .
+       echo >&3 10 = s^${!#pattern} , ${##pattern} , p^${$#pattern} , f^${-#pattern} , ${?#pattern} .
+       echo >&3 11 = s^${!%pattern} , ${#%pattern} , p^${$%pattern} , f^${-%pattern} , ${?%pattern} .
+       echo >&3 12 = $# : ${##} , ${##1} .
+       set --
+       echo >&3 14 = $# : ${##} , ${##1} .
+       set -- 1 2 3 4 5
+       echo >&3 16 = $# : ${##} , ${##1} .
+       set -- 1 2 3 4 5 6 7 8 9 a b c d e
+       echo >&3 18 = $# : ${##} , ${##1} .
+       exec 3>&-
+       <x.tmp sed \
+           -e "s/ pl^${#pid} / PID /g" -e "s/ sl^${#sub} / SUB /g" -e "s/ fl^${#flg} / FLG /g" \
+           -e "s/ pw^${%pid} / PID /g" -e "s/ sw^${%sub} / SUB /g" -e "s/ fw^${%flg} / FLG /g" \
+           -e "s/ p^$pid / PID /g" -e "s/ s^$sub / SUB /g" -e "s/ f^$flg / FLG /g"
+expected-stdout:
+       3 = SUB , 1 , PID , FLG , 0 .
+       4 = word , word , word , word , word .
+       5 = SUB , 1 , PID , FLG , 0 .
+       6 = SUB , 1 , PID , FLG , 0 .
+       7 = SUB , 1 , PID , FLG , 1 .
+       8 = SUB , 1 , PID , FLG , 1 .
+       9 = ! , SUB , $ , SUB , SUB .
+       10 = SUB , 1 , PID , FLG , 0 .
+       11 = SUB , 1 , PID , FLG , 0 .
+       12 = 1 : 1 , .
+       14 = 0 : 1 , 0 .
+       16 = 5 : 1 , 5 .
+       18 = 14 : 2 , 4 .
 ---
 name: expand-weird-3
 description:
@@ -1648,6 +1843,61 @@ expected-stdout:
        1=02.
        2=02.
 ---
+name: expand-weird-4
+description:
+       Check that tilde expansion is enabled in ${x#~}
+       and cases that are modelled after it (${x/~/~})
+stdin:
+       HOME=/etc
+       a="~/x"
+       echo "<${a#~}> <${a#\~}> <${b:-~}> <${b:-\~}> <${c:=~}><$c> <${a/~}> <${a/x/~}> <${a/x/\~}>"
+expected-stdout:
+       <~/x> </x> <~> <\~> <~><~> <~/x> <~//etc> <~/~>
+---
+name: expand-bang-1
+description:
+       Check corner case of ${!?} with ! being var vs. op
+stdin:
+       echo ${!?}
+expected-exit: 1
+expected-stderr-pattern: /not set/
+---
+name: expand-bang-2
+description:
+       Check corner case of ${!var} vs. ${var op} with var=!
+stdin:
+       echo 1 $! .
+       echo 2 ${!#} .
+       echo 3 ${!#[0-9]} .
+       echo 4 ${!-foo} .
+       # get an at least three-digit bg pid
+       while :; do
+               :&
+               x=$!
+               if [[ $x != +([0-9]) ]]; then
+                       echo >&2 "cannot test, pid '$x' not numeric"
+                       echo >&2 report this with as many details as possible
+                       exit 1
+               fi
+               [[ $x = [0-9][0-9][0-9]* ]] && break
+       done
+       y=${x#?}
+       t=$!; [[ $t = $x ]]; echo 5 $? .
+       t=${!#}; [[ $t = $x ]]; echo 6 $? .
+       t=${!#[0-9]}; [[ $t = $y ]]; echo 7 $? .
+       t=${!-foo}; [[ $t = $x ]]; echo 8 $? .
+       t=${!?bar}; [[ $t = $x ]]; echo 9 $? .
+expected-stdout:
+       1 .
+       2 .
+       3 .
+       4 foo .
+       5 0 .
+       6 0 .
+       7 0 .
+       8 0 .
+       9 0 .
+---
 name: expand-number-1
 description:
        Check that positional arguments do not overflow
@@ -1656,6 +1906,41 @@ stdin:
 expected-stdout:
        1  .
 ---
+name: expand-slashes-1
+description:
+       Check that side effects in substring replacement are handled correctly
+stdin:
+       foo=n1n1n1n2n3
+       i=2
+       n=1
+       echo 1 ${foo//n$((n++))/[$((++i))]} .
+       echo 2 $n , $i .
+expected-stdout:
+       1 [3][3][3]n2n3 .
+       2 2 , 3 .
+---
+name: expand-slashes-2
+description:
+       Check that side effects in substring replacement are handled correctly
+stdin:
+       foo=n1n1n1n2n3
+       i=2
+       n=1
+       echo 1 ${foo@/n$((n++))/[$((++i))]} .
+       echo 2 $n , $i .
+expected-stdout:
+       1 [3]n1n1[4][5] .
+       2 5 , 5 .
+---
+name: expand-slashes-3
+description:
+       Check that we can access the replaced string
+stdin:
+       foo=n1n1n1n2n3
+       echo 1 ${foo@/n[12]/[$KSH_MATCH]} .
+expected-stdout:
+       1 [n1][n1][n1][n2]n3 .
+---
 name: eglob-bad-1
 description:
        Check that globbing isn't done when glob has syntax error
@@ -1819,7 +2104,7 @@ stdin:
        [[ -n $BASH_VERSION ]] && shopt -s extglob
        x=1222321_ab/cde_b/c_1221
        y=xyz
-       echo 1: ${x/2}
+       echo 1: ${x/2} . ${x/}
        echo 2: ${x//2}
        echo 3: ${x/+(2)}
        echo 4: ${x//+(2)}
@@ -1841,15 +2126,17 @@ stdin:
        echo 20: ${x/\//.}
        echo 21: ${x//\//.}
        echo 22: ${x///.}
-       echo 23: ${x//#1/9}
-       echo 24: ${x//%1/9}
-       echo 25: ${x//\%1/9}
-       echo 26: ${x//\\%1/9}
-       echo 27: ${x//\a/9}
-       echo 28: ${x//\\a/9}
-       echo 29: ${x/2/$y}
-expected-stdout:
-       1: 122321_ab/cde_b/c_1221
+       echo 23: ${x/#1/9}
+       echo 24: ${x//#1/9}
+       echo 25: ${x/%1/9}
+       echo 26: ${x//%1/9}
+       echo 27: ${x//\%1/9}
+       echo 28: ${x//\\%1/9}
+       echo 29: ${x//\a/9}
+       echo 30: ${x//\\a/9}
+       echo 31: ${x/2/$y}
+expected-stdout:
+       1: 122321_ab/cde_b/c_1221 . 1222321_ab/cde_b/c_1221
        2: 131_ab/cde_b/c_11
        3: 1321_ab/cde_b/c_1221
        4: 131_ab/cde_b/c_11
@@ -1872,12 +2159,14 @@ expected-stdout:
        21: 1222321_ab.cde_b.c_1221
        22: 1222321_ab/cde_b/c_1221
        23: 9222321_ab/cde_b/c_1221
-       24: 1222321_ab/cde_b/c_1229
+       24: 1222321_ab/cde_b/c_1221
        25: 1222321_ab/cde_b/c_1229
        26: 1222321_ab/cde_b/c_1221
-       27: 1222321_9b/cde_b/c_1221
-       28: 1222321_9b/cde_b/c_1221
-       29: 1xyz22321_ab/cde_b/c_1221
+       27: 1222321_ab/cde_b/c_1221
+       28: 1222321_ab/cde_b/c_1221
+       29: 1222321_9b/cde_b/c_1221
+       30: 1222321_ab/cde_b/c_1221
+       31: 1xyz22321_ab/cde_b/c_1221
 ---
 name: eglob-substrpl-2
 description:
@@ -1902,6 +2191,7 @@ name: eglob-substrpl-3a
 description:
        Check substring replacement works with variables and slashes, too
 stdin:
+       HOME=/etc
        pfx=/home/user
        wd=/home/user/tmp
        echo "${wd/#$pfx/~}"
@@ -1911,9 +2201,9 @@ stdin:
        echo "${wd/#"\$pfx"/~}"
        echo "${wd/#'\$pfx'/~}"
 expected-stdout:
-       ~/tmp
+       /etc/tmp
        /home/user/tmp
-       ~/tmp
+       /etc/tmp
        /home/user/tmp
        /home/user/tmp
        /home/user/tmp
@@ -1922,20 +2212,22 @@ name: eglob-substrpl-3b
 description:
        More of this, bash fails it (bash4 passes)
 stdin:
+       HOME=/etc
        pfx=/home/user
        wd=/home/user/tmp
        echo "${wd/#$(echo /home/user)/~}"
        echo "${wd/#"$(echo /home/user)"/~}"
        echo "${wd/#'$(echo /home/user)'/~}"
 expected-stdout:
-       ~/tmp
-       ~/tmp
+       /etc/tmp
+       /etc/tmp
        /home/user/tmp
 ---
 name: eglob-substrpl-3c
 description:
        Even more weird cases
 stdin:
+       HOME=/etc
        pfx=/home/user
        wd='$pfx/tmp'
        echo 1: ${wd/#$pfx/~}
@@ -1961,31 +2253,31 @@ stdin:
        echo 17: ${ts/+($tp)/$tr}
        echo 18: ${ts/+($tp)/c/d}
        echo 19: ${ts/+($tp)/c\/d}
-       echo 25: ${ts//a\/b/$tr}
-       echo 26: ${ts//a\/b/\$tr}
-       echo 27: ${ts//$tp/$tr}
-       echo 28: ${ts//$tp/c/d}
-       echo 29: ${ts//$tp/c\/d}
-       echo 30: ${ts//+(a\/b)/$tr}
-       echo 31: ${ts//+(a\/b)/\$tr}
-       echo 32: ${ts//+($tp)/$tr}
-       echo 33: ${ts//+($tp)/c/d}
-       echo 34: ${ts//+($tp)/c\/d}
+       echo 20: ${ts//a\/b/$tr}
+       echo 21: ${ts//a\/b/\$tr}
+       echo 22: ${ts//$tp/$tr}
+       echo 23: ${ts//$tp/c/d}
+       echo 24: ${ts//$tp/c\/d}
+       echo 25: ${ts//+(a\/b)/$tr}
+       echo 26: ${ts//+(a\/b)/\$tr}
+       echo 27: ${ts//+($tp)/$tr}
+       echo 28: ${ts//+($tp)/c/d}
+       echo 29: ${ts//+($tp)/c\/d}
        tp="+($tp)"
-       echo 40: ${ts/$tp/$tr}
-       echo 41: ${ts//$tp/$tr}
+       echo 30: ${ts/$tp/$tr}
+       echo 31: ${ts//$tp/$tr}
 expected-stdout:
        1: $pfx/tmp
-       2: ~/tmp
+       2: /etc/tmp
        3: $pfx/tmp
-       4: ~/tmp
-       5: ~/tmp
-       6: ~/tmp
+       4: /etc/tmp
+       5: /etc/tmp
+       6: $pfx/tmp
        7: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
        8: $tra/b$tp$tp_a/b$tp_*(a/b)_*($tp)
        9: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
        10: a/ba/bc/d$tp_a/b$tp_*(a/b)_*($tp)
-       11: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
+       11: a/ba/b$tp$tp_a/b$tp_*(a/b)_*($tp)
        12: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
        13: c/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
        14: c\/da/b$tp$tp_a/b$tp_*(a/b)_*($tp)
@@ -1994,21 +2286,21 @@ expected-stdout:
        17: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
        18: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
        19: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
-       25: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
-       26: $tr$tr$tp$tp_$tr$tp_*($tr)_*($tp)
-       27: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
-       28: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
-       29: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
-       30: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
-       31: $tr$tp$tp_$tr$tp_*($tr)_*($tp)
-       32: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
-       33: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
-       34: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
-       40: a/ba/b$tp$tp_a/b$tp_*(a/b)_*($tp)
-       41: a/ba/b$tp$tp_a/b$tp_*(a/b)_*($tp)
+       20: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
+       21: $tr$tr$tp$tp_$tr$tp_*($tr)_*($tp)
+       22: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
+       23: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
+       24: c/dc/d$tp$tp_c/d$tp_*(c/d)_*($tp)
+       25: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
+       26: $tr$tp$tp_$tr$tp_*($tr)_*($tp)
+       27: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
+       28: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
+       29: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
+       30: a/ba/b$tp$tp_a/b$tp_*(a/b)_*($tp)
+       31: a/ba/b$tp$tp_a/b$tp_*(a/b)_*($tp)
 #      This is what GNU bash does:
-#      40: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
-#      41: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
+#      30: c/d$tp$tp_a/b$tp_*(a/b)_*($tp)
+#      31: c/d$tp$tp_c/d$tp_*(c/d)_*($tp)
 ---
 name: eglob-utf8-1
 description:
@@ -2059,9 +2351,9 @@ expected-stdout:
 name: glob-bad-2
 description:
        Check that symbolic links aren't stat()'d
-# breaks on FreeMiNT (cannot unlink dangling symlinks)
-# breaks on MSYS (does not support symlinks)
 # breaks on Dell UNIX 4.0 R2.2 (SVR4) where unlink also fails
+# breaks on FreeMiNT (cannot unlink dangling symlinks)
+# breaks on MSYS, OS/2 (do not support symlinks)
 category: !os:mint,!os:msys,!os:svr4.0,!nosymlink
 file-setup: dir 755 "dir"
 file-setup: symlink 644 "dir/abc"
@@ -2116,7 +2408,7 @@ description:
 # breaks on Mac OSX (HFS+ non-standard Unicode canonical decomposition)
 # breaks on Cygwin 1.7 (files are now UTF-16 or something)
 # breaks on QNX 6.4.1 (says RT)
-category: !os:cygwin,!os:darwin,!os:msys,!os:nto
+category: !os:cygwin,!os:darwin,!os:msys,!os:nto,!os:os2
 need-pass: no
 file-setup: file 644 "aÂc"
 stdin:
@@ -2203,9 +2495,20 @@ expected-stdout:
        hi
        there
 ---
-name: heredoc-4
+name: heredoc-4a
+description:
+       Check that an error occurs if the heredoc-delimiter is missing.
+stdin: !
+       cat << EOF
+       hi
+       there
+expected-exit: e > 0
+expected-stderr-pattern: /.*/
+---
+name: heredoc-4an
 description:
        Check that an error occurs if the heredoc-delimiter is missing.
+arguments: !-n!
 stdin: !
        cat << EOF
        hi
@@ -2213,6 +2516,23 @@ stdin: !
 expected-exit: e > 0
 expected-stderr-pattern: /.*/
 ---
+name: heredoc-4b
+description:
+       Check that an error occurs if the heredoc is missing.
+stdin: !
+       cat << EOF
+expected-exit: e > 0
+expected-stderr-pattern: /.*/
+---
+name: heredoc-4bn
+description:
+       Check that an error occurs if the heredoc is missing.
+arguments: !-n!
+stdin: !
+       cat << EOF
+expected-exit: e > 0
+expected-stderr-pattern: /.*/
+---
 name: heredoc-5
 description:
        Check that backslash quotes a $, ` and \ and kills a \newline
@@ -2309,6 +2629,8 @@ stdin:
        tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<\$bar
        tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<-foo
        tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<"$(echo "foo bar")"
+       tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<"A $(echo "foo bar") B"
+       tr abcdefghijklmnopqrstuvwxyz nopqrstuvwxyzabcdefghijklm <<<\$b\$b$bar
 expected-stdout:
        sbb
        sbb
@@ -2318,6 +2640,9 @@ expected-stdout:
        $one
        -sbb
        sbb one
+       A sbb one B
+       $o$oone
+               onm
 ---
 name: heredoc-9b
 description:
@@ -2359,6 +2684,14 @@ stdin:
 expected-stdout:
        baz
 ---
+name: heredoc-9f
+description:
+       Check long here strings
+stdin:
+       cat <<< "$(  :                                                             )aa"
+expected-stdout:
+       aa
+---
 name: heredoc-10
 description:
        Check direct here document assignment
@@ -2389,9 +2722,17 @@ stdin:
        vf=<<<$'=f $x \x40='
        # now check
        print -r -- "| va={$va} vb={$vb} vc={$vc} vd={$vd} ve={$ve} vf={$vf} |"
+       # check append
+       v=<<-EOF
+               vapp1
+       EOF
+       v+=<<-EOF
+               vapp2
+       EOF
+       print -r -- "| ${v//$'\n'/^} |"
 expected-stdout:
        function foo {
-               vc=<<-EOF
+               vc=<<-EOF 
        =c $x \x40=
        EOF
        
@@ -2404,6 +2745,7 @@ expected-stdout:
        } ve={=e $x \x40=
        } vf={=f $x @=
        } |
+       | vapp1^vapp2^ |
 ---
 name: heredoc-11
 description:
@@ -2433,13 +2775,25 @@ stdin:
        eval "$fnd"
        foo
        print -r -- "| va={$va} vb={$vb} vc={$vc} vd={$vd} |"
+       x=y
+       foo
+       typeset -f foo
+       print -r -- "| vc={$vc} vd={$vd} |"
+       # check append
+       v=<<-
+               vapp1
+       <<
+       v+=<<-''
+               vapp2
+       
+       print -r -- "| ${v//$'\n'/^} |"
 expected-stdout:
        function foo {
-               vc=<<-
+               vc=<<- 
        =c $x \x40=
        <<
        
-               vd=<<-""
+               vd=<<-"" 
        =d $x \x40=
        
        
@@ -2450,6 +2804,105 @@ expected-stdout:
        } vc={=c u \x40=
        } vd={=d $x \x40=
        } |
+       function foo {
+               vc=<<- 
+       =c $x \x40=
+       <<
+       
+               vd=<<-"" 
+       =d $x \x40=
+       
+       
+       } 
+       | vc={=c y \x40=
+       } vd={=d $x \x40=
+       } |
+       | vapp1^vapp2^ |
+---
+name: heredoc-12
+description:
+       Check here documents can use $* and $@; note shells vary:
+       • pdksh 5.2.14 acts the same
+       • dash has 1 and 2 the same but 3 lacks the space
+       • ksh93, bash4 differ in 2 by using space ipv colon
+stdin:
+       set -- a b
+       nl='
+       '
+       IFS="   $nl"; n=1
+       cat <<EOF
+       $n foo $* foo
+       $n bar "$*" bar
+       $n baz $@ baz
+       $n bla "$@" bla
+       EOF
+       IFS=":"; n=2
+       cat <<EOF
+       $n foo $* foo
+       $n bar "$*" bar
+       $n baz $@ baz
+       $n bla "$@" bla
+       EOF
+       IFS=; n=3
+       cat <<EOF
+       $n foo $* foo
+       $n bar "$*" bar
+       $n baz $@ baz
+       $n bla "$@" bla
+       EOF
+expected-stdout:
+       1 foo a b foo
+       1 bar "a b" bar
+       1 baz a b baz
+       1 bla "a b" bla
+       2 foo a:b foo
+       2 bar "a:b" bar
+       2 baz a:b baz
+       2 bla "a:b" bla
+       3 foo a b foo
+       3 bar "a b" bar
+       3 baz a b baz
+       3 bla "a b" bla
+---
+name: heredoc-14
+description:
+       Check that using multiple here documents works
+stdin:
+       foo() {
+               echo "got $(cat) on stdin"
+               echo "got $(cat <&4) on fd#4"
+               echo "got $(cat <&5) on fd#5"
+       }
+       bar() {
+               foo 4<<-a <<-b 5<<-c
+               four
+               a
+               zero
+               b
+               five
+               c
+       }
+       x=$(typeset -f bar)
+       eval "$x"
+       y=$(typeset -f bar)
+       [[ $x = "$y" ]]; echo $?
+       typeset -f bar
+       bar
+expected-stdout:
+       0
+       bar() {
+               \foo 4<<-a <<-b 5<<-c 
+       four
+       a
+       zero
+       b
+       five
+       c
+       
+       } 
+       got zero on stdin
+       got four on fd#4
+       got five on fd#5
 ---
 name: heredoc-comsub-1
 description:
@@ -2495,6 +2948,54 @@ stdin:
 expected-stdout:
        = these parens \( ) are a problem =
 ---
+name: heredoc-comsub-5
+description:
+       Check heredoc and COMSUB mixture in input
+stdin:
+       prefix() { sed -e "s/^/$1:/"; }
+       XXX() { echo x-en; }
+       YYY() { echo y-es; }
+       
+       prefix A <<XXX && echo "$(prefix B <<XXX
+       echo line 1
+       XXX
+       echo line 2)" && prefix C <<YYY
+       echo line 3
+       XXX
+       echo line 4)"
+       echo line 5
+       YYY
+       XXX
+expected-stdout:
+       A:echo line 3
+       B:echo line 1
+       line 2
+       C:echo line 4)"
+       C:echo line 5
+       x-en
+---
+name: heredoc-comsub-6
+description:
+       Check here documents and here strings can be used
+       without a specific command, like $(<…) (extension)
+stdin:
+       foo=bar
+       x=$(<<<EO${foo}F)
+       echo "3<$x>"
+               y=$(<<-EOF
+                       hi!
+       
+                       $foo) is not a problem
+       
+       
+               EOF)
+       echo "7<$y>"
+expected-stdout:
+       3<EObarF>
+       7<hi!
+       
+       bar) is not a problem>
+---
 name: heredoc-subshell-1
 description:
        Tests for here documents in subshells, taken from Austin ML
@@ -2957,6 +3458,37 @@ expected-stdout:
 expected-stderr-pattern:
        /(.*can't unlink HISTFILE.*\n)?X*$/
 ---
+name: history-multiline
+description:
+       Check correct multiline history, Debian #783978
+need-ctty: yes
+arguments: !-i!
+env-setup: !ENV=./Env!
+file-setup: file 644 "Env"
+       PS1=X
+       PS2=Y
+stdin:
+       for i in A B C
+       do
+          print $i
+          print $i
+       done
+       fc -l
+expected-stdout:
+       A
+       A
+       B
+       B
+       C
+       C
+       1       for i in A B C
+               do
+                  print $i
+                  print $i
+               done
+expected-stderr-pattern:
+       /^XYYYYXX$/
+---
 name: history-e-minus-1
 description:
        Check if more recent command is executed
@@ -3468,7 +4000,6 @@ name: history-ed-3-old
 description:
        Newly created multi line commands show up as single command
        in history.
-       (NOTE: adjusted for COMPLEX HISTORY compile time option)
        (ksh88 fails 'cause it lists the fc command)
 category: stdout-ed
 need-ctty: yes
@@ -3495,7 +4026,7 @@ expected-stdout:
        a new line
        1       echo abc def
        2       echo FOOBAR def
-       3       echo a new line
+               echo a new line
 expected-stderr-pattern:
        /^X*echo FOOBAR def\necho a new line\nX*$/
 ---
@@ -3577,7 +4108,7 @@ expected-stdout:
        a new line
        1       echo abc def
        2       echo FOOBAR def
-       3       echo a new line
+               echo a new line
 expected-stderr-pattern:
        /^X*13\n32\necho FOOBAR def\necho a new line\nX*$/
 ---
@@ -3585,23 +4116,23 @@ name: IFS-space-1
 description:
        Simple test, default IFS
 stdin:
-       showargs() { for i; do echo -n " <$i>"; done; echo; }
+       showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
        set -- A B C
        showargs 1 $*
        showargs 2 "$*"
        showargs 3 $@
        showargs 4 "$@"
 expected-stdout:
-        <1> <A> <B> <C>
-        <2> <A B C>
-        <3> <A> <B> <C>
-        <4> <A> <B> <C>
+       <1> <A> <B> <C> .
+       <2> <A B C> .
+       <3> <A> <B> <C> .
+       <4> <A> <B> <C> .
 ---
 name: IFS-colon-1
 description:
        Simple test, IFS=:
 stdin:
-       showargs() { for i; do echo -n " <$i>"; done; echo; }
+       showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
        IFS=:
        set -- A B C
        showargs 1 $*
@@ -3609,16 +4140,16 @@ stdin:
        showargs 3 $@
        showargs 4 "$@"
 expected-stdout:
-        <1> <A> <B> <C>
-        <2> <A:B:C>
-        <3> <A> <B> <C>
-        <4> <A> <B> <C>
+       <1> <A> <B> <C> .
+       <2> <A:B:C> .
+       <3> <A> <B> <C> .
+       <4> <A> <B> <C> .
 ---
 name: IFS-null-1
 description:
        Simple test, IFS=""
 stdin:
-       showargs() { for i; do echo -n " <$i>"; done; echo; }
+       showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
        IFS=""
        set -- A B C
        showargs 1 $*
@@ -3626,16 +4157,16 @@ stdin:
        showargs 3 $@
        showargs 4 "$@"
 expected-stdout:
-        <1> <A> <B> <C>
-        <2> <ABC>
-        <3> <A> <B> <C>
-        <4> <A> <B> <C>
+       <1> <A> <B> <C> .
+       <2> <ABC> .
+       <3> <A> <B> <C> .
+       <4> <A> <B> <C> .
 ---
 name: IFS-space-colon-1
 description:
        Simple test, IFS=<white-space>:
 stdin:
-       showargs() { for i; do echo -n " <$i>"; done; echo; }
+       showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
        IFS="$IFS:"
        set --
        showargs 1 $*
@@ -3644,52 +4175,52 @@ stdin:
        showargs 4 "$@"
        showargs 5 : "$@"
 expected-stdout:
-        <1>
-        <2> <>
-        <3>
-        <4>
-        <5> <:>
+       <1> .
+       <2> <> .
+       <3> .
+       <4> .
+       <5> <:> .
 ---
 name: IFS-space-colon-2
 description:
        Simple test, IFS=<white-space>:
        AT&T ksh fails this, POSIX says the test is correct.
 stdin:
-       showargs() { for i; do echo -n " <$i>"; done; echo; }
+       showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
        IFS="$IFS:"
        set --
        showargs :"$@"
 expected-stdout:
-        <:>
+       <:> .
 ---
 name: IFS-space-colon-4
 description:
        Simple test, IFS=<white-space>:
 stdin:
-       showargs() { for i; do echo -n " <$i>"; done; echo; }
+       showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
        IFS="$IFS:"
        set --
        showargs "$@$@"
 expected-stdout:
-       
+       .
 ---
 name: IFS-space-colon-5
 description:
        Simple test, IFS=<white-space>:
        Don't know what POSIX thinks of this.  AT&T ksh does not do this.
 stdin:
-       showargs() { for i; do echo -n " <$i>"; done; echo; }
+       showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
        IFS="$IFS:"
        set --
        showargs "${@:-}"
 expected-stdout:
-        <>
+       <> .
 ---
 name: IFS-subst-1
 description:
        Simple test, IFS=<white-space>:
 stdin:
-       showargs() { for i; do echo -n " <$i>"; done; echo; }
+       showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
        IFS="$IFS:"
        x=":b: :"
        echo -n '1:'; for i in $x ; do echo -n " [$i]" ; done ; echo
@@ -3711,50 +4242,83 @@ stdin:
 expected-stdout:
        1: [] [b] []
        2: [:b::]
-        <3> <> <b> <>
-        <4> <:b::>
+       <3> <> <b> <> .
+       <4> <:b::> .
        5: [a] [b]
-        <6> <a> <b>
+       <6> <a> <b> .
        7: [a] [] [c]
-        <8> <a> <> <c>
+       <8> <a> <> <c> .
        9: [h] [ith] [ere]
-        <10> <h> <ith> <ere>
-        <11> <h:ith:ere>
+       <10> <h> <ith> <ere> .
+       <11> <h:ith:ere> .
        12: [A] [B] [] [D]
-        <13> <A> <B> <> <D>
+       <13> <A> <B> <> <D> .
 ---
 name: IFS-subst-2
 description:
        Check leading whitespace after trim does not make a field
 stdin:
-       showargs() { for i; do echo -n " <$i>"; done; echo; }
+       showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
        x="X 1 2"
        showargs 1 shift ${x#X}
 expected-stdout:
-        <1> <shift> <1> <2>
+       <1> <shift> <1> <2> .
 ---
-name: IFS-subst-3
+name: IFS-subst-3-arr
 description:
        Check leading IFS non-whitespace after trim does make a field
+       but leading IFS whitespace does not, nor empty replacements
 stdin:
-       showargs() { for i; do echo -n " <$i>"; done; echo; }
+       showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
+       showargs 0 ${-+}
        IFS=:
        showargs 1 ${-+:foo:bar}
+       IFS=' '
+       showargs 2 ${-+ foo bar}
 expected-stdout:
-        <1> <> <foo> <bar>
+       <0> .
+       <1> <> <foo> <bar> .
+       <2> <foo> <bar> .
 ---
-name: IFS-subst-4-1
+name: IFS-subst-3-ass
 description:
-       reported by mikeserv
+       Check non-field semantics
 stdin:
-       a='space divded  argument
-       here'
-       IFS=\  ; set -- $a
-       IFS= ; q="$*" ; nq=$*
-       printf '<%s>\n' "$*" $* "$q" "$nq"
-       [ "$q" = "$nq" ] && echo =true || echo =false
+       showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
+       showargs 0 x=${-+}
+       IFS=:
+       showargs 1 x=${-+:foo:bar}
+       IFS=' '
+       showargs 2 x=${-+ foo bar}
 expected-stdout:
-       <spacedivdedargument
+       <0> <x=> .
+       <1> <x=> <foo> <bar> .
+       <2> <x=> <foo> <bar> .
+---
+name: IFS-subst-3-lcl
+description:
+       Check non-field semantics, smaller corner case (LP#1381965)
+stdin:
+       set -x
+       local regex=${2:-}
+       exit 1
+expected-exit: e != 0
+expected-stderr-pattern:
+       /regex=/
+---
+name: IFS-subst-4-1
+description:
+       reported by mikeserv
+stdin:
+       pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
+       a='space divded  argument
+       here'
+       IFS=\  ; set -- $a
+       IFS= ; q="$*" ; nq=$*
+       pfn "$*" $* "$q" "$nq"
+       [ "$q" = "$nq" ] && echo =true || echo =false
+expected-stdout:
+       <spacedivdedargument
        here>
        <space>
        <divded>
@@ -3770,11 +4334,12 @@ name: IFS-subst-4-2
 description:
        extended testsuite based on problem by mikeserv
 stdin:
+       pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
        a='space divded  argument
        here'
        IFS=\  ; set -- $a
        IFS= ; q="$@" ; nq=$@
-       printf '<%s>\n' "$*" $* "$q" "$nq"
+       pfn "$*" $* "$q" "$nq"
        [ "$q" = "$nq" ] && echo =true || echo =false
 expected-stdout:
        <spacedivdedargument
@@ -3793,6 +4358,7 @@ name: IFS-subst-4-3
 description:
        extended testsuite based on problem by mikeserv
 stdin:
+       pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
        a='space divded  argument
        here'
        IFS=\ ; set -- $a; IFS=
@@ -3800,14 +4366,14 @@ stdin:
        nqs=$*
        qk="$@"
        nqk=$@
-       printf '= qs '; printf '<%s>\n' "$qs"
-       printf '=nqs '; printf '<%s>\n' "$nqs"
-       printf '= qk '; printf '<%s>\n' "$qk"
-       printf '=nqk '; printf '<%s>\n' "$nqk"
-       printf '~ qs '; printf '<%s>\n' "$*"
-       printf '~nqs '; printf '<%s>\n' $*
-       printf '~ qk '; printf '<%s>\n' "$@"
-       printf '~nqk '; printf '<%s>\n' $@
+       print -nr -- '= qs '; pfn "$qs"
+       print -nr -- '=nqs '; pfn "$nqs"
+       print -nr -- '= qk '; pfn "$qk"
+       print -nr -- '=nqk '; pfn "$nqk"
+       print -nr -- '~ qs '; pfn "$*"
+       print -nr -- '~nqs '; pfn $*
+       print -nr -- '~ qk '; pfn "$@"
+       print -nr -- '~nqk '; pfn $@
 expected-stdout:
        = qs <spacedivdedargument
        here>
@@ -3836,21 +4402,22 @@ name: IFS-subst-4-4
 description:
        extended testsuite based on problem by mikeserv
 stdin:
+       pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
        a='space divded  argument
        here'
        IFS=\ ; set -- $a; IFS=
        qs="$*"
-       printf '= qs '; printf '<%s>\n' "$qs"
-       printf '~ qs '; printf '<%s>\n' "$*"
+       print -nr -- '= qs '; pfn "$qs"
+       print -nr -- '~ qs '; pfn "$*"
        nqs=$*
-       printf '=nqs '; printf '<%s>\n' "$nqs"
-       printf '~nqs '; printf '<%s>\n' $*
+       print -nr -- '=nqs '; pfn "$nqs"
+       print -nr -- '~nqs '; pfn $*
        qk="$@"
-       printf '= qk '; printf '<%s>\n' "$qk"
-       printf '~ qk '; printf '<%s>\n' "$@"
+       print -nr -- '= qk '; pfn "$qk"
+       print -nr -- '~ qk '; pfn "$@"
        nqk=$@
-       printf '=nqk '; printf '<%s>\n' "$nqk"
-       printf '~nqk '; printf '<%s>\n' $@
+       print -nr -- '=nqk '; pfn "$nqk"
+       print -nr -- '~nqk '; pfn $@
 expected-stdout:
        = qs <spacedivdedargument
        here>
@@ -3879,22 +4446,23 @@ name: IFS-subst-4-4p
 description:
        extended testsuite based on problem by mikeserv
 stdin:
+       pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
        a='space divded  argument
        here'
        IFS=\ ; set -- $a; IFS=
        unset v
        qs=${v:-"$*"}
-       printf '= qs '; printf '<%s>\n' "$qs"
-       printf '~ qs '; printf '<%s>\n' ${v:-"$*"}
+       print -nr -- '= qs '; pfn "$qs"
+       print -nr -- '~ qs '; pfn ${v:-"$*"}
        nqs=${v:-$*}
-       printf '=nqs '; printf '<%s>\n' "$nqs"
-       printf '~nqs '; printf '<%s>\n' ${v:-$*}
+       print -nr -- '=nqs '; pfn "$nqs"
+       print -nr -- '~nqs '; pfn ${v:-$*}
        qk=${v:-"$@"}
-       printf '= qk '; printf '<%s>\n' "$qk"
-       printf '~ qk '; printf '<%s>\n' ${v:-"$@"}
+       print -nr -- '= qk '; pfn "$qk"
+       print -nr -- '~ qk '; pfn ${v:-"$@"}
        nqk=${v:-$@}
-       printf '=nqk '; printf '<%s>\n' "$nqk"
-       printf '~nqk '; printf '<%s>\n' ${v:-$@}
+       print -nr -- '=nqk '; pfn "$nqk"
+       print -nr -- '~nqk '; pfn ${v:-$@}
 expected-stdout:
        = qs <spacedivdedargument
        here>
@@ -3923,21 +4491,22 @@ name: IFS-subst-4-5
 description:
        extended testsuite based on problem by mikeserv
 stdin:
+       pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
        a='space divded  argument
        here'
        IFS=\ ; set -- $a; IFS=,
        qs="$*"
-       printf '= qs '; printf '<%s>\n' "$qs"
-       printf '~ qs '; printf '<%s>\n' "$*"
+       print -nr -- '= qs '; pfn "$qs"
+       print -nr -- '~ qs '; pfn "$*"
        nqs=$*
-       printf '=nqs '; printf '<%s>\n' "$nqs"
-       printf '~nqs '; printf '<%s>\n' $*
+       print -nr -- '=nqs '; pfn "$nqs"
+       print -nr -- '~nqs '; pfn $*
        qk="$@"
-       printf '= qk '; printf '<%s>\n' "$qk"
-       printf '~ qk '; printf '<%s>\n' "$@"
+       print -nr -- '= qk '; pfn "$qk"
+       print -nr -- '~ qk '; pfn "$@"
        nqk=$@
-       printf '=nqk '; printf '<%s>\n' "$nqk"
-       printf '~nqk '; printf '<%s>\n' $@
+       print -nr -- '=nqk '; pfn "$nqk"
+       print -nr -- '~nqk '; pfn $@
 expected-stdout:
        = qs <space,divded,argument
        here>
@@ -3966,22 +4535,23 @@ name: IFS-subst-4-5p
 description:
        extended testsuite based on problem by mikeserv
 stdin:
+       pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; }
        a='space divded  argument
        here'
        IFS=\ ; set -- $a; IFS=,
        unset v
        qs=${v:-"$*"}
-       printf '= qs '; printf '<%s>\n' "$qs"
-       printf '~ qs '; printf '<%s>\n' ${v:-"$*"}
+       print -nr -- '= qs '; pfn "$qs"
+       print -nr -- '~ qs '; pfn ${v:-"$*"}
        nqs=${v:-$*}
-       printf '=nqs '; printf '<%s>\n' "$nqs"
-       printf '~nqs '; printf '<%s>\n' ${v:-$*}
+       print -nr -- '=nqs '; pfn "$nqs"
+       print -nr -- '~nqs '; pfn ${v:-$*}
        qk=${v:-"$@"}
-       printf '= qk '; printf '<%s>\n' "$qk"
-       printf '~ qk '; printf '<%s>\n' ${v:-"$@"}
+       print -nr -- '= qk '; pfn "$qk"
+       print -nr -- '~ qk '; pfn ${v:-"$@"}
        nqk=${v:-$@}
-       printf '=nqk '; printf '<%s>\n' "$nqk"
-       printf '~nqk '; printf '<%s>\n' ${v:-$@}
+       print -nr -- '=nqk '; pfn "$nqk"
+       print -nr -- '~nqk '; pfn ${v:-$@}
 expected-stdout:
        = qs <space,divded,argument
        here>
@@ -4020,38 +4590,55 @@ description:
        'emulate sh' zsh has extra fields in
        - a5ins (IFS_NWS unquoted $*)
        - b5ins, matching mksh’s
+       !!WARNING!! more to come: http://austingroupbugs.net/view.php?id=888
 stdin:
-       "$__progname" -c 'IFS=; set -- "" 2 ""; printf "[%s]\n" $*; x=$*; printf "<%s>\n" "$x"'
+       "$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
+               IFS=; set -- "" 2 ""; pfb $*; x=$*; pfn "$x"'
        echo '=a1zns'
-       "$__progname" -c 'IFS=; set -- "" 2 ""; printf "[%s]\n" "$*"; x="$*"; printf "<%s>\n" "$x"'
+       "$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
+               IFS=; set -- "" 2 ""; pfb "$*"; x="$*"; pfn "$x"'
        echo '=a2zqs'
-       "$__progname" -c 'IFS=; set -- "" 2 ""; printf "[%s]\n" $@; x=$@; printf "<%s>\n" "$x"'
+       "$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
+               IFS=; set -- "" 2 ""; pfb $@; x=$@; pfn "$x"'
        echo '=a3zna'
-       "$__progname" -c 'IFS=; set -- "" 2 ""; printf "[%s]\n" "$@"; x="$@"; printf "<%s>\n" "$x"'
+       "$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
+               IFS=; set -- "" 2 ""; pfb "$@"; x="$@"; pfn "$x"'
        echo '=a4zqa'
-       "$__progname" -c 'IFS=,; set -- "" 2 ""; printf "[%s]\n" $*; x=$*; printf "<%s>\n" "$x"'
+       "$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
+               IFS=,; set -- "" 2 ""; pfb $*; x=$*; pfn "$x"'
        echo '=a5ins'
-       "$__progname" -c 'IFS=,; set -- "" 2 ""; printf "[%s]\n" "$*"; x="$*"; printf "<%s>\n" "$x"'
+       "$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
+               IFS=,; set -- "" 2 ""; pfb "$*"; x="$*"; pfn "$x"'
        echo '=a6iqs'
-       "$__progname" -c 'IFS=,; set -- "" 2 ""; printf "[%s]\n" $@; x=$@; printf "<%s>\n" "$x"'
+       "$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
+               IFS=,; set -- "" 2 ""; pfb $@; x=$@; pfn "$x"'
        echo '=a7ina'
-       "$__progname" -c 'IFS=,; set -- "" 2 ""; printf "[%s]\n" "$@"; x="$@"; printf "<%s>\n" "$x"'
+       "$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
+               IFS=,; set -- "" 2 ""; pfb "$@"; x="$@"; pfn "$x"'
        echo '=a8iqa'
-       "$__progname" -c 'IFS=; set -- A B "" "" C; printf "[%s]\n" $*; x=$*; printf "<%s>\n" "$x"'
+       "$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
+               IFS=; set -- A B "" "" C; pfb $*; x=$*; pfn "$x"'
        echo '=b1zns'
-       "$__progname" -c 'IFS=; set -- A B "" "" C; printf "[%s]\n" "$*"; x="$*"; printf "<%s>\n" "$x"'
+       "$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
+               IFS=; set -- A B "" "" C; pfb "$*"; x="$*"; pfn "$x"'
        echo '=b2zqs'
-       "$__progname" -c 'IFS=; set -- A B "" "" C; printf "[%s]\n" $@; x=$@; printf "<%s>\n" "$x"'
+       "$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
+               IFS=; set -- A B "" "" C; pfb $@; x=$@; pfn "$x"'
        echo '=b3zna'
-       "$__progname" -c 'IFS=; set -- A B "" "" C; printf "[%s]\n" "$@"; x="$@"; printf "<%s>\n" "$x"'
+       "$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
+               IFS=; set -- A B "" "" C; pfb "$@"; x="$@"; pfn "$x"'
        echo '=b4zqa'
-       "$__progname" -c 'IFS=,; set -- A B "" "" C; printf "[%s]\n" $*; x=$*; printf "<%s>\n" "$x"'
+       "$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
+               IFS=,; set -- A B "" "" C; pfb $*; x=$*; pfn "$x"'
        echo '=b5ins'
-       "$__progname" -c 'IFS=,; set -- A B "" "" C; printf "[%s]\n" "$*"; x="$*"; printf "<%s>\n" "$x"'
+       "$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
+               IFS=,; set -- A B "" "" C; pfb "$*"; x="$*"; pfn "$x"'
        echo '=b6iqs'
-       "$__progname" -c 'IFS=,; set -- A B "" "" C; printf "[%s]\n" $@; x=$@; printf "<%s>\n" "$x"'
+       "$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
+               IFS=,; set -- A B "" "" C; pfb $@; x=$@; pfn "$x"'
        echo '=b7ina'
-       "$__progname" -c 'IFS=,; set -- A B "" "" C; printf "[%s]\n" "$@"; x="$@"; printf "<%s>\n" "$x"'
+       "$__progname" -c 'pfb() { for s_arg in "$@"; do print -r -- "[$s_arg]"; done; }; pfn() { for s_arg in "$@"; do print -r -- "<$s_arg>"; done; };
+               IFS=,; set -- A B "" "" C; pfb "$@"; x="$@"; pfn "$x"'
        echo '=b8iqa'
 expected-stdout:
        [2]
@@ -4127,13 +4714,86 @@ expected-stdout:
        <A B   C>
        =b8iqa
 ---
+name: IFS-subst-6
+description:
+       Regression wrt. vector expansion in trim
+stdin:
+       showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
+       IFS=
+       x=abc
+       set -- a b
+       showargs ${x#$*}
+expected-stdout:
+       <c> .
+---
+name: IFS-subst-7
+description:
+       ksh93 bug wrt. vector expansion in trim
+stdin:
+       showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
+       IFS="*"
+       a=abcd
+       set -- '' c
+       showargs "$*" ${a##"$*"}
+expected-stdout:
+       <*c> <abcd> .
+---
+name: IFS-subst-8
+description:
+       http://austingroupbugs.net/view.php?id=221
+stdin:
+       n() { echo "$#"; }; n "${foo-$@}"
+expected-stdout:
+       1
+---
+name: IFS-subst-9
+description:
+       Scalar context for $*/$@ in [[ and case
+stdin:
+       "$__progname" -c 'IFS=; set a b; [[ $* = "$1$2" ]]; echo 1 $?' sh a b
+       "$__progname" -c 'IFS=; [[ $* = ab ]]; echo 2 "$?"' sh a b
+       "$__progname" -c 'IFS=; [[ "$*" = ab ]]; echo 3 "$?"' sh a b
+       "$__progname" -c 'IFS=; [[ $* = a ]]; echo 4 "$?"' sh a b
+       "$__progname" -c 'IFS=; [[ "$*" = a ]]; echo 5 "$?"' sh a b
+       "$__progname" -c 'IFS=; [[ "$@" = a ]]; echo 6 "$?"' sh a b
+       "$__progname" -c 'IFS=; case "$@" in a) echo 7 a;; ab) echo 7 b;; a\ b) echo 7 ok;; esac' sh a b
+       "$__progname" -c 'IFS=; case $* in a) echo 8 a;; ab) echo 8 ok;; esac' sh a b
+       "$__progname" -c 'pfsp() { for s_arg in "$@"; do print -nr -- "<$s_arg> "; done; print .; }; IFS=; star=$* at="$@"; pfsp 9 "$star" "$at"' sh a b
+expected-stdout:
+       1 0
+       2 0
+       3 0
+       4 1
+       5 1
+       6 1
+       7 ok
+       8 ok
+       <9> <ab> <a b> .
+---
+name: IFS-subst-10
+description:
+       Scalar context in ${var=$subst}
+stdin:
+       showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
+       set -- one "two three" four
+       unset -v var
+       save_IFS=$IFS
+       IFS=
+       set -- ${var=$*}
+       IFS=$save_IFS
+       echo "var=$var"
+       showargs "$@"
+expected-stdout:
+       var=onetwo threefour
+       <onetwo threefour> .
+---
 name: IFS-arith-1
 description:
        http://austingroupbugs.net/view.php?id=832
 stdin:
        ${ZSH_VERSION+false} || emulate sh
        ${BASH_VERSION+set -o posix}
-       showargs() { for x in "$@"; do echo -n "<$x> "; done; echo .; }
+       showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
        IFS=0
        showargs $((1230456))
 expected-stdout:
@@ -4346,11 +5006,25 @@ expected-stdout:
        64
        64
 ---
+name: integer-base-8
+description:
+       Check that base-36 works (full span)
+stdin:
+       echo 1:$((36#109AZ)).
+       typeset -i36 x=1691675
+       echo 2:$x.
+       typeset -Uui36 x
+       echo 3:$x.
+expected-stdout:
+       1:1691675.
+       2:36#109az.
+       3:36#109AZ.
+---
 name: integer-base-check-flat
 description:
        Check behaviour does not match POSuX (except if set -o posix),
        because a not type-safe scripting language has *no* business
-       interpreting the string "010" as octal numer eight (dangerous).
+       interpreting the string "010" as octal number eight (dangerous).
 stdin:
        echo 1 "$("$__progname" -c 'echo :$((10))/$((010)),$((0x10)):')" .
        echo 2 "$("$__progname" -o posix -c 'echo :$((10))/$((010)),$((0x10)):')" .
@@ -4362,11 +5036,11 @@ expected-stdout:
 ---
 name: integer-base-check-numeric-from
 description:
-       Check behaviour for base one to 36, and that 37 errors out
+       Check behaviour for base one to 36, and that 37 degrades to 10
 stdin:
        echo 1:$((1#1))0.
        i=1
-       while (( ++i <= 36 )); do
+       while (( ++i <= 37 )); do
                eval 'echo '$i':$(('$i'#10)).'
        done
        echo 37:$($__progname -c 'echo $((37#10))').$?:
@@ -4407,13 +5081,12 @@ expected-stdout:
        34:34.
        35:35.
        36:36.
-       37:.0:
-expected-stderr-pattern:
-       /.*bad number '37#10'/
+       37:10.
+       37:10.0:
 ---
 name: integer-base-check-numeric-to
 description:
-       Check behaviour for base one to 36, and that 37 errors out
+       Check behaviour for base one to 36, and that 37 degrades to 10
 stdin:
        i=0
        while (( ++i <= 37 )); do
@@ -4458,9 +5131,7 @@ expected-stdout:
        34:34#1U.64.
        35:35#1T.64.
        36:36#1S.64.
-       37:36#1S.64.
-expected-stderr-pattern:
-       /.*bad integer base: 37/
+       37:64.64.
 ---
 name: integer-arithmetic-span
 description:
@@ -4610,6 +5281,24 @@ expected-stdout:
        line <6>
 expected-exit: 1
 ---
+name: lineno-eval-alias
+description:
+       Check if LINENO is trapped in eval and aliases
+stdin:
+       ${ZSH_VERSION+false} || emulate sh; echo $LINENO
+       echo $LINENO
+       eval '  echo $LINENO
+               echo $LINENO
+               echo $LINENO'
+       echo $LINENO
+expected-stdout:
+       1
+       2
+       3
+       3
+       3
+       6
+---
 name: unknown-trap
 description:
        Ensure unknown traps are not a syntax error
@@ -4627,7 +5316,7 @@ expected-stdout:
        PROG: trap: bad signal 'UNKNOWNSIGNAL'
        PROG: trap: bad signal '999999'
        PROG: trap: bad signal 'FNORD'
-       = 3
+       = 1
        trap 2 executed
 ---
 name: read-IFS-1
@@ -4646,6 +5335,66 @@ expected-stdout:
        1a:
        2: x[A B]
 ---
+name: read-IFS-2
+description:
+       Complex tests, IFS either colon (IFS-NWS) or backslash (tricky)
+stdin:
+       n=0
+       showargs() { print -nr "$1"; shift; for s_arg in "$@"; do print -nr -- " [$s_arg]"; done; print; }
+       (IFS=\\ a=\<\\\>; showargs 3 $a)
+       (IFS=: b=\<:\>; showargs 4 $b)
+       print -r '<\>' | (IFS=\\ read f g; showargs 5 "$f" "$g")
+       print -r '<\\>' | (IFS=\\ read f g; showargs 6 "$f" "$g")
+       print '<\\\n>' | (IFS=\\ read f g; showargs 7 "$f" "$g")
+       print -r '<\>' | (IFS=\\ read f; showargs 8 "$f")
+       print -r '<\\>' | (IFS=\\ read f; showargs 9 "$f")
+       print '<\\\n>' | (IFS=\\ read f; showargs 10 "$f")
+       print -r '<\>' | (IFS=\\ read -r f g; showargs 11 "$f" "$g")
+       print -r '<\\>' | (IFS=\\ read -r f g; showargs 12 "$f" "$g")
+       print '<\\\n>' | (IFS=\\ read -r f g; showargs 13 "$f" "$g")
+       print -r '<\>' | (IFS=\\ read -r f; showargs 14 "$f")
+       print -r '<\\>' | (IFS=\\ read -r f; showargs 15 "$f")
+       print '<\\\n>' | (IFS=\\ read -r f; showargs 16 "$f")
+       print -r '<:>' | (IFS=: read f g; showargs 17 "$f" "$g")
+       print -r '<::>' | (IFS=: read f g; showargs 18 "$f" "$g")
+       print '<:\n>' | (IFS=: read f g; showargs 19 "$f" "$g")
+       print -r '<:>' | (IFS=: read f; showargs 20 "$f")
+       print -r '<::>' | (IFS=: read f; showargs 21 "$f")
+       print '<:\n>' | (IFS=: read f; showargs 22 "$f")
+       print -r '<:>' | (IFS=: read -r f g; showargs 23 "$f" "$g")
+       print -r '<::>' | (IFS=: read -r f g; showargs 24 "$f" "$g")
+       print '<:\n>' | (IFS=: read -r f g; showargs 25 "$f" "$g")
+       print -r '<:>' | (IFS=: read -r f; showargs 26 "$f")
+       print -r '<::>' | (IFS=: read -r f; showargs 27 "$f")
+       print '<:\n>' | (IFS=: read -r f; showargs 28 "$f")
+expected-stdout:
+       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 [<]
+---
 name: read-ksh-1
 description:
        If no var specified, REPLY is used
@@ -4749,8 +5498,8 @@ description:
        need to be moved out of the switch to before findcom() is
        called - I don't know what this will break.
 stdin:
-       : ${PWD:-`pwd 2> /dev/null`}
-       : ${PWD:?"PWD not set - can't do test"}
+       : "${PWD:-`pwd 2> /dev/null`}"
+       : "${PWD:?"PWD not set - cannot do test"}"
        mkdir Y
        cat > Y/xxxscript << EOF
        #!/bin/sh
@@ -5288,7 +6037,7 @@ description:
 stdin:
        print '#!'"$__progname"'\nunset RANDOM\nexport | while IFS= read -r' \
            'RANDOM; do eval '\''print -r -- "$RANDOM=$'\''"$RANDOM"'\'\"\'\; \
-           done >env; chmod +x env; PATH=.:$PATH
+           done >env; chmod +x env; PATH=.$PATHSEP$PATH
        foo=bar
        readonly foo
        foo=stuff env | grep '^foo'
@@ -5671,7 +6420,7 @@ name: regression-62
 description:
        Check if test -nt/-ot succeeds if second(first) file is missing.
 stdin:
-       touch a
+       :>a
        test a -nt b && echo nt OK || echo nt BAD
        test b -ot a && echo ot OK || echo ot BAD
 expected-stdout:
@@ -5818,6 +6567,106 @@ expected-stdout:
        ac_space=' '
        ac_newline=$'\n'
 ---
+name: regression-67
+description:
+       Check that we can both break and use source on the same line
+stdin:
+       for s in s; do break; done; print -s s
+---
+name: regression-68
+description:
+       Check that all common arithmetic operators work as expected
+stdin:
+       echo 1 $(( a = 5 )) .
+       echo 2 $(( ++a )) , $(( a++ )) , $(( a )) .
+       echo 3 $(( --a )) , $(( a-- )) , $(( a )) .
+       echo 4 $(( a == 5 )) , $(( a == 6 )) .
+       echo 5 $(( a != 5 )) , $(( a != 6 )) .
+       echo 6 $(( a *= 3 )) .
+       echo 7 $(( a /= 5 )) .
+       echo 8 $(( a %= 2 )) .
+       echo 9 $(( a += 9 )) .
+       echo 10 $(( a -= 4 )) .
+       echo 11 $(( a <<= 1 )) .
+       echo 12 $(( a >>= 1 )) .
+       echo 13 $(( a &= 4 )) .
+       echo 14 $(( a ^= a )) .
+       echo 15 $(( a |= 5 )) .
+       echo 16 $(( 5 << 1 )) .
+       echo 17 $(( 5 >> 1 )) .
+       echo 18 $(( 5 <= 6 )) , $(( 5 <= 5 )) , $(( 5 <= 4 )) .
+       echo 19 $(( 5 >= 6 )) , $(( 5 >= 5 )) , $(( 5 >= 4 )) .
+       echo 20 $(( 5 < 6 )) , $(( 5 < 5 )) , $(( 5 < 4 )) .
+       echo 21 $(( 5 > 6 )) , $(( 5 > 5 )) , $(( 5 > 4 )) .
+       echo 22 $(( 0 && 0 )) , $(( 0 && 1 )) , $(( 1 && 0 )) , $(( 1 && 1 )) .
+       echo 23 $(( 0 || 0 )) , $(( 0 || 1 )) , $(( 1 || 0 )) , $(( 1 || 1 )) .
+       echo 24 $(( 5 * 3 )) .
+       echo 25 $(( 7 / 2 )) .
+       echo 26 $(( 5 % 5 )) , $(( 5 % 4 )) , $(( 5 % 1 )) , $(( 5 % -1 )) , $(( 5 % -2 )) .
+       echo 27 $(( 5 + 2 )) , $(( 5 + 0 )) , $(( 5 + -2 )) .
+       echo 28 $(( 5 - 2 )) , $(( 5 - 0 )) , $(( 5 - -2 )) .
+       echo 29 $(( 6 & 4 )) , $(( 6 & 8 )) .
+       echo 30 $(( 4 ^ 2 )) , $(( 4 ^ 4 )) .
+       echo 31 $(( 4 | 2 )) , $(( 4 | 4 )) , $(( 4 | 0 )) .
+       echo 32 $(( 0 ? 1 : 2 )) , $(( 3 ? 4 : 5 )) .
+       echo 33 $(( 5 , 2 , 3 )) .
+       echo 34 $(( ~0 )) , $(( ~1 )) , $(( ~~1 )) , $(( ~~2 )) .
+       echo 35 $(( !0 )) , $(( !1 )) , $(( !!1 )) , $(( !!2 )) .
+       echo 36 $(( (5) )) .
+expected-stdout:
+       1 5 .
+       2 6 , 6 , 7 .
+       3 6 , 6 , 5 .
+       4 1 , 0 .
+       5 0 , 1 .
+       6 15 .
+       7 3 .
+       8 1 .
+       9 10 .
+       10 6 .
+       11 12 .
+       12 6 .
+       13 4 .
+       14 0 .
+       15 5 .
+       16 10 .
+       17 2 .
+       18 1 , 1 , 0 .
+       19 0 , 1 , 1 .
+       20 1 , 0 , 0 .
+       21 0 , 0 , 1 .
+       22 0 , 0 , 0 , 1 .
+       23 0 , 1 , 1 , 1 .
+       24 15 .
+       25 3 .
+       26 0 , 1 , 0 , 0 , 1 .
+       27 7 , 5 , 3 .
+       28 3 , 5 , 7 .
+       29 4 , 0 .
+       30 6 , 0 .
+       31 6 , 4 , 4 .
+       32 2 , 4 .
+       33 3 .
+       34 -1 , -2 , 1 , 2 .
+       35 1 , 0 , 1 , 1 .
+       36 5 .
+---
+name: regression-69
+description:
+       Check that all non-lksh arithmetic operators work as expected
+category: shell:legacy-no
+stdin:
+       a=5 b=0x80000005
+       echo 1 $(( a ^<= 1 )) , $(( b ^<= 1 )) .
+       echo 2 $(( a ^>= 2 )) , $(( b ^>= 2 )) .
+       echo 3 $(( 5 ^< 1 )) .
+       echo 4 $(( 5 ^> 1 )) .
+expected-stdout:
+       1 10 , 11 .
+       2 -2147483646 , -1073741822 .
+       3 10 .
+       4 -2147483646 .
+---
 name: readonly-0
 description:
        Ensure readonly is honoured for assignments and unset
@@ -5994,7 +6843,7 @@ description:
 stdin:
        print '#!'"$__progname"'\nunset RANDOM\nexport | while IFS= read -r' \
            'RANDOM; do eval '\''print -r -- "$RANDOM=$'\''"$RANDOM"'\'\"\'\; \
-           done >env; chmod +x env; PATH=.:$PATH
+           done >env; chmod +x env; PATH=.$PATHSEP$PATH
        FOO=bar exec env
 expected-stdout-pattern:
        /(^|.*\n)FOO=bar\n/
@@ -6006,7 +6855,7 @@ description:
 stdin:
        print '#!'"$__progname"'\nunset RANDOM\nexport | while IFS= read -r' \
            'RANDOM; do eval '\''print -r -- "$RANDOM=$'\''"$RANDOM"'\'\"\'\; \
-           done >env; chmod +x env; PATH=.:$PATH
+           done >env; chmod +x env; PATH=.$PATHSEP$PATH
        env >bar1
        FOO=bar exec; env >bar2
        cmp -s bar1 bar2
@@ -6066,6 +6915,41 @@ expected-stderr-pattern:
        /bad substitution/
 expected-exit: 1
 ---
+name: xxx-variable-syntax-4
+description:
+       Not all kinds of trims are currently impossible, check those who do
+stdin:
+       foo() {
+               echo "<$*> X${*:+ }X"
+       }
+       foo a b
+       foo "" c
+       foo ""
+       foo "" ""
+       IFS=:
+       foo a b
+       foo "" c
+       foo ""
+       foo "" ""
+       IFS=
+       foo a b
+       foo "" c
+       foo ""
+       foo "" ""
+expected-stdout:
+       <a b> X X
+       < c> X X
+       <> XX
+       < > X X
+       <a:b> X X
+       <:c> X X
+       <> XX
+       <:> X X
+       <ab> X X
+       <c> X X
+       <> XX
+       <> XX
+---
 name: xxx-substitution-eval-order
 description:
        Check order of evaluation of expressions
@@ -6191,18 +7075,44 @@ name: xxx-param-subst-qmark-1
 description:
        Check suppresion of error message with null string.  According to
        POSIX, it shouldn't print the error as 'word' isn't ommitted.
-       ksh88/93, Solaris /bin/sh and /usr/xpg4/bin/sh all print the error,
-       that's why the condition is reversed.
+       ksh88/93, Solaris /bin/sh and /usr/xpg4/bin/sh all print the error.
 stdin:
        unset foo
        x=
        echo x${foo?$x}
 expected-exit: 1
-# POSIX
-#expected-fail: yes
-#expected-stderr-pattern: !/not set/
-# common use
-expected-stderr-pattern: /parameter null or not set/
+expected-stderr-pattern: !/not set/
+---
+name: xxx-param-subst-qmark-namespec
+description:
+       Check special names are output correctly
+stdin:
+       doit() {
+               "$__progname" -c "$@" >o1 2>o2
+               rv=$?
+               echo RETVAL: $rv
+               sed -e "s\ 1^${__progname%.exe}\.*e*x*e*: \ 1PROG: \ 1" -e 's/^/STDOUT: /g' <o1
+               sed -e "s\ 1^${__progname%.exe}\.*e*x*e*: \ 1PROG: \ 1" -e 's/^/STDERR: /g' <o2
+       }
+       doit 'echo ${1x}'
+       doit 'echo "${1x}"'
+       doit 'echo ${1?}'
+       doit 'echo ${19?}'
+       doit 'echo ${!:?}'
+       doit -u 'echo ${*:?}' foo ""
+expected-stdout:
+       RETVAL: 1
+       STDERR: PROG: ${1x}: bad substitution
+       RETVAL: 1
+       STDERR: PROG: ${1x}: bad substitution
+       RETVAL: 1
+       STDERR: PROG: 1: parameter null or not set
+       RETVAL: 1
+       STDERR: PROG: 19: parameter null or not set
+       RETVAL: 1
+       STDERR: PROG: !: parameter null or not set
+       RETVAL: 1
+       STDERR: foo: ${*:?}: bad substitution
 ---
 name: xxx-param-_-1
 # fails due to weirdness of execv stuff
@@ -6218,18 +7128,35 @@ description:
 env-setup: !HOME=/sweet!
 stdin:
        echo ${A=a=}~ b=~ c=d~ ~
-       set +o braceexpand
-       unset A
+       export e=~ f=d~
+       command command export g=~ h=d~
+       echo ". $e . $f ."
+       echo ". $g . $h ."
+       set -o posix
+       unset A e f g h
        echo ${A=a=}~ b=~ c=d~ ~
+       export e=~ f=d~
+       command command export g=~ h=d~
+       echo ". $e . $f ."
+       echo ". $g . $h ."
 expected-stdout:
        a=/sweet b=/sweet c=d~ /sweet
+       . /sweet . d~ .
+       . /sweet . d~ .
        a=~ b=~ c=d~ /sweet
+       . /sweet . d~ .
+       . /sweet . d~ .
 ---
 name: tilde-expand-2
 description:
        Check tilde expansion works
 env-setup: !HOME=/sweet!
 stdin:
+       :>'c=a'
+       typeset c=[ab]
+       :>'d=a'
+       x=typeset; $x d=[ab]
+       echo "<$c>" "<$d>"
        wd=$PWD
        cd /
        plus=$(print -r -- ~+)
@@ -6239,10 +7166,106 @@ stdin:
        [[ $minus = "$wd" ]]; echo two $? .
        [[ $nix = /sweet ]]; echo nix $? .
 expected-stdout:
+       <[ab]> <a>
        one 0 .
        two 0 .
        nix 0 .
 ---
+name: tilde-expand-3
+description:
+       Check mostly Austin 351 stuff
+stdin:
+       showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
+       set "1 b=2" "3 d=4"
+       export a=$1 \c=$2
+       showargs 1 "$a" "$b" "$c" "$d"
+       unset a b c d
+       HOME=/tmp
+       export \a=~ b=~
+       command export c=~
+       builtin export d=~
+       \\builtin export e=~
+       showargs 2 "$a" "$b" "$c" "$d" "$e" ksh
+       unset a b c d e
+       set -o posix
+       export \a=~ b=~
+       command export c=~
+       builtin export d=~
+       \\builtin export e=~
+       showargs 3 "$a" "$b" "$c" "$d" "$e" posix
+       unset a b c d e
+       set +o posix
+       export a=$1
+       showargs 4 "$a" "$b" ksh
+       unset a b
+       showargs 5 a=$1 ksh
+       export \a=$1
+       showargs 6 "$a" "$b" ksh
+       unset a b
+       set -o posix
+       export a=$1
+       showargs 7 "$a" "$b" posix
+       unset a b
+       showargs 8 a=$1 posix
+       export \a=$1
+       showargs 9 "$a" "$b" posix
+       unset a b
+       set +o posix
+       command echo 10 ksh a=~
+       command command export a=~
+       showargs 11 "$a"
+       unset a
+       set -o posix
+       command echo 12 posix a=~
+       command command export a=~
+       showargs 13 "$a"
+       unset a
+       # unspecified whether /tmp or ~
+       var=export; command $var a=~
+       showargs 14 "$a"
+       echo 'echo "<$foo>"' >bar
+       "$__progname" bar
+       var=foo
+       export $var=1
+       "$__progname" bar
+       export $var=~
+       "$__progname" bar
+       # unspecified
+       command -- export a=~
+       showargs 18 "$a"
+       set -A bla
+       typeset bla[1]=~:~
+       global gbl=~ g2=$1
+       local lcl=~ l2=$1
+       readonly ro=~ r2=$1
+       showargs 19 "${bla[1]}" a=~ "$gbl" "$lcl" "$ro" "$g2" "$l2" "$r2"
+       set +o posix
+       echo "20 some arbitrary stuff "=~
+       set -o posix
+       echo "21 some arbitrary stuff "=~
+expected-stdout:
+       <1> <1 b=2> <> <3> <4> .
+       <2> </tmp> </tmp> </tmp> </tmp> </tmp> <ksh> .
+       <3> <~> </tmp> </tmp> <~> </tmp> <posix> .
+       <4> <1 b=2> <> <ksh> .
+       <5> <a=1> <b=2> <ksh> .
+       <6> <1> <2> <ksh> .
+       <7> <1 b=2> <> <posix> .
+       <8> <a=1> <b=2> <posix> .
+       <9> <1> <2> <posix> .
+       10 ksh a=/tmp
+       <11> </tmp> .
+       12 posix a=~
+       <13> </tmp> .
+       <14> <~> .
+       <>
+       <1>
+       <~>
+       <18> <~> .
+       <19> </tmp:/tmp> <a=~> </tmp> </tmp> </tmp> <1 b=2> <1 b=2> <1 b=2> .
+       20 some arbitrary stuff =/tmp
+       21 some arbitrary stuff =~
+---
 name: exit-err-1
 description:
        Check some "exit on error" conditions
@@ -6250,7 +7273,7 @@ stdin:
        print '#!'"$__progname"'\nexec "$1"' >env
        print '#!'"$__progname"'\nexit 1' >false
        chmod +x env false
-       PATH=.:$PATH
+       PATH=.$PATHSEP$PATH
        set -ex
        env false && echo something
        echo END
@@ -6268,7 +7291,7 @@ stdin:
        print '#!'"$__progname"'\nexit 1' >false
        print '#!'"$__progname"'\nexit 0' >true
        chmod +x env false
-       PATH=.:$PATH
+       PATH=.$PATHSEP$PATH
        set -ex
        if env true; then
                env false && echo something
@@ -6380,6 +7403,19 @@ stdin:
        db_go
        exit 0
 ---
+name: exit-err-9
+description:
+       "set -e" versus bang pipelines
+stdin:
+       set -e
+       ! false | false
+       echo 1 ok
+       ! false && false
+       echo 2 wrong
+expected-stdout:
+       1 ok
+expected-exit: 1
+---
 name: exit-enoent-1
 description:
        SUSv4 says that the shell should exit with 126/127 in some situations
@@ -6602,7 +7638,7 @@ expected-stdout:
        After error 2
        Exit trap
 expected-stderr-pattern:
-       /syntax error: 'newline' unexpected/
+       /syntax error: unexpected 'newline'/
 ---
 name: test-stlt-1
 description:
@@ -6712,6 +7748,183 @@ expected-stdout:
        2- 1 1 1 =
        3- 0 0 0 =
 ---
+name: test-varset-1
+description:
+       Test the test -v operator
+stdin:
+       [[ -v a ]]
+       rv=$?; echo $((++i)) $rv
+       a=
+       [[ -v a ]]
+       rv=$?; echo $((++i)) $rv
+       unset a
+       [[ -v a ]]
+       rv=$?; echo $((++i)) $rv
+       a=x
+       [[ -v a ]]
+       rv=$?; echo $((++i)) $rv
+       nameref b=a
+       [[ -v b ]]
+       rv=$?; echo $((++i)) $rv
+       unset a
+       [[ -v b ]]
+       rv=$?; echo $((++i)) $rv
+       x[1]=y
+       [[ -v x ]]
+       rv=$?; echo $((++i)) $rv
+       [[ -v x[0] ]]
+       rv=$?; echo $((++i)) $rv
+       [[ -v x[1] ]]
+       rv=$?; echo $((++i)) $rv
+       [[ -v x[2] ]]
+       rv=$?; echo $((++i)) $rv
+expected-stdout:
+       1 1
+       2 0
+       3 1
+       4 0
+       5 0
+       6 1
+       7 1
+       8 1
+       9 0
+       10 1
+---
+name: test-varset-2
+description:
+       test -v works only on scalars
+stdin:
+       [[ -v x[*] ]]
+       echo ok
+expected-exit: e != 0
+expected-stderr-pattern:
+       /unexpected '\*'/
+---
+name: test-stnze-1
+description:
+       Check that the short form [ $x ] works
+stdin:
+       i=0
+       [ -n $x ]
+       rv=$?; echo $((++i)) $rv
+       [ $x ]
+       rv=$?; echo $((++i)) $rv
+       [ -n "$x" ]
+       rv=$?; echo $((++i)) $rv
+       [ "$x" ]
+       rv=$?; echo $((++i)) $rv
+       x=0
+       [ -n $x ]
+       rv=$?; echo $((++i)) $rv
+       [ $x ]
+       rv=$?; echo $((++i)) $rv
+       [ -n "$x" ]
+       rv=$?; echo $((++i)) $rv
+       [ "$x" ]
+       rv=$?; echo $((++i)) $rv
+       x='1 -a 1 = 2'
+       [ -n $x ]
+       rv=$?; echo $((++i)) $rv
+       [ $x ]
+       rv=$?; echo $((++i)) $rv
+       [ -n "$x" ]
+       rv=$?; echo $((++i)) $rv
+       [ "$x" ]
+       rv=$?; echo $((++i)) $rv
+expected-stdout:
+       1 0
+       2 1
+       3 1
+       4 1
+       5 0
+       6 0
+       7 0
+       8 0
+       9 1
+       10 1
+       11 0
+       12 0
+---
+name: test-stnze-2
+description:
+       Check that the short form [[ $x ]] works (ksh93 extension)
+stdin:
+       i=0
+       [[ -n $x ]]
+       rv=$?; echo $((++i)) $rv
+       [[ $x ]]
+       rv=$?; echo $((++i)) $rv
+       [[ -n "$x" ]]
+       rv=$?; echo $((++i)) $rv
+       [[ "$x" ]]
+       rv=$?; echo $((++i)) $rv
+       x=0
+       [[ -n $x ]]
+       rv=$?; echo $((++i)) $rv
+       [[ $x ]]
+       rv=$?; echo $((++i)) $rv
+       [[ -n "$x" ]]
+       rv=$?; echo $((++i)) $rv
+       [[ "$x" ]]
+       rv=$?; echo $((++i)) $rv
+       x='1 -a 1 = 2'
+       [[ -n $x ]]
+       rv=$?; echo $((++i)) $rv
+       [[ $x ]]
+       rv=$?; echo $((++i)) $rv
+       [[ -n "$x" ]]
+       rv=$?; echo $((++i)) $rv
+       [[ "$x" ]]
+       rv=$?; echo $((++i)) $rv
+expected-stdout:
+       1 1
+       2 1
+       3 1
+       4 1
+       5 0
+       6 0
+       7 0
+       8 0
+       9 0
+       10 0
+       11 0
+       12 0
+---
+name: test-numeq
+description:
+       Check numeric -eq works (R40d regression); spotted by Martijn Dekker
+stdin:
+       tst() {
+               eval "$2"
+               case $? in
+               (0) echo yepp 0 \#"$*" ;;
+               (1) echo nope 1 \#"$*" ;;
+               (2) echo terr 2 \#"$*" ;;
+               (*) echo wtf\? $? \#"$*" ;;
+               esac
+       }
+       tst 1 'test 2 -eq 2'
+       tst 2 'test 2 -eq 2a'
+       tst 3 'test 2 -eq 3'
+       tst 4 'test 2 -ne 2'
+       tst 5 'test 2 -ne 2a'
+       tst 6 'test 2 -ne 3'
+       tst 7 'test \! 2 -eq 2'
+       tst 8 'test \! 2 -eq 2a'
+       tst 9 'test \! 2 -eq 3'
+expected-stdout:
+       yepp 0 #1 test 2 -eq 2
+       terr 2 #2 test 2 -eq 2a
+       nope 1 #3 test 2 -eq 3
+       nope 1 #4 test 2 -ne 2
+       terr 2 #5 test 2 -ne 2a
+       yepp 0 #6 test 2 -ne 3
+       nope 1 #7 test \! 2 -eq 2
+       terr 2 #8 test \! 2 -eq 2a
+       yepp 0 #9 test \! 2 -eq 3
+expected-stderr-pattern:
+       /bad number/
+---
 name: mkshrc-1
 description:
        Check that ~/.mkshrc works correctly.
@@ -6937,11 +8150,11 @@ expected-stderr-pattern:
 ---
 name: typeset-1
 description:
-       Check that global does what typeset is supposed to do
+       Check that typeset -g works correctly
 stdin:
        set -A arrfoo 65
        foo() {
-               global -Uui16 arrfoo[*]
+               typeset -g -Uui16 arrfoo[*]
        }
        echo before ${arrfoo[0]} .
        foo
@@ -6951,7 +8164,7 @@ stdin:
                echo inside before ${arrbar[0]} .
                arrbar[0]=97
                echo inside changed ${arrbar[0]} .
-               global -Uui16 arrbar[*]
+               typeset -g -Uui16 arrbar[*]
                echo inside typeset ${arrbar[0]} .
                arrbar[0]=48
                echo inside changed ${arrbar[0]} .
@@ -6969,6 +8182,24 @@ expected-stdout:
        inside changed 16#30 .
        after 16#30 .
 ---
+name: typeset-2
+description:
+       Check that typeset -p on arrays works correctly
+stdin:
+       set -A x -- a b c
+       echo =
+       typeset -p x
+       echo =
+       typeset -p x[1]
+expected-stdout:
+       =
+       set -A x
+       typeset x[0]=a
+       typeset x[1]=b
+       typeset x[2]=c
+       =
+       typeset x[1]=b
+---
 name: typeset-padding-1
 description:
        Check if left/right justification works as per TFM
@@ -7012,7 +8243,7 @@ stdin:
        set -A anzahl -- foo/*
        echo got ${#anzahl[*]} files
        chmod +x foo/*
-       export PATH=$(pwd)/foo:$PATH
+       export PATH=$(pwd)/foo$PATHSEP$PATH
        "$__progname" -c 'fnord'
        echo =
        "$__progname" -c 'fnord; fnord; fnord; fnord'
@@ -7057,6 +8288,7 @@ description:
        XXX if the OS can already execute them, we lose
        note: cygwin execve(2) doesn't return to us with ENOEXEC, we lose
        note: Ultrix perl5 t4 returns 65280 (exit-code 255) and no text
+       XXX fails when LD_PRELOAD is set with -e and Perl chokes it (ASan)
 need-pass: no
 category: !os:cygwin,!os:msys,!os:ultrix,!os:uwin-nt,!smksh
 env-setup: !FOO=BAR!
@@ -7114,7 +8346,7 @@ description:
        -UMKSH_ASSUME_UTF8 => not expected, but if your OS is old,
         try passing HAVE_SETLOCALE_CTYPE=0 to Build.sh
 need-pass: no
-category: !os:hpux,!os:msys
+category: !os:hpux,!os:msys,!os:os2
 need-ctty: yes
 arguments: !-i!
 env-setup: !PS1=!PS2=!LC_CTYPE=en_US.UTF-8!
@@ -7178,177 +8410,100 @@ expected-stdout:
        2 off
        3 done
 ---
-name: aliases-1
+name: utf8bug-1
 description:
-       Check if built-in shell aliases are okay
-category: !android,!arge
+       Ensure trailing combining characters are not lost
 stdin:
-       alias
-       typeset -f
-expected-stdout:
-       autoload='typeset -fu'
-       functions='typeset -f'
-       hash='alias -t'
-       history='fc -l'
-       integer='typeset -i'
-       local=typeset
-       login='exec login'
-       nameref='typeset -n'
-       nohup='nohup '
-       r='fc -e -'
-       source='PATH=$PATH:. command .'
-       stop='kill -STOP'
-       type='whence -v'
+       set -U
+       a=a
+       b=$'\u0301'
+       x=$a$b
+       print -r -- "<e$x>"
+       x=$a
+       x+=$b
+       print -r -- "<e$x>"
+       b=$'\u0301'b
+       x=$a
+       x+=$b
+       print -r -- "<e$x>"
+expected-stdout:
+       <eá>
+       <eá>
+       <eáb>
 ---
-name: aliases-1-hartz4
+name: aliases-1
 description:
        Check if built-in shell aliases are okay
-category: android,arge
 stdin:
        alias
        typeset -f
 expected-stdout:
-       autoload='typeset -fu'
-       functions='typeset -f'
-       hash='alias -t'
-       history='fc -l'
-       integer='typeset -i'
-       local=typeset
-       login='exec login'
-       nameref='typeset -n'
+       autoload='\\builtin typeset -fu'
+       functions='\\builtin typeset -f'
+       hash='\\builtin alias -t'
+       history='\\builtin fc -l'
+       integer='\\builtin typeset -i'
+       local='\\builtin typeset'
+       login='\\builtin exec login'
+       nameref='\\builtin typeset -n'
        nohup='nohup '
-       r='fc -e -'
-       source='PATH=$PATH:. command .'
-       type='whence -v'
----
-name: aliases-2a
-description:
-       Check if “set -o sh” disables built-in aliases (except a few)
-category: disabled
-arguments: !-o!sh!
-stdin:
-       alias
-       typeset -f
-expected-stdout:
-       integer='typeset -i'
-       local=typeset
----
-name: aliases-3a
-description:
-       Check if running as sh disables built-in aliases (except a few)
-category: disabled
-stdin:
-       cp "$__progname" sh
-       ./sh -c 'alias; typeset -f'
-       rm -f sh
-expected-stdout:
-       integer='typeset -i'
-       local=typeset
+       r='\\builtin fc -e -'
+       type='\\builtin whence -v'
 ---
 name: aliases-2b
 description:
        Check if “set -o sh” does not influence built-in aliases
-category: !android,!arge
 arguments: !-o!sh!
 stdin:
        alias
        typeset -f
 expected-stdout:
-       autoload='typeset -fu'
-       functions='typeset -f'
-       hash='alias -t'
-       history='fc -l'
-       integer='typeset -i'
-       local=typeset
-       login='exec login'
-       nameref='typeset -n'
+       autoload='\\builtin typeset -fu'
+       functions='\\builtin typeset -f'
+       hash='\\builtin alias -t'
+       history='\\builtin fc -l'
+       integer='\\builtin typeset -i'
+       local='\\builtin typeset'
+       login='\\builtin exec login'
+       nameref='\\builtin typeset -n'
        nohup='nohup '
-       r='fc -e -'
-       source='PATH=$PATH:. command .'
-       stop='kill -STOP'
-       type='whence -v'
+       r='\\builtin fc -e -'
+       type='\\builtin whence -v'
 ---
 name: aliases-3b
 description:
        Check if running as sh does not influence built-in aliases
-category: !android,!arge
 stdin:
        cp "$__progname" sh
        ./sh -c 'alias; typeset -f'
        rm -f sh
 expected-stdout:
-       autoload='typeset -fu'
-       functions='typeset -f'
-       hash='alias -t'
-       history='fc -l'
-       integer='typeset -i'
-       local=typeset
-       login='exec login'
-       nameref='typeset -n'
+       autoload='\\builtin typeset -fu'
+       functions='\\builtin typeset -f'
+       hash='\\builtin alias -t'
+       history='\\builtin fc -l'
+       integer='\\builtin typeset -i'
+       local='\\builtin typeset'
+       login='\\builtin exec login'
+       nameref='\\builtin typeset -n'
        nohup='nohup '
-       r='fc -e -'
-       source='PATH=$PATH:. command .'
-       stop='kill -STOP'
-       type='whence -v'
+       r='\\builtin fc -e -'
+       type='\\builtin whence -v'
 ---
-name: aliases-2b-hartz4
+name: aliases-cmdline
 description:
-       Check if “set -o sh” does not influence built-in aliases
-category: android,arge
-arguments: !-o!sh!
+       Check that aliases work from the command line (Debian #517009)
+       Note that due to the nature of the lexing process, defining
+       aliases in COMSUBs then immediately using them, and things
+       like 'alias foo=bar && foo', still fail.
 stdin:
-       alias
-       typeset -f
+       "$__progname" -c $'alias a="echo OK"\na'
 expected-stdout:
-       autoload='typeset -fu'
-       functions='typeset -f'
-       hash='alias -t'
-       history='fc -l'
-       integer='typeset -i'
-       local=typeset
-       login='exec login'
-       nameref='typeset -n'
-       nohup='nohup '
-       r='fc -e -'
-       source='PATH=$PATH:. command .'
-       type='whence -v'
+       OK
 ---
-name: aliases-3b-hartz4
+name: aliases-funcdef-1
 description:
-       Check if running as sh does not influence built-in aliases
-category: android,arge
-stdin:
-       cp "$__progname" sh
-       ./sh -c 'alias; typeset -f'
-       rm -f sh
-expected-stdout:
-       autoload='typeset -fu'
-       functions='typeset -f'
-       hash='alias -t'
-       history='fc -l'
-       integer='typeset -i'
-       local=typeset
-       login='exec login'
-       nameref='typeset -n'
-       nohup='nohup '
-       r='fc -e -'
-       source='PATH=$PATH:. command .'
-       type='whence -v'
----
-name: aliases-cmdline
-description:
-       Check that aliases work from the command line (Debian #517009)
-       Note that due to the nature of the lexing process, defining
-       aliases in COMSUBs then immediately using them, and things
-       like 'alias foo=bar && foo', still fail.
-stdin:
-       "$__progname" -c $'alias a="echo OK"\na'
-expected-stdout:
-       OK
----
-name: aliases-funcdef-1
-description:
-       Check if POSIX functions take precedences over aliases
+       Check if POSIX functions take precedences over aliases
 stdin:
        alias foo='echo makro'
        foo() {
@@ -7356,7 +8511,7 @@ stdin:
        }
        foo
 expected-stdout:
-       funktion
+       makro
 ---
 name: aliases-funcdef-2
 description:
@@ -7368,7 +8523,7 @@ stdin:
        }
        foo
 expected-stdout:
-       funktion
+       makro
 ---
 name: aliases-funcdef-3
 description:
@@ -7390,8 +8545,8 @@ stdin:
        :|| local() { :; }
        alias local
 expected-stdout:
-       local=typeset
-       local=typeset
+       local='\\builtin typeset'
+       local='\\builtin typeset'
 ---
 name: arrays-1
 description:
@@ -7801,21 +8956,21 @@ expected-stdout:
 name: arrassign-fnc-global
 description:
        Check locality of array access inside a function
-       with the mksh-specific global keyword
+       with the bash4/mksh/yash/zsh typeset -g keyword
 stdin:
        function fn {
-               global x
+               typeset -g x
                x+=(f)
                echo ".fn:${x[0]}.${x[1]}.${x[2]}.${x[3]}:"
        }
        function rfn {
                set -A y
-               global y
+               typeset -g y
                y+=(f)
                echo ".rfn:${y[0]}.${y[1]}.${y[2]}.${y[3]}:"
        }
        function fnr {
-               global z
+               typeset -g z
                set -A z
                z+=(f)
                echo ".fnr:${z[0]}.${z[1]}.${z[2]}.${z[3]}:"
@@ -7953,21 +9108,21 @@ expected-stdout:
 name: strassign-fnc-global
 description:
        Check locality of string access inside a function
-       with the mksh-specific global keyword
+       with the bash4/mksh/yash/zsh typeset -g keyword
 stdin:
        function fn {
-               global x
+               typeset -g x
                x+=f
                echo ".fn:$x:"
        }
        function rfn {
                y=
-               global y
+               typeset -g y
                y+=f
                echo ".rfn:$y:"
        }
        function fnr {
-               global z
+               typeset -g z
                z=
                z+=f
                echo ".fnr:$z:"
@@ -8007,6 +9162,66 @@ expected-stdout:
        .fnr:f:
        .f2r:f:
 ---
+name: unset-fnc-local-ksh
+description:
+       Check that “unset” removes a previous “local”
+       (ksh93 syntax compatible version); apparently,
+       there are shells which fail this?
+stdin:
+       function f {
+               echo f0: $x
+               typeset x
+               echo f1: $x
+               x=fa
+               echo f2: $x
+               unset x
+               echo f3: $x
+               x=fb
+               echo f4: $x
+       }
+       x=o
+       echo before: $x
+       f
+       echo after: $x
+expected-stdout:
+       before: o
+       f0: o
+       f1:
+       f2: fa
+       f3: o
+       f4: fb
+       after: fb
+---
+name: unset-fnc-local-sh
+description:
+       Check that “unset” removes a previous “local”
+       (Debian Policy §10.4 sh version); apparently,
+       there are shells which fail this?
+stdin:
+       f() {
+               echo f0: $x
+               local x
+               echo f1: $x
+               x=fa
+               echo f2: $x
+               unset x
+               echo f3: $x
+               x=fb
+               echo f4: $x
+       }
+       x=o
+       echo before: $x
+       f
+       echo after: $x
+expected-stdout:
+       before: o
+       f0: o
+       f1:
+       f2: fa
+       f3: o
+       f4: fb
+       after: fb
+---
 name: varexpand-substr-1
 description:
        Check if bash-style substring expansion works
@@ -8053,7 +9268,7 @@ expected-stdout:
 name: varexpand-substr-3
 description:
        Check that some things that work in bash fail.
-       This is by design. And that some things fail in both.
+       This is by design. Oh and vice versa, nowadays.
 stdin:
        export x=abcdefghi n=2
        "$__progname" -c 'echo v${x:(n)}x'
@@ -8061,12 +9276,13 @@ stdin:
        "$__progname" -c 'echo x${x:n}x'
        "$__progname" -c 'echo y${x:}x'
        "$__progname" -c 'echo z${x}x'
+       # next fails only in bash
        "$__progname" -c 'x=abcdef;y=123;echo ${x:${y:2:1}:2}' >/dev/null 2>&1; echo $?
 expected-stdout:
        vcdefghix
        wcdefghix
        zabcdefghix
-       1
+       0
 expected-stderr-pattern:
        /x:n.*bad substitution.*\n.*bad substitution/
 ---
@@ -8166,13 +9382,21 @@ name: varexpand-null-1
 description:
        Ensure empty strings expand emptily
 stdin:
-       print x ${a} ${b} y
-       print z ${a#?} ${b%?} w
-       print v ${a=} ${b/c/d} u
-expected-stdout:
-       x y
-       z w
-       v u
+       print s ${a} . ${b} S
+       print t ${a#?} . ${b%?} T
+       print r ${a=} . ${b/c/d} R
+       print q
+       print s "${a}" . "${b}" S
+       print t "${a#?}" . "${b%?}" T
+       print r "${a=}" . "${b/c/d}" R
+expected-stdout:
+       s . S
+       t . T
+       r . R
+       q
+       s  .  S
+       t  .  T
+       r  .  R
 ---
 name: varexpand-null-2
 description:
@@ -8188,21 +9412,102 @@ expected-stdout:
 name: varexpand-null-3
 description:
        Ensure concatenating behaviour matches other shells
-       although the line 2<> is probably wrong? XNULLSUB case.
 stdin:
-       x=; printf "1<%s>\n" "$x$@"
-       set A; printf "2<%s>\n" "${@:+}"
+       showargs() { for s_arg in "$@"; do echo -n "<$s_arg> "; done; echo .; }
+       showargs 0 ""$@
+       x=; showargs 1 "$x"$@
+       set A; showargs 2 "${@:+}"
+       n() { echo "$#"; }
+       unset e
+       set -- a b
+       n """$@"
+       n "$@"
+       n "$@"""
+       n "$e""$@"
+       n "$@"
+       n "$@""$e"
+       set --
+       n """$@"
+       n "$@"
+       n "$@"""
+       n "$e""$@"
+       n "$@"
+       n "$@""$e"
+expected-stdout:
+       <0> <> .
+       <1> <> .
+       <2> <> .
+       2
+       2
+       2
+       2
+       2
+       2
+       1
+       0
+       1
+       1
+       0
+       1
+---
+name: varexpand-funny-chars
+description:
+       Check some characters
+       XXX \uEF80 is asymmetric, possibly buggy so we don’t check this
+stdin:
+       x=$'<\x00>'; typeset -p x
+       x=$'<\x01>'; typeset -p x
+       x=$'<\u0000>'; typeset -p x
+       x=$'<\u0001>'; typeset -p x
 expected-stdout:
-       1<>
-       2<>
+       typeset x='<'
+       typeset x=$'<\001>'
+       typeset x='<'
+       typeset x=$'<\001>'
 ---
 name: print-funny-chars
 description:
        Check print builtin's capability to output designated characters
 stdin:
-       print '<\0144\0344\xDB\u00DB\u20AC\uDB\x40>'
+       {
+               print '<\0144\0344\xDB\u00DB\u20AC\uDB\x40>'
+               print '<\x00>'
+               print '<\x01>'
+               print '<\u0000>'
+               print '<\u0001>'
+       } | {
+               # integer-base-one-3Ar
+               typeset -Uui16 -Z11 pos=0
+               typeset -Uui16 -Z5 hv=2147483647
+               dasc=
+               if read -arN -1 line; then
+                       typeset -i1 line
+                       i=0
+                       while (( i < ${#line[*]} )); do
+                               hv=${line[i++]}
+                               if (( (pos & 15) == 0 )); then
+                                       (( pos )) && print -r -- "$dasc|"
+                                       print -n "${pos#16#}  "
+                                       dasc=' |'
+                               fi
+                               print -n "${hv#16#} "
+                               if (( (hv < 32) || (hv > 126) )); then
+                                       dasc=$dasc.
+                               else
+                                       dasc=$dasc${line[i-1]#1#}
+                               fi
+                               (( (pos++ & 15) == 7 )) && print -n -- '- '
+                       done
+               fi
+               while (( pos & 15 )); do
+                       print -n '   '
+                       (( (pos++ & 15) == 7 )) && print -n -- '- '
+               done
+               (( hv == 2147483647 )) || print -r -- "$dasc|"
+       }
 expected-stdout:
-       <däÛÃ\9bâ\82¬Ã\9b@>
+       00000000  3C 64 E4 DB C3 9B E2 82 - AC C3 9B 40 3E 0A 3C 00  |<d.........@>.<.|
+       00000010  3E 0A 3C 01 3E 0A 3C 00 - 3E 0A 3C 01 3E 0A        |>.<.>.<.>.<.>.|
 ---
 name: print-bksl-c
 description:
@@ -8234,6 +9539,83 @@ expected-stdout:
        {220->> Bitte keine Werbung einwerfen! <<\r\r}
        {220 Who do you wanna pretend to be today?\r}
 ---
+name: print-crlf
+description:
+       Check that CR+LF is shown and read as-is
+category: shell:textmode-no
+stdin:
+       cat >foo <<-'EOF'
+               x='bar\r
+               ' #\r
+               echo .${#x} #\r
+               if test x"$KSH_VERSION" = x""; then #\r
+                       printf '<%s>' "$x" #\r
+               else #\r
+                       print -nr -- "<$x>" #\r
+               fi #\r
+       EOF
+       echo "[$("$__progname" foo)]"
+       "$__progname" foo | while IFS= read -r line; do
+               print -r -- "{$line}"
+       done
+expected-stdout:
+       [.5
+       <bar\r
+       >]
+       {.5}
+       {<bar\r}
+---
+name: print-crlf-textmode
+description:
+       Check that CR+LF is treated as newline
+category: shell:textmode-yes
+stdin:
+       cat >foo <<-'EOF'
+               x='bar\r
+               ' #\r
+               echo .${#x} #\r
+               if test x"$KSH_VERSION" = x""; then #\r
+                       printf '<%s>' "$x" #\r
+               else #\r
+                       print -nr -- "<$x>" #\r
+               fi #\r
+       EOF
+       echo "[$("$__progname" foo)]"
+       "$__progname" foo | while IFS= read -r line; do
+               print -r -- "{$line}"
+       done
+expected-stdout:
+       [.4
+       <bar
+       >]
+       {.4}
+       {<bar}
+---
+name: print-lf
+description:
+       Check that LF-only is shown and read as-is
+stdin:
+       cat >foo <<-'EOF'
+               x='bar
+               ' #
+               echo .${#x} #
+               if test x"$KSH_VERSION" = x""; then #
+                       printf '<%s>' "$x" #
+               else #
+                       print -nr -- "<$x>" #
+               fi #
+       EOF
+       echo "[$("$__progname" foo)]"
+       "$__progname" foo | while IFS= read -r line; do
+               print -r -- "{$line}"
+       done
+expected-stdout:
+       [.4
+       <bar
+       >]
+       {.4}
+       {<bar}
+---
 name: print-nul-chars
 description:
        Check handling of NUL characters for print and COMSUB
@@ -8244,6 +9626,16 @@ stdin:
 expected-stdout-pattern:
        /^4 3 2 <> <\0>$/
 ---
+name: print-array
+description:
+       Check that print -A works as expected
+stdin:
+       print -An 0x20AC 0xC3 0xBC 8#101
+       set -U
+       print -A 0x20AC 0xC3 0xBC 8#102
+expected-stdout:
+       ¬Ã¼Aâ\82¬Ã\83¼B
+---
 name: print-escapes
 description:
        Check backslash expansion by the print builtin
@@ -8264,7 +9656,7 @@ stdin:
                        while [[ -n $line ]]; do
                                hv=1#${line::1}
                                if (( (pos & 15) == 0 )); then
-                                       (( pos )) && print "$dasc|"
+                                       (( pos )) && print -r -- "$dasc|"
                                        print -n "${pos#16#}  "
                                        dasc=' |'
                                fi
@@ -8282,7 +9674,7 @@ stdin:
                        print -n '   '
                        (( (pos++ & 15) == 7 )) && print -n -- '- '
                done
-               (( hv == 2147483647 )) || print "$dasc|"
+               (( hv == 2147483647 )) || print -r -- "$dasc|"
        }
 expected-stdout:
        00000000  5C 20 5C 21 5C 22 5C 23 - 5C 24 5C 25 5C 26 5C 27  |\ \!\"\#\$\%\&\'|
@@ -8291,13 +9683,13 @@ expected-stdout:
        00000030  20 5C 39 5C 3A 5C 3B 5C - 3C 5C 3D 5C 3E 5C 3F 5C  | \9\:\;\<\=\>\?\|
        00000040  40 5C 41 5C 42 5C 43 5C - 44 1B 5C 46 5C 47 5C 48  |@\A\B\C\D.\F\G\H|
        00000050  5C 49 5C 4A 5C 4B 5C 4C - 5C 4D 5C 4E 5C 4F 5C 50  |\I\J\K\L\M\N\O\P|
-       00000060  5C 51 5C 52 5C 53 5C 54 - 20 5C 56 5C 57 5C 58 5C  |\Q\R\S\T \V\W\X\|
-       00000070  59 5C 5A 5C 5B 5C 5C 5D - 5C 5E 5C 5F 5C 60 07 08  |Y\Z\[\]\^\_\`..|
-       00000080  20 20 5C 64 1B 0C 5C 67 - 5C 68 5C 69 5C 6A 5C 6B  |  \d..\g\h\i\j\k|
-       00000090  5C 6C 5C 6D 0A 5C 6F 5C - 70 20 5C 71 0D 5C 73 09  |\l\m.\o\p \q.\s.|
-       000000A0  0B 5C 77 5C 79 5C 7A 5C - 7B 5C 7C 5C 7D 5C 7E 20  |.\w\y\z\{\|\}\~ |
-       000000B0  E2 82 AC 64 20 EF BF BD - 20 12 33 20 78 20 53 20  |...d ... .3 x S |
-       000000C0  53 34 0A                -                          |S4.|
+       00000060  5C 51 5C 52 5C 53 5C 54 - 20 5C 55 5C 56 5C 57 5C  |\Q\R\S\T \U\V\W\|
+       00000070  58 5C 59 5C 5A 5C 5B 5C - 5C 5D 5C 5E 5C 5F 5C 60  |X\Y\Z\[\\]\^\_\`|
+       00000080  07 08 20 20 5C 64 1B 0C - 5C 67 5C 68 5C 69 5C 6A  |..  \d..\g\h\i\j|
+       00000090  5C 6B 5C 6C 5C 6D 0A 5C - 6F 5C 70 20 5C 71 0D 5C  |\k\l\m.\o\p \q.\|
+       000000A0  73 09 5C 75 0B 5C 77 5C - 78 5C 79 5C 7A 5C 7B 5C  |s.\u.\w\x\y\z\{\|
+       000000B0  7C 5C 7D 5C 7E 20 E2 82 - AC 64 20 EF BF BD 20 12  ||\}\~ ...d ... .|
+       000000C0  33 20 78 20 53 20 53 34 - 0A                       |3 x S S4.|
 ---
 name: dollar-doublequoted-strings
 description:
@@ -8339,7 +9731,7 @@ stdin:
                        while [[ -n $line ]]; do
                                hv=1#${line::1}
                                if (( (pos & 15) == 0 )); then
-                                       (( pos )) && print "$dasc|"
+                                       (( pos )) && print -r -- "$dasc|"
                                        print -n "${pos#16#}  "
                                        dasc=' |'
                                fi
@@ -8357,7 +9749,7 @@ stdin:
                        print -n '   '
                        (( (pos++ & 15) == 7 )) && print -n -- '- '
                done
-               (( hv == 2147483647 )) || print "$dasc|"
+               (( hv == 2147483647 )) || print -r -- "$dasc|"
        }
 expected-stdout:
        00000000  20 21 22 23 24 25 26 27 - 28 29 2A 2B 2C 2D 2E 2F  | !"#$%&'()*+,-./|
@@ -8428,30 +9820,57 @@ stdin:
        "$__progname" -c source
 expected-exit: e != 0
 expected-stderr-pattern:
-       /\.: missing argument.*\n.*\.: missing argument/
+       /\.: missing argument.*\n.*source: missing argument/
+---
+name: dot-errorlevel
+description:
+       Ensure dot resets $?
+stdin:
+       :>dotfile
+       (exit 42)
+       . ./dotfile
+       echo 1 $? .
+expected-stdout:
+       1 0 .
 ---
 name: alias-function-no-conflict
 description:
-       make aliases not conflict with functions
-       note: for ksh-like functions, the order of preference is
-       different; bash outputs baz instead of bar in line 2 below
+       make aliases not conflict with function definitions
 stdin:
+       # POSIX function can be defined, but alias overrides it
        alias foo='echo bar'
+       foo
        foo() {
                echo baz
        }
+       foo
+       unset -f foo
+       foo 2>/dev/null || echo rab
+       # alias overrides ksh function
        alias korn='echo bar'
+       korn
        function korn {
                echo baz
        }
-       foo
        korn
-       unset -f foo
-       foo 2>/dev/null || echo rab
+       # alias temporarily overrides POSIX function
+       bla() {
+               echo bfn
+       }
+       bla
+       alias bla='echo bal'
+       bla
+       unalias bla
+       bla
 expected-stdout:
-       baz
        bar
-       rab
+       bar
+       bar
+       bar
+       bar
+       bfn
+       bal
+       bfn
 ---
 name: bash-function-parens
 description:
@@ -8463,24 +9882,21 @@ stdin:
                echo "$1 {"
                echo '  echo "bar='\''$0'\'\"
                echo '}'
-               echo ${2:-foo}
+               print -r -- "${2:-foo}"
        }
        mk 'function foo' >f-korn
        mk 'foo ()' >f-dash
        mk 'function foo ()' >f-bash
-       mk 'function stop ()' stop >f-stop
        print '#!'"$__progname"'\nprint -r -- "${0%/f-argh}"' >f-argh
        chmod +x f-*
        u=$(./f-argh)
        x="korn: $(./f-korn)"; echo "${x/@("$u")/.}"
        x="dash: $(./f-dash)"; echo "${x/@("$u")/.}"
        x="bash: $(./f-bash)"; echo "${x/@("$u")/.}"
-       x="stop: $(./f-stop)"; echo "${x/@("$u")/.}"
 expected-stdout:
        korn: bar='foo'
        dash: bar='./f-dash'
        bash: bar='./f-bash'
-       stop: bar='./f-stop'
 ---
 name: integer-base-one-1
 description:
@@ -8643,7 +10059,7 @@ stdin:
                        while [[ -n $line ]]; do
                                hv=1#${line::1}
                                if (( (pos & 15) == 0 )); then
-                                       (( pos )) && print "$dasc|"
+                                       (( pos )) && print -r -- "$dasc|"
                                        print -n "${pos#16#}  "
                                        dasc=' |'
                                fi
@@ -8661,7 +10077,7 @@ stdin:
                        print -n '   '
                        (( (pos++ & 15) == 7 )) && print -n -- '- '
                done
-               (( hv == 2147483647 )) || print "$dasc|"
+               (( hv == 2147483647 )) || print -r -- "$dasc|"
        }
 expected-stdout:
        00000000  48 65 6C 6C 6F 2C 20 57 - 6F 72 6C 64 21 5C 0A E3  |Hello, World!\..|
@@ -8731,7 +10147,7 @@ stdin:
                                        dasc=$dasc$dch
                                        dch=
                                elif (( (pos & 7) == 0 )); then
-                                       (( pos )) && print "$dasc|"
+                                       (( pos )) && print -r -- "$dasc|"
                                        print -n "${pos#16#}  "
                                        dasc=' |'
                                fi
@@ -8746,7 +10162,7 @@ stdin:
                        print -n '     '
                        (( (pos++ & 7) == 3 )) && print -n -- '- '
                done
-               (( hv == 2147483647 )) || print "$dasc|"
+               (( hv == 2147483647 )) || print -r -- "$dasc|"
        }
 expected-stdout:
        00000000  0048 0065 006C 006C - 006F 002C 0020 0057  |Hello, W|
@@ -8812,7 +10228,7 @@ stdin:
                        while (( i < ${#line[*]} )); do
                                hv=${line[i++]}
                                if (( (pos & 15) == 0 )); then
-                                       (( pos )) && print "$dasc|"
+                                       (( pos )) && print -r -- "$dasc|"
                                        print -n "${pos#16#}  "
                                        dasc=' |'
                                fi
@@ -8829,7 +10245,7 @@ stdin:
                        print -n '   '
                        (( (pos++ & 15) == 7 )) && print -n -- '- '
                done
-               (( hv == 2147483647 )) || print "$dasc|"
+               (( hv == 2147483647 )) || print -r -- "$dasc|"
        }
 expected-stdout:
        00000000  48 65 6C 6C 6F 2C 20 57 - 6F 72 6C 64 21 5C 0A E3  |Hello, World!\..|
@@ -8895,7 +10311,7 @@ stdin:
                                        dasc=$dasc$dch
                                        dch=
                                elif (( (pos & 7) == 0 )); then
-                                       (( pos )) && print "$dasc|"
+                                       (( pos )) && print -r -- "$dasc|"
                                        print -n "${pos#16#}  "
                                        dasc=' |'
                                fi
@@ -8909,7 +10325,7 @@ stdin:
                        print -n '     '
                        (( (pos++ & 7) == 3 )) && print -n -- '- '
                done
-               (( hv == 2147483647 )) || print "$dasc|"
+               (( hv == 2147483647 )) || print -r -- "$dasc|"
        }
 expected-stdout:
        00000000  0048 0065 006C 006C - 006F 002C 0020 0057  |Hello, W|
@@ -9000,8 +10416,15 @@ expected-stdout:
 ---
 name: ulimit-1
 description:
+       Check that ulimit as used in dot.mksh works or is stubbed
+stdin:
+       ulimit -c 0
+---
+name: ulimit-2
+description:
        Check if we can use a specific syntax idiom for ulimit
-category: !os:syllable
+       XXX Haiku works, but only for -n and -V
+category: !os:haiku,!os:syllable
 stdin:
        if ! x=$(ulimit -d) || [[ $x = unknown ]]; then
                #echo expected to fail on this OS
@@ -9046,7 +10469,6 @@ name: bashiop-1
 description:
        Check if GNU bash-like I/O redirection works
        Part 1: this is also supported by GNU bash
-category: shell:legacy-no
 stdin:
        exec 3>&1
        function threeout {
@@ -9067,7 +10489,6 @@ name: bashiop-2a
 description:
        Check if GNU bash-like I/O redirection works
        Part 2: this is *not* supported by GNU bash
-category: shell:legacy-no
 stdin:
        exec 3>&1
        function threeout {
@@ -9088,7 +10509,6 @@ name: bashiop-2b
 description:
        Check if GNU bash-like I/O redirection works
        Part 2: this is *not* supported by GNU bash
-category: shell:legacy-no
 stdin:
        exec 3>&1
        function threeout {
@@ -9109,7 +10529,6 @@ name: bashiop-2c
 description:
        Check if GNU bash-like I/O redirection works
        Part 2: this is supported by GNU bash 4 only
-category: shell:legacy-no
 stdin:
        echo mir >foo
        set -o noclobber
@@ -9133,7 +10552,6 @@ name: bashiop-3a
 description:
        Check if GNU bash-like I/O redirection fails correctly
        Part 1: this is also supported by GNU bash
-category: shell:legacy-no
 stdin:
        echo mir >foo
        set -o noclobber
@@ -9155,7 +10573,6 @@ name: bashiop-3b
 description:
        Check if GNU bash-like I/O redirection fails correctly
        Part 2: this is *not* supported by GNU bash
-category: shell:legacy-no
 stdin:
        echo mir >foo
        set -o noclobber
@@ -9179,7 +10596,6 @@ description:
        Check if GNU bash-like I/O redirection works
        Part 4: this is also supported by GNU bash,
        but failed in some mksh versions
-category: shell:legacy-no
 stdin:
        exec 3>&1
        function threeout {
@@ -9201,11 +10617,10 @@ expected-stdout:
        ras
        dwa
 ---
-name: bashiop-5-normal
+name: bashiop-5
 description:
        Check if GNU bash-like I/O redirection is only supported
        in !POSIX !sh mode as it breaks existing scripts' syntax
-category: shell:legacy-no
 stdin:
        :>x; echo 1 "$("$__progname" -c 'echo foo>/dev/null&>x echo bar')" = "$(<x)" .
        :>x; echo 2 "$("$__progname" -o posix -c 'echo foo>/dev/null&>x echo bar')" = "$(<x)" .
@@ -9215,43 +10630,6 @@ expected-stdout:
        2  = bar .
        3  = bar .
 ---
-name: bashiop-5-legacy
-description:
-       Check if GNU bash-like I/O redirection is not parsed
-       in lksh as it breaks existing scripts' syntax
-category: shell:legacy-yes
-stdin:
-       :>x; echo 1 "$("$__progname" -c 'echo foo>/dev/null&>x echo bar')" = "$(<x)" .
-       :>x; echo 2 "$("$__progname" -o posix -c 'echo foo>/dev/null&>x echo bar')" = "$(<x)" .
-       :>x; echo 3 "$("$__progname" -o sh -c 'echo foo>/dev/null&>x echo bar')" = "$(<x)" .
-expected-stdout:
-       1  = bar .
-       2  = bar .
-       3  = bar .
----
-name: mkshiop-1
-description:
-       Check for support of more than 9 file descriptors
-category: !convfds
-stdin:
-       read -u10 foo 10<<< bar
-       echo x$foo
-expected-stdout:
-       xbar
----
-name: mkshiop-2
-description:
-       Check for support of more than 9 file descriptors
-category: !convfds
-stdin:
-       exec 12>foo
-       print -u12 bar
-       echo baz >&12
-       cat foo
-expected-stdout:
-       bar
-       baz
----
 name: oksh-eval
 description:
        Check expansions.
@@ -9425,7 +10803,7 @@ description:
 stdin:
        print '#!'"$__progname"'\nunset RANDOM\nexport | while IFS= read -r' \
            'RANDOM; do eval '\''print -r -- "$RANDOM=$'\''"$RANDOM"'\'\"\'\; \
-           done >env; chmod +x env; PATH=.:$PATH
+           done >env; chmod +x env; PATH=.$PATHSEP$PATH
        function k {
                if [ x$FOO != xbar ]; then
                        echo 1
@@ -9486,38 +10864,37 @@ name: fd-cloexec-1
 description:
        Verify that file descriptors > 2 are private for Korn shells
        AT&T ksh93 does this still, which means we must keep it as well
-category: shell:legacy-no
-file-setup: file 644 "test.sh"
-       echo >&3 Fowl
+       XXX fails on some old Perl installations
+need-pass: no
 stdin:
-       exec 3>&1
-       "$__progname" test.sh
+       cat >cld <<-EOF
+               #!$__perlname
+               open(my \$fh, ">&", 9) or die "E: open \$!";
+               syswrite(\$fh, "Fowl\\n", 5) or die "E: write \$!";
+       EOF
+       chmod +x cld
+       exec 9>&1
+       ./cld
 expected-exit: e != 0
 expected-stderr-pattern:
-       /bad file descriptor/
+       /E: open /
 ---
 name: fd-cloexec-2
 description:
        Verify that file descriptors > 2 are not private for POSIX shells
        See Debian Bug #154540, Closes: #499139
-file-setup: file 644 "test.sh"
-       echo >&3 Fowl
-stdin:
-       test -n "$POSH_VERSION" || set -o sh
-       exec 3>&1
-       "$__progname" test.sh
-expected-stdout:
-       Fowl
----
-name: fd-cloexec-3
-description:
-       Verify that file descriptors > 2 are not private for LEGACY KSH
-category: shell:legacy-yes
-file-setup: file 644 "test.sh"
-       echo >&3 Fowl
+       XXX fails on some old Perl installations
+need-pass: no
 stdin:
-       exec 3>&1
-       "$__progname" test.sh
+       cat >cld <<-EOF
+               #!$__perlname
+               open(my \$fh, ">&", 9) or die "E: open \$!";
+               syswrite(\$fh, "Fowl\\n", 5) or die "E: write \$!";
+       EOF
+       chmod +x cld
+       test -n "$POSH_VERSION" || set -o posix
+       exec 9>&1
+       ./cld
 expected-stdout:
        Fowl
 ---
@@ -9585,7 +10962,7 @@ description:
        is a must (a non-recursive parser cannot pass all three of
        these test cases, especially the ‘#’ is difficult)
 stdin:
-       print '#!'"$__progname"'\necho 1234' >id; chmod +x id; PATH=.:$PATH
+       print '#!'"$__progname"'\necho 1234' >id; chmod +x id; PATH=.$PATHSEP$PATH
        echo $(typeset -i10 x=16#20; echo $x)
        echo $(typeset -Uui16 x=16#$(id -u)
        ) .
@@ -9609,10 +10986,10 @@ expected-stdout:
        x() {
                case $1 in
                (u)
-                       echo x 
+                       \echo x 
                        ;|
                (*)
-                       echo $1 
+                       \echo $1 
                        ;;
                esac 
        } 
@@ -9620,20 +10997,36 @@ expected-stdout:
 name: comsub-5
 description:
        Check COMSUB works with aliases (does not expand them twice)
+       and reentrancy safety
 stdin:
        print '#!'"$__progname"'\nfor x in "$@"; do print -r -- "$x"; done' >pfn
        chmod +x pfn
        alias echo='echo a'
        foo() {
+               echo moo
                ./pfn "$(echo foo)"
        }
        ./pfn "$(echo b)"
+       typeset -f foo >x
+       cat x
+       foo
+       . ./x
        typeset -f foo
+       foo
 expected-stdout:
        a b
        foo() {
-               ./pfn "$(echo foo )" 
+               \echo a moo 
+               ./pfn "$(\echo a foo )" 
        } 
+       a moo
+       a foo
+       foo() {
+               \echo a moo 
+               ./pfn "$(\echo a foo )" 
+       } 
+       a moo
+       a foo
 ---
 name: comsub-torture
 description:
@@ -9744,56 +11137,56 @@ expected-stdout:
                vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4"
        }
        inline_TCOM() {
-               vara=1 varb="2  3" cmd arg1 $arg2 "$arg3  4" 
+               vara=1 varb="2  3" \cmd arg1 $arg2 "$arg3  4" 
        } 
        function comsub_TCOM { x=$(
                vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4"
        ); }
        function comsub_TCOM {
-               x=$(vara=1 varb="2  3" cmd arg1 $arg2 "$arg3  4" ) 
+               x=$(vara=1 varb="2  3" \cmd arg1 $arg2 "$arg3  4" ) 
        } 
        function reread_TCOM { x=$((
                vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4"
        )|tr u x); }
        function reread_TCOM {
-               x=$(( vara=1 varb="2  3" cmd arg1 $arg2 "$arg3  4" ) | tr u x ) 
+               x=$( ( vara=1 varb="2  3" \cmd arg1 $arg2 "$arg3  4" ) | \tr u x ) 
        } 
        inline_TPAREN_TPIPE_TLIST() {
                (echo $foo  |  tr -dc 0-9; echo)
        }
        inline_TPAREN_TPIPE_TLIST() {
-               ( echo $foo | tr -dc 0-9 
-                 echo ) 
+               ( \echo $foo | \tr -dc 0-9 
+                 \echo ) 
        } 
        function comsub_TPAREN_TPIPE_TLIST { x=$(
                (echo $foo  |  tr -dc 0-9; echo)
        ); }
        function comsub_TPAREN_TPIPE_TLIST {
-               x=$(( echo $foo | tr -dc 0-9 ; echo ) ) 
+               x=$( ( \echo $foo | \tr -dc 0-9 ; \echo ) ) 
        } 
        function reread_TPAREN_TPIPE_TLIST { x=$((
                (echo $foo  |  tr -dc 0-9; echo)
        )|tr u x); }
        function reread_TPAREN_TPIPE_TLIST {
-               x=$(( ( echo $foo | tr -dc 0-9 ; echo ) ) | tr u x ) 
+               x=$( ( ( \echo $foo | \tr -dc 0-9 ; \echo ) ) | \tr u x ) 
        } 
        inline_TAND_TOR() {
                cmd  &&  echo ja  ||  echo nein
        }
        inline_TAND_TOR() {
-               cmd && echo ja || echo nein 
+               \cmd && \echo ja || \echo nein 
        } 
        function comsub_TAND_TOR { x=$(
                cmd  &&  echo ja  ||  echo nein
        ); }
        function comsub_TAND_TOR {
-               x=$(cmd && echo ja || echo nein ) 
+               x=$(\cmd && \echo ja || \echo nein ) 
        } 
        function reread_TAND_TOR { x=$((
                cmd  &&  echo ja  ||  echo nein
        )|tr u x); }
        function reread_TAND_TOR {
-               x=$(( cmd && echo ja || echo nein ) | tr u x ) 
+               x=$( ( \cmd && \echo ja || \echo nein ) | \tr u x ) 
        } 
        inline_TSELECT() {
                select  file  in  *;  do  echo  "<$file>" ;  break ;  done
@@ -9801,21 +11194,21 @@ expected-stdout:
        inline_TSELECT() {
                select file in * 
                do
-                       echo "<$file>" 
-                       break 
+                       \echo "<$file>" 
+                       \break 
                done 
        } 
        function comsub_TSELECT { x=$(
                select  file  in  *;  do  echo  "<$file>" ;  break ;  done
        ); }
        function comsub_TSELECT {
-               x=$(select file in * ; do echo "<$file>" ; break ; done ) 
+               x=$(select file in * ; do \echo "<$file>" ; \break ; done ) 
        } 
        function reread_TSELECT { x=$((
                select  file  in  *;  do  echo  "<$file>" ;  break ;  done
        )|tr u x); }
        function reread_TSELECT {
-               x=$(( select file in * ; do echo "<$file>" ; break ; done ) | tr u x ) 
+               x=$( ( select file in * ; do \echo "<$file>" ; \break ; done ) | \tr u x ) 
        } 
        inline_TFOR_TTIME() {
                time  for  i  in  {1,2,3}  ;  do  echo  $i ;  done
@@ -9823,20 +11216,20 @@ expected-stdout:
        inline_TFOR_TTIME() {
                time for i in {1,2,3} 
                do
-                       echo $i 
+                       \echo $i 
                done 
        } 
        function comsub_TFOR_TTIME { x=$(
                time  for  i  in  {1,2,3}  ;  do  echo  $i ;  done
        ); }
        function comsub_TFOR_TTIME {
-               x=$(time for i in {1,2,3} ; do echo $i ; done ) 
+               x=$(time for i in {1,2,3} ; do \echo $i ; done ) 
        } 
        function reread_TFOR_TTIME { x=$((
                time  for  i  in  {1,2,3}  ;  do  echo  $i ;  done
        )|tr u x); }
        function reread_TFOR_TTIME {
-               x=$(( time for i in {1,2,3} ; do echo $i ; done ) | tr u x ) 
+               x=$( ( time for i in {1,2,3} ; do \echo $i ; done ) | \tr u x ) 
        } 
        inline_TCASE() {
                case  $foo  in  1)  echo eins;& 2) echo zwei  ;| *) echo kann net bis drei zählen;;  esac
@@ -9844,13 +11237,13 @@ expected-stdout:
        inline_TCASE() {
                case $foo in
                (1)
-                       echo eins 
+                       \echo eins 
                        ;&
                (2)
-                       echo zwei 
+                       \echo zwei 
                        ;|
                (*)
-                       echo kann net bis drei zählen 
+                       \echo kann net bis drei zählen 
                        ;;
                esac 
        } 
@@ -9858,13 +11251,13 @@ expected-stdout:
                case  $foo  in  1)  echo eins;& 2) echo zwei  ;| *) echo kann net bis drei zählen;;  esac
        ); }
        function comsub_TCASE {
-               x=$(case $foo in (1) echo eins  ;& (2) echo zwei  ;| (*) echo kann net bis drei zählen  ;; esac ) 
+               x=$(case $foo in (1) \echo eins  ;& (2) \echo zwei  ;| (*) \echo kann net bis drei zählen  ;; esac ) 
        } 
        function reread_TCASE { x=$((
                case  $foo  in  1)  echo eins;& 2) echo zwei  ;| *) echo kann net bis drei zählen;;  esac
        )|tr u x); }
        function reread_TCASE {
-               x=$(( case $foo in (1) echo eins  ;& (2) echo zwei  ;| (*) echo kann net bis drei zählen  ;; esac ) | tr u x ) 
+               x=$( ( case $foo in (1) \echo eins  ;& (2) \echo zwei  ;| (*) \echo kann net bis drei zählen  ;; esac ) | \tr u x ) 
        } 
        inline_TIF_TBANG_TDBRACKET_TELIF() {
                if  !  [[  1  =  1  ]]  ;  then  echo eins;  elif [[ 1 = 2 ]]; then echo zwei  ;else echo drei; fi
@@ -9872,89 +11265,93 @@ expected-stdout:
        inline_TIF_TBANG_TDBRACKET_TELIF() {
                if ! [[ 1 = 1 ]] 
                then
-                       echo eins 
+                       \echo eins 
                elif [[ 1 = 2 ]] 
                then
-                       echo zwei 
+                       \echo zwei 
                else
-                       echo drei 
+                       \echo drei 
                fi 
        } 
        function comsub_TIF_TBANG_TDBRACKET_TELIF { x=$(
                if  !  [[  1  =  1  ]]  ;  then  echo eins;  elif [[ 1 = 2 ]]; then echo zwei  ;else echo drei; fi
        ); }
        function comsub_TIF_TBANG_TDBRACKET_TELIF {
-               x=$(if ! [[ 1 = 1 ]] ; then echo eins ; elif [[ 1 = 2 ]] ; then echo zwei ; else echo drei ; fi ) 
+               x=$(if ! [[ 1 = 1 ]] ; then \echo eins ; elif [[ 1 = 2 ]] ; then \echo zwei ; else \echo drei ; fi ) 
        } 
        function reread_TIF_TBANG_TDBRACKET_TELIF { x=$((
                if  !  [[  1  =  1  ]]  ;  then  echo eins;  elif [[ 1 = 2 ]]; then echo zwei  ;else echo drei; fi
        )|tr u x); }
        function reread_TIF_TBANG_TDBRACKET_TELIF {
-               x=$(( if ! [[ 1 = 1 ]] ; then echo eins ; elif [[ 1 = 2 ]] ; then echo zwei ; else echo drei ; fi ) | tr u x ) 
+               x=$( ( if ! [[ 1 = 1 ]] ; then \echo eins ; elif [[ 1 = 2 ]] ; then \echo zwei ; else \echo drei ; fi ) | \tr u x ) 
        } 
        inline_TWHILE() {
                i=1; while (( i < 10 )); do echo $i; let ++i; done
        }
        inline_TWHILE() {
                i=1 
-               while let] " i < 10 " 
+               while {
+                             \\builtin let " i < 10 " 
+                     } 
                do
-                       echo $i 
-                       let ++i 
+                       \echo $i 
+                       \let ++i 
                done 
        } 
        function comsub_TWHILE { x=$(
                i=1; while (( i < 10 )); do echo $i; let ++i; done
        ); }
        function comsub_TWHILE {
-               x=$(i=1 ; while let] " i < 10 " ; do echo $i ; let ++i ; done ) 
+               x=$(i=1 ; while { \\builtin let " i < 10 " ; } ; do \echo $i ; \let ++i ; done ) 
        } 
        function reread_TWHILE { x=$((
                i=1; while (( i < 10 )); do echo $i; let ++i; done
        )|tr u x); }
        function reread_TWHILE {
-               x=$(( i=1 ; while let] " i < 10 " ; do echo $i ; let ++i ; done ) | tr u x ) 
+               x=$( ( i=1 ; while { \\builtin let " i < 10 " ; } ; do \echo $i ; \let ++i ; done ) | \tr u x ) 
        } 
        inline_TUNTIL() {
                i=10; until  (( !--i )) ; do echo $i; done
        }
        inline_TUNTIL() {
                i=10 
-               until let] " !--i " 
+               until {
+                             \\builtin let " !--i " 
+                     } 
                do
-                       echo $i 
+                       \echo $i 
                done 
        } 
        function comsub_TUNTIL { x=$(
                i=10; until  (( !--i )) ; do echo $i; done
        ); }
        function comsub_TUNTIL {
-               x=$(i=10 ; until let] " !--i " ; do echo $i ; done ) 
+               x=$(i=10 ; until { \\builtin let " !--i " ; } ; do \echo $i ; done ) 
        } 
        function reread_TUNTIL { x=$((
                i=10; until  (( !--i )) ; do echo $i; done
        )|tr u x); }
        function reread_TUNTIL {
-               x=$(( i=10 ; until let] " !--i " ; do echo $i ; done ) | tr u x ) 
+               x=$( ( i=10 ; until { \\builtin let " !--i " ; } ; do \echo $i ; done ) | \tr u x ) 
        } 
        inline_TCOPROC() {
                cat  *  |&  ls
        }
        inline_TCOPROC() {
-               cat * |& 
-               ls 
+               \cat * |& 
+               \ls 
        } 
        function comsub_TCOPROC { x=$(
                cat  *  |&  ls
        ); }
        function comsub_TCOPROC {
-               x=$(cat * |&  ls ) 
+               x=$(\cat * |&  \ls ) 
        } 
        function reread_TCOPROC { x=$((
                cat  *  |&  ls
        )|tr u x); }
        function reread_TCOPROC {
-               x=$(( cat * |&  ls ) | tr u x ) 
+               x=$( ( \cat * |&  \ls ) | \tr u x ) 
        } 
        inline_TFUNCT_TBRACE_TASYNC() {
                function  korn  {  echo eins; echo zwei ;  }
@@ -9962,11 +11359,11 @@ expected-stdout:
        }
        inline_TFUNCT_TBRACE_TASYNC() {
                function korn {
-                       echo eins 
-                       echo zwei 
+                       \echo eins 
+                       \echo zwei 
                } 
                bourne() {
-                       logger * & 
+                       \logger * & 
                } 
        } 
        function comsub_TFUNCT_TBRACE_TASYNC { x=$(
@@ -9974,32 +11371,32 @@ expected-stdout:
                bourne  ()  {  logger *  &  }
        ); }
        function comsub_TFUNCT_TBRACE_TASYNC {
-               x=$(function korn { echo eins ; echo zwei ; } ; bourne() { logger * &  } ) 
+               x=$(function korn { \echo eins ; \echo zwei ; } ; bourne() { \logger * &  } ) 
        } 
        function reread_TFUNCT_TBRACE_TASYNC { x=$((
                function  korn  {  echo eins; echo zwei ;  }
                bourne  ()  {  logger *  &  }
        )|tr u x); }
        function reread_TFUNCT_TBRACE_TASYNC {
-               x=$(( function korn { echo eins ; echo zwei ; } ; bourne() { logger * &  } ) | tr u x ) 
+               x=$( ( function korn { \echo eins ; \echo zwei ; } ; bourne() { \logger * &  } ) | \tr u x ) 
        } 
        inline_IOREAD_IOCAT() {
                tr  x  u  0<foo  >>bar
        }
        inline_IOREAD_IOCAT() {
-               tr x u <foo >>bar 
+               \tr x u <foo >>bar 
        } 
        function comsub_IOREAD_IOCAT { x=$(
                tr  x  u  0<foo  >>bar
        ); }
        function comsub_IOREAD_IOCAT {
-               x=$(tr x u <foo >>bar ) 
+               x=$(\tr x u <foo >>bar ) 
        } 
        function reread_IOREAD_IOCAT { x=$((
                tr  x  u  0<foo  >>bar
        )|tr u x); }
        function reread_IOREAD_IOCAT {
-               x=$(( tr x u <foo >>bar ) | tr u x ) 
+               x=$( ( \tr x u <foo >>bar ) | \tr u x ) 
        } 
        inline_IOWRITE_IOCLOB_IOHERE_noIOSKIP() {
                cat  >|bar  <<'EOFN'
@@ -10007,7 +11404,7 @@ expected-stdout:
        EOFN
        }
        inline_IOWRITE_IOCLOB_IOHERE_noIOSKIP() {
-               cat >|bar <<"EOFN"
+               \cat >|bar <<"EOFN" 
                foo
        EOFN
        
@@ -10018,7 +11415,7 @@ expected-stdout:
        EOFN
        ); }
        function comsub_IOWRITE_IOCLOB_IOHERE_noIOSKIP {
-               x=$(cat >|bar <<"EOFN"
+               x=$(\cat >|bar <<"EOFN" 
                foo
        EOFN
        ) 
@@ -10029,10 +11426,10 @@ expected-stdout:
        EOFN
        )|tr u x); }
        function reread_IOWRITE_IOCLOB_IOHERE_noIOSKIP {
-               x=$(( cat >|bar <<"EOFN"
+               x=$( ( \cat >|bar <<"EOFN" 
                foo
        EOFN
-       ) | tr u x ) 
+       ) | \tr u x ) 
        } 
        inline_IOWRITE_noIOCLOB_IOHERE_IOSKIP() {
                cat  1>bar  <<-EOFI
@@ -10040,7 +11437,7 @@ expected-stdout:
                EOFI
        }
        inline_IOWRITE_noIOCLOB_IOHERE_IOSKIP() {
-               cat >bar <<-EOFI
+               \cat >bar <<-EOFI 
        foo
        EOFI
        
@@ -10051,7 +11448,7 @@ expected-stdout:
                EOFI
        ); }
        function comsub_IOWRITE_noIOCLOB_IOHERE_IOSKIP {
-               x=$(cat >bar <<-EOFI
+               x=$(\cat >bar <<-EOFI 
        foo
        EOFI
        ) 
@@ -10062,46 +11459,46 @@ expected-stdout:
                EOFI
        )|tr u x); }
        function reread_IOWRITE_noIOCLOB_IOHERE_IOSKIP {
-               x=$(( cat >bar <<-EOFI
+               x=$( ( \cat >bar <<-EOFI 
        foo
        EOFI
-       ) | tr u x ) 
+       ) | \tr u x ) 
        } 
        inline_IORDWR_IODUP() {
                sh  1<>/dev/console  0<&1  2>&1
        }
        inline_IORDWR_IODUP() {
-               sh 1<>/dev/console <&1 2>&1 
+               \sh 1<>/dev/console <&1 2>&1 
        } 
        function comsub_IORDWR_IODUP { x=$(
                sh  1<>/dev/console  0<&1  2>&1
        ); }
        function comsub_IORDWR_IODUP {
-               x=$(sh 1<>/dev/console <&1 2>&1 ) 
+               x=$(\sh 1<>/dev/console <&1 2>&1 ) 
        } 
        function reread_IORDWR_IODUP { x=$((
                sh  1<>/dev/console  0<&1  2>&1
        )|tr u x); }
        function reread_IORDWR_IODUP {
-               x=$(( sh 1<>/dev/console <&1 2>&1 ) | tr u x ) 
+               x=$( ( \sh 1<>/dev/console <&1 2>&1 ) | \tr u x ) 
        } 
        inline_COMSUB_EXPRSUB_FUNSUB_VALSUB() {
                echo $(true) $((1+ 2)) ${  :;} ${| REPLY=x;}
        }
        inline_COMSUB_EXPRSUB_FUNSUB_VALSUB() {
-               echo $(true ) $((1+ 2)) ${ : ;} ${|REPLY=x ;} 
+               \echo $(\true ) $((1+ 2)) ${ : ;} ${|REPLY=x ;} 
        } 
        function comsub_COMSUB_EXPRSUB_FUNSUB_VALSUB { x=$(
                echo $(true) $((1+ 2)) ${  :;} ${| REPLY=x;}
        ); }
        function comsub_COMSUB_EXPRSUB_FUNSUB_VALSUB {
-               x=$(echo $(true ) $((1+ 2)) ${ : ;} ${|REPLY=x ;} ) 
+               x=$(\echo $(\true ) $((1+ 2)) ${ : ;} ${|REPLY=x ;} ) 
        } 
        function reread_COMSUB_EXPRSUB_FUNSUB_VALSUB { x=$((
                echo $(true) $((1+ 2)) ${  :;} ${| REPLY=x;}
        )|tr u x); }
        function reread_COMSUB_EXPRSUB_FUNSUB_VALSUB {
-               x=$(( echo $(true ) $((1+ 2)) ${ : ;} ${|REPLY=x ;} ) | tr u x ) 
+               x=$( ( \echo $(\true ) $((1+ 2)) ${ : ;} ${|REPLY=x ;} ) | \tr u x ) 
        } 
        inline_QCHAR_OQUOTE_CQUOTE() {
                echo fo\ob\"a\`r\'b\$az
@@ -10109,9 +11506,9 @@ expected-stdout:
                echo 'fo\ob\"a\`r'\''b\$az'
        }
        inline_QCHAR_OQUOTE_CQUOTE() {
-               echo fo\ob\"a\`r\'b\$az 
-               echo "fo\ob\"a\`r\'b\$az" 
-               echo "fo\\ob\\\"a\\\`r"\'"b\\\$az" 
+               \echo fo\ob\"a\`r\'b\$az 
+               \echo "fo\ob\"a\`r\'b\$az" 
+               \echo "fo\\ob\\\"a\\\`r"\'"b\\\$az" 
        } 
        function comsub_QCHAR_OQUOTE_CQUOTE { x=$(
                echo fo\ob\"a\`r\'b\$az
@@ -10119,7 +11516,7 @@ expected-stdout:
                echo 'fo\ob\"a\`r'\''b\$az'
        ); }
        function comsub_QCHAR_OQUOTE_CQUOTE {
-               x=$(echo fo\ob\"a\`r\'b\$az ; echo "fo\ob\"a\`r\'b\$az" ; echo "fo\\ob\\\"a\\\`r"\'"b\\\$az" ) 
+               x=$(\echo fo\ob\"a\`r\'b\$az ; \echo "fo\ob\"a\`r\'b\$az" ; \echo "fo\\ob\\\"a\\\`r"\'"b\\\$az" ) 
        } 
        function reread_QCHAR_OQUOTE_CQUOTE { x=$((
                echo fo\ob\"a\`r\'b\$az
@@ -10127,7 +11524,7 @@ expected-stdout:
                echo 'fo\ob\"a\`r'\''b\$az'
        )|tr u x); }
        function reread_QCHAR_OQUOTE_CQUOTE {
-               x=$(( echo fo\ob\"a\`r\'b\$az ; echo "fo\ob\"a\`r\'b\$az" ; echo "fo\\ob\\\"a\\\`r"\'"b\\\$az" ) | tr u x ) 
+               x=$( ( \echo fo\ob\"a\`r\'b\$az ; \echo "fo\ob\"a\`r\'b\$az" ; \echo "fo\\ob\\\"a\\\`r"\'"b\\\$az" ) | \tr u x ) 
        } 
        inline_OSUBST_CSUBST_OPAT_SPAT_CPAT() {
                [[ ${foo#bl\(u\)b} = @(bar|baz) ]]
@@ -10145,7 +11542,7 @@ expected-stdout:
                [[ ${foo#bl\(u\)b} = @(bar|baz) ]]
        )|tr u x); }
        function reread_OSUBST_CSUBST_OPAT_SPAT_CPAT {
-               x=$(( [[ ${foo#bl\(u\)b} = @(bar|baz) ]] ) | tr u x ) 
+               x=$( ( [[ ${foo#bl\(u\)b} = @(bar|baz) ]] ) | \tr u x ) 
        } 
        inline_heredoc_closed() {
                x=$(cat <<EOFN
@@ -10153,11 +11550,11 @@ expected-stdout:
        EOFN); echo $x
        }
        inline_heredoc_closed() {
-               x=$(cat <<EOFN
+               x=$(\cat <<EOFN 
                note there must be no space between EOFN and )
        EOFN
        ) 
-               echo $x 
+               \echo $x 
        } 
        function comsub_heredoc_closed { x=$(
                x=$(cat <<EOFN
@@ -10165,10 +11562,10 @@ expected-stdout:
        EOFN); echo $x
        ); }
        function comsub_heredoc_closed {
-               x=$(x=$(cat <<EOFN
+               x=$(x=$(\cat <<EOFN 
                note there must be no space between EOFN and )
        EOFN
-       ) ; echo $x ) 
+       ) ; \echo $x ) 
        } 
        function reread_heredoc_closed { x=$((
                x=$(cat <<EOFN
@@ -10176,10 +11573,10 @@ expected-stdout:
        EOFN); echo $x
        )|tr u x); }
        function reread_heredoc_closed {
-               x=$(( x=$(cat <<EOFN
+               x=$( ( x=$(\cat <<EOFN 
                note there must be no space between EOFN and )
        EOFN
-       ) ; echo $x ) | tr u x ) 
+       ) ; \echo $x ) | \tr u x ) 
        } 
        inline_heredoc_space() {
                x=$(cat <<EOFN\ 
@@ -10187,11 +11584,11 @@ expected-stdout:
        EOFN ); echo $x
        }
        inline_heredoc_space() {
-               x=$(cat <<EOFN\ 
+               x=$(\cat <<EOFN\  
                note the space between EOFN and ) is actually part of the here document marker
        EOFN 
        ) 
-               echo $x 
+               \echo $x 
        } 
        function comsub_heredoc_space { x=$(
                x=$(cat <<EOFN\ 
@@ -10199,10 +11596,10 @@ expected-stdout:
        EOFN ); echo $x
        ); }
        function comsub_heredoc_space {
-               x=$(x=$(cat <<EOFN\ 
+               x=$(x=$(\cat <<EOFN\  
                note the space between EOFN and ) is actually part of the here document marker
        EOFN 
-       ) ; echo $x ) 
+       ) ; \echo $x ) 
        } 
        function reread_heredoc_space { x=$((
                x=$(cat <<EOFN\ 
@@ -10210,10 +11607,10 @@ expected-stdout:
        EOFN ); echo $x
        )|tr u x); }
        function reread_heredoc_space {
-               x=$(( x=$(cat <<EOFN\ 
+               x=$( ( x=$(\cat <<EOFN\  
                note the space between EOFN and ) is actually part of the here document marker
        EOFN 
-       ) ; echo $x ) | tr u x ) 
+       ) ; \echo $x ) | \tr u x ) 
        } 
        inline_patch_motd() {
                x=$(sysctl -n kern.version | sed 1q)
@@ -10232,8 +11629,8 @@ expected-stdout:
                fi
        }
        inline_patch_motd() {
-               x=$(sysctl -n kern.version | sed 1q ) 
-               [[ -s /etc/motd && "$([[ "$(head -1 /etc/motd )" != $x ]] && ed -s /etc/motd 2>&1 <<-EOF
+               x=$(\sysctl -n kern.version | \sed 1q ) 
+               [[ -s /etc/motd && "$([[ "$(\head -1 /etc/motd )" != $x ]] && \ed -s /etc/motd 2>&1 <<-EOF 
        1,/^\$/d
        0a
        $x
@@ -10241,11 +11638,11 @@ expected-stdout:
        .
        wq
        EOF
-       )" = @(?) ]] && rm -f /etc/motd 
+       )" = @(?) ]] && \rm -f /etc/motd 
                if [[ ! -s /etc/motd ]] 
                then
-                       install -c -o root -g wheel -m 664 /dev/null /etc/motd 
-                       print -- "$x\n" >/etc/motd 
+                       \install -c -o root -g wheel -m 664 /dev/null /etc/motd 
+                       \print -- "$x\n" >/etc/motd 
                fi 
        } 
        function comsub_patch_motd { x=$(
@@ -10265,7 +11662,7 @@ expected-stdout:
                fi
        ); }
        function comsub_patch_motd {
-               x=$(x=$(sysctl -n kern.version | sed 1q ) ; [[ -s /etc/motd && "$([[ "$(head -1 /etc/motd )" != $x ]] && ed -s /etc/motd 2>&1 <<-EOF
+               x=$(x=$(\sysctl -n kern.version | \sed 1q ) ; [[ -s /etc/motd && "$([[ "$(\head -1 /etc/motd )" != $x ]] && \ed -s /etc/motd 2>&1 <<-EOF 
        1,/^\$/d
        0a
        $x
@@ -10273,7 +11670,7 @@ expected-stdout:
        .
        wq
        EOF
-       )" = @(?) ]] && rm -f /etc/motd ; if [[ ! -s /etc/motd ]] ; then install -c -o root -g wheel -m 664 /dev/null /etc/motd ; print -- "$x\n" >/etc/motd ; fi ) 
+       )" = @(?) ]] && \rm -f /etc/motd ; if [[ ! -s /etc/motd ]] ; then \install -c -o root -g wheel -m 664 /dev/null /etc/motd ; \print -- "$x\n" >/etc/motd ; fi ) 
        } 
        function reread_patch_motd { x=$((
                x=$(sysctl -n kern.version | sed 1q)
@@ -10292,7 +11689,7 @@ expected-stdout:
                fi
        )|tr u x); }
        function reread_patch_motd {
-               x=$(( x=$(sysctl -n kern.version | sed 1q ) ; [[ -s /etc/motd && "$([[ "$(head -1 /etc/motd )" != $x ]] && ed -s /etc/motd 2>&1 <<-EOF
+               x=$( ( x=$(\sysctl -n kern.version | \sed 1q ) ; [[ -s /etc/motd && "$([[ "$(\head -1 /etc/motd )" != $x ]] && \ed -s /etc/motd 2>&1 <<-EOF 
        1,/^\$/d
        0a
        $x
@@ -10300,7 +11697,7 @@ expected-stdout:
        .
        wq
        EOF
-       )" = @(?) ]] && rm -f /etc/motd ; if [[ ! -s /etc/motd ]] ; then install -c -o root -g wheel -m 664 /dev/null /etc/motd ; print -- "$x\n" >/etc/motd ; fi ) | tr u x ) 
+       )" = @(?) ]] && \rm -f /etc/motd ; if [[ ! -s /etc/motd ]] ; then \install -c -o root -g wheel -m 664 /dev/null /etc/motd ; \print -- "$x\n" >/etc/motd ; fi ) | \tr u x ) 
        } 
        inline_wdarrassign() {
                case x in
@@ -10311,7 +11708,7 @@ expected-stdout:
                case x in
                (x)
                        a+=b 
-                       set -A c+ -- d e 
+                       \\builtin set -A c+ -- d e 
                        ;;
                esac 
        } 
@@ -10321,7 +11718,7 @@ expected-stdout:
                esac
        ); }
        function comsub_wdarrassign {
-               x=$(case x in (x) a+=b ; set -A c+ -- d e  ;; esac ) 
+               x=$(case x in (x) a+=b ; \\builtin set -A c+ -- d e  ;; esac ) 
        } 
        function reread_wdarrassign { x=$((
                case x in
@@ -10329,7 +11726,7 @@ expected-stdout:
                esac
        )|tr u x); }
        function reread_wdarrassign {
-               x=$(( case x in (x) a+=b ; set -A c+ -- d e  ;; esac ) | tr u x ) 
+               x=$( ( case x in (x) a+=b ; \\builtin set -A c+ -- d e  ;; esac ) | \tr u x ) 
        } 
 ---
 name: comsub-torture-io
@@ -10396,56 +11793,56 @@ expected-stdout:
                vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4" >&3
        }
        inline_TCOM() {
-               vara=1 varb="2  3" cmd arg1 $arg2 "$arg3  4" >&3 
+               vara=1 varb="2  3" \cmd arg1 $arg2 "$arg3  4" >&3 
        } 
        function comsub_TCOM { x=$(
                vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4" >&3
        ); }
        function comsub_TCOM {
-               x=$(vara=1 varb="2  3" cmd arg1 $arg2 "$arg3  4" >&3 ) 
+               x=$(vara=1 varb="2  3" \cmd arg1 $arg2 "$arg3  4" >&3 ) 
        } 
        function reread_TCOM { x=$((
                vara=1  varb='2  3'  cmd  arg1  $arg2  "$arg3  4" >&3
        )|tr u x); }
        function reread_TCOM {
-               x=$(( vara=1 varb="2  3" cmd arg1 $arg2 "$arg3  4" >&3 ) | tr u x ) 
+               x=$( ( vara=1 varb="2  3" \cmd arg1 $arg2 "$arg3  4" >&3 ) | \tr u x ) 
        } 
        inline_TPAREN_TPIPE_TLIST() {
                (echo $foo  |  tr -dc 0-9 >&3; echo >&3) >&3
        }
        inline_TPAREN_TPIPE_TLIST() {
-               ( echo $foo | tr -dc 0-9 >&3 
-                 echo >&3 ) >&3 
+               ( \echo $foo | \tr -dc 0-9 >&3 
+                 \echo >&3 ) >&3 
        } 
        function comsub_TPAREN_TPIPE_TLIST { x=$(
                (echo $foo  |  tr -dc 0-9 >&3; echo >&3) >&3
        ); }
        function comsub_TPAREN_TPIPE_TLIST {
-               x=$(( echo $foo | tr -dc 0-9 >&3 ; echo >&3 ) >&3 ) 
+               x=$( ( \echo $foo | \tr -dc 0-9 >&3 ; \echo >&3 ) >&3 ) 
        } 
        function reread_TPAREN_TPIPE_TLIST { x=$((
                (echo $foo  |  tr -dc 0-9 >&3; echo >&3) >&3
        )|tr u x); }
        function reread_TPAREN_TPIPE_TLIST {
-               x=$(( ( echo $foo | tr -dc 0-9 >&3 ; echo >&3 ) >&3 ) | tr u x ) 
+               x=$( ( ( \echo $foo | \tr -dc 0-9 >&3 ; \echo >&3 ) >&3 ) | \tr u x ) 
        } 
        inline_TAND_TOR() {
                cmd  >&3 &&  >&3 echo ja  ||  echo >&3 nein
        }
        inline_TAND_TOR() {
-               cmd >&3 && echo ja >&3 || echo nein >&3 
+               \cmd >&3 && \echo ja >&3 || \echo nein >&3 
        } 
        function comsub_TAND_TOR { x=$(
                cmd  >&3 &&  >&3 echo ja  ||  echo >&3 nein
        ); }
        function comsub_TAND_TOR {
-               x=$(cmd >&3 && echo ja >&3 || echo nein >&3 ) 
+               x=$(\cmd >&3 && \echo ja >&3 || \echo nein >&3 ) 
        } 
        function reread_TAND_TOR { x=$((
                cmd  >&3 &&  >&3 echo ja  ||  echo >&3 nein
        )|tr u x); }
        function reread_TAND_TOR {
-               x=$(( cmd >&3 && echo ja >&3 || echo nein >&3 ) | tr u x ) 
+               x=$( ( \cmd >&3 && \echo ja >&3 || \echo nein >&3 ) | \tr u x ) 
        } 
        inline_TSELECT() {
                select  file  in  *;  do  echo  "<$file>" ;  break >&3 ;  done >&3
@@ -10453,21 +11850,21 @@ expected-stdout:
        inline_TSELECT() {
                select file in * 
                do
-                       echo "<$file>" 
-                       break >&3 
+                       \echo "<$file>" 
+                       \break >&3 
                done >&3 
        } 
        function comsub_TSELECT { x=$(
                select  file  in  *;  do  echo  "<$file>" ;  break >&3 ;  done >&3
        ); }
        function comsub_TSELECT {
-               x=$(select file in * ; do echo "<$file>" ; break >&3 ; done >&3 ) 
+               x=$(select file in * ; do \echo "<$file>" ; \break >&3 ; done >&3 ) 
        } 
        function reread_TSELECT { x=$((
                select  file  in  *;  do  echo  "<$file>" ;  break >&3 ;  done >&3
        )|tr u x); }
        function reread_TSELECT {
-               x=$(( select file in * ; do echo "<$file>" ; break >&3 ; done >&3 ) | tr u x ) 
+               x=$( ( select file in * ; do \echo "<$file>" ; \break >&3 ; done >&3 ) | \tr u x ) 
        } 
        inline_TFOR_TTIME() {
                for  i  in  {1,2,3}  ;  do  time  >&3 echo  $i ;  done >&3
@@ -10475,20 +11872,20 @@ expected-stdout:
        inline_TFOR_TTIME() {
                for i in {1,2,3} 
                do
-                       time echo $i >&3 
+                       time \echo $i >&3 
                done >&3 
        } 
        function comsub_TFOR_TTIME { x=$(
                for  i  in  {1,2,3}  ;  do  time  >&3 echo  $i ;  done >&3
        ); }
        function comsub_TFOR_TTIME {
-               x=$(for i in {1,2,3} ; do time echo $i >&3 ; done >&3 ) 
+               x=$(for i in {1,2,3} ; do time \echo $i >&3 ; done >&3 ) 
        } 
        function reread_TFOR_TTIME { x=$((
                for  i  in  {1,2,3}  ;  do  time  >&3 echo  $i ;  done >&3
        )|tr u x); }
        function reread_TFOR_TTIME {
-               x=$(( for i in {1,2,3} ; do time echo $i >&3 ; done >&3 ) | tr u x ) 
+               x=$( ( for i in {1,2,3} ; do time \echo $i >&3 ; done >&3 ) | \tr u x ) 
        } 
        inline_TCASE() {
                case  $foo  in  1)  echo eins >&3;& 2) echo zwei >&3  ;| *) echo kann net bis drei zählen >&3;;  esac >&3
@@ -10496,13 +11893,13 @@ expected-stdout:
        inline_TCASE() {
                case $foo in
                (1)
-                       echo eins >&3 
+                       \echo eins >&3 
                        ;&
                (2)
-                       echo zwei >&3 
+                       \echo zwei >&3 
                        ;|
                (*)
-                       echo kann net bis drei zählen >&3 
+                       \echo kann net bis drei zählen >&3 
                        ;;
                esac >&3 
        } 
@@ -10510,13 +11907,13 @@ expected-stdout:
                case  $foo  in  1)  echo eins >&3;& 2) echo zwei >&3  ;| *) echo kann net bis drei zählen >&3;;  esac >&3
        ); }
        function comsub_TCASE {
-               x=$(case $foo in (1) echo eins >&3  ;& (2) echo zwei >&3  ;| (*) echo kann net bis drei zählen >&3  ;; esac >&3 ) 
+               x=$(case $foo in (1) \echo eins >&3  ;& (2) \echo zwei >&3  ;| (*) \echo kann net bis drei zählen >&3  ;; esac >&3 ) 
        } 
        function reread_TCASE { x=$((
                case  $foo  in  1)  echo eins >&3;& 2) echo zwei >&3  ;| *) echo kann net bis drei zählen >&3;;  esac >&3
        )|tr u x); }
        function reread_TCASE {
-               x=$(( case $foo in (1) echo eins >&3  ;& (2) echo zwei >&3  ;| (*) echo kann net bis drei zählen >&3  ;; esac >&3 ) | tr u x ) 
+               x=$( ( case $foo in (1) \echo eins >&3  ;& (2) \echo zwei >&3  ;| (*) \echo kann net bis drei zählen >&3  ;; esac >&3 ) | \tr u x ) 
        } 
        inline_TIF_TBANG_TDBRACKET_TELIF() {
                if  !  [[  1  =  1  ]]  >&3 ;  then  echo eins;  elif [[ 1 = 2 ]] >&3; then echo zwei  ;else echo drei; fi >&3
@@ -10524,89 +11921,93 @@ expected-stdout:
        inline_TIF_TBANG_TDBRACKET_TELIF() {
                if ! [[ 1 = 1 ]] >&3 
                then
-                       echo eins 
+                       \echo eins 
                elif [[ 1 = 2 ]] >&3 
                then
-                       echo zwei 
+                       \echo zwei 
                else
-                       echo drei 
+                       \echo drei 
                fi >&3 
        } 
        function comsub_TIF_TBANG_TDBRACKET_TELIF { x=$(
                if  !  [[  1  =  1  ]]  >&3 ;  then  echo eins;  elif [[ 1 = 2 ]] >&3; then echo zwei  ;else echo drei; fi >&3
        ); }
        function comsub_TIF_TBANG_TDBRACKET_TELIF {
-               x=$(if ! [[ 1 = 1 ]] >&3 ; then echo eins ; elif [[ 1 = 2 ]] >&3 ; then echo zwei ; else echo drei ; fi >&3 ) 
+               x=$(if ! [[ 1 = 1 ]] >&3 ; then \echo eins ; elif [[ 1 = 2 ]] >&3 ; then \echo zwei ; else \echo drei ; fi >&3 ) 
        } 
        function reread_TIF_TBANG_TDBRACKET_TELIF { x=$((
                if  !  [[  1  =  1  ]]  >&3 ;  then  echo eins;  elif [[ 1 = 2 ]] >&3; then echo zwei  ;else echo drei; fi >&3
        )|tr u x); }
        function reread_TIF_TBANG_TDBRACKET_TELIF {
-               x=$(( if ! [[ 1 = 1 ]] >&3 ; then echo eins ; elif [[ 1 = 2 ]] >&3 ; then echo zwei ; else echo drei ; fi >&3 ) | tr u x ) 
+               x=$( ( if ! [[ 1 = 1 ]] >&3 ; then \echo eins ; elif [[ 1 = 2 ]] >&3 ; then \echo zwei ; else \echo drei ; fi >&3 ) | \tr u x ) 
        } 
        inline_TWHILE() {
                i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
        }
        inline_TWHILE() {
                i=1 
-               while let] " i < 10 " >&3 
+               while {
+                             \\builtin let " i < 10 " 
+                     } >&3 
                do
-                       echo $i 
-                       let ++i 
+                       \echo $i 
+                       \let ++i 
                done >&3 
        } 
        function comsub_TWHILE { x=$(
                i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
        ); }
        function comsub_TWHILE {
-               x=$(i=1 ; while let] " i < 10 " >&3 ; do echo $i ; let ++i ; done >&3 ) 
+               x=$(i=1 ; while { \\builtin let " i < 10 " ; } >&3 ; do \echo $i ; \let ++i ; done >&3 ) 
        } 
        function reread_TWHILE { x=$((
                i=1; while (( i < 10 )) >&3; do echo $i; let ++i; done >&3
        )|tr u x); }
        function reread_TWHILE {
-               x=$(( i=1 ; while let] " i < 10 " >&3 ; do echo $i ; let ++i ; done >&3 ) | tr u x ) 
+               x=$( ( i=1 ; while { \\builtin let " i < 10 " ; } >&3 ; do \echo $i ; \let ++i ; done >&3 ) | \tr u x ) 
        } 
        inline_TUNTIL() {
                i=10; until  (( !--i )) >&3 ; do echo $i; done >&3
        }
        inline_TUNTIL() {
                i=10 
-               until let] " !--i " >&3 
+               until {
+                             \\builtin let " !--i " 
+                     } >&3 
                do
-                       echo $i 
+                       \echo $i 
                done >&3 
        } 
        function comsub_TUNTIL { x=$(
                i=10; until  (( !--i )) >&3 ; do echo $i; done >&3
        ); }
        function comsub_TUNTIL {
-               x=$(i=10 ; until let] " !--i " >&3 ; do echo $i ; done >&3 ) 
+               x=$(i=10 ; until { \\builtin let " !--i " ; } >&3 ; do \echo $i ; done >&3 ) 
        } 
        function reread_TUNTIL { x=$((
                i=10; until  (( !--i )) >&3 ; do echo $i; done >&3
        )|tr u x); }
        function reread_TUNTIL {
-               x=$(( i=10 ; until let] " !--i " >&3 ; do echo $i ; done >&3 ) | tr u x ) 
+               x=$( ( i=10 ; until { \\builtin let " !--i " ; } >&3 ; do \echo $i ; done >&3 ) | \tr u x ) 
        } 
        inline_TCOPROC() {
                cat  *  >&3 |&  >&3 ls
        }
        inline_TCOPROC() {
-               cat * >&3 |& 
-               ls >&3 
+               \cat * >&3 |& 
+               \ls >&3 
        } 
        function comsub_TCOPROC { x=$(
                cat  *  >&3 |&  >&3 ls
        ); }
        function comsub_TCOPROC {
-               x=$(cat * >&3 |&  ls >&3 ) 
+               x=$(\cat * >&3 |&  \ls >&3 ) 
        } 
        function reread_TCOPROC { x=$((
                cat  *  >&3 |&  >&3 ls
        )|tr u x); }
        function reread_TCOPROC {
-               x=$(( cat * >&3 |&  ls >&3 ) | tr u x ) 
+               x=$( ( \cat * >&3 |&  \ls >&3 ) | \tr u x ) 
        } 
        inline_TFUNCT_TBRACE_TASYNC() {
                function  korn  {  echo eins; echo >&3 zwei ;  }
@@ -10614,11 +12015,11 @@ expected-stdout:
        }
        inline_TFUNCT_TBRACE_TASYNC() {
                function korn {
-                       echo eins 
-                       echo zwei >&3 
+                       \echo eins 
+                       \echo zwei >&3 
                } 
                bourne() {
-                       logger * >&3 & 
+                       \logger * >&3 & 
                } 
        } 
        function comsub_TFUNCT_TBRACE_TASYNC { x=$(
@@ -10626,32 +12027,32 @@ expected-stdout:
                bourne  ()  {  logger *  >&3 &  }
        ); }
        function comsub_TFUNCT_TBRACE_TASYNC {
-               x=$(function korn { echo eins ; echo zwei >&3 ; } ; bourne() { logger * >&3 &  } ) 
+               x=$(function korn { \echo eins ; \echo zwei >&3 ; } ; bourne() { \logger * >&3 &  } ) 
        } 
        function reread_TFUNCT_TBRACE_TASYNC { x=$((
                function  korn  {  echo eins; echo >&3 zwei ;  }
                bourne  ()  {  logger *  >&3 &  }
        )|tr u x); }
        function reread_TFUNCT_TBRACE_TASYNC {
-               x=$(( function korn { echo eins ; echo zwei >&3 ; } ; bourne() { logger * >&3 &  } ) | tr u x ) 
+               x=$( ( function korn { \echo eins ; \echo zwei >&3 ; } ; bourne() { \logger * >&3 &  } ) | \tr u x ) 
        } 
        inline_COMSUB_EXPRSUB() {
                echo $(true >&3) $((1+ 2))
        }
        inline_COMSUB_EXPRSUB() {
-               echo $(true >&3 ) $((1+ 2)) 
+               \echo $(\true >&3 ) $((1+ 2)) 
        } 
        function comsub_COMSUB_EXPRSUB { x=$(
                echo $(true >&3) $((1+ 2))
        ); }
        function comsub_COMSUB_EXPRSUB {
-               x=$(echo $(true >&3 ) $((1+ 2)) ) 
+               x=$(\echo $(\true >&3 ) $((1+ 2)) ) 
        } 
        function reread_COMSUB_EXPRSUB { x=$((
                echo $(true >&3) $((1+ 2))
        )|tr u x); }
        function reread_COMSUB_EXPRSUB {
-               x=$(( echo $(true >&3 ) $((1+ 2)) ) | tr u x ) 
+               x=$( ( \echo $(\true >&3 ) $((1+ 2)) ) | \tr u x ) 
        } 
 ---
 name: funsub-1
@@ -10698,7 +12099,7 @@ stdin:
        echo "before:   x<$x> y<$y> z<$z> R<$REPLY>"
        x=${|
                local y
-               echo "begin:    x<$x> y<$y> z<$z> R<$REPLY>"
+               echo "start:    x<$x> y<$y> z<$z> R<$REPLY>"
                x=5
                y=6
                z=7
@@ -10713,102 +12114,12 @@ stdin:
        echo ${|true;}$(true).
 expected-stdout:
        before: x<1> y<2> z<3> R<4>
-       begin:  x<1> y<> z<3> R<>
+       start:  x<1> y<> z<3> R<>
        end:    x<5> y<6> z<7> R<8>
        after:  x<8> y<2> z<7> R<4>
        typeset t=$'foo\n\n'
        this used to segfault.
 ---
-name: test-stnze-1
-description:
-       Check that the short form [ $x ] works
-stdin:
-       i=0
-       [ -n $x ]
-       rv=$?; echo $((++i)) $rv
-       [ $x ]
-       rv=$?; echo $((++i)) $rv
-       [ -n "$x" ]
-       rv=$?; echo $((++i)) $rv
-       [ "$x" ]
-       rv=$?; echo $((++i)) $rv
-       x=0
-       [ -n $x ]
-       rv=$?; echo $((++i)) $rv
-       [ $x ]
-       rv=$?; echo $((++i)) $rv
-       [ -n "$x" ]
-       rv=$?; echo $((++i)) $rv
-       [ "$x" ]
-       rv=$?; echo $((++i)) $rv
-       x='1 -a 1 = 2'
-       [ -n $x ]
-       rv=$?; echo $((++i)) $rv
-       [ $x ]
-       rv=$?; echo $((++i)) $rv
-       [ -n "$x" ]
-       rv=$?; echo $((++i)) $rv
-       [ "$x" ]
-       rv=$?; echo $((++i)) $rv
-expected-stdout:
-       1 0
-       2 1
-       3 1
-       4 1
-       5 0
-       6 0
-       7 0
-       8 0
-       9 1
-       10 1
-       11 0
-       12 0
----
-name: test-stnze-2
-description:
-       Check that the short form [[ $x ]] works (ksh93 extension)
-stdin:
-       i=0
-       [[ -n $x ]]
-       rv=$?; echo $((++i)) $rv
-       [[ $x ]]
-       rv=$?; echo $((++i)) $rv
-       [[ -n "$x" ]]
-       rv=$?; echo $((++i)) $rv
-       [[ "$x" ]]
-       rv=$?; echo $((++i)) $rv
-       x=0
-       [[ -n $x ]]
-       rv=$?; echo $((++i)) $rv
-       [[ $x ]]
-       rv=$?; echo $((++i)) $rv
-       [[ -n "$x" ]]
-       rv=$?; echo $((++i)) $rv
-       [[ "$x" ]]
-       rv=$?; echo $((++i)) $rv
-       x='1 -a 1 = 2'
-       [[ -n $x ]]
-       rv=$?; echo $((++i)) $rv
-       [[ $x ]]
-       rv=$?; echo $((++i)) $rv
-       [[ -n "$x" ]]
-       rv=$?; echo $((++i)) $rv
-       [[ "$x" ]]
-       rv=$?; echo $((++i)) $rv
-expected-stdout:
-       1 1
-       2 1
-       3 1
-       4 1
-       5 0
-       6 0
-       7 0
-       8 0
-       9 0
-       10 0
-       11 0
-       12 0
----
 name: event-subst-3
 description:
        Check that '!' substitution in noninteractive mode is ignored
@@ -10820,7 +12131,7 @@ file-setup: file 755 "!false"
        #! /bin/sh
        echo si
 stdin:
-       export PATH=.:$PATH
+       export PATH=.$PATHSEP$PATH
        falsetto
        echo yeap
        !false
@@ -10850,7 +12161,7 @@ file-setup: file 755 "!false"
        #! /bin/sh
        echo si
 stdin:
-       export PATH=.:$PATH
+       export PATH=.$PATHSEP$PATH
        falsetto
        echo yeap
        !false
@@ -10915,6 +12226,7 @@ stdin:
        (mypid=$$; try mypid)
        echo =15
        ) 2>&1 | sed -e 's/^[^]]*]//' -e 's/^[^:]*: *//'
+       exit ${PIPESTATUS[0]}
 expected-stdout:
        y
        =1
@@ -11173,6 +12485,16 @@ stdin:
 expected-stdout:
        fxbar 0
 ---
+name: better-parens-5
+description:
+       Another corner case
+stdin:
+       ( (echo 'fo     o$bar' "baz\$bla\"" m\$eh) | tr a A)
+       ((echo 'fo      o$bar' "baz\$bla\"" m\$eh) | tr a A)
+expected-stdout:
+       fo      o$bAr bAz$blA" m$eh
+       fo      o$bAr bAz$blA" m$eh
+---
 name: echo-test-1
 description:
        Test what the echo builtin does (mksh)
@@ -11252,6 +12574,17 @@ expected-stdout:
        done
 expected-stderr-pattern: /.*-x.*option/
 ---
+name: utilities-getopts-3
+description:
+       Check unsetting OPTARG
+stdin:
+       set -- -x arg -y
+       getopts x:y opt && echo "${OPTARG-unset}"
+       getopts x:y opt && echo "${OPTARG-unset}"
+expected-stdout:
+       arg
+       unset
+---
 name: wcswidth-1
 description:
        Check the new wcswidth feature
@@ -11571,6 +12904,77 @@ expected-stdout:
        after   0='swc' 1='二' 2=''
        = done
 ---
+name: command-pvV-posix-priorities
+description:
+       For POSIX compatibility, command -v should find aliases and reserved
+       words, and command -p[vV] should find aliases, reserved words, and
+       builtins over external commands.
+stdin:
+       PATH=/bin:/usr/bin
+       alias foo="bar baz"
+       bar() { :; }
+       for word in 'if' 'foo' 'bar' 'set' 'true'; do
+               command -v "$word"
+               command -pv "$word"
+               command -V "$word"
+               command -pV "$word"
+       done
+expected-stdout:
+       if
+       if
+       if is a reserved word
+       if is a reserved word
+       alias foo='bar baz'
+       alias foo='bar baz'
+       foo is an alias for 'bar baz'
+       foo is an alias for 'bar baz'
+       bar
+       bar
+       bar is a function
+       bar is a function
+       set
+       set
+       set is a special shell builtin
+       set is a special shell builtin
+       true
+       true
+       true is a shell builtin
+       true is a shell builtin
+---
+name: whence-preserve-tradition
+description:
+       This regression test is to ensure that the POSIX compatibility
+       changes for 'command' (see previous test) do not affect traditional
+       'whence' behaviour.
+category: os:mirbsd
+stdin:
+       PATH=/bin:/usr/bin
+       alias foo="bar baz"
+       bar() { :; }
+       for word in 'if' 'foo' 'bar' 'set' 'true'; do
+               whence "$word"
+               whence -p "$word"
+               whence -v "$word"
+               whence -pv "$word"
+       done
+expected-stdout:
+       if
+       if is a reserved word
+       if not found
+       'bar baz'
+       foo is an alias for 'bar baz'
+       foo not found
+       bar
+       bar is a function
+       bar not found
+       set
+       set is a special shell builtin
+       set not found
+       true
+       /bin/true
+       true is a shell builtin
+       true is a tracked alias for /bin/true
+---
 name: duffs-device
 description:
        Check that the compiler did not optimise-break them
@@ -11643,9 +13047,91 @@ stdin:
        Copyright (C) 2002 Free Software Foundation, Inc.'
        EOF
        chmod +x bash
-       "$__progname" -xc 'foo=$(./bash --version 2>&1 | head -1); echo "=$foo="'
+       "$__progname" -xc 'foo=$(./bash --version 2>&1 | sed q); echo "=$foo="'
 expected-stdout:
        =GNU bash, version 2.05b.0(1)-release (i386-ecce-mirbsd10)=
 expected-stderr-pattern:
        /.*/
 ---
+name: xtrace-2
+description:
+       Check that "set -x" is off during PS4 expansion
+stdin:
+       f() {
+               print -n "(f1:$-)"
+               set -x
+               print -n "(f2:$-)"
+       }
+       PS4='[(p:$-)$(f)] '
+       print "(o0:$-)"
+       set -x -o inherit-xtrace
+       print "(o1:$-)"
+       set +x
+       print "(o2:$-)"
+expected-stdout:
+       (o0:sh)
+       (o1:shx)
+       (o2:sh)
+expected-stderr:
+       [(p:sh)(f1:sh)(f2:sh)] print '(o1:shx)'
+       [(p:sh)(f1:sh)(f2:sh)] set +x
+---
+name: fksh-flags
+description:
+       Check that FKSH functions have their own shell flags
+category: shell:legacy-no
+stdin:
+       [[ $KSH_VERSION = Version* ]] && set +B
+       function foo {
+               set +f
+               set -e
+               echo 2 "${-/s}" .
+       }
+       set -fh
+       echo 1 "${-/s}" .
+       foo
+       echo 3 "${-/s}" .
+expected-stdout:
+       1 fh .
+       2 eh .
+       3 fh .
+---
+name: fksh-flags-legacy
+description:
+       Check that even FKSH functions share the shell flags
+category: shell:legacy-yes
+stdin:
+       [[ $KSH_VERSION = Version* ]] && set +B
+       foo() {
+               set +f
+               set -e
+               echo 2 "${-/s}" .
+       }
+       set -fh
+       echo 1 "${-/s}" .
+       foo
+       echo 3 "${-/s}" .
+expected-stdout:
+       1 fh .
+       2 eh .
+       3 eh .
+---
+name: fsh-flags
+description:
+       Check that !FKSH functions share the shell flags
+stdin:
+       [[ $KSH_VERSION = Version* ]] && set +B
+       foo() {
+               set +f
+               set -e
+               echo 2 "${-/s}" .
+       }
+       set -fh
+       echo 1 "${-/s}" .
+       foo
+       echo 3 "${-/s}" .
+expected-stdout:
+       1 fh .
+       2 eh .
+       3 eh .
+---