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