mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2026-02-10 04:27:43 -05:00
ucm: add If condition block
The syntax is simple:
If./any-if-identificator/ {
Condition {
Type /type_here/
/optional defines/
}
True {
/block used when condition is evaluated as true/
}
False {
/block used when condition is evaluated as false/
}
}
The Type "ControlExists" is implemented:
Condition {
Type ControlExists
Device "hw:${CardId}"
Control "iface=CARD,name='Headphone Jack'"
}
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
b9b2247943
commit
8a36e38dc4
8 changed files with 536 additions and 162 deletions
|
|
@ -565,7 +565,7 @@ static int parse_value(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED,
|
|||
snd_config_t *cfg)
|
||||
{
|
||||
struct ucm_value *curr;
|
||||
snd_config_iterator_t i, next;
|
||||
snd_config_iterator_t i;
|
||||
snd_config_t *n;
|
||||
char buf[64];
|
||||
long l;
|
||||
|
|
@ -578,13 +578,21 @@ static int parse_value(snd_use_case_mgr_t *uc_mgr ATTRIBUTE_UNUSED,
|
|||
uc_error("error: compound is expected for value definition");
|
||||
return -EINVAL;
|
||||
}
|
||||
snd_config_for_each(i, next, cfg) {
|
||||
snd_config_for_each_unsafe(i, cfg) {
|
||||
const char *id;
|
||||
n = snd_config_iterator_entry(i);
|
||||
err = snd_config_get_id(n, &id);
|
||||
if (err < 0)
|
||||
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;
|
||||
}
|
||||
|
||||
/* alloc new value */
|
||||
curr = calloc(1, sizeof(struct ucm_value));
|
||||
if (curr == NULL)
|
||||
|
|
@ -620,7 +628,7 @@ __buf:
|
|||
}
|
||||
break;
|
||||
default:
|
||||
uc_error("error: invalid type %i in Value compound", type);
|
||||
uc_error("error: invalid type %i in Value compound '%s'", type, id);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
|
@ -679,7 +687,7 @@ static int parse_modifier(snd_use_case_mgr_t *uc_mgr,
|
|||
struct use_case_verb *verb = data1;
|
||||
struct use_case_modifier *modifier;
|
||||
const char *name;
|
||||
snd_config_iterator_t i, next;
|
||||
snd_config_iterator_t i;
|
||||
snd_config_t *n;
|
||||
int err;
|
||||
|
||||
|
|
@ -705,12 +713,20 @@ static int parse_modifier(snd_use_case_mgr_t *uc_mgr,
|
|||
list_add_tail(&modifier->list, &verb->modifier_list);
|
||||
modifier->name = strdup(name);
|
||||
|
||||
snd_config_for_each(i, next, cfg) {
|
||||
snd_config_for_each_unsafe(i, cfg) {
|
||||
const char *id;
|
||||
n = snd_config_iterator_entry(i);
|
||||
if (snd_config_get_id(n, &id) < 0)
|
||||
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) {
|
||||
err = parse_string(n, &modifier->comment);
|
||||
if (err < 0) {
|
||||
|
|
@ -826,7 +842,7 @@ static int parse_device(snd_use_case_mgr_t *uc_mgr,
|
|||
struct use_case_verb *verb = data1;
|
||||
const char *name;
|
||||
struct use_case_device *device;
|
||||
snd_config_iterator_t i, next;
|
||||
snd_config_iterator_t i;
|
||||
snd_config_t *n;
|
||||
int err;
|
||||
|
||||
|
|
@ -851,12 +867,20 @@ static int parse_device(snd_use_case_mgr_t *uc_mgr,
|
|||
list_add_tail(&device->list, &verb->device_list);
|
||||
device->name = strdup(name);
|
||||
|
||||
snd_config_for_each(i, next, cfg) {
|
||||
snd_config_for_each_unsafe(i, cfg) {
|
||||
const char *id;
|
||||
n = snd_config_iterator_entry(i);
|
||||
if (snd_config_get_id(n, &id) < 0)
|
||||
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) {
|
||||
err = parse_string(n, &device->comment);
|
||||
if (err < 0) {
|
||||
|
|
@ -1034,17 +1058,25 @@ static int parse_verb(snd_use_case_mgr_t *uc_mgr,
|
|||
struct use_case_verb *verb,
|
||||
snd_config_t *cfg)
|
||||
{
|
||||
snd_config_iterator_t i, next;
|
||||
snd_config_iterator_t i;
|
||||
snd_config_t *n;
|
||||
int err;
|
||||
|
||||
/* parse verb section */
|
||||
snd_config_for_each(i, next, cfg) {
|
||||
snd_config_for_each_unsafe(i, cfg) {
|
||||
const char *id;
|
||||
n = snd_config_iterator_entry(i);
|
||||
if (snd_config_get_id(n, &id) < 0)
|
||||
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) {
|
||||
uc_dbg("Parse EnableSequence");
|
||||
err = parse_sequence(uc_mgr, &verb->enable_list, n);
|
||||
|
|
@ -1103,7 +1135,7 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr,
|
|||
const char *comment,
|
||||
const char *file)
|
||||
{
|
||||
snd_config_iterator_t i, next;
|
||||
snd_config_iterator_t i;
|
||||
snd_config_t *n;
|
||||
struct use_case_verb *verb;
|
||||
snd_config_t *cfg;
|
||||
|
|
@ -1144,12 +1176,20 @@ static int parse_verb_file(snd_use_case_mgr_t *uc_mgr,
|
|||
}
|
||||
|
||||
/* parse master config sections */
|
||||
snd_config_for_each(i, next, cfg) {
|
||||
snd_config_for_each_unsafe(i, cfg) {
|
||||
const char *id;
|
||||
n = snd_config_iterator_entry(i);
|
||||
if (snd_config_get_id(n, &id) < 0)
|
||||
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 */
|
||||
if (strcmp(id, "SectionVerb") == 0) {
|
||||
err = parse_verb(uc_mgr, verb, n);
|
||||
|
|
@ -1207,7 +1247,7 @@ static int parse_master_section(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg,
|
|||
void *data1 ATTRIBUTE_UNUSED,
|
||||
void *data2 ATTRIBUTE_UNUSED)
|
||||
{
|
||||
snd_config_iterator_t i, next;
|
||||
snd_config_iterator_t i;
|
||||
snd_config_t *n;
|
||||
const char *use_case_name, *file = NULL, *comment = NULL;
|
||||
int err;
|
||||
|
|
@ -1221,13 +1261,22 @@ static int parse_master_section(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg,
|
|||
uc_error("compound type expected for use case section");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* parse master config sections */
|
||||
snd_config_for_each(i, next, cfg) {
|
||||
snd_config_for_each_unsafe(i, cfg) {
|
||||
const char *id;
|
||||
n = snd_config_iterator_entry(i);
|
||||
if (snd_config_get_id(n, &id) < 0)
|
||||
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 */
|
||||
if (strcmp(id, "File") == 0) {
|
||||
err = snd_config_get_string(n, &file);
|
||||
|
|
@ -1328,7 +1377,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)
|
||||
{
|
||||
snd_config_iterator_t i, next;
|
||||
snd_config_iterator_t i;
|
||||
snd_config_t *n;
|
||||
const char *id;
|
||||
long l;
|
||||
|
|
@ -1357,12 +1406,20 @@ static int parse_master_file(snd_use_case_mgr_t *uc_mgr, snd_config_t *cfg)
|
|||
}
|
||||
|
||||
/* parse master config sections */
|
||||
snd_config_for_each(i, next, cfg) {
|
||||
snd_config_for_each_unsafe(i, cfg) {
|
||||
|
||||
n = snd_config_iterator_entry(i);
|
||||
if (snd_config_get_id(n, &id) < 0)
|
||||
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;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue