err = parse_verb_file(uc_mgr, use_case_name, comment, file);
} else {
/* parse variants */
+ struct list_head orig_variable_list;
+ snd_config_t *orig_macros = NULL;
+ int first_iteration = 1;
+
+ /* save original variable list */
+ err = uc_mgr_duplicate_variables(&orig_variable_list, &uc_mgr->variable_list);
+ if (err < 0)
+ goto __error;
+
+ /* save original macros */
+ if (uc_mgr->macros) {
+ err = snd_config_copy(&orig_macros, uc_mgr->macros);
+ if (err < 0)
+ goto __variant_error;
+ }
+
snd_config_for_each(i, next, variant) {
char *vfile, *vcomment;
const char *id;
+
+ /* restore variables and macros for second and later iterations */
+ if (!first_iteration) {
+ uc_mgr_free_value(&uc_mgr->variable_list);
+
+ err = uc_mgr_duplicate_variables(&uc_mgr->variable_list, &orig_variable_list);
+ if (err < 0)
+ goto __variant_error;
+
+ if (uc_mgr->macros) {
+ snd_config_delete(uc_mgr->macros);
+ uc_mgr->macros = NULL;
+ }
+ if (orig_macros) {
+ err = snd_config_copy(&uc_mgr->macros, orig_macros);
+ if (err < 0)
+ goto __variant_error;
+ }
+ }
+ first_iteration = 0;
+
n = snd_config_iterator_entry(i);
if (snd_config_get_id(n, &id) < 0)
continue;
if (!parse_is_name_safe(id)) {
err = -EINVAL;
- goto __error;
+ goto __variant_error;
}
err = parse_variant(uc_mgr, n, &vfile, &vcomment);
if (err < 0)
uc_mgr->parse_variant = NULL;
free(vfile);
free(vcomment);
+ if (err < 0)
+ break;
}
+
+__variant_error:
+ uc_mgr_free_value(&orig_variable_list);
+ if (orig_macros)
+ snd_config_delete(orig_macros);
}
__error:
snd_ctl_t *uc_mgr_get_ctl(snd_use_case_mgr_t *uc_mgr);
void uc_mgr_free_ctl_list(snd_use_case_mgr_t *uc_mgr);
+void uc_mgr_free_value(struct list_head *base);
+
int uc_mgr_add_value(struct list_head *base, const char *key, char *val);
const char *uc_mgr_get_variable(snd_use_case_mgr_t *uc_mgr,
int uc_mgr_delete_variable(snd_use_case_mgr_t *uc_mgr, const char *name);
+int uc_mgr_duplicate_variables(struct list_head *dst, struct list_head *src);
+
int uc_mgr_get_substituted_value(snd_use_case_mgr_t *uc_mgr,
char **_rvalue,
const char *value);
return -ENOENT;
}
+int uc_mgr_duplicate_variables(struct list_head *dst, struct list_head *src)
+{
+ struct list_head *pos;
+ struct ucm_value *var, *new_var;
+ int err;
+
+ INIT_LIST_HEAD(dst);
+
+ list_for_each(pos, src) {
+ var = list_entry(pos, struct ucm_value, list);
+ new_var = calloc(1, sizeof(*new_var));
+ if (new_var == NULL) {
+ err = -ENOMEM;
+ goto __error;
+ }
+ new_var->name = strdup(var->name);
+ new_var->data = strdup(var->data);
+ if (new_var->name == NULL || new_var->data == NULL) {
+ free(new_var->name);
+ free(new_var->data);
+ free(new_var);
+ err = -ENOMEM;
+ goto __error;
+ }
+ list_add_tail(&new_var->list, dst);
+ }
+ return 0;
+
+__error:
+ uc_mgr_free_value(dst);
+ return err;
+}
+
void uc_mgr_free_verb(snd_use_case_mgr_t *uc_mgr)
{
struct list_head *pos, *npos;