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