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