diff options
Diffstat (limited to '')
-rw-r--r-- | edify/expr.cpp | 119 |
1 files changed, 75 insertions, 44 deletions
diff --git a/edify/expr.cpp b/edify/expr.cpp index 329cf3acd..2b7fd7a6a 100644 --- a/edify/expr.cpp +++ b/edify/expr.cpp @@ -40,12 +40,12 @@ static bool BooleanString(const std::string& s) { return !s.empty(); } -bool Evaluate(State* state, Expr* expr, std::string* result) { +bool Evaluate(State* state, const std::unique_ptr<Expr>& expr, std::string* result) { if (result == nullptr) { return false; } - std::unique_ptr<Value> v(expr->fn(expr->name, state, expr->argc, expr->argv)); + std::unique_ptr<Value> v(expr->fn(expr->name.c_str(), state, expr->argv)); if (!v) { return false; } @@ -58,8 +58,8 @@ bool Evaluate(State* state, Expr* expr, std::string* result) { return true; } -Value* EvaluateValue(State* state, Expr* expr) { - return expr->fn(expr->name, state, expr->argc, expr->argv); +Value* EvaluateValue(State* state, const std::unique_ptr<Expr>& expr) { + return expr->fn(expr->name.c_str(), state, expr->argv); } Value* StringValue(const char* str) { @@ -73,12 +73,12 @@ Value* StringValue(const std::string& str) { return StringValue(str.c_str()); } -Value* ConcatFn(const char* name, State* state, int argc, Expr* argv[]) { - if (argc == 0) { +Value* ConcatFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { + if (argv.empty()) { return StringValue(""); } std::string result; - for (int i = 0; i < argc; ++i) { + for (size_t i = 0; i < argv.size(); ++i) { std::string str; if (!Evaluate(state, argv[i], &str)) { return nullptr; @@ -89,8 +89,8 @@ Value* ConcatFn(const char* name, State* state, int argc, Expr* argv[]) { return StringValue(result); } -Value* IfElseFn(const char* name, State* state, int argc, Expr* argv[]) { - if (argc != 2 && argc != 3) { +Value* IfElseFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { + if (argv.size() != 2 && argv.size() != 3) { state->errmsg = "ifelse expects 2 or 3 arguments"; return nullptr; } @@ -102,16 +102,16 @@ Value* IfElseFn(const char* name, State* state, int argc, Expr* argv[]) { if (!cond.empty()) { return EvaluateValue(state, argv[1]); - } else if (argc == 3) { + } else if (argv.size() == 3) { return EvaluateValue(state, argv[2]); } return StringValue(""); } -Value* AbortFn(const char* name, State* state, int argc, Expr* argv[]) { +Value* AbortFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { std::string msg; - if (argc > 0 && Evaluate(state, argv[0], &msg)) { + if (!argv.empty() && Evaluate(state, argv[0], &msg)) { state->errmsg = msg; } else { state->errmsg = "called abort()"; @@ -119,8 +119,8 @@ Value* AbortFn(const char* name, State* state, int argc, Expr* argv[]) { return nullptr; } -Value* AssertFn(const char* name, State* state, int argc, Expr* argv[]) { - for (int i = 0; i < argc; ++i) { +Value* AssertFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { + for (size_t i = 0; i < argv.size(); ++i) { std::string result; if (!Evaluate(state, argv[i], &result)) { return nullptr; @@ -134,7 +134,7 @@ Value* AssertFn(const char* name, State* state, int argc, Expr* argv[]) { return StringValue(""); } -Value* SleepFn(const char* name, State* state, int argc, Expr* argv[]) { +Value* SleepFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { std::string val; if (!Evaluate(state, argv[0], &val)) { return nullptr; @@ -149,8 +149,8 @@ Value* SleepFn(const char* name, State* state, int argc, Expr* argv[]) { return StringValue(val); } -Value* StdoutFn(const char* name, State* state, int argc, Expr* argv[]) { - for (int i = 0; i < argc; ++i) { +Value* StdoutFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { + for (size_t i = 0; i < argv.size(); ++i) { std::string v; if (!Evaluate(state, argv[i], &v)) { return nullptr; @@ -161,7 +161,7 @@ Value* StdoutFn(const char* name, State* state, int argc, Expr* argv[]) { } Value* LogicalAndFn(const char* name, State* state, - int argc, Expr* argv[]) { + const std::vector<std::unique_ptr<Expr>>& argv) { std::string left; if (!Evaluate(state, argv[0], &left)) { return nullptr; @@ -174,7 +174,7 @@ Value* LogicalAndFn(const char* name, State* state, } Value* LogicalOrFn(const char* name, State* state, - int argc, Expr* argv[]) { + const std::vector<std::unique_ptr<Expr>>& argv) { std::string left; if (!Evaluate(state, argv[0], &left)) { return nullptr; @@ -187,7 +187,7 @@ Value* LogicalOrFn(const char* name, State* state, } Value* LogicalNotFn(const char* name, State* state, - int argc, Expr* argv[]) { + const std::vector<std::unique_ptr<Expr>>& argv) { std::string val; if (!Evaluate(state, argv[0], &val)) { return nullptr; @@ -197,7 +197,7 @@ Value* LogicalNotFn(const char* name, State* state, } Value* SubstringFn(const char* name, State* state, - int argc, Expr* argv[]) { + const std::vector<std::unique_ptr<Expr>>& argv) { std::string needle; if (!Evaluate(state, argv[0], &needle)) { return nullptr; @@ -212,7 +212,7 @@ Value* SubstringFn(const char* name, State* state, return StringValue(result); } -Value* EqualityFn(const char* name, State* state, int argc, Expr* argv[]) { +Value* EqualityFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { std::string left; if (!Evaluate(state, argv[0], &left)) { return nullptr; @@ -226,7 +226,8 @@ Value* EqualityFn(const char* name, State* state, int argc, Expr* argv[]) { return StringValue(result); } -Value* InequalityFn(const char* name, State* state, int argc, Expr* argv[]) { +Value* InequalityFn(const char* name, State* state, + const std::vector<std::unique_ptr<Expr>>& argv) { std::string left; if (!Evaluate(state, argv[0], &left)) { return nullptr; @@ -240,7 +241,7 @@ Value* InequalityFn(const char* name, State* state, int argc, Expr* argv[]) { return StringValue(result); } -Value* SequenceFn(const char* name, State* state, int argc, Expr* argv[]) { +Value* SequenceFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { std::unique_ptr<Value> left(EvaluateValue(state, argv[0])); if (!left) { return nullptr; @@ -248,14 +249,15 @@ Value* SequenceFn(const char* name, State* state, int argc, Expr* argv[]) { return EvaluateValue(state, argv[1]); } -Value* LessThanIntFn(const char* name, State* state, int argc, Expr* argv[]) { - if (argc != 2) { +Value* LessThanIntFn(const char* name, State* state, + const std::vector<std::unique_ptr<Expr>>& argv) { + if (argv.size() != 2) { state->errmsg = "less_than_int expects 2 arguments"; return nullptr; } std::vector<std::string> args; - if (!ReadArgs(state, 2, argv, &args)) { + if (!ReadArgs(state, argv, &args)) { return nullptr; } @@ -276,20 +278,34 @@ Value* LessThanIntFn(const char* name, State* state, int argc, Expr* argv[]) { } Value* GreaterThanIntFn(const char* name, State* state, - int argc, Expr* argv[]) { - if (argc != 2) { + const std::vector<std::unique_ptr<Expr>>& argv) { + if (argv.size() != 2) { state->errmsg = "greater_than_int expects 2 arguments"; return nullptr; } - Expr* temp[2]; - temp[0] = argv[1]; - temp[1] = argv[0]; + std::vector<std::string> args; + if (!ReadArgs(state, argv, &args)) { + return nullptr; + } + + // Parse up to at least long long or 64-bit integers. + int64_t l_int; + if (!android::base::ParseInt(args[0].c_str(), &l_int)) { + state->errmsg = "failed to parse int in " + args[0]; + return nullptr; + } + + int64_t r_int; + if (!android::base::ParseInt(args[1].c_str(), &r_int)) { + state->errmsg = "failed to parse int in " + args[1]; + return nullptr; + } - return LessThanIntFn(name, state, 2, temp); + return StringValue(l_int > r_int ? "t" : ""); } -Value* Literal(const char* name, State* state, int argc, Expr* argv[]) { +Value* Literal(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { return StringValue(name); } @@ -329,14 +345,22 @@ void RegisterBuiltins() { // convenience methods for functions // ----------------------------------------------------------------- -// Evaluate the expressions in argv, and put the results of strings in -// args. If any expression evaluates to nullptr, free the rest and return -// false. Return true on success. -bool ReadArgs(State* state, int argc, Expr* argv[], std::vector<std::string>* args) { +// Evaluate the expressions in argv, and put the results of strings in args. If any expression +// evaluates to nullptr, return false. Return true on success. +bool ReadArgs(State* state, const std::vector<std::unique_ptr<Expr>>& argv, + std::vector<std::string>* args) { + return ReadArgs(state, argv, args, 0, argv.size()); +} + +bool ReadArgs(State* state, const std::vector<std::unique_ptr<Expr>>& argv, + std::vector<std::string>* args, size_t start, size_t len) { if (args == nullptr) { return false; } - for (int i = 0; i < argc; ++i) { + if (len == 0 || start + len > argv.size()) { + return false; + } + for (size_t i = start; i < start + len; ++i) { std::string var; if (!Evaluate(state, argv[i], &var)) { args->clear(); @@ -347,15 +371,22 @@ bool ReadArgs(State* state, int argc, Expr* argv[], std::vector<std::string>* ar return true; } -// Evaluate the expressions in argv, and put the results of Value* in -// args. If any expression evaluate to nullptr, free the rest and return -// false. Return true on success. -bool ReadValueArgs(State* state, int argc, Expr* argv[], +// Evaluate the expressions in argv, and put the results of Value* in args. If any expression +// evaluate to nullptr, return false. Return true on success. +bool ReadValueArgs(State* state, const std::vector<std::unique_ptr<Expr>>& argv, std::vector<std::unique_ptr<Value>>* args) { + return ReadValueArgs(state, argv, args, 0, argv.size()); +} + +bool ReadValueArgs(State* state, const std::vector<std::unique_ptr<Expr>>& argv, + std::vector<std::unique_ptr<Value>>* args, size_t start, size_t len) { if (args == nullptr) { return false; } - for (int i = 0; i < argc; ++i) { + if (len == 0 || start + len > argv.size()) { + return false; + } + for (size_t i = start; i < start + len; ++i) { std::unique_ptr<Value> v(EvaluateValue(state, argv[i])); if (!v) { args->clear(); |