aboutsummaryrefslogtreecommitdiffstats
path: root/edify
diff options
context:
space:
mode:
authorTianjie Xu2016-10-12 12:55:04 -0500
committerTianjie Xu2016-10-14 20:18:23 -0500
commitaced5d9e4e438ba478ce54f9217166b8ab7cc24f (patch)
treeb3bfca3430c25b7c35501497e0b8a0faf2251538 /edify
parentc5b4b719134a1d2d3b06a81f92a00b24e527248d (diff)
downloadplatform-bootable-recovery-aced5d9e4e438ba478ce54f9217166b8ab7cc24f.tar.gz
platform-bootable-recovery-aced5d9e4e438ba478ce54f9217166b8ab7cc24f.tar.xz
platform-bootable-recovery-aced5d9e4e438ba478ce54f9217166b8ab7cc24f.zip
Change StringValue to use std::string
Changing the field of 'Value' in edify to std::string from char*. Meanwhile cleaning up the users of 'Value' and switching them to cpp style. Test: compontent tests passed. Bug: 31713288 Change-Id: Iec5a7d601b1e4ca40935bf1c70d325dafecec235
Diffstat (limited to 'edify')
-rw-r--r--edify/edify_parser.cpp6
-rw-r--r--edify/expr.cpp328
-rw-r--r--edify/expr.h44
3 files changed, 205 insertions, 173 deletions
diff --git a/edify/edify_parser.cpp b/edify/edify_parser.cpp
index 1b89cf21..908fcf13 100644
--- a/edify/edify_parser.cpp
+++ b/edify/edify_parser.cpp
@@ -66,12 +66,12 @@ int main(int argc, char** argv) {
66 ExprDump(0, root, buffer); 66 ExprDump(0, root, buffer);
67 67
68 State state(buffer, nullptr); 68 State state(buffer, nullptr);
69 char* result = Evaluate(&state, root); 69 std::string result;
70 if (result == NULL) { 70 if (!Evaluate(&state, root, &result)) {
71 printf("result was NULL, message is: %s\n", 71 printf("result was NULL, message is: %s\n",
72 (state.errmsg.empty() ? "(NULL)" : state.errmsg.c_str())); 72 (state.errmsg.empty() ? "(NULL)" : state.errmsg.c_str()));
73 } else { 73 } else {
74 printf("result is [%s]\n", result); 74 printf("result is [%s]\n", result.c_str());
75 } 75 }
76 } 76 }
77 return 0; 77 return 0;
diff --git a/edify/expr.cpp b/edify/expr.cpp
index 4000bc4d..ec240975 100644
--- a/edify/expr.cpp
+++ b/edify/expr.cpp
@@ -22,184 +22,164 @@
22#include <string.h> 22#include <string.h>
23#include <unistd.h> 23#include <unistd.h>
24 24
25#include <memory>
25#include <string> 26#include <string>
26#include <unordered_map> 27#include <unordered_map>
28#include <vector>
27 29
30#include <android-base/parseint.h>
28#include <android-base/stringprintf.h> 31#include <android-base/stringprintf.h>
29#include <android-base/strings.h> 32#include <android-base/strings.h>
30 33
31// Functions should: 34// Functions should:
32// 35//
33// - return a malloc()'d string 36// - return a malloc()'d string
34// - if Evaluate() on any argument returns NULL, return NULL. 37// - if Evaluate() on any argument returns nullptr, return nullptr.
35 38
36int BooleanString(const char* s) { 39static bool BooleanString(const std::string& s) {
37 return s[0] != '\0'; 40 return !s.empty();
38} 41}
39 42
40char* Evaluate(State* state, Expr* expr) { 43bool Evaluate(State* state, Expr* expr, std::string* result) {
41 Value* v = expr->fn(expr->name, state, expr->argc, expr->argv); 44 if (result == nullptr) {
42 if (v == NULL) return NULL; 45 return false;
46 }
47
48 std::unique_ptr<Value> v(expr->fn(expr->name, state, expr->argc, expr->argv));
49 if (!v) {
50 return false;
51 }
43 if (v->type != VAL_STRING) { 52 if (v->type != VAL_STRING) {
44 ErrorAbort(state, kArgsParsingFailure, "expecting string, got value type %d", v->type); 53 ErrorAbort(state, kArgsParsingFailure, "expecting string, got value type %d", v->type);
45 FreeValue(v); 54 return false;
46 return NULL;
47 } 55 }
48 char* result = v->data; 56
49 free(v); 57 *result = v->data;
50 return result; 58 return true;
51} 59}
52 60
53Value* EvaluateValue(State* state, Expr* expr) { 61Value* EvaluateValue(State* state, Expr* expr) {
54 return expr->fn(expr->name, state, expr->argc, expr->argv); 62 return expr->fn(expr->name, state, expr->argc, expr->argv);
55} 63}
56 64
57Value* StringValue(char* str) { 65Value* StringValue(const char* str) {
58 if (str == NULL) return NULL; 66 if (str == nullptr) {
59 Value* v = reinterpret_cast<Value*>(malloc(sizeof(Value))); 67 return nullptr;
60 v->type = VAL_STRING; 68 }
61 v->size = strlen(str); 69 return new Value(VAL_STRING, str);
62 v->data = str;
63 return v;
64} 70}
65 71
66void FreeValue(Value* v) { 72Value* StringValue(const std::string& str) {
67 if (v == NULL) return; 73 return StringValue(str.c_str());
68 free(v->data);
69 free(v);
70} 74}
71 75
72Value* ConcatFn(const char* name, State* state, int argc, Expr* argv[]) { 76Value* ConcatFn(const char* name, State* state, int argc, Expr* argv[]) {
73 if (argc == 0) { 77 if (argc == 0) {
74 return StringValue(strdup("")); 78 return StringValue("");
75 } 79 }
76 char** strings = reinterpret_cast<char**>(malloc(argc * sizeof(char*))); 80 std::string result;
77 int i; 81 for (int i = 0; i < argc; ++i) {
78 for (i = 0; i < argc; ++i) { 82 std::string str;
79 strings[i] = NULL; 83 if (!Evaluate(state, argv[i], &str)) {
80 } 84 return nullptr;
81 char* result = NULL;
82 int length = 0;
83 for (i = 0; i < argc; ++i) {
84 strings[i] = Evaluate(state, argv[i]);
85 if (strings[i] == NULL) {
86 goto done;
87 } 85 }
88 length += strlen(strings[i]); 86 result += str;
89 } 87 }
90 88
91 result = reinterpret_cast<char*>(malloc(length+1));
92 int p;
93 p = 0;
94 for (i = 0; i < argc; ++i) {
95 strcpy(result+p, strings[i]);
96 p += strlen(strings[i]);
97 }
98 result[p] = '\0';
99
100 done:
101 for (i = 0; i < argc; ++i) {
102 free(strings[i]);
103 }
104 free(strings);
105 return StringValue(result); 89 return StringValue(result);
106} 90}
107 91
108Value* IfElseFn(const char* name, State* state, int argc, Expr* argv[]) { 92Value* IfElseFn(const char* name, State* state, int argc, Expr* argv[]) {
109 if (argc != 2 && argc != 3) { 93 if (argc != 2 && argc != 3) {
110 state->errmsg = "ifelse expects 2 or 3 arguments"; 94 state->errmsg = "ifelse expects 2 or 3 arguments";
111 return NULL; 95 return nullptr;
112 } 96 }
113 char* cond = Evaluate(state, argv[0]); 97
114 if (cond == NULL) { 98 std::string cond;
115 return NULL; 99 if (!Evaluate(state, argv[0], &cond)) {
100 return nullptr;
116 } 101 }
117 102
118 if (BooleanString(cond) == true) { 103 if (!cond.empty()) {
119 free(cond);
120 return EvaluateValue(state, argv[1]); 104 return EvaluateValue(state, argv[1]);
121 } else { 105 } else if (argc == 3) {
122 if (argc == 3) { 106 return EvaluateValue(state, argv[2]);
123 free(cond);
124 return EvaluateValue(state, argv[2]);
125 } else {
126 return StringValue(cond);
127 }
128 } 107 }
108
109 return StringValue("");
129} 110}
130 111
131Value* AbortFn(const char* name, State* state, int argc, Expr* argv[]) { 112Value* AbortFn(const char* name, State* state, int argc, Expr* argv[]) {
132 char* msg = NULL; 113 std::string msg;
133 if (argc > 0) { 114 if (argc > 0 && Evaluate(state, argv[0], &msg)) {
134 msg = Evaluate(state, argv[0]);
135 }
136 if (msg) {
137 state->errmsg = msg; 115 state->errmsg = msg;
138 } else { 116 } else {
139 state->errmsg = "called abort()"; 117 state->errmsg = "called abort()";
140 } 118 }
141 return NULL; 119 return nullptr;
142} 120}
143 121
144Value* AssertFn(const char* name, State* state, int argc, Expr* argv[]) { 122Value* AssertFn(const char* name, State* state, int argc, Expr* argv[]) {
145 int i; 123 for (int i = 0; i < argc; ++i) {
146 for (i = 0; i < argc; ++i) { 124 std::string result;
147 char* v = Evaluate(state, argv[i]); 125 if (!Evaluate(state, argv[i], &result)) {
148 if (v == NULL) { 126 return nullptr;
149 return NULL;
150 } 127 }
151 int b = BooleanString(v); 128 if (result.empty()) {
152 free(v);
153 if (!b) {
154 int len = argv[i]->end - argv[i]->start; 129 int len = argv[i]->end - argv[i]->start;
155 state->errmsg = "assert failed: " + state->script.substr(argv[i]->start, len); 130 state->errmsg = "assert failed: " + state->script.substr(argv[i]->start, len);
156 return NULL; 131 return nullptr;
157 } 132 }
158 } 133 }
159 return StringValue(strdup("")); 134 return StringValue("");
160} 135}
161 136
162Value* SleepFn(const char* name, State* state, int argc, Expr* argv[]) { 137Value* SleepFn(const char* name, State* state, int argc, Expr* argv[]) {
163 char* val = Evaluate(state, argv[0]); 138 std::string val;
164 if (val == NULL) { 139 if (!Evaluate(state, argv[0], &val)) {
165 return NULL; 140 return nullptr;
141 }
142
143 int v;
144 if (!android::base::ParseInt(val.c_str(), &v, 0)) {
145 return nullptr;
166 } 146 }
167 int v = strtol(val, NULL, 10);
168 sleep(v); 147 sleep(v);
148
169 return StringValue(val); 149 return StringValue(val);
170} 150}
171 151
172Value* StdoutFn(const char* name, State* state, int argc, Expr* argv[]) { 152Value* StdoutFn(const char* name, State* state, int argc, Expr* argv[]) {
173 int i; 153 for (int i = 0; i < argc; ++i) {
174 for (i = 0; i < argc; ++i) { 154 std::string v;
175 char* v = Evaluate(state, argv[i]); 155 if (!Evaluate(state, argv[i], &v)) {
176 if (v == NULL) { 156 return nullptr;
177 return NULL;
178 } 157 }
179 fputs(v, stdout); 158 fputs(v.c_str(), stdout);
180 free(v);
181 } 159 }
182 return StringValue(strdup("")); 160 return StringValue("");
183} 161}
184 162
185Value* LogicalAndFn(const char* name, State* state, 163Value* LogicalAndFn(const char* name, State* state,
186 int argc, Expr* argv[]) { 164 int argc, Expr* argv[]) {
187 char* left = Evaluate(state, argv[0]); 165 std::string left;
188 if (left == NULL) return NULL; 166 if (!Evaluate(state, argv[0], &left)) {
189 if (BooleanString(left) == true) { 167 return nullptr;
190 free(left); 168 }
169 if (BooleanString(left)) {
191 return EvaluateValue(state, argv[1]); 170 return EvaluateValue(state, argv[1]);
192 } else { 171 } else {
193 return StringValue(left); 172 return StringValue("");
194 } 173 }
195} 174}
196 175
197Value* LogicalOrFn(const char* name, State* state, 176Value* LogicalOrFn(const char* name, State* state,
198 int argc, Expr* argv[]) { 177 int argc, Expr* argv[]) {
199 char* left = Evaluate(state, argv[0]); 178 std::string left;
200 if (left == NULL) return NULL; 179 if (!Evaluate(state, argv[0], &left)) {
201 if (BooleanString(left) == false) { 180 return nullptr;
202 free(left); 181 }
182 if (!BooleanString(left)) {
203 return EvaluateValue(state, argv[1]); 183 return EvaluateValue(state, argv[1]);
204 } else { 184 } else {
205 return StringValue(left); 185 return StringValue(left);
@@ -208,75 +188,75 @@ Value* LogicalOrFn(const char* name, State* state,
208 188
209Value* LogicalNotFn(const char* name, State* state, 189Value* LogicalNotFn(const char* name, State* state,
210 int argc, Expr* argv[]) { 190 int argc, Expr* argv[]) {
211 char* val = Evaluate(state, argv[0]); 191 std::string val;
212 if (val == NULL) return NULL; 192 if (!Evaluate(state, argv[0], &val)) {
213 bool bv = BooleanString(val); 193 return nullptr;
214 free(val); 194 }
215 return StringValue(strdup(bv ? "" : "t")); 195
196 return StringValue(BooleanString(val) ? "" : "t");
216} 197}
217 198
218Value* SubstringFn(const char* name, State* state, 199Value* SubstringFn(const char* name, State* state,
219 int argc, Expr* argv[]) { 200 int argc, Expr* argv[]) {
220 char* needle = Evaluate(state, argv[0]); 201 std::string needle;
221 if (needle == NULL) return NULL; 202 if (!Evaluate(state, argv[0], &needle)) {
222 char* haystack = Evaluate(state, argv[1]); 203 return nullptr;
223 if (haystack == NULL) { 204 }
224 free(needle); 205
225 return NULL; 206 std::string haystack;
207 if (!Evaluate(state, argv[1], &haystack)) {
208 return nullptr;
226 } 209 }
227 210
228 char* result = strdup(strstr(haystack, needle) ? "t" : ""); 211 std::string result = (haystack.find(needle) != std::string::npos) ? "t" : "";
229 free(needle);
230 free(haystack);
231 return StringValue(result); 212 return StringValue(result);
232} 213}
233 214
234Value* EqualityFn(const char* name, State* state, int argc, Expr* argv[]) { 215Value* EqualityFn(const char* name, State* state, int argc, Expr* argv[]) {
235 char* left = Evaluate(state, argv[0]); 216 std::string left;
236 if (left == NULL) return NULL; 217 if (!Evaluate(state, argv[0], &left)) {
237 char* right = Evaluate(state, argv[1]); 218 return nullptr;
238 if (right == NULL) { 219 }
239 free(left); 220 std::string right;
240 return NULL; 221 if (!Evaluate(state, argv[1], &right)) {
222 return nullptr;
241 } 223 }
242 224
243 char* result = strdup(strcmp(left, right) == 0 ? "t" : ""); 225 const char* result = (left == right) ? "t" : "";
244 free(left);
245 free(right);
246 return StringValue(result); 226 return StringValue(result);
247} 227}
248 228
249Value* InequalityFn(const char* name, State* state, int argc, Expr* argv[]) { 229Value* InequalityFn(const char* name, State* state, int argc, Expr* argv[]) {
250 char* left = Evaluate(state, argv[0]); 230 std::string left;
251 if (left == NULL) return NULL; 231 if (!Evaluate(state, argv[0], &left)) {
252 char* right = Evaluate(state, argv[1]); 232 return nullptr;
253 if (right == NULL) { 233 }
254 free(left); 234 std::string right;
255 return NULL; 235 if (!Evaluate(state, argv[1], &right)) {
236 return nullptr;
256 } 237 }
257 238
258 char* result = strdup(strcmp(left, right) != 0 ? "t" : ""); 239 const char* result = (left != right) ? "t" : "";
259 free(left);
260 free(right);
261 return StringValue(result); 240 return StringValue(result);
262} 241}
263 242
264Value* SequenceFn(const char* name, State* state, int argc, Expr* argv[]) { 243Value* SequenceFn(const char* name, State* state, int argc, Expr* argv[]) {
265 Value* left = EvaluateValue(state, argv[0]); 244 std::unique_ptr<Value> left(EvaluateValue(state, argv[0]));
266 if (left == NULL) return NULL; 245 if (!left) {
267 FreeValue(left); 246 return nullptr;
247 }
268 return EvaluateValue(state, argv[1]); 248 return EvaluateValue(state, argv[1]);
269} 249}
270 250
271Value* LessThanIntFn(const char* name, State* state, int argc, Expr* argv[]) { 251Value* LessThanIntFn(const char* name, State* state, int argc, Expr* argv[]) {
272 if (argc != 2) { 252 if (argc != 2) {
273 state->errmsg = "less_than_int expects 2 arguments"; 253 state->errmsg = "less_than_int expects 2 arguments";
274 return NULL; 254 return nullptr;
275 } 255 }
276 256
277 char* left; 257 char* left;
278 char* right; 258 char* right;
279 if (ReadArgs(state, argv, 2, &left, &right) < 0) return NULL; 259 if (ReadArgs(state, argv, 2, &left, &right) < 0) return nullptr;
280 260
281 bool result = false; 261 bool result = false;
282 char* end; 262 char* end;
@@ -298,14 +278,14 @@ Value* LessThanIntFn(const char* name, State* state, int argc, Expr* argv[]) {
298 done: 278 done:
299 free(left); 279 free(left);
300 free(right); 280 free(right);
301 return StringValue(strdup(result ? "t" : "")); 281 return StringValue(result ? "t" : "");
302} 282}
303 283
304Value* GreaterThanIntFn(const char* name, State* state, 284Value* GreaterThanIntFn(const char* name, State* state,
305 int argc, Expr* argv[]) { 285 int argc, Expr* argv[]) {
306 if (argc != 2) { 286 if (argc != 2) {
307 state->errmsg = "greater_than_int expects 2 arguments"; 287 state->errmsg = "greater_than_int expects 2 arguments";
308 return NULL; 288 return nullptr;
309 } 289 }
310 290
311 Expr* temp[2]; 291 Expr* temp[2];
@@ -316,7 +296,7 @@ Value* GreaterThanIntFn(const char* name, State* state,
316} 296}
317 297
318Value* Literal(const char* name, State* state, int argc, Expr* argv[]) { 298Value* Literal(const char* name, State* state, int argc, Expr* argv[]) {
319 return StringValue(strdup(name)); 299 return StringValue(name);
320} 300}
321 301
322// ----------------------------------------------------------------- 302// -----------------------------------------------------------------
@@ -355,6 +335,43 @@ void RegisterBuiltins() {
355// convenience methods for functions 335// convenience methods for functions
356// ----------------------------------------------------------------- 336// -----------------------------------------------------------------
357 337
338// Evaluate the expressions in argv, and put the results of strings in
339// args. If any expression evaluates to nullptr, free the rest and return
340// false. Return true on success.
341bool ReadArgs(State* state, int argc, Expr* argv[], std::vector<std::string>* args) {
342 if (args == nullptr) {
343 return false;
344 }
345 for (int i = 0; i < argc; ++i) {
346 std::string var;
347 if (!Evaluate(state, argv[i], &var)) {
348 args->clear();
349 return false;
350 }
351 args->push_back(var);
352 }
353 return true;
354}
355
356// Evaluate the expressions in argv, and put the results of Value* in
357// args. If any expression evaluate to nullptr, free the rest and return
358// false. Return true on success.
359bool ReadValueArgs(State* state, int argc, Expr* argv[],
360 std::vector<std::unique_ptr<Value>>* args) {
361 if (args == nullptr) {
362 return false;
363 }
364 for (int i = 0; i < argc; ++i) {
365 std::unique_ptr<Value> v(EvaluateValue(state, argv[i]));
366 if (!v) {
367 args->clear();
368 return false;
369 }
370 args->push_back(std::move(v));
371 }
372 return true;
373}
374
358// Evaluate the expressions in argv, giving 'count' char* (the ... is 375// Evaluate the expressions in argv, giving 'count' char* (the ... is
359// zero or more char** to put them in). If any expression evaluates 376// zero or more char** to put them in). If any expression evaluates
360// to NULL, free the rest and return -1. Return 0 on success. 377// to NULL, free the rest and return -1. Return 0 on success.
@@ -364,8 +381,9 @@ int ReadArgs(State* state, Expr* argv[], int count, ...) {
364 va_start(v, count); 381 va_start(v, count);
365 int i; 382 int i;
366 for (i = 0; i < count; ++i) { 383 for (i = 0; i < count; ++i) {
367 args[i] = Evaluate(state, argv[i]); 384 std::string str;
368 if (args[i] == NULL) { 385 if (!Evaluate(state, argv[i], &str) ||
386 (args[i] = strdup(str.c_str())) == nullptr) {
369 va_end(v); 387 va_end(v);
370 int j; 388 int j;
371 for (j = 0; j < i; ++j) { 389 for (j = 0; j < i; ++j) {
@@ -385,25 +403,24 @@ int ReadArgs(State* state, Expr* argv[], int count, ...) {
385// zero or more Value** to put them in). If any expression evaluates 403// zero or more Value** to put them in). If any expression evaluates
386// to NULL, free the rest and return -1. Return 0 on success. 404// to NULL, free the rest and return -1. Return 0 on success.
387int ReadValueArgs(State* state, Expr* argv[], int count, ...) { 405int ReadValueArgs(State* state, Expr* argv[], int count, ...) {
388 Value** args = reinterpret_cast<Value**>(malloc(count * sizeof(Value*))); 406 Value** args = new Value*[count];
389 va_list v; 407 va_list v;
390 va_start(v, count); 408 va_start(v, count);
391 int i; 409 for (int i = 0; i < count; ++i) {
392 for (i = 0; i < count; ++i) {
393 args[i] = EvaluateValue(state, argv[i]); 410 args[i] = EvaluateValue(state, argv[i]);
394 if (args[i] == NULL) { 411 if (args[i] == NULL) {
395 va_end(v); 412 va_end(v);
396 int j; 413 int j;
397 for (j = 0; j < i; ++j) { 414 for (j = 0; j < i; ++j) {
398 FreeValue(args[j]); 415 delete args[j];
399 } 416 }
400 free(args); 417 delete[] args;
401 return -1; 418 return -1;
402 } 419 }
403 *(va_arg(v, Value**)) = args[i]; 420 *(va_arg(v, Value**)) = args[i];
404 } 421 }
405 va_end(v); 422 va_end(v);
406 free(args); 423 delete[] args;
407 return 0; 424 return 0;
408} 425}
409 426
@@ -413,12 +430,11 @@ int ReadValueArgs(State* state, Expr* argv[], int count, ...) {
413// strings it contains. 430// strings it contains.
414char** ReadVarArgs(State* state, int argc, Expr* argv[]) { 431char** ReadVarArgs(State* state, int argc, Expr* argv[]) {
415 char** args = (char**)malloc(argc * sizeof(char*)); 432 char** args = (char**)malloc(argc * sizeof(char*));
416 int i = 0; 433 for (int i = 0; i < argc; ++i) {
417 for (i = 0; i < argc; ++i) { 434 std::string str;
418 args[i] = Evaluate(state, argv[i]); 435 if (!Evaluate(state, argv[i], &str) ||
419 if (args[i] == NULL) { 436 (args[i] = strdup(str.c_str())) == nullptr) {
420 int j; 437 for (int j = 0; j < i; ++j) {
421 for (j = 0; j < i; ++j) {
422 free(args[j]); 438 free(args[j]);
423 } 439 }
424 free(args); 440 free(args);
@@ -433,16 +449,16 @@ char** ReadVarArgs(State* state, int argc, Expr* argv[]) {
433// The caller is responsible for freeing the returned array and the 449// The caller is responsible for freeing the returned array and the
434// Values it contains. 450// Values it contains.
435Value** ReadValueVarArgs(State* state, int argc, Expr* argv[]) { 451Value** ReadValueVarArgs(State* state, int argc, Expr* argv[]) {
436 Value** args = (Value**)malloc(argc * sizeof(Value*)); 452 Value** args = new Value*[argc];
437 int i = 0; 453 int i = 0;
438 for (i = 0; i < argc; ++i) { 454 for (i = 0; i < argc; ++i) {
439 args[i] = EvaluateValue(state, argv[i]); 455 args[i] = EvaluateValue(state, argv[i]);
440 if (args[i] == NULL) { 456 if (args[i] == NULL) {
441 int j; 457 int j;
442 for (j = 0; j < i; ++j) { 458 for (j = 0; j < i; ++j) {
443 FreeValue(args[j]); 459 delete args[j];
444 } 460 }
445 free(args); 461 delete[] args;
446 return NULL; 462 return NULL;
447 } 463 }
448 } 464 }
diff --git a/edify/expr.h b/edify/expr.h
index cd6139a1..85306542 100644
--- a/edify/expr.h
+++ b/edify/expr.h
@@ -48,13 +48,19 @@ struct State {
48 bool is_retry = false; 48 bool is_retry = false;
49}; 49};
50 50
51#define VAL_STRING 1 // data will be NULL-terminated; size doesn't count null 51enum ValueType {
52#define VAL_BLOB 2 52 VAL_INVALID = -1,
53 VAL_STRING = 1,
54 VAL_BLOB = 2,
55};
53 56
54struct Value { 57struct Value {
55 int type; 58 ValueType type;
56 ssize_t size; 59 std::string data;
57 char* data; 60
61 Value(ValueType type, const std::string& str) :
62 type(type),
63 data(str) {}
58}; 64};
59 65
60struct Expr; 66struct Expr;
@@ -75,11 +81,11 @@ struct Expr {
75Value* EvaluateValue(State* state, Expr* expr); 81Value* EvaluateValue(State* state, Expr* expr);
76 82
77// Take one of the Expr*s passed to the function as an argument, 83// Take one of the Expr*s passed to the function as an argument,
78// evaluate it, assert that it is a string, and return the resulting 84// evaluate it, assert that it is a string, and update the result
79// char*. The caller takes ownership of the returned char*. This is 85// parameter. This function returns true if the evaluation succeeds.
80// a convenience function for older functions that want to deal only 86// This is a convenience function for older functions that want to
81// with strings. 87// deal only with strings.
82char* Evaluate(State* state, Expr* expr); 88bool Evaluate(State* state, Expr* expr, std::string* result);
83 89
84// Glue to make an Expr out of a literal. 90// Glue to make an Expr out of a literal.
85Value* Literal(const char* name, State* state, int argc, Expr* argv[]); 91Value* Literal(const char* name, State* state, int argc, Expr* argv[]);
@@ -114,6 +120,17 @@ Function FindFunction(const std::string& name);
114 120
115// --- convenience functions for use in functions --- 121// --- convenience functions for use in functions ---
116 122
123// Evaluate the expressions in argv, and put the results of strings in
124// args. If any expression evaluates to nullptr, free the rest and return
125// false. Return true on success.
126bool ReadArgs(State* state, int argc, Expr* argv[], std::vector<std::string>* args);
127
128// Evaluate the expressions in argv, and put the results of Value* in
129// args. If any expression evaluate to nullptr, free the rest and return
130// false. Return true on success.
131bool ReadValueArgs(State* state, int argc, Expr* argv[],
132 std::vector<std::unique_ptr<Value>>* args);
133
117// Evaluate the expressions in argv, giving 'count' char* (the ... is 134// Evaluate the expressions in argv, giving 'count' char* (the ... is
118// zero or more char** to put them in). If any expression evaluates 135// zero or more char** to put them in). If any expression evaluates
119// to NULL, free the rest and return -1. Return 0 on success. 136// to NULL, free the rest and return -1. Return 0 on success.
@@ -146,11 +163,10 @@ Value* ErrorAbort(State* state, const char* format, ...)
146Value* ErrorAbort(State* state, CauseCode cause_code, const char* format, ...) 163Value* ErrorAbort(State* state, CauseCode cause_code, const char* format, ...)
147 __attribute__((format(printf, 3, 4))); 164 __attribute__((format(printf, 3, 4)));
148 165
149// Wrap a string into a Value, taking ownership of the string. 166// Copying the string into a Value.
150Value* StringValue(char* str); 167Value* StringValue(const char* str);
151 168
152// Free a Value object. 169Value* StringValue(const std::string& str);
153void FreeValue(Value* v);
154 170
155int parse_string(const char* str, Expr** root, int* error_count); 171int parse_string(const char* str, Expr** root, int* error_count);
156 172