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