1 ## oils_failures_allowed: 3
2
3 #### append onto BashArray a=(1 2)
4 shopt -s parse_at
5 a=(1 2)
6 append '3 4' '5' (a)
7 argv.py "${a[@]}"
8
9 append -- 6 (a)
10 argv.py "${a[@]}"
11
12 ## STDOUT:
13 ['1', '2', '3 4', '5']
14 ['1', '2', '3 4', '5', '6']
15 ## END
16
17 #### append onto var a = :| 1 2 |
18 shopt -s parse_at parse_proc
19 var a = :| 1 2 |
20 append '3 4' '5' (a)
21 argv.py @a
22 ## STDOUT:
23 ['1', '2', '3 4', '5']
24 ## END
25
26 #### append onto var a = ['1', '2']
27 shopt -s parse_at parse_proc
28 var a = ['1', '2']
29 append '3 4' '5' (a)
30 argv.py @a
31 ## STDOUT:
32 ['1', '2', '3 4', '5']
33 ## END
34
35 #### append without typed arg
36 append a b
37 ## status: 2
38
39 #### append passed invalid type
40 s=''
41 append a b (s)
42 echo status=$?
43 ## status: 3
44
45 #### write --sep, --end, -n, varying flag syntax
46 shopt -s ysh:all
47 var a = %('a b' 'c d')
48 write @a
49 write .
50 write -- @a
51 write .
52
53 write --sep '' --end '' @a; write
54 write .
55
56 write --sep '_' -- @a
57 write --sep '_' --end $' END\n' -- @a
58
59 # with =
60 write --sep='_' --end=$' END\n' -- @a
61
62 write -n x
63 write -n y
64 write
65
66 ## STDOUT:
67 a b
68 c d
69 .
70 a b
71 c d
72 .
73 a bc d
74 .
75 a b_c d
76 a b_c d END
77 a b_c d END
78 xy
79 ## END
80
81 #### write --json
82 shopt --set ysh:upgrade
83
84 write --json u'\u{3bc}' x
85 write --json b'\yfe\yff' y
86
87 ## STDOUT:
88 "μ"
89 "x"
90 "��"
91 "y"
92 ## END
93
94 #### write --j8
95 shopt --set ysh:upgrade
96
97 write --j8 u'\u{3bc}' x
98 write --j8 b'\yfe\yff' y
99
100 ## STDOUT:
101 "μ"
102 "x"
103 b'\yfe\yff'
104 "y"
105 ## END
106
107 #### write -e not supported
108 shopt -s ysh:all
109 write -e foo
110 write status=$?
111 ## stdout-json: ""
112 ## status: 2
113
114 #### write syntax error
115 shopt -s ysh:all
116 write ---end foo
117 write status=$?
118 ## stdout-json: ""
119 ## status: 2
120
121 #### write --
122 shopt -s ysh:all
123 write --
124 # This is annoying
125 write -- --
126 write done
127
128 # this is a syntax error! Doh.
129 write ---
130 ## status: 2
131 ## STDOUT:
132
133 --
134 done
135 ## END
136
137 #### read flag usage
138 read --lin
139 echo status=$?
140
141 read --line :var extra
142 echo status=$?
143 ## STDOUT:
144 status=2
145 status=2
146 ## END
147
148 #### read :x :y is allowed
149 shopt --set parse_proc
150
151 echo 'foo bar' | read :x :y
152 echo x=$x y=$y
153
154 proc p {
155 # If these aren't here, it will LEAK because 'read' uses DYNAMIC SCOPE.
156 # TODO: Change semantics of : to be enforce that a local exists too?
157 var x = ''
158 var y = ''
159 echo 'spam eggs' | read x :y # OPTIONAL
160 echo x=$x y=$y
161 }
162 p
163
164 echo x=$x y=$y
165
166 ## STDOUT:
167 x=foo y=bar
168 x=spam y=eggs
169 x=foo y=bar
170 ## END
171
172 #### read (&x) is usage error
173
174 var x = null # allow no initialization
175 echo hello | read (&x)
176 echo status=$?
177
178 ## STDOUT:
179 status=2
180 ## END
181
182 #### read --line --with-eol
183 shopt -s ysh:upgrade
184
185 # Hm this preserves the newline?
186 seq 3 | while read --line {
187 write reply=$_reply # implicit
188 }
189 write a b | while read --line --with-eol (&myline) {
190 write --end '' myline=$myline
191 }
192 ## STDOUT:
193 reply=1
194 reply=2
195 reply=3
196 myline=a
197 myline=b
198 ## END
199
200 #### read --line --j8
201
202 echo $'u\'foo\'' | read --line --j8
203 write -- "$_reply"
204
205 ## STDOUT:
206 foo
207 ## END
208
209 #### echo builtin should disallow typed args - literal
210 shopt -s ysh:all
211 #shopt -p simple_echo
212
213 echo (42)
214 ## status: 2
215 ## STDOUT:
216 ## END
217
218 #### echo builtin should disallow typed args - variable
219 shopt -s ysh:all
220 #shopt -p simple_echo
221
222 var x = 43
223 echo (x)
224 ## status: 2
225 ## STDOUT:
226 ## END
227
228 #### read --all-lines
229 seq 3 | read --all-lines :nums
230 write --sep ' ' -- @nums
231 ## STDOUT:
232 1 2 3
233 ## END
234
235 #### read --all-lines --with-eol
236 seq 3 | read --all-lines --with-eol :nums
237 write --sep '' -- @nums
238 ## STDOUT:
239 1
240 2
241 3
242 ## END
243
244 #### Can simulate read --all-lines with a proc and value.Place
245
246 shopt -s ysh:upgrade # TODO: bad proc error message without this!
247
248 # Set up a file
249 seq 3 > tmp.txt
250
251 proc read-lines (; out) {
252 var lines = []
253 while read --line {
254 append $_reply (lines)
255
256 # Can also be:
257 # call lines->append(_reply)
258 # call lines->push(_reply) # might reame it
259 }
260 call out->setValue(lines)
261 }
262
263 var x
264 read-lines (&x) < tmp.txt
265 json write (x)
266
267 ## STDOUT:
268 [
269 "1",
270 "2",
271 "3"
272 ]
273 ## END
274
275 #### read --all
276 echo foo | read --all
277 echo "[$_reply]"
278
279 echo bad > tmp.txt
280 read --all (&x) < tmp.txt
281 echo "[$x]"
282
283 ## STDOUT:
284 [foo
285 ]
286 [bad
287 ]
288 ## END
289
290 #### read --line from directory is an error (EISDIR)
291 mkdir -p ./dir
292 read --line < ./dir
293 echo status=$?
294 ## STDOUT:
295 status=1
296 ## END
297
298 #### read --all from directory is an error (EISDIR)
299 mkdir -p ./dir
300 read --all < ./dir
301 echo status=$?
302 ## STDOUT:
303 status=1
304 ## END
305
306 #### read -0 is like read -r -d ''
307 set -o errexit
308
309 mkdir -p read0
310 cd read0
311 touch a\\b\\c\\d
312
313 find . -type f -a -print0 | read -r -d '' name
314 echo "[$name]"
315
316 find . -type f -a -print0 | read -0
317 echo "[$REPLY]"
318
319 ## STDOUT:
320 [./a\b\c\d]
321 [./a\b\c\d]
322 ## END
323
324 #### simple_test_builtin
325
326 test -n "foo"
327 echo status=$?
328
329 test -n "foo" -a -n "bar"
330 echo status=$?
331
332 [ -n foo ]
333 echo status=$?
334
335 shopt --set ysh:all
336 shopt --unset errexit
337
338 test -n "foo" -a -n "bar"
339 echo status=$?
340
341 [ -n foo ]
342 echo status=$?
343
344 test -z foo
345 echo status=$?
346
347 ## STDOUT:
348 status=0
349 status=0
350 status=0
351 status=2
352 status=2
353 status=1
354 ## END
355
356 #### long flags to test
357 # no options necessary!
358
359 test --dir /
360 echo status=$?
361
362 touch foo
363 test --file foo
364 echo status=$?
365
366 test --exists /
367 echo status=$?
368
369 test --symlink foo
370 echo status=$?
371
372 test --typo foo
373 echo status=$?
374
375 ## STDOUT:
376 status=0
377 status=0
378 status=0
379 status=1
380 status=2
381 ## END
382
383
384 #### push-registers
385 shopt --set ysh:upgrade
386 shopt --unset errexit
387
388 status_code() {
389 return $1
390 }
391
392 [[ foo =~ (.*) ]]
393
394 status_code 42
395 push-registers {
396 status_code 43
397 echo status=$?
398
399 [[ bar =~ (.*) ]]
400 echo ${BASH_REMATCH[@]}
401 }
402 # WEIRD SEMANTIC TO REVISIT: push-registers is "SILENT" as far as exit code
403 # This is for the headless shell, but hasn't been tested.
404 # Better method: maybe we should provide a way of SETTING $?
405
406 echo status=$?
407
408 echo ${BASH_REMATCH[@]}
409 ## STDOUT:
410 status=43
411 bar bar
412 status=42
413 foo foo
414 ## END
415
416 #### push-registers usage
417 shopt --set parse_brace
418
419 push-registers
420 echo status=$?
421
422 push-registers a b
423 echo status=$?
424
425 push-registers a b { # hm extra args are ignored
426 echo hi
427 }
428 echo status=$?
429
430 ## STDOUT:
431 status=2
432 status=2
433 hi
434 status=0
435 ## END
436
437 #### fopen
438 shopt --set parse_brace parse_proc
439
440 proc p {
441 echo 'proc'
442 }
443
444 fopen >out.txt {
445 p
446 echo 'builtin'
447 }
448
449 cat out.txt
450
451 echo ---
452
453 fopen <out.txt {
454 tac
455 }
456
457 # Awkward bash syntax, but we'll live with it
458 fopen {left}>left.txt {right}>right.txt {
459 echo 1 >& $left
460 echo 1 >& $right
461
462 echo 2 >& $left
463 echo 2 >& $right
464
465 echo 3 >& $left
466 }
467
468 echo ---
469 comm -23 left.txt right.txt
470
471 ## STDOUT:
472 proc
473 builtin
474 ---
475 builtin
476 proc
477 ---
478 3
479 ## END
480
481 #### type(x)
482 echo $[type(1234)]
483 echo $[type('foo')]
484 echo $[type(false)]
485 echo $[type(1.234)]
486 echo $[type([])]
487 echo $[type({})]
488 echo $[type(null)]
489
490 shopt --set ysh:upgrade
491
492 func f() {
493 return (42)
494 }
495
496 echo $[type(f)]
497 echo $[type(len)]
498 echo $[type('foo'->startsWith)]
499 echo $[type('foo'=>join)] # Type error happens later
500 echo $[type(1..3)]
501 ## STDOUT:
502 Int
503 Str
504 Bool
505 Float
506 List
507 Dict
508 Null
509 Func
510 BuiltinFunc
511 BoundFunc
512 BoundFunc
513 Range
514 ## END