Gentoo Archives: gentoo-commits

From: "Petteri Räty" <betelgeuse@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/libbash:master commit in: scripts/, src/core/, bashast/, src/core/tests/
Date: Thu, 28 Apr 2011 06:20:03
Message-Id: be5289bca55b033742300ed0f5f69121b2bb76c4.betelgeuse@gentoo
1 commit: be5289bca55b033742300ed0f5f69121b2bb76c4
2 Author: Mu Qiao <qiaomuf <AT> gentoo <DOT> org>
3 AuthorDate: Thu Apr 21 11:58:16 2011 +0000
4 Commit: Petteri Räty <betelgeuse <AT> gentoo <DOT> org>
5 CommitDate: Thu Apr 28 02:57:53 2011 +0000
6 URL: http://git.overlays.gentoo.org/gitweb/?p=proj/libbash.git;a=commit;h=be5289bc
7
8 Core: support unsetting variables, fix is_null
9
10 Empty variable values are all treated as null value. This simplifies
11 the previous code and fixes some logic errors.
12
13 ---
14 bashast/libbashWalker.g | 5 +--
15 scripts/var_def.bash.result | 4 +-
16 src/core/interpreter.cpp | 21 ++++++++++++++++++
17 src/core/interpreter.h | 19 +++++++++++-----
18 src/core/symbols.hpp | 40 +++++++++++++++++++++++++---------
19 src/core/tests/interpreter_test.cpp | 29 ++++++++++++++++++++++++-
20 src/core/tests/symbols_test.cpp | 12 ++++++++-
21 7 files changed, 105 insertions(+), 25 deletions(-)
22
23 diff --git a/bashast/libbashWalker.g b/bashast/libbashWalker.g
24 index e278d1b..203cd28 100644
25 --- a/bashast/libbashWalker.g
26 +++ b/bashast/libbashWalker.g
27 @@ -119,10 +119,9 @@ var_def
28 @declarations {
29 std::map<int, std::string> values;
30 unsigned index = 0;
31 - bool is_null = true;
32 }
33 - :^(EQUALS name (string_expr { is_null = false; })?) {
34 - walker->set_value($name.libbash_value, $string_expr.libbash_value, $name.index, is_null);
35 + :^(EQUALS name string_expr?) {
36 + walker->set_value($name.libbash_value, $string_expr.libbash_value, $name.index);
37 }
38 |^(EQUALS libbash_name=name_base ^(ARRAY (
39 (expr=string_expr
40
41 diff --git a/scripts/var_def.bash.result b/scripts/var_def.bash.result
42 index e840ebe..1b9e287 100644
43 --- a/scripts/var_def.bash.result
44 +++ b/scripts/var_def.bash.result
45 @@ -5,8 +5,8 @@ $- has not been implemented yet
46 $! has not been implemented yet
47 ARRAY01=1 2 3 4 5
48 ARRAY02=1 2 4 5
49 -ARRAY03=2 3
50 -ARRAY04=2 3
51 +ARRAY03= 2 3
52 +ARRAY04= 2 3
53 ARRAY05=1 2 3 4 5
54 ARRAY06=1 2 3 4 5
55 ARRAY07=1 2 3 4 5
56
57 diff --git a/src/core/interpreter.cpp b/src/core/interpreter.cpp
58 index 9548e8a..f0bf61e 100644
59 --- a/src/core/interpreter.cpp
60 +++ b/src/core/interpreter.cpp
61 @@ -178,3 +178,24 @@ void interpreter::get_all_function_names(std::vector<std::string>& function_name
62 {
63 boost::copy(functions | boost::adaptors::map_keys, back_inserter(function_names));
64 }
65 +
66 +void interpreter::unset(const std::string& name)
67 +{
68 + auto iter = members.find(name);
69 + if(iter == members.end())
70 + return;
71 + else if(iter->second->is_readonly())
72 + throw interpreter_exception("Can't unset readonly variable " + name);
73 + else
74 + members.erase(name);
75 +}
76 +
77 +void interpreter::unset(const std::string& name,
78 + const unsigned index)
79 +{
80 + auto iter = members.find(name);
81 + if(iter == members.end())
82 + return;
83 + else
84 + iter->second->unset_value(index);
85 +}
86
87 diff --git a/src/core/interpreter.h b/src/core/interpreter.h
88 index e471b94..dc446fc 100644
89 --- a/src/core/interpreter.h
90 +++ b/src/core/interpreter.h
91 @@ -468,14 +468,13 @@ public:
92 template <typename T>
93 const T& set_value(const std::string& name,
94 const T& new_value,
95 - const unsigned index=0,
96 - bool is_null=false)
97 + const unsigned index=0)
98 {
99 auto i = members.find(name);
100 if(i == members.end())
101 - define(name, new_value, false, is_null, index);
102 + define(name, new_value, false, index);
103 else
104 - i->second->set_value(new_value, index, is_null);
105 + i->second->set_value(new_value, index);
106 return new_value;
107 }
108
109 @@ -494,6 +493,15 @@ public:
110 return resolve<T>("?");
111 }
112
113 + /// \brief unset a variable
114 + /// \param the name of the variable
115 + void unset(const std::string& name);
116 +
117 + /// \brief unset a array member
118 + /// \param the name of the array
119 + /// \param the index of the member
120 + void unset(const std::string& name, const unsigned index);
121 +
122 /// \brief define a new global variable
123 /// \param the name of the variable
124 /// \param the value of the variable
125 @@ -503,11 +511,10 @@ public:
126 void define(const std::string& name,
127 const T& value,
128 bool readonly=false,
129 - bool is_null=false,
130 const unsigned index=0)
131 {
132 std::shared_ptr<variable> target(
133 - new variable(name, value, readonly, is_null, index));
134 + new variable(name, value, readonly, index));
135 members[name] = target;
136 }
137
138
139 diff --git a/src/core/symbols.hpp b/src/core/symbols.hpp
140 index b11d338..89fd657 100644
141 --- a/src/core/symbols.hpp
142 +++ b/src/core/symbols.hpp
143 @@ -137,12 +137,10 @@ public:
144 variable(const std::string& name,
145 const T& v,
146 bool ro=false,
147 - bool is_null=false,
148 const unsigned index=0)
149 : name(name), readonly(ro)
150 {
151 - if(!is_null)
152 - value[index] = v;
153 + value[index] = v;
154 }
155
156 /// \brief retrieve actual value of the variable, if index is out of bound,
157 @@ -182,16 +180,22 @@ public:
158 /// \param whether to set the variable to null value, default is false
159 template <typename T>
160 void set_value(const T& new_value,
161 - const unsigned index=0,
162 - bool is_null=false)
163 + const unsigned index=0)
164 {
165 if(readonly)
166 throw interpreter_exception(get_name() + " is readonly variable");
167
168 - if(is_null)
169 - value.erase(index);
170 - else
171 - value[index] = new_value;
172 + value[index] = new_value;
173 + }
174 +
175 + /// \brief unset the variable, only used for array variable
176 + /// \param the index to be unset
177 + void unset_value(const unsigned index)
178 + {
179 + if(readonly)
180 + throw interpreter_exception(get_name() + " is readonly variable");
181 +
182 + value.erase(index);
183 }
184
185 /// \brief get the length of a variable
186 @@ -211,10 +215,24 @@ public:
187
188 /// \brief check whether the value of the variable is null
189 /// \return whether the value of the variable is null
190 - bool is_null(const unsigned index=0) const
191 + bool is_unset(const unsigned index=0) const
192 {
193 return value.find(index) == value.end();
194 }
195 +
196 + /// \brief check whether the value of the variable is unset
197 + /// \return whether the value of the variable is unset
198 + bool is_null(const unsigned index=0) const
199 + {
200 + return get_value<std::string>(index) == "";
201 + }
202 +
203 + /// \brief check whether the value of the variable is readonly
204 + /// \return whether the value of the variable is readonly
205 + bool is_readonly() const
206 + {
207 + return readonly;
208 + }
209 };
210
211 // specialization for arrays
212 @@ -222,7 +240,7 @@ template <>
213 inline variable::variable<>(const std::string& name,
214 const std::map<int, std::string>& v,
215 bool ro,
216 - bool, unsigned)
217 + unsigned)
218 : name(name), value(v.begin(), v.end()), readonly(ro)
219 {
220 }
221
222 diff --git a/src/core/tests/interpreter_test.cpp b/src/core/tests/interpreter_test.cpp
223 index 2e92a22..54f25b0 100644
224 --- a/src/core/tests/interpreter_test.cpp
225 +++ b/src/core/tests/interpreter_test.cpp
226 @@ -54,7 +54,7 @@ TEST(interpreter, define_resolve_array)
227 EXPECT_STREQ("3", walker.resolve<string>("array", 2).c_str());
228 EXPECT_STREQ("", walker.resolve<string>("undefined",100).c_str());
229
230 - walker.define("partial", 10, false, false, 8);
231 + walker.define("partial", 10, false, 8);
232 EXPECT_EQ(1, walker.get_array_length("partial"));
233 EXPECT_EQ(10, walker.resolve<int>("partial", 8));
234 }
235 @@ -142,6 +142,33 @@ TEST(interpreter, get_array_values)
236 EXPECT_EQ(3, array_values[2]);
237 }
238
239 +TEST(interpreter, unset_values)
240 +{
241 + interpreter walker;
242 + std::map<int, std::string> values = {{0, "1"}, {1, "2"}, {2, "3"}};
243 + walker.define("array", values);
244 + walker.define("ro_array", values, true);
245 + walker.define("var", "123");
246 + walker.define("ro_var", "123", true);
247 +
248 + EXPECT_STREQ("2", walker.resolve<string>("array", 1).c_str());
249 + walker.unset("array", 1);
250 + EXPECT_STREQ("", walker.resolve<string>("array", 1).c_str());
251 + walker.unset("array");
252 + EXPECT_STREQ("", walker.resolve<string>("array", 0).c_str());
253 + EXPECT_STREQ("", walker.resolve<string>("array", 1).c_str());
254 + EXPECT_STREQ("", walker.resolve<string>("array", 2).c_str());
255 +
256 + EXPECT_THROW(walker.unset("ro_array", 1), interpreter_exception);
257 + EXPECT_THROW(walker.unset("ro_array"), interpreter_exception);
258 +
259 + EXPECT_STREQ("123", walker.resolve<string>("var").c_str());
260 + walker.unset("var");
261 + EXPECT_STREQ("", walker.resolve<string>("var").c_str());
262 +
263 + EXPECT_THROW(walker.unset("ro_var"), interpreter_exception);
264 +}
265 +
266 TEST(interperter, substring_expansion_exception)
267 {
268 interpreter walker;
269
270 diff --git a/src/core/tests/symbols_test.cpp b/src/core/tests/symbols_test.cpp
271 index d614947..f151318 100644
272 --- a/src/core/tests/symbols_test.cpp
273 +++ b/src/core/tests/symbols_test.cpp
274 @@ -122,9 +122,17 @@ TEST(symbol_test, is_null)
275 {
276 variable var("foo", 10);
277 EXPECT_FALSE(var.is_null());
278 - var.set_value("bar", 0, true);
279 + var.set_value("");
280 EXPECT_TRUE(var.is_null());
281 - EXPECT_TRUE(variable("foo", "", false, true).is_null());
282 + EXPECT_TRUE(variable("foo", "").is_null());
283 +}
284 +
285 +TEST(symbol_test, is_unset)
286 +{
287 + map<int, string> values = {{0, "1"}, {1, "2"}, {2, "3"}};
288 + variable array("foo", values);
289 + array.unset_value(1);
290 + EXPECT_TRUE(array.is_unset(1));
291 }
292
293 TEST(symbol_test, get_length)