]> git.alsa-project.org Git - alsa-lib.git/commitdiff
ucm: allow string with substitution for If.Condition block (Syntax 9)
authorJaroslav Kysela <perex@perex.cz>
Fri, 6 Feb 2026 17:41:30 +0000 (18:41 +0100)
committerJaroslav Kysela <perex@perex.cz>
Fri, 6 Feb 2026 18:32:31 +0000 (19:32 +0100)
When If.Condition is a string type instead of compound, parse it using
snd_config_load_string with variable substitution support for syntax v9+.
This allows more flexible condition definitions using variable references.

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

index a8b85f1feaa6579e3451ba19d95f5f58474a65a3..f7147f5960008a29e143a64e00c9e7470697b26a 100644 (file)
@@ -452,7 +452,9 @@ static int if_eval_one(snd_use_case_mgr_t *uc_mgr,
                       snd_config_t **prepend,
                       snd_config_t **append)
 {
-       snd_config_t *expr, *_true = NULL, *_false = NULL;
+       snd_config_t *expr, *expr_eval = NULL, *_true = NULL, *_false = NULL;
+       const char *s;
+       char *s1;
        int err, has_condition;
 
        *result = NULL;
@@ -467,73 +469,99 @@ static int if_eval_one(snd_use_case_mgr_t *uc_mgr,
        /* For syntax v8+, Condition is optional if Prepend or Append is present */
        has_condition = snd_config_search(cond, "Condition", &expr) >= 0;
 
+       if (has_condition && uc_mgr->conf_format >= 9 &&
+           snd_config_get_type(expr) == SND_CONFIG_TYPE_STRING) {
+               err = snd_config_get_string(expr, &s);
+               if (err < 0) {
+                       snd_error(UCM, "Condition string error (If)");
+                       return -EINVAL;
+               }
+               err = uc_mgr_get_substituted_value(uc_mgr, &s1, s);
+               if (err >= 0) {
+                       err = snd_config_load_string(&expr_eval, s1, 0);
+                       free(s1);
+               }
+               if (err < 0) {
+                       snd_error(UCM, "Condition string parse error (If)");
+                       return err;
+               }
+               expr = expr_eval;
+       }
+
        if (uc_mgr->conf_format >= 8) {
                /* Check for Prepend block */
                err = snd_config_search(cond, "Prepend", prepend);
                if (err < 0 && err != -ENOENT) {
                        snd_error(UCM, "prepend block error (If)");
-                       return -EINVAL;
+                       goto __error;
                }
 
                /* Check for Append block */
                err = snd_config_search(cond, "Append", append);
                if (err < 0 && err != -ENOENT) {
                        snd_error(UCM, "append block error (If)");
-                       return -EINVAL;
+                       goto __error;
                }
 
                /* If Prepend or Append is present, Condition can be omitted */
                if (!has_condition && (*prepend == NULL && *append == NULL)) {
                        snd_error(UCM, "condition block expected (If)");
-                       return -EINVAL;
+                       goto __error;
                }
        } else {
                if (!has_condition) {
                        snd_error(UCM, "condition block expected (If)");
-                       return -EINVAL;
+                       goto __error;
                }
        }
 
        err = snd_config_search(cond, "True", &_true);
        if (err < 0 && err != -ENOENT) {
                snd_error(UCM, "true block error (If)");
-               return -EINVAL;
+               goto __error;
        }
 
        err = snd_config_search(cond, "False", &_false);
        if (err < 0 && err != -ENOENT) {
                snd_error(UCM, "false block error (If)");
-               return -EINVAL;
+               goto __error;
        }
 
        err = snd_config_search(cond, "Before", before);
        if (err < 0 && err != -ENOENT) {
                snd_error(UCM, "before block identifier error");
-               return -EINVAL;
+               goto __error;
        }
 
        err = snd_config_search(cond, "After", after);
        if (err < 0 && err != -ENOENT) {
                snd_error(UCM, "before block identifier error");
-               return -EINVAL;
+               goto __error;
        }
 
        /* Evaluate condition if present */
        if (has_condition) {
                err = if_eval(uc_mgr, expr);
+               if (err < 0)
+                       goto __error;
                if (err > 0) {
                        *result = _true;
-                       return 0;
+                       goto __return;
                } else if (err == 0) {
                        *result = _false;
-                       return 0;
-               } else {
-                       return err;
+                       goto __return;
                }
        }
 
        /* If no condition (v8+ with Prepend/Append only), no result block */
        return 0;
+
+__error:
+       err = -EINVAL;
+__return:
+       if (expr_eval)
+               snd_config_delete(expr_eval);
+       return err;
 }
 
 #if 0