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