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 length
8 v=foo
9 echo ${#v}
10 # stdout: 3
11
12 ### Length of undefined variable
13 echo ${#undef}
14 # stdout: 0
15
16 ### Length of undefined variable with nounset
17 set -o nounset
18 echo ${#undef}
19 # status: 1
20 # OK dash status: 2
21
22 ### Cannot take length of substring slice
23 # These are runtime errors, but we could make them parse time errors.
24 v=abcde
25 echo ${#v:1:3}
26 # status: 1
27 # OK osh status: 2
28 # N-I dash status: 0
29 # N-I dash stdout: 5
30
31 ### Pattern replacement
32 v=abcde
33 echo ${v/c*/XX}
34 # stdout: abXX
35 # N-I dash status: 2
36 # N-I dash stdout-json: ""
37
38 ### Pattern replacement on unset variable
39 echo [${v/x/y}]
40 echo status=$?
41 set -o nounset # make sure this fails
42 echo [${v/x/y}]
43 ## STDOUT:
44 []
45 status=0
46 ## BUG mksh STDOUT:
47 # patsub disrespects nounset!
48 []
49 status=0
50 []
51 ## status: 1
52 ## BUG mksh status: 0
53 ## N-I dash status: 2
54 ## N-I dash stdout-json: ""
55
56 ### Global Pattern replacement with /
57 s=xx_xx_xx
58 echo ${s/xx?/yy_} ${s//xx?/yy_}
59 # stdout: yy_xx_xx yy_yy_xx
60 # N-I dash status: 2
61 # N-I dash stdout-json: ""
62
63 ### Left Anchored Pattern replacement with #
64 s=xx_xx_xx
65 echo ${s/?xx/_yy} ${s/#?xx/_yy}
66 # stdout: xx_yy_xx xx_xx_xx
67 # N-I dash status: 2
68 # N-I dash stdout-json: ""
69
70 ### Right Anchored Pattern replacement with %
71 s=xx_xx_xx
72 echo ${s/?xx/_yy} ${s/%?xx/_yy}
73 # stdout: xx_yy_xx xx_xx_yy
74 # N-I dash status: 2
75 # N-I dash stdout-json: ""
76
77 ### Replace fixed strings
78 s=xx_xx
79 echo ${s/xx/yy} ${s//xx/yy} ${s/#xx/yy} ${s/%xx/yy}
80 # stdout: yy_xx yy_yy yy_xx xx_yy
81 # N-I dash status: 2
82 # N-I dash stdout-json: ""
83
84 ### Replace is longest match
85 # If it were shortest, then you would just replace the first <html>
86 s='begin <html></html> end'
87 echo ${s/<*>/[]}
88 # stdout: begin [] end
89 # N-I dash status: 2
90 # N-I dash stdout-json: ""
91
92 ### Replace char class
93 s=xx_xx_xx
94 echo ${s//[[:alpha:]]/y} ${s//[^[:alpha:]]/-}
95 # stdout: yy_yy_yy xx-xx-xx
96 # N-I mksh stdout: xx_xx_xx xx_xx_xx
97 # N-I dash status: 2
98 # N-I dash stdout-json: ""
99
100 ### Pattern replacement ${v/} is not valid
101 v=abcde
102 echo -${v/}-
103 echo status=$?
104 # status: 2
105 # stdout-json: ""
106 # N-I dash status: 2
107 # N-I dash stdout-json: ""
108 # BUG bash/mksh status: 0
109 # BUG bash/mksh stdout-json: "-abcde-\nstatus=0\n"
110
111 ### Pattern replacement ${v//} is not valid
112 v='a/b/c'
113 echo -${v//}-
114 echo status=$?
115 # status: 2
116 # stdout-json: ""
117 # N-I dash status: 2
118 # N-I dash stdout-json: ""
119 # BUG bash/mksh status: 0
120 # BUG bash/mksh stdout-json: "-a/b/c-\nstatus=0\n"
121
122 ### ${v/a} is the same as ${v/a/} -- no replacement string
123 v='aabb'
124 echo ${v/a}
125 echo status=$?
126 # stdout-json: "abb\nstatus=0\n"
127 # N-I dash stdout-json: ""
128 # N-I dash status: 2
129
130 ### String slice
131 foo=abcdefg
132 echo ${foo:1:3}
133 # stdout: bcd
134 # N-I dash status: 2
135 # N-I dash stdout-json: ""
136
137 ### Negative string slice
138 foo=abcdefg
139 echo ${foo: -4:3}
140 # stdout: def
141 # N-I dash status: 2
142 # N-I dash stdout-json: ""
143
144 ### String slice with math
145 # I think this is the $(()) language inside?
146 i=1
147 foo=abcdefg
148 echo ${foo: i-3-2 : i + 2}
149 # stdout: def
150 # N-I dash status: 2
151 # N-I dash stdout-json: ""
152
153 ### Slice String with Unicode
154 # mksh slices by bytes.
155 foo='--μ--'
156 echo ${foo:1:3}
157 # stdout: -μ-
158 # BUG mksh stdout: -μ
159 # N-I dash status: 2
160 # N-I dash stdout-json: ""
161