1 |
## oils_failures_allowed: 7
|
2 |
## compare_shells: bash mksh
|
3 |
|
4 |
|
5 |
show_value() {
|
6 |
local -n array_name=$1
|
7 |
local idx=$2
|
8 |
echo "${array_name[$idx]}"
|
9 |
}
|
10 |
shadock=(ga bu zo meu)
|
11 |
show_value shadock 2
|
12 |
## stdout: zo
|
13 |
|
14 |
|
15 |
set1() {
|
16 |
local -n array_name=$1
|
17 |
local val=$2
|
18 |
array_name[1]=$val
|
19 |
}
|
20 |
shadock=(a b c d)
|
21 |
set1 shadock ZZZ
|
22 |
echo ${shadock[@]}
|
23 |
## STDOUT:
|
24 |
a ZZZ c d
|
25 |
## END
|
26 |
|
27 |
|
28 |
show_value() {
|
29 |
local -n array_name=$1
|
30 |
local idx=$2
|
31 |
echo "${array_name[$idx]}"
|
32 |
}
|
33 |
days=([monday]=eggs [tuesday]=bread [sunday]=jam)
|
34 |
show_value days sunday
|
35 |
## stdout: jam
|
36 |
## BUG mksh stdout: [monday]=eggs
|
37 |
# mksh note: it coerces "days" to 0? Horrible.
|
38 |
|
39 |
|
40 |
show_value() {
|
41 |
local -n array_name=$1
|
42 |
local idx=$2
|
43 |
echo "${array_name[$idx]}"
|
44 |
}
|
45 |
caller() {
|
46 |
local shadock=(ga bu zo meu)
|
47 |
show_value shadock 2
|
48 |
}
|
49 |
caller
|
50 |
## stdout: zo
|
51 |
# mksh appears not to have local arrays!
|
52 |
## BUG mksh stdout-json: ""
|
53 |
## BUG mksh status: 1
|
54 |
|
55 |
|
56 |
|
57 |
x=foo
|
58 |
|
59 |
ref=x
|
60 |
|
61 |
echo ref=$ref
|
62 |
|
63 |
typeset -n ref
|
64 |
echo ref=$ref
|
65 |
|
66 |
# mutate underlying var
|
67 |
x=bar
|
68 |
echo ref=$ref
|
69 |
|
70 |
typeset +n ref
|
71 |
echo ref=$ref
|
72 |
|
73 |
## STDOUT:
|
74 |
ref=x
|
75 |
ref=foo
|
76 |
ref=bar
|
77 |
ref=x
|
78 |
## END
|
79 |
|
80 |
|
81 |
x=XX
|
82 |
y=YY
|
83 |
|
84 |
ref=x
|
85 |
ref=y
|
86 |
echo 1 ref=$ref
|
87 |
|
88 |
# now it's a reference
|
89 |
typeset -n ref
|
90 |
|
91 |
echo 2 ref=$ref # prints YY
|
92 |
|
93 |
ref=XXXX
|
94 |
echo 3 ref=$ref # it actually prints y, which is XXXX
|
95 |
|
96 |
# now Y is mutated!
|
97 |
echo 4 y=$y
|
98 |
|
99 |
## STDOUT:
|
100 |
1 ref=y
|
101 |
2 ref=YY
|
102 |
3 ref=XXXX
|
103 |
4 y=XXXX
|
104 |
## END
|
105 |
|
106 |
|
107 |
|
108 |
foo=FOO # should NOT use this
|
109 |
|
110 |
x=foo
|
111 |
ref=x
|
112 |
|
113 |
echo ref=$ref
|
114 |
echo "!ref=${!ref}"
|
115 |
|
116 |
echo 'NOW A NAMEREF'
|
117 |
|
118 |
typeset -n ref
|
119 |
echo ref=$ref
|
120 |
echo "!ref=${!ref}"
|
121 |
|
122 |
## STDOUT:
|
123 |
ref=x
|
124 |
!ref=foo
|
125 |
NOW A NAMEREF
|
126 |
ref=foo
|
127 |
!ref=x
|
128 |
## END
|
129 |
## N-I mksh STDOUT:
|
130 |
ref=x
|
131 |
!ref=ref
|
132 |
NOW A NAMEREF
|
133 |
ref=foo
|
134 |
!ref=x
|
135 |
## END
|
136 |
|
137 |
|
138 |
set -- one two three
|
139 |
|
140 |
ref='#'
|
141 |
echo ref=$ref
|
142 |
typeset -n ref
|
143 |
echo ref=$ref
|
144 |
|
145 |
## STDOUT:
|
146 |
ref=#
|
147 |
ref=#
|
148 |
## END
|
149 |
|
150 |
# mksh does respect it!! Gah.
|
151 |
## OK mksh STDOUT:
|
152 |
ref=#
|
153 |
ref=3
|
154 |
## END
|
155 |
|
156 |
|
157 |
|
158 |
shopt -s strict_nameref
|
159 |
|
160 |
ref='#'
|
161 |
echo ref=$ref
|
162 |
typeset -n ref
|
163 |
echo ref=$ref
|
164 |
## STDOUT:
|
165 |
ref=#
|
166 |
## END
|
167 |
## status: 1
|
168 |
## N-I bash status: 0
|
169 |
## N-I bash STDOUT:
|
170 |
ref=#
|
171 |
ref=#
|
172 |
## END
|
173 |
## N-I mksh status: 0
|
174 |
## N-I mksh STDOUT:
|
175 |
ref=#
|
176 |
ref=0
|
177 |
## END
|
178 |
|
179 |
|
180 |
set -- one two three
|
181 |
|
182 |
x=X
|
183 |
|
184 |
ref='1'
|
185 |
echo ref=$ref
|
186 |
typeset -n ref
|
187 |
echo ref=$ref
|
188 |
|
189 |
# BUG: This is really assigning '1', which is INVALID
|
190 |
# with strict_nameref that degrades!!!
|
191 |
ref2='$1'
|
192 |
echo ref2=$ref2
|
193 |
typeset -n ref2
|
194 |
echo ref2=$ref2
|
195 |
|
196 |
x=foo
|
197 |
|
198 |
ref3='x'
|
199 |
echo ref3=$ref3
|
200 |
typeset -n ref3
|
201 |
echo ref3=$ref3
|
202 |
|
203 |
## STDOUT:
|
204 |
ref=1
|
205 |
ref=1
|
206 |
ref2=$1
|
207 |
ref2=$1
|
208 |
ref3=x
|
209 |
ref3=foo
|
210 |
## END
|
211 |
## BUG mksh status: 1
|
212 |
## BUG mksh STDOUT:
|
213 |
ref=1
|
214 |
ref=one
|
215 |
ref2=$1
|
216 |
## END
|
217 |
|
218 |
|
219 |
ref=1 # mksh makes this READ-ONLY! Because it's not valid.
|
220 |
|
221 |
echo ref=$ref
|
222 |
typeset -n ref
|
223 |
echo ref=$ref
|
224 |
|
225 |
ref=foo
|
226 |
echo ref=$ref
|
227 |
## STDOUT:
|
228 |
ref=1
|
229 |
ref=1
|
230 |
ref=foo
|
231 |
## END
|
232 |
## OK mksh status: 2
|
233 |
## OK mksh STDOUT:
|
234 |
ref=1
|
235 |
ref=
|
236 |
## END
|
237 |
|
238 |
|
239 |
case $SH in *bash|*mksh) exit ;; esac
|
240 |
|
241 |
shopt -s strict_nameref
|
242 |
|
243 |
ref=1
|
244 |
|
245 |
echo ref=$ref
|
246 |
typeset -n ref
|
247 |
echo ref=$ref
|
248 |
|
249 |
ref=foo
|
250 |
echo ref=$ref
|
251 |
## status: 1
|
252 |
## STDOUT:
|
253 |
ref=1
|
254 |
## END
|
255 |
## N-I bash/mksh status: 0
|
256 |
## N-I bash/mksh stdout-json: ""
|
257 |
|
258 |
|
259 |
typeset -n ref
|
260 |
|
261 |
# This is technically incorrect: an undefined name shouldn't evaluate to empty
|
262 |
# string. mksh doesn't allow it.
|
263 |
echo ref=$ref
|
264 |
|
265 |
echo nounset
|
266 |
set -o nounset
|
267 |
echo ref=$ref
|
268 |
## status: 1
|
269 |
## STDOUT:
|
270 |
ref=
|
271 |
nounset
|
272 |
## END
|
273 |
## OK mksh stdout-json: ""
|
274 |
|
275 |
|
276 |
typeset -n ref
|
277 |
echo ref=$ref
|
278 |
|
279 |
# this is a no-op in bash, should be stricter
|
280 |
ref=x
|
281 |
echo ref=$ref
|
282 |
|
283 |
typeset -n ref2=undef
|
284 |
echo ref2=$ref2
|
285 |
ref2=x
|
286 |
echo ref2=$ref2
|
287 |
|
288 |
## STDOUT:
|
289 |
ref=
|
290 |
ref=
|
291 |
ref2=
|
292 |
ref2=x
|
293 |
## END
|
294 |
|
295 |
# mksh gives a good error: empty nameref target
|
296 |
## OK mksh status: 1
|
297 |
## OK mksh stdout-json: ""
|
298 |
|
299 |
|
300 |
typeset -n ref
|
301 |
|
302 |
echo ref=$ref
|
303 |
|
304 |
# Now that it's a string, it still has the -n attribute
|
305 |
x=XX
|
306 |
ref=x
|
307 |
echo ref=$ref
|
308 |
|
309 |
## STDOUT:
|
310 |
ref=
|
311 |
ref=XX
|
312 |
## END
|
313 |
## N-I mksh status: 1
|
314 |
## N-I mksh stdout-json: ""
|
315 |
|
316 |
|
317 |
x=X
|
318 |
typeset -n ref #=x
|
319 |
echo hi
|
320 |
|
321 |
# bash prints warning: REMOVES the nameref attribute here!
|
322 |
ref=(x y)
|
323 |
echo ref=$ref
|
324 |
|
325 |
## status: 1
|
326 |
## STDOUT:
|
327 |
hi
|
328 |
## END
|
329 |
## N-I mksh status: 1
|
330 |
## N-I mksh stdout-json: ""
|
331 |
## BUG bash status: 0
|
332 |
## BUG bash STDOUT:
|
333 |
hi
|
334 |
ref=x
|
335 |
## END
|
336 |
|
337 |
|
338 |
x=foo
|
339 |
typeset -n -x ref=x
|
340 |
|
341 |
# hm bash ignores it but mksh doesn't. maybe disallow it.
|
342 |
printenv.py x ref
|
343 |
echo ---
|
344 |
export x
|
345 |
printenv.py x ref
|
346 |
## STDOUT:
|
347 |
None
|
348 |
x
|
349 |
---
|
350 |
foo
|
351 |
x
|
352 |
## END
|
353 |
## OK mksh STDOUT:
|
354 |
None
|
355 |
None
|
356 |
---
|
357 |
foo
|
358 |
None
|
359 |
## END
|
360 |
|
361 |
|
362 |
|
363 |
|
364 |
# hm bash also ignores -r when -n is set
|
365 |
|
366 |
x=XX
|
367 |
typeset -n -r ref=x
|
368 |
|
369 |
echo ref=$ref
|
370 |
|
371 |
# it feels like I shouldn't be able to mutate this?
|
372 |
ref=XXXX
|
373 |
echo ref=$ref
|
374 |
|
375 |
x=X
|
376 |
echo x=$x
|
377 |
|
378 |
## STDOUT:
|
379 |
ref=XX
|
380 |
ref=XXXX
|
381 |
x=X
|
382 |
## END
|
383 |
|
384 |
|
385 |
|
386 |
x=X
|
387 |
typeset -n -r ref=x
|
388 |
|
389 |
echo ref=$ref
|
390 |
|
391 |
# it feels like I shouldn't be able to mutate this?
|
392 |
ref=XX
|
393 |
echo ref=$ref
|
394 |
|
395 |
# now the underling variable is immutable
|
396 |
typeset -r x
|
397 |
|
398 |
ref=XXX
|
399 |
echo ref=$ref
|
400 |
echo x=$x
|
401 |
|
402 |
## status: 1
|
403 |
## OK mksh status: 2
|
404 |
## STDOUT:
|
405 |
ref=X
|
406 |
ref=XX
|
407 |
## END
|
408 |
|
409 |
## OK bash status: 0
|
410 |
## OK bash STDOUT:
|
411 |
ref=X
|
412 |
ref=XX
|
413 |
ref=XX
|
414 |
x=XX
|
415 |
## END
|
416 |
|
417 |
|
418 |
x=X
|
419 |
typeset -n ref=x
|
420 |
echo ref=$ref
|
421 |
|
422 |
# this works
|
423 |
unset ref
|
424 |
echo ref=$ref
|
425 |
echo x=$x
|
426 |
|
427 |
## STDOUT:
|
428 |
ref=X
|
429 |
ref=
|
430 |
x=
|
431 |
## END
|
432 |
|
433 |
|
434 |
x=foo
|
435 |
typeset -n ref=x
|
436 |
typeset -n ref_to_ref=ref
|
437 |
echo ref_to_ref=$ref_to_ref
|
438 |
echo ref=$ref
|
439 |
## STDOUT:
|
440 |
ref_to_ref=foo
|
441 |
ref=foo
|
442 |
## END
|
443 |
|
444 |
|
445 |
typeset -n ref1=ref2
|
446 |
typeset -n ref2=ref1
|
447 |
echo defined
|
448 |
echo ref1=$ref1
|
449 |
echo ref2=$ref1
|
450 |
## status: 1
|
451 |
## STDOUT:
|
452 |
defined
|
453 |
## END
|
454 |
## OK mksh stdout-json: ""
|
455 |
## BUG bash status: 0
|
456 |
## BUG bash STDOUT:
|
457 |
defined
|
458 |
ref1=
|
459 |
ref2=
|
460 |
## END
|
461 |
|
462 |
|
463 |
typeset -n ref1=ref2
|
464 |
typeset -n ref2=ref1 # not detected here
|
465 |
echo defined $?
|
466 |
ref1=z # detected here
|
467 |
echo mutated $?
|
468 |
## status: 1
|
469 |
## STDOUT:
|
470 |
defined 0
|
471 |
## END
|
472 |
## OK mksh stdout-json: ""
|
473 |
## BUG bash status: 0
|
474 |
## BUG bash STDOUT:
|
475 |
defined 0
|
476 |
mutated 1
|
477 |
## END
|
478 |
|
479 |
|
480 |
|
481 |
f3() {
|
482 |
local -n ref=$1
|
483 |
ref=x
|
484 |
}
|
485 |
|
486 |
f2() {
|
487 |
f3 "$@"
|
488 |
}
|
489 |
|
490 |
f1() {
|
491 |
local F1=F1
|
492 |
echo F1=$F1
|
493 |
f2 F1
|
494 |
echo F1=$F1
|
495 |
}
|
496 |
f1
|
497 |
|
498 |
## STDOUT:
|
499 |
F1=F1
|
500 |
F1=x
|
501 |
## END
|
502 |
|
503 |
|
504 |
|
505 |
x=XX
|
506 |
y=YY
|
507 |
typeset -n ref=x
|
508 |
echo ref=$ref
|
509 |
echo x=$x
|
510 |
echo y=$y
|
511 |
|
512 |
echo ----
|
513 |
typeset -n ref=y
|
514 |
echo ref=$ref
|
515 |
echo x=$x
|
516 |
echo y=$y
|
517 |
echo ----
|
518 |
ref=z
|
519 |
echo ref=$ref
|
520 |
echo x=$x
|
521 |
echo y=$y
|
522 |
|
523 |
## STDOUT:
|
524 |
ref=XX
|
525 |
x=XX
|
526 |
y=YY
|
527 |
----
|
528 |
ref=YY
|
529 |
x=XX
|
530 |
y=YY
|
531 |
----
|
532 |
ref=z
|
533 |
x=XX
|
534 |
y=z
|
535 |
## END
|
536 |
|
537 |
|
538 |
|
539 |
typeset -n ref='a[2]'
|
540 |
a=(zero one two three)
|
541 |
echo ref=$ref
|
542 |
## STDOUT:
|
543 |
ref=two
|
544 |
## END
|
545 |
|
546 |
|
547 |
|
548 |
# this confuses code and data
|
549 |
typeset -n ref='a[$(echo 2) + 1]'
|
550 |
a=(zero one two three)
|
551 |
echo ref=$ref
|
552 |
## STDOUT:
|
553 |
ref=three
|
554 |
## END
|
555 |
|
556 |
|
557 |
|
558 |
# this confuses code and data
|
559 |
typeset -n ref='a[@]'
|
560 |
a=('A B' C)
|
561 |
argv.py ref "$ref" # READ through ref works
|
562 |
ref=(X Y Z) # WRITE through doesn't work
|
563 |
echo status=$?
|
564 |
argv.py 'ref[@]' "${ref[@]}"
|
565 |
argv.py ref "$ref" # JOINING mangles the array?
|
566 |
argv.py 'a[@]' "${a[@]}"
|
567 |
## STDOUT:
|
568 |
['ref', 'A B', 'C']
|
569 |
status=1
|
570 |
['ref[@]']
|
571 |
['ref', 'A B', 'C']
|
572 |
['a[@]', 'A B', 'C']
|
573 |
## END
|
574 |
## OK mksh status: 1
|
575 |
## OK mksh stdout-json: ""
|
576 |
|
577 |
|
578 |
|
579 |
# This is DIFFERENT than the nameref itself being 'array[0]' !
|
580 |
|
581 |
array=(X Y Z)
|
582 |
typeset -n ref=array
|
583 |
ref[0]=xx
|
584 |
echo ${array[@]}
|
585 |
## STDOUT:
|
586 |
xx Y Z
|
587 |
## END
|
588 |
|
589 |
|
590 |
array=(X Y Z)
|
591 |
typeset -n ref='array[0]'
|
592 |
ref[0]=foo # error in bash: 'array[0]': not a valid identifier
|
593 |
echo status=$?
|
594 |
echo ${array[@]}
|
595 |
## STDOUT:
|
596 |
status=1
|
597 |
X Y Z
|
598 |
## END
|
599 |
## BUG mksh STDOUT:
|
600 |
status=0
|
601 |
foo Y Z
|
602 |
## END
|
603 |
|
604 |
|
605 |
|
606 |
set -- A B
|
607 |
typeset -n ref='@' # bash gives an error here
|
608 |
echo status=$?
|
609 |
|
610 |
echo ref=$ref # bash doesn't give an error here
|
611 |
echo status=$?
|
612 |
## status: 1
|
613 |
## stdout-json: ""
|
614 |
## OK bash status: 0
|
615 |
## OK bash STDOUT:
|
616 |
status=1
|
617 |
ref=
|
618 |
status=0
|
619 |
## END
|
620 |
|
621 |
|
622 |
typeset -A bashup_ev_r
|
623 |
bashup_ev_r['foo']=bar
|
624 |
|
625 |
p() {
|
626 |
local s=foo
|
627 |
local -n e=bashup_ev["$s"] f=bashup_ev_r["$s"]
|
628 |
# Different!
|
629 |
#local e=bashup_ev["$s"] f=bashup_ev_r["$s"]
|
630 |
argv.py "$f"
|
631 |
}
|
632 |
p
|
633 |
## STDOUT:
|
634 |
['bar']
|
635 |
## END
|
636 |
## N-I mksh stdout-json: ""
|
637 |
## N-I mksh status: 1
|