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