return 0;
}
-static int set_control(snd_ctl_t *handle, snd_config_t *control,
- int *maxnumid, int doit)
+static int parse_config_id(snd_config_t *control, snd_ctl_elem_id_t *id,
+ snd_config_t **comment, snd_config_t **value, int doit)
{
- snd_ctl_elem_value_t *ctl;
- snd_ctl_elem_info_t *info;
snd_config_iterator_t i, next;
- unsigned int numid1;
+ const char *numid;
snd_ctl_elem_iface_t iface = -1;
- int iface1;
- const char *name1;
- unsigned int numid;
- snd_ctl_elem_type_t type;
- unsigned int count;
long device = -1;
- long device1;
long subdevice = -1;
- long subdevice1;
const char *name = NULL;
- long index1;
long index = -1;
- snd_config_t *value = NULL;
- snd_config_t *comment = NULL;
- unsigned int idx;
- int err;
- char *set;
- const char *id;
- snd_ctl_elem_value_alloca(&ctl);
- snd_ctl_elem_info_alloca(&info);
- if (snd_config_get_type(control) != SND_CONFIG_TYPE_COMPOUND) {
- cerror(doit, "control is not a compound");
- return -EINVAL;
- }
- err = snd_config_get_id(control, &id);
- if (err < 0) {
- cerror(doit, "unable to get id");
+
+ snd_ctl_elem_id_clear(id);
+ if (snd_config_get_id(control, &numid) < 0)
return -EINVAL;
- }
- numid = atoi(id);
- if ((int)numid > *maxnumid)
- *maxnumid = numid;
snd_config_for_each(i, next, control) {
snd_config_t *n = snd_config_iterator_entry(i);
const char *fld;
continue;
if (strcmp(fld, "comment") == 0) {
if (snd_config_get_type(n) != SND_CONFIG_TYPE_COMPOUND) {
- cerror(doit, "control.%d.%s is invalid", numid, fld);
+ cerror(doit, "control.%s.%s is invalid", numid, fld);
return -EINVAL;
}
- comment = n;
+ if (comment)
+ *comment = n;
continue;
}
if (strcmp(fld, "iface") == 0) {
}
if (strcmp(fld, "device") == 0) {
if (snd_config_get_type(n) != SND_CONFIG_TYPE_INTEGER) {
- cerror(doit, "control.%d.%s is invalid", numid, fld);
+ cerror(doit, "control.%s.%s is invalid", numid, fld);
return -EINVAL;
}
if (snd_config_get_integer(n, &device) < 0)
}
if (strcmp(fld, "subdevice") == 0) {
if (snd_config_get_type(n) != SND_CONFIG_TYPE_INTEGER) {
- cerror(doit, "control.%d.%s is invalid", numid, fld);
+ cerror(doit, "control.%s.%s is invalid", numid, fld);
return -EINVAL;
}
if (snd_config_get_integer(n, &subdevice) < 0)
}
if (strcmp(fld, "name") == 0) {
if (snd_config_get_type(n) != SND_CONFIG_TYPE_STRING) {
- cerror(doit, "control.%d.%s is invalid", numid, fld);
+ cerror(doit, "control.%s.%s is invalid", numid, fld);
return -EINVAL;
}
if (snd_config_get_string(n, &name) < 0)
}
if (strcmp(fld, "index") == 0) {
if (snd_config_get_type(n) != SND_CONFIG_TYPE_INTEGER) {
- cerror(doit, "control.%d.%s is invalid", numid, fld);
+ cerror(doit, "control.%s.%s is invalid", numid, fld);
return -EINVAL;
}
if (snd_config_get_integer(n, &index) < 0)
continue;
}
if (strcmp(fld, "value") == 0) {
- value = n;
+ if (value)
+ *value = n;
continue;
}
- cerror(doit, "unknown control.%d.%s field", numid, fld);
- }
- if (!value) {
- cerror(doit, "missing control.%d.value", numid);
- return -EINVAL;
+ cerror(doit, "unknown control.%s.%s field", numid, fld);
}
if (device < 0)
device = 0;
subdevice = 0;
if (index < 0)
index = 0;
+ snd_ctl_elem_id_set_interface(id, iface);
+ snd_ctl_elem_id_set_device(id, device);
+ snd_ctl_elem_id_set_subdevice(id, subdevice);
+ snd_ctl_elem_id_set_name(id, name);
+ snd_ctl_elem_id_set_index(id, index);
+ return 0;
+}
+static int set_control(snd_ctl_t *handle, snd_config_t *control, int doit)
+{
+ snd_ctl_elem_value_t *ctl;
+ snd_ctl_elem_info_t *info;
+ snd_config_iterator_t i, next;
+ snd_ctl_elem_id_t *elem_id, *elem_id1;
+ unsigned int numid;
+ snd_ctl_elem_type_t type;
+ unsigned int count;
+ snd_config_t *value = NULL;
+ snd_config_t *comment = NULL;
+ unsigned int idx;
+ int err;
+ char *set;
+ const char *id;
+ snd_ctl_elem_id_alloca(&elem_id);
+ snd_ctl_elem_id_alloca(&elem_id1);
+ snd_ctl_elem_value_alloca(&ctl);
+ snd_ctl_elem_info_alloca(&info);
+ if (snd_config_get_type(control) != SND_CONFIG_TYPE_COMPOUND) {
+ cerror(doit, "control is not a compound");
+ return -EINVAL;
+ }
+ err = snd_config_get_id(control, &id);
+ if (err < 0) {
+ cerror(doit, "unable to get id");
+ return -EINVAL;
+ }
+ numid = atoi(id);
+ err = parse_config_id(control, elem_id, &comment, &value, doit);
+ if (err < 0)
+ return err;
err = -EINVAL;
if (!force_restore) {
snd_ctl_elem_info_set_numid(info, numid);
err = snd_ctl_elem_info(handle, info);
}
- if (err < 0 && name) {
- snd_ctl_elem_info_set_numid(info, 0);
- snd_ctl_elem_info_set_interface(info, iface);
- snd_ctl_elem_info_set_device(info, device);
- snd_ctl_elem_info_set_subdevice(info, subdevice);
- snd_ctl_elem_info_set_name(info, name);
- snd_ctl_elem_info_set_index(info, index);
+ id = snd_ctl_elem_id_get_name(elem_id);
+ if (err < 0 && id && id[0]) {
+ snd_ctl_elem_info_set_id(info, elem_id);
err = snd_ctl_elem_info(handle, info);
if (err < 0 && comment && check_comment_access(comment, "user")) {
err = add_user_control(handle, info, comment);
cerror(doit, "failed to obtain info for control #%d (%s)", numid, snd_strerror(err));
return -ENOENT;
}
- numid1 = snd_ctl_elem_info_get_numid(info);
- iface1 = snd_ctl_elem_info_get_interface(info);
- device1 = snd_ctl_elem_info_get_device(info);
- subdevice1 = snd_ctl_elem_info_get_subdevice(info);
- name1 = snd_ctl_elem_info_get_name(info);
- index1 = snd_ctl_elem_info_get_index(info);
count = snd_ctl_elem_info_get_count(info);
+ snd_ctl_elem_info_get_id(info, elem_id1);
type = snd_ctl_elem_info_get_type(info);
- if (err |= numid != numid1 && !force_restore)
- cerror(doit, "warning: numid mismatch (%d/%d) for control #%d",
- numid, numid1, numid);
- if (err |= (int)iface != iface1)
- cerror(doit, "warning: iface mismatch (%d/%d) for control #%d", iface, iface1, numid);
- if (err |= device != device1)
- cerror(doit, "warning: device mismatch (%ld/%ld) for control #%d", device, device1, numid);
- if (err |= subdevice != subdevice1)
- cerror(doit, "warning: subdevice mismatch (%ld/%ld) for control #%d", subdevice, subdevice1, numid);
- if (err |= strcmp(name, name1))
- cerror(doit, "warning: name mismatch (%s/%s) for control #%d", name, name1, numid);
- if (err |= index != index1)
- cerror(doit, "warning: index mismatch (%ld/%ld) for control #%d", index, index1, numid);
- if (err < 0) {
+ err = 0;
+ if (err |= !force_restore && numid != snd_ctl_elem_id_get_numid(elem_id1))
+ cerror(doit, "warning: numid mismatch (%u/%u) for control #%d",
+ (unsigned int)numid, snd_ctl_elem_id_get_numid(elem_id1), numid);
+ if (err |= snd_ctl_elem_id_get_interface(elem_id) != snd_ctl_elem_id_get_interface(elem_id1))
+ cerror(doit, "warning: iface mismatch (%d/%d) for control #%d",
+ (int)snd_ctl_elem_id_get_interface(elem_id),
+ (int)snd_ctl_elem_id_get_interface(elem_id1),
+ numid);
+ if (err |= snd_ctl_elem_id_get_device(elem_id) != snd_ctl_elem_id_get_device(elem_id1))
+ cerror(doit, "warning: device mismatch (%u/%u) for control #%d",
+ snd_ctl_elem_id_get_device(elem_id),
+ snd_ctl_elem_id_get_device(elem_id1),
+ numid);
+ if (err |= snd_ctl_elem_id_get_subdevice(elem_id) != snd_ctl_elem_id_get_subdevice(elem_id1))
+ cerror(doit, "warning: subdevice mismatch (%u/%%u) for control #%d",
+ snd_ctl_elem_id_get_subdevice(elem_id),
+ snd_ctl_elem_id_get_subdevice(elem_id1),
+ numid);
+ if (err |= strcmp(snd_ctl_elem_id_get_name(elem_id), snd_ctl_elem_id_get_name(elem_id1)))
+ cerror(doit, "warning: name mismatch (%s/%s) for control #%d",
+ snd_ctl_elem_id_get_name(elem_id),
+ snd_ctl_elem_id_get_name(elem_id1),
+ numid);
+ if (err |= snd_ctl_elem_id_get_index(elem_id) != snd_ctl_elem_id_get_index(elem_id1))
+ cerror(doit, "warning: index mismatch (%u/%u) for control #%d",
+ snd_ctl_elem_id_get_index(elem_id),
+ snd_ctl_elem_id_get_index(elem_id1),
+ numid);
+ if (err) {
cerror(doit, "failed to obtain info for control #%d (%s)", numid, snd_strerror(err));
return -ENOENT;
}
if (snd_ctl_elem_info_is_inactive(info) ||
!snd_ctl_elem_info_is_writable(info))
return 0;
- snd_ctl_elem_value_set_numid(ctl, numid1);
+ snd_ctl_elem_value_set_numid(ctl, snd_ctl_elem_id_get_numid(elem_id1));
if (count == 1) {
err = restore_config_value(handle, info, type, value, ctl, 0, doit);
_ok:
err = doit ? snd_ctl_elem_write(handle, ctl) : 0;
if (err < 0) {
- error("Cannot write control '%d:%ld:%ld:%s:%ld' : %s", (int)iface, device, subdevice, name, index, snd_strerror(err));
+ char *s = snd_ctl_ascii_elem_id_get(elem_id1);
+ error("Cannot write control '%s' : %s", s, snd_strerror(err));
+ free(s);
return err;
+ } else if (debugflag) {
+ char *s = snd_ctl_ascii_elem_id_get(elem_id1);
+ dbg("control '%s' restored", s);
+ free(s);
}
return 0;
}
}
snd_config_for_each(i, next, control) {
snd_config_t *n = snd_config_iterator_entry(i);
- err = set_control(handle, n, &maxnumid, doit);
+ err = set_control(handle, n, doit);
if (err < 0 && (!force_restore || !doit))
goto _close;
}