2 #include "parse-options.h"
9 static int opterror(const struct option
*opt
, const char *reason
, int flags
)
11 if (flags
& OPT_SHORT
)
12 return error("switch `%c' %s", opt
->short_name
, reason
);
13 if (flags
& OPT_UNSET
)
14 return error("option `no-%s' %s", opt
->long_name
, reason
);
15 return error("option `%s' %s", opt
->long_name
, reason
);
18 static int get_arg(struct parse_opt_ctx_t
*p
, const struct option
*opt
,
19 int flags
, const char **arg
)
24 } else if ((opt
->flags
& PARSE_OPT_LASTARG_DEFAULT
) && (p
->argc
== 1 ||
25 **(p
->argv
+ 1) == '-')) {
26 *arg
= (const char *)opt
->defval
;
27 } else if (p
->argc
> 1) {
31 return opterror(opt
, "requires a value", flags
);
35 static int get_value(struct parse_opt_ctx_t
*p
,
36 const struct option
*opt
, int flags
)
38 const char *s
, *arg
= NULL
;
39 const int unset
= flags
& OPT_UNSET
;
43 return opterror(opt
, "takes no value", flags
);
44 if (unset
&& (opt
->flags
& PARSE_OPT_NONEG
))
45 return opterror(opt
, "isn't available", flags
);
46 if (opt
->flags
& PARSE_OPT_DISABLED
)
47 return opterror(opt
, "is not usable", flags
);
49 if (opt
->flags
& PARSE_OPT_EXCLUSIVE
) {
50 if (p
->excl_opt
&& p
->excl_opt
!= opt
) {
53 if (((flags
& OPT_SHORT
) && p
->excl_opt
->short_name
) ||
54 p
->excl_opt
->long_name
== NULL
) {
55 scnprintf(msg
, sizeof(msg
), "cannot be used with switch `%c'",
56 p
->excl_opt
->short_name
);
58 scnprintf(msg
, sizeof(msg
), "cannot be used with %s",
59 p
->excl_opt
->long_name
);
61 opterror(opt
, msg
, flags
);
66 if (!(flags
& OPT_SHORT
) && p
->opt
) {
69 if (!(opt
->flags
& PARSE_OPT_NOARG
))
77 return opterror(opt
, "takes no value", flags
);
94 *(int *)opt
->value
&= ~opt
->defval
;
96 *(int *)opt
->value
|= opt
->defval
;
100 *(bool *)opt
->value
= unset
? false : true;
102 *(bool *)opt
->set
= true;
106 *(int *)opt
->value
= unset
? 0 : *(int *)opt
->value
+ 1;
109 case OPTION_SET_UINT
:
110 *(unsigned int *)opt
->value
= unset
? 0 : opt
->defval
;
114 *(void **)opt
->value
= unset
? NULL
: (void *)opt
->defval
;
120 *(const char **)opt
->value
= NULL
;
121 else if (opt
->flags
& PARSE_OPT_OPTARG
&& !p
->opt
)
122 *(const char **)opt
->value
= (const char *)opt
->defval
;
124 err
= get_arg(p
, opt
, flags
, (const char **)opt
->value
);
126 /* PARSE_OPT_NOEMPTY: Allow NULL but disallow empty string. */
127 if (opt
->flags
& PARSE_OPT_NOEMPTY
) {
128 const char *val
= *(const char **)opt
->value
;
133 /* Similar to unset if we are given an empty string. */
134 if (val
[0] == '\0') {
135 *(const char **)opt
->value
= NULL
;
142 case OPTION_CALLBACK
:
144 return (*opt
->callback
)(opt
, NULL
, 1) ? (-1) : 0;
145 if (opt
->flags
& PARSE_OPT_NOARG
)
146 return (*opt
->callback
)(opt
, NULL
, 0) ? (-1) : 0;
147 if (opt
->flags
& PARSE_OPT_OPTARG
&& !p
->opt
)
148 return (*opt
->callback
)(opt
, NULL
, 0) ? (-1) : 0;
149 if (get_arg(p
, opt
, flags
, &arg
))
151 return (*opt
->callback
)(opt
, arg
, 0) ? (-1) : 0;
155 *(int *)opt
->value
= 0;
158 if (opt
->flags
& PARSE_OPT_OPTARG
&& !p
->opt
) {
159 *(int *)opt
->value
= opt
->defval
;
162 if (get_arg(p
, opt
, flags
, &arg
))
164 *(int *)opt
->value
= strtol(arg
, (char **)&s
, 10);
166 return opterror(opt
, "expects a numerical value", flags
);
169 case OPTION_UINTEGER
:
171 *(unsigned int *)opt
->value
= 0;
174 if (opt
->flags
& PARSE_OPT_OPTARG
&& !p
->opt
) {
175 *(unsigned int *)opt
->value
= opt
->defval
;
178 if (get_arg(p
, opt
, flags
, &arg
))
180 *(unsigned int *)opt
->value
= strtol(arg
, (char **)&s
, 10);
182 return opterror(opt
, "expects a numerical value", flags
);
187 *(long *)opt
->value
= 0;
190 if (opt
->flags
& PARSE_OPT_OPTARG
&& !p
->opt
) {
191 *(long *)opt
->value
= opt
->defval
;
194 if (get_arg(p
, opt
, flags
, &arg
))
196 *(long *)opt
->value
= strtol(arg
, (char **)&s
, 10);
198 return opterror(opt
, "expects a numerical value", flags
);
203 *(u64
*)opt
->value
= 0;
206 if (opt
->flags
& PARSE_OPT_OPTARG
&& !p
->opt
) {
207 *(u64
*)opt
->value
= opt
->defval
;
210 if (get_arg(p
, opt
, flags
, &arg
))
212 *(u64
*)opt
->value
= strtoull(arg
, (char **)&s
, 10);
214 return opterror(opt
, "expects a numerical value", flags
);
218 case OPTION_ARGUMENT
:
221 die("should not happen, someone must be hit on the forehead");
225 static int parse_short_opt(struct parse_opt_ctx_t
*p
, const struct option
*options
)
227 for (; options
->type
!= OPTION_END
; options
++) {
228 if (options
->short_name
== *p
->opt
) {
229 p
->opt
= p
->opt
[1] ? p
->opt
+ 1 : NULL
;
230 return get_value(p
, options
, OPT_SHORT
);
236 static int parse_long_opt(struct parse_opt_ctx_t
*p
, const char *arg
,
237 const struct option
*options
)
239 const char *arg_end
= strchr(arg
, '=');
240 const struct option
*abbrev_option
= NULL
, *ambiguous_option
= NULL
;
241 int abbrev_flags
= 0, ambiguous_flags
= 0;
244 arg_end
= arg
+ strlen(arg
);
246 for (; options
->type
!= OPTION_END
; options
++) {
250 if (!options
->long_name
)
253 rest
= skip_prefix(arg
, options
->long_name
);
254 if (options
->type
== OPTION_ARGUMENT
) {
258 return opterror(options
, "takes no value", flags
);
261 p
->out
[p
->cpidx
++] = arg
- 2;
265 if (!prefixcmp(options
->long_name
, "no-")) {
267 * The long name itself starts with "no-", so
268 * accept the option without "no-" so that users
269 * do not have to enter "no-no-" to get the
272 rest
= skip_prefix(arg
, options
->long_name
+ 3);
277 /* Abbreviated case */
278 if (!prefixcmp(options
->long_name
+ 3, arg
)) {
284 if (!strncmp(options
->long_name
, arg
, arg_end
- arg
)) {
288 * If this is abbreviated, it is
289 * ambiguous. So when there is no
290 * exact match later, we need to
293 ambiguous_option
= abbrev_option
;
294 ambiguous_flags
= abbrev_flags
;
296 if (!(flags
& OPT_UNSET
) && *arg_end
)
297 p
->opt
= arg_end
+ 1;
298 abbrev_option
= options
;
299 abbrev_flags
= flags
;
302 /* negated and abbreviated very much? */
303 if (!prefixcmp("no-", arg
)) {
308 if (strncmp(arg
, "no-", 3))
311 rest
= skip_prefix(arg
+ 3, options
->long_name
);
312 /* abbreviated and negated? */
313 if (!rest
&& !prefixcmp(options
->long_name
, arg
+ 3))
324 return get_value(p
, options
, flags
);
327 if (ambiguous_option
)
328 return error("Ambiguous option: %s "
329 "(could be --%s%s or --%s%s)",
331 (ambiguous_flags
& OPT_UNSET
) ? "no-" : "",
332 ambiguous_option
->long_name
,
333 (abbrev_flags
& OPT_UNSET
) ? "no-" : "",
334 abbrev_option
->long_name
);
336 return get_value(p
, abbrev_option
, abbrev_flags
);
340 static void check_typos(const char *arg
, const struct option
*options
)
345 if (!prefixcmp(arg
, "no-")) {
346 error ("did you mean `--%s` (with two dashes ?)", arg
);
350 for (; options
->type
!= OPTION_END
; options
++) {
351 if (!options
->long_name
)
353 if (!prefixcmp(options
->long_name
, arg
)) {
354 error ("did you mean `--%s` (with two dashes ?)", arg
);
360 void parse_options_start(struct parse_opt_ctx_t
*ctx
,
361 int argc
, const char **argv
, int flags
)
363 memset(ctx
, 0, sizeof(*ctx
));
364 ctx
->argc
= argc
- 1;
365 ctx
->argv
= argv
+ 1;
367 ctx
->cpidx
= ((flags
& PARSE_OPT_KEEP_ARGV0
) != 0);
369 if ((flags
& PARSE_OPT_KEEP_UNKNOWN
) &&
370 (flags
& PARSE_OPT_STOP_AT_NON_OPTION
))
371 die("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
374 static int usage_with_options_internal(const char * const *,
375 const struct option
*, int);
377 int parse_options_step(struct parse_opt_ctx_t
*ctx
,
378 const struct option
*options
,
379 const char * const usagestr
[])
381 int internal_help
= !(ctx
->flags
& PARSE_OPT_NO_INTERNAL_HELP
);
382 int excl_short_opt
= 1;
385 /* we must reset ->opt, unknown short option leave it dangling */
388 for (; ctx
->argc
; ctx
->argc
--, ctx
->argv
++) {
390 if (*arg
!= '-' || !arg
[1]) {
391 if (ctx
->flags
& PARSE_OPT_STOP_AT_NON_OPTION
)
393 ctx
->out
[ctx
->cpidx
++] = ctx
->argv
[0];
399 if (internal_help
&& *ctx
->opt
== 'h')
400 return usage_with_options_internal(usagestr
, options
, 0);
401 switch (parse_short_opt(ctx
, options
)) {
403 return parse_options_usage(usagestr
, options
, arg
, 1);
412 check_typos(arg
, options
);
414 if (internal_help
&& *ctx
->opt
== 'h')
415 return usage_with_options_internal(usagestr
, options
, 0);
417 switch (parse_short_opt(ctx
, options
)) {
419 return parse_options_usage(usagestr
, options
, arg
, 1);
421 /* fake a short option thing to hide the fact that we may have
422 * started to parse aggregated stuff
424 * This is leaky, too bad.
426 ctx
->argv
[0] = strdup(ctx
->opt
- 1);
427 *(char *)ctx
->argv
[0] = '-';
438 if (!arg
[2]) { /* "--" */
439 if (!(ctx
->flags
& PARSE_OPT_KEEP_DASHDASH
)) {
447 if (internal_help
&& !strcmp(arg
, "help-all"))
448 return usage_with_options_internal(usagestr
, options
, 1);
449 if (internal_help
&& !strcmp(arg
, "help"))
450 return usage_with_options_internal(usagestr
, options
, 0);
451 if (!strcmp(arg
, "list-opts"))
452 return PARSE_OPT_LIST_OPTS
;
453 if (!strcmp(arg
, "list-cmds"))
454 return PARSE_OPT_LIST_SUBCMDS
;
455 switch (parse_long_opt(ctx
, arg
, options
)) {
457 return parse_options_usage(usagestr
, options
, arg
, 0);
468 if (!(ctx
->flags
& PARSE_OPT_KEEP_UNKNOWN
))
469 return PARSE_OPT_UNKNOWN
;
470 ctx
->out
[ctx
->cpidx
++] = ctx
->argv
[0];
473 return PARSE_OPT_DONE
;
476 parse_options_usage(usagestr
, options
, arg
, excl_short_opt
);
477 if ((excl_short_opt
&& ctx
->excl_opt
->short_name
) ||
478 ctx
->excl_opt
->long_name
== NULL
) {
479 char opt
= ctx
->excl_opt
->short_name
;
480 parse_options_usage(NULL
, options
, &opt
, 1);
482 parse_options_usage(NULL
, options
, ctx
->excl_opt
->long_name
, 0);
484 return PARSE_OPT_HELP
;
487 int parse_options_end(struct parse_opt_ctx_t
*ctx
)
489 memmove(ctx
->out
+ ctx
->cpidx
, ctx
->argv
, ctx
->argc
* sizeof(*ctx
->out
));
490 ctx
->out
[ctx
->cpidx
+ ctx
->argc
] = NULL
;
491 return ctx
->cpidx
+ ctx
->argc
;
494 int parse_options_subcommand(int argc
, const char **argv
, const struct option
*options
,
495 const char *const subcommands
[], const char *usagestr
[], int flags
)
497 struct parse_opt_ctx_t ctx
;
499 perf_header__set_cmdline(argc
, argv
);
501 /* build usage string if it's not provided */
502 if (subcommands
&& !usagestr
[0]) {
503 struct strbuf buf
= STRBUF_INIT
;
505 strbuf_addf(&buf
, "perf %s [<options>] {", argv
[0]);
506 for (int i
= 0; subcommands
[i
]; i
++) {
508 strbuf_addstr(&buf
, "|");
509 strbuf_addstr(&buf
, subcommands
[i
]);
511 strbuf_addstr(&buf
, "}");
513 usagestr
[0] = strdup(buf
.buf
);
514 strbuf_release(&buf
);
517 parse_options_start(&ctx
, argc
, argv
, flags
);
518 switch (parse_options_step(&ctx
, options
, usagestr
)) {
523 case PARSE_OPT_LIST_OPTS
:
524 while (options
->type
!= OPTION_END
) {
525 if (options
->long_name
)
526 printf("--%s ", options
->long_name
);
531 case PARSE_OPT_LIST_SUBCMDS
:
533 for (int i
= 0; subcommands
[i
]; i
++)
534 printf("%s ", subcommands
[i
]);
538 default: /* PARSE_OPT_UNKNOWN */
539 if (ctx
.argv
[0][1] == '-') {
540 error("unknown option `%s'", ctx
.argv
[0] + 2);
542 error("unknown switch `%c'", *ctx
.opt
);
544 usage_with_options(usagestr
, options
);
547 return parse_options_end(&ctx
);
550 int parse_options(int argc
, const char **argv
, const struct option
*options
,
551 const char * const usagestr
[], int flags
)
553 return parse_options_subcommand(argc
, argv
, options
, NULL
,
554 (const char **) usagestr
, flags
);
557 #define USAGE_OPTS_WIDTH 24
560 static void print_option_help(const struct option
*opts
, int full
)
565 if (opts
->type
== OPTION_GROUP
) {
568 fprintf(stderr
, "%s\n", opts
->help
);
571 if (!full
&& (opts
->flags
& PARSE_OPT_HIDDEN
))
573 if (opts
->flags
& PARSE_OPT_DISABLED
)
576 pos
= fprintf(stderr
, " ");
577 if (opts
->short_name
)
578 pos
+= fprintf(stderr
, "-%c", opts
->short_name
);
580 pos
+= fprintf(stderr
, " ");
582 if (opts
->long_name
&& opts
->short_name
)
583 pos
+= fprintf(stderr
, ", ");
585 pos
+= fprintf(stderr
, "--%s", opts
->long_name
);
587 switch (opts
->type
) {
588 case OPTION_ARGUMENT
:
593 case OPTION_UINTEGER
:
594 if (opts
->flags
& PARSE_OPT_OPTARG
)
596 pos
+= fprintf(stderr
, "[=<n>]");
598 pos
+= fprintf(stderr
, "[<n>]");
600 pos
+= fprintf(stderr
, " <n>");
602 case OPTION_CALLBACK
:
603 if (opts
->flags
& PARSE_OPT_NOARG
)
608 if (opts
->flags
& PARSE_OPT_OPTARG
)
610 pos
+= fprintf(stderr
, "[=<%s>]", opts
->argh
);
612 pos
+= fprintf(stderr
, "[<%s>]", opts
->argh
);
614 pos
+= fprintf(stderr
, " <%s>", opts
->argh
);
616 if (opts
->flags
& PARSE_OPT_OPTARG
)
618 pos
+= fprintf(stderr
, "[=...]");
620 pos
+= fprintf(stderr
, "[...]");
622 pos
+= fprintf(stderr
, " ...");
625 default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
631 case OPTION_SET_UINT
:
636 if (pos
<= USAGE_OPTS_WIDTH
)
637 pad
= USAGE_OPTS_WIDTH
- pos
;
640 pad
= USAGE_OPTS_WIDTH
;
642 fprintf(stderr
, "%*s%s\n", pad
+ USAGE_GAP
, "", opts
->help
);
645 int usage_with_options_internal(const char * const *usagestr
,
646 const struct option
*opts
, int full
)
649 return PARSE_OPT_HELP
;
651 fprintf(stderr
, "\n usage: %s\n", *usagestr
++);
652 while (*usagestr
&& **usagestr
)
653 fprintf(stderr
, " or: %s\n", *usagestr
++);
655 fprintf(stderr
, "%s%s\n",
656 **usagestr
? " " : "",
661 if (opts
->type
!= OPTION_GROUP
)
664 for ( ; opts
->type
!= OPTION_END
; opts
++)
665 print_option_help(opts
, full
);
669 return PARSE_OPT_HELP
;
672 void usage_with_options(const char * const *usagestr
,
673 const struct option
*opts
)
676 usage_with_options_internal(usagestr
, opts
, 0);
680 int parse_options_usage(const char * const *usagestr
,
681 const struct option
*opts
,
682 const char *optstr
, bool short_opt
)
687 fprintf(stderr
, "\n usage: %s\n", *usagestr
++);
688 while (*usagestr
&& **usagestr
)
689 fprintf(stderr
, " or: %s\n", *usagestr
++);
691 fprintf(stderr
, "%s%s\n",
692 **usagestr
? " " : "",
699 for ( ; opts
->type
!= OPTION_END
; opts
++) {
701 if (opts
->short_name
== *optstr
)
706 if (opts
->long_name
== NULL
)
709 if (!prefixcmp(optstr
, opts
->long_name
))
711 if (!prefixcmp(optstr
, "no-") &&
712 !prefixcmp(optstr
+ 3, opts
->long_name
))
716 if (opts
->type
!= OPTION_END
)
717 print_option_help(opts
, 0);
719 return PARSE_OPT_HELP
;
723 int parse_opt_verbosity_cb(const struct option
*opt
,
724 const char *arg __maybe_unused
,
727 int *target
= opt
->value
;
730 /* --no-quiet, --no-verbose */
732 else if (opt
->short_name
== 'v') {
746 void set_option_flag(struct option
*opts
, int shortopt
, const char *longopt
,
749 for (; opts
->type
!= OPTION_END
; opts
++) {
750 if ((shortopt
&& opts
->short_name
== shortopt
) ||
751 (opts
->long_name
&& longopt
&&
752 !strcmp(opts
->long_name
, longopt
))) {