19c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid/* Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 29c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid * Use of this source code is governed by a BSD-style license that can be 39c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid * found in the LICENSE file. 49c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid */ 59c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 69c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid#include <ctype.h> 79c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid#include <stdlib.h> 89c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid#include <syslog.h> 99c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 109c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid#include "array.h" 119c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid#include "cras_expr.h" 129c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 139c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic const char *copy_str(const char *begin, const char *end) 149c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 159c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid char *s = malloc(end - begin + 1); 169c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid memcpy(s, begin, end - begin); 179c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid s[end - begin] = '\0'; 189c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return s; 199c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 209c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 219c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic void value_set_boolean(struct cras_expr_value *value, char boolean) 229c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 239c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_value_free(value); 249c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value->type = CRAS_EXPR_VALUE_TYPE_BOOLEAN; 259c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value->u.boolean = !!boolean; 269c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 279c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 289c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic void value_set_integer(struct cras_expr_value *value, int integer) 299c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 309c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_value_free(value); 319c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value->type = CRAS_EXPR_VALUE_TYPE_INT; 329c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value->u.integer = integer; 339c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 349c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 359c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic void value_set_string2(struct cras_expr_value *value, const char *begin, 369c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid const char *end) 379c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 389c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_value_free(value); 399c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value->type = CRAS_EXPR_VALUE_TYPE_STRING; 409c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value->u.string = copy_str(begin, end); 419c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 429c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 439c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic void value_set_string(struct cras_expr_value *value, const char *str) 449c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 459c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value_set_string2(value, str, str + strlen(str)); 469c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 479c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 489c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic void cras_expr_value_set_function(struct cras_expr_value *value, 499c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_function_type function) 509c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 519c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_value_free(value); 529c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value->type = CRAS_EXPR_VALUE_TYPE_FUNCTION; 539c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value->u.function = function; 549c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 559c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 569c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic void copy_value(struct cras_expr_value *value, 579c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *original) 589c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 599c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_value_free(value); /* free the original value first */ 609c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value->type = original->type; 619c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid switch (value->type) { 629c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case CRAS_EXPR_VALUE_TYPE_NONE: 639c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 649c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case CRAS_EXPR_VALUE_TYPE_BOOLEAN: 659c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value->u.boolean = original->u.boolean; 669c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 679c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case CRAS_EXPR_VALUE_TYPE_INT: 689c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value->u.integer = original->u.integer; 699c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 709c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case CRAS_EXPR_VALUE_TYPE_STRING: 719c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value->u.string = strdup(original->u.string); 729c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 739c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case CRAS_EXPR_VALUE_TYPE_FUNCTION: 749c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value->u.function = original->u.function; 759c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 769c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 779c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 789c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 799c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidvoid cras_expr_value_free(struct cras_expr_value *value) 809c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 819c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid switch (value->type) { 829c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case CRAS_EXPR_VALUE_TYPE_STRING: 839c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid free((char *)value->u.string); 849c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value->u.string = NULL; 859c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 869c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case CRAS_EXPR_VALUE_TYPE_NONE: 879c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case CRAS_EXPR_VALUE_TYPE_BOOLEAN: 889c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case CRAS_EXPR_VALUE_TYPE_INT: 899c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case CRAS_EXPR_VALUE_TYPE_FUNCTION: 909c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 919c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 929c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value->type = CRAS_EXPR_VALUE_TYPE_NONE; 939c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 949c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 959c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic struct cras_expr_value *find_value(struct cras_expr_env *env, 969c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid const char *name) 979c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 989c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid int i; 999c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid const char **key; 1009c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1019c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid FOR_ARRAY_ELEMENT(&env->keys, i, key) { 1029c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (strcmp(*key, name) == 0) 1039c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return ARRAY_ELEMENT(&env->values, i); 1049c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 1059c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return NULL; 1069c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 1079c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1089c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid/* Insert a (key, value) pair to the environment. The value is 1099c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid * initialized to zero. Return the pointer to value so it can be set 1109c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid * to the proper value. */ 1119c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic struct cras_expr_value *insert_value(struct cras_expr_env *env, 1129c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid const char *key) 1139c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 1149c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid *ARRAY_APPEND_ZERO(&env->keys) = strdup(key); 1159c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return ARRAY_APPEND_ZERO(&env->values); 1169c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 1179c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1189c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic struct cras_expr_value *find_or_insert_value(struct cras_expr_env *env, 1199c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid const char *key) 1209c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 1219c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *value = find_value(env, key); 1229c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (!value) 1239c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value = insert_value(env, key); 1249c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return value; 1259c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 1269c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1279c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic void function_not(cras_expr_value_array *operands, 1289c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *result) 1299c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 1309c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *value; 1319c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid int is_false; 1329c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1339c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (ARRAY_COUNT(operands) != 2) { 1349c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_value_free(result); 1359c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid syslog(LOG_ERR, "not takes one argument"); 1369c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return; 1379c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 1389c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1399c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value = ARRAY_ELEMENT(operands, 1); 1409c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid is_false = (value->type == CRAS_EXPR_VALUE_TYPE_BOOLEAN && 1419c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid !value->u.boolean); 1429c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value_set_boolean(result, is_false); 1439c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 1449c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1459c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic void function_and(cras_expr_value_array *operands, 1469c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *result) 1479c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 1489c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid int i; 1499c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *value; 1509c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid int n = ARRAY_COUNT(operands); 1519c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1529c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid /* no operands -- return #t */ 1539c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (n <= 1) { 1549c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value_set_boolean(result, 1); 1559c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return; 1569c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 1579c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1589c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid /* if there is any #f, return it */ 1599c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid FOR_ARRAY_ELEMENT(operands, i, value) { 1609c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (i == 0) 1619c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid continue; /* ignore "and" itself */ 1629c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (value->type == CRAS_EXPR_VALUE_TYPE_BOOLEAN && 1639c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid !value->u.boolean) { 1649c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value_set_boolean(result, 0); 1659c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return; 1669c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 1679c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 1689c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1699c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid /* otherwise return the last element */ 1709c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid copy_value(result, ARRAY_ELEMENT(operands, n - 1)); 1719c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 1729c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1739c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic void function_or(cras_expr_value_array *operands, 1749c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *result) 1759c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 1769c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid int i; 1779c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *value; 1789c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1799c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid FOR_ARRAY_ELEMENT(operands, i, value) { 1809c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (i == 0) 1819c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid continue; /* ignore "or" itself */ 1829c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (value->type != CRAS_EXPR_VALUE_TYPE_BOOLEAN || 1839c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value->u.boolean) { 1849c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid copy_value(result, value); 1859c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return; 1869c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 1879c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 1889c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1899c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value_set_boolean(result, 0); 1909c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 1919c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1929c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic char function_equal_real(cras_expr_value_array *operands) 1939c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 1949c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid int i; 1959c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *value, *prev; 1969c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 1979c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid FOR_ARRAY_ELEMENT(operands, i, value) { 1989c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (i <= 1) 1999c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid continue; /* ignore equal? and first operand */ 2009c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid /* compare with the previous operand */ 2019c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 2029c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid prev = ARRAY_ELEMENT(operands, i - 1); 2039c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 2049c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (prev->type != value->type) 2059c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return 0; 2069c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 2079c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid switch (prev->type) { 2089c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case CRAS_EXPR_VALUE_TYPE_NONE: 2099c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 2109c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case CRAS_EXPR_VALUE_TYPE_BOOLEAN: 2119c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (prev->u.boolean != value->u.boolean) 2129c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return 0; 2139c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 2149c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case CRAS_EXPR_VALUE_TYPE_INT: 2159c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (prev->u.integer != value->u.integer) 2169c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return 0; 2179c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 2189c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case CRAS_EXPR_VALUE_TYPE_STRING: 2199c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (strcmp(prev->u.string, value->u.string) != 0) 2209c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return 0; 2219c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 2229c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case CRAS_EXPR_VALUE_TYPE_FUNCTION: 2239c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (prev->u.function != value->u.function) 2249c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return 0; 2259c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 2269c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 2279c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 2289c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 2299c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return 1; 2309c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 2319c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 2329c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic void function_equal(cras_expr_value_array *operands, 2339c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *result) 2349c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 2359c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value_set_boolean(result, function_equal_real(operands)); 2369c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 2379c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 2389c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic void env_set_variable(struct cras_expr_env *env, const char *name, 2399c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *new_value) 2409c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 2419c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *value = find_or_insert_value(env, name); 2429c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid copy_value(value, new_value); 2439c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 2449c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 2459c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidvoid cras_expr_env_install_builtins(struct cras_expr_env *env) 2469c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 2479c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value value = CRAS_EXPR_VALUE_INIT; 2489c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 2499c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid /* initialize env with builtin functions */ 2509c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_value_set_function(&value, &function_not); 2519c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid env_set_variable(env, "not", &value); 2529c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 2539c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_value_set_function(&value, &function_and); 2549c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid env_set_variable(env, "and", &value); 2559c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 2569c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_value_set_function(&value, &function_or); 2579c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid env_set_variable(env, "or", &value); 2589c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 2599c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_value_set_function(&value, &function_equal); 2609c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid env_set_variable(env, "equal?", &value); 2619c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 2629c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_value_free(&value); 2639c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 2649c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 2659c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidvoid cras_expr_env_set_variable_boolean(struct cras_expr_env *env, 2669c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid const char *name, char boolean) 2679c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 2689c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *value = find_or_insert_value(env, name); 2699c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value_set_boolean(value, boolean); 2709c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 2719c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 2729c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidvoid cras_expr_env_set_variable_integer(struct cras_expr_env *env, 2739c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid const char *name, int integer) 2749c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 2759c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *value = find_or_insert_value(env, name); 2769c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value_set_integer(value, integer); 2779c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 2789c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 2799c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidvoid cras_expr_env_set_variable_string(struct cras_expr_env *env, 2809c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid const char *name, const char *str) 2819c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 2829c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *value = find_or_insert_value(env, name); 2839c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value_set_string(value, str); 2849c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 2859c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 2869c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidvoid cras_expr_env_free(struct cras_expr_env *env) 2879c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 2889c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid int i; 2899c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid const char **key; 2909c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *value; 2919c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 2929c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid FOR_ARRAY_ELEMENT(&env->keys, i, key) { 2939c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid free((char *)*key); 2949c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 2959c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 2969c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid FOR_ARRAY_ELEMENT(&env->values, i, value) { 2979c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_value_free(value); 2989c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 2999c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 3009c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid ARRAY_FREE(&env->keys); 3019c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid ARRAY_FREE(&env->values); 3029c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 3039c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 3049c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic struct cras_expr_expression *new_boolean_literal(char boolean) 3059c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 3069c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_expression *expr; 3079c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid expr = calloc(1, sizeof(struct cras_expr_expression)); 3089c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid expr->type = EXPR_TYPE_LITERAL; 3099c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value_set_boolean(&expr->u.literal, boolean); 3109c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return expr; 3119c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 3129c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 3139c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic struct cras_expr_expression *new_integer_literal(int integer) 3149c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 3159c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_expression *expr; 3169c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid expr = calloc(1, sizeof(struct cras_expr_expression)); 3179c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid expr->type = EXPR_TYPE_LITERAL; 3189c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value_set_integer(&expr->u.literal, integer); 3199c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return expr; 3209c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 3219c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 3229c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic struct cras_expr_expression *new_string_literal(const char *begin, 3239c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid const char *end) 3249c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 3259c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_expression *expr; 3269c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid expr = calloc(1, sizeof(struct cras_expr_expression)); 3279c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid expr->type = EXPR_TYPE_LITERAL; 3289c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value_set_string2(&expr->u.literal, begin, end); 3299c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return expr; 3309c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 3319c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 3329c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic struct cras_expr_expression *new_variable(const char *begin, 3339c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid const char *end) 3349c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 3359c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_expression *expr; 3369c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid expr = calloc(1, sizeof(struct cras_expr_expression)); 3379c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid expr->type = EXPR_TYPE_VARIABLE; 3389c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid expr->u.variable = copy_str(begin, end); 3399c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return expr; 3409c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 3419c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 3429c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic struct cras_expr_expression *new_compound_expression() 3439c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 3449c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_expression *expr; 3459c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid expr = calloc(1, sizeof(struct cras_expr_expression)); 3469c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid expr->type = EXPR_TYPE_COMPOUND; 3479c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return expr; 3489c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 3499c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 3509c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic void add_sub_expression(struct cras_expr_expression *expr, 3519c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_expression *sub) 3529c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 3539c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid ARRAY_APPEND(&expr->u.children, sub); 3549c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 3559c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 3569c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic int is_identifier_char(char c) 3579c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 3589c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (isspace(c)) 3599c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return 0; 3609c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (c == '\0') 3619c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return 0; 3629c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (isalpha(c)) 3639c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return 1; 3649c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (c == '_' || c == '-' || c == '?') 3659c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return 1; 3669c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return 0; 3679c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 3689c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 3699c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstatic struct cras_expr_expression *parse_one_expr(const char **str) 3709c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 3719c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid /* skip whitespace */ 3729c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid while (isspace(**str)) 3739c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid (*str)++; 3749c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 3759c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (**str == '\0') 3769c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return NULL; 3779c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 3789c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid /* boolean literal: #t, #f */ 3799c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (**str == '#') { 3809c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid (*str)++; 3819c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid char c = **str; 3829c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (c == 't' || c == 'f') { 3839c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid (*str)++; 3849c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return new_boolean_literal(c == 't'); 3859c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } else { 3869c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid syslog(LOG_ERR, "unexpected char after #: '%c'", 3879c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid c); 3889c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 3899c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return NULL; 3909c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 3919c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 3929c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid /* integer literal: (-)[0-9]+ */ 3939c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (isdigit(**str) || (**str == '-' && isdigit((*str)[1]))) 3949c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return new_integer_literal(strtol(*str, (char **)str, 10)); 3959c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 3969c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid /* string literal: "..." */ 3979c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (**str == '"') { 3989c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid const char *begin = *str + 1; 3999c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid const char *end = strchr(begin, '"'); 4009c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (end == NULL) { 4019c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid syslog(LOG_ERR, "no matching \""); 4029c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid end = begin; 4039c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid *str = begin; 4049c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } else { 4059c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid *str = end + 1; 4069c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 4079c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return new_string_literal(begin, end); 4089c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 4099c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 4109c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid /* compound expression: (expr1 expr2 ...) */ 4119c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (**str == '(') { 4129c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid (*str)++; 4139c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_expression *expr = new_compound_expression(); 4149c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid while (1) { 4159c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_expression *next = parse_one_expr(str); 4169c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (next == NULL) 4179c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 4189c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid add_sub_expression(expr, next); 4199c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 4209c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (**str != ')') { 4219c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid syslog(LOG_ERR, "no matching ): found '%c'", **str); 4229c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_expression_free(expr); 4239c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return NULL; 4249c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } else { 4259c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid (*str)++; 4269c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 4279c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return expr; 4289c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 4299c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 4309c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid /* variable name */ 4319c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (is_identifier_char(**str)) { 4329c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid const char *begin = *str; 4339c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid while (is_identifier_char(**str)) 4349c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid (*str)++; 4359c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return new_variable(begin, *str); 4369c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 4379c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 4389c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return NULL; 4399c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 4409c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 4419c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidstruct cras_expr_expression *cras_expr_expression_parse(const char *str) 4429c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 4439c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (!str) 4449c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return NULL; 4459c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return parse_one_expr(&str); 4469c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 4479c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 4489c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidvoid cras_expr_expression_free(struct cras_expr_expression *expr) 4499c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 4509c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (!expr) 4519c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return; 4529c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 4539c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid switch (expr->type) { 4549c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case EXPR_TYPE_NONE: 4559c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 4569c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case EXPR_TYPE_LITERAL: 4579c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_value_free(&expr->u.literal); 4589c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 4599c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case EXPR_TYPE_VARIABLE: 4609c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid free((char *)expr->u.variable); 4619c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 4629c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case EXPR_TYPE_COMPOUND: 4639c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid { 4649c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid int i; 4659c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_expression **psub; 4669c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid FOR_ARRAY_ELEMENT(&expr->u.children, i, psub) { 4679c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_expression_free(*psub); 4689c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 4699c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid ARRAY_FREE(&expr->u.children); 4709c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 4719c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 4729c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 4739c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid free(expr); 4749c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 4759c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 4769c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidvoid cras_expr_expression_eval(struct cras_expr_expression *expr, 4779c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_env *env, 4789c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *result) 4799c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 4809c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_value_free(result); 4819c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 4829c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid switch (expr->type) { 4839c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case EXPR_TYPE_NONE: 4849c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 4859c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case EXPR_TYPE_LITERAL: 4869c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid copy_value(result, &expr->u.literal); 4879c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 4889c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case EXPR_TYPE_VARIABLE: 4899c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid { 4909c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *value = find_value(env, 4919c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid expr->u.variable); 4929c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (value == NULL) { 4939c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid syslog(LOG_ERR, "cannot find value for %s", 4949c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid expr->u.variable); 4959c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } else { 4969c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid copy_value(result, value); 4979c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 4989c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 4999c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 5009c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid case EXPR_TYPE_COMPOUND: 5019c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid { 5029c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid int i; 5039c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_expression **psub; 5049c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_value_array values = ARRAY_INIT; 5059c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *value; 5069c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 5079c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid FOR_ARRAY_ELEMENT(&expr->u.children, i, psub) { 5089c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid value = ARRAY_APPEND_ZERO(&values); 5099c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_expression_eval(*psub, env, value); 5109c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 5119c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 5129c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (ARRAY_COUNT(&values) > 0) { 5139c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value *f = ARRAY_ELEMENT(&values, 0); 5149c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (f->type == CRAS_EXPR_VALUE_TYPE_FUNCTION) 5159c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid f->u.function(&values, result); 5169c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid else 5179c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid syslog(LOG_ERR, 5189c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid "first element is not a function"); 5199c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } else { 5209c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid syslog(LOG_ERR, "empty compound expression?"); 5219c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 5229c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 5239c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid FOR_ARRAY_ELEMENT(&values, i, value) { 5249c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_value_free(value); 5259c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 5269c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 5279c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid ARRAY_FREE(&values); 5289c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid break; 5299c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 5309c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 5319c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 5329c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 5339c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidint cras_expr_expression_eval_int(struct cras_expr_expression *expr, 5349c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_env *env, 5359c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid int *integer) 5369c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 5379c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid int rc = 0; 5389c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value value = CRAS_EXPR_VALUE_INIT; 5399c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 5409c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_expression_eval(expr, env, &value); 5419c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (value.type == CRAS_EXPR_VALUE_TYPE_INT) { 5429c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid *integer = value.u.integer; 5439c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } else { 5449c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid syslog(LOG_ERR, "value type is not integer (%d)", value.type); 5459c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid rc = -1; 5469c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 5479c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_value_free(&value); 5489c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return rc; 5499c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 5509c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 5519c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reidint cras_expr_expression_eval_boolean(struct cras_expr_expression *expr, 5529c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_env *env, 5539c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid char *boolean) 5549c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid{ 5559c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid int rc = 0; 5569c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid struct cras_expr_value value = CRAS_EXPR_VALUE_INIT; 5579c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid 5589c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_expression_eval(expr, env, &value); 5599c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid if (value.type == CRAS_EXPR_VALUE_TYPE_BOOLEAN) { 5609c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid *boolean = value.u.boolean; 5619c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } else { 5629c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid syslog(LOG_ERR, "value type is not boolean (%d)", value.type); 5639c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid rc = -1; 5649c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid } 5659c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid cras_expr_value_free(&value); 5669c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid return rc; 5679c94a7e4053538cacb9695b15da4b1cc7857d09dDylan Reid} 568