ucm: change the If block parsing

- evaluate always If before the other blocks
This commit is contained in:
Jaroslav Kysela 2019-11-14 15:13:36 +01:00
parent cdc8aacbb5
commit 4724158c0a
2 changed files with 70 additions and 92 deletions

View file

@ -180,25 +180,6 @@ snd_config_t *snd_config_iterator_entry(const snd_config_iterator_t iterator);
#define snd_config_for_each(pos, next, node) \
for (pos = snd_config_iterator_first(node), next = snd_config_iterator_next(pos); pos != snd_config_iterator_end(node); pos = next, next = snd_config_iterator_next(pos))
/**
* \brief Helper macro to iterate over the children of a compound node.
* \param[in,out] pos Iterator variable for the current node.
* \param[in] node Handle to the compound configuration node to iterate over.
*
* Use this macro like a \c for statement, e.g.:
* \code
* snd_config_iterator_t pos;
* snd_config_for_each(pos, node) {
* snd_config_t *entry = snd_config_iterator_entry(pos);
* ...
* }
* \endcode
*
* This macro does not allow deleting or removing the current node.
*/
#define snd_config_for_each_unsafe(pos, node) \
for (pos = snd_config_iterator_first(node); pos != snd_config_iterator_end(node); pos = snd_config_iterator_next(pos))
/* Misc functions */
int snd_config_get_bool_ascii(const char *ascii);

View file

