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