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 printf("[%s] is not an int\n", left); 291 goto done; 292 } 293 294 long r_int = strtol(right, &end, 10); 295 if (right[0] == '\0' || *end != '\0') { 296 printf("[%s] is not an int\n", right); 297 goto done; 298 } 299 300 result = l_int < r_int; 301 302 done: 303 free(left); 304 free(right); 305 return StringValue(strdup(result ? "t" : "")); 306 } 307 308 Value* GreaterThanIntFn(const char* name, State* state, 309 int argc, Expr* argv[]) { 310 if (argc != 2) { 311 free(state->errmsg); 312 state->errmsg = strdup("greater_than_int expects 2 arguments"); 313 return NULL; 314 } 315 316 Expr* temp[2]; 317 temp[0] = argv[1]; 318 temp[1] = argv[0]; 319 320 return LessThanIntFn(name, state, 2, temp); 321 } 322 323 Value* Literal(const char* name, State* state, int argc, Expr* argv[]) { 324 return StringValue(strdup(name)); 325 } 326 327 Expr* Build(Function fn, YYLTYPE loc, int count, ...) { 328 va_list v; 329 va_start(v, count); 330 Expr* e = malloc(sizeof(Expr)); 331 e->fn = fn; 332 e->name = "(operator)"; 333 e->argc = count; 334 e->argv = malloc(count * sizeof(Expr*)); 335 int i; 336 for (i = 0; i < count; ++i) { 337 e->argv[i] = va_arg(v, Expr*); 338 } 339 va_end(v); 340 e->start = loc.start; 341 e->end = loc.end; 342 return e; 343 } 344 345 // ----------------------------------------------------------------- 346 // the function table 347 // ----------------------------------------------------------------- 348 349 static int fn_entries = 0; 350 static int fn_size = 0; 351 NamedFunction* fn_table = NULL; 352 353 void RegisterFunction(const char* name, Function fn) { 354 if (fn_entries >= fn_size) { 355 fn_size = fn_size*2 + 1; 356 fn_table = realloc(fn_table, fn_size * sizeof(NamedFunction)); 357 } 358 fn_table[fn_entries].name = name; 359 fn_table[fn_entries].fn = fn; 360 ++fn_entries; 361 } 362 363 static int fn_entry_compare(const void* a, const void* b) { 364 const char* na = ((const NamedFunction*)a)->name; 365 const char* nb = ((const NamedFunction*)b)->name; 366 return strcmp(na, nb); 367 } 368 369 void FinishRegistration() { 370 qsort(fn_table, fn_entries, sizeof(NamedFunction), fn_entry_compare); 371 } 372 373 Function FindFunction(const char* name) { 374 NamedFunction key; 375 key.name = name; 376 NamedFunction* nf = bsearch(&key, fn_table, fn_entries, 377 sizeof(NamedFunction), fn_entry_compare); 378 if (nf == NULL) { 379 return NULL; 380 } 381 return nf->fn; 382 } 383 384 void RegisterBuiltins() { 385 RegisterFunction("ifelse", IfElseFn); 386 RegisterFunction("abort", AbortFn); 387 RegisterFunction("assert", AssertFn); 388 RegisterFunction("concat", ConcatFn); 389 RegisterFunction("is_substring", SubstringFn); 390 RegisterFunction("stdout", StdoutFn); 391 RegisterFunction("sleep", SleepFn); 392 393 RegisterFunction("less_than_int", LessThanIntFn); 394 RegisterFunction("greater_than_int", GreaterThanIntFn); 395 } 396 397 398 // ----------------------------------------------------------------- 399 // convenience methods for functions 400 // ----------------------------------------------------------------- 401 402 // Evaluate the expressions in argv, giving 'count' char* (the ... is 403 // zero or more char** to put them in). If any expression evaluates 404 // to NULL, free the rest and return -1. Return 0 on success. 405 int ReadArgs(State* state, Expr* argv[], int count, ...) { 406 char** args = malloc(count * sizeof(char*)); 407 va_list v; 408 va_start(v, count); 409 int i; 410 for (i = 0; i < count; ++i) { 411 args[i] = Evaluate(state, argv[i]); 412 if (args[i] == NULL) { 413 va_end(v); 414 int j; 415 for (j = 0; j < i; ++j) { 416 free(args[j]); 417 } 418 free(args); 419 return -1; 420 } 421 *(va_arg(v, char**)) = args[i]; 422 } 423 va_end(v); 424 free(args); 425 return 0; 426 } 427 428 // Evaluate the expressions in argv, giving 'count' Value* (the ... is 429 // zero or more Value** to put them in). If any expression evaluates 430 // to NULL, free the rest and return -1. Return 0 on success. 431 int ReadValueArgs(State* state, Expr* argv[], int count, ...) { 432 Value** args = malloc(count * sizeof(Value*)); 433 va_list v; 434 va_start(v, count); 435 int i; 436 for (i = 0; i < count; ++i) { 437 args[i] = EvaluateValue(state, argv[i]); 438 if (args[i] == NULL) { 439 va_end(v); 440 int j; 441 for (j = 0; j < i; ++j) { 442 FreeValue(args[j]); 443 } 444 free(args); 445 return -1; 446 } 447 *(va_arg(v, Value**)) = args[i]; 448 } 449 va_end(v); 450 free(args); 451 return 0; 452 } 453 454 // Evaluate the expressions in argv, returning an array of char* 455 // results. If any evaluate to NULL, free the rest and return NULL. 456 // The caller is responsible for freeing the returned array and the 457 // strings it contains. 458 char** ReadVarArgs(State* state, int argc, Expr* argv[]) { 459 char** args = (char**)malloc(argc * sizeof(char*)); 460 int i = 0; 461 for (i = 0; i < argc; ++i) { 462 args[i] = Evaluate(state, argv[i]); 463 if (args[i] == NULL) { 464 int j; 465 for (j = 0; j < i; ++j) { 466 free(args[j]); 467 } 468 free(args); 469 return NULL; 470 } 471 } 472 return args; 473 } 474 475 // Evaluate the expressions in argv, returning an array of Value* 476 // results. If any evaluate to NULL, free the rest and return NULL. 477 // The caller is responsible for freeing the returned array and the 478 // Values it contains. 479 Value** ReadValueVarArgs(State* state, int argc, Expr* argv[]) { 480 Value** args = (Value**)malloc(argc * sizeof(Value*)); 481 int i = 0; 482 for (i = 0; i < argc; ++i) { 483 args[i] = EvaluateValue(state, argv[i]); 484 if (args[i] == NULL) { 485 int j; 486 for (j = 0; j < i; ++j) { 487 FreeValue(args[j]); 488 } 489 free(args); 490 return NULL; 491 } 492 } 493 return args; 494 } 495 496 // Use printf-style arguments to compose an error message to put into 497 // *state. Returns NULL. 498 Value* ErrorAbort(State* state, const char* format, ...) { 499 char* buffer = malloc(4096); 500 va_list v; 501 va_start(v, format); 502 vsnprintf(buffer, 4096, format, v); 503 va_end(v); 504 free(state->errmsg); 505 state->errmsg = buffer; 506 return NULL; 507 } 508