mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
Simplified evaluation using snd_config_walk. Fixed implementation
This commit is contained in:
parent
92b0581c33
commit
a4768a7b10
4 changed files with 227 additions and 153 deletions
|
|
@ -40,6 +40,8 @@ int snd_config_search_definition(snd_config_t *config,
|
||||||
|
|
||||||
int snd_config_expand(snd_config_t *config, const char *args,
|
int snd_config_expand(snd_config_t *config, const char *args,
|
||||||
void *private_data, snd_config_t **result);
|
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_add(snd_config_t *config, snd_config_t *leaf);
|
||||||
int snd_config_delete(snd_config_t *config);
|
int snd_config_delete(snd_config_t *config);
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,24 @@ pcm.hw {
|
||||||
@args [ CARD DEV SUBDEV ]
|
@args [ CARD DEV SUBDEV ]
|
||||||
@args.CARD {
|
@args.CARD {
|
||||||
type integer
|
type integer
|
||||||
|
default {
|
||||||
|
@func igetenv
|
||||||
|
envname [
|
||||||
|
ALSA_PCM_CARD
|
||||||
|
ALSA_CARD
|
||||||
|
]
|
||||||
|
default 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@args.DEV {
|
@args.DEV {
|
||||||
type integer
|
type integer
|
||||||
|
default {
|
||||||
|
@func igetenv
|
||||||
|
envname [
|
||||||
|
ALSA_PCM_DEVICE
|
||||||
|
]
|
||||||
|
default 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@args.SUBDEV {
|
@args.SUBDEV {
|
||||||
type integer
|
type integer
|
||||||
|
|
@ -28,9 +43,24 @@ pcm.plughw {
|
||||||
@args [ CARD DEV SUBDEV ]
|
@args [ CARD DEV SUBDEV ]
|
||||||
@args.CARD {
|
@args.CARD {
|
||||||
type integer
|
type integer
|
||||||
|
default {
|
||||||
|
@func igetenv
|
||||||
|
envname [
|
||||||
|
ALSA_PCM_CARD
|
||||||
|
ALSA_CARD
|
||||||
|
]
|
||||||
|
default 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@args.DEV {
|
@args.DEV {
|
||||||
type integer
|
type integer
|
||||||
|
default {
|
||||||
|
@func igetenv
|
||||||
|
envname [
|
||||||
|
ALSA_PCM_DEVICE
|
||||||
|
]
|
||||||
|
default 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@args.SUBDEV {
|
@args.SUBDEV {
|
||||||
type integer
|
type integer
|
||||||
|
|
@ -444,6 +474,14 @@ ctl.hw {
|
||||||
@args[ CARD ]
|
@args[ CARD ]
|
||||||
@args.CARD {
|
@args.CARD {
|
||||||
type integer
|
type integer
|
||||||
|
default {
|
||||||
|
@func igetenv
|
||||||
|
envname [
|
||||||
|
ALSA_CTL_CARD
|
||||||
|
ALSA_CARD
|
||||||
|
]
|
||||||
|
default 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
type hw
|
type hw
|
||||||
card $(CARD)
|
card $(CARD)
|
||||||
|
|
@ -465,8 +503,9 @@ ctl.shm {
|
||||||
ctl.default {
|
ctl.default {
|
||||||
type hw
|
type hw
|
||||||
card {
|
card {
|
||||||
@func getenv
|
@func igetenv
|
||||||
envname [
|
envname [
|
||||||
|
ALSA_CTL_CARD
|
||||||
ALSA_CARD
|
ALSA_CARD
|
||||||
]
|
]
|
||||||
default 0
|
default 0
|
||||||
|
|
@ -481,9 +520,24 @@ rawmidi.hw {
|
||||||
@args [ CARD DEV SUBDEV ]
|
@args [ CARD DEV SUBDEV ]
|
||||||
@args.CARD {
|
@args.CARD {
|
||||||
type integer
|
type integer
|
||||||
|
default {
|
||||||
|
@func igetenv
|
||||||
|
envname [
|
||||||
|
ALSA_RAWMIDI_CARD
|
||||||
|
ALSA_CARD
|
||||||
|
]
|
||||||
|
default 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@args.DEV {
|
@args.DEV {
|
||||||
type integer
|
type integer
|
||||||
|
default {
|
||||||
|
@func igetenv
|
||||||
|
envname [
|
||||||
|
ALSA_RAWMIDI_DEVICE
|
||||||
|
]
|
||||||
|
default 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@args.SUBDEV {
|
@args.SUBDEV {
|
||||||
type integer
|
type integer
|
||||||
|
|
|
||||||
217
src/conf.c
217
src/conf.c
|
|
@ -1862,124 +1862,112 @@ static int _snd_config_expand(snd_config_t *src,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int evaluate_node(snd_config_t *father, snd_config_t *src,
|
void snd_config_substitute(snd_config_t *dst, snd_config_t *src)
|
||||||
void *private_data, snd_config_t **dst)
|
|
||||||
{
|
{
|
||||||
snd_config_iterator_t i, next;
|
free(dst->id);
|
||||||
const char *lib = NULL, *func = NULL;
|
dst->id = src->id;
|
||||||
int err;
|
dst->type = src->type;
|
||||||
char buf[64];
|
dst->u = src->u;
|
||||||
char *evaluate_name = NULL;
|
|
||||||
int (*evaluate_func)(snd_config_t **dst, snd_config_t *src, void *private_data);
|
|
||||||
void *h;
|
|
||||||
|
|
||||||
assert(father && src && dst);
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
if (n1) { /* replace node */
|
|
||||||
snd_config_delete(n);
|
|
||||||
err = snd_config_add(src, n1);
|
|
||||||
if (err < 0)
|
|
||||||
goto __error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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 == 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) {
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
err = 0;
|
|
||||||
|
|
||||||
__error:
|
|
||||||
if (func)
|
|
||||||
free((void *)func);
|
|
||||||
if (lib)
|
|
||||||
free((void *)lib);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_config_evaluate(snd_config_t *conf, void *private_data)
|
static int _snd_config_evaluate(snd_config_t *src,
|
||||||
|
snd_config_t **dst ATTRIBUTE_UNUSED,
|
||||||
|
snd_config_walk_pass_t pass,
|
||||||
|
void *private_data)
|
||||||
{
|
{
|
||||||
snd_config_iterator_t i, next;
|
int err;
|
||||||
|
if (pass == SND_CONFIG_WALK_PASS_PRE) {
|
||||||
assert(conf);
|
char buf[256];
|
||||||
if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND)
|
const char *lib = NULL, *func_name = NULL;
|
||||||
return 0;
|
const char *str;
|
||||||
snd_config_for_each(i, next, conf) {
|
int (*func)(snd_config_t **dst, snd_config_t *src,
|
||||||
snd_config_t *n = snd_config_iterator_entry(i);
|
void *private_data);
|
||||||
if (snd_config_get_type(n) == SND_CONFIG_TYPE_COMPOUND) {
|
void *h;
|
||||||
snd_config_t *n1;
|
snd_config_t *c, *eval, *func_conf = NULL;
|
||||||
int err = evaluate_node(conf, n, private_data, &n1);
|
err = snd_config_search(src, "@func", &c);
|
||||||
if (err < 0) {
|
if (err < 0)
|
||||||
SNDERR("Error in node %s", snd_config_get_id(n));
|
return 1;
|
||||||
return err;
|
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_for_each(i, next, func_conf) {
|
||||||
snd_config_delete(n);
|
snd_config_t *n = snd_config_iterator_entry(i);
|
||||||
err = snd_config_add(conf, n1);
|
const char *id = snd_config_get_id(n);
|
||||||
if (err < 0)
|
if (strcmp(id, "comment") == 0)
|
||||||
return err;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
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) {
|
||||||
|
SNDERR("symbol %s is not defined inside %s", func_name, lib);
|
||||||
|
dlclose(h);
|
||||||
|
return -ENXIO;
|
||||||
|
}
|
||||||
|
err = func(&eval, src, private_data);
|
||||||
|
dlclose(h);
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
return 0;
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
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)
|
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));
|
SNDERR("Parse arguments error: %s", snd_strerror(err));
|
||||||
goto _end;
|
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);
|
err = snd_config_walk(config, &res, _snd_config_expand, subs);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
SNDERR("Expand error (walk): %s", snd_strerror(err));
|
SNDERR("Expand error (walk): %s", snd_strerror(err));
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = snd_config_evaluate(res, private_data);
|
err = snd_config_evaluate(res, private_data, NULL);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
SNDERR("Evaluate error: %s", snd_strerror(err));
|
SNDERR("Evaluate error: %s", snd_strerror(err));
|
||||||
snd_config_delete(res);
|
snd_config_delete(res);
|
||||||
|
|
@ -2429,7 +2422,7 @@ int snd_config_search_definition(snd_config_t *config,
|
||||||
memcpy(key, name, args - name - 1);
|
memcpy(key, name, args - name - 1);
|
||||||
key[args - name - 1] = '\0';
|
key[args - name - 1] = '\0';
|
||||||
} else {
|
} else {
|
||||||
key = (char *) base;
|
key = (char *) name;
|
||||||
}
|
}
|
||||||
err = snd_config_search_alias(config, base, key, &conf);
|
err = snd_config_search_alias(config, base, key, &conf);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
|
|
||||||
105
src/confmisc.c
105
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)
|
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;
|
snd_config_iterator_t i, next;
|
||||||
char *res, *def = NULL;
|
char *res, *def = NULL;
|
||||||
int idx = 0, err;
|
int idx = 0, err;
|
||||||
|
|
||||||
err = snd_config_expand(src, NULL, private_data, &e);
|
err = snd_config_search(src, "envname", &n);
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
err = snd_config_search(e, "envname", &n);
|
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
SNDERR("field envname not found");
|
SNDERR("field envname not found");
|
||||||
goto __error;
|
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) {
|
if (err < 0) {
|
||||||
SNDERR("field default not found");
|
SNDERR("field default not found");
|
||||||
goto __error;
|
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);
|
err = snd_config_get_ascii(d, &def);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
SNDERR("error getting field default");
|
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:
|
__error:
|
||||||
if (def)
|
if (def)
|
||||||
free(def);
|
free(def);
|
||||||
snd_config_delete(e);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -303,7 +309,6 @@ int snd_func_igetenv(snd_config_t **dst, snd_config_t *src, void *private_data)
|
||||||
err = 0;
|
err = 0;
|
||||||
|
|
||||||
_end:
|
_end:
|
||||||
snd_config_delete(d);
|
|
||||||
return err;
|
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)
|
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;
|
snd_config_iterator_t i, next;
|
||||||
char *res = NULL, *tmp;
|
char *res = NULL, *tmp;
|
||||||
int idx = 0, len = 0, len1, err;
|
int idx = 0, len = 0, len1, err;
|
||||||
|
|
||||||
err = snd_config_expand(src, NULL, private_data, &e);
|
err = snd_config_search(src, "strings", &n);
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
err = snd_config_search(e, "strings", &n);
|
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
SNDERR("field strings not found");
|
SNDERR("field strings not found");
|
||||||
goto __error;
|
goto __error;
|
||||||
}
|
}
|
||||||
|
err = snd_config_evaluate(n, private_data, NULL);
|
||||||
|
if (err < 0) {
|
||||||
|
SNDERR("error evaluating strings");
|
||||||
|
goto __error;
|
||||||
|
}
|
||||||
__retry:
|
__retry:
|
||||||
snd_config_for_each(i, next, n) {
|
snd_config_for_each(i, next, n) {
|
||||||
snd_config_t *n = snd_config_iterator_entry(i);
|
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);
|
snd_config_set_string(*dst, res);
|
||||||
free(res);
|
free(res);
|
||||||
__error:
|
__error:
|
||||||
snd_config_delete(e);
|
|
||||||
return err;
|
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)
|
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;
|
char *res = NULL;
|
||||||
snd_ctl_t *ctl = NULL;
|
snd_ctl_t *ctl = NULL;
|
||||||
snd_ctl_card_info_t *info;
|
snd_ctl_card_info_t *info;
|
||||||
long v;
|
long v;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = snd_config_expand(src, NULL, private_data, &e);
|
err = snd_config_search(src, "card", &n);
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
err = snd_config_search(e, "card", &n);
|
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
SNDERR("field card not found");
|
SNDERR("field card not found");
|
||||||
goto __error;
|
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);
|
err = snd_config_get_integer(n, &v);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
SNDERR("field card is not an integer");
|
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:
|
__error:
|
||||||
if (ctl)
|
if (ctl)
|
||||||
snd_ctl_close(ctl);
|
snd_ctl_close(ctl);
|
||||||
snd_config_delete(e);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_func_card_id(snd_config_t **dst, snd_config_t *src, void *private_data)
|
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;
|
char *res = NULL;
|
||||||
snd_ctl_t *ctl = NULL;
|
snd_ctl_t *ctl = NULL;
|
||||||
snd_ctl_card_info_t *info;
|
snd_ctl_card_info_t *info;
|
||||||
long v;
|
long v;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = snd_config_expand(src, NULL, private_data, &e);
|
err = snd_config_search(src, "card", &n);
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
err = snd_config_search(e, "card", &n);
|
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
SNDERR("field card not found");
|
SNDERR("field card not found");
|
||||||
goto __error;
|
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);
|
err = snd_config_get_integer(n, &v);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
SNDERR("field card is not an integer");
|
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:
|
__error:
|
||||||
if (ctl)
|
if (ctl)
|
||||||
snd_ctl_close(ctl);
|
snd_ctl_close(ctl);
|
||||||
snd_config_delete(e);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_func_pcm_id(snd_config_t **dst, snd_config_t *src, void *private_data)
|
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;
|
char *res = NULL;
|
||||||
snd_ctl_t *ctl = NULL;
|
snd_ctl_t *ctl = NULL;
|
||||||
snd_pcm_info_t *info;
|
snd_pcm_info_t *info;
|
||||||
long card, device, subdevice = 0;
|
long card, device, subdevice = 0;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = snd_config_expand(src, NULL, private_data, &e);
|
err = snd_config_search(src, "card", &n);
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
err = snd_config_search(e, "card", &n);
|
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
SNDERR("field card not found");
|
SNDERR("field card not found");
|
||||||
goto __error;
|
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);
|
err = snd_config_get_integer(n, &card);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
SNDERR("field card is not an integer");
|
SNDERR("field card is not an integer");
|
||||||
goto __error;
|
goto __error;
|
||||||
}
|
}
|
||||||
err = snd_config_search(e, "device", &n);
|
err = snd_config_search(src, "device", &n);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
SNDERR("field device not found");
|
SNDERR("field device not found");
|
||||||
goto __error;
|
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);
|
err = snd_config_get_integer(n, &device);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
SNDERR("field device is not an integer");
|
SNDERR("field device is not an integer");
|
||||||
goto __error;
|
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);
|
err = snd_config_get_integer(n, &subdevice);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
SNDERR("field subdevice is not an integer");
|
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:
|
__error:
|
||||||
if (ctl)
|
if (ctl)
|
||||||
snd_ctl_close(ctl);
|
snd_ctl_close(ctl);
|
||||||
snd_config_delete(e);
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_func_refer(snd_config_t **dst, snd_config_t *src, void *private_data)
|
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;
|
snd_config_t *root = NULL;
|
||||||
const char *file = NULL, *name = NULL;
|
const char *file = NULL, *name = NULL;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = snd_config_expand(src, NULL, private_data, &e);
|
err = snd_config_search(src, "file", &n);
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
err = snd_config_search(e, "file", &n);
|
|
||||||
if (err >= 0) {
|
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);
|
err = snd_config_get_string(n, &file);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
SNDERR("file is not a string");
|
SNDERR("file is not a string");
|
||||||
goto _end;
|
goto _end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
err = snd_config_search(e, "name", &n);
|
err = snd_config_search(src, "name", &n);
|
||||||
if (err >= 0) {
|
if (err >= 0) {
|
||||||
|
if (err < 0) {
|
||||||
|
SNDERR("error evaluating name");
|
||||||
|
goto _end;
|
||||||
|
}
|
||||||
err = snd_config_get_string(n, &name);
|
err = snd_config_get_string(n, &name);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
SNDERR("name is not a string");
|
SNDERR("name is not a string");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue