Home | History | Annotate | Download | only in edify
      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