1 |
commit: 9d812d19cbcfe79cdbf5daa5b42cab1c2436902b |
2 |
Author: Mu Qiao <qiaomuf <AT> gentoo <DOT> org> |
3 |
AuthorDate: Thu Apr 21 14:36:54 2011 +0000 |
4 |
Commit: Petteri Räty <betelgeuse <AT> gentoo <DOT> org> |
5 |
CommitDate: Thu Apr 28 03:09:04 2011 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=9d812d19 |
7 |
|
8 |
Builtin: implement inherit builtin |
9 |
|
10 |
metadata_generator is improved to make use of the information added |
11 |
by inherit builtin. |
12 |
|
13 |
--- |
14 |
Makefile.am | 3 + |
15 |
scripts/foo.eclass | 5 + |
16 |
scripts/sunpinyin-2.0.3-r1.ebuild | 2 + |
17 |
scripts/sunpinyin-2.0.3-r1.ebuild.result | 10 +- |
18 |
src/builtins/inherit_builtin.cpp | 130 ++++++++++++++++++++++++++++++ |
19 |
src/builtins/inherit_builtin.h | 55 +++++++++++++ |
20 |
src/cppbash_builtin.cpp | 2 + |
21 |
test/ebuild_compiler.sh | 2 +- |
22 |
utils/metadata_generator.cpp | 40 +++++++--- |
23 |
9 files changed, 232 insertions(+), 17 deletions(-) |
24 |
|
25 |
diff --git a/Makefile.am b/Makefile.am |
26 |
index 5518599..a3890bb 100644 |
27 |
--- a/Makefile.am |
28 |
+++ b/Makefile.am |
29 |
@@ -161,6 +161,8 @@ libcppbash_la_SOURCES = src/common.h \ |
30 |
src/builtins/boolean_builtins.h \ |
31 |
src/builtins/source_builtin.h \ |
32 |
src/builtins/source_builtin.cpp \ |
33 |
+ src/builtins/inherit_builtin.h \ |
34 |
+ src/builtins/inherit_builtin.cpp \ |
35 |
$(GENERATED_PARSER_C) \ |
36 |
$(GENERATED_PARSER_H) \ |
37 |
src/core/interpreter_exception.h \ |
38 |
@@ -188,6 +190,7 @@ EXTRA_DIST = bashast/bashast.g \ |
39 |
scripts/source_false.sh \ |
40 |
scripts/source_true.sh \ |
41 |
utils/meta_gen.sh \ |
42 |
+ scripts/foo.eclass \ |
43 |
$(BASH_TESTS) \ |
44 |
$(BASH_RESULT) \ |
45 |
$(EBUILD_TESTS) \ |
46 |
|
47 |
diff --git a/scripts/foo.eclass b/scripts/foo.eclass |
48 |
new file mode 100644 |
49 |
index 0000000..1e46230 |
50 |
--- /dev/null |
51 |
+++ b/scripts/foo.eclass |
52 |
@@ -0,0 +1,5 @@ |
53 |
+IUSE="abc def" |
54 |
+REQUIRED_USE="abc" |
55 |
+DEPEND="dev-util/pkgconfig" |
56 |
+RDEPEND="foo/bar" |
57 |
+PDEPEND="foo/bar" |
58 |
|
59 |
diff --git a/scripts/sunpinyin-2.0.3-r1.ebuild b/scripts/sunpinyin-2.0.3-r1.ebuild |
60 |
index 686121c..319e5ee 100644 |
61 |
--- a/scripts/sunpinyin-2.0.3-r1.ebuild |
62 |
+++ b/scripts/sunpinyin-2.0.3-r1.ebuild |
63 |
@@ -1,5 +1,7 @@ |
64 |
EAPI="1" |
65 |
|
66 |
+inherit foo |
67 |
+ |
68 |
DESCRIPTION="SunPinyin is a SLM (Statistical Language Model) based IME" |
69 |
HOMEPAGE="http://sunpinyin.googlecode.com" |
70 |
SRC_URI="${HOMEPAGE}/files/${P}.tar.gz |
71 |
|
72 |
diff --git a/scripts/sunpinyin-2.0.3-r1.ebuild.result b/scripts/sunpinyin-2.0.3-r1.ebuild.result |
73 |
index 41f016e..7c8c13b 100644 |
74 |
--- a/scripts/sunpinyin-2.0.3-r1.ebuild.result |
75 |
+++ b/scripts/sunpinyin-2.0.3-r1.ebuild.result |
76 |
@@ -1,5 +1,5 @@ |
77 |
dev-db/sqlite:3 dev-util/pkgconfig |
78 |
-dev-db/sqlite:3 |
79 |
+dev-db/sqlite:3 foo/bar |
80 |
0 |
81 |
http://sunpinyin.googlecode.com/files/.tar.gz http://open-gram.googlecode.com/files/dict.utf8.tar.bz2 http://open-gram.googlecode.com/files/lm_sc.t3g.arpa.tar.bz2 |
82 |
|
83 |
@@ -7,10 +7,10 @@ http://sunpinyin.googlecode.com |
84 |
LGPL-2.1 CDDL |
85 |
SunPinyin is a SLM (Statistical Language Model) based IME |
86 |
~amd64 ~x86 |
87 |
- |
88 |
- |
89 |
- |
90 |
- |
91 |
+foo |
92 |
+abc def |
93 |
+abc |
94 |
+foo/bar |
95 |
|
96 |
1 |
97 |
|
98 |
|
99 |
diff --git a/src/builtins/inherit_builtin.cpp b/src/builtins/inherit_builtin.cpp |
100 |
new file mode 100644 |
101 |
index 0000000..ac11cfc |
102 |
--- /dev/null |
103 |
+++ b/src/builtins/inherit_builtin.cpp |
104 |
@@ -0,0 +1,130 @@ |
105 |
+/* |
106 |
+ Please use git log for copyright holder and year information |
107 |
+ |
108 |
+ This file is part of libbash. |
109 |
+ |
110 |
+ libbash is free software: you can redistribute it and/or modify |
111 |
+ it under the terms of the GNU General Public License as published by |
112 |
+ the Free Software Foundation, either version 2 of the License, or |
113 |
+ (at your option) any later version. |
114 |
+ |
115 |
+ libbash is distributed in the hope that it will be useful, |
116 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
117 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
118 |
+ GNU General Public License for more details. |
119 |
+ |
120 |
+ You should have received a copy of the GNU General Public License |
121 |
+ along with libbash. If not, see <http://www.gnu.org/licenses/>. |
122 |
+*/ |
123 |
+/// |
124 |
+/// \file inherit_builtin.cpp |
125 |
+/// \author Mu Qiao |
126 |
+/// \brief class that implements the inherit builtin |
127 |
+/// |
128 |
+ |
129 |
+#include "builtins/inherit_builtin.h" |
130 |
+ |
131 |
+#include <cstdlib> |
132 |
+ |
133 |
+#include <string> |
134 |
+ |
135 |
+#include "core/interpreter.h" |
136 |
+ |
137 |
+inline void inherit_builtin::append_global(const std::string& name) |
138 |
+{ |
139 |
+ if(!_walker.is_unset_or_null(name, 0)) |
140 |
+ _walker.set_value("E_" + name, _walker.resolve<std::string>("E_"+name) + _walker.resolve<std::string>(name)); |
141 |
+} |
142 |
+ |
143 |
+inline void inherit_builtin::restore_global(const std::string& name, const std::string& value) |
144 |
+{ |
145 |
+ if(value != "") |
146 |
+ _walker.set_value(name, value); |
147 |
+ else |
148 |
+ _walker.unset(name); |
149 |
+} |
150 |
+ |
151 |
+inline void inherit_builtin::backup_global(const std::string& name, std::string& value) |
152 |
+{ |
153 |
+ value = _walker.resolve<std::string>(name); |
154 |
+ _walker.unset(name); |
155 |
+} |
156 |
+ |
157 |
+inline bool inherit_builtin::hasq(const std::string& value, const std::string& name) |
158 |
+{ |
159 |
+ const std::string& target = _walker.resolve<std::string>(name); |
160 |
+ return target.find(value) != std::string::npos; |
161 |
+} |
162 |
+ |
163 |
+// We do not support any QA warning |
164 |
+int inherit_builtin::exec(const std::vector<std::string>& bash_args) |
165 |
+{ |
166 |
+ _walker.pre_incr("ECLASS_DEPTH", 0); |
167 |
+ |
168 |
+ // find eclass directory |
169 |
+ std::string eclassdir; |
170 |
+ if(getenv("ECLASSDIR")) |
171 |
+ eclassdir = getenv("ECLASSDIR") + std::string("/"); |
172 |
+ else |
173 |
+ eclassdir = "/usr/portage/eclass/"; |
174 |
+ |
175 |
+ std::string location; |
176 |
+ std::string export_funcs_var; |
177 |
+ // These variables must be restored before returning |
178 |
+ std::string PECLASS(_walker.resolve<std::string>("ECLASS")); |
179 |
+ std::string prev_export_funcs_var(_walker.resolve<std::string>("__export_funcs_var")); |
180 |
+ |
181 |
+ std::string B_IUSE; |
182 |
+ std::string B_REQUIRED_USE; |
183 |
+ std::string B_DEPEND; |
184 |
+ std::string B_RDEPEND; |
185 |
+ std::string B_PDEPEND; |
186 |
+ |
187 |
+ for(auto iter = bash_args.begin(); iter != bash_args.end(); ++iter) |
188 |
+ { |
189 |
+ location = eclassdir + *iter + ".eclass"; |
190 |
+ _walker.set_value("ECLASS", *iter); |
191 |
+ export_funcs_var = "__export_functions_" + _walker.resolve<std::string>("ECLASS_DEPTH"); |
192 |
+ _walker.unset(export_funcs_var); |
193 |
+ |
194 |
+ // Portage implementation performs actions for overlays here but we don't do it for now |
195 |
+ |
196 |
+ backup_global("IUSE", B_IUSE); |
197 |
+ backup_global("REQUIRED_USE", B_REQUIRED_USE); |
198 |
+ backup_global("DEPEND", B_DEPEND); |
199 |
+ backup_global("RDEPEND", B_RDEPEND); |
200 |
+ backup_global("PDEPEND", B_PDEPEND); |
201 |
+ |
202 |
+ _walker.execute_builtin("source", {location}); |
203 |
+ |
204 |
+ append_global("IUSE"); |
205 |
+ append_global("REQUIRED_USE"); |
206 |
+ append_global("DEPEND"); |
207 |
+ append_global("RDEPEND"); |
208 |
+ append_global("PDEPEND"); |
209 |
+ |
210 |
+ restore_global("IUSE", B_IUSE); |
211 |
+ restore_global("REQUIRED_USE", B_REQUIRED_USE); |
212 |
+ restore_global("DEPEND", B_DEPEND); |
213 |
+ restore_global("RDEPEND", B_RDEPEND); |
214 |
+ restore_global("PDEPEND", B_PDEPEND); |
215 |
+ |
216 |
+ // Portage implementation exports functions here but we don't do it for now |
217 |
+ |
218 |
+ if(!hasq(*iter, "INHERITED")) |
219 |
+ _walker.set_value("INHERITED", _walker.resolve<std::string>("INHERITED") + " " + *iter); |
220 |
+ } |
221 |
+ |
222 |
+ _walker.pre_decr("ECLASS_DEPTH", 0); |
223 |
+ if(_walker.resolve<int>("ECLASS_DEPTH") > 0) |
224 |
+ { |
225 |
+ _walker.set_value("ECLASS", PECLASS); |
226 |
+ } |
227 |
+ else |
228 |
+ { |
229 |
+ _walker.unset("ECLASS"); |
230 |
+ _walker.unset("__export_funcs_var"); |
231 |
+ } |
232 |
+ |
233 |
+ return 0; |
234 |
+} |
235 |
|
236 |
diff --git a/src/builtins/inherit_builtin.h b/src/builtins/inherit_builtin.h |
237 |
new file mode 100644 |
238 |
index 0000000..6a2dc49 |
239 |
--- /dev/null |
240 |
+++ b/src/builtins/inherit_builtin.h |
241 |
@@ -0,0 +1,55 @@ |
242 |
+/* |
243 |
+ Please use git log for copyright holder and year information |
244 |
+ |
245 |
+ This file is part of libbash. |
246 |
+ |
247 |
+ libbash is free software: you can redistribute it and/or modify |
248 |
+ it under the terms of the GNU General Public License as published by |
249 |
+ the Free Software Foundation, either version 2 of the License, or |
250 |
+ (at your option) any later version. |
251 |
+ |
252 |
+ libbash is distributed in the hope that it will be useful, |
253 |
+ but WITHOUT ANY WARRANTY; without even the implied warranty of |
254 |
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
255 |
+ GNU General Public License for more details. |
256 |
+ |
257 |
+ You should have received a copy of the GNU General Public License |
258 |
+ along with libbash. If not, see <http://www.gnu.org/licenses/>. |
259 |
+*/ |
260 |
+/// |
261 |
+/// \file inherit_builtin.h |
262 |
+/// \author Mu Qiao |
263 |
+/// \brief class that implements the inherit function from Portage |
264 |
+/// |
265 |
+ |
266 |
+#ifndef LIBBASH_BUILTINS_INHERIT_BUILTIN_H_ |
267 |
+#define LIBBASH_BUILTINS_INHERIT_BUILTIN_H_ |
268 |
+ |
269 |
+#include "cppbash_builtin.h" |
270 |
+ |
271 |
+/// |
272 |
+/// \class inherit |
273 |
+/// \brief the inherit builtin for bash |
274 |
+/// |
275 |
+class inherit_builtin: public virtual cppbash_builtin |
276 |
+{ |
277 |
+ public: |
278 |
+ BUILTIN_CONSTRUCTOR(inherit) |
279 |
+ |
280 |
+ /// |
281 |
+ /// \brief runs the inherit builtin on the supplied arguments |
282 |
+ /// \param bash_args the arguments to the inherit builtin |
283 |
+ /// \return exit status of inherit |
284 |
+ /// |
285 |
+ virtual int exec(const std::vector<std::string>& bash_args); |
286 |
+ private: |
287 |
+ void append_global(const std::string& name); |
288 |
+ |
289 |
+ void backup_global(const std::string& name, std::string& value); |
290 |
+ |
291 |
+ void restore_global(const std::string& name, const std::string& value); |
292 |
+ |
293 |
+ bool hasq(const std::string& value, const std::string& name); |
294 |
+}; |
295 |
+ |
296 |
+#endif |
297 |
|
298 |
diff --git a/src/cppbash_builtin.cpp b/src/cppbash_builtin.cpp |
299 |
index 0df9cbf..dc6ec3e 100644 |
300 |
--- a/src/cppbash_builtin.cpp |
301 |
+++ b/src/cppbash_builtin.cpp |
302 |
@@ -24,6 +24,7 @@ |
303 |
|
304 |
#include "cppbash_builtin.h" |
305 |
#include "builtins/echo_builtin.h" |
306 |
+#include "builtins/inherit_builtin.h" |
307 |
#include "builtins/boolean_builtins.h" |
308 |
#include "builtins/source_builtin.h" |
309 |
|
310 |
@@ -35,6 +36,7 @@ cppbash_builtin::builtins_type& cppbash_builtin::builtins() { |
311 |
static boost::scoped_ptr<builtins_type> p(new builtins_type { |
312 |
{"echo", boost::factory<echo_builtin*>()}, |
313 |
{"source", boost::factory<source_builtin*>()}, |
314 |
+ {"inherit", boost::factory<inherit_builtin*>()}, |
315 |
{"true", boost::factory<true_builtin*>()}, |
316 |
{"false", boost::factory<false_builtin*>()} |
317 |
}); |
318 |
|
319 |
diff --git a/test/ebuild_compiler.sh b/test/ebuild_compiler.sh |
320 |
index 5930b62..7828476 100755 |
321 |
--- a/test/ebuild_compiler.sh |
322 |
+++ b/test/ebuild_compiler.sh |
323 |
@@ -4,7 +4,7 @@ declare -i error=0 |
324 |
|
325 |
for ebuild in $@ |
326 |
do |
327 |
- ./metadata_generator $ebuild | diff -u $ebuild.result - |
328 |
+ ECLASSDIR=$srcdir/scripts ./metadata_generator $ebuild | diff -u $ebuild.result - |
329 |
error+=$? |
330 |
done |
331 |
|
332 |
|
333 |
diff --git a/utils/metadata_generator.cpp b/utils/metadata_generator.cpp |
334 |
index 859839c..52b4590 100644 |
335 |
--- a/utils/metadata_generator.cpp |
336 |
+++ b/utils/metadata_generator.cpp |
337 |
@@ -73,20 +73,40 @@ int main(int argc, char** argv) |
338 |
for(auto iter_name = metadata_names.begin(); iter_name != metadata_names.end(); ++iter_name) |
339 |
{ |
340 |
auto iter_value = variables.find(*iter_name); |
341 |
+ std::string value; |
342 |
+ |
343 |
if(iter_value != variables.end()) |
344 |
+ value = iter_value->second[0]; |
345 |
+ |
346 |
+ // Check if global is defined |
347 |
+ auto iter_global = variables.find("E_" + *iter_name); |
348 |
+ if(iter_global != variables.end()) |
349 |
{ |
350 |
- std::vector<std::string> formatted; |
351 |
- boost::trim_if(iter_value->second[0], boost::is_any_of(" \t\n")); |
352 |
- boost::split(formatted, |
353 |
- iter_value->second[0], |
354 |
+ boost::trim_if(iter_global->second[0], boost::is_any_of(" \t\n")); |
355 |
+ std::vector<std::string> splitted_global; |
356 |
+ boost::split(splitted_global, |
357 |
+ iter_global->second[0], |
358 |
boost::is_any_of(" \t\n"), |
359 |
boost::token_compress_on); |
360 |
- std::cout << format(string % ' ', formatted) << std::endl; |
361 |
- } |
362 |
- else |
363 |
- { |
364 |
- std::cout << std::endl; |
365 |
+ |
366 |
+ // Append the global value to 'value' if it doesn't cause duplication |
367 |
+ for(auto iter_splitted_global = splitted_global.begin(); |
368 |
+ iter_splitted_global != splitted_global.end(); |
369 |
+ ++iter_splitted_global) |
370 |
+ { |
371 |
+ if(value.find(*iter_splitted_global) == std::string::npos) |
372 |
+ value += " " + *iter_splitted_global; |
373 |
+ } |
374 |
} |
375 |
+ |
376 |
+ boost::trim_if(value, boost::is_any_of(" \t\n")); |
377 |
+ |
378 |
+ std::vector<std::string> splitted_value; |
379 |
+ boost::split(splitted_value, |
380 |
+ value, |
381 |
+ boost::is_any_of(" \t\n"), |
382 |
+ boost::token_compress_on); |
383 |
+ std::cout << format(string % ' ', splitted_value) << std::endl; |
384 |
} |
385 |
|
386 |
// Print defined phases |
387 |
@@ -97,8 +117,6 @@ int main(int argc, char** argv) |
388 |
if(iter_phase != phases.end()) |
389 |
sorted_phases.insert(iter_phase->second); |
390 |
} |
391 |
- |
392 |
- using namespace boost::spirit::karma; |
393 |
std::cout << format(string % ' ', sorted_phases) << std::endl; |
394 |
|
395 |
// Print empty lines |