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