1 # spec/ysh-case
2
3 ## our_shell: ysh
4 ## oils_failures_allowed: 0
5
6 #### case syntax, one line
7 const x = "header.h"
8 case (x) {
9 *.h | *.cc { echo C++ }
10 *.py { echo Python }
11 }
12
13 # not recommended, but it works
14 case (x) { header.h { echo header.h } * { echo other } }
15
16 ## status: 0
17 ## STDOUT:
18 C++
19 header.h
20 ## END
21
22 #### case syntax, multiline
23 const x = "hello.py"
24 case (x) {
25 *.h | *.cc {
26 echo C++
27 echo 2; echo 3
28 }
29 *.py {
30 echo \
31 Python
32 }
33 }
34 ## status: 0
35 ## STDOUT:
36 Python
37 ## END
38
39 #### case syntax, simple expressions
40 const x = 3
41 case (x) {
42 (3) { echo three }
43 (4) { echo four }
44 }
45 ## status: 0
46 ## STDOUT:
47 three
48 ## END
49
50 #### case syntax, complex expressions
51 const x = 3
52 case (x) {
53 (1 + 2) { echo three }
54 (2 + 2) { echo four }
55 }
56 ## STDOUT:
57 three
58 ## END
59
60 #### case semantics, no match
61 const x = 2
62 case (x) {
63 (3) { echo three }
64 (4) { echo four }
65 }
66 ## status: 0
67 ## STDOUT:
68 ## END
69
70 #### case syntax, eggex
71 const x = "main.cc"
72 case (x) {
73 / dot* '.py' / {
74 echo Python
75 }
76 / dot* ('.cc' | '.h') / {
77 echo C++
78 }
79 }
80 ## STDOUT:
81 C++
82 ## END
83
84 #### empty case statement
85 const x = ""
86 case (x) { }
87 ## status: 0
88 ## STDOUT:
89 ## END
90
91 #### typed args
92 const x = "0"
93 case (x) {
94 (0) { echo int }
95 ("0") { echo string }
96 }
97
98 ## status: 0
99 ## STDOUT:
100 string
101 ## END
102
103 #### eggex capture
104 for name in foo/foo.py bar/bar.cc zz {
105 case (name) {
106 / '/f' <dot*> '.' / { echo "g0=$[_match(0)] g1=$[_match(1)] g2=$[_match(2)]" }
107 / '/b' <dot*> '.' / { echo "g0=$[_match(1)] g1=$[_match(1)]" }
108 (else) { echo 'no match' }
109 }
110 }
111 ## status: 0
112 ## STDOUT:
113 g0=/foo. g1=oo g2=null
114 g0=ar g1=ar
115 no match
116 ## END
117
118 #### else case pattern
119 var x = 123
120 case (x) {
121 (else) { echo else matches all }
122 (123) { echo unreachable }
123 }
124 ## status: 0
125 ## STDOUT:
126 else matches all
127 ## END
128
129 #### expression evaluation shortcuts
130 var x = 123
131 case (x) {
132 (x) | (y) { echo no error }
133 }
134 ## status: 0
135 ## STDOUT:
136 no error
137 ## END
138
139 #### expression evaluation order
140 var x = 123
141 case (x) {
142 (y) | (x) { echo no error }
143 }
144 ## status: 1
145 ## STDOUT:
146 ## END
147
148 #### word evaluation shortcuts
149 var x = "abc"
150 case (x) {
151 $x | $y { echo no error }
152 }
153 ## status: 0
154 ## STDOUT:
155 no error
156 ## END
157
158 #### word evaluation order
159 var x = "abc"
160 case (x) {
161 $y | $x { echo no error }
162 }
163 ## status: 1
164 ## STDOUT:
165 ## END
166
167 #### only one branch is evaluated
168 var x = "42"
169 case (x) {
170 ('42') { echo a }
171 42 { echo b }
172 / '42' / { echo c }
173 (Str(40 + 2)) { echo d }
174
175 # even errors are ignored
176 (42 / 0) { echo no error }
177 }
178 ## status: 0
179 ## STDOUT:
180 a
181 ## END
182
183 #### stop on errors
184 var x = "42"
185 case (x) {
186 (42 / 0) { echo no error }
187
188 ('42') { echo a }
189 42 { echo b }
190 / '42' / { echo c }
191 (Str(40 + 2)) { echo d }
192 }
193 ## status: 3
194 ## STDOUT:
195 ## END
196
197 #### old and new case statements
198
199 for flag in -f -x {
200
201 # We can disallow this with shopt --unset parse_old_case, because the new
202 # case statement does everything the old one does
203 #
204 # bin/osh and shopt --set ysh:upgrade let you use both styles, but bin/ysh
205 # only lets you use the new style
206
207 case $flag in
208 -f|-d)
209 echo 'file'
210 ;;
211 *)
212 echo 'other'
213 ;;
214 esac
215
216 case (flag) {
217 -f|-d { echo 'file' }
218 * { echo 'other' }
219 }
220
221 echo --
222 }
223
224 ## STDOUT:
225 file
226 file
227 --
228 other
229 other
230 --
231 ## END