diff options
Diffstat (limited to 'bin/sh/tests/parser')
95 files changed, 1213 insertions, 0 deletions
diff --git a/bin/sh/tests/parser/Makefile b/bin/sh/tests/parser/Makefile new file mode 100644 index 000000000000..c22af5414526 --- /dev/null +++ b/bin/sh/tests/parser/Makefile @@ -0,0 +1,98 @@ +PACKAGE= tests + +TESTSDIR= ${TESTSBASE}/bin/sh/${.CURDIR:T} + +.PATH: ${.CURDIR:H} +ATF_TESTS_SH= functional_test + +${PACKAGE}FILES+= alias1.0 +${PACKAGE}FILES+= alias2.0 +${PACKAGE}FILES+= alias3.0 +${PACKAGE}FILES+= alias4.0 +${PACKAGE}FILES+= alias5.0 +${PACKAGE}FILES+= alias6.0 +${PACKAGE}FILES+= alias7.0 +${PACKAGE}FILES+= alias8.0 +${PACKAGE}FILES+= alias9.0 +${PACKAGE}FILES+= alias10.0 +${PACKAGE}FILES+= alias11.0 +${PACKAGE}FILES+= alias12.0 +${PACKAGE}FILES+= alias13.0 +${PACKAGE}FILES+= alias14.0 +${PACKAGE}FILES+= alias15.0 alias15.0.stdout +${PACKAGE}FILES+= alias16.0 +${PACKAGE}FILES+= alias17.0 +${PACKAGE}FILES+= alias18.0 +${PACKAGE}FILES+= alias19.0 alias19.0.stdout +${PACKAGE}FILES+= alias20.0 alias20.0.stdout +${PACKAGE}FILES+= and-pipe-not.0 +${PACKAGE}FILES+= case1.0 +${PACKAGE}FILES+= case2.0 +${PACKAGE}FILES+= comment1.0 +${PACKAGE}FILES+= comment2.42 +${PACKAGE}FILES+= dollar-quote1.0 +${PACKAGE}FILES+= dollar-quote2.0 +${PACKAGE}FILES+= dollar-quote3.0 +${PACKAGE}FILES+= dollar-quote4.0 +${PACKAGE}FILES+= dollar-quote5.0 +${PACKAGE}FILES+= dollar-quote6.0 +${PACKAGE}FILES+= dollar-quote7.0 +${PACKAGE}FILES+= dollar-quote8.0 +${PACKAGE}FILES+= dollar-quote9.0 +${PACKAGE}FILES+= dollar-quote10.0 +${PACKAGE}FILES+= dollar-quote11.0 +${PACKAGE}FILES+= dollar-quote12.0 +${PACKAGE}FILES+= dollar-quote13.0 +${PACKAGE}FILES+= empty-braces1.0 +${PACKAGE}FILES+= empty-cmd1.0 +${PACKAGE}FILES+= for1.0 +${PACKAGE}FILES+= for2.0 +${PACKAGE}FILES+= func1.0 +${PACKAGE}FILES+= func2.0 +${PACKAGE}FILES+= func3.0 +${PACKAGE}FILES+= heredoc1.0 +${PACKAGE}FILES+= heredoc2.0 +${PACKAGE}FILES+= heredoc3.0 +${PACKAGE}FILES+= heredoc4.0 +${PACKAGE}FILES+= heredoc5.0 +${PACKAGE}FILES+= heredoc6.0 +${PACKAGE}FILES+= heredoc7.0 +${PACKAGE}FILES+= heredoc8.0 +${PACKAGE}FILES+= heredoc9.0 +${PACKAGE}FILES+= heredoc10.0 +${PACKAGE}FILES+= heredoc11.0 +${PACKAGE}FILES+= heredoc12.0 +${PACKAGE}FILES+= heredoc13.0 +${PACKAGE}FILES+= heredoc14.0 +${PACKAGE}FILES+= heredoc15.0 +${PACKAGE}FILES+= heredoc16.0 +${PACKAGE}FILES+= line-cont1.0 +${PACKAGE}FILES+= line-cont2.0 +${PACKAGE}FILES+= line-cont3.0 +${PACKAGE}FILES+= line-cont4.0 +${PACKAGE}FILES+= line-cont5.0 +${PACKAGE}FILES+= line-cont6.0 +${PACKAGE}FILES+= line-cont7.0 +${PACKAGE}FILES+= line-cont8.0 +${PACKAGE}FILES+= line-cont9.0 +${PACKAGE}FILES+= line-cont10.0 +${PACKAGE}FILES+= line-cont11.0 +${PACKAGE}FILES+= line-cont12.0 +${PACKAGE}FILES+= no-space1.0 +${PACKAGE}FILES+= no-space2.0 +${PACKAGE}FILES+= nul1.0 +${PACKAGE}FILES+= only-redir1.0 +${PACKAGE}FILES+= only-redir2.0 +${PACKAGE}FILES+= only-redir3.0 +${PACKAGE}FILES+= only-redir4.0 +${PACKAGE}FILES+= pipe-not1.0 +${PACKAGE}FILES+= ps1-expand1.0 +${PACKAGE}FILES+= ps1-expand2.0 +${PACKAGE}FILES+= ps1-expand3.0 +${PACKAGE}FILES+= ps1-expand4.0 +${PACKAGE}FILES+= ps1-expand5.0 +${PACKAGE}FILES+= ps2-expand1.0 +${PACKAGE}FILES+= set-v1.0 set-v1.0.stderr +${PACKAGE}FILES+= var-assign1.0 + +.include <bsd.test.mk> diff --git a/bin/sh/tests/parser/Makefile.depend b/bin/sh/tests/parser/Makefile.depend new file mode 100644 index 000000000000..11aba52f82cf --- /dev/null +++ b/bin/sh/tests/parser/Makefile.depend @@ -0,0 +1,10 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/bin/sh/tests/parser/alias1.0 b/bin/sh/tests/parser/alias1.0 new file mode 100644 index 000000000000..2380bb95e449 --- /dev/null +++ b/bin/sh/tests/parser/alias1.0 @@ -0,0 +1,4 @@ + +alias alias0=exit +eval 'alias0 0' +exit 1 diff --git a/bin/sh/tests/parser/alias10.0 b/bin/sh/tests/parser/alias10.0 new file mode 100644 index 000000000000..d8c77691b2b8 --- /dev/null +++ b/bin/sh/tests/parser/alias10.0 @@ -0,0 +1,8 @@ + +# This test may start consuming memory indefinitely if it fails. +ulimit -t 5 2>/dev/null +ulimit -v 100000 2>/dev/null + +alias echo='echo' +alias echo='echo' +[ "`eval echo b`" = b ] diff --git a/bin/sh/tests/parser/alias11.0 b/bin/sh/tests/parser/alias11.0 new file mode 100644 index 000000000000..286323028a2c --- /dev/null +++ b/bin/sh/tests/parser/alias11.0 @@ -0,0 +1,5 @@ + +alias alias0=alias1 +alias alias1=exit +eval 'alias0 0' +exit 3 diff --git a/bin/sh/tests/parser/alias12.0 b/bin/sh/tests/parser/alias12.0 new file mode 100644 index 000000000000..30be135c0cd1 --- /dev/null +++ b/bin/sh/tests/parser/alias12.0 @@ -0,0 +1,5 @@ + +unalias -a +alias alias0=command +alias true='echo bad' +eval 'alias0 true' diff --git a/bin/sh/tests/parser/alias13.0 b/bin/sh/tests/parser/alias13.0 new file mode 100644 index 000000000000..df35c5045aa5 --- /dev/null +++ b/bin/sh/tests/parser/alias13.0 @@ -0,0 +1,5 @@ + +unalias -a +alias command=command +alias true='echo bad' +eval 'command true' diff --git a/bin/sh/tests/parser/alias14.0 b/bin/sh/tests/parser/alias14.0 new file mode 100644 index 000000000000..20acd59d4d4c --- /dev/null +++ b/bin/sh/tests/parser/alias14.0 @@ -0,0 +1,5 @@ + +alias command='command ' +alias alias0=exit +eval 'command alias0 0' +exit 3 diff --git a/bin/sh/tests/parser/alias15.0 b/bin/sh/tests/parser/alias15.0 new file mode 100644 index 000000000000..19a1a36eaaff --- /dev/null +++ b/bin/sh/tests/parser/alias15.0 @@ -0,0 +1,11 @@ + +f_echoanddo() { + printf '%s\n' "$*" + "$@" +} + +alias echoanddo='f_echoanddo ' +alias alias0='echo test2' +eval 'echoanddo echo test1' +eval 'echoanddo alias0' +exit 0 diff --git a/bin/sh/tests/parser/alias15.0.stdout b/bin/sh/tests/parser/alias15.0.stdout new file mode 100644 index 000000000000..6dd179c065a7 --- /dev/null +++ b/bin/sh/tests/parser/alias15.0.stdout @@ -0,0 +1,4 @@ +echo test1 +test1 +echo test2 +test2 diff --git a/bin/sh/tests/parser/alias16.0 b/bin/sh/tests/parser/alias16.0 new file mode 100644 index 000000000000..b611c69ab04f --- /dev/null +++ b/bin/sh/tests/parser/alias16.0 @@ -0,0 +1,6 @@ + +v=1 +alias a='unalias a +v=2' +eval a +[ "$v" = 2 ] diff --git a/bin/sh/tests/parser/alias17.0 b/bin/sh/tests/parser/alias17.0 new file mode 100644 index 000000000000..c2e24c68aa5f --- /dev/null +++ b/bin/sh/tests/parser/alias17.0 @@ -0,0 +1,6 @@ + +v=1 +alias a='unalias -a +v=2' +eval a +[ "$v" = 2 ] diff --git a/bin/sh/tests/parser/alias18.0 b/bin/sh/tests/parser/alias18.0 new file mode 100644 index 000000000000..05117c5a830f --- /dev/null +++ b/bin/sh/tests/parser/alias18.0 @@ -0,0 +1,7 @@ + +v=1 +alias a='alias a=v=2 +v=3 +a' +eval a +[ "$v" = 2 ] diff --git a/bin/sh/tests/parser/alias19.0 b/bin/sh/tests/parser/alias19.0 new file mode 100644 index 000000000000..c35930e9835d --- /dev/null +++ b/bin/sh/tests/parser/alias19.0 @@ -0,0 +1,7 @@ + +alias begin={ end=} +begin +cat <<EOF +$(echo ok) +EOF +end diff --git a/bin/sh/tests/parser/alias19.0.stdout b/bin/sh/tests/parser/alias19.0.stdout new file mode 100644 index 000000000000..9766475a4185 --- /dev/null +++ b/bin/sh/tests/parser/alias19.0.stdout @@ -0,0 +1 @@ +ok diff --git a/bin/sh/tests/parser/alias2.0 b/bin/sh/tests/parser/alias2.0 new file mode 100644 index 000000000000..e92d62eaefdc --- /dev/null +++ b/bin/sh/tests/parser/alias2.0 @@ -0,0 +1,5 @@ + +alias alias0=exit +x=alias0 +eval 'case $x in alias0) exit 0;; esac' +exit 1 diff --git a/bin/sh/tests/parser/alias20.0 b/bin/sh/tests/parser/alias20.0 new file mode 100644 index 000000000000..7e1767eaccd8 --- /dev/null +++ b/bin/sh/tests/parser/alias20.0 @@ -0,0 +1,8 @@ + +alias begin={ end=} +: <<EOF && +$(echo bad1) +EOF +begin +echo ok +end diff --git a/bin/sh/tests/parser/alias20.0.stdout b/bin/sh/tests/parser/alias20.0.stdout new file mode 100644 index 000000000000..9766475a4185 --- /dev/null +++ b/bin/sh/tests/parser/alias20.0.stdout @@ -0,0 +1 @@ +ok diff --git a/bin/sh/tests/parser/alias3.0 b/bin/sh/tests/parser/alias3.0 new file mode 100644 index 000000000000..4651ba149c60 --- /dev/null +++ b/bin/sh/tests/parser/alias3.0 @@ -0,0 +1,5 @@ + +alias alias0=exit +x=alias0 +eval 'case $x in "alias0") alias0 0;; esac' +exit 1 diff --git a/bin/sh/tests/parser/alias4.0 b/bin/sh/tests/parser/alias4.0 new file mode 100644 index 000000000000..a46923d1ebdd --- /dev/null +++ b/bin/sh/tests/parser/alias4.0 @@ -0,0 +1,4 @@ + +alias alias0=exit +eval 'x=1 alias0 0' +exit 1 diff --git a/bin/sh/tests/parser/alias5.0 b/bin/sh/tests/parser/alias5.0 new file mode 100644 index 000000000000..4c393cd116d9 --- /dev/null +++ b/bin/sh/tests/parser/alias5.0 @@ -0,0 +1,4 @@ + +alias alias0=exit +eval '</dev/null alias0 0' +exit 1 diff --git a/bin/sh/tests/parser/alias6.0 b/bin/sh/tests/parser/alias6.0 new file mode 100644 index 000000000000..23c3d39de002 --- /dev/null +++ b/bin/sh/tests/parser/alias6.0 @@ -0,0 +1,5 @@ + +alias alias0='| cat >/dev/null' + +eval '{ echo bad; } alias0' +eval '(echo bad)alias0' diff --git a/bin/sh/tests/parser/alias7.0 b/bin/sh/tests/parser/alias7.0 new file mode 100644 index 000000000000..f644ceaa7abd --- /dev/null +++ b/bin/sh/tests/parser/alias7.0 @@ -0,0 +1,3 @@ + +alias echo='echo a' +[ "`eval echo b`" = "a b" ] diff --git a/bin/sh/tests/parser/alias8.0 b/bin/sh/tests/parser/alias8.0 new file mode 100644 index 000000000000..c71997f362cf --- /dev/null +++ b/bin/sh/tests/parser/alias8.0 @@ -0,0 +1,3 @@ + +alias echo='echo' +[ "`eval echo b`" = b ] diff --git a/bin/sh/tests/parser/alias9.0 b/bin/sh/tests/parser/alias9.0 new file mode 100644 index 000000000000..50fe86e2b8fd --- /dev/null +++ b/bin/sh/tests/parser/alias9.0 @@ -0,0 +1,5 @@ + +alias alias0=: +alias alias0=exit +eval 'alias0 0' +exit 1 diff --git a/bin/sh/tests/parser/and-pipe-not.0 b/bin/sh/tests/parser/and-pipe-not.0 new file mode 100644 index 000000000000..90889bfe62f6 --- /dev/null +++ b/bin/sh/tests/parser/and-pipe-not.0 @@ -0,0 +1 @@ +true && ! true | false diff --git a/bin/sh/tests/parser/case1.0 b/bin/sh/tests/parser/case1.0 new file mode 100644 index 000000000000..8b4e1c342a68 --- /dev/null +++ b/bin/sh/tests/parser/case1.0 @@ -0,0 +1,13 @@ + +keywords='if then else elif fi while until for do done { } case esac ! in' + +# Keywords can be used unquoted in case statements, except the keyword +# esac as the first pattern of a '|' alternation without a starting '('. +# (POSIX doesn't seem to require (esac) to work.) +for k in $keywords; do + eval "case $k in (foo|$k) ;; *) echo bad ;; esac" + eval "case $k in ($k) ;; *) echo bad ;; esac" + eval "case $k in foo|$k) ;; *) echo bad ;; esac" + [ "$k" = esac ] && continue + eval "case $k in $k) ;; *) echo bad ;; esac" +done diff --git a/bin/sh/tests/parser/case2.0 b/bin/sh/tests/parser/case2.0 new file mode 100644 index 000000000000..578187a5a320 --- /dev/null +++ b/bin/sh/tests/parser/case2.0 @@ -0,0 +1,31 @@ + +# Pretty much only ash derivatives can parse all of this. + +f1() { + x=$(case x in + (x|esac) ;; + (*) echo bad >&2 ;; + esac) +} +f1 +f2() { + x=$(case x in + (x|esac) ;; + (*) echo bad >&2 + esac) +} +f2 +f3() { + x=$(case x in + x|esac) ;; + *) echo bad >&2 ;; + esac) +} +f3 +f4() { + x=$(case x in + x|esac) ;; + *) echo bad >&2 + esac) +} +f4 diff --git a/bin/sh/tests/parser/comment1.0 b/bin/sh/tests/parser/comment1.0 new file mode 100644 index 000000000000..59904fb98ced --- /dev/null +++ b/bin/sh/tests/parser/comment1.0 @@ -0,0 +1,2 @@ + +${SH} -c '#' diff --git a/bin/sh/tests/parser/comment2.42 b/bin/sh/tests/parser/comment2.42 new file mode 100644 index 000000000000..30ab4c4d1df5 --- /dev/null +++ b/bin/sh/tests/parser/comment2.42 @@ -0,0 +1,3 @@ + +${SH} -c '# +exit 42' diff --git a/bin/sh/tests/parser/dollar-quote1.0 b/bin/sh/tests/parser/dollar-quote1.0 new file mode 100644 index 000000000000..2862b8a20b09 --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote1.0 @@ -0,0 +1,11 @@ + +set -e + +[ $'hi' = hi ] +[ $'hi +there' = 'hi +there' ] +[ $'\"\'\\\a\b\f\t\v' = "\"'\\$(printf "\a\b\f\t\v")" ] +[ $'hi\nthere' = 'hi +there' ] +[ $'a\rb' = "$(printf "a\rb")" ] diff --git a/bin/sh/tests/parser/dollar-quote10.0 b/bin/sh/tests/parser/dollar-quote10.0 new file mode 100644 index 000000000000..e28ea482ac23 --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote10.0 @@ -0,0 +1,9 @@ + +# a umlaut +s=$(printf '\303\244') +# euro sign +s=$s$(printf '\342\202\254') + +# Start a new shell so the locale change is picked up. +ss="$(LC_ALL=en_US.UTF-8 ${SH} -c "printf %s \$'\u00e4\u20ac'")" +[ "$s" = "$ss" ] diff --git a/bin/sh/tests/parser/dollar-quote11.0 b/bin/sh/tests/parser/dollar-quote11.0 new file mode 100644 index 000000000000..de567ebeed43 --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote11.0 @@ -0,0 +1,7 @@ + +# some sort of 't' outside BMP +s=$s$(printf '\360\235\225\245') + +# Start a new shell so the locale change is picked up. +ss="$(LC_ALL=en_US.UTF-8 ${SH} -c "printf %s \$'\U0001d565'")" +[ "$s" = "$ss" ] diff --git a/bin/sh/tests/parser/dollar-quote12.0 b/bin/sh/tests/parser/dollar-quote12.0 new file mode 100644 index 000000000000..a6207d29a2ba --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote12.0 @@ -0,0 +1,6 @@ + +# \u without any digits at all remains invalid. +# Our choice is a parse error. + +v=$( (eval ": \$'\u'") 2>&1 >/dev/null) +[ $? -ne 0 ] && [ -n "$v" ] diff --git a/bin/sh/tests/parser/dollar-quote13.0 b/bin/sh/tests/parser/dollar-quote13.0 new file mode 100644 index 000000000000..d042ad741646 --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote13.0 @@ -0,0 +1,7 @@ + +# This Unicode escape sequence that has never been in range should either +# fail to expand or expand to a fallback. + +c=$(eval printf %s \$\'\\Uffffff41\' 2>/dev/null) +r=$(($? != 0)) +[ "$r.$c" = '1.' ] || [ "$r.$c" = '0.?' ] || [ "$r.$c" = $'0.\u2222' ] diff --git a/bin/sh/tests/parser/dollar-quote2.0 b/bin/sh/tests/parser/dollar-quote2.0 new file mode 100644 index 000000000000..87a1b39a62ba --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote2.0 @@ -0,0 +1,4 @@ + +# This depends on the ASCII character set. + +[ $'\e' = "$(printf "\033")" ] diff --git a/bin/sh/tests/parser/dollar-quote3.0 b/bin/sh/tests/parser/dollar-quote3.0 new file mode 100644 index 000000000000..9ac5afb6d2bc --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote3.0 @@ -0,0 +1,21 @@ + +unset LC_ALL +LC_CTYPE=en_US.ISO8859-1 +export LC_CTYPE + +e= +for i in 0 1 2 3; do + for j in 0 1 2 3 4 5 6 7; do + for k in 0 1 2 3 4 5 6 7; do + case $i$j$k in + 000) continue ;; + esac + e="$e\\$i$j$k" + done + done +done +ee=`printf "$e"` +[ "${#ee}" = 255 ] || echo length bad + +# Start a new shell so the locale change is picked up. +[ "$(${SH} -c "printf %s \$'$e'")" = "$ee" ] diff --git a/bin/sh/tests/parser/dollar-quote4.0 b/bin/sh/tests/parser/dollar-quote4.0 new file mode 100644 index 000000000000..be0de8bbb508 --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote4.0 @@ -0,0 +1,18 @@ + +unset LC_ALL +LC_CTYPE=en_US.ISO8859-1 +export LC_CTYPE + +e= +for i in 0 1 2 3 4 5 6 7 8 9 a b c d e f; do + for j in 0 1 2 3 4 5 6 7 8 9 a b c d e f; do + case $i$j in + 00) continue ;; + esac + e="$e\x$i$j" + done +done + +# Start a new shell so the locale change is picked up. +ee="$(${SH} -c "printf %s \$'$e'")" +[ "${#ee}" = 255 ] || echo length bad diff --git a/bin/sh/tests/parser/dollar-quote5.0 b/bin/sh/tests/parser/dollar-quote5.0 new file mode 100644 index 000000000000..2bf6a0ea2183 --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote5.0 @@ -0,0 +1,11 @@ + +# This depends on the ASCII character set. + +set -e + +[ $'\ca\cb\cc\cd\ce\cf\cg\ch\ci\cj\ck\cl\cm\cn\co\cp\cq\cr\cs\ct\cu\cv\cw\cx\cy\cz' = $'\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032' ] +[ $'\cA\cB\cC\cD\cE\cF\cG\cH\cI\cJ\cK\cL\cM\cN\cO\cP\cQ\cR\cS\cT\cU\cV\cW\cX\cY\cZ' = $'\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032' ] +[ $'\c[' = $'\033' ] +[ $'\c]' = $'\035' ] +[ $'\c^' = $'\036' ] +[ $'\c_' = $'\037' ] diff --git a/bin/sh/tests/parser/dollar-quote6.0 b/bin/sh/tests/parser/dollar-quote6.0 new file mode 100644 index 000000000000..dc6f8ab45cf2 --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote6.0 @@ -0,0 +1,4 @@ + +# This depends on the ASCII character set. + +[ $'\c\\' = $'\034' ] diff --git a/bin/sh/tests/parser/dollar-quote7.0 b/bin/sh/tests/parser/dollar-quote7.0 new file mode 100644 index 000000000000..5108fd4eb146 --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote7.0 @@ -0,0 +1,5 @@ + +set -e + +[ $'\u0024\u0040\u0060' = '$@`' ] +[ $'\U00000024\U00000040\U00000060' = '$@`' ] diff --git a/bin/sh/tests/parser/dollar-quote8.0 b/bin/sh/tests/parser/dollar-quote8.0 new file mode 100644 index 000000000000..81dcb9b394f7 --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote8.0 @@ -0,0 +1,10 @@ + +[ $'hello\0' = hello ] +[ $'hello\0world' = hello ] +[ $'hello\0'$'world' = helloworld ] +[ $'hello\000' = hello ] +[ $'hello\000world' = hello ] +[ $'hello\000'$'world' = helloworld ] +[ $'hello\x00' = hello ] +[ $'hello\x00world' = hello ] +[ $'hello\x00'$'world' = helloworld ] diff --git a/bin/sh/tests/parser/dollar-quote9.0 b/bin/sh/tests/parser/dollar-quote9.0 new file mode 100644 index 000000000000..845f8c284326 --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote9.0 @@ -0,0 +1,7 @@ + +# POSIX and C99 say D800-DFFF are undefined in a universal character name. +# We reject this but many other shells expand to something that looks like +# CESU-8. + +v=$( (eval ": \$'\uD800'") 2>&1 >/dev/null) +[ $? -ne 0 ] && [ -n "$v" ] diff --git a/bin/sh/tests/parser/empty-braces1.0 b/bin/sh/tests/parser/empty-braces1.0 new file mode 100644 index 000000000000..11032811c80e --- /dev/null +++ b/bin/sh/tests/parser/empty-braces1.0 @@ -0,0 +1,6 @@ + +# Unfortunately, some scripts depend on the extension of allowing an empty +# pair of braces. + +{ } & +wait $! diff --git a/bin/sh/tests/parser/empty-cmd1.0 b/bin/sh/tests/parser/empty-cmd1.0 new file mode 100644 index 000000000000..15f4f4ac995b --- /dev/null +++ b/bin/sh/tests/parser/empty-cmd1.0 @@ -0,0 +1,2 @@ + +! (eval ': || f()') 2>/dev/null diff --git a/bin/sh/tests/parser/for1.0 b/bin/sh/tests/parser/for1.0 new file mode 100644 index 000000000000..1633385068c2 --- /dev/null +++ b/bin/sh/tests/parser/for1.0 @@ -0,0 +1,28 @@ + +nl=' +' +list=' a b c' +for s1 in "$nl" " "; do + for s2 in "$nl" ";" ";$nl"; do + for s3 in "$nl" " "; do + r='' + eval "for i${s1}in ${list}${s2}do${s3}r=\"\$r \$i\"; done" + [ "$r" = "$list" ] || exit 1 + done + done +done +set -- $list +for s2 in "$nl" " "; do + for s3 in "$nl" " "; do + r='' + eval "for i${s2}do${s3}r=\"\$r \$i\"; done" + [ "$r" = "$list" ] || exit 1 + done +done +for s1 in "$nl" " "; do + for s2 in "$nl" ";" ";$nl"; do + for s3 in "$nl" " "; do + eval "for i${s1}in${s2}do${s3}exit 1; done" + done + done +done diff --git a/bin/sh/tests/parser/for2.0 b/bin/sh/tests/parser/for2.0 new file mode 100644 index 000000000000..2dd2d5acd1c3 --- /dev/null +++ b/bin/sh/tests/parser/for2.0 @@ -0,0 +1,14 @@ + +# Common extensions to the 'for' syntax. + +nl=' +' +list=' a b c' +set -- $list +for s2 in ";" ";$nl"; do + for s3 in "$nl" " "; do + r='' + eval "for i${s2}do${s3}r=\"\$r \$i\"; done" + [ "$r" = "$list" ] || exit 1 + done +done diff --git a/bin/sh/tests/parser/func1.0 b/bin/sh/tests/parser/func1.0 new file mode 100644 index 000000000000..93381364aa6c --- /dev/null +++ b/bin/sh/tests/parser/func1.0 @@ -0,0 +1,24 @@ +# POSIX does not require these bytes to work in function names, +# but making them all work seems a good goal. + +failures=0 +unset LC_ALL +export LC_CTYPE=en_US.ISO8859-1 +i=128 +set -f +while [ "$i" -le 255 ]; do + c=$(printf \\"$(printf %o "$i")") + ok=0 + eval "$c() { ok=1; }" + $c + ok1=$ok + ok=0 + "$c" + if [ "$ok" != 1 ] || [ "$ok1" != 1 ]; then + echo "Bad results for character $i" >&2 + : $((failures += 1)) + fi + unset -f $c + i=$((i+1)) +done +exit $((failures > 0)) diff --git a/bin/sh/tests/parser/func2.0 b/bin/sh/tests/parser/func2.0 new file mode 100644 index 000000000000..dc9eb6ed1579 --- /dev/null +++ b/bin/sh/tests/parser/func2.0 @@ -0,0 +1,5 @@ + +f() { return 42; } +f() { return 3; } & +f +[ $? -eq 42 ] diff --git a/bin/sh/tests/parser/func3.0 b/bin/sh/tests/parser/func3.0 new file mode 100644 index 000000000000..c1462a33c80c --- /dev/null +++ b/bin/sh/tests/parser/func3.0 @@ -0,0 +1,5 @@ + +name=/var/empty/nosuch +f() { true; } <$name +name=/dev/null +f diff --git a/bin/sh/tests/parser/heredoc1.0 b/bin/sh/tests/parser/heredoc1.0 new file mode 100644 index 000000000000..6bfee605633a --- /dev/null +++ b/bin/sh/tests/parser/heredoc1.0 @@ -0,0 +1,84 @@ + +failures=0 + +check() { + if ! eval "[ $* ]"; then + echo "Failed: $*" + : $((failures += 1)) + fi +} + +check '"$(cat <<EOF +hi +EOF +)" = hi' + +check '"$(cat <<EOF +${$+hi} +EOF +)" = hi' + +unset yy +check '"$(cat <<EOF +${yy-hi} +EOF +)" = hi' + +check '"$(cat <<EOF +${$+hi +there} +EOF +)" = "hi +there"' + +check '"$(cat <<EOF +$((1+1)) +EOF +)" = 2' + +check '"$(cat <<EOF +$(echo hi) +EOF +)" = hi' + +check '"$(cat <<EOF +`echo hi` +EOF +)" = hi' + +check '"$(cat <<\EOF +${$+hi} +EOF +)" = "\${\$+hi}"' + +check '"$(cat <<\EOF +$( +EOF +)" = \$\(' + +check '"$(cat <<\EOF +` +EOF +)" = \`' + +check '"$(cat <<EOF +" +EOF +)" = \"' + +check '"$(cat <<\EOF +" +EOF +)" = \"' + +check '"$(cat <<esac +'"'"' +esac +)" = "'"'"'"' + +check '"$(cat <<\) +'"'"' +) +)" = "'"'"'"' + +exit $((failures != 0)) diff --git a/bin/sh/tests/parser/heredoc10.0 b/bin/sh/tests/parser/heredoc10.0 new file mode 100644 index 000000000000..95e280381bd3 --- /dev/null +++ b/bin/sh/tests/parser/heredoc10.0 @@ -0,0 +1,48 @@ + +# It may be argued that +# x=$(cat <<EOF +# foo +# EOF) +# is a valid complete command that sets x to foo, because +# cat <<EOF +# foo +# EOF +# is a valid script even without the final newline. +# However, if the here-document is not within a new-style command substitution +# or there are other constructs nested inside the command substitution that +# need terminators, the delimiter at the start of a line followed by a close +# parenthesis is clearly a literal part of the here-document. + +# This file contains tests that may not work with simplistic $(...) parsers. +# The open parentheses in comments help mksh, but not zsh. + +failures=0 + +check() { + if ! eval "[ $* ]"; then + echo "Failed: $*" + : $((failures += 1)) + fi +} + +check '"$(cat <<EOF # ( +EOF ) +EOF +)" = "EOF )"' + +check '"$({ cat <<EOF # ( +EOF) +EOF +})" = "EOF)"' + +check '"$(if :; then cat <<EOF # ( +EOF) +EOF +fi)" = "EOF)"' + +check '"$( (cat <<EOF # ( +EOF) +EOF +))" = "EOF)"' + +exit $((failures != 0)) diff --git a/bin/sh/tests/parser/heredoc11.0 b/bin/sh/tests/parser/heredoc11.0 new file mode 100644 index 000000000000..71bf7c017df4 --- /dev/null +++ b/bin/sh/tests/parser/heredoc11.0 @@ -0,0 +1,25 @@ + +failures='' + +check() { + if eval "[ $* ]"; then + : + else + echo "Failed: $*" + failures=x$failures + fi +} + +check '`cat <<EOF +foo +EOF` = foo' + +check '"`cat <<EOF +foo +EOF`" = foo' + +check '`eval "cat <<EOF +foo +EOF"` = foo' + +test "x$failures" = x diff --git a/bin/sh/tests/parser/heredoc12.0 b/bin/sh/tests/parser/heredoc12.0 new file mode 100644 index 000000000000..0209a94d5f40 --- /dev/null +++ b/bin/sh/tests/parser/heredoc12.0 @@ -0,0 +1,46 @@ + +failures=0 + +check() { + if ! eval "[ $* ]"; then + echo "Failed: $*" + : $((failures += 1)) + fi +} + +longmark=`printf %01000d 4` +longmarkstripped=`printf %0999d 0` + +check '"$(cat <<'"$longmark +$longmark"' +echo yes)" = "yes"' + +check '"$(cat <<\'"$longmark +$longmark"' +echo yes)" = "yes"' + +check '"$(cat <<'"$longmark +yes +$longmark"' +)" = "yes"' + +check '"$(cat <<\'"$longmark +yes +$longmark"' +)" = "yes"' + +check '"$(cat <<'"$longmark +$longmarkstripped +$longmark. +$longmark"' +)" = "'"$longmarkstripped +$longmark."'"' + +check '"$(cat <<\'"$longmark +$longmarkstripped +$longmark. +$longmark"' +)" = "'"$longmarkstripped +$longmark."'"' + +exit $((failures != 0)) diff --git a/bin/sh/tests/parser/heredoc13.0 b/bin/sh/tests/parser/heredoc13.0 new file mode 100644 index 000000000000..1a3de0572142 --- /dev/null +++ b/bin/sh/tests/parser/heredoc13.0 @@ -0,0 +1,20 @@ + +failures=0 + +check() { + if ! eval "[ $* ]"; then + echo "Failed: $*" + : $((failures += 1)) + fi +} + +check '"$(cat <<"" + +echo yes)" = "yes"' + +check '"$(cat <<"" +yes + +)" = "yes"' + +exit $((failures != 0)) diff --git a/bin/sh/tests/parser/heredoc14.0 b/bin/sh/tests/parser/heredoc14.0 new file mode 100644 index 000000000000..036be53dc0c9 --- /dev/null +++ b/bin/sh/tests/parser/heredoc14.0 @@ -0,0 +1,8 @@ +# +read x <<EOF; for i in "$x" +value +EOF +do + x=$x.$i +done +[ "$x" = value.value ] diff --git a/bin/sh/tests/parser/heredoc15.0 b/bin/sh/tests/parser/heredoc15.0 new file mode 100644 index 000000000000..94c5c5f31b18 --- /dev/null +++ b/bin/sh/tests/parser/heredoc15.0 @@ -0,0 +1,9 @@ +# +set -- dummy +read x <<EOF; for i +value +EOF +do + x=$x.$i +done +[ "$x" = value.dummy ] diff --git a/bin/sh/tests/parser/heredoc16.0 b/bin/sh/tests/parser/heredoc16.0 new file mode 100644 index 000000000000..84e5e02ae3e1 --- /dev/null +++ b/bin/sh/tests/parser/heredoc16.0 @@ -0,0 +1,8 @@ +# +read x <<EOF; case $x +value +EOF +in + value) x=$x.extended +esac +[ "$x" = value.extended ] diff --git a/bin/sh/tests/parser/heredoc2.0 b/bin/sh/tests/parser/heredoc2.0 new file mode 100644 index 000000000000..8b936bcb3799 --- /dev/null +++ b/bin/sh/tests/parser/heredoc2.0 @@ -0,0 +1,38 @@ + +failures=0 + +check() { + if ! eval "[ $* ]"; then + echo "Failed: $*" + : $((failures += 1)) + fi +} + +s='ast*que?non' sq=\' dq=\" + +check '"$(cat <<EOF +${s} +EOF +)" = "ast*que?non"' + +check '"$(cat <<EOF +${s+'$sq'x'$sq'} +EOF +)" = ${sq}x${sq}' + +check '"$(cat <<EOF +${s#ast} +EOF +)" = "*que?non"' + +check '"$(cat <<EOF +${s##"ast"} +EOF +)" = "*que?non"' + +check '"$(cat <<EOF +${s##'$sq'ast'$sq'} +EOF +)" = "*que?non"' + +exit $((failures != 0)) diff --git a/bin/sh/tests/parser/heredoc3.0 b/bin/sh/tests/parser/heredoc3.0 new file mode 100644 index 000000000000..dabd0650bd56 --- /dev/null +++ b/bin/sh/tests/parser/heredoc3.0 @@ -0,0 +1,6 @@ + +# This may be expected to work, but pretty much only ash derivatives allow it. + +test "$(cat <<EOF)" = "hi there" +hi there +EOF diff --git a/bin/sh/tests/parser/heredoc4.0 b/bin/sh/tests/parser/heredoc4.0 new file mode 100644 index 000000000000..46262887d707 --- /dev/null +++ b/bin/sh/tests/parser/heredoc4.0 @@ -0,0 +1,43 @@ + +failures=0 + +check() { + if ! eval "[ $* ]"; then + echo "Failed: $*" + : $((failures += 1)) + fi +} + +f() { + cat <<EOF && echo `echo bar` +foo +EOF +} +check '"`f`" = "foo +bar"' + +f() { + cat <<EOF && echo $(echo bar) +foo +EOF +} +check '"$(f)" = "foo +bar"' + +f() { + echo `echo bar` && cat <<EOF +foo +EOF +} +check '"`f`" = "bar +foo"' + +f() { + echo $(echo bar) && cat <<EOF +foo +EOF +} +check '"$(f)" = "bar +foo"' + +exit $((failures != 0)) diff --git a/bin/sh/tests/parser/heredoc5.0 b/bin/sh/tests/parser/heredoc5.0 new file mode 100644 index 000000000000..a336205acf75 --- /dev/null +++ b/bin/sh/tests/parser/heredoc5.0 @@ -0,0 +1,55 @@ + +failures=0 + +check() { + if ! eval "[ $* ]"; then + echo "Failed: $*" + : $((failures += 1)) + fi +} + +f() { + cat <<EOF && echo `cat <<EOF +bar +EOF +` +foo +EOF +} +check '"`f`" = "foo +bar"' + +f() { + cat <<EOF && echo $(cat <<EOF +bar +EOF +) +foo +EOF +} +check '"$(f)" = "foo +bar"' + +f() { + echo `cat <<EOF +bar +EOF +` && cat <<EOF +foo +EOF +} +check '"`f`" = "bar +foo"' + +f() { + echo $(cat <<EOF +bar +EOF +) && cat <<EOF +foo +EOF +} +check '"$(f)" = "bar +foo"' + +exit $((failures != 0)) diff --git a/bin/sh/tests/parser/heredoc6.0 b/bin/sh/tests/parser/heredoc6.0 new file mode 100644 index 000000000000..24570bcfd42f --- /dev/null +++ b/bin/sh/tests/parser/heredoc6.0 @@ -0,0 +1,4 @@ + +r= +! command eval ": <<EOF; )" 2>/dev/null; command eval : hi \${r:=0} +exit ${r:-3} diff --git a/bin/sh/tests/parser/heredoc7.0 b/bin/sh/tests/parser/heredoc7.0 new file mode 100644 index 000000000000..821e89700389 --- /dev/null +++ b/bin/sh/tests/parser/heredoc7.0 @@ -0,0 +1,18 @@ + +# Some of these created malformed parse trees with null pointers for here +# documents, causing the here document writing process to segfault. +eval ': <<EOF' +eval ': <<EOF;' +eval '`: <<EOF`' +eval '`: <<EOF;`' +eval '`: <<EOF`;' +eval '`: <<EOF;`;' + +# Some of these created malformed parse trees with null pointers for here +# documents, causing sh to segfault. +eval ': <<\EOF' +eval ': <<\EOF;' +eval '`: <<\EOF`' +eval '`: <<\EOF;`' +eval '`: <<\EOF`;' +eval '`: <<\EOF;`;' diff --git a/bin/sh/tests/parser/heredoc8.0 b/bin/sh/tests/parser/heredoc8.0 new file mode 100644 index 000000000000..673fc270fa32 --- /dev/null +++ b/bin/sh/tests/parser/heredoc8.0 @@ -0,0 +1,19 @@ + +failures=0 + +check() { + if ! eval "[ $* ]"; then + echo "Failed: $*" + : $((failures += 1)) + fi +} + +s='ast*que?non' sq=\' dq=\" + +# This is possibly useful but differs from other shells. +check '"$(cat <<EOF +${s+"x"} +EOF +)" = ${dq}x${dq}' + +exit $((failures != 0)) diff --git a/bin/sh/tests/parser/heredoc9.0 b/bin/sh/tests/parser/heredoc9.0 new file mode 100644 index 000000000000..d071bf51ef15 --- /dev/null +++ b/bin/sh/tests/parser/heredoc9.0 @@ -0,0 +1,57 @@ + +# It may be argued that +# x=$(cat <<EOF +# foo +# EOF) +# is a valid complete command that sets x to foo, because +# cat <<EOF +# foo +# EOF +# is a valid script even without the final newline. +# However, if the here-document is not within a new-style command substitution +# or there are other constructs nested inside the command substitution that +# need terminators, the delimiter at the start of a line followed by a close +# parenthesis is clearly a literal part of the here-document. + +# This file contains tests that also work with simplistic $(...) parsers. + +failures=0 + +check() { + if ! eval "[ $* ]"; then + echo "Failed: $*" + : $((failures += 1)) + fi +} + +check '`${SH} -c "cat <<EOF +EOF) +EOF +"` = "EOF)"' + +check '`${SH} -c "(cat <<EOF +EOF) +EOF +)"` = "EOF)"' + +check '"`cat <<EOF +EOF x +EOF +`" = "EOF x"' + +check '"`cat <<EOF +EOF ) +EOF +`" = "EOF )"' + +check '"`cat <<EOF +EOF) +EOF +`" = "EOF)"' + +check '"$(cat <<EOF +EOF x +EOF +)" = "EOF x"' + +exit $((failures != 0)) diff --git a/bin/sh/tests/parser/line-cont1.0 b/bin/sh/tests/parser/line-cont1.0 new file mode 100644 index 000000000000..c130070e3769 --- /dev/null +++ b/bin/sh/tests/parser/line-cont1.0 @@ -0,0 +1,15 @@ + +i\ +f +t\ +r\ +u\ +e +t\ +h\ +e\ +n +: +\ +f\ +i diff --git a/bin/sh/tests/parser/line-cont10.0 b/bin/sh/tests/parser/line-cont10.0 new file mode 100644 index 000000000000..d416e4241468 --- /dev/null +++ b/bin/sh/tests/parser/line-cont10.0 @@ -0,0 +1,17 @@ + +v=XaaaXbbbX +[ "${v\ +#\ +*\ +a}.${v\ +#\ +#\ +*\ +a}.${v\ +%\ +b\ +*}.${v\ +%\ +%\ +b\ +*}" = aaXbbbX.XbbbX.XaaaXbb.XaaaX ] diff --git a/bin/sh/tests/parser/line-cont11.0 b/bin/sh/tests/parser/line-cont11.0 new file mode 100644 index 000000000000..e1c2245b7566 --- /dev/null +++ b/bin/sh/tests/parser/line-cont11.0 @@ -0,0 +1,22 @@ + +T=$(mktemp "${TMPDIR:-/tmp}/sh-test.XXXXXXXX") || exit +trap 'rm -f -- "$T"' 0 +w='#A' +# A naive pgetc_linecont() would push back two characters here, which +# fails if a new buffer is read between the two characters. +c='${w#\#}' +c=$c$c$c$c +c=$c$c$c$c +c=$c$c$c$c +c=$c$c$c$c +c=$c$c$c$c +c=$c$c$c$c +printf 'v=%s\n' "$c" >"$T" +. "$T" +if [ "${#v}" != 4096 ]; then + echo "Length is bad (${#v})" + exit 3 +fi +case $v in +*[!A]*) echo "Content is bad"; exit 3 ;; +esac diff --git a/bin/sh/tests/parser/line-cont12.0 b/bin/sh/tests/parser/line-cont12.0 new file mode 100644 index 000000000000..2028a2ee6def --- /dev/null +++ b/bin/sh/tests/parser/line-cont12.0 @@ -0,0 +1,4 @@ + +[ '\ +' = "\\ +" ] diff --git a/bin/sh/tests/parser/line-cont2.0 b/bin/sh/tests/parser/line-cont2.0 new file mode 100644 index 000000000000..d5f7ae903748 --- /dev/null +++ b/bin/sh/tests/parser/line-cont2.0 @@ -0,0 +1,3 @@ + +[ "a\ +b" = ab ] diff --git a/bin/sh/tests/parser/line-cont3.0 b/bin/sh/tests/parser/line-cont3.0 new file mode 100644 index 000000000000..3f9d83a14105 --- /dev/null +++ b/bin/sh/tests/parser/line-cont3.0 @@ -0,0 +1,6 @@ + +v=`printf %s 'a\ +b'` +w="`printf %s 'c\ +d'`" +[ "$v$w" = abcd ] diff --git a/bin/sh/tests/parser/line-cont4.0 b/bin/sh/tests/parser/line-cont4.0 new file mode 100644 index 000000000000..0a58847b2c35 --- /dev/null +++ b/bin/sh/tests/parser/line-cont4.0 @@ -0,0 +1,7 @@ + +v=abcd +[ "$\ +v.$\ +{v}.${\ +v}.${v\ +}" = abcd.abcd.abcd.abcd ] diff --git a/bin/sh/tests/parser/line-cont5.0 b/bin/sh/tests/parser/line-cont5.0 new file mode 100644 index 000000000000..d8b5f08d7bbb --- /dev/null +++ b/bin/sh/tests/parser/line-cont5.0 @@ -0,0 +1,13 @@ + +bad=1 +case x in +x\ +) ;\ +; *) exit 7 +esac &\ +& bad= &\ +& : >\ +>/dev/null + +false |\ +| [ -z "$bad" ] diff --git a/bin/sh/tests/parser/line-cont6.0 b/bin/sh/tests/parser/line-cont6.0 new file mode 100644 index 000000000000..c5da14929ec0 --- /dev/null +++ b/bin/sh/tests/parser/line-cont6.0 @@ -0,0 +1,22 @@ + +v0\ +=abc + +v=$(cat <\ +<\ +E\ +O\ +F +${v0}d +EOF +) + +w=$(cat <\ +<\ +-\ +EOF + efgh +EOF +) + +[ "$v.$w" = "abcd.efgh" ] diff --git a/bin/sh/tests/parser/line-cont7.0 b/bin/sh/tests/parser/line-cont7.0 new file mode 100644 index 000000000000..ccc7fe4f0239 --- /dev/null +++ b/bin/sh/tests/parser/line-cont7.0 @@ -0,0 +1,6 @@ + +[ "$(\ +( +1\ ++ 1)\ +)" = 2 ] diff --git a/bin/sh/tests/parser/line-cont8.0 b/bin/sh/tests/parser/line-cont8.0 new file mode 100644 index 000000000000..7db2c9d65386 --- /dev/null +++ b/bin/sh/tests/parser/line-cont8.0 @@ -0,0 +1,5 @@ + +set -- a b c d e f g h i j +[ "${1\ +0\ +}" = j ] diff --git a/bin/sh/tests/parser/line-cont9.0 b/bin/sh/tests/parser/line-cont9.0 new file mode 100644 index 000000000000..e0f8c2b0616c --- /dev/null +++ b/bin/sh/tests/parser/line-cont9.0 @@ -0,0 +1,5 @@ + +[ "${$\ +:\ ++\ +xyz}" = xyz ] diff --git a/bin/sh/tests/parser/no-space1.0 b/bin/sh/tests/parser/no-space1.0 new file mode 100644 index 000000000000..2baba775200b --- /dev/null +++ b/bin/sh/tests/parser/no-space1.0 @@ -0,0 +1,17 @@ + +# These are ugly but are required to work. + +set -e + +while(false)do(:)done +if(false)then(:)fi +if(false)then(:)else(:)fi +(:&&:)||: +until(:)do(:)done +case x in(x);;*)exit 1;(:)esac +case x in(x);;*)exit 1;;esac +for i do(:)done +{(:)} +f(){(:)} +:|: +(:)|(:) diff --git a/bin/sh/tests/parser/no-space2.0 b/bin/sh/tests/parser/no-space2.0 new file mode 100644 index 000000000000..d03d7aa81568 --- /dev/null +++ b/bin/sh/tests/parser/no-space2.0 @@ -0,0 +1,6 @@ + +# This conflicts with ksh extended patterns but occurs in the wild. + +set -e + +!(false) diff --git a/bin/sh/tests/parser/nul1.0 b/bin/sh/tests/parser/nul1.0 new file mode 100644 index 000000000000..292669003acd --- /dev/null +++ b/bin/sh/tests/parser/nul1.0 @@ -0,0 +1,11 @@ +# Although POSIX does not specify the effect of NUL bytes in scripts, +# we ignore them. + +{ + printf 'v=%03000d\0%02000d' 7 2 + dd if=/dev/zero bs=1000 count=1 status=none + printf '1 w=%03000d%02000d1\0\n' 7 2 + printf '\0l\0v\0=\0$\0{\0#\0v\0}\n' + printf '\0l\0w\0=\0\0$\0{\0#\0w}\0\0\0\n' + printf '[ "$lv.$lw.$v" = "5001.5001.$w" ]\n' +} | ${SH} diff --git a/bin/sh/tests/parser/only-redir1.0 b/bin/sh/tests/parser/only-redir1.0 new file mode 100644 index 000000000000..1d8aff62e78c --- /dev/null +++ b/bin/sh/tests/parser/only-redir1.0 @@ -0,0 +1,2 @@ +</dev/null & +wait $! diff --git a/bin/sh/tests/parser/only-redir2.0 b/bin/sh/tests/parser/only-redir2.0 new file mode 100644 index 000000000000..efe4c3947dde --- /dev/null +++ b/bin/sh/tests/parser/only-redir2.0 @@ -0,0 +1 @@ +</dev/null | : diff --git a/bin/sh/tests/parser/only-redir3.0 b/bin/sh/tests/parser/only-redir3.0 new file mode 100644 index 000000000000..549873d15b1a --- /dev/null +++ b/bin/sh/tests/parser/only-redir3.0 @@ -0,0 +1 @@ +case x in x) </dev/null ;; esac diff --git a/bin/sh/tests/parser/only-redir4.0 b/bin/sh/tests/parser/only-redir4.0 new file mode 100644 index 000000000000..f85e9da727c5 --- /dev/null +++ b/bin/sh/tests/parser/only-redir4.0 @@ -0,0 +1 @@ +case x in x) </dev/null ;& esac diff --git a/bin/sh/tests/parser/pipe-not1.0 b/bin/sh/tests/parser/pipe-not1.0 new file mode 100644 index 000000000000..12ad17288182 --- /dev/null +++ b/bin/sh/tests/parser/pipe-not1.0 @@ -0,0 +1,2 @@ + +: | ! : | false diff --git a/bin/sh/tests/parser/ps1-expand1.0 b/bin/sh/tests/parser/ps1-expand1.0 new file mode 100644 index 000000000000..351e6437a023 --- /dev/null +++ b/bin/sh/tests/parser/ps1-expand1.0 @@ -0,0 +1,7 @@ +# Test simple variable expansion in PS1 +testvar=abcdef +output=$(testvar=abcdef PS1='$testvar:' ENV=/dev/null ${SH} +m -i </dev/null 2>&1) +case $output in +*abcdef*) exit 0 ;; +*) echo "Expected 'abcdef' in prompt output"; exit 1 ;; +esac diff --git a/bin/sh/tests/parser/ps1-expand2.0 b/bin/sh/tests/parser/ps1-expand2.0 new file mode 100644 index 000000000000..ed31a7c17136 --- /dev/null +++ b/bin/sh/tests/parser/ps1-expand2.0 @@ -0,0 +1,7 @@ +# Test braced variable expansion in PS1 +testvar=xyz123 +output=$(testvar=xyz123 PS1='prefix-${testvar}-suffix:' ENV=/dev/null ${SH} +m -i </dev/null 2>&1) +case $output in +*xyz123*) exit 0 ;; +*) echo "Expected 'xyz123' in prompt output"; exit 1 ;; +esac diff --git a/bin/sh/tests/parser/ps1-expand3.0 b/bin/sh/tests/parser/ps1-expand3.0 new file mode 100644 index 000000000000..0b6270c300ff --- /dev/null +++ b/bin/sh/tests/parser/ps1-expand3.0 @@ -0,0 +1,8 @@ +# Test special parameter $$ (PID) in PS1 +output=$(PS1='pid:$$:' ENV=/dev/null ${SH} +m -i </dev/null 2>&1) +# Check that output contains "pid:" followed by a number (not literal $$) +case $output in +*pid:\$\$:*) echo "PID not expanded, got literal \$\$"; exit 1 ;; +*pid:[0-9]*) exit 0 ;; +*) echo "Expected PID after 'pid:' in output"; exit 1 ;; +esac diff --git a/bin/sh/tests/parser/ps1-expand4.0 b/bin/sh/tests/parser/ps1-expand4.0 new file mode 100644 index 000000000000..623c52707eec --- /dev/null +++ b/bin/sh/tests/parser/ps1-expand4.0 @@ -0,0 +1,8 @@ +# Test special parameter $? (exit status) in PS1 +output=$(PS1='status:$?:' ENV=/dev/null ${SH} +m -i </dev/null 2>&1) +# Should start with exit status 0 +case $output in +*status:\$?:*) echo "Exit status not expanded, got literal \$?"; exit 1 ;; +*status:0:*) exit 0 ;; +*) echo "Expected 'status:0:' in initial prompt"; exit 1 ;; +esac diff --git a/bin/sh/tests/parser/ps1-expand5.0 b/bin/sh/tests/parser/ps1-expand5.0 new file mode 100644 index 000000000000..73fe3ba5a3d5 --- /dev/null +++ b/bin/sh/tests/parser/ps1-expand5.0 @@ -0,0 +1,8 @@ +# Test positional parameter $0 in PS1 +output=$(PS1='shell:$0:' ENV=/dev/null ${SH} +m -i </dev/null 2>&1) +# $0 should contain the shell name/path +case $output in +*shell:\$0:*) echo "Positional parameter not expanded, got literal \$0"; exit 1 ;; +*shell:*sh*:*) exit 0 ;; +*) echo "Expected shell name after 'shell:' in output"; exit 1 ;; +esac diff --git a/bin/sh/tests/parser/ps2-expand1.0 b/bin/sh/tests/parser/ps2-expand1.0 new file mode 100644 index 000000000000..f0a3a77ded1c --- /dev/null +++ b/bin/sh/tests/parser/ps2-expand1.0 @@ -0,0 +1,12 @@ +# Test variable expansion in PS2 (continuation prompt) +testvar=continue +# Send incomplete command (backslash at end) to trigger PS2 +output=$(testvar=continue PS2='$testvar>' ENV=/dev/null ${SH} +m -i <<EOF 2>&1 +echo \\ +done +EOF +) +case $output in +*continue\>*) exit 0 ;; +*) echo "Expected 'continue>' in PS2 output"; exit 1 ;; +esac diff --git a/bin/sh/tests/parser/set-v1.0 b/bin/sh/tests/parser/set-v1.0 new file mode 100644 index 000000000000..65106bc70b93 --- /dev/null +++ b/bin/sh/tests/parser/set-v1.0 @@ -0,0 +1,7 @@ + +${SH} <<\EOF +echo one >&2 +set -v +echo two >&2 +echo three >&2 +EOF diff --git a/bin/sh/tests/parser/set-v1.0.stderr b/bin/sh/tests/parser/set-v1.0.stderr new file mode 100644 index 000000000000..d904fa5ffdb2 --- /dev/null +++ b/bin/sh/tests/parser/set-v1.0.stderr @@ -0,0 +1,5 @@ +one +echo two >&2 +two +echo three >&2 +three diff --git a/bin/sh/tests/parser/var-assign1.0 b/bin/sh/tests/parser/var-assign1.0 new file mode 100644 index 000000000000..55034f2ccc4d --- /dev/null +++ b/bin/sh/tests/parser/var-assign1.0 @@ -0,0 +1,18 @@ +# In a variable assignment, both the name and the equals sign must be entirely +# unquoted. Therefore, there is only one assignment below; the other words +# containing equals signs are command words. + +abc=0 +\abc=1 2>/dev/null +a\bc=2 2>/dev/null +abc\=3 2>/dev/null +a\bc\=4 2>/dev/null +'abc'=5 2>/dev/null +a'b'c=6 2>/dev/null +abc'='7 2>/dev/null +'abc=8' 2>/dev/null +"abc"=9 2>/dev/null +a"b"c=10 2>/dev/null +abc"="11 2>/dev/null +"abc=12" 2>/dev/null +[ "$abc" = 0 ] |
