]> git.alsa-project.org Git - alsa-lib.git/commitdiff
ucm: add ${evali:} substitution
authorJaroslav Kysela <perex@perex.cz>
Thu, 12 May 2022 16:33:29 +0000 (18:33 +0200)
committerJaroslav Kysela <perex@perex.cz>
Fri, 13 May 2022 14:10:51 +0000 (16:10 +0200)
Example:

  Define.var1 2

  LibraryConfig.test.SubstiConfig {
          a "${evali:$var1+1}"
  }

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
include/conf.h
src/ucm/ucm_confdoc.h
src/ucm/ucm_subs.c

index 56ba6c233c30f09acb2f46e57929a43edbb33d21..800707d9c182e20a20f5533149e0adf54f4519f5 100644 (file)
@@ -129,6 +129,7 @@ int snd_config_remove(snd_config_t *config);
 int snd_config_delete(snd_config_t *config);
 int snd_config_delete_compound_members(const snd_config_t *config);
 int snd_config_copy(snd_config_t **dst, snd_config_t *src);
+int snd_config_substitute(snd_config_t *dst, snd_config_t *src);
 int snd_config_merge(snd_config_t *dst, snd_config_t *src, int override);
 
 int snd_config_make(snd_config_t **config, const char *key,
index 7241f5e8284814f9613fe6b6290b2a0d6e292bca..430afa271976400add751aa1c6664346ee889ff1 100644 (file)
@@ -383,6 +383,12 @@ ${eval:<str>}        | Evaluate expression like *($var+2)/3* [**Syntax 5**]
 ${find-card:<str>}   | Find a card - see _Find card substitution_ section
 ${find-device:<str>} | Find a device - see _Find device substitution_ section
 
+#### Special whole string substitution
+
+Substituted string   | Value
+---------------------|---------------------
+${evali:<str>}       | Evaluate expression like *($var+2)/3* [**Syntax 5**]; target node will be integer; substituted only in the LibraryConfig subtree
+
 #### Find card substitution
 
 This substitutions finds the ALSA card and returns the appropriate identifier or
index 530bccbd91ab8c26430b9248378e1d596bed8f65..fd3dcc6d628905cbdebb57aab231e76b3d488440 100644 (file)
@@ -582,7 +582,7 @@ static char *rval_eval(snd_use_case_mgr_t *uc_mgr, const char *e)
        int err;
 
        if (uc_mgr->conf_format < 5) {
-               uc_error("variable substitution is supported in v5+ syntax");
+               uc_error("variable evaluation is supported in v5+ syntax");
                return NULL;
        }
        err = _snd_eval_string(&dst, e, rval_eval_var_cb, uc_mgr);
@@ -597,6 +597,41 @@ static char *rval_eval(snd_use_case_mgr_t *uc_mgr, const char *e)
        return r;
 }
 
+static int rval_evali(snd_use_case_mgr_t *uc_mgr, snd_config_t *node, const char *e)
+{
+       snd_config_t *dst;
+       const char *id;
+       char *s;
+       size_t l;
+       int err;
+
+       if (uc_mgr->conf_format < 5) {
+               uc_error("variable evaluation is supported in v5+ syntax");
+               return -EINVAL;
+       }
+       err = snd_config_get_id(node, &id);
+       if (err < 0)
+               return err;
+       l = strlen(e);
+       if (e[l-1] != '}')
+               return -EINVAL;
+       s = malloc(l + 1);
+       if (s == NULL)
+               return -ENOMEM;
+       strcpy(s, e);
+       s[l-1] = '\0';
+       err = _snd_eval_string(&dst, s + 8, rval_eval_var_cb, uc_mgr);
+       free(s);
+       if (err < 0) {
+               uc_error("unable to evaluate '%s'", e);
+               return err;
+       }
+       err = snd_config_set_id(dst, id);
+       if (err < 0)
+               return err;
+       return snd_config_substitute(node, dst);
+}
+
 #define MATCH_VARIABLE(name, id, fcn, empty_ok)                                \
        if (strncmp((name), (id), sizeof(id) - 1) == 0) {               \
                rval = fcn(uc_mgr);                                     \
@@ -819,6 +854,8 @@ int uc_mgr_substitute_tree(snd_use_case_mgr_t *uc_mgr, snd_config_t *node)
                                return err;
                        if (!uc_mgr_substitute_check(s2))
                                return 0;
+                       if (strncmp(s2, "${evali:", 8) == 0)
+                               return rval_evali(uc_mgr, node, s2);
                        err = uc_mgr_get_substituted_value(uc_mgr, &s, s2);
                        if (err < 0)
                                return err;