Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

libsubcmd: Fix OPTION_GROUP sorting

The OPTION_GROUP option type is a way of grouping certain options
together in the printed usage text. It happens to be completely broken,
thanks to the fact that the subcmd option sorting just sorts everything,
without regard for grouping. Luckily, nobody uses this option anyway,
though that will change shortly.

Fix it by sorting each group individually.

Signed-off-by: Josh Poimboeuf <jpoimboe@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Miroslav Benes <mbenes@suse.cz>
Link: https://lkml.kernel.org/r/e167ea3a11e2a9800eb062c1fd0f13e9cd05140c.1650300597.git.jpoimboe@redhat.com

authored by

Josh Poimboeuf and committed by
Peter Zijlstra
aa3d60e0 3398b12d

+14 -3
+14 -3
tools/lib/subcmd/parse-options.c
··· 806 806 807 807 static struct option *options__order(const struct option *opts) 808 808 { 809 - int nr_opts = 0, len; 809 + int nr_opts = 0, nr_group = 0, len; 810 810 const struct option *o = opts; 811 - struct option *ordered; 811 + struct option *opt, *ordered, *group; 812 812 813 813 for (o = opts; o->type != OPTION_END; o++) 814 814 ++nr_opts; ··· 819 819 goto out; 820 820 memcpy(ordered, opts, len); 821 821 822 - qsort(ordered, nr_opts, sizeof(*o), option__cmp); 822 + /* sort each option group individually */ 823 + for (opt = group = ordered; opt->type != OPTION_END; opt++) { 824 + if (opt->type == OPTION_GROUP) { 825 + qsort(group, nr_group, sizeof(*opt), option__cmp); 826 + group = opt + 1; 827 + nr_group = 0; 828 + continue; 829 + } 830 + nr_group++; 831 + } 832 + qsort(group, nr_group, sizeof(*opt), option__cmp); 833 + 823 834 out: 824 835 return ordered; 825 836 }