From: Jaroslav Kysela Date: Thu, 14 Nov 2019 14:13:36 +0000 (+0100) Subject: ucm: change the If block parsing X-Git-Tag: v1.2.1~3 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=4724158c0a0822c7497121312d18a7b3e4c5bc96;p=alsa-lib.git ucm: change the If block parsing - evaluate always If before the other blocks --- diff --git a/include/conf.h b/include/conf.h index daf6f658..d44c0a2f 100644 --- a/include/conf.h +++ b/include/conf.h @@ -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); diff --git a/src/ucm/parser.c b/src/ucm/parser.c index ef308868..fc4d0e20 100644 --- a/src/ucm/parser.c +++ b/src/ucm/parser.c @@ -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) {