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 <string.h> 18 #include <stdbool.h> 19 #include <stdio.h> 20 #include <stdlib.h> 21 #include <stdarg.h> 22 #include <unistd.h> 23 24 #include "expr.h" 25 26 // Functions should: 27 // 28 // - return a malloc()'d string 29 // - if Evaluate() on any argument returns NULL, return NULL. 30 31 int BooleanString(const char* s) { 32 return s[0] != '\0'; 33 } 34 35 char* Evaluate(State* state, Expr* expr) { 36 Value* v = expr->fn(expr->name, state, expr->argc, expr->argv); 37 if (v == NULL) return NULL; 38 if (v->type != VAL_STRING) { 39 ErrorAbort(state, "expecting string, got value type %d", v->type); 40 FreeValue(v); 41 return NULL; 42 } 43 char* result = v->data; 44 free(v); 45 return result; 46 } 47 48 Value* EvaluateValue(State* state, Expr* expr) { 49 return expr->fn(expr->name, state, expr->argc, expr->argv); 50 } 51 52 Value* StringValue(char* str) { 53 if (str == NULL) return NULL; 54 Value* v = malloc(sizeof(Value)); 55 v->type = VAL_STRING; 56 v->size = strlen(str); 57 v->data = str; 58 return v; 59 } 60 61 void FreeValue(Value* v) { 62 if (v == NULL) return; 63 free(v->data); 64 free(v); 65 } 66 67 Value* ConcatFn(const char* name, State* state, int argc, Expr* argv[]) { 68 if (argc == 0) { 69 return StringValue(strdup("")); 70 } 71 char** strings = malloc(argc * sizeof(char*)); 72 int i; 73 for (i = 0; i < argc; ++i) { 74 strings[i] = NULL; 75 } 76 char* result = NULL; 77 int length = 0; 78 for (i = 0; i < argc; ++i) { 79 strings[i] = Evaluate(state, argv[i]); 80 if (strings[i] == NULL) { 81 goto done; 82 } 83 length += strlen(strings[i]); 84 } 85 86 result = malloc(length+1); 87 int p = 0; 88 for (i = 0; i < argc; ++i) { 89 strcpy(result+p, strings[i]); 90 p += strlen(strings[i]); 91 } 92 result[p] = '\0'; 93 94 done: 95 for (i = 0; i < argc; ++i) { 96 free(strings[i]); 97 } 98 free(strings); 99 return StringValue(result); 100 } 101 102 Value* IfElseFn(const char* name, State* state, int argc, Expr* argv[]) { 103 if (argc != 2 && argc != 3) { 104 free(state->errmsg); 105 state->errmsg = strdup("ifelse expects 2 or 3 arguments"); 106 return NULL; 107 } 108 char* cond = Evaluate(state, argv[0]); 109 if (cond == NULL) { 110 return NULL; 111 } 112 113 if (BooleanString(cond) == true) { 114 free(cond); 115 return EvaluateValue(state, argv[1]); 116 } else { 117 if (argc == 3) { 118 free(cond); 119 return EvaluateValue(state, argv[2]); 120 } else { 121 return StringValue(cond); 122 } 123 } 124 } 125 126 Value* AbortFn(const char* name, State* state, int argc, Expr* argv[]) { 127 char* msg = NULL; 128 if (argc > 0) { 129 msg = Evaluate(state, argv[0]); 130 } 131 free(state->errmsg); 132 if (msg) { 133 state->errmsg = msg; 134 } else { 135 state->errmsg = strdup("called abort()"); 136 } 137 return NULL; 138 } 139 140 Value* AssertFn(const char* name, State* state, int argc, Expr* argv[]) { 141 int i; 142 for (i = 0; i < argc; ++i) { 143 char* v = Evaluate(state, argv[i]); 144 if (v == NULL) { 145 return NULL; 146 } 147 int b = BooleanString(v); 148 free(v); 149 if (!b) { 150 int prefix_len; 151 int len = argv[i]->end - argv[i]->start; 152 char* err_src = malloc(len + 20); 153 strcpy(err_src, "assert failed: "); 154 prefix_len = strlen(err_src); 155 memcpy(err_src + prefix_len, state->script + argv[i]->start, len); 156 err_src[prefix_len + len] = '\0'; 157 free(state->errmsg); 158 state->errmsg = err_src; 159 return NULL; 160 } 161 } 162 return StringValue(strdup("")); 163 } 164 165 Value* SleepFn(const char* name, State* state, int argc, Expr* argv[]) { 166 char* val = Evaluate(state, argv[0]); 167 if (val == NULL) { 168 return NULL; 169 } 170 int v = strtol(val, NULL, 10); 171 sleep(v); 172 return StringValue(val); 173 } 174 175 Value* StdoutFn(const char* name, State* state, int argc, Expr* argv[]) { 176 int i; 177 for (i = 0; i < argc; ++i) { 178 char* v = Evaluate(state, argv[i]); 179 if (v == NULL) { 180 return NULL; 181 } 182 fputs(v, stdout); 183 free(v); 184 } 185 return StringValue(strdup("")); 186 } 187 188 Value* LogicalAndFn(const char* name, State* state, 189 int argc, Expr* argv[]) { 190 char* left = Evaluate(state, argv[0]); 191 if (left == NULL) return NULL; 192 if (BooleanString(left) == true) { 193 free(left); 194 return EvaluateValue(state, argv[1]); 195 } else { 196 return StringValue(left); 197 } 198 } 199 200 Value* LogicalOrFn(const char* name, State* state, 201 int argc, Expr* argv[]) { 202 char* left = Evaluate(state, argv[0]); 203 if (left == NULL) return NULL; 204 if (BooleanString(left) == false) { 205 free(left); 206 return EvaluateValue(state, argv[1]); 207 } else { 208 return StringValue(left); 209 } 210 } 211 212 Value* LogicalNotFn(const char* name, State* state, 213 int argc, Expr* argv[]) { 214 char* val = Evaluate(state, argv[0]); 215 if (val == NULL) return NULL; 216 bool bv = BooleanString(val); 217 free(val); 218 return StringValue(strdup(bv ? "" : "t")); 219 } 220 221 Value* SubstringFn(const char* name, State* state, 222 int argc, Expr* argv[]) { 223 char* needle = Evaluate(state, argv[0]); 224 if (needle == NULL) return NULL; 225 char* haystack = Evaluate(state, argv[1]); 226 if (haystack == NULL) { 227 free(needle); 228 return NULL; 229 } 230 231 char* result = strdup(strstr(haystack, needle) ? "t" : ""); 232 free(needle); 233 free(haystack); 234 return StringValue(result); 235 } 236 237 Value* EqualityFn(const char* name, State* state, int argc, Expr* argv[]) { 238 char* left = Evaluate(state, argv[0]); 239 if (left == NULL) return NULL; 240 char* right = Evaluate(state, argv[1]); 241 if (right == NULL) { 242 free(left); 243 return NULL; 244 } 245 246 char* result = strdup(strcmp(left, right) == 0 ? "t" : ""); 247 free(left); 248 free(right); 249 return StringValue(result); 250 } 251 252 Value* InequalityFn(const char* name, State* state, int argc, Expr* argv[]) { 253 char* left = Evaluate(state, argv[0]); 254 if (left == NULL) return NULL; 255 char* right = Evaluate(state, argv[1]); 256 if (right == NULL) { 257 free(left); 258 return NULL; 259 } 260 261 char* result = strdup(strcmp(left, right) != 0 ? "t" : ""); 262 free(left); 263 free(right); 264 return StringValue(result); 265 } 266 267 Value* SequenceFn(const char* name, State* state, int argc, Expr* argv[]) { 268 Value* left = EvaluateValue(state, argv[0]); 269 if (left == NULL) return NULL; 270 FreeValue(left); 271 return EvaluateValue(state, argv[1]); 272 } 273 274 Value* LessThanIntFn(const char* name, State* state, int argc, Expr* argv[]) { 275 if (argc != 2) { 276 free(state->errmsg); 277 state->errmsg = strdup("less_than_int expects 2 arguments"); 278 return NULL; 279 } 280 281 char* left; 282 char* right; 283 if (ReadArgs(state, argv, 2, &left, &right) < 0) return NULL; 284 285 bool result = false; 286 char* end; 287 288 long l_int = strtol(left, &end, 10); 289 if (left[0] == '\0' || *end != '\0') { 290 goto done; 291 } 292 293 long r_int = strtol(right, &end, 10); 294 if (right[0] == '\0' || *end != '\0') { 295 goto done; 296 } 297 298 result = l_int < r_int; 299 300 done: 301 free(left); 302 free(right); 303 return StringValue(strdup(result ? "t" : "")); 304 } 305 306 Value* GreaterThanIntFn(const char* name, State* state, 307 int argc, Expr* argv[]) { 308 if (argc != 2) { 309 free(state->errmsg); 310 state->errmsg = strdup("greater_than_int expects 2 arguments"); 311 return NULL; 312 } 313 314 Expr* temp[2]; 315 temp[0] = argv[1]; 316 temp[1] = argv[0]; 317 318 return LessThanIntFn(name, state, 2, temp); 319 } 320 321 Value* Literal(const char* name, State* state, int argc, Expr* argv[]) { 322 return StringValue(strdup(name)); 323 } 324 325 Expr* Build(Function fn, YYLTYPE loc, int count, ...) { 326 va_list v; 327 va_start(v, count); 328 Expr* e = malloc(sizeof(Expr)); 329 e->fn = fn; 330 e->name = "(operator)"; 331 e->argc = count; 332 e->argv = malloc(count * sizeof(Expr*)); 333 int i; 334 for (i = 0; i < count; ++i) { 335 e->argv[i] = va_arg(v, Expr*); 336 } 337 va_end(v); 338 e->start = loc.start; 339 e->end = loc.end; 340 return e; 341 } 342 343 // ----------------------------------------------------------------- 344 // the function table 345 // ----------------------------------------------------------------- 346 347 static int fn_entries = 0; 348 static int fn_size = 0; 349 NamedFunction* fn_table = NULL; 350 351 void RegisterFunction(const char* name, Function fn) { 352 if (fn_entries >= fn_size) { 353 fn_size = fn_size*2 + 1; 354 fn_table = realloc(fn_table, fn_size * sizeof(NamedFunction)); 355 } 356 fn_table[fn_entries].name = name; 357 fn_table[fn_entries].fn = fn; 358 ++fn_entries; 359 } 360 361 static int fn_entry_compare(const void* a, const void* b) { 362 const char* na = ((const NamedFunction*)a)->name; 363 const char* nb = ((const NamedFunction*)b)->name; 364 return strcmp(na, nb); 365 } 366 367 void FinishRegistration() { 368 qsort(fn_table, fn_entries, sizeof(NamedFunction), fn_entry_compare); 369 } 370 371 Function FindFunction(const char* name) { 372 NamedFunction key; 373 key.name = name; 374 NamedFunction* nf = bsearch(&key, fn_table, fn_entries, 375 sizeof(NamedFunction), fn_entry_compare); 376 if (nf == NULL) { 377 return NULL; 378 } 379 return nf->fn; 380 } 381 382 void RegisterBuiltins() { 383 RegisterFunction("ifelse", IfElseFn); 384 RegisterFunction("abort", AbortFn); 385 RegisterFunction("assert", AssertFn); 386 RegisterFunction("concat", ConcatFn); 387 RegisterFunction("is_substring", SubstringFn); 388 RegisterFunction("stdout", StdoutFn); 389 RegisterFunction("sleep", SleepFn); 390 391 RegisterFunction("less_than_int", LessThanIntFn); 392 RegisterFunction("greater_than_int", GreaterThanIntFn); 393 } 394 395 396 // ----------------------------------------------------------------- 397 // convenience methods for functions 398 // ----------------------------------------------------------------- 399 400 // Evaluate the expressions in argv, giving 'count' char* (the ... is 401 // zero or more char** to put them in). If any expression evaluates 402 // to NULL, free the rest and return -1. Return 0 on success. 403 int ReadArgs(State* state, Expr* argv[], int count, ...) { 404 char** args = malloc(count * sizeof(char*)); 405 va_list v; 406 va_start(v, count); 407 int i; 408 for (i = 0; i < count; ++i) { 409 args[i] = Evaluate(state, argv[i]); 410 if (args[i] == NULL) { 411 va_end(v); 412 int j; 413 for (j = 0; j < i; ++j) { 414 free(args[j]); 415 } 416 free(args); 417 return -1; 418 } 419 *(va_arg(v, char**)) = args[i]; 420 } 421 va_end(v); 422 free(args); 423 return 0; 424 } 425 426 // Evaluate the expressions in argv, giving 'count' Value* (the ... is 427 // zero or more Value** to put them in). If any expression evaluates 428 // to NULL, free the rest and return -1. Return 0 on success. 429 int ReadValueArgs(State* state, Expr* argv[], int count, ...) { 430 Value** args = malloc(count * sizeof(Value*)); 431 va_list v; 432 va_start(v, count); 433 int i; 434 for (i = 0; i < count; ++i) { 435 args[i] = EvaluateValue(state, argv[i]); 436 if (args[i] == NULL) { 437 va_end(v); 438 int j; 439 for (j = 0; j < i; ++j) { 440 FreeValue(args[j]); 441 } 442 free(args); 443 return -1; 444 } 445 *(va_arg(v, Value**)) = args[i]; 446 } 447 va_end(v); 448 free(args); 449 return 0; 450 } 451 452 // Evaluate the expressions in argv, returning an array of char* 453 // results. If any evaluate to NULL, free the rest and return NULL. 454 // The caller is responsible for freeing the returned array and the 455 // strings it contains. 456 char** ReadVarArgs(State* state, int argc, Expr* argv[]) { 457 char** args = (char**)malloc(argc * sizeof(char*)); 458 int i = 0; 459 for (i = 0; i < argc; ++i) { 460 args[i] = Evaluate(state, argv[i]); 461 if (args[i] == NULL) { 462 int j; 463 for (j = 0; j < i; ++j) { 464 free(args[j]); 465 } 466 free(args); 467 return NULL; 468 } 469 } 470 return args; 471 } 472 473 // Evaluate the expressions in argv, returning an array of Value* 474 // results. If any evaluate to NULL, free the rest and return NULL. 475 // The caller is responsible for freeing the returned array and the 476 // Values it contains. 477 Value** ReadValueVarArgs(State* state, int argc, Expr* argv[]) { 478 Value** args = (Value**)malloc(argc * sizeof(Value*)); 479 int i = 0; 480 for (i = 0; i < argc; ++i) { 481 args[i] = EvaluateValue(state, argv[i]); 482 if (args[i] == NULL) { 483 int j; 484 for (j = 0; j < i; ++j) { 485 FreeValue(args[j]); 486 } 487 free(args); 488 return NULL; 489 } 490 } 491 return args; 492 } 493 494 // Use printf-style arguments to compose an error message to put into 495 // *state. Returns NULL. 496 Value* ErrorAbort(State* state, const char* format, ...) { 497 char* buffer = malloc(4096); 498 va_list v; 499 va_start(v, format); 500 vsnprintf(buffer, 4096, format, v); 501 va_end(v); 502 free(state->errmsg); 503 state->errmsg = buffer; 504 return NULL; 505 } 506