diff options
Diffstat (limited to 'bin/sh/tests/parser')
51 files changed, 836 insertions, 0 deletions
diff --git a/bin/sh/tests/parser/Makefile b/bin/sh/tests/parser/Makefile new file mode 100644 index 0000000..71bd370 --- /dev/null +++ b/bin/sh/tests/parser/Makefile @@ -0,0 +1,59 @@ +# $FreeBSD$ + +.include <bsd.own.mk> + +FILESDIR= ${TESTSBASE}/bin/sh/parser +KYUAFILE= no + +FILES= alias1.0 +FILES+= alias2.0 +FILES+= alias3.0 +FILES+= alias4.0 +FILES+= alias5.0 +FILES+= alias6.0 +FILES+= alias7.0 +FILES+= alias8.0 +FILES+= alias9.0 +FILES+= alias10.0 +FILES+= and-pipe-not.0 +FILES+= case1.0 +FILES+= case2.0 +FILES+= dollar-quote1.0 +FILES+= dollar-quote2.0 +FILES+= dollar-quote3.0 +FILES+= dollar-quote4.0 +FILES+= dollar-quote5.0 +FILES+= dollar-quote6.0 +FILES+= dollar-quote7.0 +FILES+= dollar-quote8.0 +FILES+= dollar-quote9.0 +FILES+= dollar-quote10.0 +FILES+= dollar-quote11.0 +FILES+= empty-braces1.0 +FILES+= empty-cmd1.0 +FILES+= for1.0 +FILES+= for2.0 +FILES+= func1.0 +FILES+= func2.0 +FILES+= func3.0 +FILES+= heredoc1.0 +FILES+= heredoc2.0 +FILES+= heredoc3.0 +FILES+= heredoc4.0 +FILES+= heredoc5.0 +FILES+= heredoc6.0 +FILES+= heredoc7.0 +FILES+= heredoc8.0 +FILES+= heredoc9.0 +FILES+= heredoc10.0 +FILES+= heredoc11.0 +FILES+= no-space1.0 +FILES+= no-space2.0 +FILES+= only-redir1.0 +FILES+= only-redir2.0 +FILES+= only-redir3.0 +FILES+= only-redir4.0 +FILES+= pipe-not1.0 +FILES+= var-assign1.0 + +.include <bsd.test.mk> diff --git a/bin/sh/tests/parser/alias1.0 b/bin/sh/tests/parser/alias1.0 new file mode 100644 index 0000000..75dd9ab --- /dev/null +++ b/bin/sh/tests/parser/alias1.0 @@ -0,0 +1,5 @@ +# $FreeBSD$ + +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 0000000..30d99f4 --- /dev/null +++ b/bin/sh/tests/parser/alias10.0 @@ -0,0 +1,9 @@ +# $FreeBSD$ + +# 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/alias2.0 b/bin/sh/tests/parser/alias2.0 new file mode 100644 index 0000000..ae99b8a --- /dev/null +++ b/bin/sh/tests/parser/alias2.0 @@ -0,0 +1,6 @@ +# $FreeBSD$ + +alias alias0=exit +x=alias0 +eval 'case $x in alias0) exit 0;; esac' +exit 1 diff --git a/bin/sh/tests/parser/alias3.0 b/bin/sh/tests/parser/alias3.0 new file mode 100644 index 0000000..e0721e2 --- /dev/null +++ b/bin/sh/tests/parser/alias3.0 @@ -0,0 +1,6 @@ +# $FreeBSD$ + +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 0000000..19332ed --- /dev/null +++ b/bin/sh/tests/parser/alias4.0 @@ -0,0 +1,5 @@ +# $FreeBSD$ + +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 0000000..3d0205f --- /dev/null +++ b/bin/sh/tests/parser/alias5.0 @@ -0,0 +1,5 @@ +# $FreeBSD$ + +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 0000000..c723d08 --- /dev/null +++ b/bin/sh/tests/parser/alias6.0 @@ -0,0 +1,6 @@ +# $FreeBSD$ + +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 0000000..b26f0dd --- /dev/null +++ b/bin/sh/tests/parser/alias7.0 @@ -0,0 +1,4 @@ +# $FreeBSD$ + +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 0000000..7fc2f15 --- /dev/null +++ b/bin/sh/tests/parser/alias8.0 @@ -0,0 +1,4 @@ +# $FreeBSD$ + +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 0000000..6bd8808 --- /dev/null +++ b/bin/sh/tests/parser/alias9.0 @@ -0,0 +1,6 @@ +# $FreeBSD$ + +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 0000000..35b125c --- /dev/null +++ b/bin/sh/tests/parser/and-pipe-not.0 @@ -0,0 +1,2 @@ +# $FreeBSD$ +true && ! true | false diff --git a/bin/sh/tests/parser/case1.0 b/bin/sh/tests/parser/case1.0 new file mode 100644 index 0000000..49b4c45 --- /dev/null +++ b/bin/sh/tests/parser/case1.0 @@ -0,0 +1,14 @@ +# $FreeBSD$ + +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 0000000..14610e4 --- /dev/null +++ b/bin/sh/tests/parser/case2.0 @@ -0,0 +1,32 @@ +# $FreeBSD$ + +# 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/dollar-quote1.0 b/bin/sh/tests/parser/dollar-quote1.0 new file mode 100644 index 0000000..1206141 --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote1.0 @@ -0,0 +1,12 @@ +# $FreeBSD$ + +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 0000000..ad166da --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote10.0 @@ -0,0 +1,10 @@ +# $FreeBSD$ + +# 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 0000000..2e872ab --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote11.0 @@ -0,0 +1,8 @@ +# $FreeBSD$ + +# 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-quote2.0 b/bin/sh/tests/parser/dollar-quote2.0 new file mode 100644 index 0000000..4617ed8 --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote2.0 @@ -0,0 +1,5 @@ +# $FreeBSD$ + +# 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 0000000..a7e6852 --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote3.0 @@ -0,0 +1,22 @@ +# $FreeBSD$ + +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 0000000..f620af5 --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote4.0 @@ -0,0 +1,19 @@ +# $FreeBSD$ + +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 0000000..c2c44ca --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote5.0 @@ -0,0 +1,12 @@ +# $FreeBSD$ + +# 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 0000000..a4b1e3f --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote6.0 @@ -0,0 +1,5 @@ +# $FreeBSD$ + +# 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 0000000..c866b1a --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote7.0 @@ -0,0 +1,6 @@ +# $FreeBSD$ + +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 0000000..8f0b41a --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote8.0 @@ -0,0 +1,11 @@ +# $FreeBSD$ + +[ $'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 0000000..df64b7d --- /dev/null +++ b/bin/sh/tests/parser/dollar-quote9.0 @@ -0,0 +1,8 @@ +# $FreeBSD$ + +# 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 0000000..5ab443c --- /dev/null +++ b/bin/sh/tests/parser/empty-braces1.0 @@ -0,0 +1,7 @@ +# $FreeBSD$ + +# 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 0000000..f8b01e9 --- /dev/null +++ b/bin/sh/tests/parser/empty-cmd1.0 @@ -0,0 +1,3 @@ +# $FreeBSD$ + +! (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 0000000..eb7c881 --- /dev/null +++ b/bin/sh/tests/parser/for1.0 @@ -0,0 +1,29 @@ +# $FreeBSD$ + +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 0000000..54ebfc3 --- /dev/null +++ b/bin/sh/tests/parser/for2.0 @@ -0,0 +1,15 @@ +# $FreeBSD$ + +# 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 0000000..4e887b2 --- /dev/null +++ b/bin/sh/tests/parser/func1.0 @@ -0,0 +1,25 @@ +# $FreeBSD$ +# 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 0000000..5fd4dda --- /dev/null +++ b/bin/sh/tests/parser/func2.0 @@ -0,0 +1,6 @@ +# $FreeBSD$ + +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 0000000..dcac732 --- /dev/null +++ b/bin/sh/tests/parser/func3.0 @@ -0,0 +1,6 @@ +# $FreeBSD$ + +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 0000000..5ce3897 --- /dev/null +++ b/bin/sh/tests/parser/heredoc1.0 @@ -0,0 +1,85 @@ +# $FreeBSD$ + +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 0000000..27369a0 --- /dev/null +++ b/bin/sh/tests/parser/heredoc10.0 @@ -0,0 +1,49 @@ +# $FreeBSD$ + +# 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 0000000..5839e46 --- /dev/null +++ b/bin/sh/tests/parser/heredoc11.0 @@ -0,0 +1,26 @@ +# $FreeBSD$ + +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/heredoc2.0 b/bin/sh/tests/parser/heredoc2.0 new file mode 100644 index 0000000..4bb85ad --- /dev/null +++ b/bin/sh/tests/parser/heredoc2.0 @@ -0,0 +1,39 @@ +# $FreeBSD$ + +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 0000000..b250272 --- /dev/null +++ b/bin/sh/tests/parser/heredoc3.0 @@ -0,0 +1,7 @@ +# $FreeBSD$ + +# 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 0000000..fa3af5f --- /dev/null +++ b/bin/sh/tests/parser/heredoc4.0 @@ -0,0 +1,44 @@ +# $FreeBSD$ + +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 0000000..84b0eb2 --- /dev/null +++ b/bin/sh/tests/parser/heredoc5.0 @@ -0,0 +1,56 @@ +# $FreeBSD$ + +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 0000000..3a634de --- /dev/null +++ b/bin/sh/tests/parser/heredoc6.0 @@ -0,0 +1,5 @@ +# $FreeBSD$ + +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 0000000..a150106 --- /dev/null +++ b/bin/sh/tests/parser/heredoc7.0 @@ -0,0 +1,19 @@ +# $FreeBSD$ + +# 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 0000000..598358a --- /dev/null +++ b/bin/sh/tests/parser/heredoc8.0 @@ -0,0 +1,20 @@ +# $FreeBSD$ + +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 0000000..125a542 --- /dev/null +++ b/bin/sh/tests/parser/heredoc9.0 @@ -0,0 +1,58 @@ +# $FreeBSD$ + +# 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/no-space1.0 b/bin/sh/tests/parser/no-space1.0 new file mode 100644 index 0000000..6df9f63 --- /dev/null +++ b/bin/sh/tests/parser/no-space1.0 @@ -0,0 +1,18 @@ +# $FreeBSD$ + +# 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 0000000..4e8447b --- /dev/null +++ b/bin/sh/tests/parser/no-space2.0 @@ -0,0 +1,7 @@ +# $FreeBSD$ + +# This conflicts with ksh extended patterns but occurs in the wild. + +set -e + +!(false) diff --git a/bin/sh/tests/parser/only-redir1.0 b/bin/sh/tests/parser/only-redir1.0 new file mode 100644 index 0000000..46076c8 --- /dev/null +++ b/bin/sh/tests/parser/only-redir1.0 @@ -0,0 +1,3 @@ +# $FreeBSD$ +</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 0000000..b9e9501 --- /dev/null +++ b/bin/sh/tests/parser/only-redir2.0 @@ -0,0 +1,2 @@ +# $FreeBSD$ +</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 0000000..128a483 --- /dev/null +++ b/bin/sh/tests/parser/only-redir3.0 @@ -0,0 +1,2 @@ +# $FreeBSD$ +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 0000000..d804e12 --- /dev/null +++ b/bin/sh/tests/parser/only-redir4.0 @@ -0,0 +1,2 @@ +# $FreeBSD$ +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 0000000..9842ff0 --- /dev/null +++ b/bin/sh/tests/parser/pipe-not1.0 @@ -0,0 +1,3 @@ +# $FreeBSD$ + +: | ! : | false diff --git a/bin/sh/tests/parser/var-assign1.0 b/bin/sh/tests/parser/var-assign1.0 new file mode 100644 index 0000000..1fd3b26 --- /dev/null +++ b/bin/sh/tests/parser/var-assign1.0 @@ -0,0 +1,19 @@ +# $FreeBSD$ +# 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 ] |