]> git.alsa-project.org Git - alsa-utils.git/commitdiff
topology: Expand attribute references inside $[] expressions
authorJyri Sarha <jyri.sarha@linux.intel.com>
Sun, 31 Dec 2023 01:10:19 +0000 (03:10 +0200)
committerJaroslav Kysela <perex@perex.cz>
Wed, 24 Jan 2024 17:38:03 +0000 (18:38 +0100)
Properly expand referred object attributes inside $[] expression. This
allows for example this simplified case:

Define {
       CHANNELS 2
       BIT_DEPTH 16
}

Object.Base.foo {
channels $CHANNELS
sample_bits $BIT_DEPTH
frame_bits "$[$channels * $sample_bits]"
}

Closes: https://github.com/alsa-project/alsa-utils/pull/250
Reported-by: Seppo Ingalsuo <seppo.ingalsuo@linux.intel.com>
Signed-off-by: Jyri Sarha <jyri.sarha@linux.intel.com>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
topology/pre-process-object.c

index 34b92033435cfa9ba5541cf6ad69de7454796c08..7aa72c17c67a579ffed17a5604c4d1676508f9b0 100644 (file)
@@ -1603,6 +1603,7 @@ pre_process_object_variables_expand_fcn(snd_config_t **dst, const char *str, voi
        snd_config_t *object_cfg = tplg_pp->current_obj_cfg;
        snd_config_t *conf_defines;
        const char *object_id;
+       const char *val;
        int ret;
 
        ret = snd_config_search(tplg_pp->input_cfg, "Define", &conf_defines);
@@ -1614,14 +1615,30 @@ pre_process_object_variables_expand_fcn(snd_config_t **dst, const char *str, voi
        if (ret >= 0)
                return ret;
 
+       /* No global define found, proceeed to object attribute search */
        if (snd_config_get_id(object_cfg, &object_id) < 0)
                return -EINVAL;
 
        /* find variable from object attribute values if not found in global definitions */
        ret = pre_process_find_variable(dst, str, object_cfg);
-       if (ret < 0)
+       if (ret < 0) {
                SNDERR("Failed to find definition for attribute %s in '%s' object\n",
                       str, object_id);
+               return ret;
+       }
+
+       /* the extracted value may contain a nested $-expression */
+       if (snd_config_get_string(*dst, &val) >= 0) {
+               if (val[0] == '$') {
+                       char *var = strdup(val);
+
+                       snd_config_delete(*dst);
+                       ret = snd_config_evaluate_string(dst, var,
+                                                        pre_process_object_variables_expand_fcn,
+                                                        tplg_pp);
+                       free(var);
+               }
+       }
 
        return ret;
 }