1 /* 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 17 #include "edify/expr.h" 18 19 #include <stdarg.h> 20 #include <stdio.h> 21 #include <stdlib.h> 22 #include <string.h> 23 #include <unistd.h> 24 25 #include <memory> 26 #include <string> 27 #include <unordered_map> 28 #include <vector> 29 30 #include <android-base/parseint.h> 31 #include <android-base/stringprintf.h> 32 #include <android-base/strings.h> 33 34 #include "otautil/error_code.h" 35 36 // Functions should: 37 // 38 // - return a malloc()'d string 39 // - if Evaluate() on any argument returns nullptr, return nullptr. 40 41 static bool BooleanString(const std::string& s) { 42 return !s.empty(); 43 } 44 45 bool Evaluate(State* state, const std::unique_ptr<Expr>& expr, std::string* result) { 46 if (result == nullptr) { 47 return false; 48 } 49 50 std::unique_ptr<Value> v(expr->fn(expr->name.c_str(), state, expr->argv)); 51 if (!v) { 52 return false; 53 } 54 if (v->type != Value::Type::STRING) { 55 ErrorAbort(state, kArgsParsingFailure, "expecting string, got value type %d", v->type); 56 return false; 57 } 58 59 *result = v->data; 60 return true; 61 } 62 63 Value* EvaluateValue(State* state, const std::unique_ptr<Expr>& expr) { 64 return expr->fn(expr->name.c_str(), state, expr->argv); 65 } 66 67 Value* StringValue(const char* str) { 68 if (str == nullptr) { 69 return nullptr; 70 } 71 return new Value(Value::Type::STRING, str); 72 } 73 74 Value* StringValue(const std::string& str) { 75 return StringValue(str.c_str()); 76 } 77 78 Value* ConcatFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { 79 if (argv.empty()) { 80 return StringValue(""); 81 } 82 std::string result; 83 for (size_t i = 0; i < argv.size(); ++i) { 84 std::string str; 85 if (!Evaluate(state, argv[i], &str)) { 86 return nullptr; 87 } 88 result += str; 89 } 90 91 return StringValue(result); 92 } 93 94 Value* IfElseFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { 95 if (argv.size() != 2 && argv.size() != 3) { 96 state->errmsg = "ifelse expects 2 or 3 arguments"; 97 return nullptr; 98 } 99 100 std::string cond; 101 if (!Evaluate(state, argv[0], &cond)) { 102 return nullptr; 103 } 104 105 if (!cond.empty()) { 106 return EvaluateValue(state, argv[1]); 107 } else if (argv.size() == 3) { 108 return EvaluateValue(state, argv[2]); 109 } 110 111 return StringValue(""); 112 } 113 114 Value* AbortFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { 115 std::string msg; 116 if (!argv.empty() && Evaluate(state, argv[0], &msg)) { 117 state->errmsg += msg; 118 } else { 119 state->errmsg += "called abort()"; 120 } 121 return nullptr; 122 } 123 124 Value* AssertFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { 125 for (size_t i = 0; i < argv.size(); ++i) { 126 std::string result; 127 if (!Evaluate(state, argv[i], &result)) { 128 return nullptr; 129 } 130 if (result.empty()) { 131 int len = argv[i]->end - argv[i]->start; 132 state->errmsg = "assert failed: " + state->script.substr(argv[i]->start, len); 133 return nullptr; 134 } 135 } 136 return StringValue(""); 137 } 138 139 Value* SleepFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { 140 std::string val; 141 if (!Evaluate(state, argv[0], &val)) { 142 return nullptr; 143 } 144 145 int v; 146 if (!android::base::ParseInt(val.c_str(), &v, 0)) { 147 return nullptr; 148 } 149 sleep(v); 150 151 return StringValue(val); 152 } 153 154 Value* StdoutFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { 155 for (size_t i = 0; i < argv.size(); ++i) { 156 std::string v; 157 if (!Evaluate(state, argv[i], &v)) { 158 return nullptr; 159 } 160 fputs(v.c_str(), stdout); 161 } 162 return StringValue(""); 163 } 164 165 Value* LogicalAndFn(const char* name, State* state, 166 const std::vector<std::unique_ptr<Expr>>& argv) { 167 std::string left; 168 if (!Evaluate(state, argv[0], &left)) { 169 return nullptr; 170 } 171 if (BooleanString(left)) { 172 return EvaluateValue(state, argv[1]); 173 } else { 174 return StringValue(""); 175 } 176 } 177 178 Value* LogicalOrFn(const char* name, State* state, 179 const std::vector<std::unique_ptr<Expr>>& argv) { 180 std::string left; 181 if (!Evaluate(state, argv[0], &left)) { 182 return nullptr; 183 } 184 if (!BooleanString(left)) { 185 return EvaluateValue(state, argv[1]); 186 } else { 187 return StringValue(left); 188 } 189 } 190 191 Value* LogicalNotFn(const char* name, State* state, 192 const std::vector<std::unique_ptr<Expr>>& argv) { 193 std::string val; 194 if (!Evaluate(state, argv[0], &val)) { 195 return nullptr; 196 } 197 198 return StringValue(BooleanString(val) ? "" : "t"); 199 } 200 201 Value* SubstringFn(const char* name, State* state, 202 const std::vector<std::unique_ptr<Expr>>& argv) { 203 std::string needle; 204 if (!Evaluate(state, argv[0], &needle)) { 205 return nullptr; 206 } 207 208 std::string haystack; 209 if (!Evaluate(state, argv[1], &haystack)) { 210 return nullptr; 211 } 212 213 std::string result = (haystack.find(needle) != std::string::npos) ? "t" : ""; 214 return StringValue(result); 215 } 216 217 Value* EqualityFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { 218 std::string left; 219 if (!Evaluate(state, argv[0], &left)) { 220 return nullptr; 221 } 222 std::string right; 223 if (!Evaluate(state, argv[1], &right)) { 224 return nullptr; 225 } 226 227 const char* result = (left == right) ? "t" : ""; 228 return StringValue(result); 229 } 230 231 Value* InequalityFn(const char* name, State* state, 232 const std::vector<std::unique_ptr<Expr>>& argv) { 233 std::string left; 234 if (!Evaluate(state, argv[0], &left)) { 235 return nullptr; 236 } 237 std::string right; 238 if (!Evaluate(state, argv[1], &right)) { 239 return nullptr; 240 } 241 242 const char* result = (left != right) ? "t" : ""; 243 return StringValue(result); 244 } 245 246 Value* SequenceFn(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { 247 std::unique_ptr<Value> left(EvaluateValue(state, argv[0])); 248 if (!left) { 249 return nullptr; 250 } 251 return EvaluateValue(state, argv[1]); 252 } 253 254 Value* LessThanIntFn(const char* name, State* state, 255 const std::vector<std::unique_ptr<Expr>>& argv) { 256 if (argv.size() != 2) { 257 state->errmsg = "less_than_int expects 2 arguments"; 258 return nullptr; 259 } 260 261 std::vector<std::string> args; 262 if (!ReadArgs(state, argv, &args)) { 263 return nullptr; 264 } 265 266 // Parse up to at least long long or 64-bit integers. 267 int64_t l_int; 268 if (!android::base::ParseInt(args[0].c_str(), &l_int)) { 269 state->errmsg = "failed to parse int in " + args[0]; 270 return nullptr; 271 } 272 273 int64_t r_int; 274 if (!android::base::ParseInt(args[1].c_str(), &r_int)) { 275 state->errmsg = "failed to parse int in " + args[1]; 276 return nullptr; 277 } 278 279 return StringValue(l_int < r_int ? "t" : ""); 280 } 281 282 Value* GreaterThanIntFn(const char* name, State* state, 283 const std::vector<std::unique_ptr<Expr>>& argv) { 284 if (argv.size() != 2) { 285 state->errmsg = "greater_than_int expects 2 arguments"; 286 return nullptr; 287 } 288 289 std::vector<std::string> args; 290 if (!ReadArgs(state, argv, &args)) { 291 return nullptr; 292 } 293 294 // Parse up to at least long long or 64-bit integers. 295 int64_t l_int; 296 if (!android::base::ParseInt(args[0].c_str(), &l_int)) { 297 state->errmsg = "failed to parse int in " + args[0]; 298 return nullptr; 299 } 300 301 int64_t r_int; 302 if (!android::base::ParseInt(args[1].c_str(), &r_int)) { 303 state->errmsg = "failed to parse int in " + args[1]; 304 return nullptr; 305 } 306 307 return StringValue(l_int > r_int ? "t" : ""); 308 } 309 310 Value* Literal(const char* name, State* state, const std::vector<std::unique_ptr<Expr>>& argv) { 311 return StringValue(name); 312 } 313 314 // ----------------------------------------------------------------- 315 // the function table 316 // ----------------------------------------------------------------- 317 318 static std::unordered_map<std::string, Function> fn_table; 319 320 void RegisterFunction(const std::string& name, Function fn) { 321 fn_table[name] = fn; 322 } 323 324 Function FindFunction(const std::string& name) { 325 if (fn_table.find(name) == fn_table.end()) { 326 return nullptr; 327 } else { 328 return fn_table[name]; 329 } 330 } 331 332 void RegisterBuiltins() { 333 RegisterFunction("ifelse", IfElseFn); 334 RegisterFunction("abort", AbortFn); 335 RegisterFunction("assert", AssertFn); 336 RegisterFunction("concat", ConcatFn); 337 RegisterFunction("is_substring", SubstringFn); 338 RegisterFunction("stdout", StdoutFn); 339 RegisterFunction("sleep", SleepFn); 340 341 RegisterFunction("less_than_int", LessThanIntFn); 342 RegisterFunction("greater_than_int", GreaterThanIntFn); 343 } 344 345 346 // ----------------------------------------------------------------- 347 // convenience methods for functions 348 // ----------------------------------------------------------------- 349 350 // Evaluate the expressions in argv, and put the results of strings in args. If any expression 351 // evaluates to nullptr, return false. Return true on success. 352 bool ReadArgs(State* state, const std::vector<std::unique_ptr<Expr>>& argv, 353 std::vector<std::string>* args) { 354 return ReadArgs(state, argv, args, 0, argv.size()); 355 } 356 357 bool ReadArgs(State* state, const std::vector<std::unique_ptr<Expr>>& argv, 358 std::vector<std::string>* args, size_t start, size_t len) { 359 if (args == nullptr) { 360 return false; 361 } 362 if (start + len > argv.size()) { 363 return false; 364 } 365 for (size_t i = start; i < start + len; ++i) { 366 std::string var; 367 if (!Evaluate(state, argv[i], &var)) { 368 args->clear(); 369 return false; 370 } 371 args->push_back(var); 372 } 373 return true; 374 } 375 376 // Evaluate the expressions in argv, and put the results of Value* in args. If any expression 377 // evaluate to nullptr, return false. Return true on success. 378 bool ReadValueArgs(State* state, const std::vector<std::unique_ptr<Expr>>& argv, 379 std::vector<std::unique_ptr<Value>>* args) { 380 return ReadValueArgs(state, argv, args, 0, argv.size()); 381 } 382 383 bool ReadValueArgs(State* state, const std::vector<std::unique_ptr<Expr>>& argv, 384 std::vector<std::unique_ptr<Value>>* args, size_t start, size_t len) { 385 if (args == nullptr) { 386 return false; 387 } 388 if (len == 0 || start + len > argv.size()) { 389 return false; 390 } 391 for (size_t i = start; i < start + len; ++i) { 392 std::unique_ptr<Value> v(EvaluateValue(state, argv[i])); 393 if (!v) { 394 args->clear(); 395 return false; 396 } 397 args->push_back(std::move(v)); 398 } 399 return true; 400 } 401 402 // Use printf-style arguments to compose an error message to put into 403 // *state. Returns nullptr. 404 Value* ErrorAbort(State* state, const char* format, ...) { 405 va_list ap; 406 va_start(ap, format); 407 android::base::StringAppendV(&state->errmsg, format, ap); 408 va_end(ap); 409 return nullptr; 410 } 411 412 Value* ErrorAbort(State* state, CauseCode cause_code, const char* format, ...) { 413 std::string err_message; 414 va_list ap; 415 va_start(ap, format); 416 android::base::StringAppendV(&err_message, format, ap); 417 va_end(ap); 418 // Ensure that there's exactly one line break at the end of the error message. 419 state->errmsg = android::base::Trim(err_message) + "\n"; 420 state->cause_code = cause_code; 421 return nullptr; 422 } 423 424 State::State(const std::string& script, void* cookie) 425 : script(script), cookie(cookie), error_code(kNoError), cause_code(kNoCause) {} 426