OILS / spec / sh-func.test.sh View on Github | oils.pub

186 lines, 99 significant
1## oils_failures_allowed: 1
2## compare_shells: bash dash mksh
3
4#### Locals don't leak
5f() {
6 local f_var=f_var
7}
8f
9echo $f_var
10## stdout:
11
12#### Globals leak
13f() {
14 f_var=f_var
15}
16f
17echo $f_var
18## stdout: f_var
19
20#### Return statement
21f() {
22 echo one
23 return 42
24 echo two
25}
26f
27## stdout: one
28## status: 42
29
30#### Dynamic Scope
31f() {
32 echo $g_var
33}
34g() {
35 local g_var=g_var
36 f
37}
38g
39## stdout: g_var
40
41#### Dynamic Scope Mutation (wow this is bad)
42f() {
43 g_var=f_mutation
44}
45g() {
46 local g_var=g_var
47 echo "g_var=$g_var"
48 f
49 echo "g_var=$g_var"
50}
51g
52echo g_var=$g_var
53## STDOUT:
54g_var=g_var
55g_var=f_mutation
56g_var=
57## END
58
59#### Assign local separately
60f() {
61 local f
62 f='new-value'
63 echo "[$f]"
64}
65f
66## stdout: [new-value]
67## status: 0
68
69#### Assign a local and global on same line
70myglobal=
71f() {
72 local mylocal
73 mylocal=L myglobal=G
74 echo "[$mylocal $myglobal]"
75}
76f
77echo "[$mylocal $myglobal]"
78## STDOUT:
79[L G]
80[ G]
81## END
82## status: 0
83
84#### Return without args gives previous
85f() {
86 ( exit 42 )
87 return
88}
89f
90echo status=$?
91## STDOUT:
92status=42
93## END
94
95#### return "" (a lot of disagreement)
96f() {
97 echo f
98 return ""
99}
100
101f
102echo status=$?
103## STDOUT:
104f
105status=0
106## END
107## status: 0
108
109## OK dash status: 2
110## OK dash STDOUT:
111f
112## END
113
114## BUG mksh STDOUT:
115f
116status=1
117## END
118
119## BUG bash STDOUT:
120f
121status=2
122## END
123
124#### return $empty
125f() {
126 echo f
127 empty=
128 return $empty
129}
130
131f
132echo status=$?
133## STDOUT:
134f
135status=0
136## END
137
138#### Subshell function
139
140f() ( return 42; )
141# BUG: OSH raises invalid control flow! I think we should just allow 'return'
142# but maybe not 'break' etc.
143g() ( return 42 )
144# bash warns here but doesn't cause an error
145# g() ( break )
146
147f
148echo status=$?
149g
150echo status=$?
151
152## STDOUT:
153status=42
154status=42
155## END
156
157
158#### Scope of global variable when sourced in function (Shell Functions aren't Closures)
159set -u
160
161echo >tmp.sh '
162g="global"
163local L="local"
164
165test_func() {
166 echo "g = $g"
167 echo "L = $L"
168}
169'
170
171main() {
172 # a becomes local here
173 # test_func is defined globally
174 . ./tmp.sh
175}
176
177main
178
179# a is not defined
180test_func
181
182## status: 1
183## OK dash status: 2
184## STDOUT:
185g = global
186## END