1# $NetBSD: t_fsplit.sh,v 1.10 2024/10/19 11:59:51 kre Exp $ 2# 3# Copyright (c) 2007-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 28# The standard 29# http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html 30# explains (section 2.6) that Field splitting should be performed on the 31# result of variable expansions. 32# In particular this means that in ${x-word}, 'word' must be expanded as if 33# the "${x-" and "}" were absent from the input line. 34# 35# So: sh -c 'set ${x-a b c}; echo $#' should give 3. 36# and: sh -c 'set -- ${x-}' echo $#' should give 0 37# 38 39# the implementation of "sh" to test 40: ${TEST_SH:="/bin/sh"} 41 42nl=' 43' 44 45check() 46{ 47 if [ "${TEST}" -eq 0 ] 48 then 49 FAILURES= 50 fi 51 52 TEST=$((${TEST} + 1)) 53 54 case "$#" in 55 (2) ;; 56 (*) atf_fail "Internal test error, $# args to check, test ${TEST}";; 57 esac 58 59 result=$( ${TEST_SH} -c "unset x a b d c e f g h; $1" ) 60 STATUS="$?" 61 62 # Remove newlines 63 oifs="$IFS" 64 IFS="$nl" 65 result="$(echo $result)" 66 IFS="$oifs" 67 68 # # trim the test text in case we use it in a message below 69 # case "$1" in 70 # ????????????????*) 71 # set -- "$(expr "$1" : '\(............\).*')..." "$2" ;; 72 # esac 73 74 if [ "$2" != "${result}" ] 75 then 76 FAILURES="${FAILURES}${FAILURES:+ }${TEST}" 77 printf >&2 'Sub-test %d failed:\n %s\n' \ 78 "${TEST}" "$1" 79 printf >&2 ' Expected: [%s]\n' "$2" 80 printf >&2 ' Received: [%s]\n' "${result}" 81 82 if [ "${STATUS}" != 0 ] 83 then 84 printf >&2 ' Sub-test exit status: %d\n' "${STATUS}" 85 fi 86 elif [ "${STATUS}" != 0 ] 87 then 88 FAILURES="${FAILURES}${FAILURES:+ }${TEST}" 89 printf >&2 'Sub-test %d failed:\n\t%s\n' \ 90 "${TEST}" "$1" 91 printf >&2 ' Sub-test exit status: %d (with correct output)\n' \ 92 "${STATUS}" 93 fi 94 95 return 0 96} 97 98check_results() 99{ 100 NAME=$1 101 102 set -- ${FAILURES} 103 104 if [ $# -eq 0 ] 105 then 106 return 0 107 fi 108 109 unset IFS 110 printf >&2 'Subtest %s: %d sub-tests (of %d) [%s] failed.\n' \ 111 "${NAME}" "$#" "${TEST}" "$*" 112 113 atf_fail "$# of ${TEST} sub-tests (${FAILURES}), see stderr" 114 return 0 115} 116 117atf_test_case for 118for_head() 119{ 120 atf_set "descr" "Checks field splitting in for loops" 121} 122for_body() 123{ 124 unset x 125 126 TEST=0 127 # Since I managed to break this, leave the test in 128 check 'for f in $x; do echo x${f}y; done' '' 129 130 check_results for 131} 132 133atf_test_case default_val 134default_val_head() 135{ 136 atf_set "descr" "Checks field splitting in variable default values" 137} 138default_val_body() 139{ 140 TEST=0 141 # Check that IFS is applied to text from ${x-...} unless it is inside 142 # any set of "..." 143 check 'set -- ${x-a b c}; echo $#' 3 144 145 check 'set -- ${x-"a b" c}; echo $#' 2 146 check 'set -- ${x-a "b c"}; echo $#' 2 147 check 'set -- ${x-"a b c"}; echo $#' 1 148 149 check "set -- \${x-'a b' c}; echo \$#" 2 150 check "set -- \${x-a 'b c'}; echo \$#" 2 151 check "set -- \${x-'a b c'}; echo \$#" 1 152 153 check 'set -- ${x-a\ b c}; echo $#' 2 154 check 'set -- ${x-a b\ c}; echo $#' 2 155 check 'set -- ${x-a\ b\ c}; echo $#' 1 156 157 check 'set -- ${x}; echo $#' 0 158 check 'set -- ${x-}; echo $#' 0 159 check 'set -- ${x-""}; echo $#' 1 160 check 'set -- ""${x}; echo $#' 1 161 check 'set -- ""${x-}; echo $#' 1 162 check 'set -- ""${x-""}; echo $#' 1 163 check 'set -- ${x}""; echo $#' 1 164 check 'set -- ${x-}""; echo $#' 1 165 check 'set -- ${x-""}""; echo $#' 1 166 check 'set -- ""${x}""; echo $#' 1 167 check 'set -- ""${x-}""; echo $#' 1 168 check 'set -- ""${x-""}""; echo $#' 1 169 170 check 'for i in ${x-a b c}; do echo "z${i}z"; done' \ 171 'zaz zbz zcz' 172 check 'for i in ${x-"a b" c}; do echo "z${i}z"; done' \ 173 'za bz zcz' 174 check 'for i in ${x-"a ${x-b c}" d}; do echo "z${i}z"; done' \ 175 'za b cz zdz' 176 check 'for i in ${x-a ${x-b c} d}; do echo "z${i}z"; done' \ 177 'zaz zbz zcz zdz' 178 179 # I am not sure the first of these two is correct, the rules on 180 # quoting word in ${var-word} are peculiar, and hard to fathom... 181 # It is what the NetBSD shell does, and bash, not the freebsd shell 182 # and not ksh93 (as of Mar 1, 2016, and still in June 2017) 183 # The likely correct interp of the next one is 'za bz zcz zdz' 184 185 # That and the "should be" below are correct as of POSIX 7 TC2 186 # But this is going to change to "unspecified" in POSIX 8 187 # (resolution of bug 221) so instead of being incorrect (as now) 188 # the NetBSD shell will simply be implementing is version 189 # of unspecified behaviour. Just beware that shells differ, 190 # a shell that fails this test is not incorrect because of it. 191 192 # should be: uuuu qqqqqq uuu q uuu (unquoted/quoted) no nesting. 193 check 'for i in ${x-"a ${x-"b c"}" d}; do echo "z${i}z"; done' \ 194 'za b cz zdz' 195 check 'for i in ${x-a ${x-"b c"} d}; do echo "z${i}z"; done' \ 196 'zaz zb cz zdz' 197 198 check_results default_val 199} 200 201atf_test_case replacement_val 202replacement_val_head() 203{ 204 atf_set "descr" "Checks field splitting in variable replacement values" 205} 206replacement_val_body() 207{ 208 TEST=0 209 210 # Check that IFS is applied to text from ${x+...} unless it is inside 211 # any set of "...", or whole expansion is quoted, or both... 212 213 check 'x=BOGUS; set -- ${x+a b c}; echo $#' 3 214 215 check 'x=BOGUS; set -- ${x+"a b" c}; echo $#' 2 216 check 'x=BOGUS; set -- ${x+a "b c"}; echo $#' 2 217 check 'x=BOGUS; set -- ${x+"a b c"}; echo $#' 1 218 219 check "x=BOGUS; set -- \${x+'a b' c}; echo \$#" 2 220 check "x=BOGUS; set -- \${x+a 'b c'}; echo \$#" 2 221 check "x=BOGUS; set -- \${x+'a b c'}; echo \$#" 1 222 223 check 'x=BOGUS; set -- ${x+a\ b c}; echo $#' 2 224 check 'x=BOGUS; set -- ${x+a b\ c}; echo $#' 2 225 check 'x=BOGUS; set -- ${x+a\ b\ c}; echo $#' 1 226 227 check 'x=BOGUS; set -- ${x+}; echo $#' 0 228 check 'x=BOGUS; set -- ${x+""}; echo $#' 1 229 check 'x=BOGUS; set -- ""${x+}; echo $#' 1 230 check 'x=BOGUS; set -- ""${x+""}; echo $#' 1 231 check 'x=BOGUS; set -- ${x+}""; echo $#' 1 232 check 'x=BOGUS; set -- ${x+""}""; echo $#' 1 233 check 'x=BOGUS; set -- ""${x+}""; echo $#' 1 234 check 'x=BOGUS; set -- ""${x+""}""; echo $#' 1 235 236 # verify that the value of $x does not affecty the value of ${x+...} 237 check 'x=BOGUS; set -- ${x+}; echo X$1' X 238 check 'x=BOGUS; set -- ${x+""}; echo X$1' X 239 check 'x=BOGUS; set -- ""${x+}; echo X$1' X 240 check 'x=BOGUS; set -- ""${x+""}; echo X$1' X 241 check 'x=BOGUS; set -- ${x+}""; echo X$1' X 242 check 'x=BOGUS; set -- ${x+""}""; echo X$1' X 243 check 'x=BOGUS; set -- ""${x+}""; echo X$1' X 244 check 'x=BOGUS; set -- ""${x+""}""; echo X$1' X 245 246 check 'x=BOGUS; set -- ${x+}; echo X${1-:}X' X:X 247 check 'x=BOGUS; set -- ${x+""}; echo X${1-:}X' XX 248 check 'x=BOGUS; set -- ""${x+}; echo X${1-:}X' XX 249 check 'x=BOGUS; set -- ""${x+""}; echo X${1-:}X' XX 250 check 'x=BOGUS; set -- ${x+}""; echo X${1-:}X' XX 251 check 'x=BOGUS; set -- ${x+""}""; echo X${1-:}X' XX 252 check 'x=BOGUS; set -- ""${x+}""; echo X${1-:}X' XX 253 check 'x=BOGUS; set -- ""${x+""}""; echo X${1-:}X' XX 254 255 # and validate that the replacement can be used as expected 256 check 'x=BOGUS; for i in ${x+a b c}; do echo "z${i}z"; done'\ 257 'zaz zbz zcz' 258 check 'x=BOGUS; for i in ${x+"a b" c}; do echo "z${i}z"; done'\ 259 'za bz zcz' 260 check 'x=BOGUS; for i in ${x+"a ${x+b c}" d}; do echo "z${i}z"; done'\ 261 'za b cz zdz' 262 263 # see the (extended) comment in the default_val test. This will be 264 # unspecified, hence we are OK (will be) but expect differences. 265 # also incorrect: uuuu qqqqqq uuu q uuu 266 check 'x=BOGUS; for i in ${x+"a ${x+"b c"}" d}; do echo "z${i}z"; done'\ 267 'za b cz zdz' 268 269 check 'x=BOGUS; for i in ${x+a ${x+"b c"} d}; do echo "z${i}z"; done'\ 270 'zaz zb cz zdz' 271 check 'x=BOGUS; for i in ${x+a ${x+b c} d}; do echo "z${i}z"; done'\ 272 'zaz zbz zcz zdz' 273 274 check_results replacement_val 275} 276 277atf_test_case ifs_alpha 278ifs_alpha_head() 279{ 280 atf_set "descr" "Checks that field splitting works with alphabetic" \ 281 "characters" 282} 283ifs_alpha_body() 284{ 285 unset x 286 287 TEST=0 288 # repeat with an alphabetic in IFS 289 check 'IFS=q; set ${x-aqbqc}; echo $#' 3 290 check 'IFS=q; for i in ${x-aqbqc}; do echo "z${i}z"; done' \ 291 'zaz zbz zcz' 292 check 'IFS=q; for i in ${x-"aqb"qc}; do echo "z${i}z"; done' \ 293 'zaqbz zcz' 294 check 'IFS=q; for i in ${x-"aq${x-bqc}"qd}; do echo "z${i}z"; done' \ 295 'zaqbqcz zdz' 296 297 # this is another almost certainly incorrect expectation 298 # (but again, see comment in default_val test - becoming unspecified.) 299 # uu qqqqqq uuu q uu (quoted/unquoted) 300 check 'IFS=q; for i in ${x-"aq${x-"bqc"}"qd}; do echo "z${i}z"; done' \ 301 'zaqbqcz zdz' 302 303 check 'IFS=q; for i in ${x-aq${x-"bqc"}qd}; do echo "z${i}z"; done' \ 304 'zaz zbqcz zdz' 305 306 check_results ifs_alpha 307} 308 309atf_test_case quote 310quote_head() 311{ 312 atf_set "descr" "Checks that field splitting works with multi-word" \ 313 "fields" 314} 315quote_body() 316{ 317 unset x 318 319 TEST=0 320 # Some quote propagation checks 321 check 'set "${x-a b c}"; echo $#' 1 322 323 # this is another almost certainly incorrect expectation 324 # (but again, see comment in default_val test - becoming unspecified.) 325 # qqqq uuu qqq (quoted/unquoted) $1 is a $# is 2 326 check 'set "${x-"a b" c}"; echo $1' 'a b c' 327 328 check 'for i in "${x-a b c}"; do echo "z${i}z"; done' 'za b cz' 329 330 check_results quote 331} 332 333atf_test_case dollar_at 334dollar_at_head() 335{ 336 atf_set "descr" "Checks that field splitting works when expanding" \ 337 "\$@" 338} 339dollar_at_body() 340{ 341 unset x 342 343 TEST=0 344 # Check we get "$@" right 345 346 check 'set --; for i in x"$@"x; do echo "z${i}z"; done' 'zxxz' 347 check 'set a; for i in x"$@"x; do echo "z${i}z"; done' 'zxaxz' 348 check 'set a b; for i in x"$@"x; do echo "z${i}z"; done' \ 349 'zxaz zbxz' 350 351 check 'set --; for i; do echo "z${i}z"; done' '' 352 check 'set --; for i in $@; do echo "z${i}z"; done' '' 353 check 'set --; for i in "$@"; do echo "z${i}z"; done' '' 354 # atf_expect_fail "PR bin/50834" 355 check 'set --; for i in ""$@; do echo "z${i}z"; done' 'zz' 356 # atf_expect_pass 357 check 'set --; for i in $@""; do echo "z${i}z"; done' 'zz' 358 check 'set --; for i in ""$@""; do echo "z${i}z"; done' 'zz' 359 check 'set --; for i in """$@"; do echo "z${i}z"; done' 'zz' 360 check 'set --; for i in "$@"""; do echo "z${i}z"; done' 'zz' 361 check 'set --; for i in """$@""";do echo "z${i}z"; done' 'zz' 362 363 check 'set ""; for i; do echo "z${i}z"; done' 'zz' 364 check 'set ""; for i in "$@"; do echo "z${i}z"; done' 'zz' 365 check 'set "" ""; for i; do echo "z${i}z"; done' 'zz zz' 366 check 'set "" ""; for i in "$@"; do echo "z${i}z"; done' 'zz zz' 367 check 'set "" ""; for i in $@; do echo "z${i}z"; done' '' 368 369 check 'set "a b" c; for i; do echo "z${i}z"; done' \ 370 'za bz zcz' 371 check 'set "a b" c; for i in "$@"; do echo "z${i}z"; done' \ 372 'za bz zcz' 373 check 'set "a b" c; for i in $@; do echo "z${i}z"; done' \ 374 'zaz zbz zcz' 375 check 'set " a b " c; for i in "$@"; do echo "z${i}z"; done' \ 376 'z a b z zcz' 377 378 check 'set a b c; for i in "$@$@"; do echo "z${i}z"; done' \ 379 'zaz zbz zcaz zbz zcz' 380 check 'set a b c; for i in "$@""$@";do echo "z${i}z"; done' \ 381 'zaz zbz zcaz zbz zcz' 382 383 check_results dollar_at 384} 385 386atf_test_case ifs 387ifs_head() 388{ 389 atf_set "descr" "Checks that IFS correctly configures field" \ 390 "splitting behavior" 391} 392ifs_body() 393{ 394 unset x 395 396 TEST=0 397 # Some IFS tests 398 check 't="-- "; IFS=" "; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '0' 399 check 't=" x"; IFS=" x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '1' 400 check 't=" x "; IFS=" x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' '1' 401 check 't=axb; IFS="x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' \ 402 '2 a:b' 403 check 't="a x b"; IFS="x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' \ 404 '2 a : b' 405 check 't="a xx b"; IFS="x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' \ 406 '3 a :: b' 407 check 't="a xx b"; IFS="x ";set $t; IFS=":"; r="$*"; IFS=; echo $# $r' \ 408 '3 a::b' 409 # A recent 'clarification' means that a single trailing IFS 410 # non-whitespace doesn't generate an empty parameter 411 check 't="xax"; IFS="x"; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' \ 412 '2 :a' 413 check 't="xax "; IFS="x "; set $t; IFS=":"; r="$*"; IFS=; echo $# $r' \ 414 '2 :a' 415 # Verify that IFS isn't being applied where it shouldn't be. 416 check 'IFS="x"; set axb; IFS=":"; r="$*"; IFS=; echo $# $r' '1 axb' 417 check 'IFS=x; set axb; IFS=:; r=$*; IFS=; echo $# $r' '1 axb' 418 check 'IFS=x; set axb; set -- "$*"; IFS=:; r=$*; IFS=; echo $# $r' \ 419 '1 axb' 420 check 'IFS=x; set axb; set -- $* ; IFS=:; r=$*; IFS=; echo $# $r' \ 421 '2 a:b' 422 423 check_results ifs 424} 425 426atf_test_case var_length 427var_length_head() 428{ 429 atf_set "descr" "Checks that field splitting works when expanding" \ 430 "a variable's length" 431} 432var_length_body() 433{ 434 TEST=0 435 436 long=12345678123456781234567812345678 437 long=$long$long$long$long 438 export long 439 unset x 440 441 # first test that the test method works... 442 check 'set -u; : ${long}; echo ${#long}' '128' 443 444 # Check that we apply IFS to ${#var} 445 check 'echo ${#long}; IFS=2; echo ${#long}; set 1 ${#long};echo $#' \ 446 '128 1 8 3' 447 check 'IFS=2; set ${x-${#long}}; IFS=" "; echo $* $#' '1 8 2' 448 check 'IFS=2; set ${x-"${#long}"}; IFS=" "; echo $* $#' '128 1' 449 check 'IFS=2; set "${x-${#long}}"; IFS=" "; echo $* $#' '128 1' 450 check 'IFS=2; set ${x-${#long}}; : ; echo $* $#' '1 8 ' 451 check 'IFS=2; set ${x-${#long}}; : ; echo $* "$#"' '1 8 2' 452 check 'IFS=2; set ${x-${#long}}; : ; echo "$*" "$#"' '128 2' 453 check 'IFS=2; set ${x-${#long}}; : ; echo "$@" "$#"' '1 8 2' 454 455 check_results var_length 456} 457 458atf_test_case split_arith 459split_arith_head() 460{ 461 atf_set "descr" "Checks that field splitting works when expanding" \ 462 "the results from arithmetic" 463} 464split_arith_body() 465{ 466 TEST=0 467 468 # Check that we apply IFS to $(( expr )) 469 470 # Note: we do not check the actual arithmetic operations here 471 # (there is a separate test just for that) so we just enter 472 # the "answer" inside $(( )) ... also makes it easier to visualise 473 474 check 'IFS=5; echo $(( 123456789 ))' '1234 6789' 475 check 'IFS=5; echo "$(( 123456789 ))"' '123456789' 476 check 'IFS=37; echo $(( 123456789 ))' '12 456 89' 477 check 'IFS=37; echo "$(( 123456789 ))"' '123456789' 478 check 'IFS=159; echo $(( 123456789 ))' ' 234 678' 479 480 check 'IFS=5; set -- $(( 123456789 )); echo $#: $1 $2 $3 $4' \ 481 '2: 1234 6789' 482 check 'IFS=5; set -- "$(( 123456789 ))"; echo $#: $1 $2 $3 $4' \ 483 '1: 1234 6789' # go ahead: explain it! 484 check 'IFS=5; set -- "$(( 123456789 ))"; echo "$#: $1 $2 $3 $4"' \ 485 '1: 123456789 ' # ah! 486 487 check 'IFS=37; set -- $(( 123456789 )); echo $#: $1 $2 $3 $4' \ 488 ' : 12 456 89' # Tricky! 489 check 'IFS=5; set -- $(( 123456789 )); echo $#: $*' \ 490 '2: 1234 6789' 491 check 'IFS=47; set -- $(( 123456789 )); echo $#: $*' \ 492 '3: 123 56 89' 493 check 'IFS=5; set -- $(( 123456789 )); echo "$#: $*"' \ 494 '2: 123456789' 495 check 'IFS=37; set -- $(( 123456789 )); echo "$#: $*"' \ 496 '3: 123456389' # [sic] 497 check 'IFS=5; set -- $(( 123456789 )); echo $#: $@' \ 498 '2: 1234 6789' 499 check 'IFS=47; set -- $(( 123456789 )); echo $#: $@' \ 500 '3: 123 56 89' 501 check 'IFS=5; set -- $(( 123456789 )); echo "$#: $@"' \ 502 '2: 1234 6789' 503 check 'IFS=37; set -- $(( 123456789 )); echo "$#: $*"' \ 504 '3: 123456389' # [sic] 505 506 check 'IFS=1; set -- $(( 1111 )); echo "$#:" $*' '4: ' 507 check 'IFS=" 1"; set -- $(( 1231231231 )); echo "$#: $*"' \ 508 '4: 23 23 23' 509 check 'IFS="1 "; set -- $(( 1231231231 )); echo "$#: $*"' \ 510 '4: 123123123' 511 512 check 'IFS=5; echo 5$(( 123456789 ))5' '51234 67895' 513 check 'IFS=37; echo 73$(( 123456789 ))37' '7312 456 8937' 514 check 'IFS=159; echo 11$(( 123456789 ))95' '11 234 678 95' 515 check 'IFS="159 "; echo 11$(( 123456789 ))95' '11 234 678 95' 516 check 'IFS="159 "; echo 11$(( 11234567899 ))95' '11 234 678 95' 517 518 check_results split_arith 519} 520 521atf_test_case read_split 522read_split_head() 523{ 524 atf_set "descr" "Checks that field splitting works for the read" \ 525 "built-in utility" 526} 527# 528# CAUTION: There are literal <tab> chars in the following test. 529# It is important that they be retained as is (the ones in the data 530# and results - those used for test formatting are immaterial). 531# 532read_split_body() 533{ 534 DATA=" aaa bbb:ccc ddd+eee fff:ggg+hhh " # CAUTION: tabs! 535 536 TEST=0 537 538 check "unset IFS; printf '%s\n' '${DATA}' | { 539 read a b c d e f g h || printf 'FAIL:%d' \"\$?\" && 540 printf '<%s>' "'"$a" "$b" "$c" "$d" "$e" "$f" "$g" "$h"; }' \ 541 '<aaa><bbb:ccc><ddd+eee><fff:ggg+hhh><><><><>' 542 543 check "unset IFS; printf '%s\n' '${DATA}' | { 544 read x || printf 'FAIL:%d' \"\$?\" && 545 printf '<%s>' "'"$x"; }' \ 546 '<aaa bbb:ccc ddd+eee fff:ggg+hhh>' 547 548 check "IFS=; printf '%s\n' '${DATA}' | { 549 read a b c d e f g h || printf 'FAIL:%d' \"\$?\" && 550 printf '<%s>' "'"$a" "$b" "$c" "$d" "$e" "$f" "$g" "$h"; }' \ 551 "<${DATA}><><><><><><><>" 552 553 check "IFS=' '; printf '%s\n' '${DATA}' | { 554 read a b c d e f g h || printf 'FAIL:%d' \"\$?\" && 555 printf '<%s>' "'"$a" "$b" "$c" "$d" "$e" "$f" "$g" "$h"; }' \ 556 '<aaa><bbb:ccc><ddd+eee><fff:ggg+hhh><><><><>' 557 558 check "IFS=':'; printf '%s\n' '${DATA}' | { 559 read a b c d e f g h || printf 'FAIL:%d' \"\$?\" && 560 printf '<%s>' "'"$a" "$b" "$c" "$d" "$e" "$f" "$g" "$h"; }' \ 561 '< aaa bbb><ccc ddd+eee fff><ggg+hhh ><><><><><>' 562 563 check "IFS=': '; printf '%s\n' '${DATA}' | { 564 read a b c d e f g h || printf 'FAIL:%d' \"\$?\" && 565 printf '<%s>' "'"$a" "$b" "$c" "$d" "$e" "$f" "$g" "$h"; }' \ 566 '<aaa><bbb><ccc><ddd+eee fff><ggg+hhh ><><><>' 567 568 check "IFS=': '; printf '%s\n' '${DATA}' | { 569 read a b c d e f g h || printf 'FAIL:%d' \"\$?\" && 570 printf '<%s>' "'"$a" "$b" "$c" "$d" "$e" "$f" "$g" "$h"; }' \ 571 '< aaa bbb><ccc ddd+eee><fff><ggg+hhh>< ><><><>' 572 573 check "IFS='+'; printf '%s\n' '${DATA}' | { 574 read a b c d e f g h || printf 'FAIL:%d' \"\$?\" && 575 printf '<%s>' "'"$a" "$b" "$c" "$d" "$e" "$f" "$g" "$h"; }' \ 576 '< aaa bbb:ccc ddd><eee fff:ggg><hhh ><><><><><>' 577 578 check "IFS=' +'; printf '%s\n' '${DATA}' | { 579 read a b c d e f g h || printf 'FAIL:%d' \"\$?\" && 580 printf '<%s>' "'"$a" "$b" "$c" "$d" "$e" "$f" "$g" "$h"; }' \ 581 '<aaa><bbb:ccc><ddd><eee fff:ggg><hhh ><><><>' 582 583 check "IFS='+ '; printf '%s\n' '${DATA}' | { 584 read a b c d e f g h || printf 'FAIL:%d' \"\$?\" && 585 printf '<%s>' "'"$a" "$b" "$c" "$d" "$e" "$f" "$g" "$h"; }' \ 586 '< aaa bbb:ccc ddd><eee><fff:ggg><hhh>< ><><><>' 587 588 # This tests the bug from PR bin/57849 (which existed about 2 days) 589 # It also tests that a var-assign before read does not corrupt the 590 # value of the var in the executing shell environment 591 check "IFS='+'; printf '%s\n' '${DATA}' | { 592 IFS=: read a b c d e f g h || printf 'FAIL:%d' \"\$?\" && 593 printf '<%s>' "'"$IFS" "$a" "$b" "$c" "$d" "$e" "$f" "$g" "$h"; }' \ 594 '<+>< aaa bbb><ccc ddd+eee fff><ggg+hhh ><><><><><>' 595 596 check "IFS='+'; printf '%s\n' '${DATA}' | { 597 IFS= read a b c d e f g h || printf 'FAIL:%d' \"\$?\" && 598 printf '<%s>' "'"$IFS" "$a" "$b" "$c" "$d" "$e" "$f" "$g" "$h"; }' \ 599 "<+><${DATA}><><><><><><><>" 600 601 # This doesn't really belong here, just tests that EOF works... 602 # (and that read sets unused vars to '', doesn't leave them unset) 603 check "unset IFS; set -u; 604 read a b c d e f g h </dev/null || printf 'FAIL:%d' \"\$?\" && 605 printf '<%s>' "'"$a" "$b" "$c" "$d" "$e" "$f" "$g" "$h"' \ 606 "FAIL:1<><><><><><><><>" 607 608 # And a similar one where EOF follows some data (which is read) 609 check "unset IFS; set -u; printf 'a b c' | { 610 read a b c d e f g h || printf 'FAIL:%d' \"\$?\" && 611 printf '<%s>' "'"$a" "$b" "$c" "$d" "$e" "$f" "$g" "$h"; }' \ 612 "FAIL:1<a><b><c><><><><><>" 613 614 check_results read_split 615} 616 617atf_init_test_cases() 618{ 619 atf_add_test_case for 620 atf_add_test_case default_val 621 atf_add_test_case replacement_val 622 atf_add_test_case ifs_alpha 623 atf_add_test_case quote 624 atf_add_test_case dollar_at 625 atf_add_test_case ifs 626 atf_add_test_case var_length 627 atf_add_test_case split_arith 628 atf_add_test_case read_split 629} 630