Home | History | Annotate | Line # | Download | only in sh
      1  1.13  andvar # $NetBSD: t_syntax.sh,v 1.13 2023/12/28 20:04:10 andvar Exp $
      2   1.1     kre #
      3   1.1     kre # Copyright (c) 2017 The NetBSD Foundation, Inc.
      4   1.1     kre # All rights reserved.
      5   1.1     kre #
      6   1.1     kre # Redistribution and use in source and binary forms, with or without
      7   1.1     kre # modification, are permitted provided that the following conditions
      8   1.1     kre # are met:
      9   1.1     kre # 1. Redistributions of source code must retain the above copyright
     10   1.1     kre #    notice, this list of conditions and the following disclaimer.
     11   1.1     kre # 2. Redistributions in binary form must reproduce the above copyright
     12   1.1     kre #    notice, this list of conditions and the following disclaimer in the
     13   1.1     kre #    documentation and/or other materials provided with the distribution.
     14   1.1     kre #
     15   1.1     kre # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     16   1.1     kre # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     17   1.1     kre # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     18   1.1     kre # PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     19   1.1     kre # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     20   1.1     kre # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     21   1.1     kre # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     22   1.1     kre # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     23   1.1     kre # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     24   1.1     kre # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25   1.1     kre # POSSIBILITY OF SUCH DAMAGE.
     26   1.1     kre #
     27   1.1     kre : ${TEST_SH:=/bin/sh}
     28   1.1     kre 
     29   1.1     kre # This set of tests verifies various requirementgs relating to correct
     30   1.1     kre # (and incorrect) syntax of shell input
     31   1.1     kre #
     32   1.1     kre # There is no intent in these tests to verify correct operation
     33   1.1     kre # (though that sometimes cannot be separated from correct parsing.)
     34   1.1     kre # That is (or should be) verified elsewhere.
     35   1.1     kre #
     36   1.1     kre # Also, some very basic syntax is tested in almost every test
     37   1.1     kre # (they cannot work without basic parsing of elementary commands)
     38   1.1     kre # so that is also not explicitly tested here.
     39   1.1     kre #
     40   1.1     kre # Similarly word expansion, field splitting, redirection, all have
     41   1.1     kre # tests of their own (though we do test parsing of redirect ops).
     42   1.1     kre #
     43   1.1     kre # Note that in order to test the basic facilities, other shell operations
     44   1.1     kre # are used - a test failure here does not necessarily mean that the
     45   1.1     kre # operation intended to be tested is faulty, just that something is.
     46   1.1     kre 
     47   1.1     kre atf_test_case a_basic_tokenisation
     48   1.1     kre a_basic_tokenisation_head() {
     49   1.1     kre 	atf_set "descr" "Test the shell correctly finds various tokens"
     50   1.1     kre }
     51   1.1     kre a_basic_tokenisation_body() {
     52   1.1     kre 	atf_check -s exit:0 -o 'inline:3\n' -e empty ${TEST_SH} -c \
     53   1.1     kre 		'set -- a b c; echo $#'
     54   1.1     kre 	atf_check -s exit:0 -o 'inline:2\n' -e empty ${TEST_SH} -c \
     55   1.1     kre 		'set -- a""b c; echo $#'
     56   1.1     kre 	atf_check -s exit:0 -o 'inline:3\n' -e empty ${TEST_SH} -c \
     57   1.1     kre 		'set -- a"" b c; echo $#'
     58   1.1     kre 	atf_check -s exit:0 -o 'inline:3\n' -e empty ${TEST_SH} -c \
     59   1.1     kre 		'set -- ""a b c\;; echo $#'
     60   1.1     kre 
     61   1.1     kre 	atf_check -s exit:0 -o 'inline:3\n' -e empty ${TEST_SH} -c \
     62   1.1     kre 		'set -- set -- c; echo $#'
     63   1.1     kre 	atf_check -s exit:0 -o 'inline:1\n' -e empty ${TEST_SH} -c \
     64   1.1     kre 		'set --;set -- c; echo $#'
     65   1.1     kre 	atf_check -s exit:0 -o 'inline:1\n' -e empty ${TEST_SH} -c \
     66   1.1     kre 		'set --&set -- c; echo $#'
     67   1.1     kre 	atf_check -s exit:0 -o 'inline:1\n' -e empty ${TEST_SH} -c \
     68   1.1     kre 		'set -- a b&&set -- c; echo $#'
     69   1.1     kre 	atf_check -s exit:0 -o 'inline:2\n' -e empty ${TEST_SH} -c \
     70   1.1     kre 		'set -- a b||set -- c; echo $#'
     71   1.1     kre }
     72   1.1     kre 
     73   1.1     kre atf_test_case b_comments
     74   1.1     kre b_comments_head() {
     75   1.1     kre 	atf_set "descr" "Test the shell correctly handles comments"
     76   1.1     kre }
     77   1.1     kre b_comments_body() {
     78   1.1     kre 
     79   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '#'
     80   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c '# exit 1'
     81   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c 'true # exit 1'
     82   1.1     kre 	atf_check -s exit:1 -o empty -e empty ${TEST_SH} -c 'false # exit 0'
     83   1.1     kre 
     84   1.1     kre 	atf_check -s exit:0 -o 'inline:foo\n' -e empty ${TEST_SH} -c \
     85   1.1     kre 		'echo foo # bar'
     86   1.1     kre 	atf_check -s exit:0 -o 'inline:foo # bar\n' -e empty ${TEST_SH} -c \
     87   1.1     kre 		'echo foo \# bar'
     88   1.1     kre 	atf_check -s exit:0 -o 'inline:foo\n' -e empty ${TEST_SH} -c \
     89   1.1     kre 		'echo foo; # echo bar'
     90   1.1     kre 	atf_check -s exit:0 -o 'inline:foo#bar\n' -e empty ${TEST_SH} -c \
     91   1.1     kre 		'echo foo#bar'
     92   1.1     kre 	atf_check -s exit:0 -o 'inline:foo# bar\n' -e empty ${TEST_SH} -c \
     93   1.1     kre 		'echo foo# bar'
     94   1.1     kre 	atf_check -s exit:0 -o 'inline:foo\n' -e empty ${TEST_SH} -c \
     95   1.1     kre 		'x=foo; echo ${x#bar}'
     96   1.1     kre 
     97   1.1     kre 	atf_check -s exit:0 -o 'inline:#\n' -e empty ${TEST_SH} -c \
     98   1.1     kre 		'echo "#"'
     99   1.1     kre 	atf_check -s exit:0 -o 'inline:#\n' -e empty ${TEST_SH} -c \
    100   1.1     kre 		"echo '#'"
    101   1.1     kre 	atf_check -s exit:0 -o 'inline:#\n' -e empty ${TEST_SH} -c \
    102   1.1     kre 		'echo \#'
    103   1.1     kre 	atf_check -s exit:0 -o 'inline:##\n' -e empty ${TEST_SH} -c \
    104   1.1     kre 		'echo "#"#'
    105   1.1     kre 	atf_check -s exit:0 -o 'inline:##\n' -e empty ${TEST_SH} -c \
    106   1.1     kre 		"echo '#'#"
    107   1.1     kre 	atf_check -s exit:0 -o 'inline:##\n' -e empty ${TEST_SH} -c \
    108   1.1     kre 		'echo \##'
    109   1.1     kre 	atf_check -s exit:0 -o 'inline:##\n' -e empty ${TEST_SH} -c \
    110   1.1     kre 		'echo "#"# #"#"'
    111   1.1     kre 	atf_check -s exit:0 -o 'inline:##\n' -e empty ${TEST_SH} -c \
    112   1.1     kre 		"echo '#'# #'#'"
    113   1.1     kre 	atf_check -s exit:0 -o 'inline:##\n' -e empty ${TEST_SH} -c \
    114   1.1     kre 		'echo \## #\#'
    115   1.1     kre 
    116  1.12     kre 	cat <<-'DONE' |
    117  1.13  andvar 		# test comments do not provoke syntax errors !\
    118   1.1     kre 		echo foo # ( { " hello
    119   1.1     kre 		while : # that's forever
    120   1.1     kre 		do	# the following command list
    121   1.1     kre 			# starting with nothing ${unset?error}
    122   1.1     kre 			break	# done loop terminate $( echo bar; exit 1 )
    123   1.1     kre 		done #####################################################
    124   1.1     kre 		# "hello
    125   1.1     kre 		exit 0
    126   1.1     kre 	DONE
    127  1.12     kre 		atf_check -s exit:0 -o inline:'foo\n' -e empty ${TEST_SH} ||
    128  1.12     kre 			atf_fail "ignoring comments"
    129   1.1     kre }
    130   1.1     kre 
    131   1.1     kre atf_test_case c_line_wrapping
    132   1.1     kre c_line_wrapping_head() {
    133   1.1     kre 	atf_set "descr" "check aspects of command line wrapping"
    134   1.1     kre }
    135   1.1     kre c_line_wrapping_body() {
    136   1.1     kre 	atf_require_prog ls
    137   1.1     kre 	atf_require_prog printf
    138   1.1     kre 
    139  1.11     kre 	cat <<- 'DONE' | atf_check -s exit:0 -o ignore -e empty ${TEST_SH} -e ||
    140   1.1     kre 		l\
    141   1.1     kre 		s
    142   1.1     kre 	DONE
    143  1.11     kre 		atf_fail "#1: ls wrapped fails"
    144   1.1     kre 
    145  1.11     kre 	cat <<- 'DONE' | atf_check -s exit:7 -o empty -e empty ${TEST_SH} ||
    146   1.1     kre 		e\
    147   1.1     kre 		x\
    148   1.1     kre 		it \
    149   1.1     kre 		7
    150   1.1     kre 	DONE
    151  1.11     kre 		atf_fail "#2: exit7 wrapped fails"
    152   1.1     kre 
    153   1.1     kre 	# Have to do this twice as cannot say "any exit code but 0 or 7" ...
    154   1.1     kre 	cat <<- 'DONE' | atf_check -s not-exit:0 -o empty -e not-empty \
    155  1.11     kre 	    ${TEST_SH} ||
    156   1.1     kre 		e\
    157   1.1     kre 		x\
    158   1.1     kre 		it\
    159   1.1     kre 		7
    160   1.1     kre 	DONE
    161  1.11     kre 		atf_fail "#3a: !exit(0||7) badly wrapped fails (0)"
    162   1.1     kre 	cat <<- 'DONE' | atf_check -s not-exit:7 -o empty -e not-empty \
    163  1.11     kre 	    ${TEST_SH} ||
    164   1.1     kre 		e\
    165   1.1     kre 		x\
    166   1.1     kre 		it\
    167   1.1     kre 		7
    168   1.1     kre 	DONE
    169  1.11     kre 		atf_fail "#3b: !exit(0||7) badly wrapped fails (7)"
    170   1.1     kre 
    171  1.11     kre 	cat <<- 'DONE' | atf_check -s exit:0 -o empty -e empty  ${TEST_SH} ||
    172   1.1     kre 		wh\
    173   1.1     kre 		il\
    174   1.1     kre 		e \
    175   1.1     kre 		f\a\
    176   1.1     kre 		\l\s\e
    177   1.1     kre 		do
    178   1.1     kre 		:\
    179   1.1     kre 		;
    180   1.1     kre 		done
    181   1.1     kre 	DONE
    182  1.11     kre 		atf_fail "#4: wrapped while fails"
    183   1.1     kre 
    184   1.1     kre 	cat <<- 'DONE' | atf_check -s exit:0 -o inline:'hellohellohellohello' \
    185  1.11     kre 	    -e empty ${TEST_SH} ||
    186   1.1     kre 		V\
    187   1.1     kre 		AR=hel\
    188   1.1     kre 		lo
    189   1.1     kre 		unset U V1
    190   1.1     kre 		pri\
    191   1.1     kre 		ntf '%s' ${\
    192   1.1     kre 		VAR\
    193   1.1     kre 		}
    194   1.1     kre 		p\
    195   1.1     kre 		r\
    196   1.1     kre 		i\
    197   1.1     kre 		n\
    198   1.1     kre 		t\
    199   1.1     kre 		f\
    200   1.1     kre 		 \
    201   1.1     kre 		'%s' \
    202   1.1     kre 		$\
    203   1.1     kre 		{\
    204   1.1     kre 		V\
    205   1.1     kre 		A\
    206   1.1     kre 		R}
    207   1.1     kre 		printf '%s' ${U\
    208   1.1     kre 		-\
    209   1.1     kre 		"$\
    210   1.1     kre 		{V\
    211   1.1     kre 		1:\
    212   1.1     kre 		=$\
    213   1.1     kre 		{V\
    214   1.1     kre 		AR+\
    215   1.1     kre 		${V\
    216   1.1     kre 		AR}\
    217   1.1     kre 		}\
    218   1.3     kre 		}"}
    219   1.1     kre 		printf '%s' ${V\
    220   1.1     kre 		1?V1\
    221   1.1     kre 		 \
    222   1.1     kre 		FAIL}
    223   1.1     kre 	DONE
    224  1.11     kre 		atf_fail "#5: wrapped var expansions fails"
    225   1.3     kre 
    226  1.11     kre 	cat <<- 'DONE' | atf_check -s exit:0 -o inline:'2\n' ${TEST_SH} ||
    227   1.1     kre 		l\
    228   1.1     kre 		s=7 bi\
    229   1.1     kre 		n\
    230   1.1     kre 		=\
    231   1.1     kre 		3
    232   1.1     kre 		echo $(\
    233   1.1     kre 		( ls /bin )\
    234   1.1     kre 		)
    235   1.1     kre 	DONE
    236  1.11     kre 		atf_fail "#6: wrapped command substitution fails"
    237   1.3     kre 
    238   1.3     kre 	# Inspired by src/etc/MAKEDEV.tmpl failure with (broken)
    239   1.3     kre 	# sh LINENO code...  avoid it happening again...
    240   1.3     kre 	for VARS in 1:0:0:0 0:1:0:0 0:0:1:0 0:0:0:1 \
    241   1.3     kre 		    1:0:0:1 1:0:1:0 1:1:0:0 0:1:1:0 \
    242   1.3     kre 		    0:0:0:0 1:1:0:1 0:1:1:1 1:1:1:1
    243   1.3     kre 	do
    244   1.3     kre 		eval $(
    245   1.3     kre 			IFS=:
    246   1.3     kre 			set -- $VARS
    247   1.3     kre 			test $(( $1 + $2 + $3 + $4 )) -eq 1 &&
    248   1.3     kre 				R=OK || R=BAD
    249   1.3     kre 			printf "R=%s;" $R
    250   1.3     kre 			for v in a b c d
    251   1.3     kre 			do
    252   1.3     kre 				case $1 in
    253   1.3     kre 				(0)	printf "export %s=false;" $v;;
    254   1.3     kre 				(1)	printf "export %s=true;"  $v;;
    255   1.3     kre 				esac
    256   1.3     kre 				shift
    257   1.3     kre 			done
    258   1.3     kre 		)
    259   1.3     kre 
    260  1.11     kre 		cat <<- 'DONE' |
    261   1.3     kre 			case $(( $($a && echo 1 || echo 0) + \
    262   1.3     kre 				 $($b && echo 1 || echo 0) + \
    263   1.3     kre 				 $($c && echo 1 || echo 0) + \
    264   1.3     kre 				 $($d && echo 1 || echo 0) ))
    265   1.3     kre 			in
    266   1.3     kre 			(1)	printf OK ;;
    267   1.3     kre 			(*)	printf BAD ;;
    268   1.3     kre 			esac
    269   1.3     kre 		DONE
    270  1.11     kre 			atf_check -s exit:0 -o inline:"${R}" ${TEST_SH} ||
    271  1.11     kre 			atf_fail "#7 (${VARS}): wrapped arith fails"
    272   1.3     kre 	done
    273   1.3     kre 
    274   1.3     kre 	# inspired by pkgsrc/pkgtools/cwrappers :: libnbcompat/configure
    275   1.7     kre 	# failure with (broken) sh LINENO code .. avoid recurrence
    276   1.3     kre 	# This test would have failed.
    277  1.11     kre 	cat <<- 'DONE' | atf_check -s exit:0 -o inline:'/tmp\n' ${TEST_SH} ||
    278   1.3     kre 		dn=/tmp/foo
    279   1.3     kre 
    280   1.3     kre 		D=`dirname -- "${dn}" ||
    281   1.3     kre 		expr	X"${dn}" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \
    282   1.3     kre 			X"${dn}" : 'X\(//\)[^/]' \| \
    283   1.3     kre 			X"${dn}" : 'X\(//\)$' \| \
    284   1.3     kre 			X"${dn}" : 'X\(/\)' \| . 2>/dev/null ||
    285   1.3     kre 		echo X"${dn}" |
    286   1.3     kre 		    sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{
    287   1.3     kre 			    s//\1/
    288   1.3     kre 			    q
    289   1.3     kre 			  }
    290   1.3     kre 			  /^X\(\/\/\)[^/].*/{
    291   1.3     kre 			    s//\1/
    292   1.3     kre 			    q
    293   1.3     kre 			  }
    294   1.3     kre 			  /^X\(\/\/\)$/{ 
    295   1.3     kre 			    s//\1/
    296   1.3     kre 			    q
    297   1.3     kre 			  } 
    298   1.3     kre 			  /^X\(\/\).*/{
    299   1.3     kre 			    s//\1/
    300   1.3     kre 			    q
    301   1.3     kre 			  }
    302   1.3     kre 			  s/.*/./; q'`
    303   1.3     kre 
    304   1.3     kre 		echo "${D}"
    305   1.3     kre 	DONE
    306  1.11     kre 		atf_fail "#8:  cwrappers/LINENO bug test failed"
    307  1.11     kre 
    308   1.3     kre 	return 0
    309   1.1     kre }
    310   1.1     kre 
    311   1.7     kre atf_test_case d_cstrings
    312   1.7     kre d_cstrings_head() {
    313   1.7     kre 	atf_set "descr" "Check processing of $' ' quoting (C style strings)"
    314   1.7     kre }
    315   1.7     kre d_cstrings_body() {
    316   1.7     kre 	unset ENV
    317   1.8     kre 
    318   1.7     kre 	if ! ${TEST_SH} -c ": \$'abc'" ||
    319   1.7     kre 	     test $( ${TEST_SH} -c "printf %s \$'abc'" ) != abc
    320   1.7     kre 	then
    321   1.7     kre 		atf_skip "\$'...' (C style quoted strings) not supported"
    322   1.7     kre 	fi
    323   1.7     kre 
    324   1.7     kre 	# simple stuff
    325   1.7     kre 	atf_check -s exit:0 -e empty -o inline:'abc\tdef\n' ${TEST_SH} -c \
    326   1.7     kre 		"printf '%s\\n' \$'abc\tdef'"
    327   1.7     kre 	atf_check -s exit:0 -e empty -o inline:'abc\tdef\n' ${TEST_SH} -c \
    328   1.7     kre 		"printf '%s\\n' \$'abc\011def'"
    329   1.7     kre 	atf_check -s exit:0 -e empty -o inline:'abc\tdef\n' ${TEST_SH} -c \
    330   1.7     kre 		"printf '%s\\n' \$'abc\x09'def"
    331   1.7     kre 	atf_check -s exit:0 -e empty -o inline:'abc$def\n' ${TEST_SH} -c \
    332   1.7     kre 		"def=xyz; printf '%s\\n' \$'abc\$def'"
    333   1.7     kre 
    334   1.7     kre 	# control chars (\c) and unicode \u
    335   1.7     kre 	atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \
    336   1.7     kre 		"test \$'\\1-\\2-\\3' = \$'\\ca-\\cb-\\cc'"
    337   1.7     kre 	atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \
    338   1.7     kre 		"test \$'\\r-\\n-\\f' = \$'\\cm-\\cj-\\cl'"
    339   1.7     kre 	atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \
    340   1.9     kre 		"unset LC_ALL; export LC_CTYPE=en_AU.UTF-8;
    341   1.9     kre 		test \$'\\u0123' = \$'\\304\\243'"
    342   1.7     kre 	atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \
    343   1.7     kre 		"test \$'\\u0123' = \$'\\xC4\\xA3'"
    344   1.7     kre 	atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \
    345   1.7     kre 		"test \$'\\c\\\\' = \$'\\x1C'"
    346   1.7     kre 	atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \
    347   1.7     kre 		"test \$'\\c[\\c]\\c^\\c_\\c?' = \$'\\x1B\\x1D\\x1E\\x1F\\x7F'"
    348   1.7     kre 
    349   1.7     kre 	# all the \X sequences for a single char X (ie: not hex/octal/unicode)
    350   1.7     kre 	atf_check -s exit:0 -e empty -o inline:'\n\r\t\n' \
    353   1.7     kre 		${TEST_SH} -c "printf '%s\\n' \$'\\a\\b\\e\\f\\n\\r\\t\\v'"
    354   1.7     kre 	atf_check -s exit:0 -e empty -o inline:'\n\r\t\n' \
    357   1.7     kre 	   ${TEST_SH} -c "printf '%s\\n' \$'\\cG\\cH\\x1b\\cl\\cJ\\cm\\cI\\ck'"
    358   1.7     kre 	atf_check -s exit:0 -e empty -o inline:"'"'"\\\n' \
    359   1.7     kre 		${TEST_SH} -c "printf '%s\\n' \$'\\'\\\"\\\\'"
    360   1.7     kre 
    361   1.7     kre 	# various invalid $'...' sequences
    362   1.7     kre 	atf_check -s not-exit:0 -e not-empty -o ignore ${TEST_SH} -c \
    363   1.7     kre 		": \$'\\q'"
    364   1.7     kre 	atf_check -s not-exit:0 -e not-empty -o ignore ${TEST_SH} -c \
    365   1.7     kre 		": \$'\\c\\q'"
    366   1.7     kre 	atf_check -s not-exit:0 -e not-empty -o ignore ${TEST_SH} -c \
    367   1.7     kre 		": \$'\\uDEFF'"
    368   1.7     kre 	atf_check -s not-exit:0 -e not-empty -o ignore ${TEST_SH} -c \
    369   1.9     kre 		": \$'abcd"
    370   1.9     kre 	atf_check -s not-exit:0 -e not-empty -o ignore ${TEST_SH} -c \
    371   1.9     kre 		": \$'abcd\\"
    372   1.7     kre 
    373   1.7     kre 	# anything that generates \0 ends the $'...' immediately
    374   1.7     kre 	atf_check -s exit:0 -e empty -o inline:'aAaA' ${TEST_SH} -c \
    375   1.8     kre 		"printf '%s' \$'a\\0x'\$'A\\x00X'\$'a\\c@x'\$'A\\u0000X'"
    376   1.8     kre 
    377   1.8     kre 	# \newline in a $'...' is dropped (just like in "" strings)
    378   1.8     kre 	atf_check -s exit:0 -e empty -o inline:'abcdef' ${TEST_SH} -c \
    379   1.8     kre "printf '%s' \$'abc\\
    380   1.7     kre def'"
    381   1.8     kre 	# but a normal newline in a $'...' is just a newline
    382   1.8     kre 	atf_check -s exit:0 -e empty -o inline:'abc\ndef' ${TEST_SH} -c \
    383   1.8     kre "printf '%s' \$'abc
    384   1.8     kre def'"
    385   1.8     kre 	# and should work when elided line wrap occurs between $ and '
    386   1.8     kre 	atf_check -s exit:0 -e empty -o inline:'abc\ndef' ${TEST_SH} -c \
    387   1.8     kre "printf '%s' \$\\
    388   1.8     kre 'abc\\ndef'"
    389   1.8     kre 
    390   1.8     kre 	# $'...' only works when the $ is unquoted.
    391   1.8     kre 	atf_check -s exit:0 -e empty -o inline:"abc\$'def'g" ${TEST_SH} -c \
    392   1.8     kre 		"printf '%s' \"abc\$'def'g\""
    393   1.7     kre 	atf_check -s exit:0 -e empty -o inline:'abc$defg' ${TEST_SH} -c \
    394   1.7     kre 		"printf '%s' abc\\\$'def'g"
    395   1.7     kre 	atf_check -s exit:0 -e empty -o inline:'abc$def' ${TEST_SH} -c \
    396   1.7     kre 		"printf '%s' abc'\$'def"
    397   1.1     kre }
    398   1.1     kre 
    399   1.7     kre atf_test_case f_redirects
    400   1.1     kre f_redirects_head() {
    401   1.1     kre 	atf_set "descr" "Check parsing of redirect operators"
    402   1.1     kre }
    403   1.1     kre f_redirects_body() {
    404   1.1     kre 
    405   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    406   1.1     kre 		'>/dev/null'
    407   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    408   1.1     kre 		'</dev/null'
    409   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    410   1.1     kre 		'>>/dev/null'
    411   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    412   1.1     kre 		'<>/dev/null'
    413   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    414   1.1     kre 		'</dev/null>/dev/null'
    415   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    416   1.4     kre 		'>|/dev/null'
    417   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    418   1.4     kre 		'>/dev/null>/dev/null>/dev/null'
    419   1.1     kre 
    420   1.4     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    421   1.1     kre 		'echo hello >/dev/null'
    422   1.4     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    423   1.1     kre 		'echo >/dev/null hello'
    424   1.4     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    425   1.1     kre 		'>/dev/null echo hello'
    426   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    427   1.4     kre 		'echo hello >/dev/null world'
    428   1.1     kre 	atf_check -s exit:0 -o 'inline:hello world\n' -e empty ${TEST_SH} -c \
    429   1.4     kre 		'echo hello </dev/null world'
    430   1.1     kre 
    431   1.4     kre 	atf_check -s exit:0 -o 'inline:hello\n' -e empty ${TEST_SH} -c \
    432   1.1     kre 		'echo hello </dev/null'
    433   1.4     kre 	atf_check -s exit:0 -o 'inline:hello\n' -e empty ${TEST_SH} -c \
    434   1.1     kre 		'echo hello 3</dev/null'
    435   1.4     kre 	atf_check -s exit:0 -o 'inline:hello 3\n' -e empty ${TEST_SH} -c \
    436   1.1     kre 		'echo hello 3 </dev/null'
    437   1.4     kre 	atf_check -s exit:0 -o 'inline:hello 3\n' -e empty ${TEST_SH} -c \
    438   1.1     kre 		'echo hello \3</dev/null'
    439   1.1     kre 	atf_check -s exit:0 -o 'inline:hello\n' -e empty ${TEST_SH} -c \
    440   1.4     kre 		'echo hello</dev/null'
    441   1.1     kre 	atf_check -s exit:0 -o 'inline:3\n' -e empty ${TEST_SH} -c \
    442   1.4     kre 		'hello=3; echo ${hello}</dev/null'
    443   1.1     kre 
    444   1.4     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    445   1.1     kre 		'2>&1'
    446   1.4     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    447   1.1     kre 		'2>& 1'
    448   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    449   1.4     kre 		'FD=1; 2>&"${FD}"'
    450   1.1     kre 	atf_check -s exit:0 -o 'inline:hello\n' -e empty ${TEST_SH} -c \
    451   1.1     kre 		'FD=1; echo hello 2>&"${FD}" >&2'
    452   1.1     kre 
    453   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    454   1.1     kre 		'2>&- 3<&- 4>&-'
    455   1.7     kre 
    456   1.7     kre 	return 0
    457   1.1     kre }
    458   1.1     kre 
    459   1.7     kre atf_test_case g_variable_syntax
    460   1.1     kre g_variable_syntax_head() {
    461   1.1     kre 	atf_set "descr" "Check that var names of all legal forms work"
    462   1.1     kre }
    463   1.1     kre g_variable_syntax_body() {
    464   1.5     kre 	# don't test _ as a variable, it can be "unusual"
    465   1.5     kre 	for vname in a ab _a _9 a123 a_1_2_3 __ ___ ____ __1__ _0 \
    466   1.5     kre 	    A AA AAA AaBb _A_a A_a_ a1_ abc_123 ab_12_cd_ef_34_99 \
    467   1.1     kre 	    abcdefghijklmnopqrstuvwzyz ABCDEFGHIJKLMNOPQRSTUVWXYZ_ \
    468   1.1     kre 	    A_VERY_LONG_VARIABLE_NAME_that_is_probably_longer_than_most_used_in_the_average_shell_script_already_about_100_chars_in_this_one_but_there_is_not_supposed_to_be_any_limit_on_the_length_at_all \
    469   1.1     kre 	    Then_Make_it_Even_Longer_by_Multiplying_it___A_VERY_LONG_VARIABLE_NAME_that_is_probably_longer_than_most_used_in_the_average_shell_script_already_about_100_chars_in_this_one_but_there_is_not_supposed_to_be_any_limit_on_the_length_at_all__A_VERY_LONG_VARIABLE_NAME_that_is_probably_longer_than_most_used_in_the_average_shell_script_already_about_100_chars_in_this_one_but_there_is_not_supposed_to_be_any_limit_on_the_length_at_all__A_VERY_LONG_VARIABLE_NAME_that_is_probably_longer_than_most_used_in_the_average_shell_script_already_about_100_chars_in_this_one_but_there_is_not_supposed_to_be_any_limit_on_the_length_at_all__A_VERY_LONG_VARIABLE_NAME_that_is_probably_longer_than_most_used_in_the_average_shell_script_already_about_100_chars_in_this_one_but_there_is_not_supposed_to_be_any_limit_on_the_length_at_all \
    470   1.1     kre 	    xyzzy __0123454321__ _0_1_2_3_4_5_6_7_8_9_ ABBA X_ Y__ Z___ \
    471   1.1     kre 	    _____________________________________________________________
    472   1.1     kre 	do
    473   1.1     kre 		atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    474   1.1     kre 			"unset ${vname}"
    475   1.1     kre 		atf_check -s exit:0 -o match:OK -e empty ${TEST_SH} -c \
    476   1.1     kre 			"unset ${vname}; printf %s \${${vname}-OK}"
    477   1.1     kre 		atf_check -s exit:0 -o match:GOOD -e empty ${TEST_SH} -c \
    478   1.1     kre 			"${vname}=GOOD; printf %s \${${vname}-OK}"
    479   1.1     kre 		atf_check -s exit:0 -o match:GOOD -e empty ${TEST_SH} -c \
    480   1.1     kre 			"${vname}=GOOD; printf %s \$${vname}"
    481   1.1     kre 		atf_check -s exit:0 -o match:GOOD -e empty ${TEST_SH} -c \
    482   1.1     kre 			"unset ${vname};${vname}=GOOD;printf %s \${${vname}-OK}"
    483   1.1     kre 		atf_check -s exit:0 -o match:OK -e empty ${TEST_SH} -c \
    484   1.1     kre 			"${vname}=GOOD;unset ${vname};printf %s \${${vname}-OK}"
    485   1.5     kre 		atf_check -s exit:0 -o match:GOOD -e empty ${TEST_SH} -c \
    486   1.5     kre 			"${vname}=GOOD; unset ${vname}x; printf %s \$${vname}"
    487   1.5     kre 		atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    488   1.5     kre 			"unset ${vname}x; ${vname}=GOOD; printf %s \$${vname}x"
    489   1.5     kre 		atf_check -s exit:0 -o match:GOOD -e empty ${TEST_SH} -c \
    490   1.5     kre 			"${vname}=GOOD; ${vname}_=BAD; printf %s \$${vname}"
    491   1.5     kre 
    492   1.5     kre 		case "${vname}" in
    493   1.5     kre 		?)	continue;;
    494   1.5     kre 		esac
    495   1.5     kre 
    496   1.5     kre 		# The following tests do not work for 1 char var names.
    497   1.5     kre 		# hence the check and "continue" above to skip the remaining
    498   1.5     kre 		# tests for that case
    499   1.5     kre 
    500   1.5     kre 		atf_check -s exit:0 -o match:GOOD -e empty ${TEST_SH} -c \
    501   1.5     kre 			"${vname}=GOOD; unset ${vname%?}; printf %s \$${vname}"
    502   1.5     kre 
    503   1.5     kre 		# (this next would work, but becomes just a duplicate of
    504   1.5     kre 		# an earlier test, so is pointless for 1 ch names)
    505   1.5     kre 		atf_check -s exit:0 -o match:GOOD -e empty ${TEST_SH} -c \
    506   1.5     kre 	"${vname}=GOOD; unset ${vname}x ${vname%?}; printf %s \$${vname}"
    507   1.5     kre 
    508   1.5     kre 		atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    509   1.5     kre 			"unset ${vname%?};${vname}=GOOD; printf %s \$${vname%?}"
    510   1.5     kre 
    511   1.5     kre 		atf_check -s exit:0 -o match:GOOD -e empty ${TEST_SH} -c \
    512   1.5     kre 			"${vname}=GOOD; ${vname%?}=BAD; printf %s \$${vname}"
    513   1.5     kre 
    514   1.5     kre 		# all the remaining tests require the 2nd char of the
    515   1.5     kre 		# variable name to be a legal first character.  That
    516   1.5     kre 		# is, not a digit, so skip the rest if we have a digit
    517   1.5     kre 		# second...
    518   1.5     kre 		case "${vname}" in
    519   1.5     kre 		?[0-9]*)	continue;;
    520   1.5     kre 		esac
    521   1.5     kre 
    522   1.5     kre 		atf_check -s exit:0 -o match:GOOD -e empty ${TEST_SH} -c \
    523   1.5     kre 			"${vname}=GOOD; unset ${vname#?}; printf %s \$${vname}"
    524   1.5     kre 		atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    525   1.5     kre 			"unset ${vname#?};${vname}=GOOD; printf %s \$${vname#?}"
    526   1.5     kre 
    527   1.5     kre 		atf_check -s exit:0 -o match:GOOD -e empty ${TEST_SH} -c \
    528   1.5     kre 			"${vname}=GOOD; ${vname#?}=BAD; printf %s \$${vname}"
    529   1.5     kre 
    530   1.5     kre 		atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    531   1.5     kre 			"unset ${vname%?} ${vname#?} ${vname}x; ${vname}=GOOD;
    532   1.5     kre 			printf %s \$${vname%?}\$${vname#?}\$${vname}x"
    533   1.1     kre 
    534   1.1     kre 		atf_check -s exit:0 -o match:GOOD -e empty ${TEST_SH} -c \
    535   1.1     kre 			"${vname}=GOOD; ${vname%?}=BAD; ${vname}_=BAD;
    536   1.1     kre 			${vname#?}=BAD; printf %s \$${vname}"
    537   1.1     kre 	done
    538   1.1     kre 
    539   1.1     kre 	# don't test '.' in var names, some shells permit that (in ${} anyway)
    540   1.1     kre 	# this test also cannot check for embedded - + ? = : % or #
    541   1.1     kre 	for vname in ,x -p +h :def 0_1 'x*x' '()' '"' "'" 'a b c' '?!' ';'
    542   1.1     kre 	do
    543   1.1     kre 		atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
    544   1.1     kre 			"echo \${${vname}}"
    545   1.1     kre 	done
    546   1.1     kre 
    547   1.1     kre 	for vname in ,x -p +h :def 0_1 'x*x' '()' '"' "'" 'a b c' x,y,z '?!' \
    548   1.1     kre 	    ';' a-b a+b 'a?b' 'a:b' 'a%b' 'a#b' 0 1 99 @ '*' '!' '?'
    549   1.1     kre 	do
    550   1.1     kre 		# failure modes will differ, but they should all fail somehow
    551   1.1     kre 		atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
    552   1.1     kre 			"${vname}="
    553   1.7     kre 	done
    554   1.7     kre 
    555   1.1     kre }
    556   1.1     kre 
    557   1.7     kre atf_test_case h_var_assign
    558   1.1     kre h_var_assign_head() {
    559   1.1     kre 	atf_set "descr" "Check var assignments "
    560   1.1     kre }
    561   1.1     kre h_var_assign_body() {
    562   1.1     kre 	atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \
    563   1.1     kre 		'a=b'
    564   1.1     kre 	atf_check -s not-exit:0 -e not-empty -o empty ${TEST_SH} -c \
    565   1.1     kre 		'\a=b'
    566   1.1     kre 	atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \
    567   1.1     kre 		'a=b c=d'
    568   1.1     kre 	atf_check -s exit:0 -e empty -o 'inline:e=f\n' ${TEST_SH} -c \
    569   1.1     kre 		'a=b c=d echo e=f'
    570   1.1     kre 	atf_check -s exit:0 -e empty -o 'inline:e=f\n' ${TEST_SH} -c \
    571   1.1     kre 		'a=b 2>/dev/null c=d </dev/null echo e=f'
    572   1.1     kre 
    573   1.1     kre 	# We need to make sure that we do not accidentally
    574   1.1     kre 	# find a command called 'a=b' ...
    575   1.1     kre 
    576   1.1     kre 	for d in /foo /foo/bar /not-dir /no/such/directory '/!!!' \
    577   1.1     kre 		'/-/--/#' '/"/""/"""' - 
    578   1.1     kre 	do
    579   1.1     kre 		test -d "${d}" || break
    580   1.1     kre 	done
    581   1.1     kre 	test "${#d}" -gt 1 || atf-skip 'Wacky directories seem to exist!'
    582   1.1     kre 
    583   1.1     kre 	atf_check -s exit:0 -e empty -o empty ${TEST_SH} -c \
    584   1.1     kre 		"PATH='${d}';"'a=\b'
    585   1.1     kre 	atf_check -s not-exit:0 -e not-empty -o empty ${TEST_SH} -c \
    586   1.1     kre 		"PATH='${d}';"'a\=b'
    587   1.1     kre 	atf_check -s not-exit:0 -e not-empty -o empty ${TEST_SH} -c \
    588   1.1     kre 		"PATH='${d}';"'\a=b'
    589   1.1     kre 	atf_check -s not-exit:0 -e not-empty -o empty ${TEST_SH} -c \
    590   1.1     kre 		"PATH='${d}';"'X=; c=d ${X} a=b'
    591   1.1     kre }
    592   1.1     kre 
    593   1.1     kre atf_test_case i_pipelines
    594   1.1     kre i_pipelines_head() {
    595   1.1     kre 	atf_set "descr" "Check pipelines"
    596   1.1     kre }
    597   1.1     kre i_pipelines_body() {
    598   1.1     kre 
    599   1.1     kre 	cmd='printf "%s\n" foo'
    600   1.1     kre 	for n in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
    601   1.1     kre 	do
    602   1.1     kre 		atf_check -s exit:0 -o inline:'foo\n' -e empty ${TEST_SH} -c \
    603   1.1     kre 			"${cmd}"
    604   1.1     kre 		cmd="${cmd} | cat"
    605   1.1     kre 	done
    606   1.1     kre 
    607   1.1     kre 	cmd='printf "%s\n" foo'
    608   1.1     kre 	for n in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
    609   1.1     kre 	do
    610   1.1     kre 		atf_check -s exit:0 -o inline:'foo\n' -e empty ${TEST_SH} -c \
    611   1.1     kre 			"${cmd}"
    612   1.1     kre 		cmd="${cmd} |
    613   1.1     kre 		cat"
    614   1.1     kre 	done
    615   1.1     kre 
    616   1.1     kre 	cmd='printf "%s\n" foo'
    617   1.1     kre 	for n in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
    618   1.1     kre 	do
    619   1.1     kre 		atf_check -s exit:0 -o inline:'foo\n' -e empty ${TEST_SH} -c \
    620   1.1     kre 			"${cmd}"
    621   1.1     kre 		cmd="${cmd} |
    622   1.1     kre 
    623   1.1     kre 
    624   1.1     kre 
    625   1.1     kre 
    626   1.1     kre 		cat"
    627   1.1     kre 	done
    628   1.1     kre 
    629   1.1     kre 	cmd='! printf "%s\n" foo'
    630   1.1     kre 	for n in 1 2 3 4 5 6 7 8 9 10
    631   1.1     kre 	do
    632   1.1     kre 		atf_check -s exit:1 -o inline:'foo\n' -e empty ${TEST_SH} -c \
    633   1.1     kre 			"${cmd}"
    634   1.1     kre 		cmd="${cmd} | cat"
    635   1.1     kre 	done
    636   1.1     kre 
    637   1.1     kre 	cmd='exec 4>&2 3<&0; printf "%s\n" foo'
    638   1.1     kre 	for n in 1 2 3
    639   1.1     kre 	do
    640   1.1     kre 	    pfx=
    641   1.1     kre 	    for xtra in 'x=y' 'a=b' '6>&1' '5<&3'
    642   1.1     kre 	    do
    643   1.1     kre 		atf_check -s exit:0 -o inline:'foo\n' -e empty ${TEST_SH} -c \
    644   1.1     kre 			"${cmd} | ${xtra} cat"
    645   1.1     kre 
    646   1.1     kre 		atf_check -s exit:0 -o inline:'foo\n' -e empty ${TEST_SH} -c \
    647   1.1     kre 			"${cmd} | ${pfx} cat"
    648   1.1     kre 
    649   1.1     kre 		pfx="${pfx} ${xtra}"
    650   1.1     kre 	    done
    651   1.1     kre 	    cmd="${cmd} | ${pfx} cat"
    652   1.1     kre 	done
    653   1.1     kre 
    654   1.1     kre 	# pipelines are not required to contain commands ...
    655   1.1     kre 	# they don't do anything useful (at all) but the syntax is legal
    656   1.1     kre 	base='4>&2'; cmd="${base}"
    657   1.1     kre 	for pipe in 'a=b' '3<&0' '>>/dev/null' 'a= b= c=' '${x}' 'cat'
    658   1.1     kre 	do
    659   1.1     kre 		atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    660   1.1     kre 			"${base} | ${pipe}"
    661   1.1     kre 
    662   1.1     kre 		atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    663   1.1     kre 			"${cmd} | ${pipe}"
    664   1.1     kre 
    665   1.1     kre 		cmd="${cmd} | ${pipe}"
    666   1.1     kre 	done
    667   1.1     kre 
    668   1.1     kre 	# but the command cannot be empty, or a reserved word used improperly
    669   1.1     kre 	base='printf "%s\n" foo'; cmd="${base}"
    670   1.1     kre 	for pipe in '' do done then else fi esac
    671   1.1     kre 	do
    672   1.1     kre 		atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
    673   1.1     kre 			"${base} | ${pipe}"
    674   1.1     kre 
    675   1.1     kre 		atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
    676   1.1     kre 			"${pipe} | ${base}"
    677   1.1     kre 
    678   1.1     kre 		atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
    679   1.1     kre 			"${cmd} | ${pipe}"
    680   1.1     kre 
    681   1.1     kre 		cmd="${cmd} | ${pipe}"
    682   1.1     kre 	done
    683   1.1     kre }
    684   1.1     kre 
    685   1.1     kre atf_test_case j_and_or_lists
    686   1.1     kre j_and_or_lists_head() {
    687   1.1     kre 	atf_set "descr" "Check && and || command lists"
    688   1.1     kre }
    689   1.1     kre j_and_or_lists_body() {
    690   1.1     kre 	and=true
    691   1.1     kre 	or=false
    692   1.1     kre 	and_or=false
    693   1.1     kre 	for i in 1 2 3 4 5 6 7 8 9 10
    694   1.1     kre 	do
    695   1.1     kre 		atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    696   1.1     kre 			"${and}"
    697   1.1     kre 
    698   1.1     kre 		atf_check -s exit:1 -o empty -e empty ${TEST_SH} -c \
    699   1.1     kre 			"${or}"
    700   1.1     kre 
    701   1.1     kre 		atf_check -s exit:1 -o empty -e empty ${TEST_SH} -c \
    702   1.1     kre 			"${and_or}"
    703   1.1     kre 
    704   1.1     kre 		and="${and} && true"
    705   1.1     kre 		or="${or} || false"
    706   1.1     kre 		and_or="${and_or} || true && false"
    707   1.1     kre 	done
    708   1.1     kre 
    709   1.1     kre 	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
    710   1.1     kre 		'true &&'
    711   1.1     kre 	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
    712   1.1     kre 		'&& true'
    713   1.1     kre 	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
    714   1.1     kre 		'|| true'
    715   1.1     kre 	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
    716   1.1     kre 		'true ||'
    717   1.1     kre 	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
    718   1.1     kre 		'true || && false'
    719   1.1     kre 	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
    720   1.1     kre 		'false || && true'
    721   1.1     kre 
    722   1.1     kre 	cmd='printf "%s" foo | cat | cat>/dev/null'
    723   1.1     kre 	line="${cmd}"
    724   1.1     kre 	for i in 1 2 3 4
    725   1.1     kre 	do
    726   1.1     kre 		line="${line} && ! ${cmd} || ${cmd}"
    727   1.1     kre 
    728   1.1     kre 		atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    729   1.1     kre 			"${line}"
    730   1.1     kre 	done
    731   1.1     kre 
    732   1.1     kre }
    733   1.1     kre 
    734   1.1     kre atf_test_case k_lists
    735   1.1     kre k_lists_head() {
    736   1.1     kre 	atf_set "descr" "Check ; command lists"
    737   1.1     kre }
    738   1.1     kre k_lists_body() {
    739   1.1     kre 	line=
    740   1.1     kre 	for N in 1 2 3 4
    741   1.1     kre 	do
    742   1.1     kre 		for cmd in \
    743   1.1     kre 			true false : 'cat</dev/null>/dev/null' x=3 'exec 4>&-'
    744   1.1     kre 		do
    745   1.1     kre 			line="${line}${line:+;}${cmd}"
    746   1.1     kre 			atf_check -s exit:0 -o 'inline:hello\nworld\n' \
    747   1.1     kre 				-e empty ${TEST_SH} -c \
    748   1.1     kre 					"echo hello; ${line}; echo world"
    749   1.1     kre 			atf_check -s exit:0 -o 'inline:hello\nworld\n' \
    750   1.1     kre 				-e empty ${TEST_SH} -c \
    751   1.1     kre 					"echo hello; ${line}; echo world;"
    752   1.1     kre 		done
    753   1.1     kre 	done
    754   1.1     kre 
    755   1.1     kre 	for cmd in ';' ';;' 'false ;; true' 'false; ;true' '; true'
    756   1.1     kre 	do
    757   1.1     kre 		atf_check -s not-exit:0 -o ignore -e not-empty \
    758   1.1     kre 			${TEST_SH} -c "${cmd}"
    759   1.1     kre 	done
    760   1.1     kre }
    761   1.1     kre 
    762   1.1     kre atf_test_case l_async_lists
    763   1.1     kre l_async_lists_head() {
    764   1.1     kre 	atf_set "descr" "Check & command lists"
    765   1.1     kre }
    766   1.1     kre l_async_lists_body() {
    767   1.1     kre 	line=
    768   1.1     kre 	for N in 1 2 3 4
    769   1.1     kre 	do
    770   1.1     kre 		for cmd in \
    771   1.1     kre 			true false : 'cat</dev/null>/dev/null' x=3 'exec 4>&-'
    772   1.1     kre 		do
    773   1.1     kre 			line="${line:+${line}&}${cmd}"
    774   1.1     kre 			atf_check -s exit:0 -o 'inline:hello\nworld\n' \
    775   1.1     kre 				-e empty ${TEST_SH} -c \
    776   1.1     kre 					"echo hello; ${line}& echo world"
    777   1.1     kre 			atf_check -s exit:0 -o 'inline:hello\nworld\n' \
    778   1.1     kre 				-e empty ${TEST_SH} -c \
    779   1.1     kre 					"echo hello; ${line}& echo world"
    780   1.1     kre 		done
    781   1.1     kre 	done
    782   1.1     kre 
    783   1.1     kre 	for cmd in '&' ';&' '&;'  '& true' 'false& &true'
    784   1.1     kre 	do
    785   1.1     kre 		atf_check -s not-exit:0 -o ignore -e not-empty \
    786   1.1     kre 			${TEST_SH} -c "${cmd}"
    787   1.1     kre 	done
    788   1.1     kre }
    789   1.1     kre 
    790   1.1     kre atf_test_case m_compound_lists
    791   1.1     kre m_compound_lists_head() {
    792   1.1     kre 	atf_set "descr" "Check subshells () and { ;} command grouping"
    793   1.1     kre }
    794   1.1     kre m_compound_lists_body() {
    795   1.1     kre 	# Note: (( is an unspecified (reserved) operator, don't use it...
    796   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    797   1.1     kre 		'( true )'
    798   1.1     kre 	atf_check -s exit:1 -o empty -e empty ${TEST_SH} -c \
    799   1.1     kre 		'( false )'
    800   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    801   1.1     kre 		'( (:) )'
    802   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    803   1.1     kre 		'( ( true ))'
    804   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    805   1.1     kre 		'( ( ( ( (  true )))))'
    806   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    807   1.1     kre 		'( ( ( ( (true);:));true))'
    808   1.1     kre 
    809   1.1     kre 	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
    810   1.1     kre 		'()'
    811   1.1     kre 	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
    812   1.1     kre 		'(   )'
    813   1.1     kre 
    814   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    815   1.1     kre 		'{ true; }'
    816   1.1     kre 	atf_check -s exit:1 -o empty -e empty ${TEST_SH} -c \
    817   1.1     kre 		'{ false; }'
    818   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    819   1.1     kre 		'{ { :; };}'
    820   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    821   1.1     kre 		'{ { { { {  :;};};};};}'
    822   1.1     kre 
    823   1.1     kre 	atf_check -s exit:0 -o 'inline:}\n' -e empty ${TEST_SH} -c \
    824   1.1     kre 		'{ echo } ; }'
    825   1.1     kre 	atf_check -s exit:0 -o 'inline:{\n' -e empty ${TEST_SH} -c \
    826   1.1     kre 		'{ echo { ; }'
    827   1.1     kre }
    828   1.1     kre 
    829   1.1     kre atf_test_case q_for_loop
    830   1.1     kre q_for_loop_head() {
    831   1.1     kre 	atf_set "descr" "Check for loop parsing"
    832   1.1     kre }
    833   1.1     kre q_for_loop_body() {
    834   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    835   1.1     kre 		'for x; do : ; done'
    836   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    837   1.1     kre 		'for x in ; do : ; done'
    838   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    839   1.1     kre 		'for x in a b c ; do : ; done'
    840   1.1     kre 
    841   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    842   1.1     kre 		'for x in in;do : ; done'
    843   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    844   1.1     kre 		'for x in for;do : ; done'
    845   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    846   1.1     kre 		'for x in do;do : ; done'
    847   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    848   1.1     kre 		'for for in in;do :;done'
    849   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    850   1.1     kre 		'for for in for;do :; done'
    851   1.2     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    852   1.2     kre 		'for for in do;do : ;done'
    853   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    854   1.1     kre 		'for in in in;do : ; done'
    855   1.1     kre 	atf_check -s exit:0 -o 'inline:do\nin\ndo\n' -e empty ${TEST_SH} -c \
    856   1.1     kre    'for in in in do in;do case $in in in)echo do;;do)echo in;;esac; done'
    857   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    858   1.1     kre 		'for in in for;do : ; done'
    859   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    860   1.1     kre 		'for in in do;do : ; done'
    861   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    862   1.1     kre 		'for do in in;do : ; done'
    863   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    864   1.1     kre 		'for do in for;do : ; done'
    865   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    866   1.1     kre 		'for do in do;do : ; done'
    867   1.1     kre 	atf_check -s exit:0 -o 'inline:dodo\n' -e empty ${TEST_SH} -c \
    868   1.1     kre 		'for do in do;do echo ${do}do ; done'
    869   1.1     kre }
    870   1.1     kre 
    871   1.1     kre atf_test_case r_case
    872   1.1     kre r_case_head() {
    873   1.1     kre 	atf_set "descr" "Check case statement parsing"
    874   1.1     kre }
    875   1.1     kre r_case_body() {
    876   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    877   1.1     kre 		'case x in  esac'
    878   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    879   1.1     kre 		'case x in x) esac'
    880   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    881   1.1     kre 		'case x in (x) esac'
    882   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    883   1.1     kre 		'case x in x) ;; esac'
    884   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    885   1.1     kre 		'case x in (x) ;; esac'
    886   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    887   1.1     kre 		'case x in x|y) ;; esac'
    888   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    889   1.1     kre 		'case x in (x|y) ;; esac'
    890   1.1     kre 
    891   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    892   1.1     kre 		'case x in x|esac) ;; esac'
    893   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    894   1.1     kre 		'case x in x|esac|y) ;; esac'
    895   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    896   1.1     kre 		'case x in (x|esac) ;; esac'
    897   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    898   1.1     kre 		'case x in (x|esac|y) ;; esac'
    899   1.1     kre 
    900   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    901   1.1     kre 		'case x in in) esac'
    902   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    903   1.1     kre 		'case x in in) ;; esac'
    904   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    905   1.1     kre 		'case x in x|in) ;; esac'
    906   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    907   1.1     kre 		'case x in x|in|y) ;; esac'
    908   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    909   1.1     kre 		'case x in (x|in) ;; esac'
    910   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    911   1.1     kre 		'case x in (in|x) ;; esac'
    912   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    913   1.1     kre 		'case x in (x|in|y) ;; esac'
    914   1.1     kre 
    915   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    916   1.1     kre 		'case case in case) esac'
    917   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    918   1.1     kre 		'case in in in) esac'
    919   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    920   1.1     kre 		'case esac in (in) esac'
    921   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    922   1.1     kre 		'case in in esac|cat'
    923   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    924   1.1     kre 		'case esac in esac|cat'
    925   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    926   1.1     kre 		'case in in esac|case x in u) echo foo;; esac'
    927   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    928   1.1     kre 		'case esac in esac|case x in u) echo foo;; esac'
    929   1.1     kre 	atf_check -s exit:0 -o 'inline:foo\n' -e empty ${TEST_SH} -c \
    930   1.1     kre 		'case in in esac|case x in x) echo foo;; esac'
    931   1.1     kre 
    932   1.1     kre 	atf_check -s not-exit:0 -o empty -e not-empty ${TEST_SH} -c \
    933   1.1     kre 		'case in in (esac|cat'
    934   1.1     kre 
    935   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    936   1.1     kre 		'case x in x );;esac'
    937   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    938   1.1     kre 		'case x in ( x );;esac'
    939   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    940   1.1     kre 		'case x in x | y );;esac'
    941   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    942   1.1     kre 		'case x in ( x | y );;esac'
    943   1.1     kre 
    944   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    945   1.1     kre 		'case x
    946   1.1     kre 		 in
    947   1.1     kre 		 (    x    |    y    )
    948   1.1     kre 
    949   1.1     kre 			;;
    950   1.1     kre 
    951   1.1     kre 
    952   1.1     kre 		esac
    953   1.1     kre 		'
    954   1.1     kre }
    955   1.1     kre 
    956   1.1     kre atf_test_case s_if
    957   1.1     kre s_if_head() {
    958   1.1     kre 	atf_set "descr" "Check if statement parsing"
    959   1.1     kre }
    960   1.1     kre s_if_body() {
    961   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    962   1.1     kre 		'if :; then :; fi'
    963   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    964   1.1     kre 		'if :; then :; else :; fi'
    965   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    966   1.1     kre 		'if :; then :; elif :; then :; else :; fi'
    967   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    968   1.1     kre 		'if :; then :; elif :; then :; elif :; then :; else :; fi'
    969   1.1     kre 
    970   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    971   1.1     kre 		'if :; then : else :; fi'
    972   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    973   1.1     kre 		'if : then :; then :; fi'
    974   1.1     kre 
    975   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    976   1.1     kre 		'if if :;then :;fi then :;fi'
    977   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    978   1.1     kre 		'if if :;then if :;then :;fi fi;then :;fi'
    979   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
    980   1.1     kre 		'if if :;then :;fi;then :;else if :;then :;fi fi'
    981   1.1     kre 
    982   1.1     kre 	for a in true false; do
    983   1.1     kre 		for b in true false; do
    984   1.1     kre 			for c in true false; do
    985   1.1     kre 
    986   1.1     kre 				$a && out=a || {
    987   1.1     kre 				$b && out=b || {
    988   1.1     kre 				$c && out=c || {
    989   1.1     kre 				out=d; };};}
    990   1.1     kre 
    991   1.1     kre 				atf_check -s exit:0 -e empty \
    992   1.1     kre 					-o "inline:${out}"'\n' \
    993   1.1     kre 					${TEST_SH} -c \
    994   1.1     kre 						"if $a; then echo a
    995   1.1     kre 						elif $b; then echo b
    996   1.1     kre 						elif $c; then echo c
    997   1.1     kre 						else echo d
    998   1.1     kre 						fi"
    999   1.1     kre 			done
   1000   1.1     kre 		done
   1001   1.1     kre 	done
   1002   1.1     kre }
   1003   1.1     kre 
   1004   1.1     kre atf_test_case t_loops
   1005   1.1     kre t_loops_head() {
   1006   1.1     kre 	atf_set "descr" "Check while/until loop parsing"
   1007   1.1     kre }
   1008   1.1     kre t_loops_body() {
   1009   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1010   1.1     kre 		'while false; do :; done'
   1011   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1012   1.1     kre 		'while false; do \done; done'
   1013   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1014   1.1     kre 		'until :; do :; done'
   1015   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1016   1.1     kre 		'until :; do \done; done'
   1017   1.1     kre 
   1018   1.1     kre 	atf_check -s exit:0 -o 'inline:x\n1\n' -e empty ${TEST_SH} -c \
   1019   1.1     kre 		':; while (exit) do echo x; false; done; echo $?'
   1020   1.1     kre 	atf_check -s exit:0 -o 'inline:x\n0\n' -e empty ${TEST_SH} -c \
   1021   1.1     kre 		'false; until (exit) do echo x; done; echo $?'
   1022   1.1     kre }
   1023   1.1     kre 
   1024   1.1     kre atf_test_case u_case_cont
   1025   1.1     kre u_case_cont_head() {
   1026   1.1     kre 	atf_set "descr" "Check case stmt parsing using ;& [optional]"
   1027   1.1     kre }
   1028   1.1     kre u_case_cont_body() {
   1029   1.1     kre 
   1030   1.1     kre 	${TEST_SH} -c 'case x in (x) false ;& (y) : ;; esac' 2>/dev/null ||
   1031   1.1     kre 		atf_skip ";& case list terminator unsupported in ${TEST_SH}"
   1032   1.1     kre 
   1033   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1034   1.1     kre 		'case x in x) ;& esac'
   1035   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1036   1.1     kre 		'case x in (x) ;& esac'
   1037   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1038   1.1     kre 		'case x in x|y) ;& esac'
   1039   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1040   1.1     kre 		'case x in (x|y) ;& esac'
   1041   1.1     kre 
   1042   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1043   1.1     kre 		'case x in x );&esac'
   1044   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1045   1.1     kre 		'case x in ( x );&esac'
   1046   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1047   1.1     kre 		'case x in x | y );&esac'
   1048   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1049   1.1     kre 		'case x in ( x | y );&esac'
   1050   1.1     kre 
   1051   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1052   1.1     kre 		'case x in x) ;& (y) esac'
   1053   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1054   1.1     kre 		'case x in (x) ;& esac'
   1055   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1056   1.1     kre 		'case x in x|y) ;& esac'
   1057   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1058   1.1     kre 		'case x in (x|y) ;& esac'
   1059   1.1     kre }
   1060   1.1     kre 
   1061   1.1     kre atf_test_case x_functions
   1062   1.1     kre x_functions_head() {
   1063   1.1     kre 	atf_set "descr" "Check function definition parsing"
   1064   1.1     kre }
   1065   1.1     kre x_functions_body() {
   1066   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1067   1.1     kre 		'func() { :; }'
   1068   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1069   1.1     kre 		'func() { :; }; func'
   1070   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1071   1.1     kre 		'func()(:)'
   1072   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1073   1.1     kre 		'func()if :; then false; else true; fi'
   1074   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1075   1.1     kre 		'func()while false; do :;done'
   1076   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1077   1.1     kre 		'func () for a in b c; do :; done'
   1078   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1079   1.1     kre 		'func() case x in (y) esac'
   1080   1.1     kre 
   1081   1.1     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1082   1.1     kre 		'f1() { f2() { :; }; }; f1; f2'
   1083   1.1     kre 
   1084   1.1     kre 	# f2 should be not found, but f1 clears $?
   1085   1.1     kre 	atf_check -s exit:0 -o empty -e not-empty ${TEST_SH} -c \
   1086   1.1     kre 		'f1() { f2() { :; }; }; f2; f1'
   1087   1.1     kre 
   1088   1.6     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1089   1.6     kre 		'f1() { eval "$1() { :; }"; }; f1 f2; f2'
   1090   1.6     kre }
   1091   1.6     kre 
   1092   1.6     kre atf_test_case z_PR_48498
   1093   1.6     kre z_PR_48498_head() {
   1094   1.6     kre 	atf_set "descr" "Check for detecting the syntax error from PR bin/48498"
   1095   1.6     kre }
   1096   1.6     kre z_PR_48498_body() {
   1097   1.6     kre 
   1098   1.6     kre 	# reserved words/operators that end things,
   1099   1.6     kre 	# were completely ignored after a ';' or '&'
   1100   1.6     kre 	# many of these tests lifted directly from the PR
   1101   1.6     kre 
   1102   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1103   1.6     kre 		'true; fi'
   1104   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1105   1.6     kre 		'false; fi'
   1106   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1107   1.6     kre 		'false; then echo wut'
   1108   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1109   1.6     kre 		'true; then echo wut'
   1110   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1111   1.6     kre 		'true; do echo wut'
   1112   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1113   1.6     kre 		'true; then'
   1114   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1115   1.6     kre 		'true; else'
   1116   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1117   1.6     kre 		'true; do'
   1118   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1119   1.6     kre 		'true; done'
   1120   1.6     kre 		# {
   1121   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1122   1.6     kre 		': ; }'
   1123   1.6     kre 		# (
   1124   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1125   1.6     kre 		':;)'
   1126   1.6     kre 
   1127   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1128   1.6     kre 		'true& fi'
   1129   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1130   1.6     kre 		'false& fi'
   1131   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1132   1.6     kre 		'false& then echo wut'
   1133   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1134   1.6     kre 		'true& then echo wut'
   1135   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1136   1.6     kre 		'true& do echo wut'
   1137   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1138   1.6     kre 		'true& then'
   1139   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1140   1.6     kre 		'true& else'
   1141   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1142   1.6     kre 		'true& do'
   1143   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1144   1.6     kre 		'true&done'
   1145   1.6     kre 		# {
   1146   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1147   1.6     kre 		':&}'
   1148   1.6     kre 		# (
   1149   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1150   1.6     kre 		':&)'
   1151   1.6     kre }
   1152   1.6     kre 
   1153   1.6     kre atf_test_case z_PR_52426
   1154   1.6     kre z_PR_52426_head() {
   1155   1.6     kre 	atf_set "descr" "Check for detecting the syntax error from PR bin/52426"
   1156   1.6     kre }
   1157   1.6     kre z_PR_52426_body() {
   1158   1.6     kre 	# Absoluely anything was permitted as a pattern of a case
   1159   1.6     kre 	# statement, any token (except 'esac') would serve
   1160   1.6     kre 	# What follows are a few "pretty" examples that were accepted.
   1161   1.6     kre 	# The first is the example from the PR
   1162   1.6     kre 
   1163   1.6     kre 	# Note we use only ;; type case lists, ;& should do the same, but
   1164   1.6     kre 	# only for shells that support it, we do not want the shell to
   1165   1.6     kre 	# object to any of these just because it does not support ;&
   1166   1.6     kre 
   1167   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1168   1.6     kre 		'case x in <|() ;; esac'
   1169   1.6     kre 
   1170   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1171   1.6     kre 		'case x in ((|)) ;; esac'
   1172   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1173   1.6     kre 		'case x in _|() ;; esac'
   1174   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1175   1.6     kre 		'case x in ()|() ;; esac'
   1176   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1177   1.6     kre 		'case x in -|;) ;; esac'
   1178   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1179   1.6     kre 		'case x in (;|-) ;; esac'
   1180   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1181   1.6     kre 		'case x in ;;|;) ;; esac'
   1182   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1183   1.6     kre 		'case x in (|| | ||) ;; esac'
   1184   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1185   1.6     kre 		'case x in (<<|>>) ;; esac'
   1186   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1187   1.6     kre 		'case x in (&&|&) ;; (|||>&) ;; &) esac'
   1188   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1189   1.6     kre 		'case x in (>||<) ;; esac'
   1190   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1191   1.6     kre 		'case x in( || | || | || | || | || );; esac'
   1192   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1193   1.6     kre 		'case x in (||| ||| ||| ||| ||) ;; esac'
   1194   1.6     kre 	atf_check -s not-exit:0 -o ignore -e not-empty ${TEST_SH} -c \
   1195   1.6     kre 		'case x in <> |          
   1196   1.6     kre 		) ;; esac'
   1197   1.6     kre 
   1198   1.6     kre 	# now check some similar looking cases that are supposed to work
   1199   1.6     kre 	# That is, make sure the fix for the PR does not break valid cases.
   1200   1.6     kre 
   1201   1.6     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1202   1.6     kre 		'case fi in ({|}) ;; (!) ;; esac'
   1203   1.6     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1204   1.6     kre 		'case esac in ([|]);; (][);; !!!|!!!|!!!|!!!);; esac'
   1205   1.6     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1206   1.6     kre 		'case then in ({[]]}) ;; (^^);; (^|^);; ([!]);; (-);; esac'
   1207   1.6     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1208   1.6     kre 		'case while in while   );;(if|then|elif|fi);;(do|done);; esac'
   1209   1.6     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1210   1.6     kre 		'case until in($);;($$);;($4.50);;(1/2);;0.3333);;esac'
   1211   1.6     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1212   1.6     kre 		'case return in !);; !$);; $!);; !#);; (@);; esac'
   1213  1.10     kre 	atf_check -s exit:0 -o empty -e empty ${TEST_SH} -c \
   1214  1.10     kre 		'case break in (/);; (\/);; (/\|/\));; (\\//);; esac'
   1215  1.10     kre }
   1216  1.10     kre 
   1217  1.10     kre atf_test_case z_PR_53712
   1218  1.10     kre z_PR_53712_head() {
   1219  1.10     kre 	atf_set "descr" "Check for avoiding the core dump from PR bin/53712"
   1220  1.10     kre }
   1221  1.10     kre z_PR_53712_body() {
   1222  1.10     kre 	atf_require_prog sysctl
   1223  1.10     kre 	atf_require_prog rm
   1224  1.10     kre 
   1225  1.10     kre 	# Don't want to have to deal with all the possible ways
   1226  1.10     kre 	# that the systcm might be configured to drop core files...
   1227  1.10     kre 	sysctl -w proc.$$.corename=core ||
   1228  1.10     kre 		atf_skip "Unable to set file name for core dump file"
   1229  1.10     kre 	rm -f core
   1230  1.10     kre 
   1231  1.10     kre 	${TEST_SH} -c '{ } > out'; S=$?
   1232  1.10     kre 	test -f core &&
   1233  1.10     kre 		atf_fail "PR bin/53712: ${TEST_SH} dumps core: status=$S"
   1234  1.10     kre 	test "$S" -lt 128 ||
   1235  1.10     kre 		atf_fail "PR bin/53712: ${TEST_SH} reported status $S (core?)"
   1236  1.10     kre 
   1237  1.10     kre 	# It doesn't matter here whether or not there was an error
   1238  1.10     kre 	# from the empty compound, or whether "out" was created
   1239  1.10     kre 	# just that no core dump appeared, and the shell did not
   1240  1.10     kre 	# exit because of a signal.
   1241   1.1     kre 
   1242   1.1     kre 	return 0
   1243   1.1     kre }
   1244   1.1     kre 
   1245   1.7     kre atf_init_test_cases() {
   1246   1.7     kre 	atf_add_test_case a_basic_tokenisation
   1247   1.7     kre 	atf_add_test_case b_comments
   1248   1.7     kre 	atf_add_test_case c_line_wrapping
   1249   1.1     kre 	atf_add_test_case d_cstrings
   1250   1.1     kre 	atf_add_test_case f_redirects
   1251   1.1     kre 	atf_add_test_case g_variable_syntax
   1252   1.1     kre 	atf_add_test_case h_var_assign
   1253   1.1     kre 	atf_add_test_case i_pipelines
   1254   1.1     kre 	atf_add_test_case j_and_or_lists
   1255   1.1     kre 	atf_add_test_case k_lists
   1256   1.1     kre 	atf_add_test_case l_async_lists
   1257   1.1     kre 	atf_add_test_case m_compound_lists
   1258   1.1     kre 	atf_add_test_case q_for_loop
   1259   1.1     kre 	atf_add_test_case r_case
   1260   1.6     kre 	atf_add_test_case s_if
   1261   1.6     kre 	atf_add_test_case t_loops
   1262   1.6     kre 	atf_add_test_case u_case_cont
   1263  1.10     kre 	atf_add_test_case x_functions
   1264   1.1     kre 
   1265               	atf_add_test_case z_PR_48498
   1266               	atf_add_test_case z_PR_52426
   1267               	atf_add_test_case z_PR_53712
   1268               }
   1269