]> git.alsa-project.org Git - alsa-lib.git/commitdiff
ucm: add possibility to keep order of childs for If blocks
authorJaroslav Kysela <perex@perex.cz>
Thu, 14 Nov 2019 15:57:22 +0000 (16:57 +0100)
committerJaroslav Kysela <perex@perex.cz>
Thu, 14 Nov 2019 16:21:20 +0000 (17:21 +0100)
Because of the nature of the structured parser, it is not guaranteed
that the order of the parsed tree is equal to the lines in the source.

Add possibility to insert the If results before or after the selected
identifier like:

SectionDevice."Speaker" {
  ...
}

If.1 {
Condition { ... }
Before.SectionDevice "Speaker"
True { ... }
}
If.2 {
Condition { ... }
After.SectionDevice "Speaker"
True { ... }
}

If the "After" or "Before" identifiers are not found, the result is added
after the last entry in the block.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
src/ucm/parser.c
src/ucm/ucm_cond.c

index fc4d0e20e368438beb34deafa7c16de08f343a97..afd2033684f4bf51347d4fed28297f63a17fa107 100644 (file)
@@ -175,7 +175,9 @@ static int evaluate_condition(snd_use_case_mgr_t *uc_mgr,
        if (err < 0)
                return err;
 
-       return uc_mgr_evaluate_condition(uc_mgr, cfg, n);
+       err = uc_mgr_evaluate_condition(uc_mgr, cfg, n);
+       snd_config_delete(n);
+       return err;
 }
 
 /*
index 3ec534c0eb0e9428b04390ad159647e5b89e3965..fcf5762b41670ad4bc0eecce4a9dceefd982f350 100644 (file)
@@ -250,7 +250,9 @@ static int if_eval(snd_use_case_mgr_t *uc_mgr, snd_config_t *eval)
 
 static int if_eval_one(snd_use_case_mgr_t *uc_mgr,
                       snd_config_t *cond,
-                      snd_config_t **result)
+                      snd_config_t **result,
+                      snd_config_t **before,
+                      snd_config_t **after)
 {
        snd_config_t *expr, *_true = NULL, *_false = NULL;
        int err;
@@ -279,6 +281,18 @@ static int if_eval_one(snd_use_case_mgr_t *uc_mgr,
                return -EINVAL;
        }
 
+       err = snd_config_search(cond, "Before", before);
+       if (err < 0 && err != -ENOENT) {
+               uc_error("before block identifier error");
+               return -EINVAL;
+       }
+
+       err = snd_config_search(cond, "After", after);
+       if (err < 0 && err != -ENOENT) {
+               uc_error("before block identifier error");
+               return -EINVAL;
+       }
+
        err = if_eval(uc_mgr, expr);
        if (err > 0) {
                *result = _true;
@@ -302,10 +316,13 @@ static void config_dump(snd_config_t *cfg)
 }
 #endif
 
-static int compound_merge(snd_config_t *dst, snd_config_t *src)
+static int compound_merge(const char *id,
+                         snd_config_t *dst, snd_config_t *src,
+                         snd_config_t *before, snd_config_t *after)
 {
        snd_config_iterator_t i, next;
-       snd_config_t *n;
+       snd_config_t *n, *_before = NULL, *_after = NULL;
+       const char *s;
        int err;
 
        if (snd_config_get_type(src) != SND_CONFIG_TYPE_COMPOUND) {
@@ -313,14 +330,52 @@ static int compound_merge(snd_config_t *dst, snd_config_t *src)
                return -EINVAL;
        }
 
+       if (before) {
+               err = get_string(before, id, &s);
+               if (err < 0 && err != -ENOENT)
+                       return err;
+               if (err == 0) {
+                       err = snd_config_search(dst, s, &_before);
+                       if (err < 0 && err != -ENOENT)
+                               return err;
+               }
+       }
+       if (after) {
+               err = get_string(after, id, &s);
+               if (err < 0 && err != -ENOENT)
+                       return err;
+               if (err == 0) {
+                       err = snd_config_search(dst, s, &_after);
+                       if (err < 0 && err != -ENOENT)
+                               return err;
+               }
+       }
+
+       if (_before && _after) {
+               uc_error("defined both before and after identifiers in the If block");
+               return -EINVAL;
+       }
+
        snd_config_for_each(i, next, src) {
                n = snd_config_iterator_entry(i);
                err = snd_config_remove(n);
                if (err < 0)
                        return err;
-               err = snd_config_add(dst, n);
-               if (err < 0) {
-                       return err;
+               if (_before) {
+                       err = snd_config_add_before(_before, n);
+                       if (err < 0)
+                               return err;
+                       _before = NULL;
+                       _after = n;
+               } else if (_after) {
+                       err = snd_config_add_after(_after, n);
+                       if (err < 0)
+                               return err;
+                       _after = n;
+               } else {
+                       err = snd_config_add(dst, n);
+                       if (err < 0)
+                               return err;
                }
        }
 
@@ -335,7 +390,7 @@ int uc_mgr_evaluate_condition(snd_use_case_mgr_t *uc_mgr,
                              snd_config_t *cond)
 {
        snd_config_iterator_t i, i2, next, next2;
-       snd_config_t *a, *n, *n2, *parent2;
+       snd_config_t *a, *n, *n2, *parent2, *before, *after;
        const char *id;
        int err;
 
@@ -351,9 +406,12 @@ int uc_mgr_evaluate_condition(snd_use_case_mgr_t *uc_mgr,
 
        snd_config_for_each(i, next, cond) {
                n = snd_config_iterator_entry(i);
-               err = if_eval_one(uc_mgr, n, &a);
+               before = after = NULL;
+               err = if_eval_one(uc_mgr, n, &a, &before, &after);
                if (err < 0)
                        return err;
+               if (a == NULL)
+                       continue;
                err = snd_config_search(a, "If", &n2);
                if (err < 0 && err != -ENOENT) {
                        uc_error("If block error (If)");
@@ -380,7 +438,7 @@ __add:
                                err = snd_config_search(parent, id, &parent2);
                                if (err == -ENOENT)
                                        goto __add;
-                               err = compound_merge(parent2, n2);
+                               err = compound_merge(id, parent2, n2, before, after);
                                if (err < 0)
                                        return err;
                        }