OSDN Git Service

ucm: change the If block parsing
authorJaroslav Kysela <perex@perex.cz>
Thu, 14 Nov 2019 14:13:36 +0000 (15:13 +0100)
committerJaroslav Kysela <perex@perex.cz>
Thu, 14 Nov 2019 14:13:38 +0000 (15:13 +0100)
- evaluate always If before the other blocks

include/conf.h
src/ucm/parser.c

index daf6f65..d44c0a2 100644 (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);
index ef30886..fc4d0e2 100644 (file)
@@ -161,6 +161,24 @@ int parse_get_safe_id(snd_config_t *n, const char **id)
 }
 
 /*
+ * 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
  */
 static int parse_transition(snd_use_case_mgr_t *uc_mgr,
@@ -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) {