Changeset View
Changeset View
Standalone View
Standalone View
bin/sh/t_fsplit.sh
Property | Old Value | New Value |
---|---|---|
File Mode | 100755 | 100644 |
# $NetBSD: t_fsplit.sh,v 1.4 2016/03/27 14:50:01 christos Exp $ | # $NetBSD: t_fsplit.sh,v 1.7 2017/06/24 11:06:17 kre Exp $ | ||||
# | # | ||||
# Copyright (c) 2007-2016 The NetBSD Foundation, Inc. | # Copyright (c) 2007-2016 The NetBSD Foundation, Inc. | ||||
# All rights reserved. | # All rights reserved. | ||||
# | # | ||||
# Redistribution and use in source and binary forms, with or without | # Redistribution and use in source and binary forms, with or without | ||||
# modification, are permitted provided that the following conditions | # modification, are permitted provided that the following conditions | ||||
# are met: | # are met: | ||||
# 1. Redistributions of source code must retain the above copyright | # 1. Redistributions of source code must retain the above copyright | ||||
Show All 18 Lines | |||||
# The standard | # The standard | ||||
# http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html | # http://www.opengroup.org/onlinepubs/009695399/utilities/xcu_chap02.html | ||||
# explains (section 2.6) that Field splitting should be performed on the | # explains (section 2.6) that Field splitting should be performed on the | ||||
# result of variable expansions. | # result of variable expansions. | ||||
# In particular this means that in ${x-word}, 'word' must be expanded as if | # In particular this means that in ${x-word}, 'word' must be expanded as if | ||||
# the "${x-" and "}" were absent from the input line. | # the "${x-" and "}" were absent from the input line. | ||||
# | # | ||||
# So: sh -c 'set ${x-a b c}; echo $#' should give 3. | # So: sh -c 'set ${x-a b c}; echo $#' should give 3. | ||||
# and: sh -c 'set -- ${x-}' echo $#' shold give 0 | # and: sh -c 'set -- ${x-}' echo $#' should give 0 | ||||
# | # | ||||
# the implementation of "sh" to test | # the implementation of "sh" to test | ||||
: ${TEST_SH:="/bin/sh"} | : ${TEST_SH:="/bin/sh"} | ||||
nl=' | nl=' | ||||
' | ' | ||||
Show All 29 Lines | then | ||||
else | else | ||||
atf_fail \ | atf_fail \ | ||||
"TEST ${TEST} '$1' failed ($STATUS): expected [$2], found [$result]" | "TEST ${TEST} '$1' failed ($STATUS): expected [$2], found [$result]" | ||||
fi | fi | ||||
elif [ "${STATUS}" != 0 ] | elif [ "${STATUS}" != 0 ] | ||||
then | then | ||||
atf_fail "TEST ${TEST} '$1' failed ($STATUS)" | atf_fail "TEST ${TEST} '$1' failed ($STATUS)" | ||||
fi | fi | ||||
return 0 | |||||
} | } | ||||
atf_test_case for | atf_test_case for | ||||
for_head() { | for_head() { | ||||
atf_set "descr" "Checks field splitting in for loops" | atf_set "descr" "Checks field splitting in for loops" | ||||
} | } | ||||
for_body() { | for_body() { | ||||
unset x | unset x | ||||
▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | check 'for i in ${x-a b c}; do echo "z${i}z"; done' \ | ||||
'zaz zbz zcz' | 'zaz zbz zcz' | ||||
check 'for i in ${x-"a b" c}; do echo "z${i}z"; done' \ | check 'for i in ${x-"a b" c}; do echo "z${i}z"; done' \ | ||||
'za bz zcz' | 'za bz zcz' | ||||
check 'for i in ${x-"a ${x-b c}" d}; do echo "z${i}z"; done' \ | check 'for i in ${x-"a ${x-b c}" d}; do echo "z${i}z"; done' \ | ||||
'za b cz zdz' | 'za b cz zdz' | ||||
check 'for i in ${x-a ${x-b c} d}; do echo "z${i}z"; done' \ | check 'for i in ${x-a ${x-b c} d}; do echo "z${i}z"; done' \ | ||||
'zaz zbz zcz zdz' | 'zaz zbz zcz zdz' | ||||
# I am not sure these two are correct, the rules on quoting word | # I am not sure the first of these two is correct, the rules on | ||||
# in ${var-word} are peculiar, and hard to fathom... | # quoting word in ${var-word} are peculiar, and hard to fathom... | ||||
# They are what the NetBSD shell does, and bash, not the freebsd shell | # It is what the NetBSD shell does, and bash, not the freebsd shell | ||||
# (as of Mar 1, 2016) | # and not ksh93 (as of Mar 1, 2016, and still in June 2017) | ||||
# The likely correct interp of the next one is 'za bz zcz zdz' | |||||
# That and the "should be" below are correct as of POSIX 7 TC2 | |||||
# But this is going to change to "unspecified" in POSIX 8 | |||||
# (resolution of bug 221) so instead of being incorrect (as now) | |||||
# the NetBSD shell will simply be implementing is version | |||||
# of unspecified behaviour. Just beware that shells differ, | |||||
# a shell that fails this test is not incorrect because of it. | |||||
# should be: uuuu qqqqqq uuu q uuu (unquoted/quoted) no nesting. | |||||
check 'for i in ${x-"a ${x-"b c"}" d}; do echo "z${i}z"; done' \ | check 'for i in ${x-"a ${x-"b c"}" d}; do echo "z${i}z"; done' \ | ||||
'za b cz zdz' | 'za b cz zdz' | ||||
check 'for i in ${x-a ${x-"b c"} d}; do echo "z${i}z"; done' \ | check 'for i in ${x-a ${x-"b c"} d}; do echo "z${i}z"; done' \ | ||||
'zaz zb cz zdz' | 'zaz zb cz zdz' | ||||
} | } | ||||
atf_test_case replacement_val | atf_test_case replacement_val | ||||
replacement_val_head() { | replacement_val_head() { | ||||
▲ Show 20 Lines • Show All 49 Lines • ▼ Show 20 Lines | replacement_val_body() { | ||||
# and validate that the replacement can be used as expected | # and validate that the replacement can be used as expected | ||||
check 'x=BOGUS; for i in ${x+a b c}; do echo "z${i}z"; done'\ | check 'x=BOGUS; for i in ${x+a b c}; do echo "z${i}z"; done'\ | ||||
'zaz zbz zcz' | 'zaz zbz zcz' | ||||
check 'x=BOGUS; for i in ${x+"a b" c}; do echo "z${i}z"; done'\ | check 'x=BOGUS; for i in ${x+"a b" c}; do echo "z${i}z"; done'\ | ||||
'za bz zcz' | 'za bz zcz' | ||||
check 'x=BOGUS; for i in ${x+"a ${x+b c}" d}; do echo "z${i}z"; done'\ | check 'x=BOGUS; for i in ${x+"a ${x+b c}" d}; do echo "z${i}z"; done'\ | ||||
'za b cz zdz' | 'za b cz zdz' | ||||
# see the (extended) comment in the default_val test. This will be | |||||
# unspecified, hence we are OK (will be) but expect differences. | |||||
# also incorrect: uuuu qqqqqq uuu q uuu | |||||
check 'x=BOGUS; for i in ${x+"a ${x+"b c"}" d}; do echo "z${i}z"; done'\ | check 'x=BOGUS; for i in ${x+"a ${x+"b c"}" d}; do echo "z${i}z"; done'\ | ||||
'za b cz zdz' | 'za b cz zdz' | ||||
check 'x=BOGUS; for i in ${x+a ${x+"b c"} d}; do echo "z${i}z"; done'\ | check 'x=BOGUS; for i in ${x+a ${x+"b c"} d}; do echo "z${i}z"; done'\ | ||||
'zaz zb cz zdz' | 'zaz zb cz zdz' | ||||
check 'x=BOGUS; for i in ${x+a ${x+b c} d}; do echo "z${i}z"; done'\ | check 'x=BOGUS; for i in ${x+a ${x+b c} d}; do echo "z${i}z"; done'\ | ||||
'zaz zbz zcz zdz' | 'zaz zbz zcz zdz' | ||||
} | } | ||||
atf_test_case ifs_alpha | atf_test_case ifs_alpha | ||||
ifs_alpha_head() { | ifs_alpha_head() { | ||||
atf_set "descr" "Checks that field splitting works with alphabetic" \ | atf_set "descr" "Checks that field splitting works with alphabetic" \ | ||||
"characters" | "characters" | ||||
} | } | ||||
ifs_alpha_body() { | ifs_alpha_body() { | ||||
unset x | unset x | ||||
TEST=0 | TEST=0 | ||||
# repeat with an alphabetic in IFS | # repeat with an alphabetic in IFS | ||||
check 'IFS=q; set ${x-aqbqc}; echo $#' 3 | check 'IFS=q; set ${x-aqbqc}; echo $#' 3 | ||||
check 'IFS=q; for i in ${x-aqbqc}; do echo "z${i}z"; done' \ | check 'IFS=q; for i in ${x-aqbqc}; do echo "z${i}z"; done' \ | ||||
'zaz zbz zcz' | 'zaz zbz zcz' | ||||
check 'IFS=q; for i in ${x-"aqb"qc}; do echo "z${i}z"; done' \ | check 'IFS=q; for i in ${x-"aqb"qc}; do echo "z${i}z"; done' \ | ||||
'zaqbz zcz' | 'zaqbz zcz' | ||||
check 'IFS=q; for i in ${x-"aq${x-bqc}"qd}; do echo "z${i}z"; done' \ | check 'IFS=q; for i in ${x-"aq${x-bqc}"qd}; do echo "z${i}z"; done' \ | ||||
'zaqbqcz zdz' | 'zaqbqcz zdz' | ||||
# this is another almost certainly incorrect expectation | |||||
# (but again, see comment in default_val test - becoming unspecified.) | |||||
# uu qqqqqq uuu q uu (quoted/unquoted) | |||||
check 'IFS=q; for i in ${x-"aq${x-"bqc"}"qd}; do echo "z${i}z"; done' \ | check 'IFS=q; for i in ${x-"aq${x-"bqc"}"qd}; do echo "z${i}z"; done' \ | ||||
'zaqbqcz zdz' | 'zaqbqcz zdz' | ||||
check 'IFS=q; for i in ${x-aq${x-"bqc"}qd}; do echo "z${i}z"; done' \ | check 'IFS=q; for i in ${x-aq${x-"bqc"}qd}; do echo "z${i}z"; done' \ | ||||
'zaz zbqcz zdz' | 'zaz zbqcz zdz' | ||||
} | } | ||||
atf_test_case quote | atf_test_case quote | ||||
quote_head() { | quote_head() { | ||||
atf_set "descr" "Checks that field splitting works with multi-word" \ | atf_set "descr" "Checks that field splitting works with multi-word" \ | ||||
"fields" | "fields" | ||||
} | } | ||||
quote_body() { | quote_body() { | ||||
unset x | unset x | ||||
TEST=0 | TEST=0 | ||||
# Some quote propagation checks | # Some quote propagation checks | ||||
check 'set "${x-a b c}"; echo $#' 1 | check 'set "${x-a b c}"; echo $#' 1 | ||||
# this is another almost certainly incorrect expectation | |||||
# (but again, see comment in default_val test - becoming unspecified.) | |||||
# qqqq uuu qqq (quoted/unquoted) $1 is a $# is 2 | |||||
check 'set "${x-"a b" c}"; echo $1' 'a b c' | check 'set "${x-"a b" c}"; echo $1' 'a b c' | ||||
check 'for i in "${x-a b c}"; do echo "z${i}z"; done' 'za b cz' | check 'for i in "${x-a b c}"; do echo "z${i}z"; done' 'za b cz' | ||||
} | } | ||||
atf_test_case dollar_at | atf_test_case dollar_at | ||||
dollar_at_head() { | dollar_at_head() { | ||||
atf_set "descr" "Checks that field splitting works when expanding" \ | atf_set "descr" "Checks that field splitting works when expanding" \ | ||||
"\$@" | "\$@" | ||||
} | } | ||||
▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | atf_set "descr" "Checks that field splitting works when expanding" \ | ||||
"a variable's length" | "a variable's length" | ||||
} | } | ||||
var_length_body() { | var_length_body() { | ||||
TEST=0 | TEST=0 | ||||
long=12345678123456781234567812345678 | long=12345678123456781234567812345678 | ||||
long=$long$long$long$long | long=$long$long$long$long | ||||
export long | export long | ||||
unset x | |||||
# first test that the test method works... | # first test that the test method works... | ||||
check 'set -u; : ${long}; echo ${#long}' '128' | check 'set -u; : ${long}; echo ${#long}' '128' | ||||
# Check that we apply IFS to ${#var} | # Check that we apply IFS to ${#var} | ||||
check 'echo ${#long}; IFS=2; echo ${#long}; set 1 ${#long};echo $#' \ | check 'echo ${#long}; IFS=2; echo ${#long}; set 1 ${#long};echo $#' \ | ||||
'128 1 8 3' | '128 1 8 3' | ||||
check 'IFS=2; set ${x-${#long}}; IFS=" "; echo $* $#' '1 8 2' | check 'IFS=2; set ${x-${#long}}; IFS=" "; echo $* $#' '1 8 2' | ||||
check 'IFS=2; set ${x-"${#long}"}; IFS=" "; echo $* $#' '128 1' | check 'IFS=2; set ${x-"${#long}"}; IFS=" "; echo $* $#' '128 1' | ||||
check 'IFS=2; set "${x-${#long}}"; IFS=" "; echo $* $#' '128 1' | |||||
check 'IFS=2; set ${x-${#long}}; : ; echo $* $#' '1 8 ' | |||||
check 'IFS=2; set ${x-${#long}}; : ; echo $* "$#"' '1 8 2' | |||||
check 'IFS=2; set ${x-${#long}}; : ; echo "$*" "$#"' '128 2' | |||||
check 'IFS=2; set ${x-${#long}}; : ; echo "$@" "$#"' '1 8 2' | |||||
} | } | ||||
atf_test_case split_arith | |||||
split_arith_head() { | |||||
atf_set "descr" "Checks that field splitting works when expanding" \ | |||||
"the results from arithmetic" | |||||
} | |||||
split_arith_body() { | |||||
TEST=0 | |||||
# Check that we apply IFS to $(( expr )) | |||||
# Note: we do not check the actual arithmetic operations here | |||||
# (there is a separate test just for that) so we just enter | |||||
# the "answer" inside $(( )) ... also makes it easier to visualise | |||||
check 'IFS=5; echo $(( 123456789 ))' '1234 6789' | |||||
check 'IFS=5; echo "$(( 123456789 ))"' '123456789' | |||||
check 'IFS=37; echo $(( 123456789 ))' '12 456 89' | |||||
check 'IFS=37; echo "$(( 123456789 ))"' '123456789' | |||||
check 'IFS=159; echo $(( 123456789 ))' ' 234 678' | |||||
check 'IFS=5; set -- $(( 123456789 )); echo $#: $1 $2 $3 $4' \ | |||||
'2: 1234 6789' | |||||
check 'IFS=5; set -- "$(( 123456789 ))"; echo $#: $1 $2 $3 $4' \ | |||||
'1: 1234 6789' # go ahead: explain it! | |||||
check 'IFS=5; set -- "$(( 123456789 ))"; echo "$#: $1 $2 $3 $4"' \ | |||||
'1: 123456789 ' # ah! | |||||
check 'IFS=37; set -- $(( 123456789 )); echo $#: $1 $2 $3 $4' \ | |||||
' : 12 456 89' # Tricky! | |||||
check 'IFS=5; set -- $(( 123456789 )); echo $#: $*' \ | |||||
'2: 1234 6789' | |||||
check 'IFS=47; set -- $(( 123456789 )); echo $#: $*' \ | |||||
'3: 123 56 89' | |||||
check 'IFS=5; set -- $(( 123456789 )); echo "$#: $*"' \ | |||||
'2: 123456789' | |||||
check 'IFS=37; set -- $(( 123456789 )); echo "$#: $*"' \ | |||||
'3: 123456389' # [sic] | |||||
check 'IFS=5; set -- $(( 123456789 )); echo $#: $@' \ | |||||
'2: 1234 6789' | |||||
check 'IFS=47; set -- $(( 123456789 )); echo $#: $@' \ | |||||
'3: 123 56 89' | |||||
check 'IFS=5; set -- $(( 123456789 )); echo "$#: $@"' \ | |||||
'2: 1234 6789' | |||||
check 'IFS=37; set -- $(( 123456789 )); echo "$#: $*"' \ | |||||
'3: 123456389' # [sic] | |||||
check 'IFS=1; set -- $(( 1111 )); echo "$#:" $*' '4: ' | |||||
check 'IFS=" 1"; set -- $(( 1231231231 )); echo "$#: $*"' \ | |||||
'4: 23 23 23' | |||||
check 'IFS="1 "; set -- $(( 1231231231 )); echo "$#: $*"' \ | |||||
'4: 123123123' | |||||
check 'IFS=5; echo 5$(( 123456789 ))5' '51234 67895' | |||||
check 'IFS=37; echo 73$(( 123456789 ))37' '7312 456 8937' | |||||
check 'IFS=159; echo 11$(( 123456789 ))95' '11 234 678 95' | |||||
check 'IFS="159 "; echo 11$(( 123456789 ))95' '11 234 678 95' | |||||
check 'IFS="159 "; echo 11$(( 11234567899 ))95' '11 234 678 95' | |||||
} | |||||
atf_init_test_cases() { | atf_init_test_cases() { | ||||
atf_add_test_case for | atf_add_test_case for | ||||
atf_add_test_case default_val | atf_add_test_case default_val | ||||
atf_add_test_case replacement_val | atf_add_test_case replacement_val | ||||
atf_add_test_case ifs_alpha | atf_add_test_case ifs_alpha | ||||
atf_add_test_case quote | atf_add_test_case quote | ||||
atf_add_test_case dollar_at | atf_add_test_case dollar_at | ||||
atf_add_test_case ifs | atf_add_test_case ifs | ||||
atf_add_test_case var_length | atf_add_test_case var_length | ||||
atf_add_test_case split_arith | |||||
} | } |