mixer(8): Improve shorthand volume parsing.

The initial patch had a bug where the full volume syntax, floating point values,
:, + and -, wasn't accepted.

While at it move some defines to enum's.

Fixes:			da3d4469ef
Submitted by:		christos@
Differential Revision:	https://reviews.freebsd.org/D34617
Sponsored by:		NVIDIA Networking
This commit is contained in:
Hans Petter Selasky 2022-03-20 20:08:13 +01:00
parent 2406867f5b
commit f250ff5ff3

View File

@ -30,9 +30,11 @@
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
#define C_VOL 0 enum {
#define C_MUT 1 C_VOL = 0,
#define C_SRC 2 C_MUT,
C_SRC,
};
static void usage(void) __dead2; static void usage(void) __dead2;
static void initctls(struct mixer *); static void initctls(struct mixer *);
@ -64,7 +66,7 @@ main(int argc, char *argv[])
mix_ctl_t *cp; mix_ctl_t *cp;
char *name = NULL, buf[NAME_MAX]; char *name = NULL, buf[NAME_MAX];
char *p, *q, *devstr, *ctlstr, *valstr = NULL; char *p, *q, *devstr, *ctlstr, *valstr = NULL;
int dunit, i, n, pall = 1; int dunit, i, n, pall = 1, shorthand;
int aflag = 0, dflag = 0, oflag = 0, sflag = 0; int aflag = 0, dflag = 0, oflag = 0, sflag = 0;
int ch; int ch;
@ -135,6 +137,19 @@ main(int argc, char *argv[])
while (argc > 0) { while (argc > 0) {
if ((p = strdup(*argv)) == NULL) if ((p = strdup(*argv)) == NULL)
err(1, "strdup(%s)", *argv); err(1, "strdup(%s)", *argv);
/* Check if we're using the shorthand syntax for volume setting. */
shorthand = 0;
for (q = p; *q != '\0'; q++) {
if (*q == '=') {
q++;
shorthand = ((*q >= '0' && *q <= '9') ||
*q == '+' || *q == '-' || *q == '.');
break;
} else if (*q == '.')
break;
}
/* Split the string into device, control and value. */ /* Split the string into device, control and value. */
devstr = strsep(&p, ".="); devstr = strsep(&p, ".=");
if ((m->dev = mixer_get_dev_byname(m, devstr)) == NULL) { if ((m->dev = mixer_get_dev_byname(m, devstr)) == NULL) {
@ -146,22 +161,23 @@ main(int argc, char *argv[])
printdev(m, 1); printdev(m, 1);
pall = 0; pall = 0;
goto next; goto next;
} else { } else if (shorthand) {
for (q = p; (*q >= '0' && *q <= '9') || *q == '.'; q++) /*
; /* nothing */ * Input: `dev=N` -> shorthand for `dev.volume=N`.
/* Input: `dev=N` -> shorthand for `dev.volume=N`. */ *
if (*q == '\0') { * We don't care what the rest of the string contains as
cp = mixer_get_ctl(m->dev, C_VOL); * long as we're sure the very beginning is right,
cp->mod(cp->parent_dev, p); * mod_volume() will take care of parsing it properly.
goto next; */
} cp = mixer_get_ctl(m->dev, C_VOL);
cp->mod(cp->parent_dev, p);
goto next;
} }
ctlstr = strsep(&p, "="); ctlstr = strsep(&p, "=");
if ((cp = mixer_get_ctl_byname(m->dev, ctlstr)) == NULL) { if ((cp = mixer_get_ctl_byname(m->dev, ctlstr)) == NULL) {
warnx("%s.%s: no such control", devstr, ctlstr); warnx("%s.%s: no such control", devstr, ctlstr);
goto next; goto next;
} }
/* Input: `dev.control`. */ /* Input: `dev.control`. */
if (p == NULL) { if (p == NULL) {
(void)cp->print(cp->parent_dev, cp->name); (void)cp->print(cp->parent_dev, cp->name);