1 #!/usr/bin/env bash
2 #
3 # Test combination of var ops.
4 #
5 # NOTE: There are also slice tests in {array,arith-context}.test.sh.
6
7 #### String slice
8 foo=abcdefg
9 echo ${foo:1:3}
10 ## STDOUT:
11 bcd
12 ## END
13
14 #### Cannot take length of substring slice
15 # These are runtime errors, but we could make them parse time errors.
16 v=abcde
17 echo ${#v:1:3}
18 ## status: 1
19 ## OK osh status: 2
20 # zsh actually implements this!
21 ## OK zsh stdout: 3
22 ## OK zsh status: 0
23
24 #### Out of range string slice: begin
25 # out of range begin doesn't raise error in bash, but in mksh it skips the
26 # whole thing!
27 foo=abcdefg
28 echo _${foo:100:3}
29 echo $?
30 ## STDOUT:
31 _
32 0
33 ## END
34 ## BUG mksh stdout-json: "\n0\n"
35
36 #### Out of range string slice: length
37 # OK in both bash and mksh
38 foo=abcdefg
39 echo _${foo:3:100}
40 echo $?
41 ## STDOUT:
42 _defg
43 0
44 ## END
45 ## BUG mksh stdout-json: "_defg\n0\n"
46
47 #### String slice: negative begin
48 foo=abcdefg
49 echo ${foo: -4:3}
50 ## OK osh stdout:
51 ## stdout: def
52
53 #### String slice: negative second arg is position, not length
54 foo=abcdefg
55 echo ${foo:3:-1} ${foo: 3: -2} ${foo:3 :-3 }
56 ## OK osh stdout:
57 ## stdout: def de d
58 ## BUG mksh stdout: defg defg defg
59
60
61 #### strict-word-eval with string slice
62 shopt -s strict-word-eval || true
63 echo slice
64 s='abc'
65 echo -${s: -2}-
66 ## STDOUT:
67 slice
68 ## END
69 ## status: 1
70 ## N-I bash/mksh/zsh status: 0
71 ## N-I bash/mksh/zsh STDOUT:
72 slice
73 -bc-
74 ## END
75
76 #### String slice with math
77 # I think this is the $(()) language inside?
78 i=1
79 foo=abcdefg
80 echo ${foo: i+4-2 : i + 2}
81 ## stdout: def
82
83 #### Slice undefined
84 echo -${undef:1:2}-
85 set -o nounset
86 echo -${undef:1:2}-
87 echo -done-
88 ## STDOUT:
89 --
90 ## END
91 ## status: 1
92 # mksh doesn't respect nounset!
93 ## BUG mksh status: 0
94 ## BUG mksh STDOUT:
95 --
96 --
97 -done-
98 ## END
99
100 #### Slice UTF-8 String
101 # mksh slices by bytes.
102 foo='--μ--'
103 echo ${foo:1:3}
104 ## stdout: -μ-
105 ## BUG mksh stdout: -μ
106
107 #### Slice string with invalid UTF-8 results in empty string and warning
108 s=$(echo -e "\xFF")bcdef
109 echo -${s:1:3}-
110 ## status: 0
111 ## STDOUT:
112 --
113 ## END
114 ## STDERR:
115 [??? no location ???] warning: Invalid start of UTF-8 character
116 ## END
117 ## BUG bash/mksh/zsh status: 0
118 ## BUG bash/mksh/zsh STDOUT:
119 -bcd-
120 ## END
121 ## BUG bash/mksh/zsh stderr-json: ""
122
123
124 #### Slice string with invalid UTF-8 with strict-word-eval
125 shopt -s strict-word-eval || true
126 echo slice
127 s=$(echo -e "\xFF")bcdef
128 echo -${s:1:3}-
129 ## status: 1
130 ## STDOUT:
131 slice
132 ## END
133 ## N-I bash/mksh/zsh status: 0
134 ## N-I bash/mksh/zsh STDOUT:
135 slice
136 -bcd-
137 ## END
138
139 #### Lower Case with , and ,,
140 x='ABC DEF'
141 echo ${x,}
142 echo ${x,,}
143 ## STDOUT:
144 aBC DEF
145 abc def
146 ## END
147 ## N-I mksh/zsh stdout-json: ""
148 ## N-I mksh/zsh status: 1
149
150
151 #### Upper Case with ^ and ^^
152 x='abc def'
153 echo ${x^}
154 echo ${x^^}
155 ## STDOUT:
156 Abc def
157 ABC DEF
158 ## END
159 ## N-I mksh/zsh stdout-json: ""
160 ## N-I mksh/zsh status: 1
161
162 #### Lower Case with constant string (VERY WEIRD)
163 x='AAA ABC DEF'
164 echo ${x,A}
165 echo ${x,,A} # replaces every A only?
166 ## STDOUT:
167 aAA ABC DEF
168 aaa aBC DEF
169 ## END
170 ## N-I mksh/zsh stdout-json: ""
171 ## N-I mksh/zsh status: 1
172
173 #### Lower Case glob
174 x='ABC DEF'
175 echo ${x,[d-f]}
176 echo ${x,,[d-f]} # This seems buggy, it doesn't include F?
177 ## STDOUT:
178 ABC DEF
179 ABC deF
180 ## END
181 ## N-I mksh/zsh stdout-json: ""
182 ## N-I mksh/zsh status: 1
183
184 #### ${x@Q}
185 x="FOO'BAR spam\"eggs"
186 eval "new=${x@Q}"
187 test "$x" = "$new" && echo OK
188 ## STDOUT:
189 OK
190 ## END
191 ## N-I zsh stdout-json: ""
192 ## N-I zsh status: 1
193