blob: ec2409752a93ad6f063b9e21459a5cb41afc68e4 [file] [log] [blame]
Doug Zongker37bee622009-06-08 17:35:39 -07001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Tao Bao39119ad2016-10-10 22:52:18 -070017#include "expr.h"
18
19#include <stdarg.h>
Doug Zongker37bee622009-06-08 17:35:39 -070020#include <stdio.h>
21#include <stdlib.h>
Tao Bao39119ad2016-10-10 22:52:18 -070022#include <string.h>
Doug Zongker9931f7f2009-06-10 14:11:53 -070023#include <unistd.h>
Doug Zongker37bee622009-06-08 17:35:39 -070024
Tianjie Xuaced5d92016-10-12 10:55:04 -070025#include <memory>
Tianjie Xu16255832016-04-30 11:49:59 -070026#include <string>
Tao Bao39119ad2016-10-10 22:52:18 -070027#include <unordered_map>
Tianjie Xuaced5d92016-10-12 10:55:04 -070028#include <vector>
Tianjie Xu16255832016-04-30 11:49:59 -070029
Tianjie Xuaced5d92016-10-12 10:55:04 -070030#include <android-base/parseint.h>
Tianjie Xu16255832016-04-30 11:49:59 -070031#include <android-base/stringprintf.h>
32#include <android-base/strings.h>
33
Doug Zongker37bee622009-06-08 17:35:39 -070034// Functions should:
35//
36// - return a malloc()'d string
Tianjie Xuaced5d92016-10-12 10:55:04 -070037// - if Evaluate() on any argument returns nullptr, return nullptr.
Doug Zongker37bee622009-06-08 17:35:39 -070038
Tianjie Xuaced5d92016-10-12 10:55:04 -070039static bool BooleanString(const std::string& s) {
40 return !s.empty();
Doug Zongker37bee622009-06-08 17:35:39 -070041}
42
Tianjie Xuaced5d92016-10-12 10:55:04 -070043bool Evaluate(State* state, Expr* expr, std::string* result) {
44 if (result == nullptr) {
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 }
Doug Zongker512536a2010-02-17 16:11:44 -080052 if (v->type != VAL_STRING) {
Tianjie Xu16255832016-04-30 11:49:59 -070053 ErrorAbort(state, kArgsParsingFailure, "expecting string, got value type %d", v->type);
Tianjie Xuaced5d92016-10-12 10:55:04 -070054 return false;
Doug Zongker512536a2010-02-17 16:11:44 -080055 }
Tianjie Xuaced5d92016-10-12 10:55:04 -070056
57 *result = v->data;
58 return true;
Doug Zongker512536a2010-02-17 16:11:44 -080059}
60
61Value* EvaluateValue(State* state, Expr* expr) {
Doug Zongkerd9c9d102009-06-12 12:24:39 -070062 return expr->fn(expr->name, state, expr->argc, expr->argv);
Doug Zongker37bee622009-06-08 17:35:39 -070063}
64
Tianjie Xuaced5d92016-10-12 10:55:04 -070065Value* StringValue(const char* str) {
66 if (str == nullptr) {
67 return nullptr;
68 }
69 return new Value(VAL_STRING, str);
Doug Zongker512536a2010-02-17 16:11:44 -080070}
71
Tianjie Xuaced5d92016-10-12 10:55:04 -070072Value* StringValue(const std::string& str) {
73 return StringValue(str.c_str());
Doug Zongker512536a2010-02-17 16:11:44 -080074}
75
76Value* ConcatFn(const char* name, State* state, int argc, Expr* argv[]) {
Doug Zongkerd9c9d102009-06-12 12:24:39 -070077 if (argc == 0) {
Tianjie Xuaced5d92016-10-12 10:55:04 -070078 return StringValue("");
Doug Zongker37bee622009-06-08 17:35:39 -070079 }
Tianjie Xuaced5d92016-10-12 10:55:04 -070080 std::string result;
81 for (int i = 0; i < argc; ++i) {
82 std::string str;
83 if (!Evaluate(state, argv[i], &str)) {
84 return nullptr;
Doug Zongkerd9c9d102009-06-12 12:24:39 -070085 }
Tianjie Xuaced5d92016-10-12 10:55:04 -070086 result += str;
Doug Zongkerd9c9d102009-06-12 12:24:39 -070087 }
Doug Zongker37bee622009-06-08 17:35:39 -070088
Doug Zongker512536a2010-02-17 16:11:44 -080089 return StringValue(result);
Doug Zongker37bee622009-06-08 17:35:39 -070090}
91
Doug Zongker512536a2010-02-17 16:11:44 -080092Value* IfElseFn(const char* name, State* state, int argc, Expr* argv[]) {
Doug Zongkerd9c9d102009-06-12 12:24:39 -070093 if (argc != 2 && argc != 3) {
Tao Bao59dcb9c2016-10-03 18:06:46 -070094 state->errmsg = "ifelse expects 2 or 3 arguments";
Tianjie Xuaced5d92016-10-12 10:55:04 -070095 return nullptr;
Doug Zongkerd9c9d102009-06-12 12:24:39 -070096 }
Doug Zongker37bee622009-06-08 17:35:39 -070097
Tianjie Xuaced5d92016-10-12 10:55:04 -070098 std::string cond;
99 if (!Evaluate(state, argv[0], &cond)) {
100 return nullptr;
Doug Zongker37bee622009-06-08 17:35:39 -0700101 }
Tianjie Xuaced5d92016-10-12 10:55:04 -0700102
103 if (!cond.empty()) {
104 return EvaluateValue(state, argv[1]);
105 } else if (argc == 3) {
106 return EvaluateValue(state, argv[2]);
107 }
108
109 return StringValue("");
Doug Zongker37bee622009-06-08 17:35:39 -0700110}
111
Doug Zongker512536a2010-02-17 16:11:44 -0800112Value* AbortFn(const char* name, State* state, int argc, Expr* argv[]) {
Tianjie Xuaced5d92016-10-12 10:55:04 -0700113 std::string msg;
114 if (argc > 0 && Evaluate(state, argv[0], &msg)) {
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700115 state->errmsg = msg;
116 } else {
Tao Bao59dcb9c2016-10-03 18:06:46 -0700117 state->errmsg = "called abort()";
Doug Zongker37bee622009-06-08 17:35:39 -0700118 }
Tianjie Xuaced5d92016-10-12 10:55:04 -0700119 return nullptr;
Doug Zongker9931f7f2009-06-10 14:11:53 -0700120}
121
Doug Zongker512536a2010-02-17 16:11:44 -0800122Value* AssertFn(const char* name, State* state, int argc, Expr* argv[]) {
Tianjie Xuaced5d92016-10-12 10:55:04 -0700123 for (int i = 0; i < argc; ++i) {
124 std::string result;
125 if (!Evaluate(state, argv[i], &result)) {
126 return nullptr;
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700127 }
Tianjie Xuaced5d92016-10-12 10:55:04 -0700128 if (result.empty()) {
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700129 int len = argv[i]->end - argv[i]->start;
Tao Bao59dcb9c2016-10-03 18:06:46 -0700130 state->errmsg = "assert failed: " + state->script.substr(argv[i]->start, len);
Tianjie Xuaced5d92016-10-12 10:55:04 -0700131 return nullptr;
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700132 }
Doug Zongker37bee622009-06-08 17:35:39 -0700133 }
Tianjie Xuaced5d92016-10-12 10:55:04 -0700134 return StringValue("");
Doug Zongker37bee622009-06-08 17:35:39 -0700135}
136
Doug Zongker512536a2010-02-17 16:11:44 -0800137Value* SleepFn(const char* name, State* state, int argc, Expr* argv[]) {
Tianjie Xuaced5d92016-10-12 10:55:04 -0700138 std::string val;
139 if (!Evaluate(state, argv[0], &val)) {
140 return nullptr;
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700141 }
Tianjie Xuaced5d92016-10-12 10:55:04 -0700142
143 int v;
144 if (!android::base::ParseInt(val.c_str(), &v, 0)) {
145 return nullptr;
146 }
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700147 sleep(v);
Tianjie Xuaced5d92016-10-12 10:55:04 -0700148
Doug Zongker512536a2010-02-17 16:11:44 -0800149 return StringValue(val);
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700150}
151
Doug Zongker512536a2010-02-17 16:11:44 -0800152Value* StdoutFn(const char* name, State* state, int argc, Expr* argv[]) {
Tianjie Xuaced5d92016-10-12 10:55:04 -0700153 for (int i = 0; i < argc; ++i) {
154 std::string v;
155 if (!Evaluate(state, argv[i], &v)) {
156 return nullptr;
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700157 }
Tianjie Xuaced5d92016-10-12 10:55:04 -0700158 fputs(v.c_str(), stdout);
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700159 }
Tianjie Xuaced5d92016-10-12 10:55:04 -0700160 return StringValue("");
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700161}
162
Doug Zongker512536a2010-02-17 16:11:44 -0800163Value* LogicalAndFn(const char* name, State* state,
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700164 int argc, Expr* argv[]) {
Tianjie Xuaced5d92016-10-12 10:55:04 -0700165 std::string left;
166 if (!Evaluate(state, argv[0], &left)) {
167 return nullptr;
168 }
169 if (BooleanString(left)) {
Doug Zongker512536a2010-02-17 16:11:44 -0800170 return EvaluateValue(state, argv[1]);
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700171 } else {
Tianjie Xuaced5d92016-10-12 10:55:04 -0700172 return StringValue("");
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700173 }
174}
175
Doug Zongker512536a2010-02-17 16:11:44 -0800176Value* LogicalOrFn(const char* name, State* state,
177 int argc, Expr* argv[]) {
Tianjie Xuaced5d92016-10-12 10:55:04 -0700178 std::string left;
179 if (!Evaluate(state, argv[0], &left)) {
180 return nullptr;
181 }
182 if (!BooleanString(left)) {
Doug Zongker512536a2010-02-17 16:11:44 -0800183 return EvaluateValue(state, argv[1]);
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700184 } else {
Doug Zongker512536a2010-02-17 16:11:44 -0800185 return StringValue(left);
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700186 }
187}
188
Doug Zongker512536a2010-02-17 16:11:44 -0800189Value* LogicalNotFn(const char* name, State* state,
190 int argc, Expr* argv[]) {
Tianjie Xuaced5d92016-10-12 10:55:04 -0700191 std::string val;
192 if (!Evaluate(state, argv[0], &val)) {
193 return nullptr;
194 }
195
196 return StringValue(BooleanString(val) ? "" : "t");
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700197}
198
Doug Zongker512536a2010-02-17 16:11:44 -0800199Value* SubstringFn(const char* name, State* state,
200 int argc, Expr* argv[]) {
Tianjie Xuaced5d92016-10-12 10:55:04 -0700201 std::string needle;
202 if (!Evaluate(state, argv[0], &needle)) {
203 return nullptr;
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700204 }
205
Tianjie Xuaced5d92016-10-12 10:55:04 -0700206 std::string haystack;
207 if (!Evaluate(state, argv[1], &haystack)) {
208 return nullptr;
209 }
210
211 std::string result = (haystack.find(needle) != std::string::npos) ? "t" : "";
Doug Zongker512536a2010-02-17 16:11:44 -0800212 return StringValue(result);
Doug Zongker37bee622009-06-08 17:35:39 -0700213}
214
Doug Zongker512536a2010-02-17 16:11:44 -0800215Value* EqualityFn(const char* name, State* state, int argc, Expr* argv[]) {
Tianjie Xuaced5d92016-10-12 10:55:04 -0700216 std::string left;
217 if (!Evaluate(state, argv[0], &left)) {
218 return nullptr;
219 }
220 std::string right;
221 if (!Evaluate(state, argv[1], &right)) {
222 return nullptr;
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700223 }
224
Tianjie Xuaced5d92016-10-12 10:55:04 -0700225 const char* result = (left == right) ? "t" : "";
Doug Zongker512536a2010-02-17 16:11:44 -0800226 return StringValue(result);
Doug Zongker37bee622009-06-08 17:35:39 -0700227}
228
Doug Zongker512536a2010-02-17 16:11:44 -0800229Value* InequalityFn(const char* name, State* state, int argc, Expr* argv[]) {
Tianjie Xuaced5d92016-10-12 10:55:04 -0700230 std::string left;
231 if (!Evaluate(state, argv[0], &left)) {
232 return nullptr;
233 }
234 std::string right;
235 if (!Evaluate(state, argv[1], &right)) {
236 return nullptr;
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700237 }
238
Tianjie Xuaced5d92016-10-12 10:55:04 -0700239 const char* result = (left != right) ? "t" : "";
Doug Zongker512536a2010-02-17 16:11:44 -0800240 return StringValue(result);
Doug Zongker37bee622009-06-08 17:35:39 -0700241}
242
Doug Zongker512536a2010-02-17 16:11:44 -0800243Value* SequenceFn(const char* name, State* state, int argc, Expr* argv[]) {
Tianjie Xuaced5d92016-10-12 10:55:04 -0700244 std::unique_ptr<Value> left(EvaluateValue(state, argv[0]));
245 if (!left) {
246 return nullptr;
247 }
Doug Zongker512536a2010-02-17 16:11:44 -0800248 return EvaluateValue(state, argv[1]);
Doug Zongker37bee622009-06-08 17:35:39 -0700249}
250
Doug Zongker512536a2010-02-17 16:11:44 -0800251Value* LessThanIntFn(const char* name, State* state, int argc, Expr* argv[]) {
Doug Zongkere3da02e2009-06-12 16:13:52 -0700252 if (argc != 2) {
Tao Bao59dcb9c2016-10-03 18:06:46 -0700253 state->errmsg = "less_than_int expects 2 arguments";
Tianjie Xuaced5d92016-10-12 10:55:04 -0700254 return nullptr;
Doug Zongkere3da02e2009-06-12 16:13:52 -0700255 }
256
257 char* left;
258 char* right;
Tianjie Xuaced5d92016-10-12 10:55:04 -0700259 if (ReadArgs(state, argv, 2, &left, &right) < 0) return nullptr;
Doug Zongkere3da02e2009-06-12 16:13:52 -0700260
261 bool result = false;
262 char* end;
263
Chih-Hung Hsieh54a27472016-04-18 11:30:55 -0700264 // Parse up to at least long long or 64-bit integers.
265 int64_t l_int = static_cast<int64_t>(strtoll(left, &end, 10));
Doug Zongkere3da02e2009-06-12 16:13:52 -0700266 if (left[0] == '\0' || *end != '\0') {
Doug Zongkere3da02e2009-06-12 16:13:52 -0700267 goto done;
268 }
269
Chih-Hung Hsieh54a27472016-04-18 11:30:55 -0700270 int64_t r_int;
271 r_int = static_cast<int64_t>(strtoll(right, &end, 10));
Doug Zongkere3da02e2009-06-12 16:13:52 -0700272 if (right[0] == '\0' || *end != '\0') {
Doug Zongkere3da02e2009-06-12 16:13:52 -0700273 goto done;
274 }
275
276 result = l_int < r_int;
277
278 done:
279 free(left);
280 free(right);
Tianjie Xuaced5d92016-10-12 10:55:04 -0700281 return StringValue(result ? "t" : "");
Doug Zongkere3da02e2009-06-12 16:13:52 -0700282}
283
Doug Zongker512536a2010-02-17 16:11:44 -0800284Value* GreaterThanIntFn(const char* name, State* state,
285 int argc, Expr* argv[]) {
Doug Zongkere3da02e2009-06-12 16:13:52 -0700286 if (argc != 2) {
Tao Bao59dcb9c2016-10-03 18:06:46 -0700287 state->errmsg = "greater_than_int expects 2 arguments";
Tianjie Xuaced5d92016-10-12 10:55:04 -0700288 return nullptr;
Doug Zongkere3da02e2009-06-12 16:13:52 -0700289 }
290
291 Expr* temp[2];
292 temp[0] = argv[1];
293 temp[1] = argv[0];
294
295 return LessThanIntFn(name, state, 2, temp);
296}
297
Doug Zongker512536a2010-02-17 16:11:44 -0800298Value* Literal(const char* name, State* state, int argc, Expr* argv[]) {
Tianjie Xuaced5d92016-10-12 10:55:04 -0700299 return StringValue(name);
Doug Zongker37bee622009-06-08 17:35:39 -0700300}
301
Doug Zongker9931f7f2009-06-10 14:11:53 -0700302// -----------------------------------------------------------------
303// the function table
304// -----------------------------------------------------------------
305
Tao Bao39119ad2016-10-10 22:52:18 -0700306static std::unordered_map<std::string, Function> fn_table;
Doug Zongker37bee622009-06-08 17:35:39 -0700307
Tao Bao39119ad2016-10-10 22:52:18 -0700308void RegisterFunction(const std::string& name, Function fn) {
309 fn_table[name] = fn;
310}
311
312Function FindFunction(const std::string& name) {
313 if (fn_table.find(name) == fn_table.end()) {
314 return nullptr;
315 } else {
316 return fn_table[name];
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700317 }
Doug Zongker37bee622009-06-08 17:35:39 -0700318}
319
320void RegisterBuiltins() {
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700321 RegisterFunction("ifelse", IfElseFn);
322 RegisterFunction("abort", AbortFn);
323 RegisterFunction("assert", AssertFn);
324 RegisterFunction("concat", ConcatFn);
325 RegisterFunction("is_substring", SubstringFn);
326 RegisterFunction("stdout", StdoutFn);
327 RegisterFunction("sleep", SleepFn);
Doug Zongkere3da02e2009-06-12 16:13:52 -0700328
329 RegisterFunction("less_than_int", LessThanIntFn);
330 RegisterFunction("greater_than_int", GreaterThanIntFn);
Doug Zongker9931f7f2009-06-10 14:11:53 -0700331}
332
333
334// -----------------------------------------------------------------
335// convenience methods for functions
336// -----------------------------------------------------------------
337
Tianjie Xuaced5d92016-10-12 10:55:04 -0700338// 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
Doug Zongker9931f7f2009-06-10 14:11:53 -0700375// Evaluate the expressions in argv, giving 'count' char* (the ... is
376// zero or more char** to put them in). If any expression evaluates
377// to NULL, free the rest and return -1. Return 0 on success.
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700378int ReadArgs(State* state, Expr* argv[], int count, ...) {
Tao Bao2a5a49d2015-08-20 12:10:46 -0700379 char** args = reinterpret_cast<char**>(malloc(count * sizeof(char*)));
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700380 va_list v;
381 va_start(v, count);
382 int i;
383 for (i = 0; i < count; ++i) {
Tianjie Xuaced5d92016-10-12 10:55:04 -0700384 std::string str;
385 if (!Evaluate(state, argv[i], &str) ||
386 (args[i] = strdup(str.c_str())) == nullptr) {
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700387 va_end(v);
388 int j;
389 for (j = 0; j < i; ++j) {
390 free(args[j]);
391 }
Kenny Root21854cc2010-02-17 18:31:48 -0800392 free(args);
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700393 return -1;
394 }
395 *(va_arg(v, char**)) = args[i];
Doug Zongker9931f7f2009-06-10 14:11:53 -0700396 }
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700397 va_end(v);
Kenny Root21854cc2010-02-17 18:31:48 -0800398 free(args);
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700399 return 0;
Doug Zongker9931f7f2009-06-10 14:11:53 -0700400}
401
Doug Zongker512536a2010-02-17 16:11:44 -0800402// Evaluate the expressions in argv, giving 'count' Value* (the ... is
403// zero or more Value** to put them in). If any expression evaluates
404// to NULL, free the rest and return -1. Return 0 on success.
405int ReadValueArgs(State* state, Expr* argv[], int count, ...) {
Tianjie Xuaced5d92016-10-12 10:55:04 -0700406 Value** args = new Value*[count];
Doug Zongker512536a2010-02-17 16:11:44 -0800407 va_list v;
408 va_start(v, count);
Tianjie Xuaced5d92016-10-12 10:55:04 -0700409 for (int i = 0; i < count; ++i) {
Doug Zongker512536a2010-02-17 16:11:44 -0800410 args[i] = EvaluateValue(state, argv[i]);
411 if (args[i] == NULL) {
412 va_end(v);
413 int j;
414 for (j = 0; j < i; ++j) {
Tianjie Xuaced5d92016-10-12 10:55:04 -0700415 delete args[j];
Doug Zongker512536a2010-02-17 16:11:44 -0800416 }
Tianjie Xuaced5d92016-10-12 10:55:04 -0700417 delete[] args;
Doug Zongker512536a2010-02-17 16:11:44 -0800418 return -1;
419 }
420 *(va_arg(v, Value**)) = args[i];
421 }
422 va_end(v);
Tianjie Xuaced5d92016-10-12 10:55:04 -0700423 delete[] args;
Doug Zongker512536a2010-02-17 16:11:44 -0800424 return 0;
425}
426
Doug Zongker9931f7f2009-06-10 14:11:53 -0700427// Evaluate the expressions in argv, returning an array of char*
428// results. If any evaluate to NULL, free the rest and return NULL.
429// The caller is responsible for freeing the returned array and the
430// strings it contains.
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700431char** ReadVarArgs(State* state, int argc, Expr* argv[]) {
432 char** args = (char**)malloc(argc * sizeof(char*));
Tianjie Xuaced5d92016-10-12 10:55:04 -0700433 for (int i = 0; i < argc; ++i) {
434 std::string str;
435 if (!Evaluate(state, argv[i], &str) ||
436 (args[i] = strdup(str.c_str())) == nullptr) {
437 for (int j = 0; j < i; ++j) {
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700438 free(args[j]);
439 }
440 free(args);
441 return NULL;
442 }
Doug Zongker9931f7f2009-06-10 14:11:53 -0700443 }
Doug Zongkerd9c9d102009-06-12 12:24:39 -0700444 return args;
Doug Zongker37bee622009-06-08 17:35:39 -0700445}
Doug Zongker47cace92009-06-18 10:11:50 -0700446
Doug Zongker512536a2010-02-17 16:11:44 -0800447// Evaluate the expressions in argv, returning an array of Value*
448// results. If any evaluate to NULL, free the rest and return NULL.
449// The caller is responsible for freeing the returned array and the
450// Values it contains.
451Value** ReadValueVarArgs(State* state, int argc, Expr* argv[]) {
Tianjie Xuaced5d92016-10-12 10:55:04 -0700452 Value** args = new Value*[argc];
Doug Zongker512536a2010-02-17 16:11:44 -0800453 int i = 0;
454 for (i = 0; i < argc; ++i) {
455 args[i] = EvaluateValue(state, argv[i]);
456 if (args[i] == NULL) {
457 int j;
458 for (j = 0; j < i; ++j) {
Tianjie Xuaced5d92016-10-12 10:55:04 -0700459 delete args[j];
Doug Zongker512536a2010-02-17 16:11:44 -0800460 }
Tianjie Xuaced5d92016-10-12 10:55:04 -0700461 delete[] args;
Doug Zongker512536a2010-02-17 16:11:44 -0800462 return NULL;
463 }
464 }
465 return args;
466}
467
Tianjie Xu16255832016-04-30 11:49:59 -0700468// Use printf-style arguments to compose an error message to put into
469// *state. Returns nullptr.
470Value* ErrorAbort(State* state, const char* format, ...) {
471 va_list ap;
472 va_start(ap, format);
Tao Bao59dcb9c2016-10-03 18:06:46 -0700473 android::base::StringAppendV(&state->errmsg, format, ap);
Tianjie Xu16255832016-04-30 11:49:59 -0700474 va_end(ap);
475 return nullptr;
476}
477
478Value* ErrorAbort(State* state, CauseCode cause_code, const char* format, ...) {
479 va_list ap;
480 va_start(ap, format);
Tao Bao59dcb9c2016-10-03 18:06:46 -0700481 android::base::StringAppendV(&state->errmsg, format, ap);
Tianjie Xu16255832016-04-30 11:49:59 -0700482 va_end(ap);
483 state->cause_code = cause_code;
484 return nullptr;
Doug Zongker47cace92009-06-18 10:11:50 -0700485}
Tao Bao59dcb9c2016-10-03 18:06:46 -0700486
487State::State(const std::string& script, void* cookie) :
488 script(script),
489 cookie(cookie) {
490}
491