git: f250ff5ff309 - main - mixer(8): Improve shorthand volume parsing.

From: Hans Petter Selasky <hselasky_at_FreeBSD.org>
Date: Sun, 20 Mar 2022 19:21:46 UTC
The branch main has been updated by hselasky:

URL: https://cgit.FreeBSD.org/src/commit/?id=f250ff5ff3094abd5570df61fbe4d2c37e3624a9

commit f250ff5ff3094abd5570df61fbe4d2c37e3624a9
Author:     Hans Petter Selasky <hselasky@FreeBSD.org>
AuthorDate: 2022-03-20 19:08:13 +0000
Commit:     Hans Petter Selasky <hselasky@FreeBSD.org>
CommitDate: 2022-03-20 19:19:16 +0000

    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:                  da3d4469ef841be44ac4b346a6b51668d608ed49
    Submitted by:           christos@
    Differential Revision:  https://reviews.freebsd.org/D34617
    Sponsored by:           NVIDIA Networking
---
 usr.sbin/mixer/mixer.c | 44 ++++++++++++++++++++++++++++++--------------
 1 file changed, 30 insertions(+), 14 deletions(-)

diff --git a/usr.sbin/mixer/mixer.c b/usr.sbin/mixer/mixer.c
index f3a8d9aaa92a..c0a9ec25c6fa 100644
--- a/usr.sbin/mixer/mixer.c
+++ b/usr.sbin/mixer/mixer.c
@@ -30,9 +30,11 @@
 #include <string.h>
 #include <unistd.h>
 
-#define C_VOL 0
-#define C_MUT 1
-#define C_SRC 2
+enum {
+	C_VOL = 0,
+	C_MUT,
+	C_SRC,
+};
 
 static void usage(void) __dead2;
 static void initctls(struct mixer *);
@@ -64,7 +66,7 @@ main(int argc, char *argv[])
 	mix_ctl_t *cp;
 	char *name = NULL, buf[NAME_MAX];
 	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 ch;
 
@@ -135,6 +137,19 @@ parse:
 	while (argc > 0) {
 		if ((p = strdup(*argv)) == NULL)
 			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. */
 		devstr = strsep(&p, ".=");
 		if ((m->dev = mixer_get_dev_byname(m, devstr)) == NULL) {
@@ -146,22 +161,23 @@ parse:
 			printdev(m, 1);
 			pall = 0;
 			goto next;
-		} else {
-			for (q = p; (*q >= '0' && *q <= '9') || *q == '.'; q++)
-				;	/* nothing */
-			/* Input: `dev=N` -> shorthand for `dev.volume=N`. */
-			if (*q == '\0') {
-				cp = mixer_get_ctl(m->dev, C_VOL);
-				cp->mod(cp->parent_dev, p);
-				goto next;
-			}
+		} else if (shorthand) {
+			/*
+			 * Input: `dev=N` -> shorthand for `dev.volume=N`.
+			 *
+			 * We don't care what the rest of the string contains as
+			 * long as we're sure the very beginning is right,
+			 * mod_volume() will take care of parsing it properly.
+			 */
+			cp = mixer_get_ctl(m->dev, C_VOL);
+			cp->mod(cp->parent_dev, p);
+			goto next;
 		}
 		ctlstr = strsep(&p, "=");
 		if ((cp = mixer_get_ctl_byname(m->dev, ctlstr)) == NULL) {
 			warnx("%s.%s: no such control", devstr, ctlstr);
 			goto next;
 		}
-
 		/* Input: `dev.control`. */
 		if (p == NULL) {
 			(void)cp->print(cp->parent_dev, cp->name);