|
Packit Service |
db8eaa |
/*
|
|
Packit Service |
db8eaa |
* This library is free software; you can redistribute it and/or
|
|
Packit Service |
db8eaa |
* modify it under the terms of the GNU Lesser General Public
|
|
Packit Service |
db8eaa |
* License as published by the Free Software Foundation; either
|
|
Packit Service |
db8eaa |
* version 2 of the License, or (at your option) any later version.
|
|
Packit Service |
db8eaa |
*
|
|
Packit Service |
db8eaa |
* This library is distributed in the hope that it will be useful,
|
|
Packit Service |
db8eaa |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
db8eaa |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit Service |
db8eaa |
* Lesser General Public License for more details.
|
|
Packit Service |
db8eaa |
*
|
|
Packit Service |
db8eaa |
* You should have received a copy of the GNU Lesser General Public
|
|
Packit Service |
db8eaa |
* License along with this library; if not, write to the Free Software
|
|
Packit Service |
db8eaa |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
Packit Service |
db8eaa |
*
|
|
Packit Service |
db8eaa |
* Support for the verb/device/modifier core logic and API,
|
|
Packit Service |
db8eaa |
* command line tool and file parser was kindly sponsored by
|
|
Packit Service |
db8eaa |
* Texas Instruments Inc.
|
|
Packit Service |
db8eaa |
* Support for multiple active modifiers and devices,
|
|
Packit Service |
db8eaa |
* transition sequences, multiple client access and user defined use
|
|
Packit Service |
db8eaa |
* cases was kindly sponsored by Wolfson Microelectronics PLC.
|
|
Packit Service |
db8eaa |
*
|
|
Packit Service |
db8eaa |
* Copyright (C) 2019 Red Hat Inc.
|
|
Packit Service |
db8eaa |
* Authors: Jaroslav Kysela <perex@perex.cz>
|
|
Packit Service |
db8eaa |
*/
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
#include "ucm_local.h"
|
|
Packit Service |
db8eaa |
#include <regex.h>
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
static int get_string(snd_config_t *compound, const char *key, const char **str)
|
|
Packit Service |
db8eaa |
{
|
|
Packit Service |
db8eaa |
snd_config_t *node;
|
|
Packit Service |
db8eaa |
int err;
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = snd_config_search(compound, key, &node);
|
|
Packit Service |
db8eaa |
if (err < 0)
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
return snd_config_get_string(node, str);
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
static int if_eval_string(snd_use_case_mgr_t *uc_mgr, snd_config_t *eval)
|
|
Packit Service |
db8eaa |
{
|
|
Packit Service |
db8eaa |
const char *string1 = NULL, *string2 = NULL;
|
|
Packit Service |
db8eaa |
char *s1, *s2;
|
|
Packit Service |
db8eaa |
int err;
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
if (uc_mgr->conf_format >= 3) {
|
|
Packit Service |
db8eaa |
err = get_string(eval, "Empty", &string1);
|
|
Packit Service |
db8eaa |
if (err < 0 && err != -ENOENT) {
|
|
Packit Service |
db8eaa |
uc_error("String error (If.Condition.Empty)");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
if (string1) {
|
|
Packit Service |
db8eaa |
err = uc_mgr_get_substituted_value(uc_mgr, &s1, string1);
|
|
Packit Service |
db8eaa |
if (err < 0)
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
err = s1 == NULL || s1[0] == '\0';
|
|
Packit Service |
db8eaa |
free(s1);
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = get_string(eval, "String1", &string1);
|
|
Packit Service |
db8eaa |
if (err < 0 && err != -ENOENT) {
|
|
Packit Service |
db8eaa |
uc_error("String error (If.Condition.String1)");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = get_string(eval, "String2", &string2);
|
|
Packit Service |
db8eaa |
if (err < 0 && err != -ENOENT) {
|
|
Packit Service |
db8eaa |
uc_error("String error (If.Condition.String2)");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
if (string1 || string2) {
|
|
Packit Service |
db8eaa |
if (string1 == NULL) {
|
|
Packit Service |
db8eaa |
uc_error("If.Condition.String1 not defined");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
if (string2 == NULL) {
|
|
Packit Service |
db8eaa |
uc_error("If.Condition.String2 not defined");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
err = uc_mgr_get_substituted_value(uc_mgr, &s1, string1);
|
|
Packit Service |
db8eaa |
if (err < 0)
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
err = uc_mgr_get_substituted_value(uc_mgr, &s2, string2);
|
|
Packit Service |
db8eaa |
if (err < 0) {
|
|
Packit Service |
db8eaa |
free(s1);
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
err = strcasecmp(s1, s2) == 0;
|
|
Packit Service |
db8eaa |
free(s2);
|
|
Packit Service |
db8eaa |
free(s1);
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = get_string(eval, "Haystack", &string1);
|
|
Packit Service |
db8eaa |
if (err < 0 && err != -ENOENT) {
|
|
Packit Service |
db8eaa |
uc_error("String error (If.Condition.Haystack)");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = get_string(eval, "Needle", &string2);
|
|
Packit Service |
db8eaa |
if (err < 0 && err != -ENOENT) {
|
|
Packit Service |
db8eaa |
uc_error("String error (If.Condition.Needle)");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
if (string1 || string2) {
|
|
Packit Service |
db8eaa |
if (string1 == NULL) {
|
|
Packit Service |
db8eaa |
uc_error("If.Condition.Haystack not defined");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
if (string2 == NULL) {
|
|
Packit Service |
db8eaa |
uc_error("If.Condition.Needle not defined");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
err = uc_mgr_get_substituted_value(uc_mgr, &s1, string1);
|
|
Packit Service |
db8eaa |
if (err < 0)
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
err = uc_mgr_get_substituted_value(uc_mgr, &s2, string2);
|
|
Packit Service |
db8eaa |
if (err < 0) {
|
|
Packit Service |
db8eaa |
free(s1);
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
err = strstr(s1, s2) != NULL;
|
|
Packit Service |
db8eaa |
free(s2);
|
|
Packit Service |
db8eaa |
free(s1);
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
uc_error("Unknown String condition arguments");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
static int if_eval_regex_match(snd_use_case_mgr_t *uc_mgr, snd_config_t *eval)
|
|
Packit Service |
db8eaa |
{
|
|
Packit Service |
db8eaa |
const char *string, *regex_string;
|
|
Packit Service |
db8eaa |
char *s;
|
|
Packit Service |
db8eaa |
regex_t re;
|
|
Packit Service |
db8eaa |
int options = REG_EXTENDED | REG_ICASE;
|
|
Packit Service |
db8eaa |
regmatch_t match[1];
|
|
Packit Service |
db8eaa |
int err;
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = get_string(eval, "String", &string);
|
|
Packit Service |
db8eaa |
if (err < 0) {
|
|
Packit Service |
db8eaa |
uc_error("RegexMatch error (If.Condition.String)");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = get_string(eval, "Regex", ®ex_string);
|
|
Packit Service |
db8eaa |
if (err < 0) {
|
|
Packit Service |
db8eaa |
uc_error("RegexMatch error (If.Condition.Regex)");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = uc_mgr_get_substituted_value(uc_mgr, &s, regex_string);
|
|
Packit Service |
db8eaa |
if (err < 0)
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
err = regcomp(&re, s, options);
|
|
Packit Service |
db8eaa |
free(s);
|
|
Packit Service |
db8eaa |
if (err) {
|
|
Packit Service |
db8eaa |
uc_error("Regex '%s' compilation failed (code %d)", err);
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = uc_mgr_get_substituted_value(uc_mgr, &s, string);
|
|
Packit Service |
db8eaa |
if (err < 0) {
|
|
Packit Service |
db8eaa |
regfree(&re);
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
err = regexec(&re, s, ARRAY_SIZE(match), match, 0);
|
|
Packit Service |
db8eaa |
free(s);
|
|
Packit Service |
db8eaa |
regfree(&re);
|
|
Packit Service |
db8eaa |
return err == 0;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
static int if_eval_control_exists(snd_use_case_mgr_t *uc_mgr, snd_config_t *eval)
|
|
Packit Service |
db8eaa |
{
|
|
Packit Service |
db8eaa |
snd_ctl_t *ctl;
|
|
Packit Service |
db8eaa |
struct ctl_list *ctl_list;
|
|
Packit Service |
db8eaa |
const char *device = NULL, *ctldef, *enumval = NULL, *name;
|
|
Packit Service |
db8eaa |
snd_ctl_elem_id_t *elem_id;
|
|
Packit Service |
db8eaa |
snd_ctl_elem_info_t *elem_info;
|
|
Packit Service |
db8eaa |
snd_ctl_elem_type_t type;
|
|
Packit Service |
db8eaa |
char *s;
|
|
Packit Service |
db8eaa |
int err, i, items;
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
snd_ctl_elem_id_alloca(&elem_id);
|
|
Packit Service |
db8eaa |
snd_ctl_elem_info_alloca(&elem_info);
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = get_string(eval, "Device", &device);
|
|
Packit Service |
db8eaa |
if (err < 0 && err != -ENOENT) {
|
|
Packit Service |
db8eaa |
uc_error("ControlExists error (If.Condition.Device)");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = get_string(eval, "Control", &ctldef);
|
|
Packit Service |
db8eaa |
if (err < 0) {
|
|
Packit Service |
db8eaa |
uc_error("ControlExists error (If.Condition.Control)");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = get_string(eval, "ControlEnum", &enumval);
|
|
Packit Service |
db8eaa |
if (err < 0 && err != -ENOENT) {
|
|
Packit Service |
db8eaa |
uc_error("ControlExists error (If.Condition.ControlEnum)");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = uc_mgr_get_substituted_value(uc_mgr, &s, ctldef);
|
|
Packit Service |
db8eaa |
if (err < 0)
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
err = snd_ctl_ascii_elem_id_parse(elem_id, s);
|
|
Packit Service |
db8eaa |
free(s);
|
|
Packit Service |
db8eaa |
if (err < 0) {
|
|
Packit Service |
db8eaa |
uc_error("unable to parse element identificator (%s)", ctldef);
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
if (device == NULL) {
|
|
Packit Service |
db8eaa |
ctl = uc_mgr_get_ctl(uc_mgr);
|
|
Packit Service |
db8eaa |
if (ctl == NULL) {
|
|
Packit Service |
db8eaa |
uc_error("cannot determine control device");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
} else {
|
|
Packit Service |
db8eaa |
err = uc_mgr_get_substituted_value(uc_mgr, &s, device);
|
|
Packit Service |
db8eaa |
if (err < 0)
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
err = uc_mgr_open_ctl(uc_mgr, &ctl_list, s, 1);
|
|
Packit Service |
db8eaa |
free(s);
|
|
Packit Service |
db8eaa |
if (err < 0)
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
ctl = ctl_list->ctl;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
snd_ctl_elem_info_set_id(elem_info, elem_id);
|
|
Packit Service |
db8eaa |
err = snd_ctl_elem_info(ctl, elem_info);
|
|
Packit Service |
db8eaa |
if (err < 0)
|
|
Packit Service |
db8eaa |
return 0;
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
if (enumval) {
|
|
Packit Service |
db8eaa |
type = snd_ctl_elem_info_get_type(elem_info);
|
|
Packit Service |
db8eaa |
if (type != SND_CTL_ELEM_TYPE_ENUMERATED)
|
|
Packit Service |
db8eaa |
return 0;
|
|
Packit Service |
db8eaa |
err = uc_mgr_get_substituted_value(uc_mgr, &s, enumval);
|
|
Packit Service |
db8eaa |
if (err < 0)
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
items = snd_ctl_elem_info_get_items(elem_info);
|
|
Packit Service |
db8eaa |
for (i = 0; i < items; i++) {
|
|
Packit Service |
db8eaa |
snd_ctl_elem_info_set_item(elem_info, i);
|
|
Packit Service |
db8eaa |
err = snd_ctl_elem_info(ctl, elem_info);
|
|
Packit Service |
db8eaa |
if (err < 0) {
|
|
Packit Service |
db8eaa |
free(s);
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
name = snd_ctl_elem_info_get_item_name(elem_info);
|
|
Packit Service |
db8eaa |
if (strcasecmp(name, s) == 0) {
|
|
Packit Service |
db8eaa |
free(s);
|
|
Packit Service |
db8eaa |
return 1;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
free(s);
|
|
Packit Service |
db8eaa |
return 0;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
return 1;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
static int if_eval(snd_use_case_mgr_t *uc_mgr, snd_config_t *eval)
|
|
Packit Service |
db8eaa |
{
|
|
Packit Service |
db8eaa |
const char *type;
|
|
Packit Service |
db8eaa |
int err;
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
if (snd_config_get_type(eval) != SND_CONFIG_TYPE_COMPOUND) {
|
|
Packit Service |
db8eaa |
uc_error("compound type expected for If.Condition");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = get_string(eval, "Type", &type);
|
|
Packit Service |
db8eaa |
if (err < 0) {
|
|
Packit Service |
db8eaa |
uc_error("type block error (If.Condition)");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
if (strcmp(type, "AlwaysTrue") == 0)
|
|
Packit Service |
db8eaa |
return 1;
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
if (strcmp(type, "String") == 0)
|
|
Packit Service |
db8eaa |
return if_eval_string(uc_mgr, eval);
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
if (strcmp(type, "ControlExists") == 0)
|
|
Packit Service |
db8eaa |
return if_eval_control_exists(uc_mgr, eval);
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
if (strcmp(type, "RegexMatch") == 0)
|
|
Packit Service |
db8eaa |
return if_eval_regex_match(uc_mgr, eval);
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
uc_error("unknown If.Condition.Type");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
static int if_eval_one(snd_use_case_mgr_t *uc_mgr,
|
|
Packit Service |
db8eaa |
snd_config_t *cond,
|
|
Packit Service |
db8eaa |
snd_config_t **result,
|
|
Packit Service |
db8eaa |
snd_config_t **before,
|
|
Packit Service |
db8eaa |
snd_config_t **after)
|
|
Packit Service |
db8eaa |
{
|
|
Packit Service |
db8eaa |
snd_config_t *expr, *_true = NULL, *_false = NULL;
|
|
Packit Service |
db8eaa |
int err;
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
*result = NULL;
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
if (snd_config_get_type(cond) != SND_CONFIG_TYPE_COMPOUND) {
|
|
Packit Service |
db8eaa |
uc_error("compound type expected for If.1");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
if (snd_config_search(cond, "Condition", &expr) < 0) {
|
|
Packit Service |
db8eaa |
uc_error("condition block expected (If)");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = snd_config_search(cond, "True", &_true);
|
|
Packit Service |
db8eaa |
if (err < 0 && err != -ENOENT) {
|
|
Packit Service |
db8eaa |
uc_error("true block error (If)");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = snd_config_search(cond, "False", &_false);
|
|
Packit Service |
db8eaa |
if (err < 0 && err != -ENOENT) {
|
|
Packit Service |
db8eaa |
uc_error("false block error (If)");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = snd_config_search(cond, "Before", before);
|
|
Packit Service |
db8eaa |
if (err < 0 && err != -ENOENT) {
|
|
Packit Service |
db8eaa |
uc_error("before block identifier error");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = snd_config_search(cond, "After", after);
|
|
Packit Service |
db8eaa |
if (err < 0 && err != -ENOENT) {
|
|
Packit Service |
db8eaa |
uc_error("before block identifier error");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
err = if_eval(uc_mgr, expr);
|
|
Packit Service |
db8eaa |
if (err > 0) {
|
|
Packit Service |
db8eaa |
*result = _true;
|
|
Packit Service |
db8eaa |
return 0;
|
|
Packit Service |
db8eaa |
} else if (err == 0) {
|
|
Packit Service |
db8eaa |
*result = _false;
|
|
Packit Service |
db8eaa |
return 0;
|
|
Packit Service |
db8eaa |
} else {
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
#if 0
|
|
Packit Service |
db8eaa |
static void config_dump(snd_config_t *cfg)
|
|
Packit Service |
db8eaa |
{
|
|
Packit Service |
db8eaa |
snd_output_t *out;
|
|
Packit Service |
db8eaa |
snd_output_stdio_attach(&out, stderr, 0);
|
|
Packit Service |
db8eaa |
snd_output_printf(out, "-----\n");
|
|
Packit Service |
db8eaa |
snd_config_save(cfg, out);
|
|
Packit Service |
db8eaa |
snd_output_close(out);
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
#endif
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
/*
|
|
Packit Service |
db8eaa |
* put back the result from all conditions to the parent
|
|
Packit Service |
db8eaa |
*/
|
|
Packit Service |
db8eaa |
int uc_mgr_evaluate_condition(snd_use_case_mgr_t *uc_mgr,
|
|
Packit Service |
db8eaa |
snd_config_t *parent,
|
|
Packit Service |
db8eaa |
snd_config_t *cond)
|
|
Packit Service |
db8eaa |
{
|
|
Packit Service |
db8eaa |
snd_config_iterator_t i, next;
|
|
Packit Service |
db8eaa |
snd_config_t *a, *n, *before, *after;
|
|
Packit Service |
db8eaa |
int err;
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
if (uc_mgr->conf_format < 2) {
|
|
Packit Service |
db8eaa |
uc_error("conditions are not supported for v1 syntax");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
if (snd_config_get_type(cond) != SND_CONFIG_TYPE_COMPOUND) {
|
|
Packit Service |
db8eaa |
uc_error("compound type expected for If");
|
|
Packit Service |
db8eaa |
return -EINVAL;
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
|
|
Packit Service |
db8eaa |
snd_config_for_each(i, next, cond) {
|
|
Packit Service |
db8eaa |
n = snd_config_iterator_entry(i);
|
|
Packit Service |
db8eaa |
before = after = NULL;
|
|
Packit Service |
db8eaa |
err = if_eval_one(uc_mgr, n, &a, &before, &after);
|
|
Packit Service |
db8eaa |
if (err < 0)
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
if (a == NULL)
|
|
Packit Service |
db8eaa |
continue;
|
|
Packit Service |
db8eaa |
err = uc_mgr_evaluate_inplace(uc_mgr, a);
|
|
Packit Service |
db8eaa |
if (err < 0)
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
err = uc_mgr_config_tree_merge(uc_mgr, parent, a, before, after);
|
|
Packit Service |
db8eaa |
if (err < 0)
|
|
Packit Service |
db8eaa |
return err;
|
|
Packit Service |
db8eaa |
snd_config_delete(a);
|
|
Packit Service |
db8eaa |
}
|
|
Packit Service |
db8eaa |
return 0;
|
|
Packit Service |
db8eaa |
}
|