]> asedeno.scripts.mit.edu Git - linux.git/blob - tools/lib/subcmd/parse-options.c
Merge remote-tracking branches 'spi/topic/rockchip', 'spi/topic/rspi', 'spi/topic...
[linux.git] / tools / lib / subcmd / parse-options.c
1 #include <linux/compiler.h>
2 #include <linux/types.h>
3 #include <stdio.h>
4 #include <stdlib.h>
5 #include <stdint.h>
6 #include <string.h>
7 #include <ctype.h>
8 #include "subcmd-util.h"
9 #include "parse-options.h"
10 #include "subcmd-config.h"
11 #include "pager.h"
12
13 #define OPT_SHORT 1
14 #define OPT_UNSET 2
15
16 char *error_buf;
17
18 static int opterror(const struct option *opt, const char *reason, int flags)
19 {
20         if (flags & OPT_SHORT)
21                 fprintf(stderr, " Error: switch `%c' %s", opt->short_name, reason);
22         else if (flags & OPT_UNSET)
23                 fprintf(stderr, " Error: option `no-%s' %s", opt->long_name, reason);
24         else
25                 fprintf(stderr, " Error: option `%s' %s", opt->long_name, reason);
26
27         return -1;
28 }
29
30 static const char *skip_prefix(const char *str, const char *prefix)
31 {
32         size_t len = strlen(prefix);
33         return strncmp(str, prefix, len) ? NULL : str + len;
34 }
35
36 static void optwarning(const struct option *opt, const char *reason, int flags)
37 {
38         if (flags & OPT_SHORT)
39                 fprintf(stderr, " Warning: switch `%c' %s", opt->short_name, reason);
40         else if (flags & OPT_UNSET)
41                 fprintf(stderr, " Warning: option `no-%s' %s", opt->long_name, reason);
42         else
43                 fprintf(stderr, " Warning: option `%s' %s", opt->long_name, reason);
44 }
45
46 static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt,
47                    int flags, const char **arg)
48 {
49         const char *res;
50
51         if (p->opt) {
52                 res = p->opt;
53                 p->opt = NULL;
54         } else if ((opt->flags & PARSE_OPT_LASTARG_DEFAULT) && (p->argc == 1 ||
55                     **(p->argv + 1) == '-')) {
56                 res = (const char *)opt->defval;
57         } else if (p->argc > 1) {
58                 p->argc--;
59                 res = *++p->argv;
60         } else
61                 return opterror(opt, "requires a value", flags);
62         if (arg)
63                 *arg = res;
64         return 0;
65 }
66
67 static int get_value(struct parse_opt_ctx_t *p,
68                      const struct option *opt, int flags)
69 {
70         const char *s, *arg = NULL;
71         const int unset = flags & OPT_UNSET;
72         int err;
73
74         if (unset && p->opt)
75                 return opterror(opt, "takes no value", flags);
76         if (unset && (opt->flags & PARSE_OPT_NONEG))
77                 return opterror(opt, "isn't available", flags);
78         if (opt->flags & PARSE_OPT_DISABLED)
79                 return opterror(opt, "is not usable", flags);
80
81         if (opt->flags & PARSE_OPT_EXCLUSIVE) {
82                 if (p->excl_opt && p->excl_opt != opt) {
83                         char msg[128];
84
85                         if (((flags & OPT_SHORT) && p->excl_opt->short_name) ||
86                             p->excl_opt->long_name == NULL) {
87                                 snprintf(msg, sizeof(msg), "cannot be used with switch `%c'",
88                                          p->excl_opt->short_name);
89                         } else {
90                                 snprintf(msg, sizeof(msg), "cannot be used with %s",
91                                          p->excl_opt->long_name);
92                         }
93                         opterror(opt, msg, flags);
94                         return -3;
95                 }
96                 p->excl_opt = opt;
97         }
98         if (!(flags & OPT_SHORT) && p->opt) {
99                 switch (opt->type) {
100                 case OPTION_CALLBACK:
101                         if (!(opt->flags & PARSE_OPT_NOARG))
102                                 break;
103                         /* FALLTHROUGH */
104                 case OPTION_BOOLEAN:
105                 case OPTION_INCR:
106                 case OPTION_BIT:
107                 case OPTION_SET_UINT:
108                 case OPTION_SET_PTR:
109                         return opterror(opt, "takes no value", flags);
110                 case OPTION_END:
111                 case OPTION_ARGUMENT:
112                 case OPTION_GROUP:
113                 case OPTION_STRING:
114                 case OPTION_INTEGER:
115                 case OPTION_UINTEGER:
116                 case OPTION_LONG:
117                 case OPTION_U64:
118                 default:
119                         break;
120                 }
121         }
122
123         if (opt->flags & PARSE_OPT_NOBUILD) {
124                 char reason[128];
125                 bool noarg = false;
126
127                 err = snprintf(reason, sizeof(reason),
128                                 opt->flags & PARSE_OPT_CANSKIP ?
129                                         "is being ignored because %s " :
130                                         "is not available because %s",
131                                 opt->build_opt);
132                 reason[sizeof(reason) - 1] = '\0';
133
134                 if (err < 0)
135                         strncpy(reason, opt->flags & PARSE_OPT_CANSKIP ?
136                                         "is being ignored" :
137                                         "is not available",
138                                         sizeof(reason));
139
140                 if (!(opt->flags & PARSE_OPT_CANSKIP))
141                         return opterror(opt, reason, flags);
142
143                 err = 0;
144                 if (unset)
145                         noarg = true;
146                 if (opt->flags & PARSE_OPT_NOARG)
147                         noarg = true;
148                 if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
149                         noarg = true;
150
151                 switch (opt->type) {
152                 case OPTION_BOOLEAN:
153                 case OPTION_INCR:
154                 case OPTION_BIT:
155                 case OPTION_SET_UINT:
156                 case OPTION_SET_PTR:
157                 case OPTION_END:
158                 case OPTION_ARGUMENT:
159                 case OPTION_GROUP:
160                         noarg = true;
161                         break;
162                 case OPTION_CALLBACK:
163                 case OPTION_STRING:
164                 case OPTION_INTEGER:
165                 case OPTION_UINTEGER:
166                 case OPTION_LONG:
167                 case OPTION_U64:
168                 default:
169                         break;
170                 }
171
172                 if (!noarg)
173                         err = get_arg(p, opt, flags, NULL);
174                 if (err)
175                         return err;
176
177                 optwarning(opt, reason, flags);
178                 return 0;
179         }
180
181         switch (opt->type) {
182         case OPTION_BIT:
183                 if (unset)
184                         *(int *)opt->value &= ~opt->defval;
185                 else
186                         *(int *)opt->value |= opt->defval;
187                 return 0;
188
189         case OPTION_BOOLEAN:
190                 *(bool *)opt->value = unset ? false : true;
191                 if (opt->set)
192                         *(bool *)opt->set = true;
193                 return 0;
194
195         case OPTION_INCR:
196                 *(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
197                 return 0;
198
199         case OPTION_SET_UINT:
200                 *(unsigned int *)opt->value = unset ? 0 : opt->defval;
201                 return 0;
202
203         case OPTION_SET_PTR:
204                 *(void **)opt->value = unset ? NULL : (void *)opt->defval;
205                 return 0;
206
207         case OPTION_STRING:
208                 err = 0;
209                 if (unset)
210                         *(const char **)opt->value = NULL;
211                 else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
212                         *(const char **)opt->value = (const char *)opt->defval;
213                 else
214                         err = get_arg(p, opt, flags, (const char **)opt->value);
215
216                 /* PARSE_OPT_NOEMPTY: Allow NULL but disallow empty string. */
217                 if (opt->flags & PARSE_OPT_NOEMPTY) {
218                         const char *val = *(const char **)opt->value;
219
220                         if (!val)
221                                 return err;
222
223                         /* Similar to unset if we are given an empty string. */
224                         if (val[0] == '\0') {
225                                 *(const char **)opt->value = NULL;
226                                 return 0;
227                         }
228                 }
229
230                 return err;
231
232         case OPTION_CALLBACK:
233                 if (unset)
234                         return (*opt->callback)(opt, NULL, 1) ? (-1) : 0;
235                 if (opt->flags & PARSE_OPT_NOARG)
236                         return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
237                 if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
238                         return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
239                 if (get_arg(p, opt, flags, &arg))
240                         return -1;
241                 return (*opt->callback)(opt, arg, 0) ? (-1) : 0;
242
243         case OPTION_INTEGER:
244                 if (unset) {
245                         *(int *)opt->value = 0;
246                         return 0;
247                 }
248                 if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
249                         *(int *)opt->value = opt->defval;
250                         return 0;
251                 }
252                 if (get_arg(p, opt, flags, &arg))
253                         return -1;
254                 *(int *)opt->value = strtol(arg, (char **)&s, 10);
255                 if (*s)
256                         return opterror(opt, "expects a numerical value", flags);
257                 return 0;
258
259         case OPTION_UINTEGER:
260                 if (unset) {
261                         *(unsigned int *)opt->value = 0;
262                         return 0;
263                 }
264                 if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
265                         *(unsigned int *)opt->value = opt->defval;
266                         return 0;
267                 }
268                 if (get_arg(p, opt, flags, &arg))
269                         return -1;
270                 *(unsigned int *)opt->value = strtol(arg, (char **)&s, 10);
271                 if (*s)
272                         return opterror(opt, "expects a numerical value", flags);
273                 return 0;
274
275         case OPTION_LONG:
276                 if (unset) {
277                         *(long *)opt->value = 0;
278                         return 0;
279                 }
280                 if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
281                         *(long *)opt->value = opt->defval;
282                         return 0;
283                 }
284                 if (get_arg(p, opt, flags, &arg))
285                         return -1;
286                 *(long *)opt->value = strtol(arg, (char **)&s, 10);
287                 if (*s)
288                         return opterror(opt, "expects a numerical value", flags);
289                 return 0;
290
291         case OPTION_U64:
292                 if (unset) {
293                         *(u64 *)opt->value = 0;
294                         return 0;
295                 }
296                 if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
297                         *(u64 *)opt->value = opt->defval;
298                         return 0;
299                 }
300                 if (get_arg(p, opt, flags, &arg))
301                         return -1;
302                 *(u64 *)opt->value = strtoull(arg, (char **)&s, 10);
303                 if (*s)
304                         return opterror(opt, "expects a numerical value", flags);
305                 return 0;
306
307         case OPTION_END:
308         case OPTION_ARGUMENT:
309         case OPTION_GROUP:
310         default:
311                 die("should not happen, someone must be hit on the forehead");
312         }
313 }
314
315 static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *options)
316 {
317 retry:
318         for (; options->type != OPTION_END; options++) {
319                 if (options->short_name == *p->opt) {
320                         p->opt = p->opt[1] ? p->opt + 1 : NULL;
321                         return get_value(p, options, OPT_SHORT);
322                 }
323         }
324
325         if (options->parent) {
326                 options = options->parent;
327                 goto retry;
328         }
329
330         return -2;
331 }
332
333 static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
334                           const struct option *options)
335 {
336         const char *arg_end = strchr(arg, '=');
337         const struct option *abbrev_option = NULL, *ambiguous_option = NULL;
338         int abbrev_flags = 0, ambiguous_flags = 0;
339
340         if (!arg_end)
341                 arg_end = arg + strlen(arg);
342
343 retry:
344         for (; options->type != OPTION_END; options++) {
345                 const char *rest;
346                 int flags = 0;
347
348                 if (!options->long_name)
349                         continue;
350
351                 rest = skip_prefix(arg, options->long_name);
352                 if (options->type == OPTION_ARGUMENT) {
353                         if (!rest)
354                                 continue;
355                         if (*rest == '=')
356                                 return opterror(options, "takes no value", flags);
357                         if (*rest)
358                                 continue;
359                         p->out[p->cpidx++] = arg - 2;
360                         return 0;
361                 }
362                 if (!rest) {
363                         if (!prefixcmp(options->long_name, "no-")) {
364                                 /*
365                                  * The long name itself starts with "no-", so
366                                  * accept the option without "no-" so that users
367                                  * do not have to enter "no-no-" to get the
368                                  * negation.
369                                  */
370                                 rest = skip_prefix(arg, options->long_name + 3);
371                                 if (rest) {
372                                         flags |= OPT_UNSET;
373                                         goto match;
374                                 }
375                                 /* Abbreviated case */
376                                 if (!prefixcmp(options->long_name + 3, arg)) {
377                                         flags |= OPT_UNSET;
378                                         goto is_abbreviated;
379                                 }
380                         }
381                         /* abbreviated? */
382                         if (!strncmp(options->long_name, arg, arg_end - arg)) {
383 is_abbreviated:
384                                 if (abbrev_option) {
385                                         /*
386                                          * If this is abbreviated, it is
387                                          * ambiguous. So when there is no
388                                          * exact match later, we need to
389                                          * error out.
390                                          */
391                                         ambiguous_option = abbrev_option;
392                                         ambiguous_flags = abbrev_flags;
393                                 }
394                                 if (!(flags & OPT_UNSET) && *arg_end)
395                                         p->opt = arg_end + 1;
396                                 abbrev_option = options;
397                                 abbrev_flags = flags;
398                                 continue;
399                         }
400                         /* negated and abbreviated very much? */
401                         if (!prefixcmp("no-", arg)) {
402                                 flags |= OPT_UNSET;
403                                 goto is_abbreviated;
404                         }
405                         /* negated? */
406                         if (strncmp(arg, "no-", 3))
407                                 continue;
408                         flags |= OPT_UNSET;
409                         rest = skip_prefix(arg + 3, options->long_name);
410                         /* abbreviated and negated? */
411                         if (!rest && !prefixcmp(options->long_name, arg + 3))
412                                 goto is_abbreviated;
413                         if (!rest)
414                                 continue;
415                 }
416 match:
417                 if (*rest) {
418                         if (*rest != '=')
419                                 continue;
420                         p->opt = rest + 1;
421                 }
422                 return get_value(p, options, flags);
423         }
424
425         if (ambiguous_option) {
426                  fprintf(stderr,
427                          " Error: Ambiguous option: %s (could be --%s%s or --%s%s)",
428                          arg,
429                          (ambiguous_flags & OPT_UNSET) ?  "no-" : "",
430                          ambiguous_option->long_name,
431                          (abbrev_flags & OPT_UNSET) ?  "no-" : "",
432                          abbrev_option->long_name);
433                  return -1;
434         }
435         if (abbrev_option)
436                 return get_value(p, abbrev_option, abbrev_flags);
437
438         if (options->parent) {
439                 options = options->parent;
440                 goto retry;
441         }
442
443         return -2;
444 }
445
446 static void check_typos(const char *arg, const struct option *options)
447 {
448         if (strlen(arg) < 3)
449                 return;
450
451         if (!prefixcmp(arg, "no-")) {
452                 fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg);
453                 exit(129);
454         }
455
456         for (; options->type != OPTION_END; options++) {
457                 if (!options->long_name)
458                         continue;
459                 if (!prefixcmp(options->long_name, arg)) {
460                         fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg);
461                         exit(129);
462                 }
463         }
464 }
465
466 static void parse_options_start(struct parse_opt_ctx_t *ctx,
467                                 int argc, const char **argv, int flags)
468 {
469         memset(ctx, 0, sizeof(*ctx));
470         ctx->argc = argc - 1;
471         ctx->argv = argv + 1;
472         ctx->out  = argv;
473         ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
474         ctx->flags = flags;
475         if ((flags & PARSE_OPT_KEEP_UNKNOWN) &&
476             (flags & PARSE_OPT_STOP_AT_NON_OPTION))
477                 die("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
478 }
479
480 static int usage_with_options_internal(const char * const *,
481                                        const struct option *, int,
482                                        struct parse_opt_ctx_t *);
483
484 static int parse_options_step(struct parse_opt_ctx_t *ctx,
485                               const struct option *options,
486                               const char * const usagestr[])
487 {
488         int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
489         int excl_short_opt = 1;
490         const char *arg;
491
492         /* we must reset ->opt, unknown short option leave it dangling */
493         ctx->opt = NULL;
494
495         for (; ctx->argc; ctx->argc--, ctx->argv++) {
496                 arg = ctx->argv[0];
497                 if (*arg != '-' || !arg[1]) {
498                         if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
499                                 break;
500                         ctx->out[ctx->cpidx++] = ctx->argv[0];
501                         continue;
502                 }
503
504                 if (arg[1] != '-') {
505                         ctx->opt = ++arg;
506                         if (internal_help && *ctx->opt == 'h') {
507                                 return usage_with_options_internal(usagestr, options, 0, ctx);
508                         }
509                         switch (parse_short_opt(ctx, options)) {
510                         case -1:
511                                 return parse_options_usage(usagestr, options, arg, 1);
512                         case -2:
513                                 goto unknown;
514                         case -3:
515                                 goto exclusive;
516                         default:
517                                 break;
518                         }
519                         if (ctx->opt)
520                                 check_typos(arg, options);
521                         while (ctx->opt) {
522                                 if (internal_help && *ctx->opt == 'h')
523                                         return usage_with_options_internal(usagestr, options, 0, ctx);
524                                 arg = ctx->opt;
525                                 switch (parse_short_opt(ctx, options)) {
526                                 case -1:
527                                         return parse_options_usage(usagestr, options, arg, 1);
528                                 case -2:
529                                         /* fake a short option thing to hide the fact that we may have
530                                          * started to parse aggregated stuff
531                                          *
532                                          * This is leaky, too bad.
533                                          */
534                                         ctx->argv[0] = strdup(ctx->opt - 1);
535                                         *(char *)ctx->argv[0] = '-';
536                                         goto unknown;
537                                 case -3:
538                                         goto exclusive;
539                                 default:
540                                         break;
541                                 }
542                         }
543                         continue;
544                 }
545
546                 if (!arg[2]) { /* "--" */
547                         if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
548                                 ctx->argc--;
549                                 ctx->argv++;
550                         }
551                         break;
552                 }
553
554                 arg += 2;
555                 if (internal_help && !strcmp(arg, "help-all"))
556                         return usage_with_options_internal(usagestr, options, 1, ctx);
557                 if (internal_help && !strcmp(arg, "help"))
558                         return usage_with_options_internal(usagestr, options, 0, ctx);
559                 if (!strcmp(arg, "list-opts"))
560                         return PARSE_OPT_LIST_OPTS;
561                 if (!strcmp(arg, "list-cmds"))
562                         return PARSE_OPT_LIST_SUBCMDS;
563                 switch (parse_long_opt(ctx, arg, options)) {
564                 case -1:
565                         return parse_options_usage(usagestr, options, arg, 0);
566                 case -2:
567                         goto unknown;
568                 case -3:
569                         excl_short_opt = 0;
570                         goto exclusive;
571                 default:
572                         break;
573                 }
574                 continue;
575 unknown:
576                 if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN))
577                         return PARSE_OPT_UNKNOWN;
578                 ctx->out[ctx->cpidx++] = ctx->argv[0];
579                 ctx->opt = NULL;
580         }
581         return PARSE_OPT_DONE;
582
583 exclusive:
584         parse_options_usage(usagestr, options, arg, excl_short_opt);
585         if ((excl_short_opt && ctx->excl_opt->short_name) ||
586             ctx->excl_opt->long_name == NULL) {
587                 char opt = ctx->excl_opt->short_name;
588                 parse_options_usage(NULL, options, &opt, 1);
589         } else {
590                 parse_options_usage(NULL, options, ctx->excl_opt->long_name, 0);
591         }
592         return PARSE_OPT_HELP;
593 }
594
595 static int parse_options_end(struct parse_opt_ctx_t *ctx)
596 {
597         memmove(ctx->out + ctx->cpidx, ctx->argv, ctx->argc * sizeof(*ctx->out));
598         ctx->out[ctx->cpidx + ctx->argc] = NULL;
599         return ctx->cpidx + ctx->argc;
600 }
601
602 int parse_options_subcommand(int argc, const char **argv, const struct option *options,
603                         const char *const subcommands[], const char *usagestr[], int flags)
604 {
605         struct parse_opt_ctx_t ctx;
606
607         /* build usage string if it's not provided */
608         if (subcommands && !usagestr[0]) {
609                 char *buf = NULL;
610
611                 astrcatf(&buf, "%s %s [<options>] {", subcmd_config.exec_name, argv[0]);
612
613                 for (int i = 0; subcommands[i]; i++) {
614                         if (i)
615                                 astrcat(&buf, "|");
616                         astrcat(&buf, subcommands[i]);
617                 }
618                 astrcat(&buf, "}");
619
620                 usagestr[0] = buf;
621         }
622
623         parse_options_start(&ctx, argc, argv, flags);
624         switch (parse_options_step(&ctx, options, usagestr)) {
625         case PARSE_OPT_HELP:
626                 exit(129);
627         case PARSE_OPT_DONE:
628                 break;
629         case PARSE_OPT_LIST_OPTS:
630                 while (options->type != OPTION_END) {
631                         if (options->long_name)
632                                 printf("--%s ", options->long_name);
633                         options++;
634                 }
635                 putchar('\n');
636                 exit(130);
637         case PARSE_OPT_LIST_SUBCMDS:
638                 if (subcommands) {
639                         for (int i = 0; subcommands[i]; i++)
640                                 printf("%s ", subcommands[i]);
641                 }
642                 putchar('\n');
643                 exit(130);
644         default: /* PARSE_OPT_UNKNOWN */
645                 if (ctx.argv[0][1] == '-')
646                         astrcatf(&error_buf, "unknown option `%s'",
647                                  ctx.argv[0] + 2);
648                 else
649                         astrcatf(&error_buf, "unknown switch `%c'", *ctx.opt);
650                 usage_with_options(usagestr, options);
651         }
652
653         return parse_options_end(&ctx);
654 }
655
656 int parse_options(int argc, const char **argv, const struct option *options,
657                   const char * const usagestr[], int flags)
658 {
659         return parse_options_subcommand(argc, argv, options, NULL,
660                                         (const char **) usagestr, flags);
661 }
662
663 #define USAGE_OPTS_WIDTH 24
664 #define USAGE_GAP         2
665
666 static void print_option_help(const struct option *opts, int full)
667 {
668         size_t pos;
669         int pad;
670
671         if (opts->type == OPTION_GROUP) {
672                 fputc('\n', stderr);
673                 if (*opts->help)
674                         fprintf(stderr, "%s\n", opts->help);
675                 return;
676         }
677         if (!full && (opts->flags & PARSE_OPT_HIDDEN))
678                 return;
679         if (opts->flags & PARSE_OPT_DISABLED)
680                 return;
681
682         pos = fprintf(stderr, "    ");
683         if (opts->short_name)
684                 pos += fprintf(stderr, "-%c", opts->short_name);
685         else
686                 pos += fprintf(stderr, "    ");
687
688         if (opts->long_name && opts->short_name)
689                 pos += fprintf(stderr, ", ");
690         if (opts->long_name)
691                 pos += fprintf(stderr, "--%s", opts->long_name);
692
693         switch (opts->type) {
694         case OPTION_ARGUMENT:
695                 break;
696         case OPTION_LONG:
697         case OPTION_U64:
698         case OPTION_INTEGER:
699         case OPTION_UINTEGER:
700                 if (opts->flags & PARSE_OPT_OPTARG)
701                         if (opts->long_name)
702                                 pos += fprintf(stderr, "[=<n>]");
703                         else
704                                 pos += fprintf(stderr, "[<n>]");
705                 else
706                         pos += fprintf(stderr, " <n>");
707                 break;
708         case OPTION_CALLBACK:
709                 if (opts->flags & PARSE_OPT_NOARG)
710                         break;
711                 /* FALLTHROUGH */
712         case OPTION_STRING:
713                 if (opts->argh) {
714                         if (opts->flags & PARSE_OPT_OPTARG)
715                                 if (opts->long_name)
716                                         pos += fprintf(stderr, "[=<%s>]", opts->argh);
717                                 else
718                                         pos += fprintf(stderr, "[<%s>]", opts->argh);
719                         else
720                                 pos += fprintf(stderr, " <%s>", opts->argh);
721                 } else {
722                         if (opts->flags & PARSE_OPT_OPTARG)
723                                 if (opts->long_name)
724                                         pos += fprintf(stderr, "[=...]");
725                                 else
726                                         pos += fprintf(stderr, "[...]");
727                         else
728                                 pos += fprintf(stderr, " ...");
729                 }
730                 break;
731         default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
732         case OPTION_END:
733         case OPTION_GROUP:
734         case OPTION_BIT:
735         case OPTION_BOOLEAN:
736         case OPTION_INCR:
737         case OPTION_SET_UINT:
738         case OPTION_SET_PTR:
739                 break;
740         }
741
742         if (pos <= USAGE_OPTS_WIDTH)
743                 pad = USAGE_OPTS_WIDTH - pos;
744         else {
745                 fputc('\n', stderr);
746                 pad = USAGE_OPTS_WIDTH;
747         }
748         fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
749         if (opts->flags & PARSE_OPT_NOBUILD)
750                 fprintf(stderr, "%*s(not built-in because %s)\n",
751                         USAGE_OPTS_WIDTH + USAGE_GAP, "",
752                         opts->build_opt);
753 }
754
755 static int option__cmp(const void *va, const void *vb)
756 {
757         const struct option *a = va, *b = vb;
758         int sa = tolower(a->short_name), sb = tolower(b->short_name), ret;
759
760         if (sa == 0)
761                 sa = 'z' + 1;
762         if (sb == 0)
763                 sb = 'z' + 1;
764
765         ret = sa - sb;
766
767         if (ret == 0) {
768                 const char *la = a->long_name ?: "",
769                            *lb = b->long_name ?: "";
770                 ret = strcmp(la, lb);
771         }
772
773         return ret;
774 }
775
776 static struct option *options__order(const struct option *opts)
777 {
778         int nr_opts = 0, len;
779         const struct option *o = opts;
780         struct option *ordered;
781
782         for (o = opts; o->type != OPTION_END; o++)
783                 ++nr_opts;
784
785         len = sizeof(*o) * (nr_opts + 1);
786         ordered = malloc(len);
787         if (!ordered)
788                 goto out;
789         memcpy(ordered, opts, len);
790
791         qsort(ordered, nr_opts, sizeof(*o), option__cmp);
792 out:
793         return ordered;
794 }
795
796 static bool option__in_argv(const struct option *opt, const struct parse_opt_ctx_t *ctx)
797 {
798         int i;
799
800         for (i = 1; i < ctx->argc; ++i) {
801                 const char *arg = ctx->argv[i];
802
803                 if (arg[0] != '-') {
804                         if (arg[1] == '\0') {
805                                 if (arg[0] == opt->short_name)
806                                         return true;
807                                 continue;
808                         }
809
810                         if (opt->long_name && strcmp(opt->long_name, arg) == 0)
811                                 return true;
812
813                         if (opt->help && strcasestr(opt->help, arg) != NULL)
814                                 return true;
815
816                         continue;
817                 }
818
819                 if (arg[1] == opt->short_name ||
820                     (arg[1] == '-' && opt->long_name && strcmp(opt->long_name, arg + 2) == 0))
821                         return true;
822         }
823
824         return false;
825 }
826
827 static int usage_with_options_internal(const char * const *usagestr,
828                                        const struct option *opts, int full,
829                                        struct parse_opt_ctx_t *ctx)
830 {
831         struct option *ordered;
832
833         if (!usagestr)
834                 return PARSE_OPT_HELP;
835
836         setup_pager();
837
838         if (error_buf) {
839                 fprintf(stderr, "  Error: %s\n", error_buf);
840                 zfree(&error_buf);
841         }
842
843         fprintf(stderr, "\n Usage: %s\n", *usagestr++);
844         while (*usagestr && **usagestr)
845                 fprintf(stderr, "    or: %s\n", *usagestr++);
846         while (*usagestr) {
847                 fprintf(stderr, "%s%s\n",
848                                 **usagestr ? "    " : "",
849                                 *usagestr);
850                 usagestr++;
851         }
852
853         if (opts->type != OPTION_GROUP)
854                 fputc('\n', stderr);
855
856         ordered = options__order(opts);
857         if (ordered)
858                 opts = ordered;
859
860         for (  ; opts->type != OPTION_END; opts++) {
861                 if (ctx && ctx->argc > 1 && !option__in_argv(opts, ctx))
862                         continue;
863                 print_option_help(opts, full);
864         }
865
866         fputc('\n', stderr);
867
868         free(ordered);
869
870         return PARSE_OPT_HELP;
871 }
872
873 void usage_with_options(const char * const *usagestr,
874                         const struct option *opts)
875 {
876         usage_with_options_internal(usagestr, opts, 0, NULL);
877         exit(129);
878 }
879
880 void usage_with_options_msg(const char * const *usagestr,
881                             const struct option *opts, const char *fmt, ...)
882 {
883         va_list ap;
884         char *tmp = error_buf;
885
886         va_start(ap, fmt);
887         if (vasprintf(&error_buf, fmt, ap) == -1)
888                 die("vasprintf failed");
889         va_end(ap);
890
891         free(tmp);
892
893         usage_with_options_internal(usagestr, opts, 0, NULL);
894         exit(129);
895 }
896
897 int parse_options_usage(const char * const *usagestr,
898                         const struct option *opts,
899                         const char *optstr, bool short_opt)
900 {
901         if (!usagestr)
902                 goto opt;
903
904         fprintf(stderr, "\n Usage: %s\n", *usagestr++);
905         while (*usagestr && **usagestr)
906                 fprintf(stderr, "    or: %s\n", *usagestr++);
907         while (*usagestr) {
908                 fprintf(stderr, "%s%s\n",
909                                 **usagestr ? "    " : "",
910                                 *usagestr);
911                 usagestr++;
912         }
913         fputc('\n', stderr);
914
915 opt:
916         for (  ; opts->type != OPTION_END; opts++) {
917                 if (short_opt) {
918                         if (opts->short_name == *optstr) {
919                                 print_option_help(opts, 0);
920                                 break;
921                         }
922                         continue;
923                 }
924
925                 if (opts->long_name == NULL)
926                         continue;
927
928                 if (!prefixcmp(opts->long_name, optstr))
929                         print_option_help(opts, 0);
930                 if (!prefixcmp("no-", optstr) &&
931                     !prefixcmp(opts->long_name, optstr + 3))
932                         print_option_help(opts, 0);
933         }
934
935         return PARSE_OPT_HELP;
936 }
937
938
939 int parse_opt_verbosity_cb(const struct option *opt,
940                            const char *arg __maybe_unused,
941                            int unset)
942 {
943         int *target = opt->value;
944
945         if (unset)
946                 /* --no-quiet, --no-verbose */
947                 *target = 0;
948         else if (opt->short_name == 'v') {
949                 if (*target >= 0)
950                         (*target)++;
951                 else
952                         *target = 1;
953         } else {
954                 if (*target <= 0)
955                         (*target)--;
956                 else
957                         *target = -1;
958         }
959         return 0;
960 }
961
962 static struct option *
963 find_option(struct option *opts, int shortopt, const char *longopt)
964 {
965         for (; opts->type != OPTION_END; opts++) {
966                 if ((shortopt && opts->short_name == shortopt) ||
967                     (opts->long_name && longopt &&
968                      !strcmp(opts->long_name, longopt)))
969                         return opts;
970         }
971         return NULL;
972 }
973
974 void set_option_flag(struct option *opts, int shortopt, const char *longopt,
975                      int flag)
976 {
977         struct option *opt = find_option(opts, shortopt, longopt);
978
979         if (opt)
980                 opt->flags |= flag;
981         return;
982 }
983
984 void set_option_nobuild(struct option *opts, int shortopt,
985                         const char *longopt,
986                         const char *build_opt,
987                         bool can_skip)
988 {
989         struct option *opt = find_option(opts, shortopt, longopt);
990
991         if (!opt)
992                 return;
993
994         opt->flags |= PARSE_OPT_NOBUILD;
995         opt->flags |= can_skip ? PARSE_OPT_CANSKIP : 0;
996         opt->build_opt = build_opt;
997 }