* sorted output looks cleaner, prettier;
* it's easier to find the variable you're looking for in a sorted
output;
* hierarchical variable names yet unordered? doesn't make sense;
* this way mixerctl's behaviour will be closer to other *ctl programs
which output variables in an ordered fashion (audioctl, sysctl,
wsconsctl).

Before:
s@d630:0:/usr/src/usr.bin/mixerctl$ mixerctl
outputs.hp_source=dac-0:1
outputs.hp_dir=output
outputs.hp_boost=off
outputs.line-in_source=dac-2:3
outputs.line-in_dir=input
outputs.mic_dir=input-vr80
outputs.spkr_source=dac-2:3
outputs.spkr_dir=none
outputs.spkr_boost=off
inputs.dac-2:3_mute=off
inputs.dac-2:3=152,152
inputs.dac-0:1_mute=off
inputs.dac-0:1=152,152
inputs.sel_source=mic
outputs.sel=126,126
inputs.sel2_source=line-in
outputs.sel2=126,126
inputs.sel3_source=sel
inputs.sel3_sel=119,119
inputs.sel4_source=sel2
inputs.sel4_sel2=119,119
record.adc-0:1_source=sel3
record.adc-0:1_mute=off
record.adc-2:3_source=sel4
record.adc-2:3_mute=off
inputs.beep=85
outputs.hp_sense=plugged
outputs.line-in_sense=unplugged
outputs.spkr_muters=hp,line-in
outputs.master=153,153
outputs.master.mute=off
outputs.master.slaves=dac-2:3,dac-0:1
record.volume=0,0
record.volume.mute=off
record.volume.slaves=adc-0:1,adc-2:3

After:
s@d630:0:/usr/src/usr.bin/mixerctl$ ./mixerctl
inputs.beep=85
inputs.dac-0:1=152,152
inputs.dac-0:1_mute=off
inputs.dac-2:3=152,152
inputs.dac-2:3_mute=off
inputs.sel2_source=line-in
inputs.sel3_sel=119,119
inputs.sel3_source=sel
inputs.sel4_sel2=119,119
inputs.sel4_source=sel2
inputs.sel_source=mic
outputs.hp_boost=off
outputs.hp_dir=output
outputs.hp_sense=plugged
outputs.hp_source=dac-0:1
outputs.line-in_dir=input
outputs.line-in_sense=unplugged
outputs.line-in_source=dac-2:3
outputs.master=153,153
outputs.master.mute=off
outputs.master.slaves=dac-2:3,dac-0:1
outputs.mic_dir=input-vr80
outputs.sel=126,126
outputs.sel2=126,126
outputs.spkr_boost=off
outputs.spkr_dir=none
outputs.spkr_muters=hp,line-in
outputs.spkr_source=dac-2:3
record.adc-0:1_mute=off
record.adc-0:1_source=sel3
record.adc-2:3_mute=off
record.adc-2:3_source=sel4
record.volume=0,0
record.volume.mute=off
record.volume.slaves=adc-0:1,adc-2:3



Index: mixerctl.c
===================================================================
RCS file: /OpenBSD/src/usr.bin/mixerctl/mixerctl.c,v
retrieving revision 1.29
diff -u -r1.29 mixerctl.c
--- mixerctl.c  12 Nov 2009 07:27:31 -0000      1.29
+++ mixerctl.c  8 May 2011 22:25:03 -0000
@@ -46,23 +46,21 @@
 #include <string.h>
 #include <unistd.h>
 
-struct field *findfield(char *);
-void adjlevel(char **, u_char *, int);
-void catstr(char *, char *, char *);
-void prfield(struct field *, char *, int, mixer_ctrl_t *);
-void rdfield(int, struct field *, char *, int, char *);
-__dead void usage(void);
-
 #define FIELD_NAME_MAX 64
 
 struct field {
        char name[FIELD_NAME_MAX];
        mixer_ctrl_t *valp;
        mixer_devinfo_t *infp;
-} *fields, *rfields;
+};
 
-mixer_ctrl_t *values;
-mixer_devinfo_t *infos;
+int             fieldcmp(const void *, const void *);
+int             fieldnamecmp(const void *, const void *);
+void            adjlevel(char **, u_char *, int);
+void            catstr(char *, char *, char *);
+void            prfield(struct field *, char *, int, mixer_ctrl_t *);
+void            rdfield(int, struct field *, char *, int, char *);
+__dead void     usage(void);
 
 void
 catstr(char *p, char *q, char *out)
@@ -73,14 +71,19 @@
        strlcpy(out, tmp, FIELD_NAME_MAX);
 }
 
-struct field *
-findfield(char *name)
+int
+fieldcmp(const void *pa, const void *pb)
 {
-       int i;
-       for (i = 0; fields[i].name[0] != '\0'; i++)
-               if (strcmp(fields[i].name, name) == 0)
-                       return &fields[i];
-       return (0);
+       const struct field *a = pa, *b = pb;
+       return strcmp(a->name, b->name);
+}
+
+int
+fieldnamecmp(const void *pa, const void *pb)
+{
+       const char *name = pa;
+       const struct field *f = pb;
+       return strcmp(name, f->name);
 }
 
 #define e_member_name  un.e.member[i].label.name
@@ -241,12 +244,15 @@
 int
 main(int argc, char **argv)
 {
-       int fd, i, j, ch, pos;
+       int fd, i, ch, pos;
        int aflag = 0, qflag = 0, vflag = 0, tflag = 0;
        char *file;
        char *sep = "=";
-       mixer_devinfo_t dinfo;
+       mixer_devinfo_t dinfo, *infos;
+       mixer_ctrl_t *values;
        int ndev;
+       struct field *fields, *rfields;
+       int nfields;
 
        if ((file = getenv("MIXERDEVICE")) == 0 || *file == '\0')
                file = "/dev/mixer";
@@ -331,29 +337,31 @@
                }
        }
 
-       for (j = i = 0; i < ndev; i++) {
+       for (nfields = i = 0; i < ndev; i++) {
                if (infos[i].type != AUDIO_MIXER_CLASS &&
                    infos[i].prev == AUDIO_MIXER_LAST) {
-                       fields[j++] = rfields[i];
+                       fields[nfields++] = rfields[i];
                        for (pos = infos[i].next; pos != AUDIO_MIXER_LAST;
                            pos = infos[pos].next) {
-                               fields[j] = rfields[pos];
+                               fields[nfields] = rfields[pos];
                                catstr(rfields[i].name, infos[pos].label.name,
-                                   fields[j].name);
-                               j++;
+                                   fields[nfields].name);
+                               nfields++;
                        }
                }
        }
 
-       for (i = 0; i < j; i++) {
+       for (i = 0; i < nfields; i++) {
                int cls = fields[i].infp->mixer_class;
                if (cls >= 0 && cls < ndev)
                        catstr(infos[cls].label.name, fields[i].name,
                            fields[i].name);
        }
 
+       qsort(fields, nfields, sizeof *fields, fieldcmp);
+
        if (!argc && aflag) {
-               for (i = 0; fields[i].name[0] != '\0'; i++) {
+               for (i = 0; i < nfields; i++) {
                        prfield(&fields[i], sep, vflag, fields[i].valp);
                        printf("\n");
                }
@@ -369,7 +377,9 @@
                                ch = 1;
                        }
 
-                       if ((p = findfield(*argv)) == NULL) {
+                       p = bsearch(*argv, fields, nfields, sizeof *fields,
+                           fieldnamecmp);
+                       if (p == NULL) {
                                warnx("field %s does not exist", *argv);
                        } else if (ch || tflag) {
                                if (tflag && q == NULL)

Reply via email to