The branch main has been updated by hselasky:

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

commit f250ff5ff3094abd5570df61fbe4d2c37e3624a9
Author:     Hans Petter Selasky <hsela...@freebsd.org>
AuthorDate: 2022-03-20 19:08:13 +0000
Commit:     Hans Petter Selasky <hsela...@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);

Reply via email to