1 /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2 * Use of this source code is governed by a BSD-style license that can be 3 * found in the LICENSE file. 4 */ 5 6 #include <ctype.h> 7 #include <stdlib.h> 8 #include <syslog.h> 9 10 #include "array.h" 11 #include "cras_expr.h" 12 13 static const char *copy_str(const char *begin, const char *end) 14 { 15 char *s = malloc(end - begin + 1); 16 memcpy(s, begin, end - begin); 17 s[end - begin] = '\0'; 18 return s; 19 } 20 21 static void value_set_boolean(struct cras_expr_value *value, char boolean) 22 { 23 cras_expr_value_free(value); 24 value->type = CRAS_EXPR_VALUE_TYPE_BOOLEAN; 25 value->u.boolean = !!boolean; 26 } 27 28 static void value_set_integer(struct cras_expr_value *value, int integer) 29 { 30 cras_expr_value_free(value); 31 value->type = CRAS_EXPR_VALUE_TYPE_INT; 32 value->u.integer = integer; 33 } 34 35 static void value_set_string2(struct cras_expr_value *value, const char *begin, 36 const char *end) 37 { 38 cras_expr_value_free(value); 39 value->type = CRAS_EXPR_VALUE_TYPE_STRING; 40 value->u.string = copy_str(begin, end); 41 } 42 43 static void value_set_string(struct cras_expr_value *value, const char *str) 44 { 45 value_set_string2(value, str, str + strlen(str)); 46 } 47 48 static void cras_expr_value_set_function(struct cras_expr_value *value, 49 cras_expr_function_type function) 50 { 51 cras_expr_value_free(value); 52 value->type = CRAS_EXPR_VALUE_TYPE_FUNCTION; 53 value->u.function = function; 54 } 55 56 static void copy_value(struct cras_expr_value *value, 57 struct cras_expr_value *original) 58 { 59 cras_expr_value_free(value); /* free the original value first */ 60 value->type = original->type; 61 switch (value->type) { 62 case CRAS_EXPR_VALUE_TYPE_NONE: 63 break; 64 case CRAS_EXPR_VALUE_TYPE_BOOLEAN: 65 value->u.boolean = original->u.boolean; 66 break; 67 case CRAS_EXPR_VALUE_TYPE_INT: 68 value->u.integer = original->u.integer; 69 break; 70 case CRAS_EXPR_VALUE_TYPE_STRING: 71 value->u.string = strdup(original->u.string); 72 break; 73 case CRAS_EXPR_VALUE_TYPE_FUNCTION: 74 value->u.function = original->u.function; 75 break; 76 } 77 } 78 79 void cras_expr_value_free(struct cras_expr_value *value) 80 { 81 switch (value->type) { 82 case CRAS_EXPR_VALUE_TYPE_STRING: 83 free((char *)value->u.string); 84 value->u.string = NULL; 85 break; 86 case CRAS_EXPR_VALUE_TYPE_NONE: 87 case CRAS_EXPR_VALUE_TYPE_BOOLEAN: 88 case CRAS_EXPR_VALUE_TYPE_INT: 89 case CRAS_EXPR_VALUE_TYPE_FUNCTION: 90 break; 91 } 92 value->type = CRAS_EXPR_VALUE_TYPE_NONE; 93 } 94 95 void cras_expr_value_dump(struct dumper *d, const struct cras_expr_value *value) 96 { 97 switch (value->type) { 98 case CRAS_EXPR_VALUE_TYPE_NONE: 99 dumpf(d, "none"); 100 break; 101 case CRAS_EXPR_VALUE_TYPE_BOOLEAN: 102 dumpf(d, "boolean(%s)", 103 value->u.boolean ? "true" : "false"); 104 break; 105 case CRAS_EXPR_VALUE_TYPE_INT: 106 dumpf(d, "integer(%d)", value->u.integer); 107 break; 108 case CRAS_EXPR_VALUE_TYPE_STRING: 109 dumpf(d, "string(%s)", value->u.string); 110 break; 111 case CRAS_EXPR_VALUE_TYPE_FUNCTION: 112 dumpf(d, "function(%p)", value->u.function); 113 break; 114 } 115 } 116 117 static struct cras_expr_value *find_value(struct cras_expr_env *env, 118 const char *name) 119 { 120 int i; 121 const char **key; 122 123 FOR_ARRAY_ELEMENT(&env->keys, i, key) { 124 if (strcmp(*key, name) == 0) 125 return ARRAY_ELEMENT(&env->values, i); 126 } 127 return NULL; 128 } 129 130 /* Insert a (key, value) pair to the environment. The value is 131 * initialized to zero. Return the pointer to value so it can be set 132 * to the proper value. */ 133 static struct cras_expr_value *insert_value(struct cras_expr_env *env, 134 const char *key) 135 { 136 *ARRAY_APPEND_ZERO(&env->keys) = strdup(key); 137 return ARRAY_APPEND_ZERO(&env->values); 138 } 139 140 static struct cras_expr_value *find_or_insert_value(struct cras_expr_env *env, 141 const char *key) 142 { 143 struct cras_expr_value *value = find_value(env, key); 144 if (!value) 145 value = insert_value(env, key); 146 return value; 147 } 148 149 static void function_not(cras_expr_value_array *operands, 150 struct cras_expr_value *result) 151 { 152 struct cras_expr_value *value; 153 int is_false; 154 155 if (ARRAY_COUNT(operands) != 2) { 156 cras_expr_value_free(result); 157 syslog(LOG_ERR, "not takes one argument"); 158 return; 159 } 160 161 value = ARRAY_ELEMENT(operands, 1); 162 is_false = (value->type == CRAS_EXPR_VALUE_TYPE_BOOLEAN && 163 !value->u.boolean); 164 value_set_boolean(result, is_false); 165 } 166 167 static void function_and(cras_expr_value_array *operands, 168 struct cras_expr_value *result) 169 { 170 int i; 171 struct cras_expr_value *value; 172 int n = ARRAY_COUNT(operands); 173 174 /* no operands -- return #t */ 175 if (n <= 1) { 176 value_set_boolean(result, 1); 177 return; 178 } 179 180 /* if there is any #f, return it */ 181 FOR_ARRAY_ELEMENT(operands, i, value) { 182 if (i == 0) 183 continue; /* ignore "and" itself */ 184 if (value->type == CRAS_EXPR_VALUE_TYPE_BOOLEAN && 185 !value->u.boolean) { 186 value_set_boolean(result, 0); 187 return; 188 } 189 } 190 191 /* otherwise return the last element */ 192 copy_value(result, ARRAY_ELEMENT(operands, n - 1)); 193 } 194 195 static void function_or(cras_expr_value_array *operands, 196 struct cras_expr_value *result) 197 { 198 int i; 199 struct cras_expr_value *value; 200 201 FOR_ARRAY_ELEMENT(operands, i, value) { 202 if (i == 0) 203 continue; /* ignore "or" itself */ 204 if (value->type != CRAS_EXPR_VALUE_TYPE_BOOLEAN || 205 value->u.boolean) { 206 copy_value(result, value); 207 return; 208 } 209 } 210 211 value_set_boolean(result, 0); 212 } 213 214 static char function_equal_real(cras_expr_value_array *operands) 215 { 216 int i; 217 struct cras_expr_value *value, *prev; 218 219 FOR_ARRAY_ELEMENT(operands, i, value) { 220 if (i <= 1) 221 continue; /* ignore equal? and first operand */ 222 /* compare with the previous operand */ 223 224 prev = ARRAY_ELEMENT(operands, i - 1); 225 226 if (prev->type != value->type) 227 return 0; 228 229 switch (prev->type) { 230 case CRAS_EXPR_VALUE_TYPE_NONE: 231 break; 232 case CRAS_EXPR_VALUE_TYPE_BOOLEAN: 233 if (prev->u.boolean != value->u.boolean) 234 return 0; 235 break; 236 case CRAS_EXPR_VALUE_TYPE_INT: 237 if (prev->u.integer != value->u.integer) 238 return 0; 239 break; 240 case CRAS_EXPR_VALUE_TYPE_STRING: 241 if (strcmp(prev->u.string, value->u.string) != 0) 242 return 0; 243 break; 244 case CRAS_EXPR_VALUE_TYPE_FUNCTION: 245 if (prev->u.function != value->u.function) 246 return 0; 247 break; 248 } 249 } 250 251 return 1; 252 } 253 254 static void function_equal(cras_expr_value_array *operands, 255 struct cras_expr_value *result) 256 { 257 value_set_boolean(result, function_equal_real(operands)); 258 } 259 260 static void env_set_variable(struct cras_expr_env *env, const char *name, 261 struct cras_expr_value *new_value) 262 { 263 struct cras_expr_value *value = find_or_insert_value(env, name); 264 copy_value(value, new_value); 265 } 266 267 void cras_expr_env_install_builtins(struct cras_expr_env *env) 268 { 269 struct cras_expr_value value = CRAS_EXPR_VALUE_INIT; 270 271 /* initialize env with builtin functions */ 272 cras_expr_value_set_function(&value, &function_not); 273 env_set_variable(env, "not", &value); 274 275 cras_expr_value_set_function(&value, &function_and); 276 env_set_variable(env, "and", &value); 277 278 cras_expr_value_set_function(&value, &function_or); 279 env_set_variable(env, "or", &value); 280 281 cras_expr_value_set_function(&value, &function_equal); 282 env_set_variable(env, "equal?", &value); 283 284 cras_expr_value_free(&value); 285 } 286 287 void cras_expr_env_set_variable_boolean(struct cras_expr_env *env, 288 const char *name, char boolean) 289 { 290 struct cras_expr_value *value = find_or_insert_value(env, name); 291 value_set_boolean(value, boolean); 292 } 293 294 void cras_expr_env_set_variable_integer(struct cras_expr_env *env, 295 const char *name, int integer) 296 { 297 struct cras_expr_value *value = find_or_insert_value(env, name); 298 value_set_integer(value, integer); 299 } 300 301 void cras_expr_env_set_variable_string(struct cras_expr_env *env, 302 const char *name, const char *str) 303 { 304 struct cras_expr_value *value = find_or_insert_value(env, name); 305 value_set_string(value, str); 306 } 307 308 void cras_expr_env_free(struct cras_expr_env *env) 309 { 310 int i; 311 const char **key; 312 struct cras_expr_value *value; 313 314 FOR_ARRAY_ELEMENT(&env->keys, i, key) { 315 free((char *)*key); 316 } 317 318 FOR_ARRAY_ELEMENT(&env->values, i, value) { 319 cras_expr_value_free(value); 320 } 321 322 ARRAY_FREE(&env->keys); 323 ARRAY_FREE(&env->values); 324 } 325 326 void cras_expr_env_dump(struct dumper *d, const struct cras_expr_env *env) 327 { 328 int i; 329 const char **key; 330 struct cras_expr_value *value; 331 332 dumpf(d, "--- environment ---\n"); 333 FOR_ARRAY_ELEMENT(&env->keys, i, key) { 334 dumpf(d, " key=%s,", *key); 335 dumpf(d, " value="); 336 value = ARRAY_ELEMENT(&env->values, i); 337 cras_expr_value_dump(d, value); 338 dumpf(d, "\n"); 339 } 340 } 341 342 static struct cras_expr_expression *new_boolean_literal(char boolean) 343 { 344 struct cras_expr_expression *expr; 345 expr = calloc(1, sizeof(struct cras_expr_expression)); 346 expr->type = EXPR_TYPE_LITERAL; 347 value_set_boolean(&expr->u.literal, boolean); 348 return expr; 349 } 350 351 static struct cras_expr_expression *new_integer_literal(int integer) 352 { 353 struct cras_expr_expression *expr; 354 expr = calloc(1, sizeof(struct cras_expr_expression)); 355 expr->type = EXPR_TYPE_LITERAL; 356 value_set_integer(&expr->u.literal, integer); 357 return expr; 358 } 359 360 static struct cras_expr_expression *new_string_literal(const char *begin, 361 const char *end) 362 { 363 struct cras_expr_expression *expr; 364 expr = calloc(1, sizeof(struct cras_expr_expression)); 365 expr->type = EXPR_TYPE_LITERAL; 366 value_set_string2(&expr->u.literal, begin, end); 367 return expr; 368 } 369 370 static struct cras_expr_expression *new_variable(const char *begin, 371 const char *end) 372 { 373 struct cras_expr_expression *expr; 374 expr = calloc(1, sizeof(struct cras_expr_expression)); 375 expr->type = EXPR_TYPE_VARIABLE; 376 expr->u.variable = copy_str(begin, end); 377 return expr; 378 } 379 380 static struct cras_expr_expression *new_compound_expression() 381 { 382 struct cras_expr_expression *expr; 383 expr = calloc(1, sizeof(struct cras_expr_expression)); 384 expr->type = EXPR_TYPE_COMPOUND; 385 return expr; 386 } 387 388 static void add_sub_expression(struct cras_expr_expression *expr, 389 struct cras_expr_expression *sub) 390 { 391 ARRAY_APPEND(&expr->u.children, sub); 392 } 393 394 static int is_identifier_char(char c) 395 { 396 if (isspace(c)) 397 return 0; 398 if (c == '\0') 399 return 0; 400 if (isalpha(c)) 401 return 1; 402 if (c == '_' || c == '-' || c == '?') 403 return 1; 404 return 0; 405 } 406 407 static struct cras_expr_expression *parse_one_expr(const char **str) 408 { 409 /* skip whitespace */ 410 while (isspace(**str)) 411 (*str)++; 412 413 if (**str == '\0') 414 return NULL; 415 416 /* boolean literal: #t, #f */ 417 if (**str == '#') { 418 (*str)++; 419 char c = **str; 420 if (c == 't' || c == 'f') { 421 (*str)++; 422 return new_boolean_literal(c == 't'); 423 } else { 424 syslog(LOG_ERR, "unexpected char after #: '%c'", 425 c); 426 } 427 return NULL; 428 } 429 430 /* integer literal: (-)[0-9]+ */ 431 if (isdigit(**str) || (**str == '-' && isdigit((*str)[1]))) 432 return new_integer_literal(strtol(*str, (char **)str, 10)); 433 434 /* string literal: "..." */ 435 if (**str == '"') { 436 const char *begin = *str + 1; 437 const char *end = strchr(begin, '"'); 438 if (end == NULL) { 439 syslog(LOG_ERR, "no matching \""); 440 end = begin; 441 *str = begin; 442 } else { 443 *str = end + 1; 444 } 445 return new_string_literal(begin, end); 446 } 447 448 /* compound expression: (expr1 expr2 ...) */ 449 if (**str == '(') { 450 (*str)++; 451 struct cras_expr_expression *expr = new_compound_expression(); 452 while (1) { 453 struct cras_expr_expression *next = parse_one_expr(str); 454 if (next == NULL) 455 break; 456 add_sub_expression(expr, next); 457 } 458 if (**str != ')') { 459 syslog(LOG_ERR, "no matching ): found '%c'", **str); 460 cras_expr_expression_free(expr); 461 return NULL; 462 } else { 463 (*str)++; 464 } 465 return expr; 466 } 467 468 /* variable name */ 469 if (is_identifier_char(**str)) { 470 const char *begin = *str; 471 while (is_identifier_char(**str)) 472 (*str)++; 473 return new_variable(begin, *str); 474 } 475 476 return NULL; 477 } 478 479 struct cras_expr_expression *cras_expr_expression_parse(const char *str) 480 { 481 if (!str) 482 return NULL; 483 return parse_one_expr(&str); 484 } 485 486 static void dump_value(struct dumper *d, const struct cras_expr_value *value, 487 int indent) 488 { 489 switch (value->type) { 490 case CRAS_EXPR_VALUE_TYPE_NONE: 491 dumpf(d, "%*s(none)", indent, ""); 492 break; 493 case CRAS_EXPR_VALUE_TYPE_BOOLEAN: 494 dumpf(d, "%*s%s", indent, "", 495 value->u.boolean ? "#t" : "#f"); 496 break; 497 case CRAS_EXPR_VALUE_TYPE_INT: 498 dumpf(d, "%*s%d", indent, "", value->u.integer); 499 break; 500 case CRAS_EXPR_VALUE_TYPE_STRING: 501 dumpf(d, "%*s%s", indent, "", value->u.string); 502 break; 503 case CRAS_EXPR_VALUE_TYPE_FUNCTION: 504 dumpf(d, "%*s%p", indent, "", value->u.function); 505 break; 506 } 507 } 508 509 static void dump_one_expression(struct dumper *d, 510 const struct cras_expr_expression *expr, 511 int indent) 512 { 513 int i; 514 struct cras_expr_expression **sub; 515 516 switch (expr->type) { 517 case EXPR_TYPE_NONE: 518 dumpf(d, "%*snone", indent, ""); 519 break; 520 case EXPR_TYPE_LITERAL: 521 dumpf(d, "%*sliteral", indent, ""); 522 dump_value(d, &expr->u.literal, indent + 2); 523 break; 524 case EXPR_TYPE_VARIABLE: 525 dumpf(d, "%*svariable (%s)", indent, "", 526 expr->u.variable); 527 break; 528 case EXPR_TYPE_COMPOUND: 529 dumpf(d, "%*scompound", indent, ""); 530 FOR_ARRAY_ELEMENT(&expr->u.children, i, sub) { 531 dump_one_expression(d, *sub, indent + 2); 532 } 533 break; 534 } 535 } 536 537 void cras_expr_expression_dump(struct dumper *d, 538 const struct cras_expr_expression *expr) 539 { 540 dump_one_expression(d, expr, 0); 541 } 542 543 void cras_expr_expression_free(struct cras_expr_expression *expr) 544 { 545 if (!expr) 546 return; 547 548 switch (expr->type) { 549 case EXPR_TYPE_NONE: 550 break; 551 case EXPR_TYPE_LITERAL: 552 cras_expr_value_free(&expr->u.literal); 553 break; 554 case EXPR_TYPE_VARIABLE: 555 free((char *)expr->u.variable); 556 break; 557 case EXPR_TYPE_COMPOUND: 558 { 559 int i; 560 struct cras_expr_expression **psub; 561 FOR_ARRAY_ELEMENT(&expr->u.children, i, psub) { 562 cras_expr_expression_free(*psub); 563 } 564 ARRAY_FREE(&expr->u.children); 565 break; 566 } 567 } 568 free(expr); 569 } 570 571 void cras_expr_expression_eval(struct cras_expr_expression *expr, 572 struct cras_expr_env *env, 573 struct cras_expr_value *result) 574 { 575 cras_expr_value_free(result); 576 577 switch (expr->type) { 578 case EXPR_TYPE_NONE: 579 break; 580 case EXPR_TYPE_LITERAL: 581 copy_value(result, &expr->u.literal); 582 break; 583 case EXPR_TYPE_VARIABLE: 584 { 585 struct cras_expr_value *value = find_value(env, 586 expr->u.variable); 587 if (value == NULL) { 588 syslog(LOG_ERR, "cannot find value for %s", 589 expr->u.variable); 590 } else { 591 copy_value(result, value); 592 } 593 break; 594 } 595 case EXPR_TYPE_COMPOUND: 596 { 597 int i; 598 struct cras_expr_expression **psub; 599 cras_expr_value_array values = ARRAY_INIT; 600 struct cras_expr_value *value; 601 602 FOR_ARRAY_ELEMENT(&expr->u.children, i, psub) { 603 value = ARRAY_APPEND_ZERO(&values); 604 cras_expr_expression_eval(*psub, env, value); 605 } 606 607 if (ARRAY_COUNT(&values) > 0) { 608 struct cras_expr_value *f = ARRAY_ELEMENT(&values, 0); 609 if (f->type == CRAS_EXPR_VALUE_TYPE_FUNCTION) 610 f->u.function(&values, result); 611 else 612 syslog(LOG_ERR, 613 "first element is not a function"); 614 } else { 615 syslog(LOG_ERR, "empty compound expression?"); 616 } 617 618 FOR_ARRAY_ELEMENT(&values, i, value) { 619 cras_expr_value_free(value); 620 } 621 622 ARRAY_FREE(&values); 623 break; 624 } 625 } 626 } 627 628 int cras_expr_expression_eval_int(struct cras_expr_expression *expr, 629 struct cras_expr_env *env, 630 int *integer) 631 { 632 int rc = 0; 633 struct cras_expr_value value = CRAS_EXPR_VALUE_INIT; 634 635 cras_expr_expression_eval(expr, env, &value); 636 if (value.type == CRAS_EXPR_VALUE_TYPE_INT) { 637 *integer = value.u.integer; 638 } else { 639 syslog(LOG_ERR, "value type is not integer (%d)", value.type); 640 rc = -1; 641 } 642 cras_expr_value_free(&value); 643 return rc; 644 } 645 646 int cras_expr_expression_eval_boolean(struct cras_expr_expression *expr, 647 struct cras_expr_env *env, 648 char *boolean) 649 { 650 int rc = 0; 651 struct cras_expr_value value = CRAS_EXPR_VALUE_INIT; 652 653 cras_expr_expression_eval(expr, env, &value); 654 if (value.type == CRAS_EXPR_VALUE_TYPE_BOOLEAN) { 655 *boolean = value.u.boolean; 656 } else { 657 syslog(LOG_ERR, "value type is not boolean (%d)", value.type); 658 rc = -1; 659 } 660 cras_expr_value_free(&value); 661 return rc; 662 } 663