Skip to content

Commit

Permalink
alsactl: state: recode set_control() to use newer functions
Browse files Browse the repository at this point in the history
The goal is to make the code more clean and separate elem id parsing.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
  • Loading branch information
perexg committed Oct 15, 2024
1 parent fbde4f8 commit e2fec28
Showing 1 changed file with 98 additions and 74 deletions.
172 changes: 98 additions & 74 deletions alsactl/state.c
Original file line number Diff line number Diff line change
Expand Up @@ -1201,57 +1201,32 @@ static int restore_config_value2(snd_ctl_t *handle, snd_ctl_elem_info_t *info,
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;
if (snd_config_get_id(n, &fld) < 0)
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) {
Expand All @@ -1262,7 +1237,7 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control,
}
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)
Expand All @@ -1271,7 +1246,7 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control,
}
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)
Expand All @@ -1280,7 +1255,7 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control,
}
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)
Expand All @@ -1289,42 +1264,74 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control,
}
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)
return -EINVAL;
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;
if (subdevice < 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);
Expand All @@ -1339,28 +1346,39 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control,
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;
}
Expand All @@ -1383,7 +1401,7 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control,
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);
Expand Down Expand Up @@ -1472,8 +1490,14 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control,
_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;
}
Expand Down Expand Up @@ -1529,7 +1553,7 @@ static int set_controls(int card, snd_config_t *top, int doit)
}
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;
}
Expand Down

0 comments on commit e2fec28

Please sign in to comment.