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-json: "--\n"
113 ## stderr-json: "osh warning: Invalid start of UTF-8 character\n"
114 ## BUG bash/mksh/zsh status: 0
115 ## BUG bash/mksh/zsh stdout-json: "-bcd-\n"
116 ## BUG bash/mksh/zsh stderr-json: ""
117
118
119 #### Slice string with invalid UTF-8 with strict-word-eval
120 set -o strict-word-eval || true
121 echo slice
122 s=$(echo -e "\xFF")bcdef
123 echo -${s:1:3}-
124 ## status: 1
125 ## stdout-json: "slice\n"
126 ## N-I mksh/zsh status: 1
127 ## N-I mksh/zsh stdout-json: ""
128 ## N-I bash status: 0
129 ## N-I bash stdout-json: "slice\n-bcd-\n"
130
131 #### Lower Case with , and ,,
132 x='ABC DEF'
133 echo ${x,}
134 echo ${x,,}
135 ## STDOUT:
136 aBC DEF
137 abc def
138 ## END
139 ## N-I mksh/zsh stdout-json: ""
140 ## N-I mksh/zsh status: 1
141
142
143 #### Upper Case with ^ and ^^
144 x='abc def'
145 echo ${x^}
146 echo ${x^^}
147 ## STDOUT:
148 Abc def
149 ABC DEF
150 ## END
151 ## N-I mksh/zsh stdout-json: ""
152 ## N-I mksh/zsh status: 1
153
154 #### Lower Case with constant string (VERY WEIRD)
155 x='AAA ABC DEF'
156 echo ${x,A}
157 echo ${x,,A} # replaces every A only?
158 ## STDOUT:
159 aAA ABC DEF
160 aaa aBC DEF
161 ## END
162 ## N-I mksh/zsh stdout-json: ""
163 ## N-I mksh/zsh status: 1
164
165 #### Lower Case glob
166 x='ABC DEF'
167 echo ${x,[d-f]}
168 echo ${x,,[d-f]} # This seems buggy, it doesn't include F?
169 ## STDOUT:
170 ABC DEF
171 ABC deF
172 ## END
173 ## N-I mksh/zsh stdout-json: ""
174 ## N-I mksh/zsh status: 1
175
176 #### ${x@Q}
177 x="FOO'BAR spam\"eggs"
178 eval "new=${x@Q}"
179 test "$x" = "$new" && echo OK
180 ## STDOUT:
181 OK
182 ## END
183 ## N-I zsh stdout-json: ""
184 ## N-I zsh status: 1
185