t_here.sh revision 1.6 1 1.6 christos # $NetBSD: t_here.sh,v 1.6 2016/03/31 16:21:52 christos Exp $
2 1.1 jruoho #
3 1.1 jruoho # Copyright (c) 2007 The NetBSD Foundation, Inc.
4 1.1 jruoho # All rights reserved.
5 1.1 jruoho #
6 1.1 jruoho # Redistribution and use in source and binary forms, with or without
7 1.1 jruoho # modification, are permitted provided that the following conditions
8 1.1 jruoho # are met:
9 1.1 jruoho # 1. Redistributions of source code must retain the above copyright
10 1.1 jruoho # notice, this list of conditions and the following disclaimer.
11 1.1 jruoho # 2. Redistributions in binary form must reproduce the above copyright
12 1.1 jruoho # notice, this list of conditions and the following disclaimer in the
13 1.1 jruoho # documentation and/or other materials provided with the distribution.
14 1.1 jruoho #
15 1.1 jruoho # THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16 1.1 jruoho # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 1.1 jruoho # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 1.1 jruoho # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19 1.1 jruoho # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 1.1 jruoho # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 1.1 jruoho # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 1.1 jruoho # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 1.1 jruoho # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 1.1 jruoho # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 1.1 jruoho # POSSIBILITY OF SUCH DAMAGE.
26 1.1 jruoho #
27 1.2 christos # the implementation of "sh" to test
28 1.2 christos : ${TEST_SH:="/bin/sh"}
29 1.1 jruoho
30 1.1 jruoho nl='
31 1.1 jruoho '
32 1.1 jruoho
33 1.5 christos reset()
34 1.5 christos {
35 1.5 christos TEST_NUM=0
36 1.5 christos TEST_FAILURES=''
37 1.5 christos TEST_FAIL_COUNT=0
38 1.5 christos TEST_ID="$1"
39 1.5 christos }
40 1.5 christos
41 1.1 jruoho check()
42 1.1 jruoho {
43 1.2 christos fail=false
44 1.2 christos TEMP_FILE=$( mktemp OUT.XXXXXX )
45 1.5 christos TEST_NUM=$(( $TEST_NUM + 1 ))
46 1.2 christos
47 1.2 christos # our local shell (ATF_SHELL) better do quoting correctly...
48 1.2 christos # some of the tests expect us to expand $nl internally...
49 1.2 christos CMD="nl='${nl}'; $1"
50 1.2 christos
51 1.2 christos result="$( ${TEST_SH} -c "${CMD}" 2>"${TEMP_FILE}" )"
52 1.2 christos STATUS=$?
53 1.2 christos
54 1.2 christos if [ "${STATUS}" -ne "$3" ]; then
55 1.5 christos echo >&2 "[$TEST_NUM] expected exit code $3, got ${STATUS}"
56 1.2 christos
57 1.2 christos # don't actually fail just because of wrong exit code
58 1.2 christos # unless we either expected, or received "good"
59 1.2 christos case "$3/${STATUS}" in
60 1.2 christos (*/0|0/*) fail=true;;
61 1.2 christos esac
62 1.2 christos fi
63 1.2 christos
64 1.2 christos if [ "$3" -eq 0 ]; then
65 1.2 christos if [ -s "${TEMP_FILE}" ]; then
66 1.5 christos echo >&2 \
67 1.5 christos "[$TEST_NUM] Messages produced on stderr unexpected..."
68 1.2 christos cat "${TEMP_FILE}" >&2
69 1.2 christos fail=true
70 1.2 christos fi
71 1.2 christos else
72 1.2 christos if ! [ -s "${TEMP_FILE}" ]; then
73 1.5 christos echo >&2 \
74 1.5 christos "[$TEST_NUM] Expected messages on stderr, nothing produced"
75 1.2 christos fail=true
76 1.2 christos fi
77 1.2 christos fi
78 1.2 christos rm -f "${TEMP_FILE}"
79 1.2 christos
80 1.2 christos # Remove newlines (use local shell for this)
81 1.1 jruoho oifs="$IFS"
82 1.1 jruoho IFS="$nl"
83 1.1 jruoho result="$(echo $result)"
84 1.1 jruoho IFS="$oifs"
85 1.1 jruoho if [ "$2" != "$result" ]
86 1.1 jruoho then
87 1.5 christos echo >&2 "[$TEST_NUM] Expected output '$2', received '$result'"
88 1.2 christos fail=true
89 1.1 jruoho fi
90 1.2 christos
91 1.6 christos if $fail
92 1.6 christos then
93 1.6 christos echo >&2 "[$TEST_NUM] Full command: <<${CMD}>>"
94 1.6 christos fi
95 1.6 christos
96 1.5 christos $fail && test -n "$TEST_ID" && {
97 1.5 christos TEST_FAILURES="${TEST_FAILURES}${TEST_FAILURES:+
98 1.5 christos }${TEST_ID}[$TEST_NUM]: test of '$1' failed";
99 1.5 christos TEST_FAIL_COUNT=$(( $TEST_FAIL_COUNT + 1 ))
100 1.5 christos return 0
101 1.5 christos }
102 1.5 christos $fail && atf_fail "Test[$TEST_NUM] of '$1' failed"
103 1.2 christos return 0
104 1.1 jruoho }
105 1.1 jruoho
106 1.5 christos results()
107 1.5 christos {
108 1.5 christos test -z "${TEST_ID}" && return 0
109 1.5 christos test -z "${TEST_FAILURES}" && return 0
110 1.5 christos
111 1.5 christos echo >&2 "=========================================="
112 1.5 christos echo >&2 "While testing '${TEST_ID}'"
113 1.5 christos echo >&2 " - - - - - - - - - - - - - - - - -"
114 1.5 christos echo >&2 "${TEST_FAILURES}"
115 1.5 christos atf_fail \
116 1.5 christos "Test ${TEST_ID}: $TEST_FAIL_COUNT subtests (of $TEST_NUM) failed - see stderr"
117 1.5 christos }
118 1.5 christos
119 1.2 christos atf_test_case do_simple
120 1.2 christos do_simple_head() {
121 1.1 jruoho atf_set "descr" "Basic tests for here documents"
122 1.1 jruoho }
123 1.2 christos do_simple_body() {
124 1.1 jruoho y=x
125 1.1 jruoho
126 1.5 christos reset 'simple'
127 1.5 christos IFS=' '
128 1.2 christos check 'x=`cat <<EOF'$nl'text'${nl}EOF$nl'`; echo $x' 'text' 0
129 1.2 christos check 'x=`cat <<\EOF'$nl'text'${nl}EOF$nl'`; echo $x' 'text' 0
130 1.2 christos
131 1.2 christos check "y=${y};"'x=`cat <<EOF'$nl'te${y}t'${nl}EOF$nl'`; echo $x' \
132 1.2 christos 'text' 0
133 1.2 christos check "y=${y};"'x=`cat <<\EOF'$nl'te${y}t'${nl}EOF$nl'`; echo $x' \
134 1.2 christos 'te${y}t' 0
135 1.2 christos check "y=${y};"'x=`cat <<"EOF"'$nl'te${y}t'${nl}EOF$nl'`; echo $x' \
136 1.2 christos 'te${y}t' 0
137 1.2 christos check "y=${y};"'x=`cat <<'"'EOF'"$nl'te${y}t'${nl}EOF$nl'`; echo $x' \
138 1.2 christos 'te${y}t' 0
139 1.2 christos
140 1.2 christos # check that quotes in the here doc survive and cause no problems
141 1.2 christos check "cat <<EOF${nl}te'xt${nl}EOF$nl" "te'xt" 0
142 1.2 christos check "cat <<\EOF${nl}te'xt${nl}EOF$nl" "te'xt" 0
143 1.2 christos check "cat <<'EOF'${nl}te'xt${nl}EOF$nl" "te'xt" 0
144 1.2 christos check "cat <<EOF${nl}te\"xt${nl}EOF$nl" 'te"xt' 0
145 1.2 christos check "cat <<\EOF${nl}te\"xt${nl}EOF$nl" 'te"xt' 0
146 1.2 christos check "cat <<'EOF'${nl}te\"xt${nl}EOF$nl" 'te"xt' 0
147 1.2 christos check "cat <<'EO'F${nl}te\"xt${nl}EOF$nl" 'te"xt' 0
148 1.2 christos
149 1.2 christos check "y=${y};"'x=`cat <<EOF'$nl'te'"'"'${y}t'${nl}EOF$nl'`; echo $x' \
150 1.2 christos 'te'"'"'xt' 0
151 1.2 christos check "y=${y};"'x=`cat <<EOF'$nl'te'"''"'${y}t'${nl}EOF$nl'`; echo $x' \
152 1.2 christos 'te'"''"'xt' 0
153 1.2 christos
154 1.2 christos # note that the blocks of empty space in the following must
155 1.2 christos # be entirely tab characters, no spaces.
156 1.2 christos
157 1.2 christos check 'x=`cat <<EOF'"$nl text${nl}EOF$nl"'`; echo "$x"' \
158 1.2 christos ' text' 0
159 1.2 christos check 'x=`cat <<-EOF'"$nl text${nl}EOF$nl"'`; echo $x' \
160 1.2 christos 'text' 0
161 1.2 christos check 'x=`cat <<-EOF'"${nl}text${nl} EOF$nl"'`; echo $x' \
162 1.2 christos 'text' 0
163 1.2 christos check 'x=`cat <<-\EOF'"$nl text${nl} EOF$nl"'`; echo $x' \
164 1.2 christos 'text' 0
165 1.2 christos check 'x=`cat <<- "EOF"'"$nl text${nl}EOF$nl"'`; echo $x' \
166 1.2 christos 'text' 0
167 1.2 christos check 'x=`cat <<- '"'EOF'${nl}text${nl} EOF$nl"'`; echo $x' \
168 1.2 christos 'text' 0
169 1.5 christos results
170 1.5 christos }
171 1.5 christos
172 1.5 christos atf_test_case end_markers
173 1.5 christos end_markers_head() {
174 1.5 christos atf_set "descr" "Tests for various end markers of here documents"
175 1.5 christos }
176 1.5 christos end_markers_body() {
177 1.5 christos
178 1.5 christos reset 'end_markers'
179 1.6 christos for end in EOF 1 \! '$$$' "string " a\\\ a\\\ \ '&' '' ' ' ' ' \
180 1.6 christos --STRING-- . '~~~' ')' '(' '#' '()' '(\)' '(\/)' '--' '\' '{' '}' \
181 1.5 christos VERYVERYVERYVERYLONGLONGLONGin_fact_absurdly_LONG_LONG_HERE_DOCUMENT_TERMINATING_MARKER_THAT_goes_On_forever_and_ever_and_ever...
182 1.5 christos do
183 1.5 christos # check unquoted end markers
184 1.5 christos case "${end}" in
185 1.6 christos ('' | *[' ()\$&#*~']* ) ;; # skip unquoted endmark test for these
186 1.5 christos (*) check \
187 1.6 christos 'x=$(cat << '"${end}${nl}text${nl}${end}${nl}"'); printf %s "$x"' 'text' 0
188 1.5 christos ;;
189 1.5 christos esac
190 1.5 christos
191 1.5 christos # and quoted end markers
192 1.5 christos check \
193 1.6 christos 'x=$(cat <<'"'${end}'${nl}text${nl}${end}${nl}"'); printf %s "$x"' 'text' 0
194 1.5 christos
195 1.5 christos # and see what happens if we encounter "almost" an end marker
196 1.5 christos case "${#end}" in
197 1.5 christos (0|1) ;; # too short to try truncation tests
198 1.5 christos (*) check \
199 1.6 christos 'x=$(cat <<'"'${end}'${nl}text${nl}${end%?}${nl}${end}${nl}"'); printf %s "$x"' \
200 1.5 christos "text ${end%?}" 0
201 1.5 christos check \
202 1.6 christos 'x=$(cat <<'"'${end}'${nl}text${nl}${end#?}${nl}${end}${nl}"'); printf %s "$x"' \
203 1.5 christos "text ${end#?}" 0
204 1.5 christos check \
205 1.6 christos 'x=$(cat <<'"'${end}'${nl}text${nl}${end%?}+${nl}${end}${nl}"');printf %s "$x"' \
206 1.5 christos "text ${end%?}+" 0
207 1.5 christos ;;
208 1.5 christos esac
209 1.5 christos
210 1.5 christos # or something that is a little longer
211 1.5 christos check \
212 1.6 christos 'x=$(cat <<'"'${end}'${nl}text${nl}${end}x${nl}${end}${nl}"'); printf %s "$x"' \
213 1.5 christos "text ${end}x" 0
214 1.5 christos check \
215 1.6 christos 'x=$(cat <<'"'${end}'${nl}text${nl}!${end}${nl}${end}${nl}"'); printf %s "$x"' \
216 1.5 christos "text !${end}" 0
217 1.5 christos
218 1.5 christos # or which does not begin at start of line
219 1.5 christos check \
220 1.6 christos 'x=$(cat <<'"'${end}'${nl}text${nl} ${end}${nl}${end}${nl}"'); printf %s "$x"' \
221 1.5 christos "text ${end}" 0
222 1.5 christos check \
223 1.6 christos 'x=$(cat <<'"'${end}'${nl}text${nl} ${end}${nl}${end}${nl}"'); printf %s "$x"' \
224 1.5 christos "text ${end}" 0
225 1.5 christos
226 1.5 christos # or end at end of line
227 1.5 christos check \
228 1.6 christos 'x=$(cat <<'"'${end}'${nl}text${nl}${end} ${nl}${end}${nl}"'); printf %s "$x"' \
229 1.5 christos "text ${end} " 0
230 1.5 christos
231 1.5 christos # or something that is correct much of the way, but then...
232 1.5 christos
233 1.5 christos case "${#end}" in
234 1.5 christos (0) ;; # cannot test this one
235 1.5 christos (1) check \
236 1.6 christos 'x=$(cat <<'"'${end}'${nl}text${nl}${end}${end}${nl}${end}${nl}"'); printf %s "$x"' \
237 1.5 christos "text ${end}${end}" 0
238 1.5 christos ;;
239 1.5 christos (2-7) pfx="${end%?}"
240 1.5 christos check \
241 1.6 christos 'x=$(cat <<'"'${end}'${nl}text${nl}${end}${pfx}${nl}${end}${nl}"'); printf %s "$x"' \
242 1.5 christos "text ${end}${pfx}" 0
243 1.5 christos check \
244 1.6 christos 'x=$(cat <<'"'${end}'${nl}text${nl}${pfx}${end}${nl}${end}${nl}"'); printf %s "$x"' \
245 1.5 christos "text ${pfx}${end}" 0
246 1.5 christos ;;
247 1.5 christos (*) pfx=${end%??????}; sfx=${end#??????}
248 1.5 christos check \
249 1.6 christos 'x=$(cat <<'"'${end}'${nl}text${nl}${end}${sfx}${nl}${end}${nl}"'); printf %s "$x"' \
250 1.5 christos "text ${end}${sfx}" 0
251 1.5 christos check \
252 1.6 christos 'x=$(cat <<'"'${end}'${nl}text${nl}${pfx}${end}${nl}${end}${nl}"'); printf %s "$x"' \
253 1.5 christos "text ${pfx}${end}" 0
254 1.5 christos check \
255 1.6 christos 'x=$(cat <<'"'${end}'${nl}text${nl}${pfx}${sfx}${nl}${end}${nl}"'); printf %s "$x"' \
256 1.5 christos "text ${pfx}${sfx}" 0
257 1.5 christos ;;
258 1.5 christos esac
259 1.5 christos done
260 1.5 christos
261 1.5 christos # Add striptabs tests (in similar way) here one day...
262 1.5 christos
263 1.5 christos results
264 1.2 christos }
265 1.2 christos
266 1.2 christos atf_test_case incomplete
267 1.2 christos incomplete_head() {
268 1.2 christos atf_set "descr" "Basic tests for incomplete here documents"
269 1.2 christos }
270 1.2 christos incomplete_body() {
271 1.5 christos reset incomplete
272 1.5 christos
273 1.2 christos check 'cat <<EOF' '' 2
274 1.2 christos check 'cat <<- EOF' '' 2
275 1.2 christos check 'cat <<\EOF' '' 2
276 1.2 christos check 'cat <<- \EOF' '' 2
277 1.2 christos
278 1.2 christos check 'cat <<EOF'"${nl}" '' 2
279 1.2 christos check 'cat <<- EOF'"${nl}" '' 2
280 1.2 christos check 'cat <<'"'EOF'${nl}" '' 2
281 1.2 christos check 'cat <<- "EOF"'"${nl}" '' 2
282 1.2 christos
283 1.2 christos check 'cat << EOF'"${nl}${nl}" '' 2
284 1.2 christos check 'cat <<-EOF'"${nl}${nl}" '' 2
285 1.2 christos check 'cat << '"'EOF'${nl}${nl}" '' 2
286 1.2 christos check 'cat <<-"EOF"'"${nl}${nl}" '' 2
287 1.2 christos
288 1.2 christos check 'cat << EOF'"${nl}"'line 1'"${nl}" '' 2
289 1.2 christos check 'cat <<-EOF'"${nl}"' line 1'"${nl}" '' 2
290 1.2 christos check 'cat << EOF'"${nl}"'line 1'"${nl}"' line 2'"${nl}" '' 2
291 1.2 christos check 'cat <<-EOF'"${nl}"' line 1'"${nl}"'line 2'"${nl}" '' 2
292 1.2 christos
293 1.2 christos check 'cat << EOF'"${nl}line 1${nl}${nl}line3${nl}${nl}5!${nl}" '' 2
294 1.5 christos
295 1.5 christos results
296 1.5 christos }
297 1.5 christos
298 1.5 christos atf_test_case lineends
299 1.5 christos lineends_head() {
300 1.5 christos atf_set "descr" "Tests for line endings in here documents"
301 1.5 christos }
302 1.5 christos lineends_body() {
303 1.5 christos reset lineends
304 1.5 christos
305 1.5 christos # note that "check" removes newlines from stdout before comparing.
306 1.5 christos # (they become blanks, provided there is something before & after)
307 1.5 christos
308 1.5 christos check 'cat << \echo'"${nl}"'\'"${nl}echo${nl}echo${nl}" '\' 0
309 1.5 christos check 'cat << echo'"${nl}"'\'"${nl}echo${nl}echo${nl}" 'echo' 0
310 1.5 christos check 'cat << echo'"${nl}"'\\'"${nl}echo${nl}echo${nl}" '\' 0
311 1.5 christos
312 1.5 christos check 'X=3; cat << ec\ho'"${nl}"'$X\'"${nl}echo${nl}echo${nl}" \
313 1.5 christos '$X\' 0
314 1.5 christos check 'X=3; cat << echo'"${nl}"'$X'"${nl}echo${nl}echo${nl}" \
315 1.5 christos '3' 0
316 1.5 christos check 'X=3; cat << echo'"${nl}"'$X\'"${nl}echo${nl}echo${nl}" \
317 1.5 christos '' 0
318 1.5 christos check 'X=3; cat << echo'"${nl}"'${X}\'"${nl}echo${nl}echo${nl}" \
319 1.5 christos '3echo' 0
320 1.5 christos check 'X=3; cat << echo'"${nl}"'\$X\'"${nl}echo${nl}echo${nl}" \
321 1.5 christos '$Xecho' 0
322 1.5 christos check 'X=3; cat << echo'"${nl}"'\\$X \'"${nl}echo${nl}echo${nl}" \
323 1.5 christos '\3 echo' 0
324 1.5 christos
325 1.5 christos check \
326 1.5 christos 'cat << "echo"'"${nl}"'line1\'"${nl}"'line2\'"${nl}echo${nl}echo${nl}" \
327 1.5 christos 'line1\ line2\' 0
328 1.5 christos check \
329 1.5 christos 'cat << echo'"${nl}"'line1\'"${nl}"'line2\'"${nl}echo${nl}echo${nl}" \
330 1.5 christos 'line1line2echo' 0
331 1.5 christos
332 1.5 christos results
333 1.2 christos }
334 1.2 christos
335 1.2 christos atf_test_case multiple
336 1.2 christos multiple_head() {
337 1.5 christos atf_set "descr" "Tests for multiple here documents on one cmd line"
338 1.2 christos }
339 1.2 christos multiple_body() {
340 1.5 christos reset multiple
341 1.5 christos
342 1.2 christos check \
343 1.2 christos "(cat ; cat <&3) <<EOF0 3<<EOF3${nl}STDIN${nl}EOF0${nl}-3-${nl}EOF3${nl}" \
344 1.2 christos 'STDIN -3-' 0
345 1.2 christos
346 1.2 christos check "(read line; echo \"\$line\"; cat <<EOF1; echo \"\$line\") <<EOF2
347 1.2 christos The File
348 1.2 christos EOF1
349 1.2 christos The Line
350 1.2 christos EOF2
351 1.2 christos " 'The Line The File The Line' 0
352 1.2 christos
353 1.2 christos check "(read line; echo \"\$line\"; cat <<EOF; echo \"\$line\") <<EOF
354 1.2 christos The File
355 1.2 christos EOF
356 1.2 christos The Line
357 1.2 christos EOF
358 1.2 christos " 'The Line The File The Line' 0
359 1.2 christos
360 1.5 christos check "V=1; W=2; cat <<-1; cat <<2; cat <<- 3; cat <<'4';"' cat <<\5
361 1.5 christos $V
362 1.5 christos $W
363 1.5 christos 3
364 1.5 christos 4
365 1.5 christos 5
366 1.5 christos 1
367 1.5 christos 2
368 1.5 christos 5
369 1.5 christos 4*$W+\$V
370 1.5 christos 3
371 1.5 christos $W
372 1.5 christos 1
373 1.5 christos 2
374 1.5 christos 3
375 1.5 christos 4
376 1.5 christos 7+$V
377 1.5 christos $W+6
378 1.5 christos 5
379 1.5 christos ' '1 2 3 4 5 5 4*2+$V $W 1 2 3 7+$V $W+6' 0
380 1.5 christos
381 1.5 christos results
382 1.5 christos }
383 1.5 christos
384 1.5 christos atf_test_case nested
385 1.5 christos nested_head() {
386 1.5 christos atf_set "descr" "Tests for nested here documents for one cmd"
387 1.5 christos }
388 1.5 christos nested_body() {
389 1.5 christos reset nested
390 1.5 christos
391 1.5 christos check \
392 1.5 christos 'cat << EOF1'"${nl}"'$(cat << EOF2'"${nl}LINE${nl}EOF2${nl}"')'"${nl}EOF1${nl}"\
393 1.5 christos 'LINE' 0
394 1.5 christos
395 1.5 christos # This next one fails ... and correctly, so we will omit it (bad test)
396 1.5 christos # Reasoning is that the correct data "$(cat << EOF2)\nLINE\nEOF2\n" is
397 1.5 christos # collected for the outer (EOF1) heredoc, when that is parsed, it looks
398 1.5 christos # like
399 1.5 christos # $(cat <<EOF2)
400 1.5 christos # LINE
401 1.5 christos # EOF2
402 1.5 christos # which looks like a good command - except it is being parsed in "heredoc"
403 1.5 christos # syntax, which means it is enclosed in double quotes, which means that
404 1.5 christos # the newline after the ')' in the first line is not a newline token, but
405 1.5 christos # just a character. The EOF2 heredoc cannot start until after the next
406 1.5 christos # newline token, of which there are none here... LINE and EOF2 are just
407 1.5 christos # more data in the outer EOF1 heredoc for its "cat" command to read & write.
408 1.5 christos #
409 1.5 christos # The previous sub-test works because there the \n comes inside the
410 1.5 christos # $( ), and in there, the outside quoting rules are suspended, and it
411 1.5 christos # all starts again - so that \n is a newline token, and the EOF2 heredoc
412 1.5 christos # is processed.
413 1.5 christos #
414 1.5 christos # check \
415 1.5 christos # 'cat << EOF1'"${nl}"'$(cat << EOF2 )'"${nl}LINE${nl}EOF2${nl}EOF1${nl}" \
416 1.5 christos # 'LINE' 0
417 1.5 christos
418 1.5 christos L='cat << EOF1'"${nl}"'LINE1$(cat << EOF2'"${nl}"
419 1.5 christos L="${L}"'LINE2$(cat << EOF3'"${nl}"
420 1.5 christos L="${L}"'LINE3$(cat << EOF4'"${nl}"
421 1.5 christos L="${L}"'LINE4$(cat << EOF5'"${nl}"
422 1.5 christos L="${L}LINE5${nl}EOF5${nl})4${nl}EOF4${nl})3${nl}"
423 1.5 christos L="${L}EOF3${nl})2${nl}EOF2${nl})1${nl}EOF1${nl}"
424 1.5 christos
425 1.5 christos # That mess is ...
426 1.5 christos #
427 1.5 christos # cat <<EOF1
428 1.5 christos # LINE1$(cat << EOF2
429 1.5 christos # LINE2$(cat << EOF3
430 1.5 christos # LINE3$(cat << EOF4
431 1.5 christos # LINE4$(cat << EOF5
432 1.5 christos # LINE5
433 1.5 christos # EOF5
434 1.5 christos # )4
435 1.5 christos # EOF4
436 1.5 christos # )3
437 1.5 christos # EOF3
438 1.5 christos # )2
439 1.5 christos # EOF2
440 1.5 christos # )1
441 1.5 christos # EOF1
442 1.5 christos
443 1.5 christos check "${L}" 'LINE1LINE2LINE3LINE4LINE54321' 0
444 1.5 christos
445 1.5 christos results
446 1.5 christos }
447 1.5 christos
448 1.5 christos atf_test_case quoting
449 1.5 christos quoting_head() {
450 1.5 christos atf_set "descr" "Tests for use of quotes inside here documents"
451 1.5 christos }
452 1.5 christos quoting_body() {
453 1.5 christos reset quoting
454 1.5 christos
455 1.5 christos check 'X=!; cat <<- E\0F
456 1.5 christos <'\''"'\'' \\$X\$X "'\''" \\>
457 1.5 christos E0F
458 1.5 christos ' '<'\''"'\'' \\$X\$X "'\''" \\>' 0
459 1.5 christos
460 1.5 christos check 'X=!; cat <<- E0F
461 1.5 christos <'\''"'\'' \\$X\$X "'\''" \\>
462 1.5 christos E0F
463 1.5 christos ' '<'\''"'\'' \!$X "'\''" \>' 0
464 1.5 christos
465 1.5 christos check 'cat <<- END
466 1.5 christos $( echo "'\''" ) $( echo '\''"'\'' ) $( echo \\ )
467 1.5 christos END
468 1.5 christos ' "' \" \\" 0
469 1.5 christos
470 1.5 christos check 'X=12345; Y="string1 line1?-line2"; Z=; unset W; cat <<-EOF
471 1.5 christos ${#X}${Z:-${Y}}${W+junk}${Y%%l*}${Y#*\?}
472 1.5 christos "$Z"'\''$W'\'' ${Y%" "*} $(( X + 54321 ))
473 1.5 christos EOF
474 1.5 christos ' '5string1 line1?-line2string1 -line2 ""'\'\'' string1 66666' 0
475 1.5 christos
476 1.5 christos results
477 1.5 christos }
478 1.5 christos
479 1.5 christos atf_test_case side_effects
480 1.5 christos side_effects_head() {
481 1.5 christos atf_set "descr" "Tests how side effects in here documents are handled"
482 1.5 christos }
483 1.5 christos side_effects_body() {
484 1.5 christos
485 1.5 christos atf_check -s exit:0 -o inline:'2\n1\n' -e empty ${TEST_SH} -c '
486 1.5 christos unset X
487 1.5 christos cat <<-EOF
488 1.5 christos ${X=2}
489 1.5 christos EOF
490 1.5 christos echo "${X-1}"
491 1.5 christos '
492 1.2 christos }
493 1.2 christos
494 1.3 christos atf_test_case vicious
495 1.3 christos vicious_head() {
496 1.2 christos atf_set "descr" "Tests for obscure and obnoxious uses of here docs"
497 1.2 christos }
498 1.3 christos vicious_body() {
499 1.5 christos reset
500 1.2 christos
501 1.2 christos cat <<- \END_SCRIPT > script
502 1.2 christos cat <<ONE && cat \
503 1.2 christos <<TWO
504 1.2 christos a
505 1.2 christos ONE
506 1.2 christos b
507 1.2 christos TWO
508 1.2 christos END_SCRIPT
509 1.2 christos
510 1.2 christos atf_check -s exit:0 -o inline:'a\nb\n' -e empty ${TEST_SH} script
511 1.2 christos
512 1.2 christos # This next one is causing discussion currently (late Feb 2016)
513 1.2 christos # amongst stds writers & implementors. Consequently we
514 1.2 christos # will not check what it produces. The eventual result
515 1.2 christos # seems unlikely to be what we currently output, which
516 1.2 christos # is:
517 1.3 christos # A:echo line 1
518 1.2 christos # B:echo line 2)" && prefix DASH_CODE <<DASH_CODE
519 1.2 christos # B:echo line 3
520 1.2 christos # line 4
521 1.2 christos # line 5
522 1.2 christos #
523 1.2 christos # The likely intended output is ...
524 1.2 christos #
525 1.2 christos # A:echo line 3
526 1.2 christos # B:echo line 1
527 1.2 christos # line 2
528 1.2 christos # DASH_CODE:echo line 4)"
529 1.2 christos # DASH_CODE:echo line 5
530 1.2 christos #
531 1.5 christos # The difference is explained by differing opinions on just
532 1.2 christos # when processing of a here doc should start
533 1.2 christos
534 1.2 christos cat <<- \END_SCRIPT > script
535 1.2 christos prefix() { sed -e "s/^/$1:/"; }
536 1.2 christos DASH_CODE() { :; }
537 1.2 christos
538 1.2 christos prefix A <<XXX && echo "$(prefix B <<XXX
539 1.2 christos echo line 1
540 1.2 christos XXX
541 1.2 christos echo line 2)" && prefix DASH_CODE <<DASH_CODE
542 1.2 christos echo line 3
543 1.2 christos XXX
544 1.2 christos echo line 4)"
545 1.2 christos echo line 5
546 1.2 christos DASH_CODE
547 1.2 christos END_SCRIPT
548 1.1 jruoho
549 1.2 christos # we will just verify that the shell can parse the
550 1.2 christos # script somehow, and doesn't fall over completely...
551 1.1 jruoho
552 1.5 christos atf_check -s exit:0 -o ignore -e empty ${TEST_SH} script
553 1.1 jruoho }
554 1.1 jruoho
555 1.1 jruoho atf_init_test_cases() {
556 1.5 christos atf_add_test_case do_simple # not worthy of a comment
557 1.5 christos atf_add_test_case end_markers # the mundane, the weird, the bizarre
558 1.5 christos atf_add_test_case incomplete # where the end marker isn't...
559 1.5 christos atf_add_test_case lineends # test weird line endings in heredocs
560 1.2 christos atf_add_test_case multiple # multiple << operators on one cmd
561 1.5 christos atf_add_test_case nested # here docs inside here docs
562 1.5 christos atf_add_test_case quoting # stuff quoted inside
563 1.5 christos atf_add_test_case side_effects # here docs that modify environment
564 1.3 christos atf_add_test_case vicious # evil test from the austin-l list...
565 1.1 jruoho }
566