From a4768a7b10684dbd10b2f6ab35280d713bec9c56 Mon Sep 17 00:00:00 2001 From: Abramo Bagnara Date: Sat, 16 Jun 2001 08:19:15 +0000 Subject: [PATCH] Simplified evaluation using snd_config_walk. Fixed implementation --- include/conf.h | 2 + src/alsa.conf | 56 ++++++++++++- src/conf.c | 211 ++++++++++++++++++++++++------------------------- src/confmisc.c | 105 ++++++++++++++---------- 4 files changed, 224 insertions(+), 150 deletions(-) diff --git a/include/conf.h b/include/conf.h index 12c115fe..415adf4b 100644 --- a/include/conf.h +++ b/include/conf.h @@ -40,6 +40,8 @@ int snd_config_search_definition(snd_config_t *config, int snd_config_expand(snd_config_t *config, const char *args, void *private_data, snd_config_t **result); +int snd_config_evaluate(snd_config_t *config, void *private_data, + snd_config_t **result); int snd_config_add(snd_config_t *config, snd_config_t *leaf); int snd_config_delete(snd_config_t *config); diff --git a/src/alsa.conf b/src/alsa.conf index baf3a443..9d824ce2 100644 --- a/src/alsa.conf +++ b/src/alsa.conf @@ -10,9 +10,24 @@ pcm.hw { @args [ CARD DEV SUBDEV ] @args.CARD { type integer + default { + @func igetenv + envname [ + ALSA_PCM_CARD + ALSA_CARD + ] + default 0 + } } @args.DEV { type integer + default { + @func igetenv + envname [ + ALSA_PCM_DEVICE + ] + default 0 + } } @args.SUBDEV { type integer @@ -28,9 +43,24 @@ pcm.plughw { @args [ CARD DEV SUBDEV ] @args.CARD { type integer + default { + @func igetenv + envname [ + ALSA_PCM_CARD + ALSA_CARD + ] + default 0 + } } @args.DEV { type integer + default { + @func igetenv + envname [ + ALSA_PCM_DEVICE + ] + default 0 + } } @args.SUBDEV { type integer @@ -444,6 +474,14 @@ ctl.hw { @args[ CARD ] @args.CARD { type integer + default { + @func igetenv + envname [ + ALSA_CTL_CARD + ALSA_CARD + ] + default 0 + } } type hw card $(CARD) @@ -465,8 +503,9 @@ ctl.shm { ctl.default { type hw card { - @func getenv + @func igetenv envname [ + ALSA_CTL_CARD ALSA_CARD ] default 0 @@ -481,9 +520,24 @@ rawmidi.hw { @args [ CARD DEV SUBDEV ] @args.CARD { type integer + default { + @func igetenv + envname [ + ALSA_RAWMIDI_CARD + ALSA_CARD + ] + default 0 + } } @args.DEV { type integer + default { + @func igetenv + envname [ + ALSA_RAWMIDI_DEVICE + ] + default 0 + } } @args.SUBDEV { type integer diff --git a/src/conf.c b/src/conf.c index 263212e0..f6252f3c 100644 --- a/src/conf.c +++ b/src/conf.c @@ -1862,124 +1862,112 @@ static int _snd_config_expand(snd_config_t *src, return 1; } -static int evaluate_node(snd_config_t *father, snd_config_t *src, - void *private_data, snd_config_t **dst) +void snd_config_substitute(snd_config_t *dst, snd_config_t *src) { - snd_config_iterator_t i, next; - const char *lib = NULL, *func = NULL; - int err; - char buf[64]; - char *evaluate_name = NULL; - int (*evaluate_func)(snd_config_t **dst, snd_config_t *src, void *private_data); - void *h; - - assert(father && src && dst); + free(dst->id); + dst->id = src->id; + dst->type = src->type; + dst->u = src->u; +} - snd_config_for_each(i, next, src) { - snd_config_t *n = snd_config_iterator_entry(i); - const char *id; - if (snd_config_get_type(n) == SND_CONFIG_TYPE_COMPOUND) { - snd_config_t *n1; - err = evaluate_node(src, n, private_data, &n1); - if (err < 0) { - SNDERR("Error in node %s", snd_config_get_id(n)); - goto __error; +static int _snd_config_evaluate(snd_config_t *src, + snd_config_t **dst ATTRIBUTE_UNUSED, + snd_config_walk_pass_t pass, + void *private_data) +{ + int err; + if (pass == SND_CONFIG_WALK_PASS_PRE) { + char buf[256]; + const char *lib = NULL, *func_name = NULL; + const char *str; + int (*func)(snd_config_t **dst, snd_config_t *src, + void *private_data); + void *h; + snd_config_t *c, *eval, *func_conf = NULL; + err = snd_config_search(src, "@func", &c); + if (err < 0) + return 1; + err = snd_config_get_string(c, &str); + if (err < 0) { + SNDERR("Invalid type for @func"); + return err; + } + err = snd_config_search_definition(snd_config, "func", str, &func_conf); + if (err >= 0) { + snd_config_iterator_t i, next; + if (snd_config_get_type(func_conf) != SND_CONFIG_TYPE_COMPOUND) { + SNDERR("Invalid type for func %s definition", str); + goto _err; } - if (n1) { /* replace node */ - snd_config_delete(n); - err = snd_config_add(src, n1); - if (err < 0) - goto __error; + snd_config_for_each(i, next, func_conf) { + snd_config_t *n = snd_config_iterator_entry(i); + const char *id = snd_config_get_id(n); + if (strcmp(id, "comment") == 0) + continue; + if (strcmp(id, "lib") == 0) { + err = snd_config_get_string(n, &lib); + if (err < 0) { + SNDERR("Invalid type for %s", id); + goto _err; + } + continue; + } + if (strcmp(id, "open") == 0) { + err = snd_config_get_string(n, &func_name); + if (err < 0) { + SNDERR("Invalid type for %s", id); + goto _err; + } + continue; + } + SNDERR("Unknown field %s", id); + _err: + snd_config_delete(func_conf); + return -EINVAL; } } - id = snd_config_get_id(n); - if (*id++ != '@') /* quick look */ - continue; - if (!strcmp(id, "lib")) { - if ((err = snd_config_get_string(n, &lib)) < 0) { - _invalid_field: - SNDERR("Unknown type of field %s", id); - return err; - } - lib = strdup(lib); - if (lib == NULL) - goto __error; - snd_config_delete(n); - } else if (!strcmp(id, "func")) { - if ((err = snd_config_get_string(n, &func)) < 0) - goto _invalid_field; - func = strdup(func); - if (func == NULL) - goto __error; - snd_config_delete(n); + if (!func_name) { + func_name = buf; + snprintf(buf, sizeof(buf), "snd_func_%s", str); + } + if (!lib) + lib = ALSA_LIB; + h = dlopen(lib, RTLD_NOW); + if (h) + func = dlsym(h, func_name); + if (func_conf) + snd_config_delete(func_conf); + if (!h) { + SNDERR("Cannot open shared library %s", lib); + return -ENOENT; } - } - - if (func == NULL) { - *dst = NULL; - return 0; - } - - if (evaluate_name == NULL) { - snprintf(buf, sizeof(buf), "snd_func_%s", func); - buf[sizeof(buf) - 1] = '\0'; - evaluate_name = buf; - } - - h = dlopen(lib, RTLD_NOW); - if (!h) { - SNDERR("Cannot open shared library %s", lib); - err = -ENOENT; - goto __error; - } - evaluate_func = dlsym(h, evaluate_name); - if (!evaluate_func) { + if (!func) { + SNDERR("symbol %s is not defined inside %s", func_name, lib); + dlclose(h); + return -ENXIO; + } + err = func(&eval, src, private_data); dlclose(h); - SNDERR("symbol %s is not defined inside %s", evaluate_name, lib ? lib : ALSA_LIB); - err = -ENXIO; - goto __error; - } - err = evaluate_func(dst, src, private_data); - dlclose(h); - if (err < 0) { - SNDERR("function %s returned error: %s", evaluate_name, snd_strerror(err)); - goto __error; + if (err < 0) { + SNDERR("function %s returned error: %s", func_name, snd_strerror(err)); + return err; + } + if (eval) { + snd_config_substitute(src, eval); + free(eval); + } + return 0; } - err = 0; - - __error: - if (func) - free((void *)func); - if (lib) - free((void *)lib); - return err; + return 1; } -int snd_config_evaluate(snd_config_t *conf, void *private_data) -{ - snd_config_iterator_t i, next; - assert(conf); - if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND) - return 0; - snd_config_for_each(i, next, conf) { - snd_config_t *n = snd_config_iterator_entry(i); - if (snd_config_get_type(n) == SND_CONFIG_TYPE_COMPOUND) { - snd_config_t *n1; - int err = evaluate_node(conf, n, private_data, &n1); - if (err < 0) { - SNDERR("Error in node %s", snd_config_get_id(n)); - return err; - } - if (n1) { /* replace node */ - snd_config_delete(n); - err = snd_config_add(conf, n1); - if (err < 0) - return err; - } - } - } - return 0; +int snd_config_evaluate(snd_config_t *config, void *private_data, + snd_config_t **result) +{ + /* FIXME: Only in place evaluation is currently implemented */ + assert(result == NULL); + return snd_config_walk(config, result, _snd_config_evaluate, private_data); } static int load_defaults(snd_config_t *subs, snd_config_t *defs) @@ -2383,13 +2371,18 @@ int snd_config_expand(snd_config_t *config, const char *args, SNDERR("Parse arguments error: %s", snd_strerror(err)); goto _end; } + err = snd_config_evaluate(subs, private_data, NULL); + if (err < 0) { + SNDERR("Args evaluate error: %s", snd_strerror(err)); + goto _end; + } err = snd_config_walk(config, &res, _snd_config_expand, subs); if (err < 0) { SNDERR("Expand error (walk): %s", snd_strerror(err)); goto _end; } } - err = snd_config_evaluate(res, private_data); + err = snd_config_evaluate(res, private_data, NULL); if (err < 0) { SNDERR("Evaluate error: %s", snd_strerror(err)); snd_config_delete(res); @@ -2429,7 +2422,7 @@ int snd_config_search_definition(snd_config_t *config, memcpy(key, name, args - name - 1); key[args - name - 1] = '\0'; } else { - key = (char *) base; + key = (char *) name; } err = snd_config_search_alias(config, base, key, &conf); if (err < 0) diff --git a/src/confmisc.c b/src/confmisc.c index f2aee2be..f28c798a 100644 --- a/src/confmisc.c +++ b/src/confmisc.c @@ -213,24 +213,31 @@ int snd_config_string_replace(const char *src, char idchr, int snd_func_getenv(snd_config_t **dst, snd_config_t *src, void *private_data) { - snd_config_t *n, *d, *e; + snd_config_t *n, *d; snd_config_iterator_t i, next; char *res, *def = NULL; int idx = 0, err; - err = snd_config_expand(src, NULL, private_data, &e); - if (err < 0) - return err; - err = snd_config_search(e, "envname", &n); + err = snd_config_search(src, "envname", &n); if (err < 0) { SNDERR("field envname not found"); goto __error; } - err = snd_config_search(e, "default", &d); + err = snd_config_evaluate(n, private_data, NULL); + if (err < 0) { + SNDERR("error evaluating envname"); + goto __error; + } + err = snd_config_search(src, "default", &d); if (err < 0) { SNDERR("field default not found"); goto __error; } + err = snd_config_evaluate(d, private_data, NULL); + if (err < 0) { + SNDERR("error evaluating default"); + goto __error; + } err = snd_config_get_ascii(d, &def); if (err < 0) { SNDERR("error getting field default"); @@ -277,7 +284,6 @@ int snd_func_getenv(snd_config_t **dst, snd_config_t *src, void *private_data) __error: if (def) free(def); - snd_config_delete(e); return err; } @@ -303,7 +309,6 @@ int snd_func_igetenv(snd_config_t **dst, snd_config_t *src, void *private_data) err = 0; _end: - snd_config_delete(d); return err; } @@ -311,19 +316,21 @@ int snd_func_igetenv(snd_config_t **dst, snd_config_t *src, void *private_data) int snd_func_concat(snd_config_t **dst, snd_config_t *src, void *private_data) { - snd_config_t *n, *e; + snd_config_t *n; snd_config_iterator_t i, next; char *res = NULL, *tmp; int idx = 0, len = 0, len1, err; - err = snd_config_expand(src, NULL, private_data, &e); - if (err < 0) - return err; - err = snd_config_search(e, "strings", &n); + err = snd_config_search(src, "strings", &n); if (err < 0) { SNDERR("field strings not found"); goto __error; } + err = snd_config_evaluate(n, private_data, NULL); + if (err < 0) { + SNDERR("error evaluating strings"); + goto __error; + } __retry: snd_config_for_each(i, next, n) { snd_config_t *n = snd_config_iterator_entry(i); @@ -366,7 +373,6 @@ int snd_func_concat(snd_config_t **dst, snd_config_t *src, void *private_data) snd_config_set_string(*dst, res); free(res); __error: - snd_config_delete(e); return err; } @@ -402,21 +408,23 @@ static int string_from_integer(char **dst, long v) int snd_func_card_strtype(snd_config_t **dst, snd_config_t *src, void *private_data) { - snd_config_t *n, *e; + snd_config_t *n; char *res = NULL; snd_ctl_t *ctl = NULL; snd_ctl_card_info_t *info; long v; int err; - err = snd_config_expand(src, NULL, private_data, &e); - if (err < 0) - return err; - err = snd_config_search(e, "card", &n); + err = snd_config_search(src, "card", &n); if (err < 0) { SNDERR("field card not found"); goto __error; } + err = snd_config_evaluate(n, private_data, NULL); + if (err < 0) { + SNDERR("error evaluating card"); + goto __error; + } err = snd_config_get_integer(n, &v); if (err < 0) { SNDERR("field card is not an integer"); @@ -445,27 +453,28 @@ int snd_func_card_strtype(snd_config_t **dst, snd_config_t *src, void *private_d __error: if (ctl) snd_ctl_close(ctl); - snd_config_delete(e); return err; } int snd_func_card_id(snd_config_t **dst, snd_config_t *src, void *private_data) { - snd_config_t *n, *e; + snd_config_t *n; char *res = NULL; snd_ctl_t *ctl = NULL; snd_ctl_card_info_t *info; long v; int err; - err = snd_config_expand(src, NULL, private_data, &e); - if (err < 0) - return err; - err = snd_config_search(e, "card", &n); + err = snd_config_search(src, "card", &n); if (err < 0) { SNDERR("field card not found"); goto __error; } + err = snd_config_evaluate(n, private_data, NULL); + if (err < 0) { + SNDERR("error evaluating card"); + goto __error; + } err = snd_config_get_integer(n, &v); if (err < 0) { SNDERR("field card is not an integer"); @@ -494,43 +503,54 @@ int snd_func_card_id(snd_config_t **dst, snd_config_t *src, void *private_data) __error: if (ctl) snd_ctl_close(ctl); - snd_config_delete(e); return err; } int snd_func_pcm_id(snd_config_t **dst, snd_config_t *src, void *private_data) { - snd_config_t *n, *e; + snd_config_t *n; char *res = NULL; snd_ctl_t *ctl = NULL; snd_pcm_info_t *info; long card, device, subdevice = 0; int err; - err = snd_config_expand(src, NULL, private_data, &e); - if (err < 0) - return err; - err = snd_config_search(e, "card", &n); + err = snd_config_search(src, "card", &n); if (err < 0) { SNDERR("field card not found"); goto __error; } + err = snd_config_evaluate(n, private_data, NULL); + if (err < 0) { + SNDERR("error evaluating card"); + goto __error; + } err = snd_config_get_integer(n, &card); if (err < 0) { SNDERR("field card is not an integer"); goto __error; } - err = snd_config_search(e, "device", &n); + err = snd_config_search(src, "device", &n); if (err < 0) { SNDERR("field device not found"); goto __error; } + err = snd_config_evaluate(n, private_data, NULL); + if (err < 0) { + SNDERR("error evaluating device"); + goto __error; + } err = snd_config_get_integer(n, &device); if (err < 0) { SNDERR("field device is not an integer"); goto __error; } - if (snd_config_search(e, "subdevice", &n) >= 0) { + if (snd_config_search(src, "subdevice", &n) >= 0) { + err = snd_config_evaluate(n, private_data, NULL); + if (err < 0) { + SNDERR("error evaluating subdevice"); + goto __error; + } err = snd_config_get_integer(n, &subdevice); if (err < 0) { SNDERR("field subdevice is not an integer"); @@ -562,30 +582,35 @@ int snd_func_pcm_id(snd_config_t **dst, snd_config_t *src, void *private_data) __error: if (ctl) snd_ctl_close(ctl); - snd_config_delete(e); return err; } int snd_func_refer(snd_config_t **dst, snd_config_t *src, void *private_data) { - snd_config_t *n, *e; + snd_config_t *n; snd_config_t *root = NULL; const char *file = NULL, *name = NULL; int err; - err = snd_config_expand(src, NULL, private_data, &e); - if (err < 0) - return err; - err = snd_config_search(e, "file", &n); + err = snd_config_search(src, "file", &n); if (err >= 0) { + err = snd_config_evaluate(n, private_data, NULL); + if (err < 0) { + SNDERR("error evaluating file"); + goto _end; + } err = snd_config_get_string(n, &file); if (err < 0) { SNDERR("file is not a string"); goto _end; } } - err = snd_config_search(e, "name", &n); + err = snd_config_search(src, "name", &n); if (err >= 0) { + if (err < 0) { + SNDERR("error evaluating name"); + goto _end; + } err = snd_config_get_string(n, &name); if (err < 0) { SNDERR("name is not a string"); -- 2.47.1