ucm: add ${evali:} substitution

Example:

  Define.var1 2

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

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Jaroslav Kysela 2022-05-12 18:33:29 +02:00
parent f1fa7ea077
commit d65b1c7b52
3 changed files with 45 additions and 1 deletions

View 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(snd_config_t *config);
int snd_config_delete_compound_members(const 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_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_merge(snd_config_t *dst, snd_config_t *src, int override);
int snd_config_make(snd_config_t **config, const char *key, int snd_config_make(snd_config_t **config, const char *key,

View 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-card:<str>} | Find a card - see _Find card substitution_ section
${find-device:<str>} | Find a device - see _Find device 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 #### Find card substitution
This substitutions finds the ALSA card and returns the appropriate identifier or This substitutions finds the ALSA card and returns the appropriate identifier or

View file

@ -582,7 +582,7 @@ static char *rval_eval(snd_use_case_mgr_t *uc_mgr, const char *e)
int err; int err;
if (uc_mgr->conf_format < 5) { 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; return NULL;
} }
err = _snd_eval_string(&dst, e, rval_eval_var_cb, uc_mgr); 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; 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) \ #define MATCH_VARIABLE(name, id, fcn, empty_ok) \
if (strncmp((name), (id), sizeof(id) - 1) == 0) { \ if (strncmp((name), (id), sizeof(id) - 1) == 0) { \
rval = fcn(uc_mgr); \ 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; return err;
if (!uc_mgr_substitute_check(s2)) if (!uc_mgr_substitute_check(s2))
return 0; 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); err = uc_mgr_get_substituted_value(uc_mgr, &s, s2);
if (err < 0) if (err < 0)
return err; return err;