summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2022-05-12 18:33:29 +0200
committerJaroslav Kysela <perex@perex.cz>2022-05-13 16:10:51 +0200
commitd65b1c7b52503cd1ff22998eaf182d9c68f0c03e (patch)
treee7aec0bb003c044423fee0e42bb90e3cb0c46e33
parentf1fa7ea07768bd5dbe15462ef734b28380a12a43 (diff)
downloadalsa-lib-d65b1c7b52503cd1ff22998eaf182d9c68f0c03e.tar.gz
ucm: add ${evali:} substitution
Example: Define.var1 2 LibraryConfig.test.SubstiConfig { a "${evali:$var1+1}" } Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r--include/conf.h1
-rw-r--r--src/ucm/ucm_confdoc.h6
-rw-r--r--src/ucm/ucm_subs.c39
3 files changed, 45 insertions, 1 deletions
diff --git a/include/conf.h b/include/conf.h
index 56ba6c23..800707d9 100644
--- a/include/conf.h
+++ b/include/conf.h
@@ -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,
diff --git a/src/ucm/ucm_confdoc.h b/src/ucm/ucm_confdoc.h
index 7241f5e8..430afa27 100644
--- a/src/ucm/ucm_confdoc.h
+++ b/src/ucm/ucm_confdoc.h
@@ -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
diff --git a/src/ucm/ucm_subs.c b/src/ucm/ucm_subs.c
index 530bccbd..fd3dcc6d 100644
--- a/src/ucm/ucm_subs.c
+++ b/src/ucm/ucm_subs.c
@@ -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;