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 #### strict-word-eval with string slice
61 set -o strict-word-eval || true
62 echo slice
63 s='abc'
64 echo -${s: -2}-
65 ## STDOUT:
66 slice
67 ## END
68 ## status: 1
69 ## N-I bash status: 0
70 ## N-I bash STDOUT:
71 slice
72 -bc-
73 # END
74 ## N-I mksh/zsh status: 1
75 ## N-I mksh/zsh stdout-json: ""
76
77 #### String slice with math
78 # I think this is the $(()) language inside?
79 i=1
80 foo=abcdefg
81 echo ${foo: i+4-2 : i + 2}
82 ## stdout: def
83
84 #### Slice undefined
85 echo -${undef:1:2}-
86 set -o nounset
87 echo -${undef:1:2}-
88 echo -done-
89 ## STDOUT:
90 --
91 ## END
92 ## status: 1
93 # mksh doesn't respect nounset!
94 ## BUG mksh status: 0
95 ## BUG mksh STDOUT:
96 --
97 --
98 -done-
99 ## END
100
101 #### Slice UTF-8 String
102 # mksh slices by bytes.
103 foo='--μ--'
104 echo ${foo:1:3}
105 ## stdout: -μ-
106 ## BUG mksh stdout: -μ
107
108 #### Slice string with invalid UTF-8 results in empty string and warning
109 s=$(echo -e "\xFF")bcdef
110 echo -${s:1:3}-
111 ## status: 0
112 ## STDOUT:
113 --
114 ## END
115 ## STDERR:
116 [??? no location ???] warning: Invalid start of UTF-8 character
117 ## END
118 ## BUG bash/mksh/zsh status: 0
119 ## BUG bash/mksh/zsh STDOUT:
120 -bcd-
121 ## END
122 ## BUG bash/mksh/zsh stderr-json: ""
123
124
125 #### Slice string with invalid UTF-8 with strict-word-eval
126 set -o strict-word-eval || true
127 echo slice
128 s=$(echo -e "\xFF")bcdef
129 echo -${s:1:3}-
130 ## status: 1
131 ## stdout-json: "slice\n"
132 ## N-I mksh/zsh status: 1
133 ## N-I mksh/zsh stdout-json: ""
134 ## N-I bash status: 0
135 ## N-I bash stdout-json: "slice\n-bcd-\n"
136
137 #### Lower Case with , and ,,
138 x='ABC DEF'
139 echo ${x,}
140 echo ${x,,}
141 ## STDOUT:
142 aBC DEF
143 abc def
144 ## END
145 ## N-I mksh/zsh stdout-json: ""
146 ## N-I mksh/zsh status: 1
147
148
149 #### Upper Case with ^ and ^^
150 x='abc def'
151 echo ${x^}
152 echo ${x^^}
153 ## STDOUT:
154 Abc def
155 ABC DEF
156 ## END
157 ## N-I mksh/zsh stdout-json: ""
158 ## N-I mksh/zsh status: 1
159
160 #### Lower Case with constant string (VERY WEIRD)
161 x='AAA ABC DEF'
162 echo ${x,A}
163 echo ${x,,A} # replaces every A only?
164 ## STDOUT:
165 aAA ABC DEF
166 aaa aBC DEF
167 ## END
168 ## N-I mksh/zsh stdout-json: ""
169 ## N-I mksh/zsh status: 1
170
171 #### Lower Case glob
172 x='ABC DEF'
173 echo ${x,[d-f]}
174 echo ${x,,[d-f]} # This seems buggy, it doesn't include F?
175 ## STDOUT:
176 ABC DEF
177 ABC deF
178 ## END
179 ## N-I mksh/zsh stdout-json: ""
180 ## N-I mksh/zsh status: 1
181
182 #### ${x@Q}
183 x="FOO'BAR spam\"eggs"
184 eval "new=${x@Q}"
185 test "$x" = "$new" && echo OK
186 ## STDOUT:
187 OK
188 ## END
189 ## N-I zsh stdout-json: ""
190 ## N-I zsh status: 1
191