@ -160,6 +160,24 @@ int parse_get_safe_id(snd_config_t *n, const char **id)
return 0;
}
/*
* Evaluate condition (in-place)
*/
static int evaluate_condition(snd_use_case_mgr_t *uc_mgr,
snd_config_t *cfg)
{
snd_config_t *n;
int err;
err = snd_config_search(cfg, "If", &n);
if (err == -ENOENT)
return 0;
if (err < 0)
return err;
return uc_mgr_evaluate_condition(uc_mgr, cfg, n);
}
/*
* Parse transition
*/
@ -584,7 +602,7 @@ static int parse_value(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED,
struct list_head *base,
snd_config_t *cfg)
{
snd_config_iterator_t i;
snd_config_iterator_t i, next;
snd_config_t *n;
char *s;
snd_config_type_t type;
@ -594,21 +612,19 @@ static int parse_value(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED,
uc_error("error: compound is expected for value definition");
return -EINVAL;
}
snd_config_for_each_unsafe(i, cfg) {
/* in-place condition evaluation */
err = evaluate_condition(uc_mgr, cfg);
if (err < 0)
return err;
snd_config_for_each(i, next, cfg) {
const char *id;
n = snd_config_iterator_entry(i);
err = snd_config_get_id(n, &id);
if (err < 0)
continue;
/* in-place condition evaluation */
if (strcmp(id, "If") == 0) {
err = uc_mgr_evaluate_condition(uc_mgr, cfg, n);
if (err < 0)
return err;
continue;
}
type = snd_config_get_type(n);
switch (type) {
case SND_CONFIG_TYPE_INTEGER:
@ -690,7 +706,7 @@ static int parse_modifier(snd_use_case_mgr_t *uc_mgr,
struct use_case_verb *verb = data1;
struct use_case_modifier *modifier;
const char *name;
snd_config_iterator_t i;
snd_config_iterator_t i, next;
snd_config_t *n;
int err;
@ -716,20 +732,17 @@ static int parse_modifier(snd_use_case_mgr_t *uc_mgr,
list_add_tail(&modifier->list, &verb->modifier_list);
modifier->name = strdup(name);
snd_config_for_each_unsafe(i, cfg) {
/* in-place condition evaluation */
err = evaluate_condition(uc_mgr, cfg);
if (err < 0)
return err;
snd_config_for_each(i, next, cfg) {
const char *id;
n = snd_config_iterator_entry(i);
if (snd_config_get_id(n, &id) < 0)
continue;
/* in-place condition evaluation */
if (strcmp(id, "If") == 0) {
err = uc_mgr_evaluate_condition(uc_mgr, cfg, n);
if (err < 0)
return err;
continue;
}
if (strcmp(id, "Comment") == 0) {
err = parse_string(n, &modifier->comment);
if (err < 0) {
@ -845,7 +858,7 @@ static int parse_device(snd_use_case_mgr_t *uc_mgr,
struct use_case_verb *verb = data1;
const char *name;
struct use_case_device *device;
snd_config_iterator_t i;
snd_config_iterator_t i, next;
snd_config_t *n;
int err;
@ -870,20 +883,17 @@ static int parse_device(snd_use_case_mgr_t *uc_mgr,
list_add_tail(&device->list, &verb->device_list);
device->name = strdup(name);
snd_config_for_each_unsafe(i, cfg) {
/* in-place condition evaluation */
err = evaluate_condition(uc_mgr, cfg);
if (err < 0)
return err;
snd_config_for_each(i, next, cfg) {
const char *id;
n = snd_config_iterator_entry(i);
if (snd_config_get_id(n, &id) < 0)
continue;
/* in-place condition evaluation */
if (strcmp(id, "If") == 0) {
err = uc_mgr_evaluate_condition(uc_mgr, cfg, n);
if (err < 0)
return err;
continue;
}
if (strcmp(id, "Comment") == 0) {
err = parse_string(n, &device->comment);
if (err < 0) {
@ -1061,25 +1071,22 @@ static int parse_verb(snd_use_case_mgr_t *uc_mgr,
struct use_case_verb *verb,
snd_config_t *cfg)
{
snd_config_iterator_t i;
snd_config_iterator_t i, next;
snd_config_t *n;
int err;
/* in-place condition evaluation */
err = evaluate_condition(uc_mgr, cfg);
if (err < 0)
return err;
/* parse verb section */
snd_config_for_each_unsafe(i, cfg) {
snd_config_for_each(i, next, cfg) {
const char *id;
n = snd_config_iterator_entry(i);
if (snd_config_get_id(n, &id) < 0)
continue;
/* in-place condition evaluation */
if (strcmp(id, "If") == 0) {
err = uc_mgr_evaluate_condition(uc_mgr, cfg, n);
if (err < 0)
return err;
continue;
}
if (strcmp(id, "EnableSequence") == 0) {
uc_dbg("Parse EnableSequence");
err = parse_sequence(uc_mgr, &verb->enable_list, n);
@ -1138,7 +1145,7 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr,
const char *comment,
const char *file)
{
snd_config_iterator_t i;
snd_config_iterator_t i, next;
snd_config_t *n;
struct use_case_verb *verb;
snd_config_t *cfg;
@ -1178,21 +1185,18 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr,
return err;
}
/* in-place condition evaluation */
err = evaluate_condition(uc_mgr, cfg);
if (err < 0)
return err;
/* parse master config sections */
snd_config_for_each_unsafe(i, cfg) {
snd_config_for_each(i, next, cfg) {
const char *id;
n = snd_config_iterator_entry(i);
if (snd_config_get_id(n, &id) < 0)
continue;
/* in-place condition evaluation */
if (strcmp(id, "If") == 0) {
err = uc_mgr_evaluate_condition(uc_mgr, cfg, n);
if (err < 0)
return err;
continue;
}
/* find verb section and parse it */
if (strcmp(id, "SectionVerb") == 0) {
err = parse_verb(uc_mgr, verb, n);
@ -1250,7 +1254,7 @@ static int parse_master_section(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg,
void *data1 ATTRIBUTE_UNUSED,
void *data2 ATTRIBUTE_UNUSED)
{
snd_config_iterator_t i;
snd_config_iterator_t i, next;
snd_config_t *n;
const char *use_case_name, *file = NULL, *comment = NULL;
int err;
@ -1265,21 +1269,18 @@ static int parse_master_section(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg,
return -EINVAL;
}
/* in-place condition evaluation */
err = evaluate_condition(uc_mgr, cfg);
if (err < 0)
return err;
/* parse master config sections */
snd_config_for_each_unsafe(i, cfg) {
snd_config_for_each(i, next, cfg) {
const char *id;
n = snd_config_iterator_entry(i);
if (snd_config_get_id(n, &id) < 0)
continue;
/* in-place condition evaluation */
if (strcmp(id, "If") == 0) {
err = uc_mgr_evaluate_condition(uc_mgr, cfg, n);
if (err < 0)
return err;
continue;
}
/* get use case verb file name */
if (strcmp(id, "File") == 0) {
err = snd_config_get_string(n, &file);
@ -1380,7 +1381,7 @@ static int parse_controls(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg)
*/
static int parse_master_file(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg)
{
snd_config_iterator_t i;
snd_config_iterator_t i, next;
snd_config_t *n;
const char *id;
long l;
@ -1406,26 +1407,22 @@ static int parse_master_file(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg)
uc_error("Incompatible syntax %d in %s", l, uc_mgr->conf_file_name);
return -EINVAL;
}
/* delete this field to avoid strcmp() call in the loop */
snd_config_delete(n);
}
/* in-place condition evaluation */
err = evaluate_condition(uc_mgr, cfg);
if (err < 0)
return err;
/* parse master config sections */
snd_config_for_each_unsafe(i, cfg) {
snd_config_for_each(i, next, cfg) {
n = snd_config_iterator_entry(i);
if (snd_config_get_id(n, &id) < 0)
continue;
/* in-place condition evaluation */
if (strcmp(id, "If") == 0) {
err = uc_mgr_evaluate_condition(uc_mgr, cfg, n);
if (err < 0)
return err;
continue;
}
if (uc_mgr->conf_format >= 2 && strcmp(id, "Syntax") == 0)
continue;
if (strcmp(id, "Comment") == 0) {
err = parse_string(n, &uc_mgr->comment);
if (err < 0) {