On Sun, May 8, 2011 at 5:32 PM, Sviatoslav Chagaev <sviatoslav.chag...@gmail.com> wrote: > * 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 B 12 Nov 2009 07:27:31 -0000 B B B 1.29 > +++ mixerctl.c B 8 May 2011 22:25:03 -0000 > @@ -46,23 +46,21 @@ > B #include <string.h> > B #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); > - > B #define FIELD_NAME_MAX 64 > > B struct field { > B B B B char name[FIELD_NAME_MAX]; > B B B B mixer_ctrl_t *valp; > B B B B mixer_devinfo_t *infp; > -} *fields, *rfields; > +}; > > -mixer_ctrl_t *values; > -mixer_devinfo_t *infos; > +int B B B B B B fieldcmp(const void *, const void *); > +int B B B B B B fieldnamecmp(const void *, const void *); > +void B B B B B B adjlevel(char **, u_char *, int); > +void B B B B B B catstr(char *, char *, char *); > +void B B B B B B prfield(struct field *, char *, int, mixer_ctrl_t *); > +void B B B B B B rdfield(int, struct field *, char *, int, char *); > +__dead void B B usage(void); > > B void > B catstr(char *p, char *q, char *out) > @@ -73,14 +71,19 @@ > B B B B strlcpy(out, tmp, FIELD_NAME_MAX); > B } > > -struct field * > -findfield(char *name) > +int > +fieldcmp(const void *pa, const void *pb) > B { > - B B B int i; > - B B B for (i = 0; fields[i].name[0] != '\0'; i++) > - B B B B B B B if (strcmp(fields[i].name, name) == 0) > - B B B B B B B B B B B return &fields[i]; > - B B B return (0); > + B B B const struct field *a = pa, *b = pb; > + B B B return strcmp(a->name, b->name); > +} > + > +int > +fieldnamecmp(const void *pa, const void *pb) > +{ > + B B B const char *name = pa; > + B B B const struct field *f = pb; > + B B B return strcmp(name, f->name); > B } > > B #define e_member_name B un.e.member[i].label.name > @@ -241,12 +244,15 @@ > B int > B main(int argc, char **argv) > B { > - B B B int fd, i, j, ch, pos; > + B B B int fd, i, ch, pos; > B B B B int aflag = 0, qflag = 0, vflag = 0, tflag = 0; > B B B B char *file; > B B B B char *sep = "="; > - B B B mixer_devinfo_t dinfo; > + B B B mixer_devinfo_t dinfo, *infos; > + B B B mixer_ctrl_t *values; > B B B B int ndev; > + B B B struct field *fields, *rfields; > + B B B int nfields; > > B B B B if ((file = getenv("MIXERDEVICE")) == 0 || *file == '\0') > B B B B B B B B file = "/dev/mixer"; > @@ -331,29 +337,31 @@ > B B B B B B B B } > B B B B } > > - B B B for (j = i = 0; i < ndev; i++) { > + B B B for (nfields = i = 0; i < ndev; i++) { > B B B B B B B B if (infos[i].type != AUDIO_MIXER_CLASS && > B B B B B B B B B B infos[i].prev == AUDIO_MIXER_LAST) { > - B B B B B B B B B B B fields[j++] = rfields[i]; > + B B B B B B B B B B B fields[nfields++] = rfields[i]; > B B B B B B B B B B B B for (pos = infos[i].next; pos != AUDIO_MIXER_LAST; > B B B B B B B B B B B B B B pos = infos[pos].next) { > - B B B B B B B B B B B B B B B fields[j] = rfields[pos]; > + B B B B B B B B B B B B B B B fields[nfields] = rfields[pos]; > B B B B B B B B B B B B B B B B catstr(rfields[i].name, infos[pos].label.name, > - B B B B B B B B B B B B B B B B B fields[j].name); > - B B B B B B B B B B B B B B B j++; > + B B B B B B B B B B B B B B B B B fields[nfields].name); > + B B B B B B B B B B B B B B B nfields++; > B B B B B B B B B B B B } > B B B B B B B B } > B B B B } > > - B B B for (i = 0; i < j; i++) { > + B B B for (i = 0; i < nfields; i++) { > B B B B B B B B int cls = fields[i].infp->mixer_class; > B B B B B B B B if (cls >= 0 && cls < ndev) > B B B B B B B B B B B B catstr(infos[cls].label.name, fields[i].name, > B B B B B B B B B B B B B B fields[i].name); > B B B B } > > + B B B qsort(fields, nfields, sizeof *fields, fieldcmp); > + > B B B B if (!argc && aflag) { > - B B B B B B B for (i = 0; fields[i].name[0] != '\0'; i++) { > + B B B B B B B for (i = 0; i < nfields; i++) { > B B B B B B B B B B B B prfield(&fields[i], sep, vflag, fields[i].valp); > B B B B B B B B B B B B printf("\n"); > B B B B B B B B } > @@ -369,7 +377,9 @@ > B B B B B B B B B B B B B B B B ch = 1; > B B B B B B B B B B B B } > > - B B B B B B B B B B B if ((p = findfield(*argv)) == NULL) { > + B B B B B B B B B B B p = bsearch(*argv, fields, nfields, sizeof *fields, > + B B B B B B B B B B B B B fieldnamecmp); > + B B B B B B B B B B B if (p == NULL) { > B B B B B B B B B B B B B B B B warnx("field %s does not exist", *argv); > B B B B B B B B B B B B } else if (ch || tflag) { > B B B B B B B B B B B B B B B B if (tflag && q == NULL) > >
Am I missing something? $ sysctl | sort > /tmp/sysctl_sorted $ sysctl | cmp -s /tmp/sysctl_sorted /dev/stdin || echo "different"; different $