| 1 | #!/usr/bin/env bash |
| 2 | # |
| 3 | # Tests for the args in: |
| 4 | # |
| 5 | # ${foo:-} |
| 6 | # |
| 7 | # I think the weird single quote behavior is a bug, but everyone agrees. It's |
| 8 | # a consequence of quote removal. |
| 9 | # |
| 10 | # WEIRD: single quoted default, inside double quotes. Oh I guess this is |
| 11 | # because double quotes don't treat single quotes as special? |
| 12 | # |
| 13 | # OK here is the issue. If we have ${} bare, then the default is parsed as |
| 14 | # LexState.OUTER. If we have "${}", then it's parsed as LexState.DQ. That |
| 15 | # makes sense I guess. Vim's syntax highlighting is throwing me off. |
| 16 | |
| 17 | #### "${empty:-}" |
| 18 | empty= |
| 19 | argv.py "${empty:-}" |
| 20 | ## stdout: [''] |
| 21 | |
| 22 | #### ${empty:-} |
| 23 | empty= |
| 24 | argv.py ${empty:-} |
| 25 | ## stdout: [] |
| 26 | |
| 27 | #### array with empty values |
| 28 | declare -a A=('' x "" '') |
| 29 | argv.py "${A[@]}" |
| 30 | ## stdout: ['', 'x', '', ''] |
| 31 | ## N-I dash stdout-json: "" |
| 32 | ## N-I dash status: 2 |
| 33 | ## N-I mksh stdout-json: "" |
| 34 | ## N-I mksh status: 1 |
| 35 | |
| 36 | #### substitution of IFS character, quoted and unquoted |
| 37 | IFS=: |
| 38 | s=: |
| 39 | argv.py $s |
| 40 | argv.py "$s" |
| 41 | ## STDOUT: |
| 42 | [''] |
| 43 | [':'] |
| 44 | ## END |
| 45 | |
| 46 | #### :- |
| 47 | empty='' |
| 48 | argv.py ${empty:-a} ${Unset:-b} |
| 49 | ## stdout: ['a', 'b'] |
| 50 | |
| 51 | #### - |
| 52 | empty='' |
| 53 | argv.py ${empty-a} ${Unset-b} |
| 54 | # empty one is still elided! |
| 55 | ## stdout: ['b'] |
| 56 | |
| 57 | #### Inner single quotes |
| 58 | argv.py ${Unset:-'b'} |
| 59 | ## stdout: ['b'] |
| 60 | |
| 61 | #### Inner single quotes, outer double quotes |
| 62 | # This is the WEIRD ONE. Single quotes appear outside. But all shells agree! |
| 63 | argv.py "${Unset:-'b'}" |
| 64 | ## stdout: ["'b'"] |
| 65 | |
| 66 | #### Inner double quotes |
| 67 | argv.py ${Unset:-"b"} |
| 68 | ## stdout: ['b'] |
| 69 | |
| 70 | #### Inner double quotes, outer double quotes |
| 71 | argv.py "${Unset-"b"}" |
| 72 | ## stdout: ['b'] |
| 73 | |
| 74 | #### Multiple words: no quotes |
| 75 | argv.py ${Unset:-a b c} |
| 76 | ## stdout: ['a', 'b', 'c'] |
| 77 | |
| 78 | #### Multiple words: no outer quotes, inner single quotes |
| 79 | argv.py ${Unset:-'a b c'} |
| 80 | ## stdout: ['a b c'] |
| 81 | |
| 82 | #### Multiple words: no outer quotes, inner double quotes |
| 83 | argv.py ${Unset:-"a b c"} |
| 84 | ## stdout: ['a b c'] |
| 85 | |
| 86 | #### Multiple words: outer double quotes, no inner quotes |
| 87 | argv.py "${Unset:-a b c}" |
| 88 | ## stdout: ['a b c'] |
| 89 | |
| 90 | #### Multiple words: outer double quotes, inner double quotes |
| 91 | argv.py "${Unset:-"a b c"}" |
| 92 | ## stdout: ['a b c'] |
| 93 | |
| 94 | #### Multiple words: outer double quotes, inner single quotes |
| 95 | argv.py "${Unset:-'a b c'}" |
| 96 | # WEIRD ONE. |
| 97 | ## stdout: ["'a b c'"] |
| 98 | |
| 99 | #### Mixed inner quotes |
| 100 | argv.py ${Unset:-"a b" c} |
| 101 | ## stdout: ['a b', 'c'] |
| 102 | |
| 103 | #### Mixed inner quotes with outer quotes |
| 104 | argv.py "${Unset:-"a b" c}" |
| 105 | ## stdout: ['a b c'] |
| 106 | |
| 107 | #### part_value tree with multiple words |
| 108 | argv.py ${a:-${a:-"1 2" "3 4"}5 "6 7"} |
| 109 | ## stdout: ['1 2', '3 45', '6 7'] |
| 110 | |
| 111 | #### part_value tree on RHS |
| 112 | v=${a:-${a:-"1 2" "3 4"}5 "6 7"} |
| 113 | argv.py "${v}" |
| 114 | ## stdout: ['1 2 3 45 6 7'] |
| 115 | |
| 116 | #### Var with multiple words: no quotes |
| 117 | var='a b c' |
| 118 | argv.py ${Unset:-$var} |
| 119 | ## stdout: ['a', 'b', 'c'] |
| 120 | |
| 121 | #### Multiple words: no outer quotes, inner single quotes |
| 122 | var='a b c' |
| 123 | argv.py ${Unset:-'$var'} |
| 124 | ## stdout: ['$var'] |
| 125 | |
| 126 | #### Multiple words: no outer quotes, inner double quotes |
| 127 | var='a b c' |
| 128 | argv.py ${Unset:-"$var"} |
| 129 | ## stdout: ['a b c'] |
| 130 | |
| 131 | #### Multiple words: outer double quotes, no inner quotes |
| 132 | var='a b c' |
| 133 | argv.py "${Unset:-$var}" |
| 134 | ## stdout: ['a b c'] |
| 135 | |
| 136 | #### Multiple words: outer double quotes, inner double quotes |
| 137 | var='a b c' |
| 138 | argv.py "${Unset:-"$var"}" |
| 139 | ## stdout: ['a b c'] |
| 140 | |
| 141 | #### Multiple words: outer double quotes, inner single quotes |
| 142 | # WEIRD ONE. |
| 143 | # |
| 144 | # I think I should just disallow any word with single quotes inside double |
| 145 | # quotes. |
| 146 | var='a b c' |
| 147 | argv.py "${Unset:-'$var'}" |
| 148 | ## stdout: ["'a b c'"] |
| 149 | |
| 150 | #### No outer quotes, Multiple internal quotes |
| 151 | # It's like a single command word. Parts are joined directly. |
| 152 | var='a b c' |
| 153 | argv.py ${Unset:-A$var " $var"D E F} |
| 154 | ## stdout: ['Aa', 'b', 'c', ' a b cD', 'E', 'F'] |
| 155 | |
| 156 | #### Strip a string with single quotes, unquoted |
| 157 | foo="'a b c d'" |
| 158 | argv.py ${foo%d\'} |
| 159 | ## stdout: ["'a", 'b', 'c'] |
| 160 | |
| 161 | #### Strip a string with single quotes, double quoted |
| 162 | foo="'a b c d'" |
| 163 | argv.py "${foo%d\'}" |
| 164 | ## stdout: ["'a b c "] |
| 165 | |
| 166 | #### The string to strip is space sensitive |
| 167 | foo='a b c d' |
| 168 | argv.py "${foo%c d}" "${foo%c d}" |
| 169 | ## stdout: ['a b ', 'a b c d'] |
| 170 | |
| 171 | #### The string to strip can be single quoted, outer is unquoted |
| 172 | foo='a b c d' |
| 173 | argv.py ${foo%'c d'} ${foo%'c d'} |
| 174 | ## stdout: ['a', 'b', 'a', 'b', 'c', 'd'] |
| 175 | |
| 176 | #### Strip a string with single quotes, double quoted, with unescaped ' |
| 177 | # We're in a double quoted context, so we should be able to use a literal |
| 178 | # single quote. This is very much the case with :-. |
| 179 | foo="'a b c d'" |
| 180 | argv.py "${foo%d'}" |
| 181 | ## stdout: ["'a b c "] |
| 182 | ## BUG bash/mksh stdout-json: "" |
| 183 | ## BUG bash status: 2 |
| 184 | ## BUG mksh status: 1 |
| 185 | |
| 186 | #### The string to strip can be single quoted, outer is double quoted |
| 187 | # This is an inconsistency in bash/mksh because '' are treated as literals in |
| 188 | # double quotes. The correct ways are above. |
| 189 | foo='a b c d' |
| 190 | argv.py "${foo%'c d'}" "${foo%'c d'}" |
| 191 | ## stdout: ['a b c d', 'a b c d'] |
| 192 | ## BUG bash/mksh stdout: ['a b ', 'a b c d'] |
| 193 | |
| 194 | #### $'' allowed within VarSub arguments |
| 195 | # Odd behavior of bash/mksh: $'' is recognized but NOT ''! |
| 196 | x=abc |
| 197 | echo ${x%$'b'*} |
| 198 | echo "${x%$'b'*}" # git-prompt.sh relies on this |
| 199 | ## STDOUT: |
| 200 | a |
| 201 | a |
| 202 | ## END |
| 203 | ## N-I dash STDOUT: |
| 204 | abc |
| 205 | abc |
| 206 | ## END |