From e2fec28b65368f342096a36b7f62d7b451d22f4a Mon Sep 17 00:00:00 2001 From: Jaroslav Kysela Date: Tue, 15 Oct 2024 16:50:54 +0200 Subject: [PATCH] alsactl: state: recode set_control() to use newer functions The goal is to make the code more clean and separate elem id parsing. Signed-off-by: Jaroslav Kysela --- alsactl/state.c | 172 +++++++++++++++++++++++++++--------------------- 1 file changed, 98 insertions(+), 74 deletions(-) diff --git a/alsactl/state.c b/alsactl/state.c index 88996d4a2..d1fc1329f 100644 --- a/alsactl/state.c +++ b/alsactl/state.c @@ -1201,46 +1201,20 @@ 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; @@ -1248,10 +1222,11 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control, 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) { @@ -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) @@ -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) @@ -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) @@ -1289,7 +1264,7 @@ 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) @@ -1297,14 +1272,11 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control, 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; @@ -1312,19 +1284,54 @@ static int set_control(snd_ctl_t *handle, snd_config_t *control, 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); @@ -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; } @@ -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); @@ -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; } @@ -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; }