1 #include <linux/compiler.h>
2 #include <linux/string.h>
3 #include <linux/types.h>
9 #include "subcmd-util.h"
10 #include "parse-options.h"
11 #include "subcmd-config.h"
19 static int opterror(const struct option *opt, const char *reason, int flags)
21 if (flags & OPT_SHORT)
22 fprintf(stderr, " Error: switch `%c' %s", opt->short_name, reason);
23 else if (flags & OPT_UNSET)
24 fprintf(stderr, " Error: option `no-%s' %s", opt->long_name, reason);
26 fprintf(stderr, " Error: option `%s' %s", opt->long_name, reason);
31 static const char *skip_prefix(const char *str, const char *prefix)
33 size_t len = strlen(prefix);
34 return strncmp(str, prefix, len) ? NULL : str + len;
37 static void optwarning(const struct option *opt, const char *reason, int flags)
39 if (flags & OPT_SHORT)
40 fprintf(stderr, " Warning: switch `%c' %s", opt->short_name, reason);
41 else if (flags & OPT_UNSET)
42 fprintf(stderr, " Warning: option `no-%s' %s", opt->long_name, reason);
44 fprintf(stderr, " Warning: option `%s' %s", opt->long_name, reason);
47 static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt,
48 int flags, const char **arg)
55 } else if ((opt->flags & PARSE_OPT_LASTARG_DEFAULT) && (p->argc == 1 ||
56 **(p->argv + 1) == '-')) {
57 res = (const char *)opt->defval;
58 } else if (p->argc > 1) {
62 return opterror(opt, "requires a value", flags);
68 static int get_value(struct parse_opt_ctx_t *p,
69 const struct option *opt, int flags)
71 const char *s, *arg = NULL;
72 const int unset = flags & OPT_UNSET;
76 return opterror(opt, "takes no value", flags);
77 if (unset && (opt->flags & PARSE_OPT_NONEG))
78 return opterror(opt, "isn't available", flags);
79 if (opt->flags & PARSE_OPT_DISABLED)
80 return opterror(opt, "is not usable", flags);
82 if (opt->flags & PARSE_OPT_EXCLUSIVE) {
83 if (p->excl_opt && p->excl_opt != opt) {
86 if (((flags & OPT_SHORT) && p->excl_opt->short_name) ||
87 p->excl_opt->long_name == NULL) {
88 snprintf(msg, sizeof(msg), "cannot be used with switch `%c'",
89 p->excl_opt->short_name);
91 snprintf(msg, sizeof(msg), "cannot be used with %s",
92 p->excl_opt->long_name);
94 opterror(opt, msg, flags);
99 if (!(flags & OPT_SHORT) && p->opt) {
101 case OPTION_CALLBACK:
102 if (!(opt->flags & PARSE_OPT_NOARG))
108 case OPTION_SET_UINT:
110 return opterror(opt, "takes no value", flags);
112 case OPTION_ARGUMENT:
116 case OPTION_UINTEGER:
124 if (opt->flags & PARSE_OPT_NOBUILD) {
128 err = snprintf(reason, sizeof(reason),
129 opt->flags & PARSE_OPT_CANSKIP ?
130 "is being ignored because %s " :
131 "is not available because %s",
133 reason[sizeof(reason) - 1] = '\0';
136 strncpy(reason, opt->flags & PARSE_OPT_CANSKIP ?
141 if (!(opt->flags & PARSE_OPT_CANSKIP))
142 return opterror(opt, reason, flags);
147 if (opt->flags & PARSE_OPT_NOARG)
149 if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
156 case OPTION_SET_UINT:
159 case OPTION_ARGUMENT:
163 case OPTION_CALLBACK:
166 case OPTION_UINTEGER:
174 err = get_arg(p, opt, flags, NULL);
178 optwarning(opt, reason, flags);
185 *(int *)opt->value &= ~opt->defval;
187 *(int *)opt->value |= opt->defval;
191 *(bool *)opt->value = unset ? false : true;
193 *(bool *)opt->set = true;
197 *(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
200 case OPTION_SET_UINT:
201 *(unsigned int *)opt->value = unset ? 0 : opt->defval;
205 *(void **)opt->value = unset ? NULL : (void *)opt->defval;
211 *(const char **)opt->value = NULL;
212 else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
213 *(const char **)opt->value = (const char *)opt->defval;
215 err = get_arg(p, opt, flags, (const char **)opt->value);
218 *(bool *)opt->set = true;
220 /* PARSE_OPT_NOEMPTY: Allow NULL but disallow empty string. */
221 if (opt->flags & PARSE_OPT_NOEMPTY) {
222 const char *val = *(const char **)opt->value;
227 /* Similar to unset if we are given an empty string. */
228 if (val[0] == '\0') {
229 *(const char **)opt->value = NULL;
236 case OPTION_CALLBACK:
238 return (*opt->callback)(opt, NULL, 1) ? (-1) : 0;
239 if (opt->flags & PARSE_OPT_NOARG)
240 return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
241 if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
242 return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
243 if (get_arg(p, opt, flags, &arg))
245 return (*opt->callback)(opt, arg, 0) ? (-1) : 0;
249 *(int *)opt->value = 0;
252 if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
253 *(int *)opt->value = opt->defval;
256 if (get_arg(p, opt, flags, &arg))
258 *(int *)opt->value = strtol(arg, (char **)&s, 10);
260 return opterror(opt, "expects a numerical value", flags);
263 case OPTION_UINTEGER:
265 *(unsigned int *)opt->value = 0;
268 if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
269 *(unsigned int *)opt->value = opt->defval;
272 if (get_arg(p, opt, flags, &arg))
275 return opterror(opt, "expects an unsigned numerical value", flags);
276 *(unsigned int *)opt->value = strtol(arg, (char **)&s, 10);
278 return opterror(opt, "expects a numerical value", flags);
283 *(long *)opt->value = 0;
286 if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
287 *(long *)opt->value = opt->defval;
290 if (get_arg(p, opt, flags, &arg))
292 *(long *)opt->value = strtol(arg, (char **)&s, 10);
294 return opterror(opt, "expects a numerical value", flags);
299 *(u64 *)opt->value = 0;
302 if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
303 *(u64 *)opt->value = opt->defval;
306 if (get_arg(p, opt, flags, &arg))
309 return opterror(opt, "expects an unsigned numerical value", flags);
310 *(u64 *)opt->value = strtoull(arg, (char **)&s, 10);
312 return opterror(opt, "expects a numerical value", flags);
316 case OPTION_ARGUMENT:
319 die("should not happen, someone must be hit on the forehead");
323 static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *options)
326 for (; options->type != OPTION_END; options++) {
327 if (options->short_name == *p->opt) {
328 p->opt = p->opt[1] ? p->opt + 1 : NULL;
329 return get_value(p, options, OPT_SHORT);
333 if (options->parent) {
334 options = options->parent;
341 static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
342 const struct option *options)
344 const char *arg_end = strchr(arg, '=');
345 const struct option *abbrev_option = NULL, *ambiguous_option = NULL;
346 int abbrev_flags = 0, ambiguous_flags = 0;
349 arg_end = arg + strlen(arg);
352 for (; options->type != OPTION_END; options++) {
356 if (!options->long_name)
359 rest = skip_prefix(arg, options->long_name);
360 if (options->type == OPTION_ARGUMENT) {
364 return opterror(options, "takes no value", flags);
367 p->out[p->cpidx++] = arg - 2;
371 if (strstarts(options->long_name, "no-")) {
373 * The long name itself starts with "no-", so
374 * accept the option without "no-" so that users
375 * do not have to enter "no-no-" to get the
378 rest = skip_prefix(arg, options->long_name + 3);
383 /* Abbreviated case */
384 if (strstarts(options->long_name + 3, arg)) {
390 if (!strncmp(options->long_name, arg, arg_end - arg)) {
394 * If this is abbreviated, it is
395 * ambiguous. So when there is no
396 * exact match later, we need to
399 ambiguous_option = abbrev_option;
400 ambiguous_flags = abbrev_flags;
402 if (!(flags & OPT_UNSET) && *arg_end)
403 p->opt = arg_end + 1;
404 abbrev_option = options;
405 abbrev_flags = flags;
408 /* negated and abbreviated very much? */
409 if (strstarts("no-", arg)) {
414 if (strncmp(arg, "no-", 3))
417 rest = skip_prefix(arg + 3, options->long_name);
418 /* abbreviated and negated? */
419 if (!rest && strstarts(options->long_name, arg + 3))
430 return get_value(p, options, flags);
433 if (ambiguous_option) {
435 " Error: Ambiguous option: %s (could be --%s%s or --%s%s)",
437 (ambiguous_flags & OPT_UNSET) ? "no-" : "",
438 ambiguous_option->long_name,
439 (abbrev_flags & OPT_UNSET) ? "no-" : "",
440 abbrev_option->long_name);
444 return get_value(p, abbrev_option, abbrev_flags);
446 if (options->parent) {
447 options = options->parent;
454 static void check_typos(const char *arg, const struct option *options)
459 if (strstarts(arg, "no-")) {
460 fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg);
464 for (; options->type != OPTION_END; options++) {
465 if (!options->long_name)
467 if (strstarts(options->long_name, arg)) {
468 fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg);
474 static void parse_options_start(struct parse_opt_ctx_t *ctx,
475 int argc, const char **argv, int flags)
477 memset(ctx, 0, sizeof(*ctx));
478 ctx->argc = argc - 1;
479 ctx->argv = argv + 1;
481 ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
483 if ((flags & PARSE_OPT_KEEP_UNKNOWN) &&
484 (flags & PARSE_OPT_STOP_AT_NON_OPTION))
485 die("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
488 static int usage_with_options_internal(const char * const *,
489 const struct option *, int,
490 struct parse_opt_ctx_t *);
492 static int parse_options_step(struct parse_opt_ctx_t *ctx,
493 const struct option *options,
494 const char * const usagestr[])
496 int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
497 int excl_short_opt = 1;
500 /* we must reset ->opt, unknown short option leave it dangling */
503 for (; ctx->argc; ctx->argc--, ctx->argv++) {
505 if (*arg != '-' || !arg[1]) {
506 if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
508 ctx->out[ctx->cpidx++] = ctx->argv[0];
514 if (internal_help && *ctx->opt == 'h') {
515 return usage_with_options_internal(usagestr, options, 0, ctx);
517 switch (parse_short_opt(ctx, options)) {
519 return parse_options_usage(usagestr, options, arg, 1);
528 check_typos(arg, options);
530 if (internal_help && *ctx->opt == 'h')
531 return usage_with_options_internal(usagestr, options, 0, ctx);
533 switch (parse_short_opt(ctx, options)) {
535 return parse_options_usage(usagestr, options, arg, 1);
537 /* fake a short option thing to hide the fact that we may have
538 * started to parse aggregated stuff
540 * This is leaky, too bad.
542 ctx->argv[0] = strdup(ctx->opt - 1);
543 *(char *)ctx->argv[0] = '-';
554 if (!arg[2]) { /* "--" */
555 if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
563 if (internal_help && !strcmp(arg, "help-all"))
564 return usage_with_options_internal(usagestr, options, 1, ctx);
565 if (internal_help && !strcmp(arg, "help"))
566 return usage_with_options_internal(usagestr, options, 0, ctx);
567 if (!strcmp(arg, "list-opts"))
568 return PARSE_OPT_LIST_OPTS;
569 if (!strcmp(arg, "list-cmds"))
570 return PARSE_OPT_LIST_SUBCMDS;
571 switch (parse_long_opt(ctx, arg, options)) {
573 return parse_options_usage(usagestr, options, arg, 0);
584 if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN))
585 return PARSE_OPT_UNKNOWN;
586 ctx->out[ctx->cpidx++] = ctx->argv[0];
589 return PARSE_OPT_DONE;
592 parse_options_usage(usagestr, options, arg, excl_short_opt);
593 if ((excl_short_opt && ctx->excl_opt->short_name) ||
594 ctx->excl_opt->long_name == NULL) {
595 char opt = ctx->excl_opt->short_name;
596 parse_options_usage(NULL, options, &opt, 1);
598 parse_options_usage(NULL, options, ctx->excl_opt->long_name, 0);
600 return PARSE_OPT_HELP;
603 static int parse_options_end(struct parse_opt_ctx_t *ctx)
605 memmove(ctx->out + ctx->cpidx, ctx->argv, ctx->argc * sizeof(*ctx->out));
606 ctx->out[ctx->cpidx + ctx->argc] = NULL;
607 return ctx->cpidx + ctx->argc;
610 int parse_options_subcommand(int argc, const char **argv, const struct option *options,
611 const char *const subcommands[], const char *usagestr[], int flags)
613 struct parse_opt_ctx_t ctx;
615 /* build usage string if it's not provided */
616 if (subcommands && !usagestr[0]) {
619 astrcatf(&buf, "%s %s [<options>] {", subcmd_config.exec_name, argv[0]);
621 for (int i = 0; subcommands[i]; i++) {
624 astrcat(&buf, subcommands[i]);
631 parse_options_start(&ctx, argc, argv, flags);
632 switch (parse_options_step(&ctx, options, usagestr)) {
637 case PARSE_OPT_LIST_OPTS:
638 while (options->type != OPTION_END) {
639 if (options->long_name)
640 printf("--%s ", options->long_name);
645 case PARSE_OPT_LIST_SUBCMDS:
647 for (int i = 0; subcommands[i]; i++)
648 printf("%s ", subcommands[i]);
652 default: /* PARSE_OPT_UNKNOWN */
653 if (ctx.argv[0][1] == '-')
654 astrcatf(&error_buf, "unknown option `%s'",
657 astrcatf(&error_buf, "unknown switch `%c'", *ctx.opt);
658 usage_with_options(usagestr, options);
661 return parse_options_end(&ctx);
664 int parse_options(int argc, const char **argv, const struct option *options,
665 const char * const usagestr[], int flags)
667 return parse_options_subcommand(argc, argv, options, NULL,
668 (const char **) usagestr, flags);
671 #define USAGE_OPTS_WIDTH 24
674 static void print_option_help(const struct option *opts, int full)
679 if (opts->type == OPTION_GROUP) {
682 fprintf(stderr, "%s\n", opts->help);
685 if (!full && (opts->flags & PARSE_OPT_HIDDEN))
687 if (opts->flags & PARSE_OPT_DISABLED)
690 pos = fprintf(stderr, " ");
691 if (opts->short_name)
692 pos += fprintf(stderr, "-%c", opts->short_name);
694 pos += fprintf(stderr, " ");
696 if (opts->long_name && opts->short_name)
697 pos += fprintf(stderr, ", ");
699 pos += fprintf(stderr, "--%s", opts->long_name);
701 switch (opts->type) {
702 case OPTION_ARGUMENT:
707 case OPTION_UINTEGER:
708 if (opts->flags & PARSE_OPT_OPTARG)
710 pos += fprintf(stderr, "[=<n>]");
712 pos += fprintf(stderr, "[<n>]");
714 pos += fprintf(stderr, " <n>");
716 case OPTION_CALLBACK:
717 if (opts->flags & PARSE_OPT_NOARG)
722 if (opts->flags & PARSE_OPT_OPTARG)
724 pos += fprintf(stderr, "[=<%s>]", opts->argh);
726 pos += fprintf(stderr, "[<%s>]", opts->argh);
728 pos += fprintf(stderr, " <%s>", opts->argh);
730 if (opts->flags & PARSE_OPT_OPTARG)
732 pos += fprintf(stderr, "[=...]");
734 pos += fprintf(stderr, "[...]");
736 pos += fprintf(stderr, " ...");
739 default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
745 case OPTION_SET_UINT:
750 if (pos <= USAGE_OPTS_WIDTH)
751 pad = USAGE_OPTS_WIDTH - pos;
754 pad = USAGE_OPTS_WIDTH;
756 fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
757 if (opts->flags & PARSE_OPT_NOBUILD)
758 fprintf(stderr, "%*s(not built-in because %s)\n",
759 USAGE_OPTS_WIDTH + USAGE_GAP, "",
763 static int option__cmp(const void *va, const void *vb)
765 const struct option *a = va, *b = vb;
766 int sa = tolower(a->short_name), sb = tolower(b->short_name), ret;
776 const char *la = a->long_name ?: "",
777 *lb = b->long_name ?: "";
778 ret = strcmp(la, lb);
784 static struct option *options__order(const struct option *opts)
786 int nr_opts = 0, len;
787 const struct option *o = opts;
788 struct option *ordered;
790 for (o = opts; o->type != OPTION_END; o++)
793 len = sizeof(*o) * (nr_opts + 1);
794 ordered = malloc(len);
797 memcpy(ordered, opts, len);
799 qsort(ordered, nr_opts, sizeof(*o), option__cmp);
804 static bool option__in_argv(const struct option *opt, const struct parse_opt_ctx_t *ctx)
808 for (i = 1; i < ctx->argc; ++i) {
809 const char *arg = ctx->argv[i];
812 if (arg[1] == '\0') {
813 if (arg[0] == opt->short_name)
818 if (opt->long_name && strcmp(opt->long_name, arg) == 0)
821 if (opt->help && strcasestr(opt->help, arg) != NULL)
827 if (arg[1] == opt->short_name ||
828 (arg[1] == '-' && opt->long_name && strcmp(opt->long_name, arg + 2) == 0))
835 static int usage_with_options_internal(const char * const *usagestr,
836 const struct option *opts, int full,
837 struct parse_opt_ctx_t *ctx)
839 struct option *ordered;
842 return PARSE_OPT_HELP;
847 fprintf(stderr, " Error: %s\n", error_buf);
851 fprintf(stderr, "\n Usage: %s\n", *usagestr++);
852 while (*usagestr && **usagestr)
853 fprintf(stderr, " or: %s\n", *usagestr++);
855 fprintf(stderr, "%s%s\n",
856 **usagestr ? " " : "",
861 if (opts->type != OPTION_GROUP)
864 ordered = options__order(opts);
868 for ( ; opts->type != OPTION_END; opts++) {
869 if (ctx && ctx->argc > 1 && !option__in_argv(opts, ctx))
871 print_option_help(opts, full);
878 return PARSE_OPT_HELP;
881 void usage_with_options(const char * const *usagestr,
882 const struct option *opts)
884 usage_with_options_internal(usagestr, opts, 0, NULL);
888 void usage_with_options_msg(const char * const *usagestr,
889 const struct option *opts, const char *fmt, ...)
892 char *tmp = error_buf;
895 if (vasprintf(&error_buf, fmt, ap) == -1)
896 die("vasprintf failed");
901 usage_with_options_internal(usagestr, opts, 0, NULL);
905 int parse_options_usage(const char * const *usagestr,
906 const struct option *opts,
907 const char *optstr, bool short_opt)
912 fprintf(stderr, "\n Usage: %s\n", *usagestr++);
913 while (*usagestr && **usagestr)
914 fprintf(stderr, " or: %s\n", *usagestr++);
916 fprintf(stderr, "%s%s\n",
917 **usagestr ? " " : "",
924 for ( ; opts->type != OPTION_END; opts++) {
926 if (opts->short_name == *optstr) {
927 print_option_help(opts, 0);
933 if (opts->long_name == NULL)
936 if (strstarts(opts->long_name, optstr))
937 print_option_help(opts, 0);
938 if (strstarts("no-", optstr) &&
939 strstarts(opts->long_name, optstr + 3))
940 print_option_help(opts, 0);
943 return PARSE_OPT_HELP;
947 int parse_opt_verbosity_cb(const struct option *opt,
948 const char *arg __maybe_unused,
951 int *target = opt->value;
954 /* --no-quiet, --no-verbose */
956 else if (opt->short_name == 'v') {
970 static struct option *
971 find_option(struct option *opts, int shortopt, const char *longopt)
973 for (; opts->type != OPTION_END; opts++) {
974 if ((shortopt && opts->short_name == shortopt) ||
975 (opts->long_name && longopt &&
976 !strcmp(opts->long_name, longopt)))
982 void set_option_flag(struct option *opts, int shortopt, const char *longopt,
985 struct option *opt = find_option(opts, shortopt, longopt);
992 void set_option_nobuild(struct option *opts, int shortopt,
994 const char *build_opt,
997 struct option *opt = find_option(opts, shortopt, longopt);
1002 opt->flags |= PARSE_OPT_NOBUILD;
1003 opt->flags |= can_skip ? PARSE_OPT_CANSKIP : 0;
1004 opt->build_opt = build_opt;