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