diff options
author | Tianjie Xu | 2017-03-06 16:44:59 -0600 |
---|---|---|
committer | Tianjie Xu | 2017-03-22 16:20:57 -0500 |
commit | c444732540d5245b6219293e96d29f325daa7839 (patch) | |
tree | d66338f891ad8b440a36e781988fae89cca1da7f /edify | |
parent | d882b8892a1592101b901dd474de41e56c31b17b (diff) | |
download | platform-bootable-recovery-c444732540d5245b6219293e96d29f325daa7839.tar.gz platform-bootable-recovery-c444732540d5245b6219293e96d29f325daa7839.tar.xz platform-bootable-recovery-c444732540d5245b6219293e96d29f325daa7839.zip |
Remove malloc in edify functions
And switch them to std::vector & std::unique_ptr
Bug: 32117870
Test: recovery tests passed on sailfish
Change-Id: I5a45951c4bdf895be311d6d760e52e7a1b0798c3
Diffstat (limited to 'edify')
-rw-r--r-- | edify/edify_parser.cpp | 9 | ||||
-rw-r--r-- | edify/expr.cpp | 119 | ||||
-rw-r--r-- | edify/expr.h | 83 | ||||
-rw-r--r-- | edify/parser.yy | 71 |
4 files changed, 153 insertions, 129 deletions
diff --git a/edify/edify_parser.cpp b/edify/edify_parser.cpp index 908fcf13..f1b56284 100644 --- a/edify/edify_parser.cpp +++ b/edify/edify_parser.cpp | |||
@@ -27,18 +27,19 @@ | |||
27 | #include <errno.h> | 27 | #include <errno.h> |
28 | #include <stdio.h> | 28 | #include <stdio.h> |
29 | 29 | ||
30 | #include <memory> | ||
30 | #include <string> | 31 | #include <string> |
31 | 32 | ||
32 | #include <android-base/file.h> | 33 | #include <android-base/file.h> |
33 | 34 | ||
34 | #include "expr.h" | 35 | #include "expr.h" |
35 | 36 | ||
36 | static void ExprDump(int depth, const Expr* n, const std::string& script) { | 37 | static void ExprDump(int depth, const std::unique_ptr<Expr>& n, const std::string& script) { |
37 | printf("%*s", depth*2, ""); | 38 | printf("%*s", depth*2, ""); |
38 | printf("%s %p (%d-%d) \"%s\"\n", | 39 | printf("%s %p (%d-%d) \"%s\"\n", |
39 | n->name == NULL ? "(NULL)" : n->name, n->fn, n->start, n->end, | 40 | n->name.c_str(), n->fn, n->start, n->end, |
40 | script.substr(n->start, n->end - n->start).c_str()); | 41 | script.substr(n->start, n->end - n->start).c_str()); |
41 | for (int i = 0; i < n->argc; ++i) { | 42 | for (size_t i = 0; i < n->argv.size(); ++i) { |
42 | ExprDump(depth+1, n->argv[i], script); | 43 | ExprDump(depth+1, n->argv[i], script); |
43 | } | 44 | } |
44 | } | 45 | } |
@@ -57,7 +58,7 @@ int main(int argc, char** argv) { | |||
57 | return 1; | 58 | return 1; |
58 | } | 59 | } |
59 | 60 | ||
60 | Expr* root; | 61 | std::unique_ptr<Expr> root; |
61 | int error_count = 0; | 62 | int error_count = 0; |
62 | int error = parse_string(buffer.data(), &root, &error_count); | 63 | int error = parse_string(buffer.data(), &root, &error_count); |
63 | printf("parse returned %d; %d errors encountered\n", error, error_count); | 64 | printf("parse returned %d; %d errors encountered\n", error, error_count); |
diff --git a/edify/expr.cpp b/edify/expr.cpp index 329cf3ac..2b7fd7a6 100644 --- a/edify/expr.cpp +++ b/edify/expr.cpp | |||
@@ -40,12 +40,12 @@ static bool BooleanString(const std::string& s) { | |||
40 | return !s.empty(); | 40 | return !s.empty(); |
41 | } | 41 | } |
42 | 42 | ||
43 | bool Evaluate(State* state, Expr* expr, std::string* result) { | 43 | bool Evaluate(State* state, const std::unique_ptr<Expr>& expr, std::string* result) { |
44 | if (result == nullptr) { | 44 | if (result == nullptr) { |
45 | return false; | 45 | return false; |
46 | } | 46 | } |
47 | 47 | ||
48 | std::unique_ptr<Value> v(expr->fn(expr->name, state, expr->argc, expr->argv)); | 48 | std::unique_ptr<Value> v(expr->fn(expr->name.c_str(), state, expr->argv)); |
49 | if (!v) { | 49 | if (!v) { |
50 | return false; | 50 | return false; |
51 | } | 51 | } |
@@ -58,8 +58,8 @@ bool Evaluate(State* state, Expr* expr, std::string* result) { | |||
58 | return true; | 58 | return true; |
59 | } | 59 | } |
60 | 60 | ||
61 | Value* EvaluateValue(State* state, Expr* expr) { | 61 | Value* EvaluateValue(State* state, const std::unique_ptr<Expr>& expr) { |
62 | return expr->fn(expr->name, state, expr->argc, expr->argv); | 62 | return expr->fn(expr->name.c_str(), state, expr->argv); |
63 | } | 63 | } |
64 | 64 | ||
65 | Value* StringValue(const char* str) { | 65 | Value* StringValue(const char* str) { |
@@ -73,12 +73,12 @@ Value* StringValue(const std::string& str) { | |||
73 | return StringValue(str.c_str()); | 73 | return StringValue(str.c_str()); |
74 | } | 74 | } |
75 | 75 | ||
76 | Value* ConcatFn(const char* name, State* state, int argc, Expr* argv[]) { | 76 | Value* ConcatFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { |
77 | if (argc == 0) { | 77 | if (argv.empty()) { |
78 | return StringValue(""); | 78 | return StringValue(""); |
79 | } | 79 | } |
80 | std::string result; | 80 | std::string result; |
81 | for (int i = 0; i < argc; ++i) { | 81 | for (size_t i = 0; i < argv.size(); ++i) { |
82 | std::string str; | 82 | std::string str; |
83 | if (!Evaluate(state, argv[i], &str)) { | 83 | if (!Evaluate(state, argv[i], &str)) { |
84 | return nullptr; | 84 | return nullptr; |
@@ -89,8 +89,8 @@ Value* ConcatFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
89 | return StringValue(result); | 89 | return StringValue(result); |
90 | } | 90 | } |
91 | 91 | ||
92 | Value* IfElseFn(const char* name, State* state, int argc, Expr* argv[]) { | 92 | Value* IfElseFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { |
93 | if (argc != 2 && argc != 3) { | 93 | if (argv.size() != 2 && argv.size() != 3) { |
94 | state->errmsg = "ifelse expects 2 or 3 arguments"; | 94 | state->errmsg = "ifelse expects 2 or 3 arguments"; |
95 | return nullptr; | 95 | return nullptr; |
96 | } | 96 | } |
@@ -102,16 +102,16 @@ Value* IfElseFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
102 | 102 | ||
103 | if (!cond.empty()) { | 103 | if (!cond.empty()) { |
104 | return EvaluateValue(state, argv[1]); | 104 | return EvaluateValue(state, argv[1]); |
105 | } else if (argc == 3) { | 105 | } else if (argv.size() == 3) { |
106 | return EvaluateValue(state, argv[2]); | 106 | return EvaluateValue(state, argv[2]); |
107 | } | 107 | } |
108 | 108 | ||
109 | return StringValue(""); | 109 | return StringValue(""); |
110 | } | 110 | } |
111 | 111 | ||
112 | Value* AbortFn(const char* name, State* state, int argc, Expr* argv[]) { | 112 | Value* AbortFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { |
113 | std::string msg; | 113 | std::string msg; |
114 | if (argc > 0 && Evaluate(state, argv[0], &msg)) { | 114 | if (!argv.empty() && Evaluate(state, argv[0], &msg)) { |
115 | state->errmsg = msg; | 115 | state->errmsg = msg; |
116 | } else { | 116 | } else { |
117 | state->errmsg = "called abort()"; | 117 | state->errmsg = "called abort()"; |
@@ -119,8 +119,8 @@ Value* AbortFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
119 | return nullptr; | 119 | return nullptr; |
120 | } | 120 | } |
121 | 121 | ||
122 | Value* AssertFn(const char* name, State* state, int argc, Expr* argv[]) { | 122 | Value* AssertFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { |
123 | for (int i = 0; i < argc; ++i) { | 123 | for (size_t i = 0; i < argv.size(); ++i) { |
124 | std::string result; | 124 | std::string result; |
125 | if (!Evaluate(state, argv[i], &result)) { | 125 | if (!Evaluate(state, argv[i], &result)) { |
126 | return nullptr; | 126 | return nullptr; |
@@ -134,7 +134,7 @@ Value* AssertFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
134 | return StringValue(""); | 134 | return StringValue(""); |
135 | } | 135 | } |
136 | 136 | ||
137 | Value* SleepFn(const char* name, State* state, int argc, Expr* argv[]) { | 137 | Value* SleepFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { |
138 | std::string val; | 138 | std::string val; |
139 | if (!Evaluate(state, argv[0], &val)) { | 139 | if (!Evaluate(state, argv[0], &val)) { |
140 | return nullptr; | 140 | return nullptr; |
@@ -149,8 +149,8 @@ Value* SleepFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
149 | return StringValue(val); | 149 | return StringValue(val); |
150 | } | 150 | } |
151 | 151 | ||
152 | Value* StdoutFn(const char* name, State* state, int argc, Expr* argv[]) { | 152 | Value* StdoutFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { |
153 | for (int i = 0; i < argc; ++i) { | 153 | for (size_t i = 0; i < argv.size(); ++i) { |
154 | std::string v; | 154 | std::string v; |
155 | if (!Evaluate(state, argv[i], &v)) { | 155 | if (!Evaluate(state, argv[i], &v)) { |
156 | return nullptr; | 156 | return nullptr; |
@@ -161,7 +161,7 @@ Value* StdoutFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
161 | } | 161 | } |
162 | 162 | ||
163 | Value* LogicalAndFn(const char* name, State* state, | 163 | Value* LogicalAndFn(const char* name, State* state, |
164 | int argc, Expr* argv[]) { | 164 | const std::vector<std::unique_ptr<Expr>>& argv) { |
165 | std::string left; | 165 | std::string left; |
166 | if (!Evaluate(state, argv[0], &left)) { | 166 | if (!Evaluate(state, argv[0], &left)) { |
167 | return nullptr; | 167 | return nullptr; |
@@ -174,7 +174,7 @@ Value* LogicalAndFn(const char* name, State* state, | |||
174 | } | 174 | } |
175 | 175 | ||
176 | Value* LogicalOrFn(const char* name, State* state, | 176 | Value* LogicalOrFn(const char* name, State* state, |
177 | int argc, Expr* argv[]) { | 177 | const std::vector<std::unique_ptr<Expr>>& argv) { |
178 | std::string left; | 178 | std::string left; |
179 | if (!Evaluate(state, argv[0], &left)) { | 179 | if (!Evaluate(state, argv[0], &left)) { |
180 | return nullptr; | 180 | return nullptr; |
@@ -187,7 +187,7 @@ Value* LogicalOrFn(const char* name, State* state, | |||
187 | } | 187 | } |
188 | 188 | ||
189 | Value* LogicalNotFn(const char* name, State* state, | 189 | Value* LogicalNotFn(const char* name, State* state, |
190 | int argc, Expr* argv[]) { | 190 | const std::vector<std::unique_ptr<Expr>>& argv) { |
191 | std::string val; | 191 | std::string val; |
192 | if (!Evaluate(state, argv[0], &val)) { | 192 | if (!Evaluate(state, argv[0], &val)) { |
193 | return nullptr; | 193 | return nullptr; |
@@ -197,7 +197,7 @@ Value* LogicalNotFn(const char* name, State* state, | |||
197 | } | 197 | } |
198 | 198 | ||
199 | Value* SubstringFn(const char* name, State* state, | 199 | Value* SubstringFn(const char* name, State* state, |
200 | int argc, Expr* argv[]) { | 200 | const std::vector<std::unique_ptr<Expr>>& argv) { |
201 | std::string needle; | 201 | std::string needle; |
202 | if (!Evaluate(state, argv[0], &needle)) { | 202 | if (!Evaluate(state, argv[0], &needle)) { |
203 | return nullptr; | 203 | return nullptr; |
@@ -212,7 +212,7 @@ Value* SubstringFn(const char* name, State* state, | |||
212 | return StringValue(result); | 212 | return StringValue(result); |
213 | } | 213 | } |
214 | 214 | ||
215 | Value* EqualityFn(const char* name, State* state, int argc, Expr* argv[]) { | 215 | Value* EqualityFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { |
216 | std::string left; | 216 | std::string left; |
217 | if (!Evaluate(state, argv[0], &left)) { | 217 | if (!Evaluate(state, argv[0], &left)) { |
218 | return nullptr; | 218 | return nullptr; |
@@ -226,7 +226,8 @@ Value* EqualityFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
226 | return StringValue(result); | 226 | return StringValue(result); |
227 | } | 227 | } |
228 | 228 | ||
229 | Value* InequalityFn(const char* name, State* state, int argc, Expr* argv[]) { | 229 | Value* InequalityFn(const char* name, State* state, |
230 | const std::vector<std::unique_ptr<Expr>>& argv) { | ||
230 | std::string left; | 231 | std::string left; |
231 | if (!Evaluate(state, argv[0], &left)) { | 232 | if (!Evaluate(state, argv[0], &left)) { |
232 | return nullptr; | 233 | return nullptr; |
@@ -240,7 +241,7 @@ Value* InequalityFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
240 | return StringValue(result); | 241 | return StringValue(result); |
241 | } | 242 | } |
242 | 243 | ||
243 | Value* SequenceFn(const char* name, State* state, int argc, Expr* argv[]) { | 244 | Value* SequenceFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { |
244 | std::unique_ptr<Value> left(EvaluateValue(state, argv[0])); | 245 | std::unique_ptr<Value> left(EvaluateValue(state, argv[0])); |
245 | if (!left) { | 246 | if (!left) { |
246 | return nullptr; | 247 | return nullptr; |
@@ -248,14 +249,15 @@ Value* SequenceFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
248 | return EvaluateValue(state, argv[1]); | 249 | return EvaluateValue(state, argv[1]); |
249 | } | 250 | } |
250 | 251 | ||
251 | Value* LessThanIntFn(const char* name, State* state, int argc, Expr* argv[]) { | 252 | Value* LessThanIntFn(const char* name, State* state, |
252 | if (argc != 2) { | 253 | const std::vector<std::unique_ptr<Expr>>& argv) { |
254 | if (argv.size() != 2) { | ||
253 | state->errmsg = "less_than_int expects 2 arguments"; | 255 | state->errmsg = "less_than_int expects 2 arguments"; |
254 | return nullptr; | 256 | return nullptr; |
255 | } | 257 | } |
256 | 258 | ||
257 | std::vector<std::string> args; | 259 | std::vector<std::string> args; |
258 | if (!ReadArgs(state, 2, argv, &args)) { | 260 | if (!ReadArgs(state, argv, &args)) { |
259 | return nullptr; | 261 | return nullptr; |
260 | } | 262 | } |
261 | 263 | ||
@@ -276,20 +278,34 @@ Value* LessThanIntFn(const char* name, State* state, int argc, Expr* argv[]) { | |||
276 | } | 278 | } |
277 | 279 | ||
278 | Value* GreaterThanIntFn(const char* name, State* state, | 280 | Value* GreaterThanIntFn(const char* name, State* state, |
279 | int argc, Expr* argv[]) { | 281 | const std::vector<std::unique_ptr<Expr>>& argv) { |
280 | if (argc != 2) { | 282 | if (argv.size() != 2) { |
281 | state->errmsg = "greater_than_int expects 2 arguments"; | 283 | state->errmsg = "greater_than_int expects 2 arguments"; |
282 | return nullptr; | 284 | return nullptr; |
283 | } | 285 | } |
284 | 286 | ||
285 | Expr* temp[2]; | 287 | std::vector<std::string> args; |
286 | temp[0] = argv[1]; | 288 | if (!ReadArgs(state, argv, &args)) { |
287 | temp[1] = argv[0]; | 289 | return nullptr; |
290 | } | ||
291 | |||
292 | // Parse up to at least long long or 64-bit integers. | ||
293 | int64_t l_int; | ||
294 | if (!android::base::ParseInt(args[0].c_str(), &l_int)) { | ||
295 | state->errmsg = "failed to parse int in " + args[0]; | ||
296 | return nullptr; | ||
297 | } | ||
298 | |||
299 | int64_t r_int; | ||
300 | if (!android::base::ParseInt(args[1].c_str(), &r_int)) { | ||
301 | state->errmsg = "failed to parse int in " + args[1]; | ||
302 | return nullptr; | ||
303 | } | ||
288 | 304 | ||
289 | return LessThanIntFn(name, state, 2, temp); | 305 | return StringValue(l_int > r_int ? "t" : ""); |
290 | } | 306 | } |
291 | 307 | ||
292 | Value* Literal(const char* name, State* state, int argc, Expr* argv[]) { | 308 | Value* Literal(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { |
293 | return StringValue(name); | 309 | return StringValue(name); |
294 | } | 310 | } |
295 | 311 | ||
@@ -329,14 +345,22 @@ void RegisterBuiltins() { | |||
329 | // convenience methods for functions | 345 | // convenience methods for functions |
330 | // ----------------------------------------------------------------- | 346 | // ----------------------------------------------------------------- |
331 | 347 | ||
332 | // Evaluate the expressions in argv, and put the results of strings in | 348 | // Evaluate the expressions in argv, and put the results of strings in args. If any expression |
333 | // args. If any expression evaluates to nullptr, free the rest and return | 349 | // evaluates to nullptr, return false. Return true on success. |
334 | // false. Return true on success. | 350 | bool ReadArgs(State* state, const std::vector<std::unique_ptr<Expr>>& argv, |
335 | bool ReadArgs(State* state, int argc, Expr* argv[], std::vector<std::string>* args) { | 351 | std::vector<std::string>* args) { |
352 | return ReadArgs(state, argv, args, 0, argv.size()); | ||
353 | } | ||
354 | |||
355 | bool ReadArgs(State* state, const std::vector<std::unique_ptr<Expr>>& argv, | ||
356 | std::vector<std::string>* args, size_t start, size_t len) { | ||
336 | if (args == nullptr) { | 357 | if (args == nullptr) { |
337 | return false; | 358 | return false; |
338 | } | 359 | } |
339 | for (int i = 0; i < argc; ++i) { | 360 | if (len == 0 || start + len > argv.size()) { |
361 | return false; | ||
362 | } | ||
363 | for (size_t i = start; i < start + len; ++i) { | ||
340 | std::string var; | 364 | std::string var; |
341 | if (!Evaluate(state, argv[i], &var)) { | 365 | if (!Evaluate(state, argv[i], &var)) { |
342 | args->clear(); | 366 | args->clear(); |
@@ -347,15 +371,22 @@ bool ReadArgs(State* state, int argc, Expr* argv[], std::vector<std::string>* ar | |||
347 | return true; | 371 | return true; |
348 | } | 372 | } |
349 | 373 | ||
350 | // Evaluate the expressions in argv, and put the results of Value* in | 374 | // Evaluate the expressions in argv, and put the results of Value* in args. If any expression |
351 | // args. If any expression evaluate to nullptr, free the rest and return | 375 | // evaluate to nullptr, return false. Return true on success. |
352 | // false. Return true on success. | 376 | bool ReadValueArgs(State* state, const std::vector<std::unique_ptr<Expr>>& argv, |
353 | bool ReadValueArgs(State* state, int argc, Expr* argv[], | ||
354 | std::vector<std::unique_ptr<Value>>* args) { | 377 | std::vector<std::unique_ptr<Value>>* args) { |
378 | return ReadValueArgs(state, argv, args, 0, argv.size()); | ||
379 | } | ||
380 | |||
381 | bool ReadValueArgs(State* state, const std::vector<std::unique_ptr<Expr>>& argv, | ||
382 | std::vector<std::unique_ptr<Value>>* args, size_t start, size_t len) { | ||
355 | if (args == nullptr) { | 383 | if (args == nullptr) { |
356 | return false; | 384 | return false; |
357 | } | 385 | } |
358 | for (int i = 0; i < argc; ++i) { | 386 | if (len == 0 || start + len > argv.size()) { |
387 | return false; | ||
388 | } | ||
389 | for (size_t i = start; i < start + len; ++i) { | ||
359 | std::unique_ptr<Value> v(EvaluateValue(state, argv[i])); | 390 | std::unique_ptr<Value> v(EvaluateValue(state, argv[i])); |
360 | if (!v) { | 391 | if (!v) { |
361 | args->clear(); | 392 | args->clear(); |
diff --git a/edify/expr.h b/edify/expr.h index 911adbc8..4838d20c 100644 --- a/edify/expr.h +++ b/edify/expr.h | |||
@@ -18,7 +18,10 @@ | |||
18 | #define _EXPRESSION_H | 18 | #define _EXPRESSION_H |
19 | 19 | ||
20 | #include <unistd.h> | 20 | #include <unistd.h> |
21 | |||
22 | #include <memory> | ||
21 | #include <string> | 23 | #include <string> |
24 | #include <vector> | ||
22 | 25 | ||
23 | #include "error_code.h" | 26 | #include "error_code.h" |
24 | 27 | ||
@@ -65,47 +68,49 @@ struct Value { | |||
65 | 68 | ||
66 | struct Expr; | 69 | struct Expr; |
67 | 70 | ||
68 | using Function = Value* (*)(const char* name, State* state, int argc, Expr* argv[]); | 71 | using Function = Value* (*)(const char* name, State* state, |
72 | const std::vector<std::unique_ptr<Expr>>& argv); | ||
69 | 73 | ||
70 | struct Expr { | 74 | struct Expr { |
71 | Function fn; | 75 | Function fn; |
72 | const char* name; | 76 | std::string name; |
73 | int argc; | 77 | std::vector<std::unique_ptr<Expr>> argv; |
74 | Expr** argv; | 78 | int start, end; |
75 | int start, end; | 79 | |
80 | Expr(Function fn, const std::string& name, int start, int end) : | ||
81 | fn(fn), | ||
82 | name(name), | ||
83 | start(start), | ||
84 | end(end) {} | ||
76 | }; | 85 | }; |
77 | 86 | ||
78 | // Take one of the Expr*s passed to the function as an argument, | 87 | // Evaluate the input expr, return the resulting Value. |
79 | // evaluate it, return the resulting Value. The caller takes | 88 | Value* EvaluateValue(State* state, const std::unique_ptr<Expr>& expr); |
80 | // ownership of the returned Value. | ||
81 | Value* EvaluateValue(State* state, Expr* expr); | ||
82 | 89 | ||
83 | // Take one of the Expr*s passed to the function as an argument, | 90 | // Evaluate the input expr, assert that it is a string, and update the result parameter. This |
84 | // evaluate it, assert that it is a string, and update the result | 91 | // function returns true if the evaluation succeeds. This is a convenience function for older |
85 | // parameter. This function returns true if the evaluation succeeds. | 92 | // functions that want to deal only with strings. |
86 | // This is a convenience function for older functions that want to | 93 | bool Evaluate(State* state, const std::unique_ptr<Expr>& expr, std::string* result); |
87 | // deal only with strings. | ||
88 | bool Evaluate(State* state, Expr* expr, std::string* result); | ||
89 | 94 | ||
90 | // Glue to make an Expr out of a literal. | 95 | // Glue to make an Expr out of a literal. |
91 | Value* Literal(const char* name, State* state, int argc, Expr* argv[]); | 96 | Value* Literal(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv); |
92 | 97 | ||
93 | // Functions corresponding to various syntactic sugar operators. | 98 | // Functions corresponding to various syntactic sugar operators. |
94 | // ("concat" is also available as a builtin function, to concatenate | 99 | // ("concat" is also available as a builtin function, to concatenate |
95 | // more than two strings.) | 100 | // more than two strings.) |
96 | Value* ConcatFn(const char* name, State* state, int argc, Expr* argv[]); | 101 | Value* ConcatFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv); |
97 | Value* LogicalAndFn(const char* name, State* state, int argc, Expr* argv[]); | 102 | Value* LogicalAndFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv); |
98 | Value* LogicalOrFn(const char* name, State* state, int argc, Expr* argv[]); | 103 | Value* LogicalOrFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv); |
99 | Value* LogicalNotFn(const char* name, State* state, int argc, Expr* argv[]); | 104 | Value* LogicalNotFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv); |
100 | Value* SubstringFn(const char* name, State* state, int argc, Expr* argv[]); | 105 | Value* SubstringFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv); |
101 | Value* EqualityFn(const char* name, State* state, int argc, Expr* argv[]); | 106 | Value* EqualityFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv); |
102 | Value* InequalityFn(const char* name, State* state, int argc, Expr* argv[]); | 107 | Value* InequalityFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv); |
103 | Value* SequenceFn(const char* name, State* state, int argc, Expr* argv[]); | 108 | Value* SequenceFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv); |
104 | 109 | ||
105 | // Global builtins, registered by RegisterBuiltins(). | 110 | // Global builtins, registered by RegisterBuiltins(). |
106 | Value* IfElseFn(const char* name, State* state, int argc, Expr* argv[]); | 111 | Value* IfElseFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv); |
107 | Value* AssertFn(const char* name, State* state, int argc, Expr* argv[]); | 112 | Value* AssertFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv); |
108 | Value* AbortFn(const char* name, State* state, int argc, Expr* argv[]); | 113 | Value* AbortFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv); |
109 | 114 | ||
110 | // Register a new function. The same Function may be registered under | 115 | // Register a new function. The same Function may be registered under |
111 | // multiple names, but a given name should only be used once. | 116 | // multiple names, but a given name should only be used once. |
@@ -120,15 +125,19 @@ Function FindFunction(const std::string& name); | |||
120 | 125 | ||
121 | // --- convenience functions for use in functions --- | 126 | // --- convenience functions for use in functions --- |
122 | 127 | ||
123 | // Evaluate the expressions in argv, and put the results of strings in | 128 | // Evaluate the expressions in argv, and put the results of strings in args. If any expression |
124 | // args. If any expression evaluates to nullptr, free the rest and return | 129 | // evaluates to nullptr, return false. Return true on success. |
125 | // false. Return true on success. | 130 | bool ReadArgs(State* state, const std::vector<std::unique_ptr<Expr>>& argv, |
126 | bool ReadArgs(State* state, int argc, Expr* argv[], std::vector<std::string>* args); | 131 | std::vector<std::string>* args); |
132 | bool ReadArgs(State* state, const std::vector<std::unique_ptr<Expr>>& argv, | ||
133 | std::vector<std::string>* args, size_t start, size_t len); | ||
127 | 134 | ||
128 | // Evaluate the expressions in argv, and put the results of Value* in | 135 | // Evaluate the expressions in argv, and put the results of Value* in args. If any |
129 | // args. If any expression evaluate to nullptr, free the rest and return | 136 | // expression evaluate to nullptr, return false. Return true on success. |
130 | // false. Return true on success. | 137 | bool ReadValueArgs(State* state, const std::vector<std::unique_ptr<Expr>>& argv, |
131 | bool ReadValueArgs(State* state, int argc, Expr* argv[], std::vector<std::unique_ptr<Value>>* args); | 138 | std::vector<std::unique_ptr<Value>>* args); |
139 | bool ReadValueArgs(State* state, const std::vector<std::unique_ptr<Expr>>& argv, | ||
140 | std::vector<std::unique_ptr<Value>>* args, size_t start, size_t len); | ||
132 | 141 | ||
133 | // Use printf-style arguments to compose an error message to put into | 142 | // Use printf-style arguments to compose an error message to put into |
134 | // *state. Returns NULL. | 143 | // *state. Returns NULL. |
@@ -145,6 +154,6 @@ Value* StringValue(const char* str); | |||
145 | 154 | ||
146 | Value* StringValue(const std::string& str); | 155 | Value* StringValue(const std::string& str); |
147 | 156 | ||
148 | int parse_string(const char* str, Expr** root, int* error_count); | 157 | int parse_string(const char* str, std::unique_ptr<Expr>* root, int* error_count); |
149 | 158 | ||
150 | #endif // _EXPRESSION_H | 159 | #endif // _EXPRESSION_H |
diff --git a/edify/parser.yy b/edify/parser.yy index 58a8dec6..97205fe3 100644 --- a/edify/parser.yy +++ b/edify/parser.yy | |||
@@ -19,6 +19,10 @@ | |||
19 | #include <stdlib.h> | 19 | #include <stdlib.h> |
20 | #include <string.h> | 20 | #include <string.h> |
21 | 21 | ||
22 | #include <memory> | ||
23 | #include <string> | ||
24 | #include <vector> | ||
25 | |||
22 | #include "expr.h" | 26 | #include "expr.h" |
23 | #include "yydefs.h" | 27 | #include "yydefs.h" |
24 | #include "parser.h" | 28 | #include "parser.h" |
@@ -26,8 +30,8 @@ | |||
26 | extern int gLine; | 30 | extern int gLine; |
27 | extern int gColumn; | 31 | extern int gColumn; |
28 | 32 | ||
29 | void yyerror(Expr** root, int* error_count, const char* s); | 33 | void yyerror(std::unique_ptr<Expr>* root, int* error_count, const char* s); |
30 | int yyparse(Expr** root, int* error_count); | 34 | int yyparse(std::unique_ptr<Expr>* root, int* error_count); |
31 | 35 | ||
32 | struct yy_buffer_state; | 36 | struct yy_buffer_state; |
33 | void yy_switch_to_buffer(struct yy_buffer_state* new_buffer); | 37 | void yy_switch_to_buffer(struct yy_buffer_state* new_buffer); |
@@ -38,17 +42,11 @@ struct yy_buffer_state* yy_scan_string(const char* yystr); | |||
38 | static Expr* Build(Function fn, YYLTYPE loc, size_t count, ...) { | 42 | static Expr* Build(Function fn, YYLTYPE loc, size_t count, ...) { |
39 | va_list v; | 43 | va_list v; |
40 | va_start(v, count); | 44 | va_start(v, count); |
41 | Expr* e = static_cast<Expr*>(malloc(sizeof(Expr))); | 45 | Expr* e = new Expr(fn, "(operator)", loc.start, loc.end); |
42 | e->fn = fn; | ||
43 | e->name = "(operator)"; | ||
44 | e->argc = count; | ||
45 | e->argv = static_cast<Expr**>(malloc(count * sizeof(Expr*))); | ||
46 | for (size_t i = 0; i < count; ++i) { | 46 | for (size_t i = 0; i < count; ++i) { |
47 | e->argv[i] = va_arg(v, Expr*); | 47 | e->argv.emplace_back(va_arg(v, Expr*)); |
48 | } | 48 | } |
49 | va_end(v); | 49 | va_end(v); |
50 | e->start = loc.start; | ||
51 | e->end = loc.end; | ||
52 | return e; | 50 | return e; |
53 | } | 51 | } |
54 | 52 | ||
@@ -59,10 +57,7 @@ static Expr* Build(Function fn, YYLTYPE loc, size_t count, ...) { | |||
59 | %union { | 57 | %union { |
60 | char* str; | 58 | char* str; |
61 | Expr* expr; | 59 | Expr* expr; |
62 | struct { | 60 | std::vector<std::unique_ptr<Expr>>* args; |
63 | int argc; | ||
64 | Expr** argv; | ||
65 | } args; | ||
66 | } | 61 | } |
67 | 62 | ||
68 | %token AND OR SUBSTR SUPERSTR EQ NE IF THEN ELSE ENDIF | 63 | %token AND OR SUBSTR SUPERSTR EQ NE IF THEN ELSE ENDIF |
@@ -70,7 +65,10 @@ static Expr* Build(Function fn, YYLTYPE loc, size_t count, ...) { | |||
70 | %type <expr> expr | 65 | %type <expr> expr |
71 | %type <args> arglist | 66 | %type <args> arglist |
72 | 67 | ||
73 | %parse-param {Expr** root} | 68 | %destructor { delete $$; } expr |
69 | %destructor { delete $$; } arglist | ||
70 | |||
71 | %parse-param {std::unique_ptr<Expr>* root} | ||
74 | %parse-param {int* error_count} | 72 | %parse-param {int* error_count} |
75 | %error-verbose | 73 | %error-verbose |
76 | 74 | ||
@@ -85,17 +83,11 @@ static Expr* Build(Function fn, YYLTYPE loc, size_t count, ...) { | |||
85 | 83 | ||
86 | %% | 84 | %% |
87 | 85 | ||
88 | input: expr { *root = $1; } | 86 | input: expr { root->reset($1); } |
89 | ; | 87 | ; |
90 | 88 | ||
91 | expr: STRING { | 89 | expr: STRING { |
92 | $$ = static_cast<Expr*>(malloc(sizeof(Expr))); | 90 | $$ = new Expr(Literal, $1, @$.start, @$.end); |
93 | $$->fn = Literal; | ||
94 | $$->name = $1; | ||
95 | $$->argc = 0; | ||
96 | $$->argv = NULL; | ||
97 | $$->start = @$.start; | ||
98 | $$->end = @$.end; | ||
99 | } | 91 | } |
100 | | '(' expr ')' { $$ = $2; $$->start=@$.start; $$->end=@$.end; } | 92 | | '(' expr ')' { $$ = $2; $$->start=@$.start; $$->end=@$.end; } |
101 | | expr ';' { $$ = $1; $$->start=@1.start; $$->end=@1.end; } | 93 | | expr ';' { $$ = $1; $$->start=@1.start; $$->end=@1.end; } |
@@ -110,41 +102,32 @@ expr: STRING { | |||
110 | | IF expr THEN expr ENDIF { $$ = Build(IfElseFn, @$, 2, $2, $4); } | 102 | | IF expr THEN expr ENDIF { $$ = Build(IfElseFn, @$, 2, $2, $4); } |
111 | | IF expr THEN expr ELSE expr ENDIF { $$ = Build(IfElseFn, @$, 3, $2, $4, $6); } | 103 | | IF expr THEN expr ELSE expr ENDIF { $$ = Build(IfElseFn, @$, 3, $2, $4, $6); } |
112 | | STRING '(' arglist ')' { | 104 | | STRING '(' arglist ')' { |
113 | $$ = static_cast<Expr*>(malloc(sizeof(Expr))); | 105 | Function fn = FindFunction($1); |
114 | $$->fn = FindFunction($1); | 106 | if (fn == nullptr) { |
115 | if ($$->fn == nullptr) { | 107 | std::string msg = "unknown function \"" + std::string($1) + "\""; |
116 | char buffer[256]; | 108 | yyerror(root, error_count, msg.c_str()); |
117 | snprintf(buffer, sizeof(buffer), "unknown function \"%s\"", $1); | ||
118 | yyerror(root, error_count, buffer); | ||
119 | YYERROR; | 109 | YYERROR; |
120 | } | 110 | } |
121 | $$->name = $1; | 111 | $$ = new Expr(fn, $1, @$.start, @$.end); |
122 | $$->argc = $3.argc; | 112 | $$->argv = std::move(*$3); |
123 | $$->argv = $3.argv; | ||
124 | $$->start = @$.start; | ||
125 | $$->end = @$.end; | ||
126 | } | 113 | } |
127 | ; | 114 | ; |
128 | 115 | ||
129 | arglist: /* empty */ { | 116 | arglist: /* empty */ { |
130 | $$.argc = 0; | 117 | $$ = new std::vector<std::unique_ptr<Expr>>; |
131 | $$.argv = NULL; | ||
132 | } | 118 | } |
133 | | expr { | 119 | | expr { |
134 | $$.argc = 1; | 120 | $$ = new std::vector<std::unique_ptr<Expr>>; |
135 | $$.argv = static_cast<Expr**>(malloc(sizeof(Expr*))); | 121 | $$->emplace_back($1); |
136 | $$.argv[0] = $1; | ||
137 | } | 122 | } |
138 | | arglist ',' expr { | 123 | | arglist ',' expr { |
139 | $$.argc = $1.argc + 1; | 124 | $$->push_back(std::unique_ptr<Expr>($3)); |
140 | $$.argv = static_cast<Expr**>(realloc($$.argv, $$.argc * sizeof(Expr*))); | ||
141 | $$.argv[$$.argc-1] = $3; | ||
142 | } | 125 | } |
143 | ; | 126 | ; |
144 | 127 | ||
145 | %% | 128 | %% |
146 | 129 | ||
147 | void yyerror(Expr** root, int* error_count, const char* s) { | 130 | void yyerror(std::unique_ptr<Expr>* root, int* error_count, const char* s) { |
148 | if (strlen(s) == 0) { | 131 | if (strlen(s) == 0) { |
149 | s = "syntax error"; | 132 | s = "syntax error"; |
150 | } | 133 | } |
@@ -152,7 +135,7 @@ void yyerror(Expr** root, int* error_count, const char* s) { | |||
152 | ++*error_count; | 135 | ++*error_count; |
153 | } | 136 | } |
154 | 137 | ||
155 | int parse_string(const char* str, Expr** root, int* error_count) { | 138 | int parse_string(const char* str, std::unique_ptr<Expr>* root, int* error_count) { |
156 | yy_switch_to_buffer(yy_scan_string(str)); | 139 | yy_switch_to_buffer(yy_scan_string(str)); |
157 | return yyparse(root, error_count); | 140 | return yyparse(root, error_count); |
158 | } | 141 | } |