1 ## our_shell: ysh
2
3 #### Unquoted backslash escapes, as in J8 strings
4
5 # everything except \b \f \n
6
7 var nl = \n
8 pp test_ (nl)
9
10 var tab = \t
11 pp test_ (tab)
12
13 pp test_ (\r)
14
15 pp test_ (\" ++ \' ++ \\)
16
17 echo backslash $[\\]
18 echo "backslash $[\\]"
19
20 ## STDOUT:
21 (Str) "\n"
22 (Str) "\t"
23 (Str) "\r"
24 (Str) "\"'\\"
25 backslash \
26 backslash \
27 ## END
28
29 #### Unquoted \u{3bc} escape
30
31 var x = 'mu ' ++ \u{3bc}
32 echo $x
33
34 echo mu $[\u{3bc}]
35 echo "mu $[\u{3bc}]"
36
37 ## STDOUT:
38 mu μ
39 mu μ
40 mu μ
41 ## END
42
43 #### Unquoted \y24 escape
44
45 var x = 'foo ' ++ \y24
46 echo $x
47
48 var y = 0x24
49 echo $y
50
51 echo foo $[\y40]
52 echo "foo $[\y41]"
53
54 ## STDOUT:
55 foo $
56 36
57 foo @
58 foo A
59 ## END
60
61 #### single quoted -- implicit and explicit raw
62 var x = 'foo bar'
63 echo $x
64 setvar x = r'foo bar' # Same string
65 echo $x
66 setvar x = r'\t\n' # This is raw
67 echo $x
68 ## STDOUT:
69 foo bar
70 foo bar
71 \t\n
72 ## END
73
74 #### Implicit raw string '\t\n' is a syntax error because backslash is ambiguous
75 var x = ' \t\n '
76 ## status: 2
77 ## stdout-json: ""
78
79 #### Multiline ''' \t ''' is a also syntax error because backslash is ambiguous
80 var y = ''' \t '''
81 ## status: 2
82 ## stdout-json: ""
83
84 #### $"foo $x" to make "foo $x" explicit
85
86 var x = $"bar"
87
88 # expression mode
89 var y = $"foo $x"
90 echo "$y"
91
92 # command mode
93 if test "$y" = $"foo $x"; then
94 echo equal
95 fi
96
97 ## STDOUT:
98 foo bar
99 equal
100 ## END
101
102 #### raw strings and J8 strings don't work in OSH
103 shopt --unset ysh:all
104
105 echo r'hello \'
106 echo u'mu \u{3bc}'
107 echo b'byte \yff'
108
109 echo --
110
111 echo r'''
112 raw multi
113 '''
114
115 echo u'''
116 u multi
117 '''
118
119 echo b'''
120 b multi
121 '''
122
123 ## STDOUT:
124 rhello \
125 umu \u{3bc}
126 bbyte \yff
127 --
128 r
129 raw multi
130
131 u
132 u multi
133
134 b
135 b multi
136
137 ## END
138
139 #### J8-style u'' and b'' strings in expression mode
140
141 var x = u'\u{3bc}'
142 var y = b'\yff'
143
144
145 write --end '' -- $x | od -A n -t x1
146 write --end '' -- $y | od -A n -t x1
147
148 ## STDOUT:
149 ce bc
150 ff
151 ## END
152
153 #### J8-style u'' and b'' strings in command mode
154
155 write --end '' -- u'\u{3bc}' | od -A n -t x1
156 write --end '' -- b'\yff' | od -A n -t x1
157
158 # TODO: make this be illegal
159 # echo u'hello \u03bc'
160
161 ## STDOUT:
162 ce bc
163 ff
164 ## END
165
166 #### J8-style multi-line strings u''' b''' in command mode
167
168 write --end '' -- u'''
169 --
170 \u{61}
171 --
172 '''
173 write --end '' -- b'''
174 --
175 \y62
176 --
177 '''
178
179 # Should be illegal?
180 #echo u'hello \u03bc'
181
182 ## STDOUT:
183 --
184 a
185 --
186 --
187 b
188 --
189 ## END
190
191 #### Double Quoted
192 var name = 'World'
193 var g = "Hello $name"
194
195 echo "Hello $name"
196 echo $g
197 ## STDOUT:
198 Hello World
199 Hello World
200 ## END
201
202 #### Multiline strings with '' and ""
203
204 var single = '
205 single
206 '
207
208 var x = 42
209 var double = "
210 double $x
211 "
212
213 echo $single
214 echo $double
215
216 ## STDOUT:
217
218 single
219
220
221 double 42
222
223 ## END
224
225 #### shopt parse_ysh_string
226
227 # Ignored prefix
228 echo r'\'
229
230 # space
231 write r '' end
232
233 # Now it's a regular r
234 shopt --unset parse_ysh_string
235 shopt --unset no_parse_word_join
236 write unset r'\'
237
238 ## STDOUT:
239 \
240 r
241
242 end
243 unset
244 r\
245 ## END
246
247 #### Special rule for <<< ''' and <<< """ - no extra newline
248
249 read --all <<< unquoted
250 pp test_ (_reply)
251
252 read --all <<< 'single with newline'
253 pp test_ (_reply)
254
255 read --all <<< "double with newline"
256 pp test_ (_reply)
257
258 read --all <<< u'j8 with newline'
259 pp test_ (_reply)
260
261 echo
262
263 read --all <<< '''
264 multi
265 single
266 '''
267 pp test_ (_reply)
268
269 read --all <<< """
270 multi
271 double
272 """
273 pp test_ (_reply)
274
275 read --all <<< u'''
276 multi
277 j8
278 '''
279 pp test_ (_reply)
280
281
282 ## STDOUT:
283 (Str) "unquoted\n"
284 (Str) "single with newline\n"
285 (Str) "double with newline\n"
286 (Str) "j8 with newline\n"
287
288 (Str) "multi\nsingle\n"
289 (Str) "multi\ndouble\n"
290 (Str) "multi\nj8\n"
291 ## END
292
293 #### $''' isn't a a multiline string (removed)
294
295 shopt -s ysh:upgrade
296
297 echo $'''
298 foo
299 '''
300
301 ## status: 2
302 ## STDOUT:
303 ## END
304
305
306 #### """ and $""" in Expression Mode
307
308 var line1 = """line1"""
309 echo line1=$line1
310 var line2 = """
311 line2"""
312 echo line2=$line2
313
314 var two = 2
315 var three = 3
316 var x = """
317 one "
318 two = $two ""
319 three = $three
320 """
321 echo "[$x]"
322
323 var i = 42
324 var x = """
325 good
326 bad $i
327 """
328 echo "[$x]"
329
330 # alias
331 var x = $"""
332 good
333 bad $i
334 """
335 echo "[$x]"
336
337 ## STDOUT:
338 line1=line1
339 line2=line2
340 [one "
341 two = 2 ""
342 three = 3
343 ]
344 [good
345 bad 42
346 ]
347 [good
348 bad 42
349 ]
350 ## END
351
352 #### ''' in Expression Mode
353
354 var two = 2
355 var three = 2
356
357 var x = r'''
358 two = $two '
359 three = $three ''
360 \u{61}
361 '''
362 echo "[$x]"
363
364 var x = u'''
365 two = $two '
366 three = $three ''
367 \u{61}
368 '''
369 echo "[$x]"
370
371 var x = b'''
372 two = $two '
373 three = $three ''
374 \u{61} \y61
375 '''
376 echo "[$x]"
377
378 ## STDOUT:
379 [two = $two '
380 three = $three ''
381 \u{61}
382 ]
383 [two = $two '
384 three = $three ''
385 a
386 ]
387 [two = $two '
388 three = $three ''
389 a a
390 ]
391 ## END
392
393
394 #### """ and $""" in Command Mode
395
396 var two=2
397 var three=3
398
399 echo --
400 echo """
401 one "
402 two = $two ""
403 three = $three
404 """
405
406 # optional $ prefix
407 echo --
408 echo $"""
409 one "
410 two = $two ""
411 three = $three
412 """
413
414 echo --
415 tac <<< """
416 one "
417 two = $two ""
418 three = $three
419 """
420
421 ## STDOUT:
422 --
423 one "
424 two = 2 ""
425 three = 3
426
427 --
428 one "
429 two = 2 ""
430 three = 3
431
432 --
433 three = 3
434 two = 2 ""
435 one "
436 ## END
437
438
439 #### ''' in Command Mode
440
441 echo --
442 echo '''
443 two = $two
444 '
445 '' '
446 \u{61}
447 '''
448 ## STDOUT:
449 --
450 two = $two
451 '
452 '' '
453 \u{61}
454
455 ## END
456
457 #### r''' in Command Mode, Expression mode
458
459 echo r'''\'''
460
461 var x = r'''\'''
462 echo $x
463
464 shopt --unset parse_ysh_string
465 shopt --unset no_parse_word_join
466
467 echo r'''\'''
468
469 ## STDOUT:
470 \
471 \
472 r\
473 ## END
474
475
476 #### ''' in Here Doc
477
478 tac <<< '''
479 two = $two
480 '
481 '' '
482 \u{61}
483 '''
484
485 ## STDOUT:
486 \u{61}
487 '' '
488 '
489 two = $two
490 ## END
491
492 #### ''' without parse_triple_quote
493
494 # 2025-06: re-allowed after hack for case (x) ''/foo/
495 # See spec/ysh-TODO-deprecate
496 # This is a corner case that can change
497
498 shopt --unset parse_triple_quote
499
500 echo '''
501 two = $two
502 \u{61}
503 '''
504
505 ## STDOUT:
506
507 two = $two
508 \u{61}
509
510 ## END
511
512 #### here doc with quotes
513
514 # This has 3 right double quotes
515
516 cat <<EOF
517 "hello"
518 ""
519 """
520 EOF
521
522
523 ## STDOUT:
524 "hello"
525 ""
526 """
527 ## END
528
529 #### triple quoted and implicit concatenation
530
531 # Should we allow this? Or I think it's possible to make it a syntax error
532
533 echo '''
534 single
535 '''zz
536
537 echo """
538 double
539 """zz
540 ## status: 2
541 ## stdout-json: ""
542