1 |
commit: 24300d3ce1fccca3034a3bd9497341902d1cd4c0 |
2 |
Author: Mu Qiao <qiaomuf <AT> gentoo <DOT> org> |
3 |
AuthorDate: Thu May 5 14:20:00 2011 +0000 |
4 |
Commit: Petteri Räty <betelgeuse <AT> gentoo <DOT> org> |
5 |
CommitDate: Sat May 7 09:13:51 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=24300d3c |
7 |
|
8 |
Builtin: implement the return builtin |
9 |
|
10 |
--- |
11 |
Makefile.am | 5 +++ |
12 |
bashast/libbashWalker.g | 17 +++++++-- |
13 |
scripts/function_def.bash | 16 ++++++++ |
14 |
scripts/function_def.bash.result | 2 + |
15 |
scripts/source_return.sh | 2 + |
16 |
.../{source_builtin.cpp => builtin_exceptions.h} | 39 ++++++++------------ |
17 |
.../{source_builtin.cpp => return_builtin.cpp} | 33 ++++++----------- |
18 |
.../{tests/source_tests.cpp => return_builtin.h} | 32 +++++----------- |
19 |
src/builtins/source_builtin.cpp | 7 +++- |
20 |
.../tests/{source_tests.cpp => return_tests.cpp} | 27 ++++++-------- |
21 |
src/builtins/tests/source_tests.cpp | 37 +++++++++++++++++-- |
22 |
src/cppbash_builtin.cpp | 7 +++- |
23 |
12 files changed, 130 insertions(+), 94 deletions(-) |
24 |
|
25 |
diff --git a/Makefile.am b/Makefile.am |
26 |
index a3890bb..499624f 100644 |
27 |
--- a/Makefile.am |
28 |
+++ b/Makefile.am |
29 |
@@ -102,6 +102,7 @@ cppunittests_SOURCES = test/run_tests.cpp \ |
30 |
src/builtins/tests/echo_tests.cpp \ |
31 |
src/builtins/tests/boolean_tests.cpp \ |
32 |
src/builtins/tests/source_tests.cpp \ |
33 |
+ src/builtins/tests/return_tests.cpp \ |
34 |
test/post_check.cpp \ |
35 |
test/api_test.cpp \ |
36 |
test/walker_test.cpp |
37 |
@@ -161,8 +162,11 @@ libcppbash_la_SOURCES = src/common.h \ |
38 |
src/builtins/boolean_builtins.h \ |
39 |
src/builtins/source_builtin.h \ |
40 |
src/builtins/source_builtin.cpp \ |
41 |
+ src/builtins/return_builtin.h \ |
42 |
+ src/builtins/return_builtin.cpp \ |
43 |
src/builtins/inherit_builtin.h \ |
44 |
src/builtins/inherit_builtin.cpp \ |
45 |
+ src/builtins/builtin_exceptions.h \ |
46 |
$(GENERATED_PARSER_C) \ |
47 |
$(GENERATED_PARSER_H) \ |
48 |
src/core/interpreter_exception.h \ |
49 |
@@ -189,6 +193,7 @@ EXTRA_DIST = bashast/bashast.g \ |
50 |
test/verify_bashs_test.sh \ |
51 |
scripts/source_false.sh \ |
52 |
scripts/source_true.sh \ |
53 |
+ scripts/source_return.sh \ |
54 |
utils/meta_gen.sh \ |
55 |
scripts/foo.eclass \ |
56 |
$(BASH_TESTS) \ |
57 |
|
58 |
diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g |
59 |
index 064556a..beabfdf 100644 |
60 |
--- a/bashast/libbashWalker.g |
61 |
+++ b/bashast/libbashWalker.g |
62 |
@@ -42,6 +42,7 @@ options |
63 |
|
64 |
#include <boost/format.hpp> |
65 |
|
66 |
+ #include "builtins/builtin_exceptions.h" |
67 |
#include "core/interpreter.h" |
68 |
#include "cppbash_builtin.h" |
69 |
|
70 |
@@ -285,10 +286,18 @@ simple_command |
71 |
:^(COMMAND string_expr (argument[libbash_args])* var_def*) { |
72 |
if(walker->has_function($string_expr.libbash_value)) |
73 |
{ |
74 |
- walker->set_status(walker->call($string_expr.libbash_value, |
75 |
- libbash_args, |
76 |
- ctx, |
77 |
- compound_command)); |
78 |
+ ANTLR3_MARKER command_index = INDEX(); |
79 |
+ try |
80 |
+ { |
81 |
+ walker->set_status(walker->call($string_expr.libbash_value, |
82 |
+ libbash_args, |
83 |
+ ctx, |
84 |
+ compound_command)); |
85 |
+ } |
86 |
+ catch(return_exception& e) |
87 |
+ { |
88 |
+ SEEK(command_index); |
89 |
+ } |
90 |
} |
91 |
else if(cppbash_builtin::is_builtin($string_expr.libbash_value)) |
92 |
{ |
93 |
|
94 |
diff --git a/scripts/function_def.bash b/scripts/function_def.bash |
95 |
index 194d030..ee57a94 100644 |
96 |
--- a/scripts/function_def.bash |
97 |
+++ b/scripts/function_def.bash |
98 |
@@ -26,3 +26,19 @@ FOO001="4 5" |
99 |
ARRAY=(1 2 3) |
100 |
func_with_args ${ARRAY[@]} $FOO001 |
101 |
func_with_args 100 $ARG2 $ARG3 $ARG4 |
102 |
+ |
103 |
+func_with_return() |
104 |
+{ |
105 |
+ return 1 |
106 |
+ NOT_EXIST=1 |
107 |
+} |
108 |
+func_with_return |
109 |
+RETURN_STATUS=$? |
110 |
+func_with_return2() |
111 |
+{ |
112 |
+ true |
113 |
+ return |
114 |
+ NOT_EXIST=1 |
115 |
+} |
116 |
+func_with_return2 |
117 |
+RETURN_STATUS2=$? |
118 |
|
119 |
diff --git a/scripts/function_def.bash.result b/scripts/function_def.bash.result |
120 |
index de9f3f8..b02d5bc 100644 |
121 |
--- a/scripts/function_def.bash.result |
122 |
+++ b/scripts/function_def.bash.result |
123 |
@@ -9,3 +9,5 @@ ARRAY=1 2 3 |
124 |
EAPI=5 |
125 |
FOO001=4 5 |
126 |
MY_PV=2.0.3-r1 |
127 |
+RETURN_STATUS=1 |
128 |
+RETURN_STATUS2=0 |
129 |
|
130 |
diff --git a/scripts/source_return.sh b/scripts/source_return.sh |
131 |
new file mode 100644 |
132 |
index 0000000..dab5ede |
133 |
--- /dev/null |
134 |
+++ b/scripts/source_return.sh |
135 |
@@ -0,0 +1,2 @@ |
136 |
+return 10 |
137 |
+NOT_EXIST=1 |
138 |
|
139 |
diff --git a/src/builtins/source_builtin.cpp b/src/builtins/builtin_exceptions.h |
140 |
similarity index 50% |
141 |
copy from src/builtins/source_builtin.cpp |
142 |
copy to src/builtins/builtin_exceptions.h |
143 |
index d2b4bcb..8cce34e 100644 |
144 |
--- a/src/builtins/source_builtin.cpp |
145 |
+++ b/src/builtins/builtin_exceptions.h |
146 |
@@ -17,34 +17,25 @@ |
147 |
along with libbash. If not, see <http://www.gnu.org/licenses/>. |
148 |
*/ |
149 |
/// |
150 |
-/// \file source_builtin.h |
151 |
+/// \file builtin_exceptions.h |
152 |
/// \author Mu Qiao |
153 |
-/// \brief class that implements the source builtin |
154 |
+/// \brief implementations for builtin exceptions |
155 |
/// |
156 |
|
157 |
-#include "builtins/source_builtin.h" |
158 |
+#ifndef LIBBASH_BUILTINS_BUILTIN_EXCEPTIONS_H_ |
159 |
+#define LIBBASH_BUILTINS_BUILTIN_EXCEPTIONS_H_ |
160 |
|
161 |
-#include <fstream> |
162 |
-#include <string> |
163 |
+#include <stdexcept> |
164 |
|
165 |
-#include "cppbash_builtin.h" |
166 |
-#include "core/interpreter.h" |
167 |
-#include "core/interpreter_exception.h" |
168 |
-#include "core/bash_ast.h" |
169 |
- |
170 |
-int source_builtin::exec(const std::vector<std::string>& bash_args) |
171 |
+/// |
172 |
+/// \class return_exception |
173 |
+/// \brief thrown when executing the return builtin |
174 |
+/// |
175 |
+class return_exception: public std::runtime_error |
176 |
{ |
177 |
- if(bash_args.size() == 0) |
178 |
- throw interpreter_exception("should provide one argument for source builtin"); |
179 |
- |
180 |
- // we need fix this to pass extra arguments as positional parameters |
181 |
- const std::string& path = bash_args[0]; |
182 |
- std::ifstream input(path); |
183 |
- if(!input) |
184 |
- throw interpreter_exception(path + " can't be read"); |
185 |
- |
186 |
- bash_ast ast(input); |
187 |
- ast.interpret_with(_walker); |
188 |
+public: |
189 |
+ explicit return_exception(): |
190 |
+ runtime_error(""){} |
191 |
+}; |
192 |
|
193 |
- return _walker.get_status(); |
194 |
-} |
195 |
+#endif |
196 |
|
197 |
diff --git a/src/builtins/source_builtin.cpp b/src/builtins/return_builtin.cpp |
198 |
similarity index 54% |
199 |
copy from src/builtins/source_builtin.cpp |
200 |
copy to src/builtins/return_builtin.cpp |
201 |
index d2b4bcb..3180345 100644 |
202 |
--- a/src/builtins/source_builtin.cpp |
203 |
+++ b/src/builtins/return_builtin.cpp |
204 |
@@ -17,34 +17,23 @@ |
205 |
along with libbash. If not, see <http://www.gnu.org/licenses/>. |
206 |
*/ |
207 |
/// |
208 |
-/// \file source_builtin.h |
209 |
+/// \file return_builtin.h |
210 |
/// \author Mu Qiao |
211 |
-/// \brief class that implements the source builtin |
212 |
+/// \brief implementation for the return builtin |
213 |
/// |
214 |
|
215 |
-#include "builtins/source_builtin.h" |
216 |
+#include "builtins/return_builtin.h" |
217 |
|
218 |
-#include <fstream> |
219 |
-#include <string> |
220 |
- |
221 |
-#include "cppbash_builtin.h" |
222 |
+#include "builtins/builtin_exceptions.h" |
223 |
#include "core/interpreter.h" |
224 |
-#include "core/interpreter_exception.h" |
225 |
-#include "core/bash_ast.h" |
226 |
+#include "cppbash_builtin.h" |
227 |
|
228 |
-int source_builtin::exec(const std::vector<std::string>& bash_args) |
229 |
+int return_builtin::exec(const std::vector<std::string>& bash_args) |
230 |
{ |
231 |
- if(bash_args.size() == 0) |
232 |
- throw interpreter_exception("should provide one argument for source builtin"); |
233 |
- |
234 |
- // we need fix this to pass extra arguments as positional parameters |
235 |
- const std::string& path = bash_args[0]; |
236 |
- std::ifstream input(path); |
237 |
- if(!input) |
238 |
- throw interpreter_exception(path + " can't be read"); |
239 |
- |
240 |
- bash_ast ast(input); |
241 |
- ast.interpret_with(_walker); |
242 |
+ if(bash_args.size() > 1) |
243 |
+ throw interpreter_exception("return: too many arguments"); |
244 |
+ else if(bash_args.size() == 1) |
245 |
+ _walker.set_status(boost::lexical_cast<int>(bash_args[0])); |
246 |
|
247 |
- return _walker.get_status(); |
248 |
+ throw return_exception(); |
249 |
} |
250 |
|
251 |
diff --git a/src/builtins/tests/source_tests.cpp b/src/builtins/return_builtin.h |
252 |
similarity index 51% |
253 |
copy from src/builtins/tests/source_tests.cpp |
254 |
copy to src/builtins/return_builtin.h |
255 |
index ac0fd3c..54663c2 100644 |
256 |
--- a/src/builtins/tests/source_tests.cpp |
257 |
+++ b/src/builtins/return_builtin.h |
258 |
@@ -17,31 +17,19 @@ |
259 |
along with libbash. If not, see <http://www.gnu.org/licenses/>. |
260 |
*/ |
261 |
/// |
262 |
-/// \file source_tests.cpp |
263 |
-/// \brief series of unit tests for source built in |
264 |
+/// \file return_builtin.h |
265 |
+/// \brief implementation for the return builtin |
266 |
/// |
267 |
+#ifndef LIBBASH_BUILTINS_RETURN_BUILTIN_H_ |
268 |
+#define LIBBASH_BUILTINS_RETURN_BUILTIN_H_ |
269 |
|
270 |
-#include <cstdlib> |
271 |
- |
272 |
-#include <iostream> |
273 |
-#include <string> |
274 |
- |
275 |
-#include <gtest/gtest.h> |
276 |
- |
277 |
-#include "core/interpreter.h" |
278 |
#include "cppbash_builtin.h" |
279 |
|
280 |
-using namespace std; |
281 |
- |
282 |
-TEST(source_builtin_test, source) |
283 |
+class return_builtin : public virtual cppbash_builtin |
284 |
{ |
285 |
- std::string srcdir(getenv("srcdir")); |
286 |
- interpreter walker; |
287 |
- int status = cppbash_builtin::exec("source", {srcdir + "/scripts/source_true.sh"}, std::cout, std::cerr, std::cin, walker); |
288 |
- EXPECT_EQ(status, 0); |
289 |
- EXPECT_TRUE(walker.has_function("foo")); |
290 |
- EXPECT_STREQ("hello", walker.resolve<std::string>("FOO001").c_str()); |
291 |
+public: |
292 |
+ BUILTIN_CONSTRUCTOR(return) |
293 |
+ virtual int exec(const std::vector<std::string>& ); |
294 |
+}; |
295 |
|
296 |
- status = cppbash_builtin::exec("source", {srcdir + "/scripts/source_false.sh"}, std::cout, std::cerr, std::cin, walker); |
297 |
- EXPECT_EQ(status, 1); |
298 |
-} |
299 |
+#endif |
300 |
|
301 |
diff --git a/src/builtins/source_builtin.cpp b/src/builtins/source_builtin.cpp |
302 |
index d2b4bcb..1e82c77 100644 |
303 |
--- a/src/builtins/source_builtin.cpp |
304 |
+++ b/src/builtins/source_builtin.cpp |
305 |
@@ -27,6 +27,7 @@ |
306 |
#include <fstream> |
307 |
#include <string> |
308 |
|
309 |
+#include "builtins/builtin_exceptions.h" |
310 |
#include "cppbash_builtin.h" |
311 |
#include "core/interpreter.h" |
312 |
#include "core/interpreter_exception.h" |
313 |
@@ -44,7 +45,11 @@ int source_builtin::exec(const std::vector<std::string>& bash_args) |
314 |
throw interpreter_exception(path + " can't be read"); |
315 |
|
316 |
bash_ast ast(input); |
317 |
- ast.interpret_with(_walker); |
318 |
+ try |
319 |
+ { |
320 |
+ ast.interpret_with(_walker); |
321 |
+ } |
322 |
+ catch(return_exception& e) {} |
323 |
|
324 |
return _walker.get_status(); |
325 |
} |
326 |
|
327 |
diff --git a/src/builtins/tests/source_tests.cpp b/src/builtins/tests/return_tests.cpp |
328 |
similarity index 58% |
329 |
copy from src/builtins/tests/source_tests.cpp |
330 |
copy to src/builtins/tests/return_tests.cpp |
331 |
index ac0fd3c..23e147a 100644 |
332 |
--- a/src/builtins/tests/source_tests.cpp |
333 |
+++ b/src/builtins/tests/return_tests.cpp |
334 |
@@ -17,31 +17,26 @@ |
335 |
along with libbash. If not, see <http://www.gnu.org/licenses/>. |
336 |
*/ |
337 |
/// |
338 |
-/// \file source_tests.cpp |
339 |
-/// \brief series of unit tests for source built in |
340 |
+/// \file return_tests.cpp |
341 |
+/// \brief series of unit tests for return builtin |
342 |
/// |
343 |
- |
344 |
-#include <cstdlib> |
345 |
- |
346 |
#include <iostream> |
347 |
-#include <string> |
348 |
|
349 |
+#include <boost/lexical_cast.hpp> |
350 |
#include <gtest/gtest.h> |
351 |
|
352 |
+#include "builtins/builtin_exceptions.h" |
353 |
#include "core/interpreter.h" |
354 |
#include "cppbash_builtin.h" |
355 |
|
356 |
-using namespace std; |
357 |
- |
358 |
-TEST(source_builtin_test, source) |
359 |
+TEST(return_builtin_test, bad_argument) |
360 |
{ |
361 |
- std::string srcdir(getenv("srcdir")); |
362 |
interpreter walker; |
363 |
- int status = cppbash_builtin::exec("source", {srcdir + "/scripts/source_true.sh"}, std::cout, std::cerr, std::cin, walker); |
364 |
- EXPECT_EQ(status, 0); |
365 |
- EXPECT_TRUE(walker.has_function("foo")); |
366 |
- EXPECT_STREQ("hello", walker.resolve<std::string>("FOO001").c_str()); |
367 |
+ EXPECT_THROW(cppbash_builtin::exec("return", {"abc"}, std::cout, std::cerr, std::cin, walker), boost::bad_lexical_cast); |
368 |
+} |
369 |
|
370 |
- status = cppbash_builtin::exec("source", {srcdir + "/scripts/source_false.sh"}, std::cout, std::cerr, std::cin, walker); |
371 |
- EXPECT_EQ(status, 1); |
372 |
+TEST(return_builtin_test, bad_location) |
373 |
+{ |
374 |
+ interpreter walker; |
375 |
+ EXPECT_THROW(cppbash_builtin::exec("return", {}, std::cout, std::cerr, std::cin, walker), return_exception); |
376 |
} |
377 |
|
378 |
diff --git a/src/builtins/tests/source_tests.cpp b/src/builtins/tests/source_tests.cpp |
379 |
index ac0fd3c..ae603ae 100644 |
380 |
--- a/src/builtins/tests/source_tests.cpp |
381 |
+++ b/src/builtins/tests/source_tests.cpp |
382 |
@@ -28,20 +28,51 @@ |
383 |
|
384 |
#include <gtest/gtest.h> |
385 |
|
386 |
+#include "builtins/builtin_exceptions.h" |
387 |
#include "core/interpreter.h" |
388 |
#include "cppbash_builtin.h" |
389 |
|
390 |
using namespace std; |
391 |
|
392 |
-TEST(source_builtin_test, source) |
393 |
+TEST(source_builtin_test, source_true) |
394 |
{ |
395 |
std::string srcdir(getenv("srcdir")); |
396 |
interpreter walker; |
397 |
- int status = cppbash_builtin::exec("source", {srcdir + "/scripts/source_true.sh"}, std::cout, std::cerr, std::cin, walker); |
398 |
+ |
399 |
+ int status = cppbash_builtin::exec("source", |
400 |
+ {srcdir + "/scripts/source_true.sh"}, |
401 |
+ std::cout, |
402 |
+ std::cerr, |
403 |
+ std::cin, |
404 |
+ walker); |
405 |
EXPECT_EQ(status, 0); |
406 |
EXPECT_TRUE(walker.has_function("foo")); |
407 |
EXPECT_STREQ("hello", walker.resolve<std::string>("FOO001").c_str()); |
408 |
+} |
409 |
|
410 |
- status = cppbash_builtin::exec("source", {srcdir + "/scripts/source_false.sh"}, std::cout, std::cerr, std::cin, walker); |
411 |
+TEST(source_builtin_test, source_false) |
412 |
+{ |
413 |
+ std::string srcdir(getenv("srcdir")); |
414 |
+ interpreter walker; |
415 |
+ int status = cppbash_builtin::exec("source", |
416 |
+ {srcdir + "/scripts/source_false.sh"}, |
417 |
+ std::cout, |
418 |
+ std::cerr, |
419 |
+ std::cin, |
420 |
+ walker); |
421 |
EXPECT_EQ(status, 1); |
422 |
} |
423 |
+ |
424 |
+TEST(source_builtin_test, source_return) |
425 |
+{ |
426 |
+ std::string srcdir(getenv("srcdir")); |
427 |
+ interpreter walker; |
428 |
+ int status = cppbash_builtin::exec("source", |
429 |
+ {srcdir + "/scripts/source_return.sh"}, |
430 |
+ std::cout, |
431 |
+ std::cerr, |
432 |
+ std::cin, |
433 |
+ walker); |
434 |
+ EXPECT_EQ(status, 10); |
435 |
+ EXPECT_TRUE(walker.is_unset_or_null("NOT_EXIST", 0)); |
436 |
+} |
437 |
|
438 |
diff --git a/src/cppbash_builtin.cpp b/src/cppbash_builtin.cpp |
439 |
index dc6ec3e..71d3153 100644 |
440 |
--- a/src/cppbash_builtin.cpp |
441 |
+++ b/src/cppbash_builtin.cpp |
442 |
@@ -23,9 +23,11 @@ |
443 |
/// |
444 |
|
445 |
#include "cppbash_builtin.h" |
446 |
+ |
447 |
+#include "builtins/boolean_builtins.h" |
448 |
#include "builtins/echo_builtin.h" |
449 |
#include "builtins/inherit_builtin.h" |
450 |
-#include "builtins/boolean_builtins.h" |
451 |
+#include "builtins/return_builtin.h" |
452 |
#include "builtins/source_builtin.h" |
453 |
|
454 |
cppbash_builtin::cppbash_builtin(BUILTIN_ARGS): _out_stream(&out), _err_stream(&err), _inp_stream(&in), _walker(walker) |
455 |
@@ -38,7 +40,8 @@ cppbash_builtin::builtins_type& cppbash_builtin::builtins() { |
456 |
{"source", boost::factory<source_builtin*>()}, |
457 |
{"inherit", boost::factory<inherit_builtin*>()}, |
458 |
{"true", boost::factory<true_builtin*>()}, |
459 |
- {"false", boost::factory<false_builtin*>()} |
460 |
+ {"false", boost::factory<false_builtin*>()}, |
461 |
+ {"return", boost::factory<return_builtin*>()} |
462 |
}); |
463 |
return *p; |
464 |
} |