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