1 # Oil builtins
2
3 #### append onto a=(1 2)
4 shopt -s parse_at
5 a=(1 2)
6 append :a '3 4' '5'
7 argv.py @a
8 append -- :a 6
9 argv.py @a
10 ## STDOUT:
11 ['1', '2', '3 4', '5']
12 ['1', '2', '3 4', '5', '6']
13 ## END
14
15 #### append onto var a = %(1 2)
16 shopt -s parse_at
17 var a = %(1 2)
18 append a '3 4' '5' # : is optional
19 argv.py @a
20 ## STDOUT:
21 ['1', '2', '3 4', '5']
22 ## END
23
24 #### append with invalid type
25 s=''
26 append :s a b
27 echo status=$?
28 ## stdout: status=1
29
30 #### append with invalid var name
31 append - a b
32 echo status=$?
33 ## stdout: status=2
34
35 #### write -sep, -end, -n, varying flag syntax
36 shopt -s oil:all
37 var a = %('a b' 'c d')
38 write @a
39 write .
40 write -- @a
41 write .
42
43 write -sep '' -end '' @a; write
44 write .
45
46 write -sep '_' -- @a
47 write -sep '_' -end $' END\n' -- @a
48
49 # with =
50 write -sep='_' -end=$' END\n' -- @a
51 # long flags
52 write --sep '_' --end $' END\n' -- @a
53 # long flags with =
54 write --sep='_' --end=$' END\n' -- @a
55
56 write -n x
57 write -n y
58 write
59
60 ## STDOUT:
61 a b
62 c d
63 .
64 a b
65 c d
66 .
67 a bc d
68 .
69 a b_c d
70 a b_c d END
71 a b_c d END
72 a b_c d END
73 a b_c d END
74 xy
75 ## END
76
77 #### write --qsn
78 write --qsn foo bar
79 write __
80
81 write --qsn 'abc def' ' 123 456'
82 write __
83
84 write --qsn $'one\ttwo\n'
85
86 write __
87 write --qsn $'\u{3bc}'
88
89
90 ## STDOUT:
91 foo
92 bar
93 __
94 'abc def'
95 ' 123 456'
96 __
97 'one\ttwo\n'
98 __
99 'μ'
100 ## END
101
102
103 #### write --qsn --unicode
104 write --qsn $'\u{3bc}'
105 write --qsn --unicode u $'\u{3bc}'
106 write --qsn --unicode x $'\u{3bc}'
107
108 ## STDOUT:
109 'μ'
110 '\u{3bc}'
111 '\xce\xbc'
112 ## END
113
114 #### write -e not supported
115 shopt -s oil:all
116 write -e foo
117 write status=$?
118 ## stdout-json: ""
119 ## status: 2
120
121 #### write syntax error
122 shopt -s oil:all
123 write ---end foo
124 write status=$?
125 ## stdout-json: ""
126 ## status: 2
127
128 #### write --
129 shopt -s oil:all
130 write --
131 # This is annoying
132 write -- --
133 write done
134
135 # this is a syntax error! Doh.
136 write ---
137 ## status: 2
138 ## STDOUT:
139
140 --
141 done
142 ## END
143
144 #### read flag usage
145 read --lin
146 echo status=$?
147
148 read --line :var extra
149 echo status=$?
150 ## STDOUT:
151 status=2
152 status=2
153 ## END
154
155 #### read :x :y is allowed
156 echo 'foo bar' | read :x :y
157 echo x=$x y=$y
158
159 proc p {
160 # If these aren't here, it will LEAK because 'read' uses DYNAMIC SCOPE.
161 # TODO: Change semantics of : to be enforce that a local exists too?
162 var x = ''
163 var y = ''
164 echo 'spam eggs' | read x :y # OPTIONAL
165 echo x=$x y=$y
166 }
167 p
168
169 echo x=$x y=$y
170
171 ## STDOUT:
172 x=foo y=bar
173 x=spam y=eggs
174 x=foo y=bar
175 ## END
176
177 #### Idiom for returning 'read'
178 proc p(:out) {
179 #var tmp = ''
180
181 # We can't do read :out in Oil. I think that's OK -- there's consistency in
182 # using setref everywhere.
183 echo foo | read :tmp
184 setref out = tmp
185 }
186 p :z
187 echo z=$z
188 ## STDOUT:
189 z=foo
190 ## END
191
192 #### read --line --with-eol
193 shopt -s oil:basic
194
195 # Hm this preserves the newline?
196 seq 3 | while read --line {
197 write line=$_line # implisict
198 }
199 write a b | while read --line --with-eol :myline {
200 write -end '' line=$myline
201 }
202 ## STDOUT:
203 line=1
204 line=2
205 line=3
206 line=a
207 line=b
208 ## END
209
210 #### read --line --qsn
211 read --line --qsn <<EOF
212 'foo\n'
213 EOF
214 write --qsn -- "$_line"
215
216 read --line --qsn <<EOF
217 'foo\tbar hex=\x01 mu=\u{3bc}'
218 EOF
219 write --qsn --unicode u -- "$_line"
220
221 ## STDOUT:
222 'foo\n'
223 'foo\tbar hex=\u{1} mu=\u{3bc}'
224 ## END
225
226 #### read --line --with-eol --qsn
227
228 # whitespace is allowed after closing single quote; it doesn't make a
229 # difference.
230
231 read --line --with-eol --qsn <<EOF
232 'foo\n'
233 EOF
234 write --qsn -- "$_line"
235 ## STDOUT:
236 'foo\n'
237 ## END
238
239 #### read --qsn usage
240 read --qsn << EOF
241 foo
242 EOF
243 echo status=$?
244
245 ## STDOUT:
246 status=2
247 ## END
248
249 #### read --all-lines
250 seq 3 | read --all-lines :nums
251 write --sep ' ' -- @nums
252 ## STDOUT:
253 1 2 3
254 ## END
255
256 #### read --all-lines --with-eol
257 seq 3 | read --all-lines --with-eol :nums
258 write --sep '' -- @nums
259 ## STDOUT:
260 1
261 2
262 3
263 ## END
264
265 #### read --all-lines --qsn --with-eol
266 read --all-lines --qsn --with-eol :lines << EOF
267 foo
268 bar
269 'one\ntwo'
270 EOF
271 write --sep '' -- @lines
272 ## STDOUT:
273 foo
274 bar
275 one
276 two
277 ## END
278
279 #### read --all
280 echo foo | read --all
281 echo "[$_all]"
282
283 echo bad > tmp.txt
284 read --all :x < tmp.txt
285 echo "[$x]"
286
287 ## STDOUT:
288 [foo
289 ]
290 [bad
291 ]
292 ## END
293
294 #### read -0 is like read -r -d ''
295 set -o errexit
296
297 mkdir -p read0
298 cd read0
299 touch a\\b\\c\\d
300
301 find . -type f -a -print0 | read -r -d '' name
302 echo "[$name]"
303
304 find . -type f -a -print0 | read -0
305 echo "[$REPLY]"
306
307 ## STDOUT:
308 [./a\b\c\d]
309 [./a\b\c\d]
310 ## END
311
312
313 #### shopt supports long flags
314 shopt -p nullglob
315
316 shopt --set nullglob
317 shopt -p nullglob
318
319 shopt --unset nullglob
320 shopt -p nullglob
321 ## STDOUT:
322 shopt -u nullglob
323 shopt -s nullglob
324 shopt -u nullglob
325 ## END
326
327 #### shopt supports 'set' options
328 shopt -p errexit
329
330 shopt --set errexit
331 false
332
333 echo should not get here
334 ## status: 1
335 ## STDOUT:
336 shopt -u errexit
337 ## END
338
339
340 #### shopt and block
341 shopt --set oil:all
342
343 echo one
344
345 shopt --unset errexit {
346 echo two
347 false
348 echo three
349 }
350
351 false
352 echo 'should not get here'
353
354 ## status: 1
355 ## STDOUT:
356 one
357 two
358 three
359 ## END
360
361 #### shopt and block status
362 shopt --set oil:all
363
364 shopt --unset errexit {
365 false
366 }
367 # this is still 0, even though last command was 1
368 echo status=$?
369
370 ## STDOUT:
371 status=0
372 ## END
373
374 #### shopt usage error
375 shopt --set oil:all
376
377 echo one
378 shopt --set a {
379 echo two
380 }
381 echo status=$?
382 ## status: 2
383 ## STDOUT:
384 one
385 ## END
386
387 #### shopt --print
388
389 # TODO: It would be nice to print long flags ...
390
391 shopt -p errexit
392 shopt -p nullglob
393
394 echo --
395 shopt -p strict:all | head -n 3
396
397 echo --
398 shopt --set strict:all
399 shopt -p strict:all | head -n 3
400
401 ## STDOUT:
402 shopt -u errexit
403 shopt -u nullglob
404 --
405 shopt -u strict_argv
406 shopt -u strict_arith
407 shopt -u strict_array
408 --
409 shopt -s strict_argv
410 shopt -s strict_arith
411 shopt -s strict_array
412 ## END
413
414 #### simple_test_builtin
415
416 test -n "foo"
417 echo status=$?
418
419 test -n "foo" -a -n "bar"
420 echo status=$?
421
422 [ -n foo ]
423 echo status=$?
424
425 shopt --set oil:all
426 shopt --unset errexit
427
428 test -n "foo" -a -n "bar"
429 echo status=$?
430
431 [ -n foo ]
432 echo status=$?
433
434 test -z foo
435 echo status=$?
436
437 ## STDOUT:
438 status=0
439 status=0
440 status=0
441 status=2
442 status=2
443 status=1
444 ## END
445
446 #### long flags to test
447 # no options necessary!
448
449 test --dir /
450 echo status=$?
451
452 touch foo
453 test --file foo
454 echo status=$?
455
456 test --exists /
457 echo status=$?
458
459 test --symlink foo
460 echo status=$?
461
462 test --typo foo
463 echo status=$?
464
465 ## STDOUT:
466 status=0
467 status=0
468 status=0
469 status=1
470 status=2
471 ## END
472
473
474 #### push-registers
475 shopt --set oil:basic
476 shopt --unset errexit
477
478 status_code() {
479 return $1
480 }
481
482 [[ foo =~ (.*) ]]
483
484 status_code 42
485 push-registers {
486 status_code 43
487 echo status=$?
488
489 [[ bar =~ (.*) ]]
490 echo ${BASH_REMATCH[@]}
491 }
492 echo status=$? # push-registers will return 42
493
494 echo ${BASH_REMATCH[@]}
495 ## STDOUT:
496 status=43
497 bar bar
498 status=42
499 foo foo
500 ## END
501
502 #### module
503 shopt --set oil:basic
504
505 module 'main' || return 0
506 source $REPO_ROOT/spec/testdata/module/common.oil
507 source $REPO_ROOT/spec/testdata/module/module1.oil
508 ## STDOUT:
509 common
510 module1
511 ## END
512
513
514 #### runproc
515 f() {
516 write -- f "$@"
517 }
518 proc p {
519 write -- p "$@"
520 }
521 runproc f 1 2
522 echo status=$?
523
524 runproc p 3 4
525 echo status=$?
526
527 runproc invalid 5 6
528 echo status=$?
529
530 runproc
531 echo status=$?
532
533 ## STDOUT:
534 f
535 1
536 2
537 status=0
538 p
539 3
540 4
541 status=0
542 status=1
543 status=2
544 ## END