From: Arnaldo Carvalho de Melo Date: Fri, 23 Oct 2015 14:23:28 +0000 (-0300) Subject: perf tools: Show tool command line options ordered X-Git-Tag: firefly_0821_release~176^2~832^2~3^2~1 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=869c55b0f473fecfe6c294c6fa965dedfe469e02;p=firefly-linux-kernel-4.4.55.git perf tools: Show tool command line options ordered When asking for a listing of the options, be it using -h or when an unknown option is passed, order it by one-letter options, then the ones having just long names. Suggested-by: Ingo Molnar Cc: Adrian Hunter Cc: Borislav Petkov Cc: Brendan Gregg Cc: Chandler Carruth Cc: David Ahern Cc: Frederic Weisbecker Cc: Jiri Olsa Cc: Namhyung Kim Cc: Peter Zijlstra Cc: Stephane Eranian Cc: Wang Nan Link: http://lkml.kernel.org/n/tip-41qh68t35n4ehrpsuazp1dx8@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo --- diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c index 8aa7922397a9..fb26532d67c3 100644 --- a/tools/perf/util/parse-options.c +++ b/tools/perf/util/parse-options.c @@ -2,6 +2,7 @@ #include "parse-options.h" #include "cache.h" #include "header.h" +#include #define OPT_SHORT 1 #define OPT_UNSET 2 @@ -642,9 +643,50 @@ static void print_option_help(const struct option *opts, int full) fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help); } +static int option__cmp(const void *va, const void *vb) +{ + const struct option *a = va, *b = vb; + int sa = tolower(a->short_name), sb = tolower(b->short_name), ret; + + if (sa == 0) + sa = 'z' + 1; + if (sb == 0) + sb = 'z' + 1; + + ret = sa - sb; + + if (ret == 0) { + const char *la = a->long_name ?: "", + *lb = b->long_name ?: ""; + ret = strcmp(la, lb); + } + + return ret; +} + +static struct option *options__order(const struct option *opts) +{ + int nr_opts = 0; + const struct option *o = opts; + struct option *ordered; + + for (o = opts; o->type != OPTION_END; o++) + ++nr_opts; + + ordered = memdup(opts, sizeof(*o) * (nr_opts + 1)); + if (ordered == NULL) + goto out; + + qsort(ordered, nr_opts, sizeof(*o), option__cmp); +out: + return ordered; +} + int usage_with_options_internal(const char * const *usagestr, const struct option *opts, int full) { + struct option *ordered; + if (!usagestr) return PARSE_OPT_HELP; @@ -661,11 +703,17 @@ int usage_with_options_internal(const char * const *usagestr, if (opts->type != OPTION_GROUP) fputc('\n', stderr); + ordered = options__order(opts); + if (ordered) + opts = ordered; + for ( ; opts->type != OPTION_END; opts++) print_option_help(opts, full); fputc('\n', stderr); + free(ordered); + return PARSE_OPT_HELP; }