| 1 | # |
| 2 | # Tests for the args in: |
| 3 | # |
| 4 | # ${foo:-} |
| 5 | # |
| 6 | # I think the weird single quote behavior is a bug, but everyone agrees. It's |
| 7 | # a consequence of quote removal. |
| 8 | # |
| 9 | # WEIRD: single quoted default, inside double quotes. Oh I guess this is |
| 10 | # because double quotes don't treat single quotes as special? |
| 11 | # |
| 12 | # OK here is the issue. If we have ${} bare, then the default is parsed as |
| 13 | # LexState.OUTER. If we have "${}", then it's parsed as LexState.DQ. That |
| 14 | # makes sense I guess. Vim's syntax highlighting is throwing me off. |
| 15 | |
| 16 | #### "${empty:-}" |
| 17 | empty= |
| 18 | argv.py "${empty:-}" |
| 19 | ## stdout: [''] |
| 20 | |
| 21 | #### ${empty:-} |
| 22 | empty= |
| 23 | argv.py ${empty:-} |
| 24 | ## stdout: [] |
| 25 | |
| 26 | #### array with empty values |
| 27 | declare -a A=('' x "" '') |
| 28 | argv.py "${A[@]}" |
| 29 | ## stdout: ['', 'x', '', ''] |
| 30 | ## N-I dash stdout-json: "" |
| 31 | ## N-I dash status: 2 |
| 32 | ## N-I mksh stdout-json: "" |
| 33 | ## N-I mksh status: 1 |
| 34 | |
| 35 | #### substitution of IFS character, quoted and unquoted |
| 36 | IFS=: |
| 37 | s=: |
| 38 | argv.py $s |
| 39 | argv.py "$s" |
| 40 | ## STDOUT: |
| 41 | [''] |
| 42 | [':'] |
| 43 | ## END |
| 44 | |
| 45 | #### :- |
| 46 | empty='' |
| 47 | argv.py ${empty:-a} ${Unset:-b} |
| 48 | ## stdout: ['a', 'b'] |
| 49 | |
| 50 | #### - |
| 51 | empty='' |
| 52 | argv.py ${empty-a} ${Unset-b} |
| 53 | # empty one is still elided! |
| 54 | ## stdout: ['b'] |
| 55 | |
| 56 | #### Inner single quotes |
| 57 | argv.py ${Unset:-'b'} |
| 58 | ## stdout: ['b'] |
| 59 | |
| 60 | #### Inner single quotes, outer double quotes |
| 61 | # This is the WEIRD ONE. Single quotes appear outside. But all shells agree! |
| 62 | argv.py "${Unset:-'b'}" |
| 63 | ## stdout: ["'b'"] |
| 64 | |
| 65 | #### Inner double quotes |
| 66 | argv.py ${Unset:-"b"} |
| 67 | ## stdout: ['b'] |
| 68 | |
| 69 | #### Inner double quotes, outer double quotes |
| 70 | argv.py "${Unset-"b"}" |
| 71 | ## stdout: ['b'] |
| 72 | |
| 73 | #### Multiple words: no quotes |
| 74 | argv.py ${Unset:-a b c} |
| 75 | ## stdout: ['a', 'b', 'c'] |
| 76 | |
| 77 | #### Multiple words: no outer quotes, inner single quotes |
| 78 | argv.py ${Unset:-'a b c'} |
| 79 | ## stdout: ['a b c'] |
| 80 | |
| 81 | #### Multiple words: no outer quotes, inner double quotes |
| 82 | argv.py ${Unset:-"a b c"} |
| 83 | ## stdout: ['a b c'] |
| 84 | |
| 85 | #### Multiple words: outer double quotes, no inner quotes |
| 86 | argv.py "${Unset:-a b c}" |
| 87 | ## stdout: ['a b c'] |
| 88 | |
| 89 | #### Multiple words: outer double quotes, inner double quotes |
| 90 | argv.py "${Unset:-"a b c"}" |
| 91 | ## stdout: ['a b c'] |
| 92 | |
| 93 | #### Multiple words: outer double quotes, inner single quotes |
| 94 | argv.py "${Unset:-'a b c'}" |
| 95 | # WEIRD ONE. |
| 96 | ## stdout: ["'a b c'"] |
| 97 | |
| 98 | #### Mixed inner quotes |
| 99 | argv.py ${Unset:-"a b" c} |
| 100 | ## stdout: ['a b', 'c'] |
| 101 | |
| 102 | #### Mixed inner quotes with outer quotes |
| 103 | argv.py "${Unset:-"a b" c}" |
| 104 | ## stdout: ['a b c'] |
| 105 | |
| 106 | #### part_value tree with multiple words |
| 107 | argv.py ${a:-${a:-"1 2" "3 4"}5 "6 7"} |
| 108 | ## stdout: ['1 2', '3 45', '6 7'] |
| 109 | |
| 110 | #### part_value tree on RHS |
| 111 | v=${a:-${a:-"1 2" "3 4"}5 "6 7"} |
| 112 | argv.py "${v}" |
| 113 | ## stdout: ['1 2 3 45 6 7'] |
| 114 | |
| 115 | #### Var with multiple words: no quotes |
| 116 | var='a b c' |
| 117 | argv.py ${Unset:-$var} |
| 118 | ## stdout: ['a', 'b', 'c'] |
| 119 | |
| 120 | #### Multiple words: no outer quotes, inner single quotes |
| 121 | var='a b c' |
| 122 | argv.py ${Unset:-'$var'} |
| 123 | ## stdout: ['$var'] |
| 124 | |
| 125 | #### Multiple words: no outer quotes, inner double quotes |
| 126 | var='a b c' |
| 127 | argv.py ${Unset:-"$var"} |
| 128 | ## stdout: ['a b c'] |
| 129 | |
| 130 | #### Multiple words: outer double quotes, no inner quotes |
| 131 | var='a b c' |
| 132 | argv.py "${Unset:-$var}" |
| 133 | ## stdout: ['a b c'] |
| 134 | |
| 135 | #### Multiple words: outer double quotes, inner double quotes |
| 136 | var='a b c' |
| 137 | argv.py "${Unset:-"$var"}" |
| 138 | ## stdout: ['a b c'] |
| 139 | |
| 140 | #### Multiple words: outer double quotes, inner single quotes |
| 141 | # WEIRD ONE. |
| 142 | # |
| 143 | # I think I should just disallow any word with single quotes inside double |
| 144 | # quotes. |
| 145 | var='a b c' |
| 146 | argv.py "${Unset:-'$var'}" |
| 147 | ## stdout: ["'a b c'"] |
| 148 | |
| 149 | #### No outer quotes, Multiple internal quotes |
| 150 | # It's like a single command word. Parts are joined directly. |
| 151 | var='a b c' |
| 152 | argv.py ${Unset:-A$var " $var"D E F} |
| 153 | ## stdout: ['Aa', 'b', 'c', ' a b cD', 'E', 'F'] |
| 154 | |
| 155 | #### Strip a string with single quotes, unquoted |
| 156 | foo="'a b c d'" |
| 157 | argv.py ${foo%d\'} |
| 158 | ## stdout: ["'a", 'b', 'c'] |
| 159 | |
| 160 | #### Strip a string with single quotes, double quoted |
| 161 | foo="'a b c d'" |
| 162 | argv.py "${foo%d\'}" |
| 163 | ## STDOUT: |
| 164 | ["'a b c "] |
| 165 | ## END |
| 166 | |
| 167 | #### The string to strip is space sensitive |
| 168 | foo='a b c d' |
| 169 | argv.py "${foo%c d}" "${foo%c d}" |
| 170 | ## stdout: ['a b ', 'a b c d'] |
| 171 | |
| 172 | #### The string to strip can be single quoted, outer is unquoted |
| 173 | foo='a b c d' |
| 174 | argv.py ${foo%'c d'} ${foo%'c d'} |
| 175 | ## stdout: ['a', 'b', 'a', 'b', 'c', 'd'] |
| 176 | |
| 177 | #### Syntax error for single quote in double quote |
| 178 | foo="'a b c d'" |
| 179 | argv.py "${foo%d'}" |
| 180 | ## stdout-json: "" |
| 181 | ## status: 2 |
| 182 | ## OK mksh status: 1 |
| 183 | |
| 184 | #### "${undef-'c d'}" and "${foo%'c d'}" are parsed differently |
| 185 | |
| 186 | # quotes are LITERAL here |
| 187 | argv.py "${undef-'c d'}" "${undef-'c d'}" |
| 188 | argv.py ${undef-'c d'} ${undef-'c d'} |
| 189 | |
| 190 | echo --- |
| 191 | |
| 192 | # quotes are RESPECTED here |
| 193 | foo='a b c d' |
| 194 | argv.py "${foo%'c d'}" "${foo%'c d'}" |
| 195 | |
| 196 | case $SH in (dash) exit ;; esac |
| 197 | |
| 198 | argv.py "${foo//'c d'/zzz}" "${foo//'c d'/zzz}" |
| 199 | argv.py "${foo//'c d'/'zzz'}" "${foo//'c d'/'zzz'}" |
| 200 | |
| 201 | ## STDOUT: |
| 202 | ["'c d'", "'c d'"] |
| 203 | ['c d', 'c d'] |
| 204 | --- |
| 205 | ['a b ', 'a b c d'] |
| 206 | ['a b zzz', 'a b c d'] |
| 207 | ['a b zzz', 'a b c d'] |
| 208 | ## END |
| 209 | ## OK dash STDOUT: |
| 210 | ["'c d'", "'c d'"] |
| 211 | ['c d', 'c d'] |
| 212 | --- |
| 213 | ['a b ', 'a b c d'] |
| 214 | ## END |
| 215 | |
| 216 | #### $'' allowed within VarSub arguments |
| 217 | # Odd behavior of bash/mksh: $'' is recognized but NOT ''! |
| 218 | x=abc |
| 219 | echo ${x%$'b'*} |
| 220 | echo "${x%$'b'*}" # git-prompt.sh relies on this |
| 221 | ## STDOUT: |
| 222 | a |
| 223 | a |
| 224 | ## END |
| 225 | ## N-I dash STDOUT: |
| 226 | abc |
| 227 | abc |
| 228 | ## END |
| 229 | |
| 230 | #### # operator with single quoted arg (dash/ash and bash/mksh disagree, reported by Crestwave) |
| 231 | var=a |
| 232 | echo -${var#'a'}- |
| 233 | echo -"${var#'a'}"- |
| 234 | var="'a'" |
| 235 | echo -${var#'a'}- |
| 236 | echo -"${var#'a'}"- |
| 237 | ## STDOUT: |
| 238 | -- |
| 239 | -- |
| 240 | -'a'- |
| 241 | -'a'- |
| 242 | ## END |
| 243 | ## OK ash STDOUT: |
| 244 | -- |
| 245 | -a- |
| 246 | -'a'- |
| 247 | -- |
| 248 | ## END |
| 249 | |
| 250 | #### / operator with single quoted arg (causes syntax error in regex in OSH, reported by Crestwave) |
| 251 | var="++--''++--''" |
| 252 | echo no plus or minus "${var//[+-]}" |
| 253 | echo no plus or minus "${var//['+-']}" |
| 254 | ## STDOUT: |
| 255 | no plus or minus '''' |
| 256 | no plus or minus '''' |
| 257 | ## END |
| 258 | ## status: 0 |
| 259 | ## BUG ash STDOUT: |
| 260 | no plus or minus '''' |
| 261 | no plus or minus ++--++-- |
| 262 | ## END |
| 263 | ## BUG ash status: 0 |
| 264 | ## N-I dash stdout-json: "" |
| 265 | ## N-I dash status: 2 |
| 266 | |
| 267 | #### single quotes work inside character classes |
| 268 | x='a[[[---]]]b' |
| 269 | echo "${x//['[]']}" |
| 270 | ## STDOUT: |
| 271 | a---b |
| 272 | ## END |
| 273 | ## BUG ash STDOUT: |
| 274 | a[[[---]]]b |
| 275 | ## END |
| 276 | ## N-I dash stdout-json: "" |
| 277 | ## N-I dash status: 2 |
| 278 | |
| 279 | #### comparison: :- operator with single quoted arg |
| 280 | echo ${unset:-'a'} |
| 281 | echo "${unset:-'a'}" |
| 282 | ## STDOUT: |
| 283 | a |
| 284 | 'a' |
| 285 | ## END |
| 286 | |
| 287 | |
| 288 | #### Right Brace as argument (similar to #702) |
| 289 | |
| 290 | echo "${var-}}" |
| 291 | echo "${var-\}}" |
| 292 | echo "${var-'}'}" |
| 293 | echo "${var-"}"}" |
| 294 | ## STDOUT: |
| 295 | } |
| 296 | } |
| 297 | ''} |
| 298 | } |
| 299 | ## END |
| 300 | ## BUG bash STDOUT: |
| 301 | } |
| 302 | } |
| 303 | '}' |
| 304 | } |
| 305 | ## END |
| 306 | ## BUG yash STDOUT: |
| 307 | } |
| 308 | } |
| 309 | } |
| 310 | } |
| 311 | ## END |
| 312 |