mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
ucm: change the If block parsing
- evaluate always If before the other blocks
This commit is contained in:
parent
cdc8aacbb5
commit
4724158c0a
2 changed files with 70 additions and 92 deletions
|
|
@ -180,25 +180,6 @@ snd_config_t *snd_config_iterator_entry(const snd_config_iterator_t iterator);
|
||||||
#define snd_config_for_each(pos, next, node) \
|
#define snd_config_for_each(pos, next, node) \
|
||||||
for (pos = snd_config_iterator_first(node), next = snd_config_iterator_next(pos); pos != snd_config_iterator_end(node); pos = next, next = snd_config_iterator_next(pos))
|
for (pos = snd_config_iterator_first(node), next = snd_config_iterator_next(pos); pos != snd_config_iterator_end(node); pos = next, next = snd_config_iterator_next(pos))
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Helper macro to iterate over the children of a compound node.
|
|
||||||
* \param[in,out] pos Iterator variable for the current node.
|
|
||||||
* \param[in] node Handle to the compound configuration node to iterate over.
|
|
||||||
*
|
|
||||||
* Use this macro like a \c for statement, e.g.:
|
|
||||||
* \code
|
|
||||||
* snd_config_iterator_t pos;
|
|
||||||
* snd_config_for_each(pos, node) {
|
|
||||||
* snd_config_t *entry = snd_config_iterator_entry(pos);
|
|
||||||
* ...
|
|
||||||
* }
|
|
||||||
* \endcode
|
|
||||||
*
|
|
||||||
* This macro does not allow deleting or removing the current node.
|
|
||||||
*/
|
|
||||||
#define snd_config_for_each_unsafe(pos, node) \
|
|
||||||
for (pos = snd_config_iterator_first(node); pos != snd_config_iterator_end(node); pos = snd_config_iterator_next(pos))
|
|
||||||
|
|
||||||
/* Misc functions */
|
/* Misc functions */
|
||||||
|
|
||||||
int snd_config_get_bool_ascii(const char *ascii);
|
int snd_config_get_bool_ascii(const char *ascii);
|
||||||
|
|
|
||||||
143
src/ucm/parser.c
143
src/ucm/parser.c
|
|
@ -160,6 +160,24 @@ int parse_get_safe_id(snd_config_t *n, const char **id)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Evaluate condition (in-place)
|
||||||
|
*/
|
||||||
|
static int evaluate_condition(snd_use_case_mgr_t *uc_mgr,
|
||||||
|
snd_config_t *cfg)
|
||||||
|
{
|
||||||
|
snd_config_t *n;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
err = snd_config_search(cfg, "If", &n);
|
||||||
|
if (err == -ENOENT)
|
||||||
|
return 0;
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return uc_mgr_evaluate_condition(uc_mgr, cfg, n);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse transition
|
* Parse transition
|
||||||
*/
|
*/
|
||||||
|
|
@ -584,7 +602,7 @@ static int parse_value(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED,
|
||||||
struct list_head *base,
|
struct list_head *base,
|
||||||
snd_config_t *cfg)
|
snd_config_t *cfg)
|
||||||
{
|
{
|
||||||
snd_config_iterator_t i;
|
snd_config_iterator_t i, next;
|
||||||
snd_config_t *n;
|
snd_config_t *n;
|
||||||
char *s;
|
char *s;
|
||||||
snd_config_type_t type;
|
snd_config_type_t type;
|
||||||
|
|
@ -594,21 +612,19 @@ static int parse_value(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED,
|
||||||
uc_error("error: compound is expected for value definition");
|
uc_error("error: compound is expected for value definition");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
snd_config_for_each_unsafe(i, cfg) {
|
|
||||||
|
/* in-place condition evaluation */
|
||||||
|
err = evaluate_condition(uc_mgr, cfg);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
snd_config_for_each(i, next, cfg) {
|
||||||
const char *id;
|
const char *id;
|
||||||
n = snd_config_iterator_entry(i);
|
n = snd_config_iterator_entry(i);
|
||||||
err = snd_config_get_id(n, &id);
|
err = snd_config_get_id(n, &id);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* in-place condition evaluation */
|
|
||||||
if (strcmp(id, "If") == 0) {
|
|
||||||
err = uc_mgr_evaluate_condition(uc_mgr, cfg, n);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
type = snd_config_get_type(n);
|
type = snd_config_get_type(n);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SND_CONFIG_TYPE_INTEGER:
|
case SND_CONFIG_TYPE_INTEGER:
|
||||||
|
|
@ -690,7 +706,7 @@ static int parse_modifier(snd_use_case_mgr_t *uc_mgr,
|
||||||
struct use_case_verb *verb = data1;
|
struct use_case_verb *verb = data1;
|
||||||
struct use_case_modifier *modifier;
|
struct use_case_modifier *modifier;
|
||||||
const char *name;
|
const char *name;
|
||||||
snd_config_iterator_t i;
|
snd_config_iterator_t i, next;
|
||||||
snd_config_t *n;
|
snd_config_t *n;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
|
@ -716,20 +732,17 @@ static int parse_modifier(snd_use_case_mgr_t *uc_mgr,
|
||||||
list_add_tail(&modifier->list, &verb->modifier_list);
|
list_add_tail(&modifier->list, &verb->modifier_list);
|
||||||
modifier->name = strdup(name);
|
modifier->name = strdup(name);
|
||||||
|
|
||||||
snd_config_for_each_unsafe(i, cfg) {
|
/* in-place condition evaluation */
|
||||||
|
err = evaluate_condition(uc_mgr, cfg);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
snd_config_for_each(i, next, cfg) {
|
||||||
const char *id;
|
const char *id;
|
||||||
n = snd_config_iterator_entry(i);
|
n = snd_config_iterator_entry(i);
|
||||||
if (snd_config_get_id(n, &id) < 0)
|
if (snd_config_get_id(n, &id) < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* in-place condition evaluation */
|
|
||||||
if (strcmp(id, "If") == 0) {
|
|
||||||
err = uc_mgr_evaluate_condition(uc_mgr, cfg, n);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(id, "Comment") == 0) {
|
if (strcmp(id, "Comment") == 0) {
|
||||||
err = parse_string(n, &modifier->comment);
|
err = parse_string(n, &modifier->comment);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
|
@ -845,7 +858,7 @@ static int parse_device(snd_use_case_mgr_t *uc_mgr,
|
||||||
struct use_case_verb *verb = data1;
|
struct use_case_verb *verb = data1;
|
||||||
const char *name;
|
const char *name;
|
||||||
struct use_case_device *device;
|
struct use_case_device *device;
|
||||||
snd_config_iterator_t i;
|
snd_config_iterator_t i, next;
|
||||||
snd_config_t *n;
|
snd_config_t *n;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
|
@ -870,20 +883,17 @@ static int parse_device(snd_use_case_mgr_t *uc_mgr,
|
||||||
list_add_tail(&device->list, &verb->device_list);
|
list_add_tail(&device->list, &verb->device_list);
|
||||||
device->name = strdup(name);
|
device->name = strdup(name);
|
||||||
|
|
||||||
snd_config_for_each_unsafe(i, cfg) {
|
/* in-place condition evaluation */
|
||||||
|
err = evaluate_condition(uc_mgr, cfg);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
snd_config_for_each(i, next, cfg) {
|
||||||
const char *id;
|
const char *id;
|
||||||
n = snd_config_iterator_entry(i);
|
n = snd_config_iterator_entry(i);
|
||||||
if (snd_config_get_id(n, &id) < 0)
|
if (snd_config_get_id(n, &id) < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* in-place condition evaluation */
|
|
||||||
if (strcmp(id, "If") == 0) {
|
|
||||||
err = uc_mgr_evaluate_condition(uc_mgr, cfg, n);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(id, "Comment") == 0) {
|
if (strcmp(id, "Comment") == 0) {
|
||||||
err = parse_string(n, &device->comment);
|
err = parse_string(n, &device->comment);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
|
@ -1061,25 +1071,22 @@ static int parse_verb(snd_use_case_mgr_t *uc_mgr,
|
||||||
struct use_case_verb *verb,
|
struct use_case_verb *verb,
|
||||||
snd_config_t *cfg)
|
snd_config_t *cfg)
|
||||||
{
|
{
|
||||||
snd_config_iterator_t i;
|
snd_config_iterator_t i, next;
|
||||||
snd_config_t *n;
|
snd_config_t *n;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
/* in-place condition evaluation */
|
||||||
|
err = evaluate_condition(uc_mgr, cfg);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
/* parse verb section */
|
/* parse verb section */
|
||||||
snd_config_for_each_unsafe(i, cfg) {
|
snd_config_for_each(i, next, cfg) {
|
||||||
const char *id;
|
const char *id;
|
||||||
n = snd_config_iterator_entry(i);
|
n = snd_config_iterator_entry(i);
|
||||||
if (snd_config_get_id(n, &id) < 0)
|
if (snd_config_get_id(n, &id) < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* in-place condition evaluation */
|
|
||||||
if (strcmp(id, "If") == 0) {
|
|
||||||
err = uc_mgr_evaluate_condition(uc_mgr, cfg, n);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strcmp(id, "EnableSequence") == 0) {
|
if (strcmp(id, "EnableSequence") == 0) {
|
||||||
uc_dbg("Parse EnableSequence");
|
uc_dbg("Parse EnableSequence");
|
||||||
err = parse_sequence(uc_mgr, &verb->enable_list, n);
|
err = parse_sequence(uc_mgr, &verb->enable_list, n);
|
||||||
|
|
@ -1138,7 +1145,7 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr,
|
||||||
const char *comment,
|
const char *comment,
|
||||||
const char *file)
|
const char *file)
|
||||||
{
|
{
|
||||||
snd_config_iterator_t i;
|
snd_config_iterator_t i, next;
|
||||||
snd_config_t *n;
|
snd_config_t *n;
|
||||||
struct use_case_verb *verb;
|
struct use_case_verb *verb;
|
||||||
snd_config_t *cfg;
|
snd_config_t *cfg;
|
||||||
|
|
@ -1178,21 +1185,18 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* in-place condition evaluation */
|
||||||
|
err = evaluate_condition(uc_mgr, cfg);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
/* parse master config sections */
|
/* parse master config sections */
|
||||||
snd_config_for_each_unsafe(i, cfg) {
|
snd_config_for_each(i, next, cfg) {
|
||||||
const char *id;
|
const char *id;
|
||||||
n = snd_config_iterator_entry(i);
|
n = snd_config_iterator_entry(i);
|
||||||
if (snd_config_get_id(n, &id) < 0)
|
if (snd_config_get_id(n, &id) < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* in-place condition evaluation */
|
|
||||||
if (strcmp(id, "If") == 0) {
|
|
||||||
err = uc_mgr_evaluate_condition(uc_mgr, cfg, n);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* find verb section and parse it */
|
/* find verb section and parse it */
|
||||||
if (strcmp(id, "SectionVerb") == 0) {
|
if (strcmp(id, "SectionVerb") == 0) {
|
||||||
err = parse_verb(uc_mgr, verb, n);
|
err = parse_verb(uc_mgr, verb, n);
|
||||||
|
|
@ -1250,7 +1254,7 @@ static int parse_master_section(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg,
|
||||||
void *data1 ATTRIBUTE_UNUSED,
|
void *data1 ATTRIBUTE_UNUSED,
|
||||||
void *data2 ATTRIBUTE_UNUSED)
|
void *data2 ATTRIBUTE_UNUSED)
|
||||||
{
|
{
|
||||||
snd_config_iterator_t i;
|
snd_config_iterator_t i, next;
|
||||||
snd_config_t *n;
|
snd_config_t *n;
|
||||||
const char *use_case_name, *file = NULL, *comment = NULL;
|
const char *use_case_name, *file = NULL, *comment = NULL;
|
||||||
int err;
|
int err;
|
||||||
|
|
@ -1265,21 +1269,18 @@ static int parse_master_section(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* in-place condition evaluation */
|
||||||
|
err = evaluate_condition(uc_mgr, cfg);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
/* parse master config sections */
|
/* parse master config sections */
|
||||||
snd_config_for_each_unsafe(i, cfg) {
|
snd_config_for_each(i, next, cfg) {
|
||||||
const char *id;
|
const char *id;
|
||||||
n = snd_config_iterator_entry(i);
|
n = snd_config_iterator_entry(i);
|
||||||
if (snd_config_get_id(n, &id) < 0)
|
if (snd_config_get_id(n, &id) < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* in-place condition evaluation */
|
|
||||||
if (strcmp(id, "If") == 0) {
|
|
||||||
err = uc_mgr_evaluate_condition(uc_mgr, cfg, n);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get use case verb file name */
|
/* get use case verb file name */
|
||||||
if (strcmp(id, "File") == 0) {
|
if (strcmp(id, "File") == 0) {
|
||||||
err = snd_config_get_string(n, &file);
|
err = snd_config_get_string(n, &file);
|
||||||
|
|
@ -1380,7 +1381,7 @@ static int parse_controls(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg)
|
||||||
*/
|
*/
|
||||||
static int parse_master_file(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg)
|
static int parse_master_file(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg)
|
||||||
{
|
{
|
||||||
snd_config_iterator_t i;
|
snd_config_iterator_t i, next;
|
||||||
snd_config_t *n;
|
snd_config_t *n;
|
||||||
const char *id;
|
const char *id;
|
||||||
long l;
|
long l;
|
||||||
|
|
@ -1406,26 +1407,22 @@ static int parse_master_file(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg)
|
||||||
uc_error("Incompatible syntax %d in %s", l, uc_mgr->conf_file_name);
|
uc_error("Incompatible syntax %d in %s", l, uc_mgr->conf_file_name);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
/* delete this field to avoid strcmp() call in the loop */
|
||||||
|
snd_config_delete(n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* in-place condition evaluation */
|
||||||
|
err = evaluate_condition(uc_mgr, cfg);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
/* parse master config sections */
|
/* parse master config sections */
|
||||||
snd_config_for_each_unsafe(i, cfg) {
|
snd_config_for_each(i, next, cfg) {
|
||||||
|
|
||||||
n = snd_config_iterator_entry(i);
|
n = snd_config_iterator_entry(i);
|
||||||
if (snd_config_get_id(n, &id) < 0)
|
if (snd_config_get_id(n, &id) < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* in-place condition evaluation */
|
|
||||||
if (strcmp(id, "If") == 0) {
|
|
||||||
err = uc_mgr_evaluate_condition(uc_mgr, cfg, n);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (uc_mgr->conf_format >= 2 && strcmp(id, "Syntax") == 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (strcmp(id, "Comment") == 0) {
|
if (strcmp(id, "Comment") == 0) {
|
||||||
err = parse_string(n, &uc_mgr->comment);
|
err = parse_string(n, &uc_mgr->comment);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue