1 |
commit: ddfcd534ecd1d7415041b431006e087c717dea4c |
2 |
Author: André Aparício <aparicio99 <AT> gmail <DOT> com> |
3 |
AuthorDate: Mon May 28 02:17:41 2012 +0000 |
4 |
Commit: Petteri Räty <betelgeuse <AT> gentoo <DOT> org> |
5 |
CommitDate: Tue Jul 3 01:16:19 2012 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=ddfcd534 |
7 |
|
8 |
Builtin: Implement set builtin |
9 |
|
10 |
--- |
11 |
Makefile.am | 3 + |
12 |
bashast/libbashWalker.g | 2 +- |
13 |
scripts/function_def.bash | 15 +++++++ |
14 |
src/builtins/set_builtin.cpp | 79 ++++++++++++++++++++++++++++++++++++++ |
15 |
src/builtins/set_builtin.h | 46 ++++++++++++++++++++++ |
16 |
src/builtins/tests/set_tests.cpp | 43 ++++++++++++++++++++ |
17 |
src/core/interpreter.cpp | 15 +++++++ |
18 |
src/core/interpreter.h | 3 + |
19 |
src/cppbash_builtin.cpp | 2 + |
20 |
9 files changed, 207 insertions(+), 1 deletions(-) |
21 |
|
22 |
diff --git a/Makefile.am b/Makefile.am |
23 |
index ca61091..cc57503 100644 |
24 |
--- a/Makefile.am |
25 |
+++ b/Makefile.am |
26 |
@@ -106,6 +106,7 @@ cppunittests_SOURCES = test/run_tests.cpp \ |
27 |
src/builtins/tests/shopt_tests.cpp \ |
28 |
src/builtins/tests/return_tests.cpp \ |
29 |
src/builtins/tests/read_tests.cpp \ |
30 |
+ src/builtins/tests/set_tests.cpp \ |
31 |
src/builtins/tests/printf_tests.cpp \ |
32 |
test/test.h \ |
33 |
test/test.cpp \ |
34 |
@@ -239,6 +240,8 @@ libbash_la_SOURCES = include/common.h \ |
35 |
src/builtins/unset_builtin.cpp \ |
36 |
src/builtins/read_builtin.h \ |
37 |
src/builtins/read_builtin.cpp \ |
38 |
+ src/builtins/set_builtin.h \ |
39 |
+ src/builtins/set_builtin.cpp \ |
40 |
src/builtins/builtin_exceptions.h \ |
41 |
$(GENERATED_PARSER_C) \ |
42 |
$(GENERATED_PARSER_H) \ |
43 |
|
44 |
diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g |
45 |
index fb1ca55..9157574 100644 |
46 |
--- a/bashast/libbashWalker.g |
47 |
+++ b/bashast/libbashWalker.g |
48 |
@@ -649,7 +649,7 @@ execute_command[std::string& name, std::vector<std::string>& libbash_args] |
49 |
bool redirection = false; |
50 |
} |
51 |
@init { |
52 |
- if(name != "local") |
53 |
+ if(name != "local" && name != "set") |
54 |
current_scope.reset(new interpreter::local_scope(*walker)); |
55 |
} |
56 |
:var_def[true]* (redirect[out, err, in]{ redirection = true; })* { |
57 |
|
58 |
diff --git a/scripts/function_def.bash b/scripts/function_def.bash |
59 |
index b425221..53cc6da 100644 |
60 |
--- a/scripts/function_def.bash |
61 |
+++ b/scripts/function_def.bash |
62 |
@@ -76,6 +76,21 @@ func_positional_args() { |
63 |
func_positional_args 1 2 3 |
64 |
IFS=" \t\n" |
65 |
|
66 |
+nested_func_override_positional_args() { |
67 |
+ echo $@ |
68 |
+ set -- 40 50 60 |
69 |
+ echo $@ |
70 |
+} |
71 |
+func_override_positional_args() { |
72 |
+ echo $@ |
73 |
+ nested_func_override_positional_args 4 5 6 |
74 |
+ set -- 10 20 30 |
75 |
+ echo $@ |
76 |
+} |
77 |
+set -- foo bar |
78 |
+func_override_positional_args 1 2 3 |
79 |
+echo $@ |
80 |
+ |
81 |
if true; then |
82 |
function_in_compound_statement() { |
83 |
echo "function_in_compound_statement" |
84 |
|
85 |
diff --git a/src/builtins/set_builtin.cpp b/src/builtins/set_builtin.cpp |
86 |
new file mode 100644 |
87 |
index 0000000..fca0f82 |
88 |
--- /dev/null |
89 |
+++ b/src/builtins/set_builtin.cpp |
90 |
@@ -0,0 +1,79 @@ |
91 |
+/* |
92 |
+ Please use git log for copyright holder and year information |
93 |
+ |
94 |
+ This file is part of libbash. |
95 |
+ |
96 |
+ libbash is free software: you can redistribute it and/or modify |
97 |
+ it under the terms of the GNU General Public License as published by |
98 |
+ the Free Software Foundation, either version 2 of the License, or |
99 |
+ (at your option) any later version. |
100 |
+ |
101 |
+ libbash is distributed in the hope that it will be useful, |
102 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
103 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
104 |
+ GNU General Public License for more details. |
105 |
+ |
106 |
+ You should have received a copy of the GNU General Public License |
107 |
+ along with libbash. If not, see <http://www.gnu.org/licenses/>. |
108 |
+*/ |
109 |
+/// |
110 |
+/// \file set_builtin.cpp |
111 |
+/// \brief class that implements the set builtin |
112 |
+/// |
113 |
+#include "builtins/set_builtin.h" |
114 |
+ |
115 |
+#include "core/interpreter.h" |
116 |
+#include "exceptions.h" |
117 |
+ |
118 |
+int set_builtin::exec(const std::vector<std::string>& bash_args) |
119 |
+{ |
120 |
+ if(bash_args.empty()) |
121 |
+ { |
122 |
+ throw libbash::unsupported_exception("set: variables printing are not supported"); |
123 |
+ return 1; |
124 |
+ } |
125 |
+ |
126 |
+ if(bash_args[0][0] != '-' && bash_args[0][0] != '+') |
127 |
+ { |
128 |
+ throw libbash::illegal_argument_exception("set: invalid option"); |
129 |
+ return 1; |
130 |
+ } |
131 |
+ |
132 |
+ switch(bash_args[0][1]) |
133 |
+ { |
134 |
+ case '-': |
135 |
+ if(bash_args[0][0] != '-') { |
136 |
+ throw libbash::unsupported_exception("set: invalid option"); |
137 |
+ return 1; |
138 |
+ } |
139 |
+ else |
140 |
+ { |
141 |
+ _walker.define_positional_arguments(bash_args.begin() + 1, bash_args.end()); |
142 |
+ return 0; |
143 |
+ } |
144 |
+ case 'a': |
145 |
+ case 'b': |
146 |
+ case 'e': |
147 |
+ case 'f': |
148 |
+ case 'h': |
149 |
+ case 'k': |
150 |
+ case 'm': |
151 |
+ case 'n': |
152 |
+ case 'p': |
153 |
+ case 't': |
154 |
+ case 'u': |
155 |
+ case 'v': |
156 |
+ case 'x': |
157 |
+ case 'B': |
158 |
+ case 'C': |
159 |
+ case 'E': |
160 |
+ case 'H': |
161 |
+ case 'P': |
162 |
+ case 'T': |
163 |
+ throw libbash::unsupported_exception("set " + bash_args[0] + " is not supported yet"); |
164 |
+ return 1; |
165 |
+ default: |
166 |
+ throw libbash::illegal_argument_exception("set: unrecognized option: " + bash_args[0]); |
167 |
+ return 1; |
168 |
+ } |
169 |
+} |
170 |
|
171 |
diff --git a/src/builtins/set_builtin.h b/src/builtins/set_builtin.h |
172 |
new file mode 100644 |
173 |
index 0000000..ad27243 |
174 |
--- /dev/null |
175 |
+++ b/src/builtins/set_builtin.h |
176 |
@@ -0,0 +1,46 @@ |
177 |
+/* |
178 |
+ Please use git log for copyright holder and year information |
179 |
+ |
180 |
+ This file is part of libbash. |
181 |
+ |
182 |
+ libbash is free software: you can redistribute it and/or modify |
183 |
+ it under the terms of the GNU General Public License as published by |
184 |
+ the Free Software Foundation, either version 2 of the License, or |
185 |
+ (at your option) any later version. |
186 |
+ |
187 |
+ libbash is distributed in the hope that it will be useful, |
188 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
189 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
190 |
+ GNU General Public License for more details. |
191 |
+ |
192 |
+ You should have received a copy of the GNU General Public License |
193 |
+ along with libbash. If not, see <http://www.gnu.org/licenses/>. |
194 |
+*/ |
195 |
+/// |
196 |
+/// \file set_builtin.h |
197 |
+/// \brief class that implements the set builtin |
198 |
+/// |
199 |
+ |
200 |
+#ifndef LIBBASH_BUILTINS_SET_BUILTIN_H_ |
201 |
+#define LIBBASH_BUILTINS_SET_BUILTIN_H_ |
202 |
+ |
203 |
+#include "cppbash_builtin.h" |
204 |
+ |
205 |
+/// |
206 |
+/// \class set_builtin |
207 |
+/// \brief the set builtin for bash |
208 |
+/// |
209 |
+class set_builtin: public virtual cppbash_builtin |
210 |
+{ |
211 |
+public: |
212 |
+ BUILTIN_CONSTRUCTOR(set) |
213 |
+ |
214 |
+ /// |
215 |
+ /// \brief runs the set builtin on the supplied arguments |
216 |
+ /// \param bash_args the arguments to the set builtin |
217 |
+ /// \return exit status of set |
218 |
+ /// |
219 |
+ virtual int exec(const std::vector<std::string>& bash_args); |
220 |
+}; |
221 |
+ |
222 |
+#endif |
223 |
|
224 |
diff --git a/src/builtins/tests/set_tests.cpp b/src/builtins/tests/set_tests.cpp |
225 |
new file mode 100644 |
226 |
index 0000000..c4807c9 |
227 |
--- /dev/null |
228 |
+++ b/src/builtins/tests/set_tests.cpp |
229 |
@@ -0,0 +1,43 @@ |
230 |
+/* |
231 |
+ Please use git log for copyright holder and year information |
232 |
+ |
233 |
+ This file is part of libbash. |
234 |
+ |
235 |
+ libbash is free software: you can redistribute it and/or modify |
236 |
+ it under the terms of the GNU General Public License as published by |
237 |
+ the Free Software Foundation, either version 2 of the License, or |
238 |
+ (at your option) any later version. |
239 |
+ |
240 |
+ libbash is distributed in the hope that it will be useful, |
241 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
242 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
243 |
+ GNU General Public License for more details. |
244 |
+ |
245 |
+ You should have received a copy of the GNU General Public License |
246 |
+ along with libbash. If not, see <http://www.gnu.org/licenses/>. |
247 |
+*/ |
248 |
+/// |
249 |
+/// \file set_tests.cpp |
250 |
+/// \brief series of unit tests for set builtin |
251 |
+/// |
252 |
+#include <boost/lexical_cast.hpp> |
253 |
+#include <gtest/gtest.h> |
254 |
+ |
255 |
+#include "core/interpreter.h" |
256 |
+#include "cppbash_builtin.h" |
257 |
+#include "exceptions.h" |
258 |
+ |
259 |
+TEST(set_builtin_test, positional) |
260 |
+{ |
261 |
+ interpreter walker; |
262 |
+ |
263 |
+ EXPECT_EQ(0, cppbash_builtin::exec("set", {"--", "1", "2", "3"}, std::cout, std::cerr, std::cin, walker)); |
264 |
+ EXPECT_EQ(3, walker.get_array_length("*")); |
265 |
+ EXPECT_STREQ("1", walker.resolve<std::string>("*", 1).c_str()); |
266 |
+ EXPECT_STREQ("2", walker.resolve<std::string>("*", 2).c_str()); |
267 |
+ EXPECT_STREQ("3", walker.resolve<std::string>("*", 3).c_str()); |
268 |
+ |
269 |
+ EXPECT_EQ(0, cppbash_builtin::exec("set", {"--"}, std::cout, std::cerr, std::cin, walker)); |
270 |
+ EXPECT_EQ(0, walker.get_array_length("*")); |
271 |
+ EXPECT_STREQ("", walker.resolve<std::string>("*", 1).c_str()); |
272 |
+} |
273 |
|
274 |
diff --git a/src/core/interpreter.cpp b/src/core/interpreter.cpp |
275 |
index b048353..405023d 100644 |
276 |
--- a/src/core/interpreter.cpp |
277 |
+++ b/src/core/interpreter.cpp |
278 |
@@ -312,6 +312,21 @@ void interpreter::define_function_arguments(scope& current_stack, |
279 |
current_stack["*"].reset(new variable("*", positional_args)); |
280 |
} |
281 |
|
282 |
+void interpreter::define_positional_arguments(const std::vector<std::string>::const_iterator begin, |
283 |
+ const std::vector<std::string>::const_iterator end) |
284 |
+{ |
285 |
+ std::map<unsigned, std::string> positional_args; |
286 |
+ std::vector<std::string>::const_iterator iter = begin; |
287 |
+ |
288 |
+ for(auto i = 1u; iter != end ; ++i, ++iter) |
289 |
+ positional_args[i] = *iter; |
290 |
+ |
291 |
+ if(local_members.size() < 1) |
292 |
+ define("*", positional_args); |
293 |
+ else |
294 |
+ define_local("*", positional_args); |
295 |
+} |
296 |
+ |
297 |
namespace |
298 |
{ |
299 |
bool check_function_name(const std::string& name) |
300 |
|
301 |
diff --git a/src/core/interpreter.h b/src/core/interpreter.h |
302 |
index fbb9d48..dd72377 100644 |
303 |
--- a/src/core/interpreter.h |
304 |
+++ b/src/core/interpreter.h |
305 |
@@ -521,6 +521,9 @@ public: |
306 |
/// \return zero unless n is greater than $# or less than zero, non-zero otherwise. |
307 |
int shift(int shift_number); |
308 |
|
309 |
+ void define_positional_arguments(const std::vector<std::string>::const_iterator begin, |
310 |
+ const std::vector<std::string>::const_iterator end); |
311 |
+ |
312 |
/// \brief perform expansion like ${var//foo/bar} |
313 |
/// \param value the value to be expanded |
314 |
/// \param pattern the pattern used to match the value |
315 |
|
316 |
diff --git a/src/cppbash_builtin.cpp b/src/cppbash_builtin.cpp |
317 |
index c93b94a..e4a7c29 100644 |
318 |
--- a/src/cppbash_builtin.cpp |
319 |
+++ b/src/cppbash_builtin.cpp |
320 |
@@ -45,6 +45,7 @@ |
321 |
#include "builtins/source_builtin.h" |
322 |
#include "builtins/unset_builtin.h" |
323 |
#include "builtins/read_builtin.h" |
324 |
+#include "builtins/set_builtin.h" |
325 |
|
326 |
namespace qi = boost::spirit::qi; |
327 |
namespace karma = boost::spirit::karma; |
328 |
@@ -75,6 +76,7 @@ cppbash_builtin::builtins_type& cppbash_builtin::builtins() { |
329 |
{"let", boost::factory<let_builtin*>()}, |
330 |
{"unset", boost::factory<unset_builtin*>()}, |
331 |
{"read", boost::factory<read_builtin*>()}, |
332 |
+ {"set", boost::factory<set_builtin*>()}, |
333 |
}); |
334 |
return *p; |
335 |
} |