xref: /freebsd/contrib/netbsd-tests/bin/sh/t_cmdsub.sh (revision c22165b4f1f5d38b681921797a44b3ba8c13b7e0)
1*640235e2SEnji Cooper# $NetBSD: t_cmdsub.sh,v 1.4 2016/04/04 12:40:13 christos Exp $
2*640235e2SEnji Cooper#
3*640235e2SEnji Cooper# Copyright (c) 2016 The NetBSD Foundation, Inc.
4*640235e2SEnji Cooper# All rights reserved.
5*640235e2SEnji Cooper#
6*640235e2SEnji Cooper# Redistribution and use in source and binary forms, with or without
7*640235e2SEnji Cooper# modification, are permitted provided that the following conditions
8*640235e2SEnji Cooper# are met:
9*640235e2SEnji Cooper# 1. Redistributions of source code must retain the above copyright
10*640235e2SEnji Cooper#    notice, this list of conditions and the following disclaimer.
11*640235e2SEnji Cooper# 2. Redistributions in binary form must reproduce the above copyright
12*640235e2SEnji Cooper#    notice, this list of conditions and the following disclaimer in the
13*640235e2SEnji Cooper#    documentation and/or other materials provided with the distribution.
14*640235e2SEnji Cooper#
15*640235e2SEnji Cooper# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16*640235e2SEnji Cooper# ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17*640235e2SEnji Cooper# TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18*640235e2SEnji Cooper# PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19*640235e2SEnji Cooper# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20*640235e2SEnji Cooper# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21*640235e2SEnji Cooper# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22*640235e2SEnji Cooper# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23*640235e2SEnji Cooper# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24*640235e2SEnji Cooper# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25*640235e2SEnji Cooper# POSSIBILITY OF SUCH DAMAGE.
26*640235e2SEnji Cooper#
27*640235e2SEnji Cooper# the implementation of "sh" to test
28*640235e2SEnji Cooper: ${TEST_SH:="/bin/sh"}
29*640235e2SEnji Cooper
30*640235e2SEnji Cooper#
31*640235e2SEnji Cooper# This file tests command substitutions ( `...` and $( ... ) )
32*640235e2SEnji Cooper#
33*640235e2SEnji Cooper# CAUTION:
34*640235e2SEnji Cooper#	Be careful attempting running these tests outside the ATF environment
35*640235e2SEnji Cooper#	Some of the tests run "rm *" in the current directory to clean up
36*640235e2SEnji Cooper#	An ATF test directory should be empty already, outside ATF, anything
37*640235e2SEnji Cooper
38*640235e2SEnji Cooperatf_test_case a_basic_cmdsub
39*640235e2SEnji Coopera_basic_cmdsub_head() {
40*640235e2SEnji Cooper	atf_set "descr" 'Test operation of simple $( ) substitutions'
41*640235e2SEnji Cooper}
42*640235e2SEnji Coopera_basic_cmdsub_body() {
43*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'Result is true today' -e empty \
44*640235e2SEnji Cooper	    ${TEST_SH} -c \
45*640235e2SEnji Cooper		'echo Result is $( true && echo true || echo false ) today'
46*640235e2SEnji Cooper
47*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'Result is false today' -e empty \
48*640235e2SEnji Cooper	    ${TEST_SH} -c \
49*640235e2SEnji Cooper		'echo Result is $( false && echo true || echo false ) today'
50*640235e2SEnji Cooper
51*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'aaabbbccc' -e empty \
52*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo aaa$( echo bbb )ccc'
53*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'aaabbb cccddd' -e empty \
54*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo aaa$( echo bbb ccc )ddd'
55*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'aaabbb cccddd\n' -e empty \
56*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo aaa$( echo bbb; echo ccc )ddd'
57*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'aaabbb\ncccddd\n' -e empty \
58*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo "aaa$( echo bbb; echo ccc )ddd"'
59*640235e2SEnji Cooper
60*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'some string\n' -e empty \
61*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=$( echo some string ); echo "$X"'
62*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'weird; string *\n' -e empty \
63*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=$( echo "weird; string *" ); echo "$X"'
64*640235e2SEnji Cooper
65*640235e2SEnji Cooper	rm -f * 2>/dev/null || :
66*640235e2SEnji Cooper	for f in file-1 file-2
67*640235e2SEnji Cooper	do
68*640235e2SEnji Cooper		cp /dev/null "$f"
69*640235e2SEnji Cooper	done
70*640235e2SEnji Cooper
71*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \
72*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo Found $( echo * )'
73*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \
74*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo Found "$( echo * )"'
75*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \
76*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo Found $('" echo '*' )"
77*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'Found \*' -e empty \
78*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo Found "$('" echo '*' "')"'
79*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \
80*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo Found $('" echo \\* )"
81*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'Found \*' -e empty \
82*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo Found "$('" echo \\* )"\"
83*640235e2SEnji Cooper}
84*640235e2SEnji Cooper
85*640235e2SEnji Cooperatf_test_case b_basic_backticks
86*640235e2SEnji Cooperb_basic_backticks_head() {
87*640235e2SEnji Cooper	atf_set "descr" 'Test operation of old style ` ` substitutions'
88*640235e2SEnji Cooper}
89*640235e2SEnji Cooperb_basic_backticks_body() {
90*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'Result is true today' -e empty \
91*640235e2SEnji Cooper	    ${TEST_SH} -c \
92*640235e2SEnji Cooper		'echo Result is `true && echo true || echo false` today'
93*640235e2SEnji Cooper
94*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'Result is false today' -e empty \
95*640235e2SEnji Cooper	    ${TEST_SH} -c \
96*640235e2SEnji Cooper		'echo Result is `false && echo true || echo false` today'
97*640235e2SEnji Cooper
98*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'aaabbbccc' -e empty \
99*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo aaa` echo bbb `ccc'
100*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'aaabbb cccddd' -e empty \
101*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo aaa` echo bbb ccc `ddd'
102*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'aaabbb cccddd\n' -e empty \
103*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo aaa` echo bbb; echo ccc `ddd'
104*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'aaabbb\ncccddd\n' -e empty \
105*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo "aaa` echo bbb; echo ccc `ddd"'
106*640235e2SEnji Cooper
107*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'some string\n' -e empty \
108*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=` echo some string `; echo "$X"'
109*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'weird; string *\n' -e empty \
110*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=` echo "weird; string *" `; echo "$X"'
111*640235e2SEnji Cooper
112*640235e2SEnji Cooper	rm -f * 2>/dev/null || :
113*640235e2SEnji Cooper	for f in file-1 file-2
114*640235e2SEnji Cooper	do
115*640235e2SEnji Cooper		cp /dev/null "$f"
116*640235e2SEnji Cooper	done
117*640235e2SEnji Cooper
118*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \
119*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo Found ` echo * `'
120*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \
121*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo Found "` echo * `"'
122*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \
123*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo Found `'" echo '*' "'`'
124*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'Found \*' -e empty \
125*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo Found "`'" echo '*' "'`"'
126*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'Found file-1 file-2' -e empty \
127*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo Found `'" echo \\* "'`'
128*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'Found \*' -e empty \
129*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo Found "`'" echo \\* "'`"'
130*640235e2SEnji Cooper}
131*640235e2SEnji Cooper
132*640235e2SEnji Cooperatf_test_case c_nested_cmdsub
133*640235e2SEnji Cooperc_nested_cmdsub_head() {
134*640235e2SEnji Cooper	atf_set "descr" "Test that cmd substitutions can be nested"
135*640235e2SEnji Cooper}
136*640235e2SEnji Cooperc_nested_cmdsub_body() {
137*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \
138*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo __$( echo foo$(echo bar)bletch )__'
139*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'_abcde_' -e empty \
140*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo _$(echo a$(echo $(echo b)c$(echo d))e )_'
141*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'123454321' -e empty \
142*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo 1$(echo 2$(echo 3$(echo 4$(echo 5)4)3)2)1'
143*640235e2SEnji Cooper}
144*640235e2SEnji Cooper
145*640235e2SEnji Cooperatf_test_case d_nested_backticks
146*640235e2SEnji Cooperd_nested_backticks_head() {
147*640235e2SEnji Cooper	atf_set "descr" "Tests that old style backtick cmd subs can be nested"
148*640235e2SEnji Cooper}
149*640235e2SEnji Cooperd_nested_backticks_body() {
150*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \
151*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo __` echo foo\`echo bar\`bletch `__'
152*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'_abcde_' -e empty \
153*640235e2SEnji Cooper	    ${TEST_SH} -c \
154*640235e2SEnji Cooper		'echo _`echo a\`echo \\\`echo b\\\`c\\\`echo d\\\`\`e `_'
155*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'123454321' -e empty \
156*640235e2SEnji Cooper	    ${TEST_SH} -c \
157*640235e2SEnji Cooper	    'echo 1`echo 2\`echo 3\\\`echo 4\\\\\\\`echo 5\\\\\\\`4\\\`3\`2`1'
158*640235e2SEnji Cooper}
159*640235e2SEnji Cooper
160*640235e2SEnji Cooperatf_test_case e_perverse_mixing
161*640235e2SEnji Coopere_perverse_mixing_head() {
162*640235e2SEnji Cooper	atf_set "descr" \
163*640235e2SEnji Cooper		"Checks various mixed new and old style cmd substitutions"
164*640235e2SEnji Cooper}
165*640235e2SEnji Coopere_perverse_mixing_body() {
166*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \
167*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo __$( echo foo`echo bar`bletch )__'
168*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__foobarbletch__' -e empty \
169*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo __` echo foo$(echo bar)bletch `__'
170*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'_abcde_' -e empty \
171*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo _$(echo a`echo $(echo b)c$(echo d)`e )_'
172*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'_abcde_' -e empty \
173*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo _`echo a$(echo \`echo b\`c\`echo d\`)e `_'
174*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'12345654321' -e empty \
175*640235e2SEnji Cooper	    ${TEST_SH} -c \
176*640235e2SEnji Cooper		'echo 1`echo 2$(echo 3\`echo 4\\\`echo 5$(echo 6)5\\\`4\`3)2`1'
177*640235e2SEnji Cooper}
178*640235e2SEnji Cooper
179*640235e2SEnji Cooperatf_test_case f_redirect_in_cmdsub
180*640235e2SEnji Cooperf_redirect_in_cmdsub_head() {
181*640235e2SEnji Cooper	atf_set "descr" "Checks that redirects work in command substitutions"
182*640235e2SEnji Cooper}
183*640235e2SEnji Cooperf_redirect_in_cmdsub_body() {
184*640235e2SEnji Cooper	atf_require_prog cat
185*640235e2SEnji Cooper	atf_require_prog rm
186*640235e2SEnji Cooper
187*640235e2SEnji Cooper	rm -f file 2>/dev/null || :
188*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'_aa_' -e empty \
189*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo _$( echo a$( echo b > file )a)_'
190*640235e2SEnji Cooper	atf_check -s exit:0 -o match:b -e empty ${TEST_SH} -c 'cat file'
191*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'_aba_' -e empty \
192*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo _$( echo a$( cat < file )a)_'
193*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'_aa_' -e empty \
194*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo _$( echo a$( echo d >> file )a)_'
195*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'b\nd\n' -e empty ${TEST_SH} -c 'cat file'
196*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'_aa_' -e match:'not error' \
197*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo _$( echo a$( echo not error >&2 )a)_'
198*640235e2SEnji Cooper}
199*640235e2SEnji Cooper
200*640235e2SEnji Cooperatf_test_case g_redirect_in_backticks
201*640235e2SEnji Cooperg_redirect_in_backticks_head() {
202*640235e2SEnji Cooper	atf_set "descr" "Checks that redirects work in old style cmd sub"
203*640235e2SEnji Cooper}
204*640235e2SEnji Cooperg_redirect_in_backticks_body() {
205*640235e2SEnji Cooper	atf_require_prog cat
206*640235e2SEnji Cooper	atf_require_prog rm
207*640235e2SEnji Cooper
208*640235e2SEnji Cooper	rm -f file 2>/dev/null || :
209*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'_aa_' -e empty \
210*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo _` echo a\` echo b > file \`a`_'
211*640235e2SEnji Cooper	atf_check -s exit:0 -o match:b -e empty ${TEST_SH} -c 'cat file'
212*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'_aba_' -e empty \
213*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo _` echo a\` cat < file \`a`_'
214*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'_aa_' -e empty \
215*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo _` echo a\` echo d >> file \`a`_'
216*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'b\nd\n' -e empty ${TEST_SH} -c 'cat file'
217*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'_aa_' -e match:'not error' \
218*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo _` echo a\` echo not error >&2 \`a`_'
219*640235e2SEnji Cooper}
220*640235e2SEnji Cooper
221*640235e2SEnji Cooperatf_test_case h_vars_in_cmdsub
222*640235e2SEnji Cooperh_vars_in_cmdsub_head() {
223*640235e2SEnji Cooper	atf_set "descr" "Check that variables work in command substitutions"
224*640235e2SEnji Cooper}
225*640235e2SEnji Cooperh_vars_in_cmdsub_body() {
226*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__abc__' -e empty \
227*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=abc; echo __$( echo ${X} )__'
228*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__abc__' -e empty \
229*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=abc; echo __$( echo "${X}" )__'
230*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__abc__' -e empty \
231*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=abc; echo "__$( echo ${X} )__"'
232*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__abc__' -e empty \
233*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=abc; echo "__$( echo "${X}" )__"'
234*640235e2SEnji Cooper
235*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'a\n\nb\n\nc\n' -e empty \
236*640235e2SEnji Cooper	    ${TEST_SH} -c "for X in a '' b '' c"'; do echo $( echo "$X" ); done'
237*640235e2SEnji Cooper
238*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__acd__' -e empty \
239*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X-b}${Y-c}d)__"'
240*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__abcd__' -e empty \
241*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X:-b}${Y:-c}d)__"'
242*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__XYX__' -e empty \
243*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=X; echo "__${X}$( X=Y; echo ${X} )${X}__"'
244*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__def__' -e empty \
245*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=abc; echo "__$(X=def; echo "${X}" )__"'
246*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'abcdef\nabc\n' -e empty \
247*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=abc; echo "$X$(X=def; echo ${X} )"; echo $X'
248*640235e2SEnji Cooper}
249*640235e2SEnji Cooper
250*640235e2SEnji Cooperatf_test_case i_vars_in_backticks
251*640235e2SEnji Cooperi_vars_in_backticks_head() {
252*640235e2SEnji Cooper	atf_set "descr" "Checks that variables work in old style cmd sub"
253*640235e2SEnji Cooper}
254*640235e2SEnji Cooperi_vars_in_backticks_body() {
255*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__abc__' -e empty \
256*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=abc; echo __` echo ${X} `__'
257*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__abc__' -e empty \
258*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=abc; echo __` echo "${X}" `__'
259*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__abc__' -e empty \
260*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=abc; echo "__` echo ${X} `__"'
261*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__abc__' -e empty \
262*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=abc; echo "__` echo \"${X}\" `__"'
263*640235e2SEnji Cooper
264*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'a\n\nb\n\nc\n' -e empty \
265*640235e2SEnji Cooper	    ${TEST_SH} -c "for X in a '' b '' c"'; do echo $( echo "$X" ); done'
266*640235e2SEnji Cooper
267*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__acd__' -e empty \
268*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X-b}${Y-c}d)__"'
269*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__abcd__' -e empty \
270*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=; unset Y; echo "__$( echo a${X:-b}${Y:-c}d)__"'
271*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'__XYX__' -e empty \
272*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=X; echo "__${X}$( X=Y; echo ${X} )${X}__"'
273*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'abcdef\nabc\n' -e empty \
274*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=abc; echo "$X`X=def; echo \"${X}\" `";echo $X'
275*640235e2SEnji Cooper
276*640235e2SEnji Cooper	# The following is nonsense, so is not included ...
277*640235e2SEnji Cooper	# atf_check -s exit:0 -o match:'__abc__' -e empty \
278*640235e2SEnji Cooper	#                              oV             cV   oV   cV
279*640235e2SEnji Cooper	#    ${TEST_SH} -c 'X=abc; echo "__`X=def echo "${X}" `__"'
280*640235e2SEnji Cooper	#				   `start in " ^ " ends, ` not yet
281*640235e2SEnji Cooper}
282*640235e2SEnji Cooper
283*640235e2SEnji Cooperatf_test_case j_cmdsub_in_varexpand
284*640235e2SEnji Cooperj_cmdsub_in_varexpand_head() {
285*640235e2SEnji Cooper	atf_set "descr" "Checks that command sub can be used in var expansion"
286*640235e2SEnji Cooper}
287*640235e2SEnji Cooperj_cmdsub_in_varexpand_body() {
288*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'foo' -e empty \
289*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=set; echo ${X+$(echo foo)}'
290*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'set' -e empty \
291*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=set; echo ${X-$(echo foo)}'
292*640235e2SEnji Cooper	rm -f bar 2>/dev/null || :
293*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'set' -e empty \
294*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=set; echo ${X-$(echo foo > bar)}'
295*640235e2SEnji Cooper	test -f bar && atf_fail "bar should not exist, but does"
296*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'\n' -e empty \
297*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=set; echo ${X+$(echo foo > bar)}'
298*640235e2SEnji Cooper	test -f bar || atf_fail "bar should exist, but does not"
299*640235e2SEnji Cooper}
300*640235e2SEnji Cooper
301*640235e2SEnji Cooperatf_test_case k_backticks_in_varexpand
302*640235e2SEnji Cooperk_backticks_in_varexpand_head() {
303*640235e2SEnji Cooper	atf_set "descr" "Checks that old style cmd sub works in var expansion"
304*640235e2SEnji Cooper}
305*640235e2SEnji Cooperk_backticks_in_varexpand_body() {
306*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'foo' -e empty \
307*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=set; echo ${X+`echo foo`}'
308*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'set' -e empty \
309*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=set; echo ${X-`echo foo`}'
310*640235e2SEnji Cooper	rm -f bar 2>/dev/null || :
311*640235e2SEnji Cooper	atf_check -s exit:0 -o match:'set' -e empty \
312*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=set; echo ${X-`echo foo > bar`}'
313*640235e2SEnji Cooper	test -f bar && atf_fail "bar should not exist, but does"
314*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'\n' -e empty \
315*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=set; echo ${X+`echo foo > bar`}'
316*640235e2SEnji Cooper	test -f bar || atf_fail "bar should exist, but does not"
317*640235e2SEnji Cooper}
318*640235e2SEnji Cooper
319*640235e2SEnji Cooperatf_test_case l_arithmetic_in_cmdsub
320*640235e2SEnji Cooperl_arithmetic_in_cmdsub_head() {
321*640235e2SEnji Cooper	atf_set "descr" "Checks that arithmetic works in cmd substitutions"
322*640235e2SEnji Cooper}
323*640235e2SEnji Cooperl_arithmetic_in_cmdsub_body() {
324*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'1 + 1 = 2\n' -e empty \
325*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo 1 + 1 = $( echo $(( 1 + 1 )) )'
326*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'X * Y = 6\n' -e empty \
327*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=2; Y=3; echo X \* Y = $( echo $(( X * Y )) )'
328*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'Y % X = 1\n' -e empty \
329*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=2; Y=3; echo Y % X = $( echo $(( $Y % $X )) )'
330*640235e2SEnji Cooper}
331*640235e2SEnji Cooper
332*640235e2SEnji Cooperatf_test_case m_arithmetic_in_backticks
333*640235e2SEnji Cooperm_arithmetic_in_backticks_head() {
334*640235e2SEnji Cooper	atf_set "descr" "Checks that arithmetic works in old style cmd sub"
335*640235e2SEnji Cooper}
336*640235e2SEnji Cooperm_arithmetic_in_backticks_body() {
337*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'2 + 3 = 5\n' -e empty \
338*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo 2 + 3 = ` echo $(( 2 + 3 )) `'
339*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'X * Y = 6\n' -e empty \
340*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=2; Y=3; echo X \* Y = ` echo $(( X * Y )) `'
341*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'Y % X = 1\n' -e empty \
342*640235e2SEnji Cooper	    ${TEST_SH} -c 'X=2; Y=3; echo Y % X = ` echo $(( $Y % $X )) `'
343*640235e2SEnji Cooper}
344*640235e2SEnji Cooper
345*640235e2SEnji Cooperatf_test_case n_cmdsub_in_arithmetic
346*640235e2SEnji Coopern_cmdsub_in_arithmetic_head() {
347*640235e2SEnji Cooper	atf_set "descr" "Tests uses of command substitutions in arithmetic"
348*640235e2SEnji Cooper}
349*640235e2SEnji Coopern_cmdsub_in_arithmetic_body() {
350*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'7\n' -e empty \
351*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo $(( $( echo 3 ) $( echo + ) $( echo 4 ) ))'
352*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'11\n7\n18\n4\n1\n' -e empty \
353*640235e2SEnji Cooper	    ${TEST_SH} -c \
354*640235e2SEnji Cooper		 'for op in + - \* / %
355*640235e2SEnji Cooper		  do
356*640235e2SEnji Cooper		      echo $(( $( echo 9 ) $( echo "${op}" ) $( echo 2 ) ))
357*640235e2SEnji Cooper		  done'
358*640235e2SEnji Cooper}
359*640235e2SEnji Cooper
360*640235e2SEnji Cooperatf_test_case o_backticks_in_arithmetic
361*640235e2SEnji Coopero_backticks_in_arithmetic_head() {
362*640235e2SEnji Cooper	atf_set "descr" "Tests old style cmd sub used in arithmetic"
363*640235e2SEnji Cooper}
364*640235e2SEnji Coopero_backticks_in_arithmetic_body() {
365*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'33\n' -e empty \
366*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo $(( `echo 77` `echo -` `echo 44`))'
367*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'14\n8\n33\n3\n2\n' -e empty \
368*640235e2SEnji Cooper	    ${TEST_SH} -c \
369*640235e2SEnji Cooper		 'for op in + - \* / %
370*640235e2SEnji Cooper		  do
371*640235e2SEnji Cooper		      echo $((`echo 11``echo "${op}"``echo 3`))
372*640235e2SEnji Cooper		  done'
373*640235e2SEnji Cooper}
374*640235e2SEnji Cooper
375*640235e2SEnji Cooperatf_test_case p_cmdsub_in_heredoc
376*640235e2SEnji Cooperp_cmdsub_in_heredoc_head() {
377*640235e2SEnji Cooper	atf_set "descr" "Checks that cmdsubs work inside a here document"
378*640235e2SEnji Cooper}
379*640235e2SEnji Cooperp_cmdsub_in_heredoc_body() {
380*640235e2SEnji Cooper	atf_require_prog cat
381*640235e2SEnji Cooper
382*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'line 1+1\nline 2\nline 3\n' -e empty \
383*640235e2SEnji Cooper	    ${TEST_SH} -c \
384*640235e2SEnji Cooper		'cat <<- EOF
385*640235e2SEnji Cooper			$( echo line 1 )$( echo +1 )
386*640235e2SEnji Cooper			$( echo line 2;echo line 3 )
387*640235e2SEnji Cooper		EOF'
388*640235e2SEnji Cooper}
389*640235e2SEnji Cooper
390*640235e2SEnji Cooperatf_test_case q_backticks_in_heredoc
391*640235e2SEnji Cooperq_backticks_in_heredoc_head() {
392*640235e2SEnji Cooper	atf_set "descr" "Checks that old style cmdsubs work in here docs"
393*640235e2SEnji Cooper}
394*640235e2SEnji Cooperq_backticks_in_heredoc_body() {
395*640235e2SEnji Cooper	atf_require_prog cat
396*640235e2SEnji Cooper
397*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'Mary had a\nlittle\nlamb\n' -e empty \
398*640235e2SEnji Cooper	    ${TEST_SH} -c \
399*640235e2SEnji Cooper		'cat <<- EOF
400*640235e2SEnji Cooper			`echo Mary ` `echo had a `
401*640235e2SEnji Cooper			` echo little; echo lamb `
402*640235e2SEnji Cooper		EOF'
403*640235e2SEnji Cooper}
404*640235e2SEnji Cooper
405*640235e2SEnji Cooperatf_test_case r_heredoc_in_cmdsub
406*640235e2SEnji Cooperr_heredoc_in_cmdsub_head() {
407*640235e2SEnji Cooper	atf_set "descr" "Checks that here docs work inside cmd subs"
408*640235e2SEnji Cooper}
409*640235e2SEnji Cooperr_heredoc_in_cmdsub_body() {
410*640235e2SEnji Cooper	atf_require_prog cat
411*640235e2SEnji Cooper
412*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'Mary had a\nlittle\nlamb\n' -e empty \
413*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo "$( cat <<- \EOF
414*640235e2SEnji Cooper				Mary had a
415*640235e2SEnji Cooper				little
416*640235e2SEnji Cooper				lamb
417*640235e2SEnji Cooper			EOF
418*640235e2SEnji Cooper			)"'
419*640235e2SEnji Cooper
420*640235e2SEnji Cooper	atf_check -s exit:0 -e empty \
421*640235e2SEnji Cooper	    -o inline:'Mary had 1\nlittle\nlamb\nMary had 4\nlittle\nlambs\n' \
422*640235e2SEnji Cooper	    ${TEST_SH} -c 'for N in 1 4; do echo "$( cat <<- EOF
423*640235e2SEnji Cooper				Mary had ${N}
424*640235e2SEnji Cooper				little
425*640235e2SEnji Cooper				lamb$( [ $N -gt 1 ] && echo s )
426*640235e2SEnji Cooper			EOF
427*640235e2SEnji Cooper			)"; done'
428*640235e2SEnji Cooper
429*640235e2SEnji Cooper
430*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'A Calculation:\n2 * 7 = 14\n' -e empty \
431*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo "$( cat <<- EOF
432*640235e2SEnji Cooper				A Calculation:
433*640235e2SEnji Cooper					2 * 7 = $(( 2 * 7 ))
434*640235e2SEnji Cooper			EOF
435*640235e2SEnji Cooper			)"'
436*640235e2SEnji Cooper}
437*640235e2SEnji Cooper
438*640235e2SEnji Cooperatf_test_case s_heredoc_in_backticks
439*640235e2SEnji Coopers_heredoc_in_backticks_head() {
440*640235e2SEnji Cooper	atf_set "descr" "Checks that here docs work inside old style cmd subs"
441*640235e2SEnji Cooper}
442*640235e2SEnji Coopers_heredoc_in_backticks_body() {
443*640235e2SEnji Cooper	atf_require_prog cat
444*640235e2SEnji Cooper
445*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'Mary had a little lamb\n' -e empty \
446*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo ` cat <<- \EOF
447*640235e2SEnji Cooper				Mary had a
448*640235e2SEnji Cooper				little
449*640235e2SEnji Cooper				lamb
450*640235e2SEnji Cooper			EOF
451*640235e2SEnji Cooper			`'
452*640235e2SEnji Cooper
453*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'A Calculation:\n17 / 3 = 5\n' -e empty \
454*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo "` cat <<- EOF
455*640235e2SEnji Cooper				A Calculation:
456*640235e2SEnji Cooper					17 / 3 = $(( 17 / 3 ))
457*640235e2SEnji Cooper			EOF
458*640235e2SEnji Cooper			`"'
459*640235e2SEnji Cooper}
460*640235e2SEnji Cooper
461*640235e2SEnji Cooperatf_test_case t_nested_cmdsubs_in_heredoc
462*640235e2SEnji Coopert_nested_cmdsubs_in_heredoc_head() {
463*640235e2SEnji Cooper	atf_set "descr" "Checks nested command substitutions in here docs"
464*640235e2SEnji Cooper}
465*640235e2SEnji Coopert_nested_cmdsubs_in_heredoc_body() {
466*640235e2SEnji Cooper	atf_require_prog cat
467*640235e2SEnji Cooper	atf_require_prog rm
468*640235e2SEnji Cooper
469*640235e2SEnji Cooper	rm -f * 2>/dev/null || :
470*640235e2SEnji Cooper	echo "Hello" > File
471*640235e2SEnji Cooper
472*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'Hello U\nHelp me!\n' -e empty \
473*640235e2SEnji Cooper	    ${TEST_SH} -c 'cat <<- EOF
474*640235e2SEnji Cooper		$(cat File) U
475*640235e2SEnji Cooper		$( V=$(cat File); echo "${V%lo}p" ) me!
476*640235e2SEnji Cooper		EOF'
477*640235e2SEnji Cooper
478*640235e2SEnji Cooper	rm -f * 2>/dev/null || :
479*640235e2SEnji Cooper	echo V>V ; echo A>A; echo R>R
480*640235e2SEnji Cooper	echo Value>VAR
481*640235e2SEnji Cooper
482*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'$2.50\n' -e empty \
483*640235e2SEnji Cooper	    ${TEST_SH} -c 'cat <<- EOF
484*640235e2SEnji Cooper	$(Value='\''$2.50'\'';eval echo $(eval $(cat V)$(cat A)$(cat R)=\'\''\$$(cat $(cat V)$(cat A)$(cat R))\'\''; eval echo \$$(set -- *;echo ${3}${1}${2})))
485*640235e2SEnji Cooper		EOF'
486*640235e2SEnji Cooper}
487*640235e2SEnji Cooper
488*640235e2SEnji Cooperatf_test_case u_nested_backticks_in_heredoc
489*640235e2SEnji Cooperu_nested_backticks_in_heredoc_head() {
490*640235e2SEnji Cooper	atf_set "descr" "Checks nested old style cmd subs in here docs"
491*640235e2SEnji Cooper}
492*640235e2SEnji Cooperu_nested_backticks_in_heredoc_body() {
493*640235e2SEnji Cooper	atf_require_prog cat
494*640235e2SEnji Cooper	atf_require_prog rm
495*640235e2SEnji Cooper
496*640235e2SEnji Cooper	rm -f * 2>/dev/null || :
497*640235e2SEnji Cooper	echo "Hello" > File
498*640235e2SEnji Cooper
499*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'Hello U\nHelp me!\n' -e empty \
500*640235e2SEnji Cooper	    ${TEST_SH} -c 'cat <<- EOF
501*640235e2SEnji Cooper		`cat File` U
502*640235e2SEnji Cooper		`V=\`cat File\`; echo "${V%lo}p" ` me!
503*640235e2SEnji Cooper		EOF'
504*640235e2SEnji Cooper
505*640235e2SEnji Cooper	rm -f * 2>/dev/null || :
506*640235e2SEnji Cooper	echo V>V ; echo A>A; echo R>R
507*640235e2SEnji Cooper	echo Value>VAR
508*640235e2SEnji Cooper
509*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'$5.20\n' -e empty \
510*640235e2SEnji Cooper	    ${TEST_SH} -c 'cat <<- EOF
511*640235e2SEnji Cooper	`Value='\''$5.20'\'';eval echo \`eval \\\`cat V\\\`\\\`cat A\\\`\\\`cat R\\\`=\\\'\''\\\$\\\`cat \\\\\\\`cat V\\\\\\\`\\\\\\\`cat A\\\\\\\`\\\\\\\`cat R\\\\\\\`\\\`\\\'\''; eval echo \\\$\\\`set -- *;echo \\\\\${3}\\\\\${1}\\\\\${2}\\\`\``
512*640235e2SEnji Cooper		EOF'
513*640235e2SEnji Cooper}
514*640235e2SEnji Cooper
515*640235e2SEnji Cooperatf_test_case v_cmdsub_paren_tests
516*640235e2SEnji Cooperv_cmdsub__paren_tests_head() {
517*640235e2SEnji Cooper	atf_set "descr" "tests with cmdsubs containing embedded ')'"
518*640235e2SEnji Cooper}
519*640235e2SEnji Cooperv_cmdsub_paren_tests_body() {
520*640235e2SEnji Cooper
521*640235e2SEnji Cooper	# Tests from:
522*640235e2SEnji Cooper	#	http://www.in-ulm.de/~mascheck/various/cmd-subst/
523*640235e2SEnji Cooper	# (slightly modified.)
524*640235e2SEnji Cooper
525*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'A.1\n' -e empty ${TEST_SH} -c \
526*640235e2SEnji Cooper		'echo $(
527*640235e2SEnji Cooper			case x in  x) echo A.1;; esac
528*640235e2SEnji Cooper		)'
529*640235e2SEnji Cooper
530*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'A.2\n' -e empty ${TEST_SH} -c \
531*640235e2SEnji Cooper		'echo $(
532*640235e2SEnji Cooper			case x in  x) echo A.2;; esac # comment
533*640235e2SEnji Cooper		)'
534*640235e2SEnji Cooper
535*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'A.3\n' -e empty ${TEST_SH} -c \
536*640235e2SEnji Cooper		'echo $(
537*640235e2SEnji Cooper			case x in (x) echo A.3;; esac
538*640235e2SEnji Cooper		)'
539*640235e2SEnji Cooper
540*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'A.4\n' -e empty ${TEST_SH} -c \
541*640235e2SEnji Cooper		'echo $(
542*640235e2SEnji Cooper			case x in (x) echo A.4;; esac # comment
543*640235e2SEnji Cooper		)'
544*640235e2SEnji Cooper
545*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'A.5\n' -e empty ${TEST_SH} -c \
546*640235e2SEnji Cooper		'echo $(
547*640235e2SEnji Cooper			case x in (x) echo A.5
548*640235e2SEnji Cooper			esac
549*640235e2SEnji Cooper		)'
550*640235e2SEnji Cooper
551*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'B: quoted )\n' -e empty ${TEST_SH} -c \
552*640235e2SEnji Cooper		'echo $(
553*640235e2SEnji Cooper			echo '\''B: quoted )'\''
554*640235e2SEnji Cooper		)'
555*640235e2SEnji Cooper
556*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'C: comment then closing paren\n' \
557*640235e2SEnji Cooper		-e empty ${TEST_SH} -c \
558*640235e2SEnji Cooper			'echo $(
559*640235e2SEnji Cooper				echo C: comment then closing paren # )
560*640235e2SEnji Cooper			)'
561*640235e2SEnji Cooper
562*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'D.1: here-doc with )\n' \
563*640235e2SEnji Cooper		-e empty ${TEST_SH} -c \
564*640235e2SEnji Cooper			'echo $(
565*640235e2SEnji Cooper				cat <<-\eof
566*640235e2SEnji Cooper				D.1: here-doc with )
567*640235e2SEnji Cooper				eof
568*640235e2SEnji Cooper			)'
569*640235e2SEnji Cooper
570*640235e2SEnji Cooper	# D.2 is a bogus test.
571*640235e2SEnji Cooper
572*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'D.3: here-doc with \()\n' \
573*640235e2SEnji Cooper		-e empty ${TEST_SH} -c \
574*640235e2SEnji Cooper			'echo $(
575*640235e2SEnji Cooper				cat <<-\eof
576*640235e2SEnji Cooper				D.3: here-doc with \()
577*640235e2SEnji Cooper				eof
578*640235e2SEnji Cooper			)'
579*640235e2SEnji Cooper
580*640235e2SEnji Cooper	atf_check -s exit:0 -e empty \
581*640235e2SEnji Cooper	  -o inline:'E: here-doc terminated with a parenthesis ("academic")\n' \
582*640235e2SEnji Cooper		${TEST_SH} -c \
583*640235e2SEnji Cooper		'echo $(
584*640235e2SEnji Cooper			cat <<-\)
585*640235e2SEnji Cooper			E: here-doc terminated with a parenthesis ("academic")
586*640235e2SEnji Cooper			)
587*640235e2SEnji Cooper		)'
588*640235e2SEnji Cooper
589*640235e2SEnji Cooper	atf_check -s exit:0 -e empty \
590*640235e2SEnji Cooper-o inline:'F.1: here-doc embed with unbal single, back- or doublequote '\''\n' \
591*640235e2SEnji Cooper		${TEST_SH} -c \
592*640235e2SEnji Cooper		'echo $(
593*640235e2SEnji Cooper			cat <<-"eof"
594*640235e2SEnji Cooper		F.1: here-doc embed with unbal single, back- or doublequote '\''
595*640235e2SEnji Cooper			eof
596*640235e2SEnji Cooper		)'
597*640235e2SEnji Cooper	atf_check -s exit:0 -e empty \
598*640235e2SEnji Cooper -o inline:'F.2: here-doc embed with unbal single, back- or doublequote "\n' \
599*640235e2SEnji Cooper		${TEST_SH} -c \
600*640235e2SEnji Cooper		'echo $(
601*640235e2SEnji Cooper			cat <<-"eof"
602*640235e2SEnji Cooper		F.2: here-doc embed with unbal single, back- or doublequote "
603*640235e2SEnji Cooper			eof
604*640235e2SEnji Cooper		)'
605*640235e2SEnji Cooper	atf_check -s exit:0 -e empty \
606*640235e2SEnji Cooper -o inline:'F.3: here-doc embed with unbal single, back- or doublequote `\n' \
607*640235e2SEnji Cooper		${TEST_SH} -c \
608*640235e2SEnji Cooper		'echo $(
609*640235e2SEnji Cooper			cat <<-"eof"
610*640235e2SEnji Cooper		F.3: here-doc embed with unbal single, back- or doublequote `
611*640235e2SEnji Cooper			eof
612*640235e2SEnji Cooper		)'
613*640235e2SEnji Cooper
614*640235e2SEnji Cooper	atf_check -s exit:0 -e empty -o inline:'G: backslash at end of line\n' \
615*640235e2SEnji Cooper		${TEST_SH} -c \
616*640235e2SEnji Cooper			'echo $(
617*640235e2SEnji Cooper				echo G: backslash at end of line # \
618*640235e2SEnji Cooper			)'
619*640235e2SEnji Cooper
620*640235e2SEnji Cooper	atf_check -s exit:0 -e empty \
621*640235e2SEnji Cooper		-o inline:'H: empty command-substitution\n' \
622*640235e2SEnji Cooper		${TEST_SH} -c 'echo H: empty command-substitution $( )'
623*640235e2SEnji Cooper}
624*640235e2SEnji Cooper
625*640235e2SEnji Cooperatf_test_case w_heredoc_outside_cmdsub
626*640235e2SEnji Cooperw_heredoc_outside_cmdsub_head() {
627*640235e2SEnji Cooper	atf_set "descr" "Checks that here docs work inside cmd subs"
628*640235e2SEnji Cooper}
629*640235e2SEnji Cooperw_heredoc_outside_cmdsub_body() {
630*640235e2SEnji Cooper	atf_require_prog cat
631*640235e2SEnji Cooper
632*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'Mary had a\nlittle\nlamb\n' -e empty \
633*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo "$( cat <<- \EOF )"
634*640235e2SEnji Cooper				Mary had a
635*640235e2SEnji Cooper				little
636*640235e2SEnji Cooper				lamb
637*640235e2SEnji Cooper			EOF
638*640235e2SEnji Cooper			'
639*640235e2SEnji Cooper
640*640235e2SEnji Cooper	atf_check -s exit:0 -e empty \
641*640235e2SEnji Cooper	    -o inline:'Mary had 1\nlittle\nlamb\nMary had 4\nlittle\nlambs\n' \
642*640235e2SEnji Cooper	    ${TEST_SH} -c 'for N in 1 4; do echo "$( cat <<- EOF )"
643*640235e2SEnji Cooper				Mary had ${N}
644*640235e2SEnji Cooper				little
645*640235e2SEnji Cooper				lamb$( [ $N -gt 1 ] && echo s )
646*640235e2SEnji Cooper			EOF
647*640235e2SEnji Cooper			done'
648*640235e2SEnji Cooper
649*640235e2SEnji Cooper
650*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'A Calculation:\n2 * 7 = 14\n' -e empty \
651*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo "$( cat <<- EOF)"
652*640235e2SEnji Cooper				A Calculation:
653*640235e2SEnji Cooper					2 * 7 = $(( 2 * 7 ))
654*640235e2SEnji Cooper			EOF
655*640235e2SEnji Cooper			'
656*640235e2SEnji Cooper}
657*640235e2SEnji Cooper
658*640235e2SEnji Cooperatf_test_case x_heredoc_outside_backticks
659*640235e2SEnji Cooperx_heredoc_outside_backticks_head() {
660*640235e2SEnji Cooper	atf_set "descr" "Checks that here docs work inside old style cmd subs"
661*640235e2SEnji Cooper}
662*640235e2SEnji Cooperx_heredoc_outside_backticks_body() {
663*640235e2SEnji Cooper	atf_require_prog cat
664*640235e2SEnji Cooper
665*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'Mary had a little lamb\n' -e empty \
666*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo ` cat <<- \EOF `
667*640235e2SEnji Cooper				Mary had a
668*640235e2SEnji Cooper				little
669*640235e2SEnji Cooper				lamb
670*640235e2SEnji Cooper			EOF
671*640235e2SEnji Cooper			'
672*640235e2SEnji Cooper
673*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'A Calculation:\n17 / 3 = 5\n' -e empty \
674*640235e2SEnji Cooper	    ${TEST_SH} -c 'echo "` cat <<- EOF `"
675*640235e2SEnji Cooper				A Calculation:
676*640235e2SEnji Cooper					17 / 3 = $(( 17 / 3 ))
677*640235e2SEnji Cooper			EOF
678*640235e2SEnji Cooper			'
679*640235e2SEnji Cooper}
680*640235e2SEnji Cooper
681*640235e2SEnji Cooperatf_test_case t_nested_cmdsubs_in_heredoc
682*640235e2SEnji Coopert_nested_cmdsubs_in_heredoc_head() {
683*640235e2SEnji Cooper	atf_set "descr" "Checks nested command substitutions in here docs"
684*640235e2SEnji Cooper}
685*640235e2SEnji Coopert_nested_cmdsubs_in_heredoc_body() {
686*640235e2SEnji Cooper	atf_require_prog cat
687*640235e2SEnji Cooper	atf_require_prog rm
688*640235e2SEnji Cooper
689*640235e2SEnji Cooper	rm -f * 2>/dev/null || :
690*640235e2SEnji Cooper	echo "Hello" > File
691*640235e2SEnji Cooper
692*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'Hello U\nHelp me!\n' -e empty \
693*640235e2SEnji Cooper	    ${TEST_SH} -c 'cat <<- EOF
694*640235e2SEnji Cooper		$(cat File) U
695*640235e2SEnji Cooper		$( V=$(cat File); echo "${V%lo}p" ) me!
696*640235e2SEnji Cooper		EOF'
697*640235e2SEnji Cooper
698*640235e2SEnji Cooper	rm -f * 2>/dev/null || :
699*640235e2SEnji Cooper	echo V>V ; echo A>A; echo R>R
700*640235e2SEnji Cooper	echo Value>VAR
701*640235e2SEnji Cooper
702*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'$2.50\n' -e empty \
703*640235e2SEnji Cooper	    ${TEST_SH} -c 'cat <<- EOF
704*640235e2SEnji Cooper	$(Value='\''$2.50'\'';eval echo $(eval $(cat V)$(cat A)$(cat R)=\'\''\$$(cat $(cat V)$(cat A)$(cat R))\'\''; eval echo \$$(set -- *;echo ${3}${1}${2})))
705*640235e2SEnji Cooper		EOF'
706*640235e2SEnji Cooper}
707*640235e2SEnji Cooper
708*640235e2SEnji Cooperatf_test_case z_absurd_heredoc_cmdsub_combos
709*640235e2SEnji Cooperz_absurd_heredoc_cmdsub_combos_head() {
710*640235e2SEnji Cooper	atf_set "descr" "perverse and unusual cmd substitutions & more"
711*640235e2SEnji Cooper}
712*640235e2SEnji Cooperz_absurd_heredoc_cmdsub_combos_body() {
713*640235e2SEnji Cooper
714*640235e2SEnji Cooper	echo "Help!" > help
715*640235e2SEnji Cooper
716*640235e2SEnji Cooper	# This version works in NetBSD (& FreeBSD)'s sh (and most others)
717*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'Help!\nMe 2\n' -e empty ${TEST_SH} -c '
718*640235e2SEnji Cooper			cat <<- EOF
719*640235e2SEnji Cooper				$(
720*640235e2SEnji Cooper					cat <<- STOP
721*640235e2SEnji Cooper						$(
722*640235e2SEnji Cooper							cat `echo help`
723*640235e2SEnji Cooper						)
724*640235e2SEnji Cooper					STOP
725*640235e2SEnji Cooper				)
726*640235e2SEnji Cooper				$(
727*640235e2SEnji Cooper					cat <<- END 4<<-TRASH
728*640235e2SEnji Cooper						Me $(( 1 + 1 ))
729*640235e2SEnji Cooper					END
730*640235e2SEnji Cooper					This is unused noise!
731*640235e2SEnji Cooper					TRASH
732*640235e2SEnji Cooper				)
733*640235e2SEnji Cooper			EOF
734*640235e2SEnji Cooper		'
735*640235e2SEnji Cooper
736*640235e2SEnji Cooper	# atf_expect_fail "PR bin/50993 - heredoc parsing done incorrectly"
737*640235e2SEnji Cooper	atf_check -s exit:0 -o inline:'Help!\nMe 2\n' -e empty ${TEST_SH} -c '
738*640235e2SEnji Cooper			cat <<- EOF
739*640235e2SEnji Cooper				$(
740*640235e2SEnji Cooper					cat << STOP
741*640235e2SEnji Cooper						$(
742*640235e2SEnji Cooper							cat `echo help`
743*640235e2SEnji Cooper						)
744*640235e2SEnji Cooper					STOP
745*640235e2SEnji Cooper				)
746*640235e2SEnji Cooper				$(
747*640235e2SEnji Cooper					cat <<- END 4<<TRASH
748*640235e2SEnji Cooper						Me $(( 1 + 1 ))
749*640235e2SEnji Cooper					END
750*640235e2SEnji Cooper					This is unused noise!
751*640235e2SEnji Cooper					TRASH
752*640235e2SEnji Cooper				)
753*640235e2SEnji Cooper			EOF
754*640235e2SEnji Cooper		'
755*640235e2SEnji Cooper}
756*640235e2SEnji Cooper
757*640235e2SEnji Cooperatf_init_test_cases() {
758*640235e2SEnji Cooper	atf_add_test_case a_basic_cmdsub
759*640235e2SEnji Cooper	atf_add_test_case b_basic_backticks
760*640235e2SEnji Cooper	atf_add_test_case c_nested_cmdsub
761*640235e2SEnji Cooper	atf_add_test_case d_nested_backticks
762*640235e2SEnji Cooper	atf_add_test_case e_perverse_mixing
763*640235e2SEnji Cooper	atf_add_test_case f_redirect_in_cmdsub
764*640235e2SEnji Cooper	atf_add_test_case g_redirect_in_backticks
765*640235e2SEnji Cooper	atf_add_test_case h_vars_in_cmdsub
766*640235e2SEnji Cooper	atf_add_test_case i_vars_in_backticks
767*640235e2SEnji Cooper	atf_add_test_case j_cmdsub_in_varexpand
768*640235e2SEnji Cooper	atf_add_test_case k_backticks_in_varexpand
769*640235e2SEnji Cooper	atf_add_test_case l_arithmetic_in_cmdsub
770*640235e2SEnji Cooper	atf_add_test_case m_arithmetic_in_backticks
771*640235e2SEnji Cooper	atf_add_test_case n_cmdsub_in_arithmetic
772*640235e2SEnji Cooper	atf_add_test_case o_backticks_in_arithmetic
773*640235e2SEnji Cooper	atf_add_test_case p_cmdsub_in_heredoc
774*640235e2SEnji Cooper	atf_add_test_case q_backticks_in_heredoc
775*640235e2SEnji Cooper	atf_add_test_case r_heredoc_in_cmdsub
776*640235e2SEnji Cooper	atf_add_test_case s_heredoc_in_backticks
777*640235e2SEnji Cooper	atf_add_test_case t_nested_cmdsubs_in_heredoc
778*640235e2SEnji Cooper	atf_add_test_case u_nested_backticks_in_heredoc
779*640235e2SEnji Cooper	atf_add_test_case v_cmdsub_paren_tests
780*640235e2SEnji Cooper	atf_add_test_case w_heredoc_outside_cmdsub
781*640235e2SEnji Cooper	atf_add_test_case x_heredoc_outside_backticks
782*640235e2SEnji Cooper	atf_add_test_case z_absurd_heredoc_cmdsub_combos
783*640235e2SEnji Cooper}
784