From 63f7745be504e447923f2cde421177a2fca99340 Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 4 May 2021 20:27:45 +0200 Subject: [PATCH] conf: extend load_for_all_cards hook (id/value table) For the per-card configuration, add possibility to define card number -> card driver link table. Example: cards.0 'cards.USB-Audio' cards.1 'cards.USB-Audio' cards.2 'cards.HDA-Intel' cards.3 'cards.USB-Audio' Signed-off-by: Jaroslav Kysela --- src/conf.c | 106 +++++++++++++++++++++++++++++++++++---------- src/conf/alsa.conf | 15 +++++++ 2 files changed, 97 insertions(+), 24 deletions(-) diff --git a/src/conf.c b/src/conf.c index 941662ca..12aad1a9 100644 --- a/src/conf.c +++ b/src/conf.c @@ -3964,12 +3964,7 @@ int snd_config_hook_load(snd_config_t *root, snd_config_t *config, snd_config_t assert(root && dst); if ((err = snd_config_search(config, "errors", &n)) >= 0) { - char *tmp; - err = snd_config_get_ascii(n, &tmp); - if (err < 0) - return err; - errors = snd_config_get_bool_ascii(tmp); - free(tmp); + errors = snd_config_get_bool(n); if (errors < 0) { SNDERR("Invalid bool value in field errors"); return errors; @@ -4040,6 +4035,75 @@ SND_DLSYM_BUILD_VERSION(snd_config_hook_load, SND_CONFIG_DLSYM_VERSION_HOOK); int snd_determine_driver(int card, char **driver); #endif +snd_config_t *_snd_config_hook_private_data(int card, const char *driver) +{ + snd_config_t *private_data, *v; + int err; + + err = snd_config_make_compound(&private_data, NULL, 0); + if (err < 0) + goto __err; + err = snd_config_imake_integer(&v, "integer", card); + if (err < 0) + goto __err; + err = snd_config_add(private_data, v); + if (err < 0) { + snd_config_delete(v); + goto __err; + } + err = snd_config_imake_string(&v, "string", driver); + if (err < 0) + goto __err; + err = snd_config_add(private_data, v); + if (err < 0) { + snd_config_delete(v); + goto __err; + } + return private_data; + +__err: + snd_config_delete(private_data); + return NULL; +} + +static int _snd_config_hook_table(snd_config_t *root, snd_config_t *config, snd_config_t *private_data) +{ + snd_config_t *n, *tn; + const char *id; + int err; + + if (snd_config_search(config, "table", &n) < 0) + return 0; + if ((err = snd_config_expand(n, root, NULL, private_data, &n)) < 0) { + SNDERR("Unable to expand table compound"); + return err; + } + if (snd_config_search(n, "id", &tn) < 0 || + snd_config_get_string(tn, &id) < 0) { + SNDERR("Unable to find field table.id"); + snd_config_delete(n); + return -EINVAL; + } + if (snd_config_search(n, "value", &tn) < 0 || + snd_config_get_type(tn) != SND_CONFIG_TYPE_STRING) { + SNDERR("Unable to find field table.value"); + snd_config_delete(n); + return -EINVAL; + } + snd_config_remove(tn); + if ((err = snd_config_set_id(tn, id)) < 0) { + snd_config_delete(tn); + snd_config_delete(n); + return err; + } + snd_config_delete(n); + if ((err = snd_config_add(root, tn)) < 0) { + snd_config_delete(tn); + return err; + } + return 0; +} + /** * \brief Loads and parses the given configurations files for each * installed sound card. @@ -4064,16 +4128,20 @@ int snd_config_hook_load_for_all_cards(snd_config_t *root, snd_config_t *config, if (err < 0) return err; if (card >= 0) { - snd_config_t *n, *v, *private_data = NULL; + snd_config_t *n, *private_data = NULL; const char *driver; char *fdriver = NULL; err = snd_determine_driver(card, &fdriver); if (err < 0) return err; if (snd_config_search(root, fdriver, &n) >= 0) { - if (snd_config_get_string(n, &driver) < 0) + if (snd_config_get_string(n, &driver) < 0) { + if (snd_config_get_type(n) == SND_CONFIG_TYPE_COMPOUND) { + snd_config_get_id(n, &driver); + goto __std; + } goto __err; - assert(driver); + } while (1) { char *s = strchr(driver, '.'); if (s == NULL) @@ -4085,25 +4153,15 @@ int snd_config_hook_load_for_all_cards(snd_config_t *root, snd_config_t *config, } else { driver = fdriver; } - err = snd_config_make_compound(&private_data, NULL, 0); - if (err < 0) - goto __err; - err = snd_config_imake_integer(&v, "integer", card); - if (err < 0) - goto __err; - err = snd_config_add(private_data, v); - if (err < 0) { - snd_config_delete(v); + __std: + private_data = _snd_config_hook_private_data(card, driver); + if (!private_data) { + err = -ENOMEM; goto __err; } - err = snd_config_imake_string(&v, "string", driver); + err = _snd_config_hook_table(root, config, private_data); if (err < 0) goto __err; - err = snd_config_add(private_data, v); - if (err < 0) { - snd_config_delete(v); - goto __err; - } err = snd_config_hook_load(root, config, &n, private_data); __err: if (private_data) diff --git a/src/conf/alsa.conf b/src/conf/alsa.conf index 3b96d4fb..a74b2cfa 100644 --- a/src/conf/alsa.conf +++ b/src/conf/alsa.conf @@ -67,6 +67,21 @@ cards.@hooks [ ] } ] + table { + id { + @func concat + strings [ + { @func private_integer } + ] + } + value { + @func concat + strings [ + "cards." + { @func private_string } + ] + } + } errors false } ] -- 2.47.1