mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-10 08:15:43 +01:00
topology: Add option to pass pre-processor definitions
Add a -D switch to be able to pass pre-processor definitions that will be used to expand arguments in the input config file. This will be useful to generate multiple topology binaries from the same input config file with different argument values. For example: if we had a pipeline config as follows: Object.Pipeline { volume-playback.1 { dynamic_pipeline $DYNAMIC_PIPELINE } } We can define the variable for DYNAMIC_PIPELINE as: Define { DYNAMIC_PIPELINE 0 } And when pre-processing the conf file pass "-D DYNAMIC_PIPELINE=1" to override the default value for dynamic_pipeline attribute in the input conf file. Signed-off-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
c4e43384fc
commit
da8f90c424
3 changed files with 118 additions and 10 deletions
|
@ -222,7 +222,93 @@ err:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pre_process(struct tplg_pre_processor *tplg_pp, char *config, size_t config_size)
|
static int pre_process_defines(struct tplg_pre_processor *tplg_pp, const char *pre_processor_defs,
|
||||||
|
snd_config_t *top)
|
||||||
|
{
|
||||||
|
snd_config_t *conf_defines, *defines;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = snd_config_search(tplg_pp->input_cfg, "Define", &conf_defines);
|
||||||
|
if (ret < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (snd_config_get_type(conf_defines) != SND_CONFIG_TYPE_COMPOUND)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* load and merge the command line defines with the variables in the conf file to override
|
||||||
|
* default values
|
||||||
|
*/
|
||||||
|
if (pre_processor_defs != NULL) {
|
||||||
|
ret = snd_config_load_string(&defines, pre_processor_defs, strlen(pre_processor_defs));
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "Failed to load pre-processor command line definitions\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = snd_config_merge(conf_defines, defines, true);
|
||||||
|
if (ret < 0) {
|
||||||
|
fprintf(stderr, "Failed to override variable definitions\n");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pre_process_variables_expand_fcn(snd_config_t **dst, const char *str,
|
||||||
|
void *private_data)
|
||||||
|
{
|
||||||
|
struct tplg_pre_processor *tplg_pp = private_data;
|
||||||
|
snd_config_iterator_t i, next;
|
||||||
|
snd_config_t *conf_defines;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = snd_config_search(tplg_pp->input_cfg, "Define", &conf_defines);
|
||||||
|
if (ret < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/* find variable definition */
|
||||||
|
snd_config_for_each(i, next, conf_defines) {
|
||||||
|
snd_config_t *n;
|
||||||
|
const char *id;
|
||||||
|
|
||||||
|
n = snd_config_iterator_entry(i);
|
||||||
|
if (snd_config_get_id(n, &id) < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (strcmp(id, str))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* found definition. Match type and return appropriate config */
|
||||||
|
if (snd_config_get_type(n) == SND_CONFIG_TYPE_STRING) {
|
||||||
|
const char *s;
|
||||||
|
|
||||||
|
if (snd_config_get_string(n, &s) < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
return snd_config_imake_string(dst, NULL, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (snd_config_get_type(n) == SND_CONFIG_TYPE_INTEGER) {
|
||||||
|
long v;
|
||||||
|
|
||||||
|
if (snd_config_get_integer(n, &v) < 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
ret = snd_config_imake_integer(dst, NULL, v);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "No definition for variable %s\n", str);
|
||||||
|
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pre_process(struct tplg_pre_processor *tplg_pp, char *config, size_t config_size,
|
||||||
|
const char *pre_processor_defs)
|
||||||
{
|
{
|
||||||
snd_input_t *in;
|
snd_input_t *in;
|
||||||
snd_config_t *top;
|
snd_config_t *top;
|
||||||
|
@ -249,7 +335,22 @@ int pre_process(struct tplg_pre_processor *tplg_pp, char *config, size_t config_
|
||||||
|
|
||||||
tplg_pp->input_cfg = top;
|
tplg_pp->input_cfg = top;
|
||||||
|
|
||||||
err = pre_process_config(tplg_pp, top);
|
/* parse command line definitions */
|
||||||
|
err = pre_process_defines(tplg_pp, pre_processor_defs, tplg_pp->input_cfg);
|
||||||
|
if (err < 0) {
|
||||||
|
fprintf(stderr, "Failed to parse arguments in input config\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* expand pre-processor variables */
|
||||||
|
err = snd_config_expand_custom(tplg_pp->input_cfg, tplg_pp->input_cfg, pre_process_variables_expand_fcn,
|
||||||
|
tplg_pp, &tplg_pp->input_cfg);
|
||||||
|
if (err < 0) {
|
||||||
|
fprintf(stderr, "Failed to expand pre-processor definitions in input config\n");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = pre_process_config(tplg_pp, tplg_pp->input_cfg);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
fprintf(stderr, "Unable to pre-process configuration\n");
|
fprintf(stderr, "Unable to pre-process configuration\n");
|
||||||
goto err;
|
goto err;
|
||||||
|
|
|
@ -234,7 +234,8 @@ static int dump(const char *source_file, const char *output_file, int cflags, in
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Convert Topology2.0 conf to the existing conf syntax */
|
/* Convert Topology2.0 conf to the existing conf syntax */
|
||||||
static int pre_process_conf(const char *source_file, const char *output_file)
|
static int pre_process_conf(const char *source_file, const char *output_file,
|
||||||
|
const char *pre_processor_defs)
|
||||||
{
|
{
|
||||||
struct tplg_pre_processor *tplg_pp;
|
struct tplg_pre_processor *tplg_pp;
|
||||||
size_t config_size;
|
size_t config_size;
|
||||||
|
@ -254,7 +255,7 @@ static int pre_process_conf(const char *source_file, const char *output_file)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* pre-process conf file */
|
/* pre-process conf file */
|
||||||
err = pre_process(tplg_pp, config, config_size);
|
err = pre_process(tplg_pp, config, config_size, pre_processor_defs);
|
||||||
|
|
||||||
/* free pre-processor */
|
/* free pre-processor */
|
||||||
free_pre_preprocessor(tplg_pp);
|
free_pre_preprocessor(tplg_pp);
|
||||||
|
@ -262,7 +263,8 @@ static int pre_process_conf(const char *source_file, const char *output_file)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int compile(const char *source_file, const char *output_file, int cflags)
|
static int compile(const char *source_file, const char *output_file, int cflags,
|
||||||
|
const char *pre_processor_defs)
|
||||||
{
|
{
|
||||||
struct tplg_pre_processor *tplg_pp = NULL;
|
struct tplg_pre_processor *tplg_pp = NULL;
|
||||||
snd_tplg_t *tplg;
|
snd_tplg_t *tplg;
|
||||||
|
@ -284,7 +286,7 @@ static int compile(const char *source_file, const char *output_file, int cflags)
|
||||||
init_pre_precessor(&tplg_pp, SND_OUTPUT_BUFFER, NULL);
|
init_pre_precessor(&tplg_pp, SND_OUTPUT_BUFFER, NULL);
|
||||||
|
|
||||||
/* pre-process conf file */
|
/* pre-process conf file */
|
||||||
err = pre_process(tplg_pp, config, config_size);
|
err = pre_process(tplg_pp, config, config_size, pre_processor_defs);
|
||||||
if (err) {
|
if (err) {
|
||||||
free_pre_preprocessor(tplg_pp);
|
free_pre_preprocessor(tplg_pp);
|
||||||
free(config);
|
free(config);
|
||||||
|
@ -353,7 +355,7 @@ static int decode(const char *source_file, const char *output_file,
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
static const char short_options[] = "hc:d:n:u:v:o:pP:sgxzV";
|
static const char short_options[] = "hc:d:n:u:v:o:pP:sgxzVD:";
|
||||||
static const struct option long_options[] = {
|
static const struct option long_options[] = {
|
||||||
{"help", 0, NULL, 'h'},
|
{"help", 0, NULL, 'h'},
|
||||||
{"verbose", 1, NULL, 'v'},
|
{"verbose", 1, NULL, 'v'},
|
||||||
|
@ -372,6 +374,7 @@ int main(int argc, char *argv[])
|
||||||
};
|
};
|
||||||
char *source_file = NULL;
|
char *source_file = NULL;
|
||||||
char *output_file = NULL;
|
char *output_file = NULL;
|
||||||
|
const char *pre_processor_defs = NULL;
|
||||||
int c, err, op = 'c', cflags = 0, dflags = 0, sflags = 0, option_index;
|
int c, err, op = 'c', cflags = 0, dflags = 0, sflags = 0, option_index;
|
||||||
|
|
||||||
#ifdef ENABLE_NLS
|
#ifdef ENABLE_NLS
|
||||||
|
@ -423,6 +426,9 @@ int main(int argc, char *argv[])
|
||||||
case 'x':
|
case 'x':
|
||||||
sflags |= SND_TPLG_SAVE_NOCHECK;
|
sflags |= SND_TPLG_SAVE_NOCHECK;
|
||||||
break;
|
break;
|
||||||
|
case 'D':
|
||||||
|
pre_processor_defs = optarg;
|
||||||
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
version(argv[0]);
|
version(argv[0]);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -448,13 +454,13 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case 'c':
|
case 'c':
|
||||||
err = compile(source_file, output_file, cflags);
|
err = compile(source_file, output_file, cflags, pre_processor_defs);
|
||||||
break;
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
err = decode(source_file, output_file, cflags, dflags, sflags);
|
err = decode(source_file, output_file, cflags, dflags, sflags);
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'P':
|
||||||
err = pre_process_conf(source_file, output_file);
|
err = pre_process_conf(source_file, output_file, pre_processor_defs);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
err = dump(source_file, output_file, cflags, sflags);
|
err = dump(source_file, output_file, cflags, sflags);
|
||||||
|
|
|
@ -27,7 +27,8 @@ struct tplg_pre_processor {
|
||||||
snd_output_t *dbg_output;
|
snd_output_t *dbg_output;
|
||||||
};
|
};
|
||||||
|
|
||||||
int pre_process(struct tplg_pre_processor *tplg_pp, char *config, size_t config_size);
|
int pre_process(struct tplg_pre_processor *tplg_pp, char *config, size_t config_size,
|
||||||
|
const char *pre_processor_defs);
|
||||||
int init_pre_precessor(struct tplg_pre_processor **tplg_pp, snd_output_type_t type,
|
int init_pre_precessor(struct tplg_pre_processor **tplg_pp, snd_output_type_t type,
|
||||||
const char *output_file);
|
const char *output_file);
|
||||||
void free_pre_preprocessor(struct tplg_pre_processor *tplg_pp);
|
void free_pre_preprocessor(struct tplg_pre_processor *tplg_pp);
|
||||||
|
|
Loading…
Reference in a new issue