* 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)