1 ## compare_shells: bash-4.4 mksh
2 ## oils_failures_allowed: 1
3
4 # Extended assignment language, e.g. typeset, declare, arrays, etc.
5 # Things that dash doesn't support.
6
7 #### local -a
8 # nixpkgs setup.sh uses this (issue #26)
9 f() {
10 local -a array=(x y z)
11 argv.py "${array[@]}"
12 }
13 f
14 ## stdout: ['x', 'y', 'z']
15 ## N-I mksh stdout-json: ""
16 ## N-I mksh status: 1
17
18 #### declare -a
19 # nixpkgs setup.sh uses this (issue #26)
20 declare -a array=(x y z)
21 argv.py "${array[@]}"
22 ## stdout: ['x', 'y', 'z']
23 ## N-I mksh stdout-json: ""
24 ## N-I mksh status: 1
25
26 #### declare -f exit code indicates function existence
27 func2=x # var names are NOT found
28 declare -f myfunc func2
29 echo $?
30
31 myfunc() { echo myfunc; }
32 # This prints the source code.
33 declare -f myfunc func2 > /dev/null
34 echo $?
35
36 func2() { echo func2; }
37 declare -f myfunc func2 > /dev/null
38 echo $?
39 ## STDOUT:
40 1
41 1
42 0
43 ## END
44 ## N-I mksh STDOUT:
45 127
46 127
47 127
48 ## END
49
50 #### declare -F prints function names
51 add () { expr 4 + 4; }
52 div () { expr 6 / 2; }
53 ek () { echo hello; }
54 __ec () { echo hi; }
55 _ab () { expr 10 % 3; }
56
57 declare -F
58 ## STDOUT:
59 declare -f __ec
60 declare -f _ab
61 declare -f add
62 declare -f div
63 declare -f ek
64 ## END
65 ## N-I mksh stdout-json: ""
66 ## N-I mksh status: 127
67
68 #### declare -F with shopt -s extdebug prints more info
69 case $SH in mksh) exit ;; esac
70
71 source $REPO_ROOT/spec/testdata/bash-source-2.sh
72
73 shopt -s extdebug
74
75 add () { expr 4 + 4; }
76
77 declare -F
78 echo
79
80 declare -F add
81 # in bash-source-2
82 declare -F g | sed "s;$REPO_ROOT;ROOT;g"
83
84 ## STDOUT:
85 declare -f add
86 declare -f g
87
88 add 7 main
89 g 3 ROOT/spec/testdata/bash-source-2.sh
90 ## END
91 ## N-I mksh STDOUT:
92 ## END
93
94 #### declare -F with shopt -s extdebug and main file
95 case $SH in mksh) exit ;; esac
96
97 $SH $REPO_ROOT/spec/testdata/extdebug.sh | sed "s;$REPO_ROOT;ROOT;g"
98
99 ## STDOUT:
100 declare -f add
101 declare -f g
102
103 add 5 ROOT/spec/testdata/extdebug.sh
104 g 3 ROOT/spec/testdata/bash-source-2.sh
105 ## END
106 ## N-I mksh STDOUT:
107 ## END
108
109 #### declare -p var (exit status)
110 var1() { echo func; } # function names are NOT found.
111 declare -p var1 var2 >/dev/null
112 echo $?
113
114 var1=x
115 declare -p var1 var2 >/dev/null
116 echo $?
117
118 var2=y
119 declare -p var1 var2 >/dev/null
120 echo $?
121 ## STDOUT:
122 1
123 1
124 0
125 ## N-I mksh STDOUT:
126 127
127 127
128 127
129 ## END
130
131 #### declare
132 test_var1=111
133 readonly test_var2=222
134 export test_var3=333
135 declare -n test_var4=test_var1
136 f1() {
137 local test_var5=555
138 {
139 echo '[declare]'
140 declare
141 echo '[readonly]'
142 readonly
143 echo '[export]'
144 export
145 echo '[local]'
146 local
147 } | grep -E '^\[|^\b.*test_var.\b'
148 }
149 f1
150 ## STDOUT:
151 [declare]
152 test_var1=111
153 test_var2=222
154 test_var3=333
155 test_var4=test_var1
156 test_var5=555
157 [readonly]
158 declare -r test_var2=222
159 [export]
160 declare -x test_var3=333
161 [local]
162 test_var5=555
163 ## END
164 ## OK bash STDOUT:
165 [declare]
166 test_var1=111
167 test_var2=222
168 test_var3=333
169 test_var4=test_var1
170 test_var5=555
171 [readonly]
172 declare -r test_var2="222"
173 [export]
174 declare -x test_var3="333"
175 [local]
176 test_var5=555
177 ## END
178 ## N-I mksh STDOUT:
179 [declare]
180 [readonly]
181 test_var2
182 [export]
183 test_var3
184 [local]
185 typeset test_var1
186 typeset -r test_var2
187 typeset -x test_var3
188 typeset test_var5
189 ## END
190
191 #### declare -p
192 # BUG: bash doesn't output flags with "local -p", which seems to contradict
193 # with manual.
194 test_var1=111
195 readonly test_var2=222
196 export test_var3=333
197 declare -n test_var4=test_var1
198 f1() {
199 local test_var5=555
200 {
201 echo '[declare]'
202 declare -p
203 echo '[readonly]'
204 readonly -p
205 echo '[export]'
206 export -p
207 echo '[local]'
208 local -p
209 } | grep -E '^\[|^\b.*test_var.\b'
210 }
211 f1
212 ## STDOUT:
213 [declare]
214 declare -- test_var1=111
215 declare -r test_var2=222
216 declare -x test_var3=333
217 declare -n test_var4=test_var1
218 declare -- test_var5=555
219 [readonly]
220 declare -r test_var2=222
221 [export]
222 declare -x test_var3=333
223 [local]
224 declare -- test_var5=555
225 ## END
226 ## BUG bash STDOUT:
227 [declare]
228 declare -- test_var1="111"
229 declare -r test_var2="222"
230 declare -x test_var3="333"
231 declare -n test_var4="test_var1"
232 declare -- test_var5="555"
233 [readonly]
234 declare -r test_var2="222"
235 [export]
236 declare -x test_var3="333"
237 [local]
238 test_var5=555
239 ## END
240 ## N-I mksh STDOUT:
241 [declare]
242 [readonly]
243 readonly test_var2=222
244 [export]
245 export test_var3=333
246 [local]
247 typeset test_var1=111
248 typeset -r test_var2=222
249 typeset -x test_var3=333
250 typeset test_var5=555
251 ## END
252
253 #### declare -p doesn't print binary data, but can be loaded into bash
254
255 # bash prints binary data!
256 case $SH in bash*|mksh) exit ;; esac
257
258 unquoted='foo'
259 sq='foo bar'
260 bash1=$'\x1f' # ASCII control char
261 bash2=$'\xfe\xff' # Invalid UTF-8
262
263 s1=$unquoted
264 s2=$sq
265 s3=$bash1
266 s4=$bash2
267
268 declare -a a=("$unquoted" "$sq" "$bash1" "$bash2")
269 declare -A A=(["$unquoted"]="$sq" ["$bash1"]="$bash2")
270
271 #echo lengths ${#s1} ${#s2} ${#s3} ${#s4} ${#a[@]} ${#A[@]}
272
273 declare -p s1 s2 s3 s4 a A | tee tmp.bash
274
275 echo ---
276
277 bash -c 'source tmp.bash; echo "$s1 $s2"; echo -n "$s3" "$s4" | od -A n -t x1'
278 echo bash=$?
279
280 ## STDOUT:
281 declare -- s1=foo
282 declare -- s2='foo bar'
283 declare -- s3=$'\u001f'
284 declare -- s4=$'\xfe\xff'
285 declare -a a=(foo 'foo bar' $'\u001f' $'\xfe\xff')
286 declare -A A=([$'\u001f']=$'\xfe\xff' ['foo']='foo bar')
287 ---
288 foo foo bar
289 1f 20 fe ff
290 bash=0
291 ## END
292
293 ## N-I bash/mksh STDOUT:
294 ## END
295
296
297
298 #### declare -p var
299 # BUG? bash doesn't output anything for 'local/readonly -p var', which seems to
300 # contradict with manual. Besides, 'export -p var' is not described in
301 # manual
302 test_var1=111
303 readonly test_var2=222
304 export test_var3=333
305 declare -n test_var4=test_var1
306 f1() {
307 local test_var5=555
308 {
309 echo '[declare]'
310 declare -p test_var{0..5}
311 echo '[readonly]'
312 readonly -p test_var{0..5}
313 echo '[export]'
314 export -p test_var{0..5}
315 echo '[local]'
316 local -p test_var{0..5}
317 } | grep -E '^\[|^\b.*test_var.\b'
318 }
319 f1
320 ## STDOUT:
321 [declare]
322 declare -- test_var1=111
323 declare -r test_var2=222
324 declare -x test_var3=333
325 declare -n test_var4=test_var1
326 declare -- test_var5=555
327 [readonly]
328 declare -r test_var2=222
329 [export]
330 declare -x test_var3=333
331 [local]
332 declare -- test_var5=555
333 ## END
334 ## BUG bash STDOUT:
335 [declare]
336 declare -- test_var1="111"
337 declare -r test_var2="222"
338 declare -x test_var3="333"
339 declare -n test_var4="test_var1"
340 declare -- test_var5="555"
341 [readonly]
342 [export]
343 [local]
344 ## END
345 ## N-I mksh STDOUT:
346 [declare]
347 [readonly]
348 ## END
349
350 #### declare -p arr
351 test_arr1=()
352 declare -a test_arr2=()
353 declare -A test_arr3=()
354 test_arr4=(1 2 3)
355 declare -a test_arr5=(1 2 3)
356 declare -A test_arr6=(['a']=1 ['b']=2 ['c']=3)
357 test_arr7=()
358 test_arr7[3]=foo
359 declare -p test_arr{1..7}
360 ## STDOUT:
361 declare -a test_arr1=()
362 declare -a test_arr2=()
363 declare -A test_arr3=()
364 declare -a test_arr4=(1 2 3)
365 declare -a test_arr5=(1 2 3)
366 declare -A test_arr6=(['a']=1 ['b']=2 ['c']=3)
367 declare -a test_arr7=([3]=foo)
368 ## END
369 ## OK bash STDOUT:
370 declare -a test_arr1=()
371 declare -a test_arr2=()
372 declare -A test_arr3=()
373 declare -a test_arr4=([0]="1" [1]="2" [2]="3")
374 declare -a test_arr5=([0]="1" [1]="2" [2]="3")
375 declare -A test_arr6=([a]="1" [b]="2" [c]="3" )
376 declare -a test_arr7=([3]="foo")
377 ## END
378 ## N-I mksh stdout-json: ""
379 ## N-I mksh status: 1
380
381 #### declare -p foo=bar doesn't make sense
382 case $SH in (mksh) exit 0; esac
383
384 declare -p foo=bar
385 echo status=$?
386
387 a=b
388 declare -p a foo=bar > tmp.txt
389 echo status=$?
390 sed 's/"//g' tmp.txt # don't care about quotes
391 ## STDOUT:
392 status=1
393 status=1
394 declare -- a=b
395 ## END
396 ## N-I mksh stdout-json: ""
397
398 #### declare -pnrx
399 test_var1=111
400 readonly test_var2=222
401 export test_var3=333
402 declare -n test_var4=test_var1
403 f1() {
404 local test_var5=555
405 {
406 echo '[declare -pn]'
407 declare -pn
408 echo '[declare -pr]'
409 declare -pr
410 echo '[declare -px]'
411 declare -px
412 } | grep -E '^\[|^\b.*test_var.\b'
413 }
414 f1
415 ## STDOUT:
416 [declare -pn]
417 declare -n test_var4=test_var1
418 [declare -pr]
419 declare -r test_var2=222
420 [declare -px]
421 declare -x test_var3=333
422 ## END
423 ## OK bash STDOUT:
424 [declare -pn]
425 declare -n test_var4="test_var1"
426 [declare -pr]
427 declare -r test_var2="222"
428 [declare -px]
429 declare -x test_var3="333"
430 ## END
431 ## N-I mksh STDOUT:
432 [declare -pn]
433 [declare -pr]
434 [declare -px]
435 ## END
436
437 #### declare -paA
438 declare -a test_var6=()
439 declare -A test_var7=()
440 f1() {
441 {
442 echo '[declare -pa]'
443 declare -pa
444 echo '[declare -pA]'
445 declare -pA
446 } | grep -E '^\[|^\b.*test_var.\b'
447 }
448 f1
449 ## STDOUT:
450 [declare -pa]
451 declare -a test_var6=()
452 [declare -pA]
453 declare -A test_var7=()
454 ## END
455 ## OK bash STDOUT:
456 [declare -pa]
457 declare -a test_var6=()
458 [declare -pA]
459 declare -A test_var7=()
460 ## END
461 ## N-I mksh stdout-json: ""
462 ## N-I mksh status: 1
463
464 #### declare -pnrx var
465 # Note: Bash ignores other flags (-nrx) when variable names are supplied while
466 # OSH uses other flags to select variables. Bash's behavior is documented.
467 test_var1=111
468 readonly test_var2=222
469 export test_var3=333
470 declare -n test_var4=test_var1
471 f1() {
472 local test_var5=555
473 {
474 echo '[declare -pn]'
475 declare -pn test_var{0..5}
476 echo '[declare -pr]'
477 declare -pr test_var{0..5}
478 echo '[declare -px]'
479 declare -px test_var{0..5}
480 } | grep -E '^\[|^\b.*test_var.\b'
481 }
482 f1
483 ## STDOUT:
484 [declare -pn]
485 declare -n test_var4=test_var1
486 [declare -pr]
487 declare -r test_var2=222
488 [declare -px]
489 declare -x test_var3=333
490 ## END
491 ## N-I bash STDOUT:
492 [declare -pn]
493 declare -- test_var1="111"
494 declare -r test_var2="222"
495 declare -x test_var3="333"
496 declare -n test_var4="test_var1"
497 declare -- test_var5="555"
498 [declare -pr]
499 declare -- test_var1="111"
500 declare -r test_var2="222"
501 declare -x test_var3="333"
502 declare -n test_var4="test_var1"
503 declare -- test_var5="555"
504 [declare -px]
505 declare -- test_var1="111"
506 declare -r test_var2="222"
507 declare -x test_var3="333"
508 declare -n test_var4="test_var1"
509 declare -- test_var5="555"
510 ## END
511 ## N-I mksh STDOUT:
512 [declare -pn]
513 [declare -pr]
514 [declare -px]
515 ## END
516
517 #### declare -pg
518 test_var1=global
519 f1() {
520 local test_var1=local
521 {
522 declare -pg
523 } | grep -E '^\[|^\b[^"]*test_var.\b'
524 }
525 f1
526 ## STDOUT:
527 declare -- test_var1=global
528 ## END
529 ## N-I bash STDOUT:
530 declare -- test_var1="local"
531 ## END
532 ## N-I mksh stdout-json: ""
533 ## N-I mksh status: 1
534
535 #### declare -pg var
536 test_var1=global
537 f1() {
538 local test_var1=local
539 {
540 declare -pg test_var1
541 } | grep -E '^\[|^\b.*test_var.\b'
542 }
543 f1
544 ## STDOUT:
545 declare -- test_var1=global
546 ## END
547 ## N-I bash STDOUT:
548 declare -- test_var1="local"
549 ## END
550 ## N-I mksh stdout-json: ""
551 ## N-I mksh status: 1
552
553 #### ble.sh: eval -- "$(declare -p var arr)"
554 # This illustrates an example usage of "eval & declare" for exporting
555 # multiple variables from $().
556 eval -- "$(
557 printf '%s\n' a{1..10} | {
558 sum=0 i=0 arr=()
559 while read line; do
560 ((sum+=${#line},i++))
561 arr[$((i/3))]=$line
562 done
563 declare -p sum arr
564 })"
565 echo sum=$sum
566 for ((i=0;i<${#arr[@]};i++)); do
567 echo "arr[$i]=${arr[i]}"
568 done
569 ## STDOUT:
570 sum=21
571 arr[0]=a2
572 arr[1]=a5
573 arr[2]=a8
574 arr[3]=a10
575 ## END
576 ## N-I mksh stdout-json: ""
577 ## N-I mksh status: 1
578
579 #### declare -p and value.Undef
580
581 # This is a regression for a crash
582 # But actually there is also an incompatibility -- we don't print anything
583
584 declare x
585 declare -p x
586
587 function f { local x; declare -p x; }
588 x=1
589 f
590
591 ## STDOUT:
592 declare -- x
593 declare -- x
594 ## END
595
596 ## N-I mksh status: 127
597 ## N-I mksh STDOUT:
598 ## END
599
600 #### eval -- "$(declare -p arr)" (restore arrays w/ unset elements)
601 arr=(1 2 3)
602 eval -- "$(arr=(); arr[3]= arr[4]=foo; declare -p arr)"
603 for i in {0..4}; do
604 echo "arr[$i]: ${arr[$i]+set ... [}${arr[$i]-unset}${arr[$i]+]}"
605 done
606 ## STDOUT:
607 arr[0]: unset
608 arr[1]: unset
609 arr[2]: unset
610 arr[3]: set ... []
611 arr[4]: set ... [foo]
612 ## END
613 ## N-I mksh stdout-json: ""
614 ## N-I mksh status: 1
615
616 #### declare -p UNDEF (and typeset) -- prints something to stderr
617
618 x=42
619 readonly x
620 export x
621
622 declare -p x undef1 undef2 2> de
623
624 typeset -p x undef1 undef2 2> ty
625
626 # readonly -p and export -p don't accept args! They only print all
627 #
628 # These do not accept args
629 # readonly -p x undef1 undef2 2> re
630 # export -p x undef1 undef2 2> ex
631
632 f() {
633 # it behaves weird with x
634 #local -p undef1 undef2 2>lo
635 local -p a b b>lo
636 #local -p x undef1 undef2 2> lo
637 }
638 # local behaves differently in bash 4.4 and bash 5, not specifying now
639 # f
640 # files='de ty lo'
641
642 files='de ty'
643
644 wc -l $files
645 #cat $files
646
647 ## STDOUT:
648 declare -rx x="42"
649 declare -rx x="42"
650 2 de
651 2 ty
652 4 total
653 ## END
654
655 ## OK osh STDOUT:
656 declare -rx x=42
657 declare -rx x=42
658 2 de
659 2 ty
660 4 total
661 ## END
662
663 ## N-I mksh STDOUT:
664 typeset -x -r x=42
665 1 de
666 0 ty
667 1 total
668 ## END
669
670
671 #### typeset -f
672 # mksh implement typeset but not declare
673 typeset -f myfunc func2
674 echo $?
675
676 myfunc() { echo myfunc; }
677 # This prints the source code.
678 typeset -f myfunc func2 > /dev/null
679 echo $?
680
681 func2() { echo func2; }
682 typeset -f myfunc func2 > /dev/null
683 echo $?
684 ## STDOUT:
685 1
686 1
687 0
688 ## END
689
690 #### typeset -p
691 var1() { echo func; } # function names are NOT found.
692 typeset -p var1 var2 >/dev/null
693 echo $?
694
695 var1=x
696 typeset -p var1 var2 >/dev/null
697 echo $?
698
699 var2=y
700 typeset -p var1 var2 >/dev/null
701 echo $?
702 ## STDOUT:
703 1
704 1
705 0
706 ## BUG mksh STDOUT:
707 # mksh doesn't respect exit codes
708 0
709 0
710 0
711 ## END
712
713 #### typeset -r makes a string readonly
714 typeset -r s1='12'
715 typeset -r s2='34'
716
717 s1='c'
718 echo status=$?
719 s2='d'
720 echo status=$?
721
722 s1+='e'
723 echo status=$?
724 s2+='f'
725 echo status=$?
726
727 unset s1
728 echo status=$?
729 unset s2
730 echo status=$?
731
732 ## status: 1
733 ## stdout-json: ""
734 ## OK mksh status: 2
735 ## OK bash status: 0
736 ## OK bash STDOUT:
737 status=1
738 status=1
739 status=1
740 status=1
741 status=1
742 status=1
743 ## END
744
745 #### typeset -ar makes it readonly
746 typeset -a -r array1=(1 2)
747 typeset -ar array2=(3 4)
748
749 array1=('c')
750 echo status=$?
751 array2=('d')
752 echo status=$?
753
754 array1+=('e')
755 echo status=$?
756 array2+=('f')
757 echo status=$?
758
759 unset array1
760 echo status=$?
761 unset array2
762 echo status=$?
763
764 ## status: 1
765 ## stdout-json: ""
766 ## OK bash status: 0
767 ## OK bash STDOUT:
768 status=1
769 status=1
770 status=1
771 status=1
772 status=1
773 status=1
774 ## END
775 ## N-I mksh status: 1
776 ## N-I mksh stdout-json: ""
777
778 #### typeset -x makes it exported
779 typeset -rx PYTHONPATH=lib/
780 printenv.py PYTHONPATH
781 ## STDOUT:
782 lib/
783 ## END
784
785 #### Multiple assignments / array assignments on a line
786 a=1 b[0+0]=2 c=3
787 echo $a ${b[@]} $c
788 ## stdout: 1 2 3
789
790 #### Env bindings shouldn't contain array assignments
791 a=1 b[0]=2 c=3 printenv.py a b c
792 ## status: 2
793 ## stdout-json: ""
794 ## OK bash STDOUT:
795 1
796 None
797 3
798 ## END
799 ## OK bash status: 0
800 ## BUG mksh STDOUT:
801 1
802 2
803 3
804 ## END
805 ## BUG mksh status: 0
806
807 #### syntax error in array assignment
808 a=x b[0+]=y c=z
809 echo $a $b $c
810 ## status: 2
811 ## stdout-json: ""
812 ## BUG bash stdout: x
813 ## BUG bash status: 0
814 ## OK mksh stdout-json: ""
815 ## OK mksh status: 1
816
817 #### declare -g (bash-specific; bash-completion uses it)
818 f() {
819 declare -g G=42
820 declare L=99
821
822 declare -Ag dict
823 dict["foo"]=bar
824
825 declare -A localdict
826 localdict["spam"]=Eggs
827
828 # For bash-completion
829 eval 'declare -Ag ev'
830 ev["ev1"]=ev2
831 }
832 f
833 argv.py "$G" "$L"
834 argv.py "${dict["foo"]}" "${localdict["spam"]}"
835 argv.py "${ev["ev1"]}"
836 ## STDOUT:
837 ['42', '']
838 ['bar', '']
839 ['ev2']
840 ## END
841 ## N-I mksh STDOUT:
842 ['', '']
843 ## END
844 ## N-I mksh status: 1
845
846 #### myvar=typeset (another form of dynamic assignment)
847 myvar=typeset
848 x='a b'
849 $myvar x=$x
850 echo $x
851 ## STDOUT:
852 a
853 ## END
854 ## OK osh STDOUT:
855 a b
856 ## END
857
858 #### dynamic array parsing is not allowed
859 code='x=(1 2 3)'
860 typeset -a "$code" # note: -a flag is required
861 echo status=$?
862 argv.py "$x"
863 ## STDOUT:
864 status=2
865 ['']
866 ## END
867 ## OK mksh STDOUT:
868 status=0
869 ['(1 2 3)']
870 ## END
871 # bash allows it
872 ## OK bash STDOUT:
873 status=0
874 ['1']
875 ## END
876
877 #### dynamic flag in array in assign builtin
878 typeset b
879 b=(unused1 unused2) # this works in mksh
880
881 a=(x 'foo=F' 'bar=B')
882 typeset -"${a[@]}"
883 echo foo=$foo
884 echo bar=$bar
885 printenv.py foo
886 printenv.py bar
887
888 # syntax error in mksh! But works in bash and zsh.
889 #typeset -"${a[@]}" b=(spam eggs)
890 #echo "length of b = ${#b[@]}"
891 #echo "b[0]=${b[0]}"
892 #echo "b[1]=${b[1]}"
893
894 ## STDOUT:
895 foo=F
896 bar=B
897 F
898 B
899 ## END
900
901 #### typeset +x
902 export e=E
903 printenv.py e
904 typeset +x e=E2
905 printenv.py e # no longer exported
906 ## STDOUT:
907 E
908 None
909 ## END
910
911 #### typeset +r removes read-only attribute (TODO: documented in bash to do nothing)
912 readonly r=r1
913 echo r=$r
914
915 # clear the readonly flag. Why is this accepted in bash, but doesn't do
916 # anything?
917 typeset +r r=r2
918 echo r=$r
919
920 r=r3
921 echo r=$r
922
923 ## status: 0
924 ## STDOUT:
925 r=r1
926 r=r2
927 r=r3
928 ## END
929
930 # mksh doesn't allow you to unset
931 ## OK mksh status: 2
932 ## OK mksh STDOUT:
933 r=r1
934 ## END
935
936 # bash doesn't allow you to unset
937 ## OK bash status: 0
938 ## OK bash STDOUT:
939 r=r1
940 r=r1
941 r=r1
942 ## END
943
944
945 #### function name with /
946 ble/foo() { echo hi; }
947 declare -F ble/foo
948 echo status=$?
949 ## STDOUT:
950 ble/foo
951 status=0
952 ## END
953 ## N-I mksh stdout: status=127
954 ## N-I zsh stdout-json: ""
955 ## N-I zsh status: 1
956 ## N-I ash stdout-json: ""
957 ## N-I ash status: 2
958
959 #### invalid var name
960 typeset foo/bar
961 ## status: 1
962
963 #### unset and shell funcs
964 foo() {
965 echo bar
966 }
967
968 foo
969
970 declare -F
971 unset foo
972 declare -F
973
974 foo
975
976 ## status: 127
977 ## STDOUT:
978 bar
979 declare -f foo
980 ## END
981 ## N-I mksh status: 0
982 ## N-I mksh STDOUT:
983 bar
984 bar
985 ## END