summaryrefslogtreecommitdiffstats
path: root/tools/lib/subcmd/parse-options.c
diff options
context:
space:
mode:
authorJosh Poimboeuf <jpoimboe@redhat.com>2022-04-18 18:50:21 +0200
committerPeter Zijlstra <peterz@infradead.org>2022-04-22 12:32:01 +0200
commitaa3d60e050112ef1373d7216eabe0ee966615527 (patch)
tree60c0084d3faf49fee0a2813daa339268b0f2191e /tools/lib/subcmd/parse-options.c
parentMerge branch 'tip/x86/urgent' (diff)
downloadlinux-aa3d60e050112ef1373d7216eabe0ee966615527.tar.xz
linux-aa3d60e050112ef1373d7216eabe0ee966615527.zip
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
Diffstat (limited to 'tools/lib/subcmd/parse-options.c')
-rw-r--r--tools/lib/subcmd/parse-options.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/tools/lib/subcmd/parse-options.c b/tools/lib/subcmd/parse-options.c
index 39ebf6192016..9fa75943f2ed 100644
--- a/tools/lib/subcmd/parse-options.c
+++ b/tools/lib/subcmd/parse-options.c
@@ -806,9 +806,9 @@ static int option__cmp(const void *va, const void *vb)
static struct option *options__order(const struct option *opts)
{
- int nr_opts = 0, len;
+ int nr_opts = 0, nr_group = 0, len;
const struct option *o = opts;
- struct option *ordered;
+ struct option *opt, *ordered, *group;
for (o = opts; o->type != OPTION_END; o++)
++nr_opts;
@@ -819,7 +819,18 @@ static struct option *options__order(const struct option *opts)
goto out;
memcpy(ordered, opts, len);
- qsort(ordered, nr_opts, sizeof(*o), option__cmp);
+ /* sort each option group individually */
+ for (opt = group = ordered; opt->type != OPTION_END; opt++) {
+ if (opt->type == OPTION_GROUP) {
+ qsort(group, nr_group, sizeof(*opt), option__cmp);
+ group = opt + 1;
+ nr_group = 0;
+ continue;
+ }
+ nr_group++;
+ }
+ qsort(group, nr_group, sizeof(*opt), option__cmp);
+
out:
return ordered;
}