static int if_eval_one(snd_use_case_mgr_t *uc_mgr,
snd_config_t *cond,
- snd_config_t **result)
+ snd_config_t **result,
+ snd_config_t **before,
+ snd_config_t **after)
{
snd_config_t *expr, *_true = NULL, *_false = NULL;
int err;
return -EINVAL;
}
+ err = snd_config_search(cond, "Before", before);
+ if (err < 0 && err != -ENOENT) {
+ uc_error("before block identifier error");
+ return -EINVAL;
+ }
+
+ err = snd_config_search(cond, "After", after);
+ if (err < 0 && err != -ENOENT) {
+ uc_error("before block identifier error");
+ return -EINVAL;
+ }
+
err = if_eval(uc_mgr, expr);
if (err > 0) {
*result = _true;
}
#endif
-static int compound_merge(snd_config_t *dst, snd_config_t *src)
+static int compound_merge(const char *id,
+ snd_config_t *dst, snd_config_t *src,
+ snd_config_t *before, snd_config_t *after)
{
snd_config_iterator_t i, next;
- snd_config_t *n;
+ snd_config_t *n, *_before = NULL, *_after = NULL;
+ const char *s;
int err;
if (snd_config_get_type(src) != SND_CONFIG_TYPE_COMPOUND) {
return -EINVAL;
}
+ if (before) {
+ err = get_string(before, id, &s);
+ if (err < 0 && err != -ENOENT)
+ return err;
+ if (err == 0) {
+ err = snd_config_search(dst, s, &_before);
+ if (err < 0 && err != -ENOENT)
+ return err;
+ }
+ }
+ if (after) {
+ err = get_string(after, id, &s);
+ if (err < 0 && err != -ENOENT)
+ return err;
+ if (err == 0) {
+ err = snd_config_search(dst, s, &_after);
+ if (err < 0 && err != -ENOENT)
+ return err;
+ }
+ }
+
+ if (_before && _after) {
+ uc_error("defined both before and after identifiers in the If block");
+ return -EINVAL;
+ }
+
snd_config_for_each(i, next, src) {
n = snd_config_iterator_entry(i);
err = snd_config_remove(n);
if (err < 0)
return err;
- err = snd_config_add(dst, n);
- if (err < 0) {
- return err;
+ if (_before) {
+ err = snd_config_add_before(_before, n);
+ if (err < 0)
+ return err;
+ _before = NULL;
+ _after = n;
+ } else if (_after) {
+ err = snd_config_add_after(_after, n);
+ if (err < 0)
+ return err;
+ _after = n;
+ } else {
+ err = snd_config_add(dst, n);
+ if (err < 0)
+ return err;
}
}
snd_config_t *cond)
{
snd_config_iterator_t i, i2, next, next2;
- snd_config_t *a, *n, *n2, *parent2;
+ snd_config_t *a, *n, *n2, *parent2, *before, *after;
const char *id;
int err;
snd_config_for_each(i, next, cond) {
n = snd_config_iterator_entry(i);
- err = if_eval_one(uc_mgr, n, &a);
+ before = after = NULL;
+ err = if_eval_one(uc_mgr, n, &a, &before, &after);
if (err < 0)
return err;
+ if (a == NULL)
+ continue;
err = snd_config_search(a, "If", &n2);
if (err < 0 && err != -ENOENT) {
uc_error("If block error (If)");
err = snd_config_search(parent, id, &parent2);
if (err == -ENOENT)
goto __add;
- err = compound_merge(parent2, n2);
+ err = compound_merge(id, parent2, n2, before, after);
if (err < 0)
return err;
}