| 1 | #!/bin/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 | ### :- |
| 18 | empty='' |
| 19 | argv ${empty:-a} ${Unset:-b} |
| 20 | # stdout: ['a', 'b'] |
| 21 | |
| 22 | ### - |
| 23 | empty='' |
| 24 | argv ${empty-a} ${Unset-b} |
| 25 | # empty one is still elided! |
| 26 | # stdout: ['b'] |
| 27 | |
| 28 | ### Inner single quotes |
| 29 | argv ${Unset:-'b'} |
| 30 | # stdout: ['b'] |
| 31 | |
| 32 | ### Inner single quotes, outer double quotes |
| 33 | # This is the WEIRD ONE. Single quotes appear outside. But all shells agree! |
| 34 | argv "${Unset:-'b'}" |
| 35 | # stdout: ["'b'"] |
| 36 | |
| 37 | ### Inner double quotes |
| 38 | argv ${Unset:-"b"} |
| 39 | # stdout: ['b'] |
| 40 | |
| 41 | ### Inner double quotes, outer double quotes |
| 42 | argv "${Unset-"b"}" |
| 43 | # stdout: ['b'] |
| 44 | |
| 45 | ### Multiple words: no quotes |
| 46 | argv ${Unset:-a b c} |
| 47 | # stdout: ['a', 'b', 'c'] |
| 48 | |
| 49 | ### Multiple words: no outer quotes, inner single quotes |
| 50 | argv ${Unset:-'a b c'} |
| 51 | # stdout: ['a b c'] |
| 52 | |
| 53 | ### Multiple words: no outer quotes, inner double quotes |
| 54 | argv ${Unset:-"a b c"} |
| 55 | # stdout: ['a b c'] |
| 56 | |
| 57 | ### Multiple words: outer double quotes, no inner quotes |
| 58 | argv "${Unset:-a b c}" |
| 59 | # stdout: ['a b c'] |
| 60 | |
| 61 | ### Multiple words: outer double quotes, inner double quotes |
| 62 | argv "${Unset:-"a b c"}" |
| 63 | # stdout: ['a b c'] |
| 64 | |
| 65 | ### Multiple words: outer double quotes, inner single quotes |
| 66 | argv "${Unset:-'a b c'}" |
| 67 | # WEIRD ONE. |
| 68 | # stdout: ["'a b c'"] |
| 69 | |
| 70 | |
| 71 | ### Var with multiple words: no quotes |
| 72 | var='a b c' |
| 73 | argv ${Unset:-$var} |
| 74 | # stdout: ['a', 'b', 'c'] |
| 75 | |
| 76 | ### Multiple words: no outer quotes, inner single quotes |
| 77 | var='a b c' |
| 78 | argv ${Unset:-'$var'} |
| 79 | # stdout: ['$var'] |
| 80 | |
| 81 | ### Multiple words: no outer quotes, inner double quotes |
| 82 | var='a b c' |
| 83 | argv ${Unset:-"$var"} |
| 84 | # stdout: ['a b c'] |
| 85 | |
| 86 | ### Multiple words: outer double quotes, no inner quotes |
| 87 | var='a b c' |
| 88 | argv "${Unset:-$var}" |
| 89 | # stdout: ['a b c'] |
| 90 | |
| 91 | ### Multiple words: outer double quotes, inner double quotes |
| 92 | var='a b c' |
| 93 | argv "${Unset:-"$var"}" |
| 94 | # stdout: ['a b c'] |
| 95 | |
| 96 | ### Multiple words: outer double quotes, inner single quotes |
| 97 | # WEIRD ONE. |
| 98 | # |
| 99 | # I think I should just disallow any word with single quotes inside double |
| 100 | # quotes. |
| 101 | var='a b c' |
| 102 | argv "${Unset:-'$var'}" |
| 103 | # stdout: ["'a b c'"] |
| 104 | |
| 105 | |
| 106 | |
| 107 | ### No outer quotes, Multiple internal quotes |
| 108 | # It's like a single command word. Parts are joined directly. |
| 109 | var='a b c' |
| 110 | argv ${Unset:-A$var " $var"D E F} |
| 111 | # stdout: ['Aa', 'b', 'c', ' a b cD', 'E', 'F'] |
| 112 | |
| 113 | |
| 114 | |
| 115 | ### Strip a string with single quotes, unquoted |
| 116 | foo="'a b c d'" |
| 117 | argv ${foo%d\'} |
| 118 | # stdout: ["'a", 'b', 'c'] |
| 119 | |
| 120 | ### Strip a string with single quotes, double quoted |
| 121 | foo="'a b c d'" |
| 122 | argv "${foo%d\'}" |
| 123 | # stdout: ["'a b c "] |
| 124 | |
| 125 | ### Strip a string with single quotes, double quoted, with unescaped ' |
| 126 | # We're in a double quoted context, so we should be able to use a regular |
| 127 | # single quote. This is very much the case with :-. |
| 128 | foo="'a b c d'" |
| 129 | argv "${foo%d'}" |
| 130 | # stdout: ["'a b c "] |
| 131 | # BUG bash/mksh stdout-json: "" |
| 132 | |
| 133 | ### The string to strip is space sensitive |
| 134 | foo='a b c d' |
| 135 | argv "${foo%c d}" "${foo%c d}" |
| 136 | # stdout: ['a b ', 'a b c d'] |
| 137 | |
| 138 | ### The string to strip can be single quoted, outer is double quoted |
| 139 | foo='a b c d' |
| 140 | argv "${foo%'c d'}" "${foo%'c d'}" |
| 141 | # stdout: ['a b ', 'a b c d'] |
| 142 | # BUG dash stdout: ['a b c d', 'a b c d'] |
| 143 | |
| 144 | ### The string to strip can be single quoted, outer is unquoted |
| 145 | foo='a b c d' |
| 146 | argv ${foo%'c d'} ${foo%'c d'} |
| 147 | # stdout: ['a', 'b', 'a', 'b', 'c', 'd'] |