mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2026-02-28 01:40:08 -05:00
ucm: add Prepend and Append block handling for If conditions (syntax 8+)
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
parent
ebfc29110c
commit
a8620e814b
2 changed files with 125 additions and 26 deletions
|
|
@ -373,21 +373,50 @@ static int if_eval_one(snd_use_case_mgr_t *uc_mgr,
|
||||||
snd_config_t *cond,
|
snd_config_t *cond,
|
||||||
snd_config_t **result,
|
snd_config_t **result,
|
||||||
snd_config_t **before,
|
snd_config_t **before,
|
||||||
snd_config_t **after)
|
snd_config_t **after,
|
||||||
|
snd_config_t **prepend,
|
||||||
|
snd_config_t **append)
|
||||||
{
|
{
|
||||||
snd_config_t *expr, *_true = NULL, *_false = NULL;
|
snd_config_t *expr, *_true = NULL, *_false = NULL;
|
||||||
int err;
|
int err, has_condition;
|
||||||
|
|
||||||
*result = NULL;
|
*result = NULL;
|
||||||
|
*prepend = NULL;
|
||||||
|
*append = NULL;
|
||||||
|
|
||||||
if (snd_config_get_type(cond) != SND_CONFIG_TYPE_COMPOUND) {
|
if (snd_config_get_type(cond) != SND_CONFIG_TYPE_COMPOUND) {
|
||||||
snd_error(UCM, "compound type expected for If.1");
|
snd_error(UCM, "compound type expected for If.1");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (snd_config_search(cond, "Condition", &expr) < 0) {
|
/* For syntax v8+, Condition is optional if Prepend or Append is present */
|
||||||
snd_error(UCM, "condition block expected (If)");
|
has_condition = snd_config_search(cond, "Condition", &expr) >= 0;
|
||||||
return -EINVAL;
|
|
||||||
|
if (uc_mgr->conf_format >= 8) {
|
||||||
|
/* Check for Prepend block */
|
||||||
|
err = snd_config_search(cond, "Prepend", prepend);
|
||||||
|
if (err < 0 && err != -ENOENT) {
|
||||||
|
snd_error(UCM, "prepend block error (If)");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check for Append block */
|
||||||
|
err = snd_config_search(cond, "Append", append);
|
||||||
|
if (err < 0 && err != -ENOENT) {
|
||||||
|
snd_error(UCM, "append block error (If)");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If Prepend or Append is present, Condition can be omitted */
|
||||||
|
if (!has_condition && (*prepend == NULL && *append == NULL)) {
|
||||||
|
snd_error(UCM, "condition block expected (If)");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!has_condition) {
|
||||||
|
snd_error(UCM, "condition block expected (If)");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = snd_config_search(cond, "True", &_true);
|
err = snd_config_search(cond, "True", &_true);
|
||||||
|
|
@ -414,16 +443,22 @@ static int if_eval_one(snd_use_case_mgr_t *uc_mgr,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = if_eval(uc_mgr, expr);
|
/* Evaluate condition if present */
|
||||||
if (err > 0) {
|
if (has_condition) {
|
||||||
*result = _true;
|
err = if_eval(uc_mgr, expr);
|
||||||
return 0;
|
if (err > 0) {
|
||||||
} else if (err == 0) {
|
*result = _true;
|
||||||
*result = _false;
|
return 0;
|
||||||
return 0;
|
} else if (err == 0) {
|
||||||
} else {
|
*result = _false;
|
||||||
return err;
|
return 0;
|
||||||
|
} else {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* If no condition (v8+ with Prepend/Append only), no result block */
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
|
@ -445,7 +480,7 @@ int uc_mgr_evaluate_condition(snd_use_case_mgr_t *uc_mgr,
|
||||||
snd_config_t *cond)
|
snd_config_t *cond)
|
||||||
{
|
{
|
||||||
snd_config_iterator_t i, next;
|
snd_config_iterator_t i, next;
|
||||||
snd_config_t *a, *n, *before, *after;
|
snd_config_t *a, *n, *before, *after, *prepend, *append;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (uc_mgr->conf_format < 2) {
|
if (uc_mgr->conf_format < 2) {
|
||||||
|
|
@ -460,19 +495,43 @@ int uc_mgr_evaluate_condition(snd_use_case_mgr_t *uc_mgr,
|
||||||
|
|
||||||
snd_config_for_each(i, next, cond) {
|
snd_config_for_each(i, next, cond) {
|
||||||
n = snd_config_iterator_entry(i);
|
n = snd_config_iterator_entry(i);
|
||||||
before = after = NULL;
|
before = after = prepend = append = NULL;
|
||||||
err = if_eval_one(uc_mgr, n, &a, &before, &after);
|
err = if_eval_one(uc_mgr, n, &a, &before, &after, &prepend, &append);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
if (a == NULL)
|
|
||||||
continue;
|
/* For v8+: Handle Prepend block - prepend to parent before result */
|
||||||
err = uc_mgr_evaluate_inplace(uc_mgr, a);
|
if (prepend != NULL) {
|
||||||
if (err < 0)
|
err = uc_mgr_evaluate_inplace(uc_mgr, prepend);
|
||||||
return err;
|
if (err < 0)
|
||||||
err = uc_mgr_config_tree_merge(uc_mgr, parent, a, before, after);
|
return err;
|
||||||
if (err < 0)
|
err = uc_mgr_config_tree_merge(uc_mgr, parent, prepend, before, after);
|
||||||
return err;
|
if (err < 0)
|
||||||
snd_config_delete(a);
|
return err;
|
||||||
|
snd_config_delete(prepend);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Merge the condition result (True or False block) */
|
||||||
|
if (a != NULL) {
|
||||||
|
err = uc_mgr_evaluate_inplace(uc_mgr, a);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
err = uc_mgr_config_tree_merge(uc_mgr, parent, a, before, after);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
snd_config_delete(a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* For v8+: Handle Append block - append to parent after result */
|
||||||
|
if (append != NULL) {
|
||||||
|
err = uc_mgr_evaluate_inplace(uc_mgr, append);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
err = uc_mgr_config_tree_merge(uc_mgr, parent, append, before, after);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
snd_config_delete(append);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -550,6 +550,14 @@ must define a *Condition* block and *True* or *False* blocks or both. The *True*
|
||||||
blocks will be merged to the parent tree (where the *If* block is defined) when
|
blocks will be merged to the parent tree (where the *If* block is defined) when
|
||||||
the *Condition* is evaluated.
|
the *Condition* is evaluated.
|
||||||
|
|
||||||
|
Starting with *Syntax* version *8*, *If* blocks can also include *Prepend* and *Append*
|
||||||
|
configuration blocks. These blocks are always merged to the parent tree, independent of the
|
||||||
|
condition evaluation result:
|
||||||
|
- *Prepend* block is merged before the condition result (*True* or *False* block)
|
||||||
|
- *Append* block is merged after the condition result (*True* or *False* block)
|
||||||
|
- Both *Prepend* and *Append* can be specified simultaneously
|
||||||
|
- When *Prepend* or *Append* is present, the *Condition* directive can be omitted
|
||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
~~~{.html}
|
~~~{.html}
|
||||||
|
|
@ -566,6 +574,38 @@ If.uniqueid {
|
||||||
}
|
}
|
||||||
~~~
|
~~~
|
||||||
|
|
||||||
|
Example with Prepend and Append (*Syntax* version *8*+):
|
||||||
|
|
||||||
|
~~~{.html}
|
||||||
|
If.setup {
|
||||||
|
Prepend {
|
||||||
|
Define.before "prepended"
|
||||||
|
}
|
||||||
|
Condition {
|
||||||
|
Type AlwaysTrue
|
||||||
|
}
|
||||||
|
True {
|
||||||
|
Define.middle "conditional"
|
||||||
|
}
|
||||||
|
Append {
|
||||||
|
Define.after "appended"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
|
Example with Prepend/Append only (no Condition, *Syntax* version *8*+):
|
||||||
|
|
||||||
|
~~~{.html}
|
||||||
|
If.common {
|
||||||
|
Prepend {
|
||||||
|
Define.x "always executed"
|
||||||
|
}
|
||||||
|
Append {
|
||||||
|
Define.y "also always executed"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
~~~
|
||||||
|
|
||||||
#### True (Type AlwaysTrue)
|
#### True (Type AlwaysTrue)
|
||||||
|
|
||||||
Execute only *True* block. It may be used to change the evaluation order as
|
Execute only *True* block. It may be used to change the evaluation order as
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue