perf tools: Document parameterized and symbolic events
[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"
07800601
IM
5
6#define OPT_SHORT 1
7#define OPT_UNSET 2
8
9static int opterror(const struct option *opt, const char *reason, int flags)
10{
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);
16}
17
18static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt,
19 int flags, const char **arg)
20{
21 if (p->opt) {
22 *arg = p->opt;
23 p->opt = NULL;
5a4b1817
FW
24 } else if ((opt->flags & PARSE_OPT_LASTARG_DEFAULT) && (p->argc == 1 ||
25 **(p->argv + 1) == '-')) {
07800601
IM
26 *arg = (const char *)opt->defval;
27 } else if (p->argc > 1) {
28 p->argc--;
29 *arg = *++p->argv;
30 } else
31 return opterror(opt, "requires a value", flags);
32 return 0;
33}
34
35static int get_value(struct parse_opt_ctx_t *p,
36 const struct option *opt, int flags)
37{
233f0b95 38 const char *s, *arg = NULL;
07800601
IM
39 const int unset = flags & OPT_UNSET;
40
41 if (unset && p->opt)
42 return opterror(opt, "takes no value", flags);
43 if (unset && (opt->flags & PARSE_OPT_NONEG))
44 return opterror(opt, "isn't available", flags);
d152d1be
NK
45 if (opt->flags & PARSE_OPT_DISABLED)
46 return opterror(opt, "is not usable", flags);
07800601 47
42bd71d0
NK
48 if (opt->flags & PARSE_OPT_EXCLUSIVE) {
49 if (p->excl_opt) {
50 char msg[128];
51
52 if (((flags & OPT_SHORT) && p->excl_opt->short_name) ||
53 p->excl_opt->long_name == NULL) {
54 scnprintf(msg, sizeof(msg), "cannot be used with switch `%c'",
55 p->excl_opt->short_name);
56 } else {
57 scnprintf(msg, sizeof(msg), "cannot be used with %s",
58 p->excl_opt->long_name);
59 }
60 opterror(opt, msg, flags);
61 return -3;
62 }
63 p->excl_opt = opt;
64 }
07800601
IM
65 if (!(flags & OPT_SHORT) && p->opt) {
66 switch (opt->type) {
67 case OPTION_CALLBACK:
68 if (!(opt->flags & PARSE_OPT_NOARG))
69 break;
70 /* FALLTHROUGH */
71 case OPTION_BOOLEAN:
c0555642 72 case OPTION_INCR:
07800601 73 case OPTION_BIT:
edb7c60e 74 case OPTION_SET_UINT:
07800601
IM
75 case OPTION_SET_PTR:
76 return opterror(opt, "takes no value", flags);
83a0944f
IM
77 case OPTION_END:
78 case OPTION_ARGUMENT:
79 case OPTION_GROUP:
80 case OPTION_STRING:
81 case OPTION_INTEGER:
c100edbe 82 case OPTION_UINTEGER:
83a0944f 83 case OPTION_LONG:
6ba85cea 84 case OPTION_U64:
07800601
IM
85 default:
86 break;
87 }
88 }
89
90 switch (opt->type) {
91 case OPTION_BIT:
92 if (unset)
93 *(int *)opt->value &= ~opt->defval;
94 else
95 *(int *)opt->value |= opt->defval;
96 return 0;
97
98 case OPTION_BOOLEAN:
c0555642 99 *(bool *)opt->value = unset ? false : true;
167faf32
AH
100 if (opt->set)
101 *(bool *)opt->set = true;
c0555642
IM
102 return 0;
103
104 case OPTION_INCR:
07800601
IM
105 *(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
106 return 0;
107
edb7c60e
ACM
108 case OPTION_SET_UINT:
109 *(unsigned int *)opt->value = unset ? 0 : opt->defval;
07800601
IM
110 return 0;
111
112 case OPTION_SET_PTR:
113 *(void **)opt->value = unset ? NULL : (void *)opt->defval;
114 return 0;
115
116 case OPTION_STRING:
117 if (unset)
118 *(const char **)opt->value = NULL;
119 else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
120 *(const char **)opt->value = (const char *)opt->defval;
121 else
122 return get_arg(p, opt, flags, (const char **)opt->value);
123 return 0;
124
125 case OPTION_CALLBACK:
126 if (unset)
127 return (*opt->callback)(opt, NULL, 1) ? (-1) : 0;
128 if (opt->flags & PARSE_OPT_NOARG)
129 return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
130 if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
131 return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
132 if (get_arg(p, opt, flags, &arg))
133 return -1;
134 return (*opt->callback)(opt, arg, 0) ? (-1) : 0;
135
136 case OPTION_INTEGER:
137 if (unset) {
138 *(int *)opt->value = 0;
139 return 0;
140 }
141 if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
142 *(int *)opt->value = opt->defval;
143 return 0;
144 }
145 if (get_arg(p, opt, flags, &arg))
146 return -1;
147 *(int *)opt->value = strtol(arg, (char **)&s, 10);
148 if (*s)
149 return opterror(opt, "expects a numerical value", flags);
e61078a0
PZ
150 return 0;
151
c100edbe
ACM
152 case OPTION_UINTEGER:
153 if (unset) {
154 *(unsigned int *)opt->value = 0;
155 return 0;
156 }
157 if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
158 *(unsigned int *)opt->value = opt->defval;
159 return 0;
160 }
161 if (get_arg(p, opt, flags, &arg))
162 return -1;
163 *(unsigned int *)opt->value = strtol(arg, (char **)&s, 10);
164 if (*s)
165 return opterror(opt, "expects a numerical value", flags);
166 return 0;
167
e61078a0
PZ
168 case OPTION_LONG:
169 if (unset) {
170 *(long *)opt->value = 0;
171 return 0;
172 }
173 if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
174 *(long *)opt->value = opt->defval;
175 return 0;
176 }
177 if (get_arg(p, opt, flags, &arg))
178 return -1;
179 *(long *)opt->value = strtol(arg, (char **)&s, 10);
180 if (*s)
181 return opterror(opt, "expects a numerical value", flags);
07800601
IM
182 return 0;
183
6ba85cea
ACM
184 case OPTION_U64:
185 if (unset) {
186 *(u64 *)opt->value = 0;
187 return 0;
188 }
189 if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
190 *(u64 *)opt->value = opt->defval;
191 return 0;
192 }
193 if (get_arg(p, opt, flags, &arg))
194 return -1;
195 *(u64 *)opt->value = strtoull(arg, (char **)&s, 10);
196 if (*s)
197 return opterror(opt, "expects a numerical value", flags);
198 return 0;
199
83a0944f
IM
200 case OPTION_END:
201 case OPTION_ARGUMENT:
202 case OPTION_GROUP:
07800601
IM
203 default:
204 die("should not happen, someone must be hit on the forehead");
205 }
206}
207
208static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *options)
209{
210 for (; options->type != OPTION_END; options++) {
211 if (options->short_name == *p->opt) {
212 p->opt = p->opt[1] ? p->opt + 1 : NULL;
213 return get_value(p, options, OPT_SHORT);
214 }
215 }
216 return -2;
217}
218
219static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
220 const struct option *options)
221{
222 const char *arg_end = strchr(arg, '=');
223 const struct option *abbrev_option = NULL, *ambiguous_option = NULL;
224 int abbrev_flags = 0, ambiguous_flags = 0;
225
226 if (!arg_end)
227 arg_end = arg + strlen(arg);
228
229 for (; options->type != OPTION_END; options++) {
230 const char *rest;
231 int flags = 0;
232
233 if (!options->long_name)
234 continue;
235
236 rest = skip_prefix(arg, options->long_name);
237 if (options->type == OPTION_ARGUMENT) {
238 if (!rest)
239 continue;
240 if (*rest == '=')
241 return opterror(options, "takes no value", flags);
242 if (*rest)
243 continue;
244 p->out[p->cpidx++] = arg - 2;
245 return 0;
246 }
247 if (!rest) {
4bc43796
AH
248 if (!prefixcmp(options->long_name, "no-")) {
249 /*
250 * The long name itself starts with "no-", so
251 * accept the option without "no-" so that users
252 * do not have to enter "no-no-" to get the
253 * negation.
254 */
255 rest = skip_prefix(arg, options->long_name + 3);
256 if (rest) {
257 flags |= OPT_UNSET;
258 goto match;
259 }
260 /* Abbreviated case */
261 if (!prefixcmp(options->long_name + 3, arg)) {
262 flags |= OPT_UNSET;
263 goto is_abbreviated;
264 }
265 }
07800601
IM
266 /* abbreviated? */
267 if (!strncmp(options->long_name, arg, arg_end - arg)) {
268is_abbreviated:
269 if (abbrev_option) {
270 /*
271 * If this is abbreviated, it is
272 * ambiguous. So when there is no
273 * exact match later, we need to
274 * error out.
275 */
276 ambiguous_option = abbrev_option;
277 ambiguous_flags = abbrev_flags;
278 }
279 if (!(flags & OPT_UNSET) && *arg_end)
280 p->opt = arg_end + 1;
281 abbrev_option = options;
282 abbrev_flags = flags;
283 continue;
284 }
285 /* negated and abbreviated very much? */
286 if (!prefixcmp("no-", arg)) {
287 flags |= OPT_UNSET;
288 goto is_abbreviated;
289 }
290 /* negated? */
291 if (strncmp(arg, "no-", 3))
292 continue;
293 flags |= OPT_UNSET;
294 rest = skip_prefix(arg + 3, options->long_name);
295 /* abbreviated and negated? */
296 if (!rest && !prefixcmp(options->long_name, arg + 3))
297 goto is_abbreviated;
298 if (!rest)
299 continue;
300 }
4bc43796 301match:
07800601
IM
302 if (*rest) {
303 if (*rest != '=')
304 continue;
305 p->opt = rest + 1;
306 }
307 return get_value(p, options, flags);
308 }
309
310 if (ambiguous_option)
311 return error("Ambiguous option: %s "
312 "(could be --%s%s or --%s%s)",
313 arg,
314 (ambiguous_flags & OPT_UNSET) ? "no-" : "",
315 ambiguous_option->long_name,
316 (abbrev_flags & OPT_UNSET) ? "no-" : "",
317 abbrev_option->long_name);
318 if (abbrev_option)
319 return get_value(p, abbrev_option, abbrev_flags);
320 return -2;
321}
322
323static void check_typos(const char *arg, const struct option *options)
324{
325 if (strlen(arg) < 3)
326 return;
327
328 if (!prefixcmp(arg, "no-")) {
329 error ("did you mean `--%s` (with two dashes ?)", arg);
330 exit(129);
331 }
332
333 for (; options->type != OPTION_END; options++) {
334 if (!options->long_name)
335 continue;
336 if (!prefixcmp(options->long_name, arg)) {
337 error ("did you mean `--%s` (with two dashes ?)", arg);
338 exit(129);
339 }
340 }
341}
342
343void parse_options_start(struct parse_opt_ctx_t *ctx,
344 int argc, const char **argv, int flags)
345{
346 memset(ctx, 0, sizeof(*ctx));
347 ctx->argc = argc - 1;
348 ctx->argv = argv + 1;
349 ctx->out = argv;
350 ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
351 ctx->flags = flags;
352 if ((flags & PARSE_OPT_KEEP_UNKNOWN) &&
353 (flags & PARSE_OPT_STOP_AT_NON_OPTION))
354 die("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
355}
356
357static int usage_with_options_internal(const char * const *,
358 const struct option *, int);
359
360int parse_options_step(struct parse_opt_ctx_t *ctx,
361 const struct option *options,
362 const char * const usagestr[])
363{
364 int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
42bd71d0
NK
365 int excl_short_opt = 1;
366 const char *arg;
07800601
IM
367
368 /* we must reset ->opt, unknown short option leave it dangling */
369 ctx->opt = NULL;
370
371 for (; ctx->argc; ctx->argc--, ctx->argv++) {
42bd71d0 372 arg = ctx->argv[0];
07800601
IM
373 if (*arg != '-' || !arg[1]) {
374 if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
375 break;
376 ctx->out[ctx->cpidx++] = ctx->argv[0];
377 continue;
378 }
379
380 if (arg[1] != '-') {
42bd71d0 381 ctx->opt = ++arg;
07800601 382 if (internal_help && *ctx->opt == 'h')
ac697625 383 return usage_with_options_internal(usagestr, options, 0);
07800601
IM
384 switch (parse_short_opt(ctx, options)) {
385 case -1:
42bd71d0 386 return parse_options_usage(usagestr, options, arg, 1);
07800601
IM
387 case -2:
388 goto unknown;
42bd71d0
NK
389 case -3:
390 goto exclusive;
83a0944f
IM
391 default:
392 break;
07800601
IM
393 }
394 if (ctx->opt)
42bd71d0 395 check_typos(arg, options);
07800601
IM
396 while (ctx->opt) {
397 if (internal_help && *ctx->opt == 'h')
ac697625
NK
398 return usage_with_options_internal(usagestr, options, 0);
399 arg = ctx->opt;
07800601
IM
400 switch (parse_short_opt(ctx, options)) {
401 case -1:
ac697625 402 return parse_options_usage(usagestr, options, arg, 1);
07800601
IM
403 case -2:
404 /* fake a short option thing to hide the fact that we may have
405 * started to parse aggregated stuff
406 *
407 * This is leaky, too bad.
408 */
409 ctx->argv[0] = strdup(ctx->opt - 1);
410 *(char *)ctx->argv[0] = '-';
411 goto unknown;
42bd71d0
NK
412 case -3:
413 goto exclusive;
83a0944f
IM
414 default:
415 break;
07800601
IM
416 }
417 }
418 continue;
419 }
420
421 if (!arg[2]) { /* "--" */
422 if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
423 ctx->argc--;
424 ctx->argv++;
425 }
426 break;
427 }
428
42bd71d0
NK
429 arg += 2;
430 if (internal_help && !strcmp(arg, "help-all"))
07800601 431 return usage_with_options_internal(usagestr, options, 1);
42bd71d0 432 if (internal_help && !strcmp(arg, "help"))
ac697625 433 return usage_with_options_internal(usagestr, options, 0);
42bd71d0 434 if (!strcmp(arg, "list-opts"))
09a71b97 435 return PARSE_OPT_LIST_OPTS;
42bd71d0 436 if (!strcmp(arg, "list-cmds"))
09a71b97 437 return PARSE_OPT_LIST_SUBCMDS;
42bd71d0 438 switch (parse_long_opt(ctx, arg, options)) {
07800601 439 case -1:
42bd71d0 440 return parse_options_usage(usagestr, options, arg, 0);
07800601
IM
441 case -2:
442 goto unknown;
42bd71d0
NK
443 case -3:
444 excl_short_opt = 0;
445 goto exclusive;
83a0944f
IM
446 default:
447 break;
07800601
IM
448 }
449 continue;
450unknown:
451 if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN))
452 return PARSE_OPT_UNKNOWN;
453 ctx->out[ctx->cpidx++] = ctx->argv[0];
454 ctx->opt = NULL;
455 }
456 return PARSE_OPT_DONE;
42bd71d0
NK
457
458exclusive:
459 parse_options_usage(usagestr, options, arg, excl_short_opt);
460 if ((excl_short_opt && ctx->excl_opt->short_name) ||
461 ctx->excl_opt->long_name == NULL) {
462 char opt = ctx->excl_opt->short_name;
463 parse_options_usage(NULL, options, &opt, 1);
464 } else {
465 parse_options_usage(NULL, options, ctx->excl_opt->long_name, 0);
466 }
467 return PARSE_OPT_HELP;
07800601
IM
468}
469
470int parse_options_end(struct parse_opt_ctx_t *ctx)
471{
472 memmove(ctx->out + ctx->cpidx, ctx->argv, ctx->argc * sizeof(*ctx->out));
473 ctx->out[ctx->cpidx + ctx->argc] = NULL;
474 return ctx->cpidx + ctx->argc;
475}
476
09a71b97
RR
477int parse_options_subcommand(int argc, const char **argv, const struct option *options,
478 const char *const subcommands[], const char *usagestr[], int flags)
07800601
IM
479{
480 struct parse_opt_ctx_t ctx;
481
56e6f602
DA
482 perf_header__set_cmdline(argc, argv);
483
09a71b97
RR
484 /* build usage string if it's not provided */
485 if (subcommands && !usagestr[0]) {
486 struct strbuf buf = STRBUF_INIT;
487
488 strbuf_addf(&buf, "perf %s [<options>] {", argv[0]);
489 for (int i = 0; subcommands[i]; i++) {
490 if (i)
491 strbuf_addstr(&buf, "|");
492 strbuf_addstr(&buf, subcommands[i]);
493 }
494 strbuf_addstr(&buf, "}");
495
496 usagestr[0] = strdup(buf.buf);
497 strbuf_release(&buf);
498 }
499
07800601
IM
500 parse_options_start(&ctx, argc, argv, flags);
501 switch (parse_options_step(&ctx, options, usagestr)) {
502 case PARSE_OPT_HELP:
503 exit(129);
504 case PARSE_OPT_DONE:
505 break;
09a71b97 506 case PARSE_OPT_LIST_OPTS:
4d8061fa
NK
507 while (options->type != OPTION_END) {
508 printf("--%s ", options->long_name);
509 options++;
510 }
511 exit(130);
09a71b97
RR
512 case PARSE_OPT_LIST_SUBCMDS:
513 for (int i = 0; subcommands[i]; i++)
514 printf("%s ", subcommands[i]);
515 exit(130);
07800601
IM
516 default: /* PARSE_OPT_UNKNOWN */
517 if (ctx.argv[0][1] == '-') {
518 error("unknown option `%s'", ctx.argv[0] + 2);
519 } else {
520 error("unknown switch `%c'", *ctx.opt);
521 }
522 usage_with_options(usagestr, options);
523 }
524
525 return parse_options_end(&ctx);
526}
527
09a71b97
RR
528int parse_options(int argc, const char **argv, const struct option *options,
529 const char * const usagestr[], int flags)
530{
531 return parse_options_subcommand(argc, argv, options, NULL,
532 (const char **) usagestr, flags);
533}
534
07800601
IM
535#define USAGE_OPTS_WIDTH 24
536#define USAGE_GAP 2
537
ac697625
NK
538static void print_option_help(const struct option *opts, int full)
539{
540 size_t pos;
541 int pad;
542
543 if (opts->type == OPTION_GROUP) {
544 fputc('\n', stderr);
545 if (*opts->help)
546 fprintf(stderr, "%s\n", opts->help);
547 return;
548 }
549 if (!full && (opts->flags & PARSE_OPT_HIDDEN))
550 return;
d152d1be
NK
551 if (opts->flags & PARSE_OPT_DISABLED)
552 return;
ac697625
NK
553
554 pos = fprintf(stderr, " ");
555 if (opts->short_name)
556 pos += fprintf(stderr, "-%c", opts->short_name);
557 else
558 pos += fprintf(stderr, " ");
559
560 if (opts->long_name && opts->short_name)
561 pos += fprintf(stderr, ", ");
562 if (opts->long_name)
563 pos += fprintf(stderr, "--%s", opts->long_name);
564
565 switch (opts->type) {
566 case OPTION_ARGUMENT:
567 break;
568 case OPTION_LONG:
569 case OPTION_U64:
570 case OPTION_INTEGER:
571 case OPTION_UINTEGER:
572 if (opts->flags & PARSE_OPT_OPTARG)
573 if (opts->long_name)
574 pos += fprintf(stderr, "[=<n>]");
575 else
576 pos += fprintf(stderr, "[<n>]");
577 else
578 pos += fprintf(stderr, " <n>");
579 break;
580 case OPTION_CALLBACK:
581 if (opts->flags & PARSE_OPT_NOARG)
582 break;
583 /* FALLTHROUGH */
584 case OPTION_STRING:
585 if (opts->argh) {
586 if (opts->flags & PARSE_OPT_OPTARG)
587 if (opts->long_name)
588 pos += fprintf(stderr, "[=<%s>]", opts->argh);
589 else
590 pos += fprintf(stderr, "[<%s>]", opts->argh);
591 else
592 pos += fprintf(stderr, " <%s>", opts->argh);
593 } else {
594 if (opts->flags & PARSE_OPT_OPTARG)
595 if (opts->long_name)
596 pos += fprintf(stderr, "[=...]");
597 else
598 pos += fprintf(stderr, "[...]");
599 else
600 pos += fprintf(stderr, " ...");
601 }
602 break;
603 default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
604 case OPTION_END:
605 case OPTION_GROUP:
606 case OPTION_BIT:
607 case OPTION_BOOLEAN:
608 case OPTION_INCR:
609 case OPTION_SET_UINT:
610 case OPTION_SET_PTR:
611 break;
612 }
613
614 if (pos <= USAGE_OPTS_WIDTH)
615 pad = USAGE_OPTS_WIDTH - pos;
616 else {
617 fputc('\n', stderr);
618 pad = USAGE_OPTS_WIDTH;
619 }
620 fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
621}
622
07800601
IM
623int usage_with_options_internal(const char * const *usagestr,
624 const struct option *opts, int full)
625{
626 if (!usagestr)
627 return PARSE_OPT_HELP;
628
502fc5c7 629 fprintf(stderr, "\n usage: %s\n", *usagestr++);
07800601 630 while (*usagestr && **usagestr)
6e6b754f 631 fprintf(stderr, " or: %s\n", *usagestr++);
07800601
IM
632 while (*usagestr) {
633 fprintf(stderr, "%s%s\n",
634 **usagestr ? " " : "",
635 *usagestr);
636 usagestr++;
637 }
638
639 if (opts->type != OPTION_GROUP)
640 fputc('\n', stderr);
641
ac697625
NK
642 for ( ; opts->type != OPTION_END; opts++)
643 print_option_help(opts, full);
07800601 644
07800601
IM
645 fputc('\n', stderr);
646
647 return PARSE_OPT_HELP;
648}
649
650void usage_with_options(const char * const *usagestr,
651 const struct option *opts)
652{
478b0973 653 exit_browser(false);
07800601
IM
654 usage_with_options_internal(usagestr, opts, 0);
655 exit(129);
656}
657
658int parse_options_usage(const char * const *usagestr,
ac697625
NK
659 const struct option *opts,
660 const char *optstr, bool short_opt)
07800601 661{
ac697625 662 if (!usagestr)
cc03c542 663 goto opt;
ac697625
NK
664
665 fprintf(stderr, "\n usage: %s\n", *usagestr++);
666 while (*usagestr && **usagestr)
667 fprintf(stderr, " or: %s\n", *usagestr++);
668 while (*usagestr) {
669 fprintf(stderr, "%s%s\n",
670 **usagestr ? " " : "",
671 *usagestr);
672 usagestr++;
673 }
674 fputc('\n', stderr);
675
cc03c542 676opt:
ac697625
NK
677 for ( ; opts->type != OPTION_END; opts++) {
678 if (short_opt) {
679 if (opts->short_name == *optstr)
680 break;
681 continue;
682 }
683
684 if (opts->long_name == NULL)
685 continue;
686
687 if (!prefixcmp(optstr, opts->long_name))
688 break;
689 if (!prefixcmp(optstr, "no-") &&
690 !prefixcmp(optstr + 3, opts->long_name))
691 break;
692 }
693
694 if (opts->type != OPTION_END)
695 print_option_help(opts, 0);
696
697 return PARSE_OPT_HELP;
07800601
IM
698}
699
700
1d037ca1
IT
701int parse_opt_verbosity_cb(const struct option *opt,
702 const char *arg __maybe_unused,
07800601
IM
703 int unset)
704{
705 int *target = opt->value;
706
707 if (unset)
708 /* --no-quiet, --no-verbose */
709 *target = 0;
710 else if (opt->short_name == 'v') {
711 if (*target >= 0)
712 (*target)++;
713 else
714 *target = 1;
715 } else {
716 if (*target <= 0)
717 (*target)--;
718 else
719 *target = -1;
720 }
721 return 0;
722}
d152d1be
NK
723
724void set_option_flag(struct option *opts, int shortopt, const char *longopt,
725 int flag)
726{
727 for (; opts->type != OPTION_END; opts++) {
728 if ((shortopt && opts->short_name == shortopt) ||
729 (opts->long_name && longopt &&
730 !strcmp(opts->long_name, longopt))) {
731 opts->flags |= flag;
732 break;
733 }
734 }
735}
This page took 0.352884 seconds and 5 git commands to generate.