1 1.23 kre # $NetBSD: t_expand.sh,v 1.23 2023/03/06 05:54:54 kre Exp $ 2 1.1 jruoho # 3 1.1 jruoho # Copyright (c) 2007, 2009 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.6 christos # the implementation of "sh" to test 28 1.6 christos : ${TEST_SH:="/bin/sh"} 29 1.1 jruoho 30 1.1 jruoho # 31 1.1 jruoho # This file tests the functions in expand.c. 32 1.1 jruoho # 33 1.1 jruoho 34 1.1 jruoho delim_argv() { 35 1.1 jruoho str= 36 1.1 jruoho while [ $# -gt 0 ]; do 37 1.1 jruoho if [ -z "${str}" ]; then 38 1.1 jruoho str=">$1<" 39 1.1 jruoho else 40 1.1 jruoho str="${str} >$1<" 41 1.1 jruoho fi 42 1.2 ast shift 43 1.1 jruoho done 44 1.1 jruoho echo ${str} 45 1.1 jruoho } 46 1.1 jruoho 47 1.1 jruoho atf_test_case dollar_at 48 1.1 jruoho dollar_at_head() { 49 1.21 kre atf_set descr "Somewhere between 2.0.2 and 3.0 the expansion" \ 50 1.1 jruoho "of the \$@ variable had been broken. Check for" \ 51 1.1 jruoho "this behavior." 52 1.1 jruoho } 53 1.1 jruoho dollar_at_body() { 54 1.1 jruoho # This one should work everywhere. 55 1.6 christos atf_check -s exit:0 -o inline:' EOL\n' -e empty \ 56 1.6 christos ${TEST_SH} -c 'echo "" "" | '" sed 's,\$,EOL,'" 57 1.1 jruoho 58 1.1 jruoho # This code triggered the bug. 59 1.6 christos atf_check -s exit:0 -o inline:' EOL\n' -e empty \ 60 1.6 christos ${TEST_SH} -c 'set -- "" ""; echo "$@" | '" sed 's,\$,EOL,'" 61 1.6 christos 62 1.6 christos atf_check -s exit:0 -o inline:'0\n' -e empty ${TEST_SH} -c \ 63 1.6 christos 'set -- -; shift; n_arg() { echo $#; }; n_arg "$@"' 64 1.1 jruoho } 65 1.1 jruoho 66 1.20 kre atf_test_case dollar_at_unquoted_or_conditional 67 1.20 kre dollar_at_unquoted_or_conditional_head() { 68 1.21 kre atf_set descr 'Sometime during 2013 the expansion of "${1+$@}"' \ 69 1.20 kre ' (where $1 and $2 (and maybe more) are set)' \ 70 1.20 kre ' seems to have broken. Check for this bug.' 71 1.20 kre } 72 1.20 kre dollar_at_unquoted_or_conditional_body() { 73 1.20 kre 74 1.20 kre atf_check -s exit:0 -o inline:'a\na\nb\nb\n' -e empty \ 75 1.20 kre ${TEST_SH} -c 'set -- "a a" "b b"; printf %s\\n $@' 76 1.20 kre atf_check -s exit:0 -o inline:'a\na\nb\nb\n' -e empty \ 77 1.20 kre ${TEST_SH} -c 'set -- "a a" "b b"; printf %s\\n ${1+$@}' 78 1.20 kre atf_check -s exit:0 -o inline:'a a\nb b\n' -e empty \ 79 1.20 kre ${TEST_SH} -c 'set -- "a a" "b b"; printf %s\\n "$@"' 80 1.20 kre atf_check -s exit:0 -o inline:'a a\nb b\n' -e empty \ 81 1.20 kre ${TEST_SH} -c 'set -- "a a" "b b"; printf %s\\n ${1+"$@"}' 82 1.20 kre 83 1.20 kre # This is the one that fails when the bug is present 84 1.20 kre atf_check -s exit:0 -o inline:'a a\nb b\n' -e empty \ 85 1.20 kre ${TEST_SH} -c 'set -- "a a" "b b"; printf %s\\n "${1+$@}"' 86 1.20 kre } 87 1.20 kre 88 1.1 jruoho atf_test_case dollar_at_with_text 89 1.1 jruoho dollar_at_with_text_head() { 90 1.21 kre atf_set descr "Test \$@ expansion when it is surrounded by text" \ 91 1.1 jruoho "within the quotes. PR bin/33956." 92 1.1 jruoho } 93 1.1 jruoho dollar_at_with_text_body() { 94 1.6 christos 95 1.6 christos cat <<'EOF' > h-f1 96 1.6 christos 97 1.6 christos delim_argv() { 98 1.6 christos str= 99 1.6 christos while [ $# -gt 0 ]; do 100 1.6 christos if [ -z "${str}" ]; then 101 1.6 christos str=">$1<" 102 1.6 christos else 103 1.6 christos str="${str} >$1<" 104 1.6 christos fi 105 1.6 christos shift 106 1.6 christos done 107 1.6 christos echo "${str}" 108 1.6 christos } 109 1.6 christos 110 1.6 christos EOF 111 1.6 christos cat <<'EOF' > h-f2 112 1.6 christos 113 1.6 christos delim_argv() { 114 1.6 christos str= 115 1.6 christos while [ $# -gt 0 ]; do 116 1.6 christos 117 1.6 christos str="${str}${str:+ }>$1<" 118 1.6 christos shift 119 1.6 christos 120 1.6 christos done 121 1.6 christos echo "${str}" 122 1.6 christos } 123 1.6 christos 124 1.6 christos EOF 125 1.6 christos 126 1.6 christos chmod +x h-f1 h-f2 127 1.6 christos 128 1.6 christos for f in 1 2 129 1.6 christos do 130 1.6 christos atf_check -s exit:0 -o inline:'\n' -e empty ${TEST_SH} -c \ 131 1.20 kre ". ./h-f${f}; "'set -- ; delim_argv $@' 132 1.20 kre atf_check -s exit:0 -o inline:'\n' -e empty ${TEST_SH} -c \ 133 1.6 christos ". ./h-f${f}; "'set -- ; delim_argv "$@"' 134 1.6 christos atf_check -s exit:0 -o inline:'>foobar<\n' -e empty \ 135 1.6 christos ${TEST_SH} -c \ 136 1.6 christos ". ./h-f${f}; "'set -- ; delim_argv "foo$@bar"' 137 1.20 kre atf_check -s exit:0 -o inline:'>foobar<\n' -e empty \ 138 1.20 kre ${TEST_SH} -c \ 139 1.20 kre ". ./h-f${f}; "'set -- ; delim_argv foo"$@"bar' 140 1.6 christos atf_check -s exit:0 -o inline:'>foo bar<\n' -e empty \ 141 1.6 christos ${TEST_SH} -c \ 142 1.6 christos ". ./h-f${f}; "'set -- ; delim_argv "foo $@ bar"' 143 1.20 kre atf_check -s exit:0 -o inline:'>foo bar<\n' -e empty \ 144 1.20 kre ${TEST_SH} -c \ 145 1.20 kre ". ./h-f${f}; "'set -- ; delim_argv foo" $@ "bar' 146 1.6 christos 147 1.6 christos atf_check -s exit:0 -o inline:'>a< >b< >c<\n' -e empty \ 148 1.6 christos ${TEST_SH} -c \ 149 1.6 christos ". ./h-f${f}; "'set -- a b c; delim_argv "$@"' 150 1.20 kre 151 1.6 christos atf_check -s exit:0 -o inline:'>fooa< >b< >cbar<\n' -e empty \ 152 1.6 christos ${TEST_SH} -c \ 153 1.6 christos ". ./h-f${f}; "'set -- a b c; delim_argv "foo$@bar"' 154 1.20 kre 155 1.6 christos atf_check -s exit:0 -o inline:'>foo a< >b< >c bar<\n' -e empty \ 156 1.6 christos ${TEST_SH} -c \ 157 1.6 christos ". ./h-f${f}; "'set -- a b c; delim_argv "foo $@ bar"' 158 1.6 christos done 159 1.1 jruoho } 160 1.1 jruoho 161 1.20 kre atf_test_case dollar_at_empty_and_conditional 162 1.20 kre dollar_at_empty_and_conditional_head() { 163 1.21 kre atf_set descr 'Test $@ expansion when there are no args, and ' \ 164 1.20 kre 'when conditionally expanded.' 165 1.20 kre } 166 1.20 kre dollar_at_empty_and_conditional_body() { 167 1.20 kre 168 1.20 kre # same task, implementation different from previous, 169 1.20 kre # that these work is also a test... 170 1.20 kre 171 1.20 kre cat <<'EOF' > h-f3 172 1.20 kre 173 1.20 kre delim_argv() { 174 1.20 kre str= 175 1.20 kre for Arg; do 176 1.20 kre str="${str:+${str} }>${Arg}<" 177 1.20 kre done 178 1.20 kre printf '%s\n' "${str}" 179 1.20 kre } 180 1.20 kre 181 1.20 kre EOF 182 1.20 kre 183 1.20 kre chmod +x h-f3 184 1.20 kre 185 1.20 kre # in these we give printf a first arg of "", which makes 186 1.20 kre # the first output char be \n, then the $@ produces anything else 187 1.20 kre # (we need to make sure we don't end up with: 188 1.20 kre # printf %s\\n 189 1.20 kre # -- that is, no operands for the %s, that's unspecified) 190 1.20 kre 191 1.20 kre atf_check -s exit:0 -o inline:'\na a\nb b\n' -e empty \ 192 1.20 kre ${TEST_SH} -c 'set -- "a a" "b b"; printf %s\\n "" "$@"' 193 1.20 kre atf_check -s exit:0 -o inline:'\n' -e empty \ 194 1.20 kre ${TEST_SH} -c 'set -- ; printf %s\\n "" "$@"' 195 1.20 kre atf_check -s exit:0 -o inline:'\n' -e empty \ 196 1.20 kre ${TEST_SH} -c 'set -- ; printf %s\\n ""${1+"$@"}' 197 1.20 kre atf_check -s exit:0 -o inline:'\n' -e empty \ 198 1.20 kre ${TEST_SH} -c 'set -- ; printf %s\\n """${1+$@}"' 199 1.20 kre 200 1.20 kre # in these we prefix (concat) the $@ expansion with "" to make 201 1.20 kre # sure there is always at least one arg for the %s in printf 202 1.20 kre # If there is anything else there, the prepended nothing vanishes 203 1.20 kre atf_check -s exit:0 -o inline:'a a\nb b\n' -e empty \ 204 1.20 kre ${TEST_SH} -c 'set -- "a a" "b b"; printf %s\\n """$@"' 205 1.20 kre atf_check -s exit:0 -o inline:'\n' -e empty \ 206 1.20 kre ${TEST_SH} -c 'set -- ; printf %s\\n """$@"' 207 1.20 kre atf_check -s exit:0 -o inline:'\n' -e empty \ 208 1.20 kre ${TEST_SH} -c 'set -- ; printf %s\\n ""${1+"$@"}' 209 1.20 kre atf_check -s exit:0 -o inline:'\n' -e empty \ 210 1.20 kre ${TEST_SH} -c 'set -- ; printf %s\\n """${1+$@}"' 211 1.20 kre 212 1.20 kre atf_check -s exit:0 -o inline:'>a< >b< >c<\n' -e empty ${TEST_SH} -c \ 213 1.20 kre '. ./h-f3; set -- a b c; delim_argv "${1+$@}"' 214 1.20 kre atf_check -s exit:0 -o inline:'>a< >b< >c<\n' -e empty ${TEST_SH} -c \ 215 1.20 kre '. ./h-f3; set -- a b c; delim_argv ${1+"$@"}' 216 1.20 kre atf_check -s exit:0 -o inline:'>fooa< >b< >cbar<\n' -e empty \ 217 1.20 kre ${TEST_SH} -c \ 218 1.20 kre '. ./h-f3; set -- a b c; delim_argv "foo${1+$@}bar"' 219 1.20 kre atf_check -s exit:0 -o inline:'>fooa< >b< >cbar<\n' -e empty \ 220 1.20 kre ${TEST_SH} -c \ 221 1.20 kre '. ./h-f3; set -- a b c; delim_argv foo${1+"$@"}bar' 222 1.20 kre atf_check -s exit:0 -o inline:'>foo a< >b< >c bar<\n' -e empty \ 223 1.20 kre ${TEST_SH} -c \ 224 1.20 kre '. ./h-f3; set -- a b c; delim_argv "foo ${1+$@} bar"' 225 1.20 kre atf_check -s exit:0 -o inline:'>foo a< >b< >c bar<\n' -e empty \ 226 1.20 kre ${TEST_SH} -c \ 227 1.20 kre '. ./h-f3; set -- a b c; delim_argv "foo "${1+"$@"}" bar"' 228 1.20 kre 229 1.20 kre # since $1 is not set, we get nothing ($@ is irrelevant) 230 1.20 kre # (note here we are not using printf, don't need to guarantee an arg) 231 1.20 kre atf_check -s exit:0 -o inline:'\n' -e empty ${TEST_SH} -c \ 232 1.20 kre '. ./h-f3; set -- ; delim_argv ${1+"$@"}' 233 1.20 kre 234 1.20 kre # here since $1 is not set we get "" as the special $@ properties 235 1.20 kre # do not apply, and ${foo+anything} generates nothing if foo is unset 236 1.20 kre atf_check -s exit:0 -o inline:'><\n' -e empty ${TEST_SH} -c \ 237 1.20 kre '. ./h-f3; set -- ; delim_argv "${1+$@}"' 238 1.20 kre 239 1.20 kre # in this one we get the initial "" followed by nothing 240 1.20 kre atf_check -s exit:0 -o inline:'><\n' -e empty ${TEST_SH} -c \ 241 1.20 kre '. ./h-f3; set -- ; delim_argv ""${1+"$@"}' 242 1.20 kre # which we verify by changing the "" to X, and including Y 243 1.20 kre atf_check -s exit:0 -o inline:'>X<\n' -e empty ${TEST_SH} -c \ 244 1.20 kre '. ./h-f3; set -- ; delim_argv X${1+"$@"Y}' 245 1.20 kre # and again, done differently (the ${1+...} produces nothing at all 246 1.20 kre atf_check -s exit:0 -o inline:'>X<\n' -e empty ${TEST_SH} -c \ 247 1.20 kre '. ./h-f3; set -- ; delim_argv X ${1+"$@"}' 248 1.20 kre # in these two we get the initial "" and then nothing 249 1.20 kre atf_check -s exit:0 -o inline:'><\n' -e empty ${TEST_SH} -c \ 250 1.20 kre '. ./h-f3; set -- ; delim_argv """${1+$@}"' 251 1.20 kre atf_check -s exit:0 -o inline:'>< ><\n' -e empty ${TEST_SH} -c \ 252 1.20 kre '. ./h-f3; set -- ; delim_argv "" "${1+$@}"' 253 1.20 kre 254 1.20 kre # now we repeat all those with $1 set (so we eval the $@) 255 1.20 kre atf_check -s exit:0 -o inline:'>a<\n' -e empty ${TEST_SH} -c \ 256 1.20 kre '. ./h-f3; set -- a ; delim_argv ""${1+"$@"}' 257 1.20 kre atf_check -s exit:0 -o inline:'>XaY<\n' -e empty ${TEST_SH} -c \ 258 1.20 kre '. ./h-f3; set -- a ; delim_argv X${1+"$@"Y}' 259 1.20 kre atf_check -s exit:0 -o inline:'>X< >a<\n' -e empty ${TEST_SH} -c \ 260 1.20 kre '. ./h-f3; set -- a ; delim_argv X ${1+"$@"}' 261 1.20 kre atf_check -s exit:0 -o inline:'>a<\n' -e empty ${TEST_SH} -c \ 262 1.20 kre '. ./h-f3; set -- a ; delim_argv """${1+$@}"' 263 1.20 kre atf_check -s exit:0 -o inline:'>< >a<\n' -e empty ${TEST_SH} -c \ 264 1.20 kre '. ./h-f3; set -- a ; delim_argv "" "${1+$@}"' 265 1.20 kre 266 1.20 kre # now we do all of those again, but testing $X instead of $1 (X set) 267 1.20 kre atf_check -s exit:0 -o inline:'\n' -e empty ${TEST_SH} -c \ 268 1.20 kre '. ./h-f3; X=1; set -- ; delim_argv ${X+"$@"}' 269 1.20 kre atf_check -s exit:0 -o inline:'><\n' -e empty ${TEST_SH} -c \ 270 1.20 kre '. ./h-f3; X=1; set -- ; delim_argv ""${X+"$@"}' 271 1.20 kre atf_check -s exit:0 -o inline:'>X<\n' -e empty ${TEST_SH} -c \ 272 1.20 kre '. ./h-f3; X=1; set -- ; delim_argv X${X+"$@"}' 273 1.20 kre atf_check -s exit:0 -o inline:'>X<\n' -e empty ${TEST_SH} -c \ 274 1.20 kre '. ./h-f3; X=1; set -- ; delim_argv X ${X+"$@"}' 275 1.20 kre atf_check -s exit:0 -o inline:'\n' -e empty ${TEST_SH} -c \ 276 1.20 kre '. ./h-f3; X=1; set -- ; delim_argv "${X+$@}"' 277 1.20 kre atf_check -s exit:0 -o inline:'><\n' -e empty ${TEST_SH} -c \ 278 1.20 kre '. ./h-f3; X=1; set -- ; delim_argv """${X+$@}"' 279 1.20 kre atf_check -s exit:0 -o inline:'><\n' -e empty ${TEST_SH} -c \ 280 1.20 kre '. ./h-f3; X=1; set -- ; delim_argv "" "${X+$@}"' 281 1.20 kre 282 1.20 kre atf_check -s exit:0 -o inline:'>a<\n' -e empty ${TEST_SH} -c \ 283 1.20 kre '. ./h-f3; X=1; set -- a; delim_argv ${X+"$@"}' 284 1.20 kre atf_check -s exit:0 -o inline:'>a< >b<\n' -e empty ${TEST_SH} -c \ 285 1.20 kre '. ./h-f3; X=1; set -- a b; delim_argv ${X+"$@"}' 286 1.20 kre atf_check -s exit:0 -o inline:'>a<\n' -e empty ${TEST_SH} -c \ 287 1.20 kre '. ./h-f3; X=1; set -- a ; delim_argv ""${X+"$@"}' 288 1.20 kre atf_check -s exit:0 -o inline:'>Xa<\n' -e empty ${TEST_SH} -c \ 289 1.20 kre '. ./h-f3; X=1; set -- a ; delim_argv X${X+"$@"}' 290 1.20 kre atf_check -s exit:0 -o inline:'>X< >a<\n' -e empty ${TEST_SH} -c \ 291 1.20 kre '. ./h-f3; X=1; set -- a ; delim_argv X ${X+"$@"}' 292 1.20 kre atf_check -s exit:0 -o inline:'>a<\n' -e empty ${TEST_SH} -c \ 293 1.20 kre '. ./h-f3; X=1; set -- a ; delim_argv """${X+$@}"' 294 1.20 kre atf_check -s exit:0 -o inline:'>a< >b<\n' -e empty ${TEST_SH} -c \ 295 1.20 kre '. ./h-f3; X=1; set -- a b ; delim_argv """${X+$@}"' 296 1.20 kre atf_check -s exit:0 -o inline:'>< >a<\n' -e empty ${TEST_SH} -c \ 297 1.20 kre '. ./h-f3; X=1; set -- a ; delim_argv "" "${X+$@}"' 298 1.20 kre atf_check -s exit:0 -o inline:'>< >a< >b<\n' -e empty ${TEST_SH} -c \ 299 1.20 kre '. ./h-f3; X=1; set -- a b ; delim_argv "" "${X+$@}"' 300 1.20 kre 301 1.20 kre # and again, but testing $X where X is unset 302 1.20 kre atf_check -s exit:0 -o inline:'\n' -e empty ${TEST_SH} -c \ 303 1.20 kre '. ./h-f3; unset X; set -- ; delim_argv ${X+"$@"}' 304 1.20 kre atf_check -s exit:0 -o inline:'><\n' -e empty ${TEST_SH} -c \ 305 1.20 kre '. ./h-f3; unset X; set -- ; delim_argv ""${X+"$@"}' 306 1.20 kre atf_check -s exit:0 -o inline:'>X<\n' -e empty ${TEST_SH} -c \ 307 1.20 kre '. ./h-f3; unset X; set -- ; delim_argv X${X+"$@"}' 308 1.20 kre atf_check -s exit:0 -o inline:'>X<\n' -e empty ${TEST_SH} -c \ 309 1.20 kre '. ./h-f3; unset X; set -- ; delim_argv X ${X+"$@"}' 310 1.20 kre atf_check -s exit:0 -o inline:'><\n' -e empty ${TEST_SH} -c \ 311 1.20 kre '. ./h-f3; unset X; set -- ; delim_argv "${X+$@}"' 312 1.20 kre atf_check -s exit:0 -o inline:'><\n' -e empty ${TEST_SH} -c \ 313 1.20 kre '. ./h-f3; unset X; set -- ; delim_argv """${X+$@}"' 314 1.20 kre atf_check -s exit:0 -o inline:'>< ><\n' -e empty ${TEST_SH} -c \ 315 1.20 kre '. ./h-f3; unset X; set -- ; delim_argv "" "${X+$@}"' 316 1.20 kre atf_check -s exit:0 -o inline:'\n' -e empty ${TEST_SH} -c \ 317 1.20 kre '. ./h-f3; unset X; set -- a; delim_argv ${X+"$@"}' 318 1.20 kre atf_check -s exit:0 -o inline:'\n' -e empty ${TEST_SH} -c \ 319 1.20 kre '. ./h-f3; unset X; set -- a b; delim_argv ${X+"$@"}' 320 1.20 kre atf_check -s exit:0 -o inline:'><\n' -e empty ${TEST_SH} -c \ 321 1.20 kre '. ./h-f3; unset X; set -- a ; delim_argv ""${X+"$@"}' 322 1.20 kre atf_check -s exit:0 -o inline:'>X<\n' -e empty ${TEST_SH} -c \ 323 1.20 kre '. ./h-f3; unset X; set -- a ; delim_argv X${X+"$@"}' 324 1.20 kre atf_check -s exit:0 -o inline:'>X<\n' -e empty ${TEST_SH} -c \ 325 1.20 kre '. ./h-f3; unset X; set -- a ; delim_argv X ${X+"$@"}' 326 1.20 kre atf_check -s exit:0 -o inline:'><\n' -e empty ${TEST_SH} -c \ 327 1.20 kre '. ./h-f3; unset X; set -- a ; delim_argv """${X+$@}"' 328 1.20 kre atf_check -s exit:0 -o inline:'>< ><\n' -e empty ${TEST_SH} -c \ 329 1.20 kre '. ./h-f3; unset X; set -- a; delim_argv "" "${X+$@}"' 330 1.20 kre 331 1.20 kre # a few that stretch belief... 332 1.20 kre 333 1.20 kre atf_check -s exit:0 -o inline:'>a< >b<\n' -e empty ${TEST_SH} -c \ 334 1.20 kre '. ./h-f3; X=1; set -- a b ; delim_argv ${X+${1+"$@"}}' 335 1.20 kre atf_check -s exit:0 -o inline:'\n' -e empty ${TEST_SH} -c \ 336 1.20 kre '. ./h-f3; X=1; set -- ; delim_argv ${X+${1+"$@"}}' 337 1.20 kre atf_check -s exit:0 -o inline:'\n' -e empty ${TEST_SH} -c \ 338 1.20 kre '. ./h-f3; unset X; set -- a b ; delim_argv ${X+${1+"$@"}}' 339 1.20 kre 340 1.20 kre # and now for something completely different 341 1.20 kre 342 1.20 kre atf_check -s exit:0 -o inline:'>a< >b< >ca< >b< >c<\n' -e empty \ 343 1.20 kre ${TEST_SH} -c '. ./h-f3; set -- a b c; delim_argv "$@$@"' 344 1.20 kre atf_check -s exit:0 -o inline:'>a< >b< >ca b c<\n' -e empty \ 345 1.20 kre ${TEST_SH} -c '. ./h-f3; set -- a b c; delim_argv "$@$*"' 346 1.20 kre atf_check -s exit:0 -o inline:'>a b ca< >b< >c<\n' -e empty \ 347 1.20 kre ${TEST_SH} -c '. ./h-f3; set -- a b c; delim_argv "$*$@"' 348 1.20 kre atf_check -s exit:0 -o inline:'>a a++b + ca a< >< >b < > c<\n' \ 349 1.20 kre -e empty ${TEST_SH} -c \ 350 1.20 kre '. ./h-f3; set -- "a a" "" "b " " c"; IFS=+; delim_argv "$*$@"' 351 1.20 kre atf_check -s exit:0 -o inline:'>a< >a< >< >b < > ca+a< >< >b < > c<\n' \ 352 1.20 kre -e empty ${TEST_SH} -c \ 353 1.20 kre '. ./h-f3; set -- "a+a" "" "b " " c"; IFS=+; delim_argv $*"$@"' 354 1.20 kre } 355 1.20 kre 356 1.1 jruoho atf_test_case strip 357 1.1 jruoho strip_head() { 358 1.21 kre atf_set descr "Checks that the %% operator works and strips" \ 359 1.1 jruoho "the contents of a variable from the given point" \ 360 1.6 christos "to the end" 361 1.1 jruoho } 362 1.1 jruoho strip_body() { 363 1.1 jruoho line='#define bindir "/usr/bin" /* comment */' 364 1.1 jruoho stripped='#define bindir "/usr/bin" ' 365 1.6 christos 366 1.6 christos # atf_expect_fail "PR bin/43469" -- now fixed 367 1.6 christos for exp in \ 368 1.6 christos '${line%%/\**}' \ 369 1.6 christos '${line%%"/*"*}' \ 370 1.6 christos '${line%%'"'"'/*'"'"'*}' \ 371 1.6 christos '"${line%%/\**}"' \ 372 1.6 christos '"${line%%"/*"*}"' \ 373 1.6 christos '"${line%%'"'"'/*'"'"'*}"' \ 374 1.6 christos '${line%/\**}' \ 375 1.6 christos '${line%"/*"*}' \ 376 1.6 christos '${line%'"'"'/*'"'"'*}' \ 377 1.6 christos '"${line%/\**}"' \ 378 1.6 christos '"${line%"/*"*}"' \ 379 1.6 christos '"${line%'"'"'/*'"'"'*}"' 380 1.6 christos do 381 1.6 christos atf_check -o inline:":$stripped:\n" -e empty ${TEST_SH} -c \ 382 1.6 christos "line='${line}'; echo :${exp}:" 383 1.6 christos done 384 1.1 jruoho } 385 1.1 jruoho 386 1.14 kre atf_test_case wrap_strip 387 1.14 kre wrap_strip_head() { 388 1.21 kre atf_set descr "Checks that the %% operator works and strips" \ 389 1.14 kre "the contents of a variable from the given point" \ 390 1.14 kre 'to the end, and that \ \n sequences do not break it' 391 1.14 kre } 392 1.14 kre wrap_strip_body() { 393 1.14 kre line='#define bindir "/usr/bin" /* comment */' 394 1.14 kre stripped='#define bindir "/usr/bin" ' 395 1.14 kre 396 1.14 kre for exp in \ 397 1.14 kre '${line\ 398 1.14 kre %%/\**}' \ 399 1.14 kre '${line%%"/\ 400 1.14 kre *"*}' \ 401 1.14 kre '${line%%'"'"'/*'"'"'\ 402 1.14 kre *}' \ 403 1.14 kre '"${li\ 404 1.14 kre ne%%/\**}"' \ 405 1.14 kre '"${line%%"\ 406 1.14 kre /*"*}"' \ 407 1.14 kre '"${line%\ 408 1.14 kre %'"'"'/*'"'"'*}"' \ 409 1.14 kre '${line\ 410 1.14 kre %\ 411 1.14 kre /\*\ 412 1.14 kre *\ 413 1.14 kre }' \ 414 1.14 kre '${line%"/*\ 415 1.14 kre "*\ 416 1.14 kre }' \ 417 1.14 kre '${line\ 418 1.14 kre %\ 419 1.14 kre '"'"'/*'"'"'*}' \ 420 1.14 kre '"$\ 421 1.14 kre {li\ 422 1.14 kre ne%\ 423 1.14 kre '"'"'/*'"'"'*}"' 424 1.14 kre do 425 1.14 kre atf_check -o inline:":$stripped:\n" -e empty ${TEST_SH} -c \ 426 1.14 kre "line='${line}'; echo :${exp}:" 427 1.14 kre done 428 1.14 kre } 429 1.14 kre 430 1.18 kre atf_test_case tilde 431 1.18 kre tilde_head() { 432 1.21 kre atf_set descr "Checks that the ~ expansions work" 433 1.18 kre } 434 1.18 kre tilde_body() { 435 1.23 kre for HOME in '' / /home/foo /home/foo/ \ 436 1.18 kre /a/very/long/home/directory/path/that/might/push/the/tilde/expansion/code/beyond/what/it/would/normally/ever/see/on/any/sane/system/and/perhaps/expose/some/bugs 437 1.18 kre do 438 1.18 kre export HOME 439 1.18 kre 440 1.18 kre atf_check -s exit:0 -e empty \ 441 1.18 kre -o inline:'HOME\t'"${HOME}"' 442 1.18 kre ~\t'"${HOME}"' 443 1.23 kre ~/foobar\t'"${HOME%/}"'/foobar 444 1.18 kre "$V"\t'"${HOME}"' 445 1.18 kre "$X"\t~ 446 1.18 kre "$Y"\t'"${HOME}"':'"${HOME}"' 447 1.23 kre "$YY"\t'"${HOME%/}"'/foo:'"${HOME%/}"'/bar 448 1.23 kre "$Z"\t'"${HOME%/}"'/~ 449 1.18 kre ${U:-~}\t'"${HOME}"' 450 1.18 kre $V\t'"${HOME}"' 451 1.18 kre $X\t~ 452 1.18 kre $Y\t'"${HOME}"':'"${HOME}"' 453 1.23 kre $YY\t'"${HOME%/}"'/foo:'"${HOME%/}"'/bar 454 1.23 kre $Z\t'"${HOME%/}"'/~ 455 1.18 kre ${U:=~}\t'"${HOME}"' 456 1.18 kre ${UU:=~:~}\t'"${HOME}"':'"${HOME}"' 457 1.23 kre ${UUU:=~/:~}\t'"${HOME%/}"'/:'"${HOME}"' 458 1.23 kre ${U4:=~/:~/}\t'"${HOME%/}"'/:'"${HOME%/}"'/\n' \ 459 1.18 kre ${TEST_SH} -s <<- \EOF 460 1.18 kre unset -v U UU UUU U4 461 1.18 kre V=~ 462 1.18 kre X="~" 463 1.18 kre Y=~:~ YY=~/foo:~/bar 464 1.18 kre Z=~/~ 465 1.18 kre printf '%s\t%s\n' \ 466 1.18 kre 'HOME' "${HOME}" \ 467 1.18 kre '~' ~ \ 468 1.18 kre '~/foobar' ~/foobar \ 469 1.18 kre '"$V"' "$V" \ 470 1.18 kre '"$X"' "$X" \ 471 1.18 kre '"$Y"' "$Y" \ 472 1.18 kre '"$YY"' "$YY" \ 473 1.18 kre '"$Z"' "$Z" \ 474 1.18 kre '${U:-~}' ''${U:-~} \ 475 1.18 kre '$V' ''$V \ 476 1.18 kre '$X' ''$X \ 477 1.18 kre '$Y' ''$Y \ 478 1.18 kre '$YY' ''$YY \ 479 1.18 kre '$Z' ''$Z \ 480 1.18 kre '${U:=~}' ''${U:=~} \ 481 1.18 kre '${UU:=~:~}' ''${UU:=~:~} \ 482 1.18 kre '${UUU:=~/:~}' ''${UUU:=~/:~} \ 483 1.18 kre '${U4:=~/:~/}' ''${U4:=~/:~/} 484 1.18 kre EOF 485 1.18 kre done 486 1.18 kre 487 1.23 kre # Verify that when HOME is "" expanding a bare ~ 488 1.23 kre # makes an empty word, not nothing (or anything else) 489 1.23 kre HOME="" 490 1.23 kre export HOME 491 1.23 kre atf_check -s exit:0 -e empty -o inline:'1:<>\n' ${TEST_SH} -c \ 492 1.23 kre 'set -- ~ ; IFS=, ; printf '"'%d:<%s>\\n'"' "$#" "$*"' 493 1.23 kre atf_check -s exit:0 -e empty -o inline:'4:<,X,,/>\n' ${TEST_SH} -c \ 494 1.23 kre 'set -- ~ X ~ ~/ ; IFS=, ; printf '"'%d:<%s>\\n'"' "$#" "$*"' 495 1.23 kre 496 1.18 kre # Testing ~user is harder, so, perhaps later... 497 1.18 kre } 498 1.18 kre 499 1.1 jruoho atf_test_case varpattern_backslashes 500 1.1 jruoho varpattern_backslashes_head() { 501 1.21 kre atf_set descr "Tests that protecting wildcards with backslashes" \ 502 1.1 jruoho "works in variable patterns." 503 1.1 jruoho } 504 1.1 jruoho varpattern_backslashes_body() { 505 1.1 jruoho line='/foo/bar/*/baz' 506 1.1 jruoho stripped='/foo/bar/' 507 1.6 christos atf_check -o inline:'/foo/bar/\n' -e empty ${TEST_SH} -c \ 508 1.6 christos 'line="/foo/bar/*/baz"; echo ${line%%\**}' 509 1.1 jruoho } 510 1.1 jruoho 511 1.1 jruoho atf_test_case arithmetic 512 1.1 jruoho arithmetic_head() { 513 1.21 kre atf_set descr "POSIX requires shell arithmetic to use signed" \ 514 1.1 jruoho "long or a wider type. We use intmax_t, so at" \ 515 1.1 jruoho "least 64 bits should be available. Make sure" \ 516 1.1 jruoho "this is true." 517 1.1 jruoho } 518 1.1 jruoho arithmetic_body() { 519 1.6 christos 520 1.6 christos atf_check -o inline:'3' -e empty ${TEST_SH} -c \ 521 1.6 christos 'printf %s $((1 + 2))' 522 1.6 christos atf_check -o inline:'2147483647' -e empty ${TEST_SH} -c \ 523 1.6 christos 'printf %s $((0x7fffffff))' 524 1.6 christos atf_check -o inline:'9223372036854775807' -e empty ${TEST_SH} -c \ 525 1.6 christos 'printf %s $(((1 << 63) - 1))' 526 1.1 jruoho } 527 1.1 jruoho 528 1.2 ast atf_test_case iteration_on_null_parameter 529 1.2 ast iteration_on_null_parameter_head() { 530 1.21 kre atf_set descr "Check iteration of \$@ in for loop when set to null;" \ 531 1.2 ast "the error \"sh: @: parameter not set\" is incorrect." \ 532 1.2 ast "PR bin/48202." 533 1.2 ast } 534 1.2 ast iteration_on_null_parameter_body() { 535 1.6 christos atf_check -o empty -e empty ${TEST_SH} -c \ 536 1.6 christos 'N=; set -- ${N}; for X; do echo "[$X]"; done' 537 1.6 christos } 538 1.6 christos 539 1.6 christos atf_test_case iteration_on_quoted_null_parameter 540 1.6 christos iteration_on_quoted_null_parameter_head() { 541 1.21 kre atf_set descr \ 542 1.6 christos 'Check iteration of "$@" in for loop when set to null;' 543 1.6 christos } 544 1.6 christos iteration_on_quoted_null_parameter_body() { 545 1.6 christos atf_check -o inline:'[]\n' -e empty ${TEST_SH} -c \ 546 1.6 christos 'N=; set -- "${N}"; for X; do echo "[$X]"; done' 547 1.6 christos } 548 1.6 christos 549 1.6 christos atf_test_case iteration_on_null_or_null_parameter 550 1.6 christos iteration_on_null_or_null_parameter_head() { 551 1.21 kre atf_set descr \ 552 1.6 christos 'Check expansion of null parameter as default for another null' 553 1.6 christos } 554 1.6 christos iteration_on_null_or_null_parameter_body() { 555 1.6 christos atf_check -o empty -e empty ${TEST_SH} -c \ 556 1.6 christos 'N=; E=; set -- ${N:-${E}}; for X; do echo "[$X]"; done' 557 1.6 christos } 558 1.6 christos 559 1.6 christos atf_test_case iteration_on_null_or_missing_parameter 560 1.6 christos iteration_on_null_or_missing_parameter_head() { 561 1.21 kre atf_set descr \ 562 1.6 christos 'Check expansion of missing parameter as default for another null' 563 1.6 christos } 564 1.6 christos iteration_on_null_or_missing_parameter_body() { 565 1.6 christos # atf_expect_fail 'PR bin/50834' 566 1.6 christos atf_check -o empty -e empty ${TEST_SH} -c \ 567 1.6 christos 'N=; set -- ${N:-}; for X; do echo "[$X]"; done' 568 1.2 ast } 569 1.2 ast 570 1.10 kre ####### The remaining tests use the following helper functions ... 571 1.10 kre 572 1.7 christos nl=' 573 1.7 christos ' 574 1.7 christos reset() 575 1.7 christos { 576 1.7 christos TEST_NUM=0 577 1.7 christos TEST_FAILURES='' 578 1.7 christos TEST_FAIL_COUNT=0 579 1.7 christos TEST_ID="$1" 580 1.7 christos } 581 1.7 christos 582 1.7 christos check() 583 1.7 christos { 584 1.7 christos fail=false 585 1.7 christos TEMP_FILE=$( mktemp OUT.XXXXXX ) 586 1.7 christos TEST_NUM=$(( $TEST_NUM + 1 )) 587 1.7 christos MSG= 588 1.7 christos 589 1.7 christos # our local shell (ATF_SHELL) better do quoting correctly... 590 1.7 christos # some of the tests expect us to expand $nl internally... 591 1.7 christos CMD="$1" 592 1.7 christos 593 1.7 christos result="$( ${TEST_SH} -c "${CMD}" 2>"${TEMP_FILE}" )" 594 1.7 christos STATUS=$? 595 1.7 christos 596 1.7 christos if [ "${STATUS}" -ne "$3" ]; then 597 1.7 christos MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]" 598 1.7 christos MSG="${MSG} expected exit code $3, got ${STATUS}" 599 1.7 christos 600 1.7 christos # don't actually fail just because of wrong exit code 601 1.7 christos # unless we either expected, or received "good" 602 1.13 kre # or something else is detected as incorrect as well. 603 1.7 christos case "$3/${STATUS}" in 604 1.7 christos (*/0|0/*) fail=true;; 605 1.7 christos esac 606 1.7 christos fi 607 1.7 christos 608 1.7 christos if [ "$3" -eq 0 ]; then 609 1.7 christos if [ -s "${TEMP_FILE}" ]; then 610 1.7 christos MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]" 611 1.7 christos MSG="${MSG} Messages produced on stderr unexpected..." 612 1.7 christos MSG="${MSG}${nl}$( cat "${TEMP_FILE}" )" 613 1.7 christos fail=true 614 1.7 christos fi 615 1.7 christos else 616 1.7 christos if ! [ -s "${TEMP_FILE}" ]; then 617 1.7 christos MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]" 618 1.7 christos MSG="${MSG} Expected messages on stderr," 619 1.7 christos MSG="${MSG} nothing produced" 620 1.7 christos fail=true 621 1.7 christos fi 622 1.7 christos fi 623 1.7 christos rm -f "${TEMP_FILE}" 624 1.7 christos 625 1.7 christos # Remove newlines (use local shell for this) 626 1.7 christos oifs="$IFS" 627 1.7 christos IFS="$nl" 628 1.7 christos result="$(echo $result)" 629 1.7 christos IFS="$oifs" 630 1.7 christos if [ "$2" != "$result" ] 631 1.7 christos then 632 1.7 christos MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]" 633 1.7 christos MSG="${MSG} Expected output '$2', received '$result'" 634 1.7 christos fail=true 635 1.7 christos fi 636 1.7 christos 637 1.7 christos if $fail 638 1.7 christos then 639 1.7 christos MSG="${MSG}${MSG:+${nl}}[$TEST_NUM]" 640 1.7 christos MSG="${MSG} Full command: <<${CMD}>>" 641 1.7 christos fi 642 1.7 christos 643 1.7 christos $fail && test -n "$TEST_ID" && { 644 1.7 christos TEST_FAILURES="${TEST_FAILURES}${TEST_FAILURES:+${nl}}" 645 1.7 christos TEST_FAILURES="${TEST_FAILURES}${TEST_ID}[$TEST_NUM]:" 646 1.7 christos TEST_FAILURES="${TEST_FAILURES} Test of '$1' failed."; 647 1.7 christos TEST_FAILURES="${TEST_FAILURES}${nl}${MSG}" 648 1.7 christos TEST_FAIL_COUNT=$(( $TEST_FAIL_COUNT + 1 )) 649 1.7 christos return 0 650 1.7 christos } 651 1.13 kre $fail && atf_fail "Test[$TEST_NUM] failed: $( 652 1.13 kre # ATF does not like newlines in messages, so change them... 653 1.13 kre printf '%s' "${MSG}" | tr '\n' ';' 654 1.13 kre )" 655 1.7 christos return 0 656 1.7 christos } 657 1.7 christos 658 1.7 christos results() 659 1.7 christos { 660 1.10 kre test -n "$1" && atf_expect_fail "$1" 661 1.10 kre 662 1.7 christos test -z "${TEST_ID}" && return 0 663 1.7 christos test -z "${TEST_FAILURES}" && return 0 664 1.7 christos 665 1.7 christos echo >&2 "==========================================" 666 1.7 christos echo >&2 "While testing '${TEST_ID}'" 667 1.7 christos echo >&2 " - - - - - - - - - - - - - - - - -" 668 1.7 christos echo >&2 "${TEST_FAILURES}" 669 1.10 kre 670 1.7 christos atf_fail \ 671 1.9 kre "Test ${TEST_ID}: $TEST_FAIL_COUNT (of $TEST_NUM) subtests failed - see stderr" 672 1.7 christos } 673 1.7 christos 674 1.10 kre ####### End helpers 675 1.10 kre 676 1.7 christos atf_test_case shell_params 677 1.7 christos shell_params_head() { 678 1.21 kre atf_set descr "Test correct operation of the numeric parameters" 679 1.7 christos } 680 1.7 christos shell_params_body() { 681 1.7 christos atf_require_prog mktemp 682 1.7 christos 683 1.7 christos reset shell_params 684 1.7 christos 685 1.7 christos check 'set -- a b c; echo "$#: $1 $2 $3"' '3: a b c' 0 686 1.7 christos check 'set -- a b c d e f g h i j k l m; echo "$#: ${1}0 ${10} $10"' \ 687 1.7 christos '13: a0 j a0' 0 688 1.7 christos check 'x="$0"; set -- a b; y="$0"; 689 1.7 christos [ "x${x}y" = "x${y}y" ] && echo OK || echo x="$x" y="$y"' \ 690 1.7 christos 'OK' 0 691 1.7 christos check "${TEST_SH} -c 'echo 0=\$0 1=\$1 2=\$2' a b c" '0=a 1=b 2=c' 0 692 1.7 christos 693 1.7 christos echo 'echo 0="$0" 1="$1" 2="$2"' > helper.sh 694 1.8 christos check "${TEST_SH} helper.sh a b c" '0=helper.sh 1=a 2=b' 0 695 1.7 christos 696 1.7 christos check 'set -- a bb ccc dddd eeeee ffffff ggggggg hhhhhhhh \ 697 1.7 christos iiiiiiiii jjjjjjjjjj kkkkkkkkkkk 698 1.7 christos echo "${#}: ${#1} ${#2} ${#3} ${#4} ... ${#9} ${#10} ${#11}"' \ 699 1.7 christos '11: 1 2 3 4 ... 9 10 11' 0 700 1.7 christos 701 1.7 christos check 'set -- a b c; echo "$#: ${1-A} ${2-B} ${3-C} ${4-D} ${5-E}"' \ 702 1.7 christos '3: a b c D E' 0 703 1.7 christos check 'set -- a "" c "" e 704 1.7 christos echo "$#: ${1:-A} ${2:-B} ${3:-C} ${4:-D} ${5:-E}"' \ 705 1.7 christos '5: a B c D e' 0 706 1.7 christos check 'set -- a "" c "" e 707 1.7 christos echo "$#: ${1:+A} ${2:+B} ${3:+C} ${4:+D} ${5:+E}"' \ 708 1.7 christos '5: A C E' 0 709 1.7 christos check 'set -- "abab*cbb" 710 1.7 christos echo "${1} ${1#a} ${1%b} ${1##ab} ${1%%b} ${1#*\*} ${1%\**}"' \ 711 1.7 christos 'abab*cbb bab*cbb abab*cb ab*cbb abab*cb cbb abab' 0 712 1.7 christos check 'set -- "abab?cbb" 713 1.7 christos echo "${1}:${1#*a}+${1%b*}-${1##*a}_${1%%b*}%${1#[ab]}=${1%?*}/${1%\?*}"' \ 714 1.7 christos 'abab?cbb:bab?cbb+abab?cb-b?cbb_a%bab?cbb=abab?cb/abab' 0 715 1.7 christos check 'set -- a "" c "" e; echo "${2:=b}"' '' 1 716 1.7 christos 717 1.15 kre check 'set -- a b c d; echo ${4294967297}' '' 0 # result 'a' => ${1} 718 1.15 kre check 'set -- a b c; echo ${01}' 'a' 0 719 1.15 kre check "${TEST_SH} -c 'echo 0=\${00} 1=\${01} 2=\${02}' a b c" \ 720 1.15 kre '0=a 1=b 2=c' 0 721 1.15 kre 722 1.16 kre # by special request, for PaulG... (${0...} is not octal!) 723 1.17 kre 724 1.17 kre # Posix XCU 2.5.1 (Issue 7 TC2 pg 2349 lines 74835..6): 725 1.17 kre # The digits denoting the positional parameters shall always 726 1.17 kre # be interpreted as a decimal value, even if there is a leading zero. 727 1.17 kre 728 1.16 kre check \ 729 1.16 kre 'set -- a b c d e f g h i j k l m; echo "$#: ${08} ${010} ${011}"' \ 730 1.16 kre '13: h j k' 0 731 1.16 kre 732 1.7 christos results 733 1.7 christos } 734 1.7 christos 735 1.9 kre atf_test_case var_with_embedded_cmdsub 736 1.9 kre var_with_embedded_cmdsub_head() { 737 1.21 kre atf_set descr "Test expansion of vars with embedded cmdsub" 738 1.9 kre } 739 1.9 kre var_with_embedded_cmdsub_body() { 740 1.9 kre 741 1.9 kre reset var_with_embedded_cmdsub 742 1.9 kre 743 1.9 kre check 'unset x; echo ${x-$(echo a)}$(echo b)' 'ab' 0 #1 744 1.9 kre check 'unset x; echo ${x:-$(echo a)}$(echo b)' 'ab' 0 #2 745 1.9 kre check 'x=""; echo ${x-$(echo a)}$(echo b)' 'b' 0 #3 746 1.9 kre check 'x=""; echo ${x:-$(echo a)}$(echo b)' 'ab' 0 #4 747 1.9 kre check 'x=c; echo ${x-$(echo a)}$(echo b)' 'cb' 0 #5 748 1.9 kre check 'x=c; echo ${x:-$(echo a)}$(echo b)' 'cb' 0 #6 749 1.9 kre 750 1.9 kre check 'unset x; echo ${x+$(echo a)}$(echo b)' 'b' 0 #7 751 1.9 kre check 'unset x; echo ${x:+$(echo a)}$(echo b)' 'b' 0 #8 752 1.9 kre check 'x=""; echo ${x+$(echo a)}$(echo b)' 'ab' 0 #9 753 1.9 kre check 'x=""; echo ${x:+$(echo a)}$(echo b)' 'b' 0 #10 754 1.9 kre check 'x=c; echo ${x+$(echo a)}$(echo b)' 'ab' 0 #11 755 1.9 kre check 'x=c; echo ${x:+$(echo a)}$(echo b)' 'ab' 0 #12 756 1.9 kre 757 1.9 kre check 'unset x; echo ${x=$(echo a)}$(echo b)' 'ab' 0 #13 758 1.9 kre check 'unset x; echo ${x:=$(echo a)}$(echo b)' 'ab' 0 #14 759 1.9 kre check 'x=""; echo ${x=$(echo a)}$(echo b)' 'b' 0 #15 760 1.9 kre check 'x=""; echo ${x:=$(echo a)}$(echo b)' 'ab' 0 #16 761 1.9 kre check 'x=c; echo ${x=$(echo a)}$(echo b)' 'cb' 0 #17 762 1.9 kre check 'x=c; echo ${x:=$(echo a)}$(echo b)' 'cb' 0 #18 763 1.9 kre 764 1.9 kre check 'unset x; echo ${x?$(echo a)}$(echo b)' '' 2 #19 765 1.9 kre check 'unset x; echo ${x:?$(echo a)}$(echo b)' '' 2 #20 766 1.9 kre check 'x=""; echo ${x?$(echo a)}$(echo b)' 'b' 0 #21 767 1.9 kre check 'x=""; echo ${x:?$(echo a)}$(echo b)' '' 2 #22 768 1.9 kre check 'x=c; echo ${x?$(echo a)}$(echo b)' 'cb' 0 #23 769 1.9 kre check 'x=c; echo ${x:?$(echo a)}$(echo b)' 'cb' 0 #24 770 1.9 kre 771 1.9 kre check 'unset x; echo ${x%$(echo a)}$(echo b)' 'b' 0 #25 772 1.9 kre check 'unset x; echo ${x%%$(echo a)}$(echo b)' 'b' 0 #26 773 1.9 kre check 'x=""; echo ${x%$(echo a)}$(echo b)' 'b' 0 #27 774 1.9 kre check 'x=""; echo ${x%%$(echo a)}$(echo b)' 'b' 0 #28 775 1.9 kre check 'x=c; echo ${x%$(echo a)}$(echo b)' 'cb' 0 #29 776 1.9 kre check 'x=c; echo ${x%%$(echo a)}$(echo b)' 'cb' 0 #30 777 1.9 kre check 'x=aa; echo ${x%$(echo "*a")}$(echo b)' 'ab' 0 #31 778 1.9 kre check 'x=aa; echo ${x%%$(echo "*a")}$(echo b)' 'b' 0 #32 779 1.9 kre 780 1.9 kre check 'unset x; echo ${x#$(echo a)}$(echo b)' 'b' 0 #33 781 1.9 kre check 'unset x; echo ${x##$(echo a)}$(echo b)' 'b' 0 #34 782 1.9 kre check 'x=""; echo ${x#$(echo a)}$(echo b)' 'b' 0 #35 783 1.9 kre check 'x=""; echo ${x##$(echo a)}$(echo b)' 'b' 0 #36 784 1.9 kre check 'x=c; echo ${x#$(echo a)}$(echo b)' 'cb' 0 #37 785 1.9 kre check 'x=c; echo ${x##$(echo a)}$(echo b)' 'cb' 0 #38 786 1.9 kre check 'x=aa; echo ${x#$(echo "*a")}$(echo b)' 'ab' 0 #39 787 1.9 kre check 'x=aa; echo ${x##$(echo "*a")}$(echo b)' 'b' 0 #40 788 1.9 kre 789 1.9 kre results 790 1.9 kre } 791 1.9 kre 792 1.12 kre atf_test_case dollar_hash 793 1.12 kre dollar_hash_head() { 794 1.21 kre atf_set descr 'Test expansion of various aspects of $#' 795 1.12 kre } 796 1.12 kre dollar_hash_body() { 797 1.12 kre 798 1.12 kre # 799 1.12 kre # $# looks like it should be so simple that it doesn't really 800 1.12 kre # need a test of its own, and used in that way, it really doesn't. 801 1.12 kre # But when we add braces ${#} we need to deal with the three 802 1.12 kre # (almost 4) different meanings of a # inside a ${} expansion... 803 1.13 kre # 804 1.13 kre # Note that some of these are just how we treat expansions that 805 1.13 kre # are unspecified by posix (as noted below.) 806 1.12 kre # 807 1.12 kre # 1. ${#} is just $# (number of params) 808 1.12 kre # 1.a ${\#} is nothing at all (error: invalid expansion) 809 1.12 kre # 1.b ${\#...} (anything after) is the same (invalid) 810 1.12 kre # 2. ${#VAR} is the length of the value VAR 811 1.12 kre # 2.a Including ${##} - the length of ${#} 812 1.12 kre # 3 ${VAR#pat} is the value of VAR with leading pat removed 813 1.12 kre # 3.a Including ${VAR#} which just removes leading nothing 814 1.12 kre # This is relevant in case of ${VAR#${X}} with X='' 815 1.13 kre # nb: not required by posix, see XCU 2.6.2 816 1.12 kre # 3.b ${##} is not a case of 3.a but rather 2.a 817 1.12 kre # 3.c Yet ${##pat} is a case of 3.a 818 1.12 kre # Including ${##${X}} where X='' or X='#' 819 1.13 kre # nb: not required by posix, see XCU 2.6.2 820 1.12 kre # 3.d And ${#\#} is invalid (error) 821 1.12 kre # 3.e But ${##\#} removes a leading # from the value of $# 822 1.12 kre # (so is just $# as there is no leading # there) 823 1.13 kre # nb: not required by posix, see XCU 2.6.2 824 1.12 kre # 4 ${VAR##pat} is the value of VAR with longest pat removed 825 1.12 kre # 4.a Including ${VAR##} which removes the longest nothing 826 1.12 kre # 4.b Which in this case includes ${###} (so is == $#) 827 1.13 kre # nb: not required by posix, see XCU 2.6.2 828 1.12 kre # 4.c But not ${##\#} which is $# with a leading '#' removed 829 1.12 kre # (and so is also == $#), i.e.: like ${###} but different. 830 1.13 kre # nb: not required by posix, see XCU 2.6.2 831 1.12 kre # 4.d As is ${###\#} or just ${####} - remove # (so just $#) 832 1.13 kre # nb: not required by posix, see XCU 2.6.2 833 1.12 kre # 834 1.12 kre 835 1.12 kre reset dollar_hash 836 1.12 kre 837 1.12 kre check 'set -- ; echo $#' '0' 0 # 1 838 1.12 kre check 'set -- a b c; echo $#' '3' 0 # 2 839 1.12 kre check 'set -- a b c d e f g h i j; echo $#' '10' 0 # 3 840 1.12 kre # rule 1 841 1.12 kre check 'set -- ; echo ${#}' '0' 0 # 4 842 1.12 kre check 'set -- a b c; echo ${#}' '3' 0 # 5 843 1.12 kre check 'set -- a b c d e f g h i j; echo ${#}' '10' 0 # 6 844 1.12 kre # rule 1.a 845 1.12 kre check 'set -- a b c; echo ${\#}' '' 2 # 7 846 1.12 kre # rule 1.b 847 1.12 kre check 'set -- a b c; echo ${\#:-foo}' '' 2 # 8 848 1.12 kre # rule 2 849 1.12 kre check 'VAR=12345; echo ${#VAR}' '5' 0 # 9 850 1.12 kre check 'VAR=123456789012; echo ${#VAR}' '12' 0 #10 851 1.12 kre # rule 2.a 852 1.12 kre check 'set -- ; echo ${##}' '1' 0 #11 853 1.12 kre check 'set -- a b c; echo ${##}' '1' 0 #12 854 1.12 kre check 'set -- a b c d e f g h i j; echo ${##}' '2' 0 #13 855 1.12 kre # rule 3 856 1.12 kre check 'VAR=12345; echo ${VAR#1}' '2345' 0 #14 857 1.12 kre check 'VAR=12345; echo ${VAR#2}' '12345' 0 #15 858 1.12 kre check 'VAR=#2345; echo ${VAR#\#}' '2345' 0 #16 859 1.12 kre check 'X=1; VAR=12345; echo ${VAR#${X}}' '2345' 0 #17 860 1.12 kre check 'X=1; VAR=#2345; echo ${VAR#${X}}' '#2345' 0 #18 861 1.12 kre # rule 3.a 862 1.12 kre check 'VAR=12345; echo ${VAR#}' '12345' 0 #19 863 1.12 kre check 'X=; VAR=12345; echo ${VAR#${X}}' '12345' 0 #20 864 1.12 kre # rule 3.b (tested above, rule 2.a) 865 1.12 kre # rule 3.c 866 1.12 kre check 'set -- ; echo ${##0}' '' 0 #21 867 1.12 kre check 'set -- a b c; echo ${##1}' '3' 0 #22 868 1.12 kre check 'set -- a b c d e f g h i j; echo ${##1}' '0' 0 #23 869 1.12 kre check 'X=0; set -- ; echo ${##${X}}' '' 0 #24 870 1.12 kre check 'X=; set -- ; echo ${##${X}}' '0' 0 #25 871 1.12 kre check 'X=1; set -- a b c; echo ${##${X}}' '3' 0 #26 872 1.12 kre check 'X=1; set -- a b c d e f g h i j; echo ${##${X}}' '0' 0 #27 873 1.12 kre check 'X=; set -- a b c d e f g h i j; echo ${##${X}}' '10' 0 #28 874 1.12 kre check 'X=#; VAR=#2345; echo ${VAR#${X}}' '2345' 0 #29 875 1.12 kre check 'X=#; VAR=12345; echo ${VAR#${X}}' '12345' 0 #30 876 1.12 kre # rule 3.d 877 1.12 kre check 'set -- a b c; echo ${#\#}' '' 2 #31 878 1.12 kre # rule 3.e 879 1.12 kre check 'set -- ; echo ${##\#}' '0' 0 #32 880 1.12 kre check 'set -- a b c d e f g h i j; echo ${##\#}' '10' 0 #33 881 1.12 kre 882 1.12 kre # rule 4 883 1.12 kre check 'VAR=12345; echo ${VAR##1}' '2345' 0 #34 884 1.12 kre check 'VAR=12345; echo ${VAR##\1}' '2345' 0 #35 885 1.12 kre # rule 4.a 886 1.12 kre check 'VAR=12345; echo ${VAR##}' '12345' 0 #36 887 1.12 kre # rule 4.b 888 1.12 kre check 'set -- ; echo ${###}' '0' 0 #37 889 1.12 kre check 'set -- a b c d e f g h i j; echo ${###}' '10' 0 #38 890 1.12 kre # rule 4.c 891 1.12 kre check 'VAR=12345; echo ${VAR#\#}' '12345' 0 #39 892 1.12 kre check 'VAR=12345; echo ${VAR#\#1}' '12345' 0 #40 893 1.12 kre check 'VAR=#2345; echo ${VAR#\#}' '2345' 0 #41 894 1.12 kre check 'VAR=#12345; echo ${VAR#\#1}' '2345' 0 #42 895 1.12 kre check 'VAR=#2345; echo ${VAR#\#1}' '#2345' 0 #43 896 1.12 kre check 'set -- ; echo ${####}' '0' 0 #44 897 1.12 kre check 'set -- ; echo ${###\#}' '0' 0 #45 898 1.12 kre check 'set -- a b c d e f g h i j; echo ${####}' '10' 0 #46 899 1.12 kre check 'set -- a b c d e f g h i j; echo ${###\#}' '10' 0 #47 900 1.12 kre 901 1.12 kre # now check for some more utter nonsense, not mentioned in the rules 902 1.12 kre # above (doesn't need to be) 903 1.12 kre 904 1.12 kre check 'x=hello; set -- a b c; echo ${#x:-1}' '' 2 #48 905 1.12 kre check 'x=hello; set -- a b c; echo ${#x-1}' '' 2 #49 906 1.12 kre check 'x=hello; set -- a b c; echo ${#x:+1}' '' 2 #50 907 1.12 kre check 'x=hello; set -- a b c; echo ${#x+1}' '' 2 #51 908 1.12 kre check 'x=hello; set -- a b c; echo ${#x+1}' '' 2 #52 909 1.12 kre check 'x=hello; set -- a b c; echo ${#x:?msg}' '' 2 #53 910 1.12 kre check 'x=hello; set -- a b c; echo ${#x?msg}' '' 2 #54 911 1.12 kre check 'x=hello; set -- a b c; echo ${#x:=val}' '' 2 #55 912 1.12 kre check 'x=hello; set -- a b c; echo ${#x=val}' '' 2 #56 913 1.12 kre check 'x=hello; set -- a b c; echo ${#x#h}' '' 2 #57 914 1.12 kre check 'x=hello; set -- a b c; echo ${#x#*l}' '' 2 #58 915 1.12 kre check 'x=hello; set -- a b c; echo ${#x##*l}' '' 2 #59 916 1.12 kre check 'x=hello; set -- a b c; echo ${#x%o}' '' 2 #60 917 1.12 kre check 'x=hello; set -- a b c; echo ${#x%l*}' '' 2 #61 918 1.12 kre check 'x=hello; set -- a b c; echo ${#x%%l*}' '' 2 #62 919 1.12 kre 920 1.12 kre # but just to be complete, these ones should work 921 1.12 kre 922 1.12 kre check 'x=hello; set -- a b c; echo ${#%5}' '3' 0 #63 923 1.12 kre check 'x=hello; set -- a b c; echo ${#%3}' '' 0 #64 924 1.12 kre check 'x=hello; set -- a b c; echo ${#%?}' '' 0 #65 925 1.12 kre check 'X=#; set -- a b c; echo ${#%${X}}' '3' 0 #66 926 1.12 kre check 'X=3; set -- a b c; echo ${#%${X}}' '' 0 #67 927 1.12 kre check 'set -- a b c; echo ${#%%5}' '3' 0 #68 928 1.12 kre check 'set -- a b c; echo ${#%%3}' '' 0 #69 929 1.12 kre check 'set -- a b c d e f g h i j k l; echo ${#%1}' '12' 0 #70 930 1.12 kre check 'set -- a b c d e f g h i j k l; echo ${#%2}' '1' 0 #71 931 1.12 kre check 'set -- a b c d e f g h i j k l; echo ${#%?}' '1' 0 #72 932 1.12 kre check 'set -- a b c d e f g h i j k l; echo ${#%[012]}' '1' 0 #73 933 1.12 kre check 'set -- a b c d e f g h i j k l; echo ${#%[0-4]}' '1' 0 #74 934 1.12 kre check 'set -- a b c d e f g h i j k l; echo ${#%?2}' '' 0 #75 935 1.12 kre check 'set -- a b c d e f g h i j k l; echo ${#%1*}' '' 0 #76 936 1.12 kre check 'set -- a b c d e f g h i j k l; echo ${#%%2}' '1' 0 #77 937 1.12 kre check 'set -- a b c d e f g h i j k l; echo ${#%%1*}' '' 0 #78 938 1.12 kre 939 1.12 kre # and this lot are stupid, as $# is never unset or null, but they do work... 940 1.12 kre 941 1.12 kre check 'set -- a b c; echo ${#:-99}' '3' 0 #79 942 1.12 kre check 'set -- a b c; echo ${#-99}' '3' 0 #80 943 1.12 kre check 'set -- a b c; echo ${#:+99}' '99' 0 #81 944 1.12 kre check 'set -- a b c; echo ${#+99}' '99' 0 #82 945 1.12 kre check 'set -- a b c; echo ${#:?bogus}' '3' 0 #83 946 1.12 kre check 'set -- a b c; echo ${#?bogus}' '3' 0 #84 947 1.12 kre 948 1.12 kre # even this utter nonsense is OK, as while special params cannot be 949 1.12 kre # set this way, here, as $# is not unset, or null, the assignment 950 1.12 kre # never happens (isn't even attempted) 951 1.12 kre 952 1.12 kre check 'set -- a b c; echo ${#:=bogus}' '3' 0 #85 953 1.12 kre check 'set -- a b c; echo ${#=bogus}' '3' 0 #86 954 1.12 kre 955 1.13 kre for n in 0 1 10 25 100 #87 #88 #89 #90 #91 956 1.13 kre do 957 1.13 kre check "(exit $n)"'; echo ${#?}' "${#n}" 0 958 1.13 kre done 959 1.13 kre 960 1.13 kre results # results so far anyway... 961 1.13 kre 962 1.13 kre # now we have some harder to verify cases, as they (must) check unknown values 963 1.13 kre # and hence the resuls cannot just be built into the script, but we have 964 1.13 kre # to use some tricks to validate them, so for these, just do regular testing 965 1.13 kre # and don't attempt to use the check helper function, nor to include 966 1.13 kre # these tests in the result summary. If anything has already failed, we 967 1.13 kre # do not get this far... From here on, first failure ends this test. 968 1.13 kre 969 1.13 kre for opts in '' '-a' '-au' '-auf' '-aufe' # options safe enough to set 970 1.13 kre do 971 1.13 kre # Note the shell might have other (or these) opts set already 972 1.13 kre 973 1.13 kre RES=$(${TEST_SH} -c "test -n '${opts}' && set ${opts}; 974 1.13 kre printf '%s' \"\$-\";printf ' %s\\n' \"\${#-}\"") || 975 1.13 kre atf_fail '${#-} test exited with status '"$?" 976 1.13 kre LEN="${RES##* }" 977 1.13 kre DMINUS="${RES% ${LEN}}" 978 1.13 kre if [ "${#DMINUS}" != "${LEN}" ] 979 1.13 kre then 980 1.13 kre atf_fail \ 981 1.13 kre '${#-} test'" produced ${LEN} for opts ${DMINUS} (${RES})" 982 1.13 kre fi 983 1.13 kre done 984 1.13 kre 985 1.13 kre for seq in a b c d e f g h i j 986 1.13 kre do 987 1.13 kre # now we are tryin to generate different pids for $$ and $! 988 1.13 kre # so we just run the test a number of times, and hope... 989 1.13 kre # On NetBSD pid randomisation will usually help the tests 990 1.13 kre 991 1.13 kre eval "$(${TEST_SH} -c \ 992 1.13 kre '(exit 0)& BG=$! LBG=${#!}; 993 1.13 kre printf "SH=%s BG=%s LSH=%s LBG=%s" "$$" "$BG" "${#$}" "$LBG"; 994 1.13 kre wait')" 995 1.13 kre 996 1.13 kre if [ "${#SH}" != "${LSH}" ] || [ "${#BG}" != "${LBG}" ] 997 1.13 kre then 998 1.13 kre atf_fail \ 999 1.13 kre '${#!] of '"${BG} was ${LBG}, expected ${#BG}"'; ${#$} of '"${SH} was ${LSH}, expected ${#SH}" 1000 1.13 kre fi 1001 1.13 kre done 1002 1.12 kre } 1003 1.12 kre 1004 1.10 kre atf_test_case dollar_star 1005 1.10 kre dollar_star_head() { 1006 1.21 kre atf_set descr 'Test expansion of various aspects of $*' 1007 1.10 kre } 1008 1.10 kre dollar_star_body() { 1009 1.10 kre 1010 1.12 kre reset dollar_star 1011 1.10 kre 1012 1.10 kre check 'set -- a b c; echo $# $*' '3 a b c' 0 # 1 1013 1.10 kre check 'set -- a b c; echo $# "$*"' '3 a b c' 0 # 2 1014 1.10 kre check 'set -- a "b c"; echo $# $*' '2 a b c' 0 # 3 1015 1.10 kre check 'set -- a "b c"; echo $# "$*"' '2 a b c' 0 # 4 1016 1.10 kre check 'set -- a b c; set -- $* ; echo $# $*' '3 a b c' 0 # 5 1017 1.10 kre check 'set -- a b c; set -- "$*" ; echo $# $*' '1 a b c' 0 # 6 1018 1.10 kre check 'set -- a "b c"; set -- $* ; echo $# $*' '3 a b c' 0 # 7 1019 1.10 kre check 'set -- a "b c"; set -- "$*" ; echo $# $*' \ 1020 1.10 kre '1 a b c' 0 # 8 1021 1.10 kre 1022 1.10 kre check 'IFS=". "; set -- a b c; echo $# $*' '3 a b c' 0 # 9 1023 1.10 kre check 'IFS=". "; set -- a b c; echo $# "$*"' '3 a.b.c' 0 #10 1024 1.10 kre check 'IFS=". "; set -- a "b c"; echo $# $*' '2 a b c' 0 #11 1025 1.10 kre check 'IFS=". "; set -- a "b c"; echo $# "$*"' '2 a.b c' 0 #12 1026 1.10 kre check 'IFS=". "; set -- a "b.c"; echo $# $*' '2 a b c' 0 #13 1027 1.10 kre check 'IFS=". "; set -- a "b.c"; echo $# "$*"' '2 a.b.c' 0 #14 1028 1.10 kre check 'IFS=". "; set -- a b c; set -- $* ; echo $# $*' \ 1029 1.10 kre '3 a b c' 0 #15 1030 1.10 kre check 'IFS=". "; set -- a b c; set -- "$*" ; echo $# $*' \ 1031 1.10 kre '1 a b c' 0 #16 1032 1.10 kre check 'IFS=". "; set -- a "b c"; set -- $* ; echo $# $*' \ 1033 1.10 kre '3 a b c' 0 #17 1034 1.10 kre check 'IFS=". "; set -- a "b c"; set -- "$*" ; echo $# $*' \ 1035 1.10 kre '1 a b c' 0 #18 1036 1.10 kre check 'IFS=". "; set -- a b c; set -- $* ; echo $# "$*"' \ 1037 1.10 kre '3 a.b.c' 0 #19 1038 1.10 kre check 'IFS=". "; set -- a b c; set -- "$*" ; echo $# "$*"' \ 1039 1.10 kre '1 a.b.c' 0 #20 1040 1.10 kre check 'IFS=". "; set -- a "b c"; set -- $* ; echo $# "$*"' \ 1041 1.10 kre '3 a.b.c' 0 #21 1042 1.10 kre check 'IFS=". "; set -- a "b c"; set -- "$*" ; echo $# "$*"' \ 1043 1.10 kre '1 a.b c' 0 #22 1044 1.10 kre 1045 1.10 kre results 1046 1.10 kre } 1047 1.10 kre 1048 1.10 kre atf_test_case dollar_star_in_word 1049 1.10 kre dollar_star_in_word_head() { 1050 1.21 kre atf_set descr 'Test expansion $* occurring in word of ${var:-word}' 1051 1.10 kre } 1052 1.10 kre dollar_star_in_word_body() { 1053 1.10 kre 1054 1.10 kre reset dollar_star_in_word 1055 1.10 kre 1056 1.10 kre unset xXx ; # just in case! 1057 1.10 kre 1058 1.10 kre # Note that the expected results for these tests are identical 1059 1.10 kre # to those from the dollar_star test. It should never make 1060 1.10 kre # a difference whether we expand $* or ${unset:-$*} 1061 1.10 kre 1062 1.10 kre # (note expanding ${unset:-"$*"} is different, that is not tested here) 1063 1.10 kre 1064 1.10 kre check 'set -- a b c; echo $# ${xXx:-$*}' '3 a b c' 0 # 1 1065 1.10 kre check 'set -- a b c; echo $# "${xXx:-$*}"' '3 a b c' 0 # 2 1066 1.10 kre check 'set -- a "b c"; echo $# ${xXx:-$*}' '2 a b c' 0 # 3 1067 1.10 kre check 'set -- a "b c"; echo $# "${xXx:-$*}"' '2 a b c' 0 # 4 1068 1.10 kre check 'set -- a b c; set -- ${xXx:-$*} ; echo $# $*' '3 a b c' 0 # 5 1069 1.10 kre check 'set -- a b c; set -- "${xXx:-$*}" ; echo $# $*' '1 a b c' 0 # 6 1070 1.10 kre check 'set -- a "b c"; set -- ${xXx:-$*} ; echo $# $*' '3 a b c' 0 # 7 1071 1.10 kre check 'set -- a "b c"; set -- "${xXx:-$*}" ; echo $# $*' \ 1072 1.10 kre '1 a b c' 0 # 8 1073 1.10 kre 1074 1.10 kre check 'IFS=". "; set -- a b c; echo $# ${xXx:-$*}' '3 a b c' 0 # 9 1075 1.10 kre check 'IFS=". "; set -- a b c; echo $# "${xXx:-$*}"' '3 a.b.c' 0 #10 1076 1.10 kre check 'IFS=". "; set -- a "b c"; echo $# ${xXx:-$*}' '2 a b c' 0 #11 1077 1.10 kre check 'IFS=". "; set -- a "b c"; echo $# "${xXx:-$*}"' '2 a.b c' 0 #12 1078 1.10 kre check 'IFS=". "; set -- a "b.c"; echo $# ${xXx:-$*}' '2 a b c' 0 #13 1079 1.10 kre check 'IFS=". "; set -- a "b.c"; echo $# "${xXx:-$*}"' '2 a.b.c' 0 #14 1080 1.10 kre check 'IFS=". ";set -- a b c;set -- ${xXx:-$*};echo $# ${xXx:-$*}' \ 1081 1.10 kre '3 a b c' 0 #15 1082 1.10 kre check 'IFS=". ";set -- a b c;set -- "${xXx:-$*}";echo $# ${xXx:-$*}' \ 1083 1.10 kre '1 a b c' 0 #16 1084 1.10 kre check 'IFS=". ";set -- a "b c";set -- ${xXx:-$*};echo $# ${xXx:-$*}' \ 1085 1.10 kre '3 a b c' 0 #17 1086 1.10 kre check 'IFS=". ";set -- a "b c";set -- "${xXx:-$*}";echo $# ${xXx:-$*}' \ 1087 1.10 kre '1 a b c' 0 #18 1088 1.10 kre check 'IFS=". ";set -- a b c;set -- ${xXx:-$*};echo $# "${xXx:-$*}"' \ 1089 1.10 kre '3 a.b.c' 0 #19 1090 1.10 kre check 'IFS=". ";set -- a b c;set -- "$*";echo $# "$*"' \ 1091 1.10 kre '1 a.b.c' 0 #20 1092 1.10 kre check 'IFS=". ";set -- a "b c";set -- $*;echo $# "$*"' \ 1093 1.10 kre '3 a.b.c' 0 #21 1094 1.10 kre check 'IFS=". ";set -- a "b c";set -- "$*";echo $# "$*"' \ 1095 1.10 kre '1 a.b c' 0 #22 1096 1.10 kre 1097 1.10 kre results 1098 1.10 kre } 1099 1.10 kre 1100 1.10 kre atf_test_case dollar_star_with_empty_ifs 1101 1.10 kre dollar_star_with_empty_ifs_head() { 1102 1.21 kre atf_set descr 'Test expansion of $* with IFS=""' 1103 1.10 kre } 1104 1.10 kre dollar_star_with_empty_ifs_body() { 1105 1.10 kre 1106 1.10 kre reset dollar_star_with_empty_ifs 1107 1.10 kre 1108 1.10 kre check 'IFS=""; set -- a b c; echo $# $*' '3 a b c' 0 # 1 1109 1.10 kre check 'IFS=""; set -- a b c; echo $# "$*"' '3 abc' 0 # 2 1110 1.10 kre check 'IFS=""; set -- a "b c"; echo $# $*' '2 a b c' 0 # 3 1111 1.10 kre check 'IFS=""; set -- a "b c"; echo $# "$*"' '2 ab c' 0 # 4 1112 1.10 kre check 'IFS=""; set -- a "b.c"; echo $# $*' '2 a b.c' 0 # 5 1113 1.10 kre check 'IFS=""; set -- a "b.c"; echo $# "$*"' '2 ab.c' 0 # 6 1114 1.10 kre check 'IFS=""; set -- a b c; set -- $* ; echo $# $*' \ 1115 1.10 kre '3 a b c' 0 # 7 1116 1.10 kre check 'IFS=""; set -- a b c; set -- "$*" ; echo $# $*' \ 1117 1.10 kre '1 abc' 0 # 8 1118 1.10 kre check 'IFS=""; set -- a "b c"; set -- $* ; echo $# $*' \ 1119 1.10 kre '2 a b c' 0 # 9 1120 1.10 kre check 'IFS=""; set -- a "b c"; set -- "$*" ; echo $# $*' \ 1121 1.10 kre '1 ab c' 0 #10 1122 1.10 kre check 'IFS=""; set -- a b c; set -- $* ; echo $# "$*"' \ 1123 1.10 kre '3 abc' 0 #11 1124 1.10 kre check 'IFS=""; set -- a b c; set -- "$*" ; echo $# "$*"' \ 1125 1.10 kre '1 abc' 0 #12 1126 1.10 kre check 'IFS=""; set -- a "b c"; set -- $* ; echo $# "$*"' \ 1127 1.10 kre '2 ab c' 0 #13 1128 1.10 kre check 'IFS=""; set -- a "b c"; set -- "$*" ; echo $# "$*"' \ 1129 1.10 kre '1 ab c' 0 #14 1130 1.10 kre 1131 1.11 kre results # FIXED: 'PR bin/52090 expect 7 of 14 subtests to fail' 1132 1.10 kre } 1133 1.10 kre 1134 1.10 kre atf_test_case dollar_star_in_word_empty_ifs 1135 1.10 kre dollar_star_in_word_empty_ifs_head() { 1136 1.21 kre atf_set descr 'Test expansion of ${unset:-$*} with IFS=""' 1137 1.10 kre } 1138 1.10 kre dollar_star_in_word_empty_ifs_body() { 1139 1.10 kre 1140 1.10 kre reset dollar_star_in_word_empty_ifs 1141 1.10 kre 1142 1.10 kre unset xXx ; # just in case 1143 1.10 kre 1144 1.10 kre # Note that the expected results for these tests are identical 1145 1.10 kre # to those from the dollar_star_with_empty_ifs test. It should 1146 1.10 kre # never make a difference whether we expand $* or ${unset:-$*} 1147 1.10 kre 1148 1.10 kre # (note expanding ${unset:-"$*"} is different, that is not tested here) 1149 1.10 kre 1150 1.10 kre check 'IFS="";set -- a b c;echo $# ${xXx:-$*}' '3 a b c' 0 # 1 1151 1.10 kre check 'IFS="";set -- a b c;echo $# "${xXx:-$*}"' '3 abc' 0 # 2 1152 1.10 kre check 'IFS="";set -- a "b c";echo $# ${xXx:-$*}' '2 a b c' 0 # 3 1153 1.10 kre check 'IFS="";set -- a "b c";echo $# "${xXx:-$*}"' '2 ab c' 0 # 4 1154 1.10 kre check 'IFS="";set -- a "b.c";echo $# ${xXx:-$*}' '2 a b.c' 0 # 5 1155 1.10 kre check 'IFS="";set -- a "b.c";echo $# "${xXx:-$*}"' '2 ab.c' 0 # 6 1156 1.10 kre check 'IFS="";set -- a b c;set -- ${xXx:-$*};echo $# ${xXx:-$*}' \ 1157 1.10 kre '3 a b c' 0 # 7 1158 1.10 kre check 'IFS="";set -- a b c;set -- "${xXx:-$*}";echo $# ${xXx:-$*}' \ 1159 1.10 kre '1 abc' 0 # 8 1160 1.10 kre check 'IFS="";set -- a "b c";set -- ${xXx:-$*};echo $# ${xXx:-$*}' \ 1161 1.10 kre '2 a b c' 0 # 9 1162 1.10 kre check 'IFS="";set -- a "b c";set -- "${xXx:-$*}";echo $# ${xXx:-$*}' \ 1163 1.10 kre '1 ab c' 0 #10 1164 1.10 kre check 'IFS="";set -- a b c;set -- ${xXx:-$*};echo $# "${xXx:-$*}"' \ 1165 1.10 kre '3 abc' 0 #11 1166 1.10 kre check 'IFS="";set -- a b c;set -- "${xXx:-$*}";echo $# "${xXx:-$*}"' \ 1167 1.10 kre '1 abc' 0 #12 1168 1.10 kre check 'IFS="";set -- a "b c";set -- ${xXx:-$*};echo $# "${xXx:-$*}"' \ 1169 1.10 kre '2 ab c' 0 #13 1170 1.10 kre check 'IFS="";set -- a "b c";set -- "${xXx:-$*}";echo $# "${xXx:-$*}"' \ 1171 1.10 kre '1 ab c' 0 #14 1172 1.10 kre 1173 1.11 kre results # FIXED: 'PR bin/52090 expect 7 of 14 subtests to fail' 1174 1.10 kre } 1175 1.10 kre 1176 1.10 kre atf_test_case dollar_star_in_quoted_word 1177 1.10 kre dollar_star_in_quoted_word_head() { 1178 1.21 kre atf_set descr 'Test expansion $* occurring in word of ${var:-"word"}' 1179 1.10 kre } 1180 1.10 kre dollar_star_in_quoted_word_body() { 1181 1.10 kre 1182 1.10 kre reset dollar_star_in_quoted_word 1183 1.10 kre 1184 1.10 kre unset xXx ; # just in case! 1185 1.10 kre 1186 1.10 kre check 'set -- a b c; echo $# ${xXx:-"$*"}' '3 a b c' 0 # 1 1187 1.10 kre check 'set -- a "b c"; echo $# ${xXx:-"$*"}' '2 a b c' 0 # 2 1188 1.10 kre check 'set -- a b c; set -- ${xXx:-"$*"} ; echo $# ${xXx-"$*"}' \ 1189 1.10 kre '1 a b c' 0 # 3 1190 1.10 kre check 'set -- a "b c"; set -- ${xXx:-"$*"} ; echo $# ${xXx-"$*"}' \ 1191 1.10 kre '1 a b c' 0 # 4 1192 1.10 kre check 'set -- a b c; set -- ${xXx:-"$*"} ; echo $# ${xXx-"$*"}' \ 1193 1.10 kre '1 a b c' 0 # 5 1194 1.10 kre check 'set -- a "b c"; set -- ${xXx:-"$*"} ; echo $# ${xXx-$*}' \ 1195 1.10 kre '1 a b c' 0 # 6 1196 1.10 kre check 'set -- a b c; set -- ${xXx:-$*} ; echo $# ${xXx-"$*"}' \ 1197 1.10 kre '3 a b c' 0 # 7 1198 1.10 kre check 'set -- a "b c"; set -- ${xXx:-$*} ; echo $# ${xXx-"$*"}' \ 1199 1.10 kre '3 a b c' 0 # 8 1200 1.10 kre 1201 1.10 kre check 'IFS=". "; set -- a b c; echo $# ${xXx:-"$*"}' '3 a.b.c' 0 # 9 1202 1.10 kre check 'IFS=". "; set -- a "b c"; echo $# ${xXx:-"$*"}' '2 a.b c' 0 #10 1203 1.10 kre check 'IFS=". "; set -- a "b.c"; echo $# ${xXx:-"$*"}' '2 a.b.c' 0 #11 1204 1.10 kre check 'IFS=". ";set -- a b c;set -- ${xXx:-"$*"};echo $# ${xXx:-"$*"}' \ 1205 1.10 kre '1 a.b.c' 0 #12 1206 1.10 kre check 'IFS=". ";set -- a "b c";set -- ${xXx:-"$*"};echo $# ${xXx:-"$*"}' \ 1207 1.10 kre '1 a.b c' 0 #13 1208 1.10 kre check 'IFS=". ";set -- a b c;set -- ${xXx:-$*};echo $# ${xXx:-"$*"}' \ 1209 1.10 kre '3 a.b.c' 0 #14 1210 1.10 kre check 'IFS=". ";set -- a "b c";set -- ${xXx:-$*};echo $# ${xXx:-"$*"}' \ 1211 1.10 kre '3 a.b.c' 0 #15 1212 1.10 kre check 'IFS=". ";set -- a b c;set -- ${xXx:-"$*"};echo $# ${xXx:-$*}' \ 1213 1.10 kre '1 a b c' 0 #16 1214 1.10 kre check 'IFS=". ";set -- a "b c";set -- ${xXx:-"$*"};echo $# ${xXx:-$*}' \ 1215 1.10 kre '1 a b c' 0 #17 1216 1.10 kre 1217 1.10 kre check 'IFS="";set -- a b c;echo $# ${xXx:-"$*"}' '3 abc' 0 #18 1218 1.10 kre check 'IFS="";set -- a "b c";echo $# ${xXx:-"$*"}' '2 ab c' 0 #19 1219 1.10 kre check 'IFS="";set -- a "b.c";echo $# ${xXx:-"$*"}' '2 ab.c' 0 #20 1220 1.10 kre check 'IFS="";set -- a b c;set -- ${xXx:-"$*"};echo $# ${xXx:-"$*"}' \ 1221 1.10 kre '1 abc' 0 #21 1222 1.10 kre check 'IFS="";set -- a "b c";set -- ${xXx:-"$*"};echo $# ${xXx:-"$*"}' \ 1223 1.10 kre '1 ab c' 0 #22 1224 1.10 kre check 'IFS="";set -- a b c;set -- ${xXx:-$*};echo $# ${xXx:-"$*"}' \ 1225 1.10 kre '3 abc' 0 #23 1226 1.10 kre check 'IFS="";set -- a "b c";set -- ${xXx:-$*};echo $# ${xXx:-"$*"}' \ 1227 1.10 kre '2 ab c' 0 #24 1228 1.10 kre check 'IFS="";set -- a b c;set -- ${xXx:-"$*"};echo $# ${xXx:-$*}' \ 1229 1.10 kre '1 abc' 0 #25 1230 1.10 kre check 'IFS="";set -- a "b c";set -- ${xXx:-"$*"};echo $# ${xXx:-$*}' \ 1231 1.10 kre '1 ab c' 0 #26 1232 1.10 kre 1233 1.11 kre results # FIXED: 'PR bin/52090 - 2 of 26 subtests expected to fail' 1234 1.10 kre } 1235 1.10 kre 1236 1.21 kre atf_test_case dollar_at_in_field_split_context 1237 1.21 kre dollar_at_in_field_split_context_head() { 1238 1.21 kre atf_set descr 'Test "$@" wth field splitting -- PR bin/54112' 1239 1.21 kre } 1240 1.21 kre dollar_at_in_field_split_context_body() { 1241 1.21 kre reset dollar_at_in_field_split_context 1242 1.21 kre 1243 1.21 kre # the simple case (no field split) which always worked 1244 1.21 kre check 'set -- ""; set -- ${0+"$@"}; echo $#' 1 0 #1 1245 1.21 kre 1246 1.21 kre # The original failure case from the bash-bug list 1247 1.21 kre check 'set -- ""; set -- ${0+"$@" "$@"}; echo $#' 2 0 #2 1248 1.21 kre 1249 1.21 kre # slightly simpler cases that triggered the same issue 1250 1.21 kre check 'set -- ""; set -- ${0+"$@" }; echo $#' 1 0 #3 1251 1.21 kre check 'set -- ""; set -- ${0+ "$@"}; echo $#' 1 0 #4 1252 1.21 kre check 'set -- ""; set -- ${0+ "$@" }; echo $#' 1 0 #5 1253 1.21 kre 1254 1.21 kre # and the bizarre 1255 1.21 kre check 'set -- ""; set -- ${0+"$@" "$@" "$@"}; echo $#' 3 0 #6 1256 1.21 kre 1257 1.21 kre # repeat tests when there is more than one set empty numeric param 1258 1.21 kre 1259 1.21 kre check 'set -- "" ""; set -- ${0+"$@"}; echo $#' 2 0 #7 1260 1.21 kre check 'set -- "" ""; set -- ${0+"$@" "$@"}; echo $#' 4 0 #8 1261 1.21 kre check 'set -- "" ""; set -- ${0+"$@" }; echo $#' 2 0 #9 1262 1.21 kre check 'set -- "" ""; set -- ${0+ "$@"}; echo $#' 2 0 #10 1263 1.21 kre check 'set -- "" ""; set -- ${0+ "$@" }; echo $#' 2 0 #11 1264 1.21 kre check 'set -- "" ""; set -- ${0+"$@" "$@" "$@"}; echo $#' \ 1265 1.21 kre 6 0 #12 1266 1.21 kre 1267 1.21 kre # Next some checks of the way the NetBSD shell 1268 1.21 kre # interprets some expressions that are POSIX unspecified. 1269 1.21 kre # Other shells might fail these tests, without that 1270 1.21 kre # being a problem. We retain these tests so accidental 1271 1.21 kre # changes in our behaviour can be detected. 1272 1.21 kre 1273 1.21 kre check 'set --; X=; set -- "$X$@"; echo $#' 0 0 #13 1274 1.21 kre check 'set --; X=; set -- "$@$X"; echo $#' 0 0 #14 1275 1.21 kre check 'set --; X=; set -- "$X$@$X"; echo $#' 0 0 #15 1276 1.21 kre check 'set --; X=; set -- "$@$@"; echo $#' 0 0 #16 1277 1.21 kre 1278 1.21 kre check 'set -- ""; X=; set -- "$X$@"; echo $#' 1 0 #17 1279 1.21 kre check 'set -- ""; X=; set -- "$@$X"; echo $#' 1 0 #19 1280 1.21 kre check 'set -- ""; X=; set -- "$X$@$X"; echo $#' 1 0 #19 1281 1.21 kre check 'set -- ""; X=; set -- "$@$@"; echo $#' 1 0 #20 1282 1.21 kre 1283 1.21 kre check 'set -- "" ""; X=; set -- "$X$@"; echo $#' 2 0 #21 1284 1.21 kre check 'set -- "" ""; X=; set -- "$@$X"; echo $#' 2 0 #22 1285 1.21 kre check 'set -- "" ""; X=; set -- "$X$@$X"; echo $#' 2 0 #23 1286 1.21 kre # Yes, this next one really is (and should be) 3... 1287 1.21 kre check 'set -- "" ""; X=; set -- "$@$@"; echo $#' 3 0 #24 1288 1.21 kre 1289 1.21 kre results 1290 1.21 kre } 1291 1.21 kre 1292 1.19 kre atf_test_case embedded_nl 1293 1.19 kre embedded_nl_head() { 1294 1.21 kre atf_set descr 'Test literal \n in xxx string in ${var-xxx}' 1295 1.19 kre } 1296 1.19 kre embedded_nl_body() { 1297 1.19 kre 1298 1.19 kre atf_check -s exit:0 -o inline:'a\nb\n' -e empty ${TEST_SH} <<- 'EOF' 1299 1.19 kre unset V 1300 1.19 kre X="${V-a 1301 1.19 kre b}" 1302 1.19 kre printf '%s\n' "${X}" 1303 1.19 kre EOF 1304 1.19 kre 1305 1.19 kre atf_check -s exit:0 -o inline:'a\nb\n' -e empty ${TEST_SH} <<- 'EOF' 1306 1.19 kre unset V 1307 1.19 kre X=${V-"a 1308 1.19 kre b"} 1309 1.19 kre printf '%s\n' "${X}" 1310 1.19 kre EOF 1311 1.19 kre 1312 1.19 kre # This should not generate a syntax error, see PR bin/53201 1313 1.19 kre atf_check -s exit:0 -o inline:'abc\n' -e empty ${TEST_SH} <<- 'EOF' 1314 1.19 kre V=abc 1315 1.19 kre X=${V-a 1316 1.19 kre b} 1317 1.19 kre printf '%s\n' "${X}" 1318 1.19 kre EOF 1319 1.19 kre 1320 1.19 kre # Nor should any of these... 1321 1.19 kre atf_check -s exit:0 -o inline:'a\nb\n' -e empty ${TEST_SH} <<- 'EOF' 1322 1.19 kre unset V 1323 1.19 kre X=${V-a 1324 1.19 kre b} 1325 1.19 kre printf '%s\n' "${X}" 1326 1.19 kre EOF 1327 1.19 kre 1328 1.19 kre atf_check -s exit:0 -o inline:'a\nb\n' -e empty ${TEST_SH} <<- 'EOF' 1329 1.19 kre unset V 1330 1.19 kre X=${V:=a 1331 1.19 kre b} 1332 1.19 kre printf '%s\n' "${X}" 1333 1.19 kre EOF 1334 1.19 kre 1335 1.19 kre atf_check -s exit:0 -o inline:'xa\nby\na\nb\n' -e empty \ 1336 1.19 kre ${TEST_SH} <<- 'EOF' 1337 1.19 kre unset V 1338 1.19 kre X=x${V:=a 1339 1.19 kre b}y 1340 1.19 kre printf '%s\n' "${X}" "${V}" 1341 1.19 kre EOF 1342 1.19 kre } 1343 1.19 kre 1344 1.22 kre check3() 1345 1.22 kre { 1346 1.22 kre check "X=foo; ${1}" "$2" 0 1347 1.22 kre check "X=; ${1}" "$3" 0 1348 1.22 kre check "unset X; ${1}" "$4" 0 1349 1.22 kre } 1350 1.22 kre 1351 1.22 kre atf_test_case alternative 1352 1.22 kre alternative_head() { 1353 1.22 kre atf_set descr 'Test various possibilities for ${var+xxx}' 1354 1.22 kre } 1355 1.22 kre alternative_body() { 1356 1.22 kre reset alternative 1357 1.22 kre 1358 1.22 kre # just to verify (validate) that the test method works as expected 1359 1.22 kre # (this is currently the very first test performed in this test set) 1360 1.22 kre check 'printf %s a b' ab 0 # 1 1361 1.22 kre 1362 1.22 kre check3 'set -- ${X+bar}; echo "$#:$1"' 1:bar 1:bar 0: # 4 1363 1.22 kre check3 'set -- ${X+}; echo "$#:$1"' 0: 0: 0: # 7 1364 1.22 kre check3 'set -- ${X+""}; echo "$#:$1"' 1: 1: 0: # 10 1365 1.22 kre check3 'set -- "${X+}"; echo "$#:$1"' 1: 1: 1: # 13 1366 1.22 kre check3 'set -- "${X+bar}"; echo "$#:$1"' 1:bar 1:bar 1: # 16 1367 1.22 kre 1368 1.22 kre check3 'set -- ${X+a b c}; echo "$#:$1"' 3:a 3:a 0: # 19 1369 1.22 kre check3 'set -- ${X+"a b c"}; echo "$#:$1"' '1:a b c' '1:a b c' 0: 1370 1.22 kre check3 'set -- "${X+a b c}"; echo "$#:$1"' '1:a b c' '1:a b c' 1: 1371 1.22 kre check3 'set -- ${X+a b\ c}; echo "$#:$1"' 2:a 2:a 0: # 28 1372 1.22 kre check3 'set -- ${X+"a b" c}; echo "$#:$1"' '2:a b' '2:a b' 0: 1373 1.22 kre 1374 1.22 kre check3 'printf %s "" ${X+}' '' '' '' # 34 1375 1.22 kre check3 'printf %s ""${X+bar}' bar bar '' # 37 1376 1.22 kre 1377 1.22 kre check3 'Y=bar; printf %s ${X+x}${Y+y}' xy xy y # 40 1378 1.22 kre check3 'Y=bar; printf %s ""${X+${Y+z}}' z z '' # 43 1379 1.22 kre check3 'Y=; printf %s ""${X+${Y+z}}' z z '' # 46 1380 1.22 kre check3 'unset Y; printf %s ""${X+${Y+z}}' '' '' '' # 49 1381 1.22 kre check3 'Y=1; printf %s a ${X+"${Y+z}"}' az az a # 52 1382 1.22 kre 1383 1.22 kre check3 'printf %s ${X+}x}' x} x} x} # 55 1384 1.22 kre check3 'printf %s ${X+}}' } } } # 58 1385 1.22 kre check3 'printf %s "" ${X+"}"x}' }x }x '' # 61 1386 1.22 kre check3 'printf %s "" ${X+\}x}' }x }x '' # 64 1387 1.22 kre check3 'printf %s "${X+\}x}"' }x }x '' # 67 1388 1.22 kre check3 'printf %s "${X+\}}"' } } '' # 70 1389 1.22 kre 1390 1.22 kre check3 'set -- ${X:+bar}; echo "$#:$1"' 1:bar 0: 0: # 73 1391 1.22 kre check3 'set -- ${X:+}; echo "$#:$1"' 0: 0: 0: # 76 1392 1.22 kre check3 'set -- ${X:+""}; echo "$#:$1"' 1: 0: 0: # 79 1393 1.22 kre check3 'set -- "${X:+}"; echo "$#:$1"' 1: 1: 1: # 80 1394 1.22 kre check3 'set -- "${X:+bar}"; echo "$#:$1"' 1:bar 1: 1: # 83 1395 1.22 kre 1396 1.22 kre check3 'set -- ${X:+a b c}; echo "$#:$1"' 3:a 0: 0: # 86 1397 1.22 kre check3 'set -- ${X:+"a b c"}; echo "$#:$1"' '1:a b c' 0: 0: # 89 1398 1.22 kre check3 'set -- "${X:+a b c}"; echo "$#:$1"' '1:a b c' 1: 1: # 92 1399 1.22 kre check3 'set -- ${X:+a b\ c}; echo "$#:$1"' 2:a 0: 0: # 95 1400 1.22 kre check3 'set -- ${X:+"a b" c}; echo "$#:$1"' '2:a b' 0: 0: # 98 1401 1.22 kre 1402 1.22 kre check3 'printf %s "" ${X:+}' '' '' '' #101 1403 1.22 kre check3 'printf %s ""${X:+bar}' bar '' '' #104 1404 1.22 kre 1405 1.22 kre check3 'Y=bar; printf %s ${X:+x}${Y:+y}' xy y y #107 1406 1.22 kre check3 'Y=bar; printf %s ""${X:+${Y:+z}}' z '' '' #110 1407 1.22 kre check3 'Y=; printf %s ""${X:+${Y+z}}' z '' '' #113 1408 1.22 kre check3 'Y=; printf %s ""${X:+${Y:+z}}' '' '' '' #116 1409 1.22 kre check3 'unset Y; printf %s ""${X:+${Y:+z}}' '' '' '' #119 1410 1.22 kre check3 'Y=1; printf %s a ${X:+"${Y:+z}"}' az a a #122 1411 1.22 kre 1412 1.22 kre check3 'printf %s ${X:+}x}' x} x} x} #125 1413 1.22 kre check3 'printf %s ${X:+}}' } } } #128 1414 1.22 kre check3 'printf %s "" ${X:+"}"x}' }x '' '' #131 1415 1.22 kre check3 'printf %s "" ${X:+\}x}' }x '' '' #134 1416 1.22 kre check3 'printf %s "${X:+\}x}"' }x '' '' #137 1417 1.22 kre check3 'printf %s "${X:+\}}"' } '' '' #140 1418 1.22 kre 1419 1.22 kre results 1420 1.22 kre } 1421 1.22 kre 1422 1.22 kre atf_test_case default 1423 1.22 kre default_head() { 1424 1.22 kre atf_set descr 'Test various possibilities for ${var-xxx}' 1425 1.22 kre } 1426 1.22 kre default_body() { 1427 1.22 kre reset default 1428 1.22 kre 1429 1.22 kre check3 'set -- ${X-bar}; echo "$#:$1"' 1:foo 0: 1:bar # 3 1430 1.22 kre check3 'set -- ${X-}; echo "$#:$1"' 1:foo 0: 0: # 6 1431 1.22 kre check3 'set -- ${X-""}; echo "$#:$1"' 1:foo 0: 1: # 9 1432 1.22 kre check3 'set -- "${X-}"; echo "$#:$1"' 1:foo 1: 1: # 12 1433 1.22 kre check3 'set -- "${X-bar}"; echo "$#:$1"' 1:foo 1: 1:bar # 15 1434 1.22 kre 1435 1.22 kre check3 'set -- ${X-a b c}; echo "$#:$1"' 1:foo 0: 3:a # 18 1436 1.22 kre check3 'set -- ${X-"a b c"}; echo "$#:$1"' 1:foo 0: '1:a b c' #21 1437 1.22 kre check3 'set -- "${X-a b c}"; echo "$#:$1"' 1:foo 1: '1:a b c' #24 1438 1.22 kre check3 'set -- ${X-a b\ c}; echo "$#:$1"' 1:foo 0: 2:a # 27 1439 1.22 kre check3 'set -- ${X-"a b" c}; echo "$#:$1"' 1:foo 0: '2:a b' #30 1440 1.22 kre 1441 1.22 kre check3 'printf %s "" ${X-}' foo '' '' # 33 1442 1.22 kre check3 'printf %s ""${X-bar}' foo '' bar # 36 1443 1.22 kre 1444 1.22 kre check3 'Y=bar; printf %s ${X-x}${Y-y}' foobar bar xbar # 39 1445 1.22 kre check3 'Y=bar; printf %s ""${X-${Y-z}}' foo '' bar # 42 1446 1.22 kre check3 'Y=; printf %s ""${X-${Y-z}}' foo '' '' # 45 1447 1.22 kre check3 'unset Y; printf %s ""${X-${Y-z}}' foo '' z # 48 1448 1.22 kre check3 'Y=1; printf %s a ${X-"${Y-z}"}' afoo a a1 # 51 1449 1.22 kre 1450 1.22 kre check3 'printf %s ${X-}x}' foox} x} x} # 54 1451 1.22 kre check3 'printf %s ${X-}}' foo} } } # 57 1452 1.22 kre check3 'printf %s ${X-{}}' foo} } {} # 60 1453 1.22 kre check3 'printf %s "" ${X-"}"x}' foo '' }x # 63 1454 1.22 kre check3 'printf %s "" ${X-\}x}' foo '' }x # 66 1455 1.22 kre check3 'printf %s "${X-\}x}"' foo '' }x # 69 1456 1.22 kre check3 'printf %s "${X-\}}"' foo '' } # 72 1457 1.22 kre 1458 1.22 kre check3 'set -- ${X:-bar}; echo "$#:$1"' 1:foo 1:bar 1:bar #75 1459 1.22 kre check3 'set -- ${X:-}; echo "$#:$1"' 1:foo 0: 0: # 78 1460 1.22 kre check3 'set -- ${X:-""}; echo "$#:$1"' 1:foo 1: 1: # 81 1461 1.22 kre check3 'set -- "${X:-}"; echo "$#:$1"' 1:foo 1: 1: # 84 1462 1.22 kre check3 'set -- "${X:-bar}"; echo "$#:$1"' 1:foo 1:bar 1:bar #87 1463 1.22 kre 1464 1.22 kre check3 'set -- ${X:-a b c}; echo "$#:$1"' 1:foo 3:a 3:a # 90 1465 1.22 kre check3 'set -- ${X:-"a b c"}; echo "$#:$1"' 1:foo '1:a b c' '1:a b c' 1466 1.22 kre check3 'set -- "${X:-a b c}"; echo "$#:$1"' 1:foo '1:a b c' '1:a b c' 1467 1.22 kre check3 'set -- ${X:-a b\ c}; echo "$#:$1"' 1:foo 2:a 2:a # 99 1468 1.22 kre check3 'set -- ${X:-"a b" c}; echo "$#:$1"' 1:foo '2:a b' '2:a b' 1469 1.22 kre 1470 1.22 kre check3 'printf %s "" ${X:-}' foo '' '' #105 1471 1.22 kre check3 'printf %s ""${X:-bar}' foo bar bar #108 1472 1.22 kre 1473 1.22 kre check3 'Y=bar; printf %s ${X:-x}${Y:-y}' foobar xbar xbar #111 1474 1.22 kre check3 'Y=bar; printf %s ""${X:-${Y:-z}}' foo bar bar #114 1475 1.22 kre check3 'Y=; printf %s ""${X:-${Y-z}}' foo '' '' #117 1476 1.22 kre check3 'Y=; printf %s ""${X:-${Y:-z}}' foo z z #120 1477 1.22 kre check3 'unset Y; printf %s ""${X:-${Y:-z}}' foo z z #123 1478 1.22 kre check3 'Y=1; printf %s a ${X:-"${Y:-z}"}' afoo a1 a1 #126 1479 1.22 kre 1480 1.22 kre check3 'printf %s ${X:-}x}' foox} x} x} #129 1481 1.22 kre check3 'printf %s ${X:-}}' foo} } } #132 1482 1.22 kre check3 'printf %s ${X:-{}}' foo} {} {} #135 1483 1.22 kre check3 'printf %s "" ${X:-"}"x}' foo }x }x #138 1484 1.22 kre check3 'printf %s "" ${X:-\}x}' foo }x }x #141 1485 1.22 kre check3 'printf %s "${X:-\}x}"' foo }x }x #144 1486 1.22 kre check3 'printf %s "${X:-\}}"' foo } } #147 1487 1.22 kre 1488 1.22 kre results 1489 1.22 kre } 1490 1.22 kre 1491 1.22 kre atf_test_case assign 1492 1.22 kre assign_head() { 1493 1.22 kre atf_set descr 'Test various possibilities for ${var=xxx}' 1494 1.22 kre } 1495 1.22 kre assign_body() { 1496 1.22 kre reset assign 1497 1.22 kre 1498 1.22 kre check3 'set -- ${X=bar}; echo "$#:$1"' 1:foo 0: 1:bar # 3 1499 1.22 kre check3 'set -- ${X=}; echo "$#:$1"' 1:foo 0: 0: # 6 1500 1.22 kre check3 'set -- ${X=""}; echo "$#:$1"' 1:foo 0: 0: # 9 1501 1.22 kre check3 'set -- "${X=}"; echo "$#:$1"' 1:foo 1: 1: # 12 1502 1.22 kre check3 'set -- "${X=bar}"; echo "$#:$1"' 1:foo 1: 1:bar # 15 1503 1.22 kre 1504 1.22 kre check3 'set -- ${X=a b c}; echo "$#:$1"' 1:foo 0: 3:a # 18 1505 1.22 kre check3 'set -- ${X="a b c"}; echo "$#:$1"' 1:foo 0: 3:a # 21 1506 1.22 kre check3 'set -- "${X=a b c}"; echo "$#:$1"' 1:foo 1: '1:a b c' #24 1507 1.22 kre check3 'set -- ${X=a b\ c}; echo "$#:$1"' 1:foo 0: 3:a # 27 1508 1.22 kre check3 'set -- ${X="a b" c}; echo "$#:$1"' 1:foo 0: 3:a # 30 1509 1.22 kre 1510 1.22 kre check3 'printf %s "" ${X=}' foo '' '' # 33 1511 1.22 kre check3 'printf %s ""${X=bar}' foo '' bar # 36 1512 1.22 kre 1513 1.22 kre check3 'Y=bar; printf %s ${X=x}${Y=y}' foobar bar xbar # 39 1514 1.22 kre check3 'Y=bar; printf %s ""${X=${Y=z}}' foo '' bar # 42 1515 1.22 kre check3 'Y=; printf %s ""${X=${Y=z}}' foo '' '' # 45 1516 1.22 kre check3 'unset Y; printf %s ""${X=${Y=z}}' foo '' z # 48 1517 1.22 kre check3 'Y=1; printf %s a ${X="${Y=z}"}' afoo a a1 # 51 1518 1.22 kre 1519 1.22 kre check3 'printf %s ${X=}x}' foox} x} x} # 54 1520 1.22 kre check3 'printf %s ${X=}}' foo} } } # 57 1521 1.22 kre check3 'printf %s ${X={}}' foo} } {} # 60 1522 1.22 kre check3 'printf %s "" ${X="}"x}' foo '' }x # 63 1523 1.22 kre check3 'printf %s "" ${X=\}x}' foo '' }x # 66 1524 1.22 kre check3 'printf %s "${X=\}x}"' foo '' }x # 69 1525 1.22 kre check3 'printf %s "${X=\}}"' foo '' } # 72 1526 1.22 kre 1527 1.22 kre check3 'set -- ${X=a b c}; echo "$#:$1:$X"' 1:foo:foo 0:: '3:a:a b c' 1528 1.22 kre check3 'set -- ${X="a b c"}; echo "$#:$1:$X"' 1:foo:foo 0:: '3:a:a b c' 1529 1.22 kre check3 'set -- "${X=a b c}"; echo "$#:$1:$X"' \ 1530 1.22 kre 1:foo:foo 1:: '1:a b c:a b c' 1531 1.22 kre check3 'set -- ${X=a b\ c}; echo "$#:$1:$X"' 1:foo:foo 0:: '3:a:a b c' 1532 1.22 kre check3 'set -- ${X="a b" c}; echo "$#:$1:$X"' 1:foo:foo 0:: '3:a:a b c' 1533 1.22 kre 1534 1.22 kre check3 'printf %s ${X=}x}; printf :%s "${X-U}"' foox}:foo x}: x}: #90 1535 1.22 kre check3 'printf %s ${X=}}; printf :%s "${X-U}"' foo}:foo }: }: #93 1536 1.22 kre check3 'printf %s ${X={}}; printf :%s "${X-U}"' foo}:foo }: {}:{ #96 1537 1.22 kre 1538 1.22 kre check3 'set -- ${X:=bar}; echo "$#:$1"' 1:foo 1:bar 1:bar # 99 1539 1.22 kre check3 'set -- ${X:=}; echo "$#:$1"' 1:foo 0: 0: #102 1540 1.22 kre check3 'set -- ${X:=""}; echo "$#:$1"' 1:foo 0: 0: #105 1541 1.22 kre check3 'set -- "${X:=}"; echo "$#:$1"' 1:foo 1: 1: #108 1542 1.22 kre check3 'set -- "${X:=bar}"; echo "$#:$1"' 1:foo 1:bar 1:bar #111 1543 1.22 kre 1544 1.22 kre check3 'set -- ${X:=a b c}; echo "$#:$1"' 1:foo 3:a 3:a #114 1545 1.22 kre check3 'set -- ${X:="a b c"}; echo "$#:$1"' 1:foo 3:a 3:a #117 1546 1.22 kre check3 'set -- "${X:=a b c}"; echo "$#:$1"' 1:foo '1:a b c' '1:a b c' 1547 1.22 kre check3 'set -- ${X:=a b\ c}; echo "$#:$1"' 1:foo 3:a 3:a #123 1548 1.22 kre check3 'set -- ${X:="a b" c}; echo "$#:$1"' 1:foo 3:a 3:a #126 1549 1.22 kre 1550 1.22 kre check3 'printf %s "" ${X:=}' foo '' '' #129 1551 1.22 kre check3 'printf %s ""${X:=bar}' foo bar bar #132 1552 1.22 kre 1553 1.22 kre check3 'Y=bar; printf %s ${X:=x}${Y:=y}' foobar xbar xbar #135 1554 1.22 kre check3 'Y=bar; printf %s ""${X:=${Y:=z}}' foo bar bar #138 1555 1.22 kre check3 'Y=; printf %s ""${X:=${Y=z}}' foo '' '' #141 1556 1.22 kre check3 'Y=; printf %s ""${X:=${Y:=z}}' foo z z #144 1557 1.22 kre check3 'unset Y; printf %s ""${X:=${Y:=z}}' foo z z #147 1558 1.22 kre check3 'Y=1; printf %s a ${X:="${Y:=z}"}' afoo a1 a1 #150 1559 1.22 kre 1560 1.22 kre check3 'printf %s ${X:=}x}' foox} x} x} #153 1561 1.22 kre check3 'printf %s ${X:=}}' foo} } } #156 1562 1.22 kre check3 'printf %s ${X:={}}' foo} {} {} #159 1563 1.22 kre check3 'printf %s "" ${X:="}"x}' foo }x }x #162 1564 1.22 kre check3 'printf %s "" ${X:=\}x}' foo }x }x #165 1565 1.22 kre check3 'printf %s "${X:=\}x}"' foo }x }x #168 1566 1.22 kre check3 'printf %s "${X:=\}}"' foo } } #171 1567 1.22 kre 1568 1.22 kre check3 'set -- ${X:=a b c}; echo "$#:$1:$X"' \ 1569 1.22 kre 1:foo:foo '3:a:a b c' '3:a:a b c' #174 1570 1.22 kre check3 'set -- ${X:="a b c"}; echo "$#:$1:$X"' \ 1571 1.22 kre 1:foo:foo '3:a:a b c' '3:a:a b c' #177 1572 1.22 kre check3 'set -- "${X:=a b c}"; echo "$#:$1:$X"' \ 1573 1.22 kre 1:foo:foo '1:a b c:a b c' '1:a b c:a b c' #180 1574 1.22 kre check3 'set -- ${X:=a b\ c}; echo "$#:$1:$X"' \ 1575 1.22 kre 1:foo:foo '3:a:a b c' '3:a:a b c' #183 1576 1.22 kre check3 'set -- ${X:="a b" c}; echo "$#:$1:$X"' \ 1577 1.22 kre 1:foo:foo '3:a:a b c' '3:a:a b c' #186 1578 1.22 kre 1579 1.22 kre check3 'printf %s ${X:=}x}; printf :%s "${X-U}"' foox}:foo x}: x}: 1580 1.22 kre check3 'printf %s ${X:=}}; printf :%s "${X-U}"' foo}:foo }: }: 1581 1.22 kre check3 'printf %s ${X:=\}}; printf :%s "${X-U}"' foo:foo }:} }:} 1582 1.22 kre check3 'printf %s ${X:={}}; printf :%s "${X-U}"' foo}:foo {}:{ {}:{ 1583 1.22 kre #198 1584 1.22 kre 1585 1.22 kre results 1586 1.22 kre } 1587 1.22 kre 1588 1.22 kre atf_test_case error 1589 1.22 kre error_head() { 1590 1.22 kre atf_set descr 'Test various possibilities for ${var?xxx}' 1591 1.22 kre } 1592 1.22 kre error_body() { 1593 1.22 kre reset error 1594 1.22 kre 1595 1.22 kre check 'X=foo; printf %s ${X?X is not set}' foo 0 #1 1596 1.22 kre check 'X=; printf %s ${X?X is not set}' '' 0 #2 1597 1.22 kre check 'unset X; printf %s ${X?X is not set}' '' 2 #3 1598 1.22 kre 1599 1.22 kre check 'X=foo; printf %s ${X?}' foo 0 #4 1600 1.22 kre check 'X=; printf %s ${X?}' '' 0 #5 1601 1.22 kre check 'unset X; printf %s ${X?}' '' 2 #6 1602 1.22 kre 1603 1.22 kre check 'X=foo; printf %s ${X:?X is not set}' foo 0 #7 1604 1.22 kre check 'X=; printf %s ${X:?X is not set}' '' 2 #8 1605 1.22 kre check 'unset X; printf %s ${X:?X is not set}' '' 2 #9 1606 1.22 kre 1607 1.22 kre check 'X=foo; printf %s ${X:?}' foo 0 #10 1608 1.22 kre check 'X=; printf %s ${X:?}' '' 2 #11 1609 1.22 kre check 'unset X; printf %s ${X:?}' '' 2 #12 1610 1.22 kre 1611 1.22 kre results 1612 1.22 kre } 1613 1.22 kre 1614 1.1 jruoho atf_init_test_cases() { 1615 1.10 kre # Listed here in the order ATF runs them, not the order from above 1616 1.10 kre 1617 1.22 kre atf_add_test_case alternative 1618 1.10 kre atf_add_test_case arithmetic 1619 1.22 kre atf_add_test_case assign 1620 1.22 kre atf_add_test_case default 1621 1.1 jruoho atf_add_test_case dollar_at 1622 1.21 kre atf_add_test_case dollar_at_empty_and_conditional 1623 1.21 kre atf_add_test_case dollar_at_in_field_split_context 1624 1.20 kre atf_add_test_case dollar_at_unquoted_or_conditional 1625 1.1 jruoho atf_add_test_case dollar_at_with_text 1626 1.12 kre atf_add_test_case dollar_hash 1627 1.10 kre atf_add_test_case dollar_star 1628 1.10 kre atf_add_test_case dollar_star_in_quoted_word 1629 1.10 kre atf_add_test_case dollar_star_in_word 1630 1.10 kre atf_add_test_case dollar_star_in_word_empty_ifs 1631 1.10 kre atf_add_test_case dollar_star_with_empty_ifs 1632 1.19 kre atf_add_test_case embedded_nl 1633 1.22 kre atf_add_test_case error 1634 1.2 ast atf_add_test_case iteration_on_null_parameter 1635 1.6 christos atf_add_test_case iteration_on_quoted_null_parameter 1636 1.6 christos atf_add_test_case iteration_on_null_or_null_parameter 1637 1.6 christos atf_add_test_case iteration_on_null_or_missing_parameter 1638 1.7 christos atf_add_test_case shell_params 1639 1.10 kre atf_add_test_case strip 1640 1.18 kre atf_add_test_case tilde 1641 1.14 kre atf_add_test_case wrap_strip 1642 1.9 kre atf_add_test_case var_with_embedded_cmdsub 1643 1.10 kre atf_add_test_case varpattern_backslashes 1644 1.1 jruoho } 1645