at v3.14-rc2 652 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; 411 switch (parse_long_opt(ctx, arg + 2, options)) { 412 case -1: 413 return parse_options_usage(usagestr, options, arg + 2, 0); 414 case -2: 415 goto unknown; 416 default: 417 break; 418 } 419 continue; 420unknown: 421 if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN)) 422 return PARSE_OPT_UNKNOWN; 423 ctx->out[ctx->cpidx++] = ctx->argv[0]; 424 ctx->opt = NULL; 425 } 426 return PARSE_OPT_DONE; 427} 428 429int parse_options_end(struct parse_opt_ctx_t *ctx) 430{ 431 memmove(ctx->out + ctx->cpidx, ctx->argv, ctx->argc * sizeof(*ctx->out)); 432 ctx->out[ctx->cpidx + ctx->argc] = NULL; 433 return ctx->cpidx + ctx->argc; 434} 435 436int parse_options(int argc, const char **argv, const struct option *options, 437 const char * const usagestr[], int flags) 438{ 439 struct parse_opt_ctx_t ctx; 440 441 perf_header__set_cmdline(argc, argv); 442 443 parse_options_start(&ctx, argc, argv, flags); 444 switch (parse_options_step(&ctx, options, usagestr)) { 445 case PARSE_OPT_HELP: 446 exit(129); 447 case PARSE_OPT_DONE: 448 break; 449 case PARSE_OPT_LIST: 450 while (options->type != OPTION_END) { 451 printf("--%s ", options->long_name); 452 options++; 453 } 454 exit(130); 455 default: /* PARSE_OPT_UNKNOWN */ 456 if (ctx.argv[0][1] == '-') { 457 error("unknown option `%s'", ctx.argv[0] + 2); 458 } else { 459 error("unknown switch `%c'", *ctx.opt); 460 } 461 usage_with_options(usagestr, options); 462 } 463 464 return parse_options_end(&ctx); 465} 466 467#define USAGE_OPTS_WIDTH 24 468#define USAGE_GAP 2 469 470static void print_option_help(const struct option *opts, int full) 471{ 472 size_t pos; 473 int pad; 474 475 if (opts->type == OPTION_GROUP) { 476 fputc('\n', stderr); 477 if (*opts->help) 478 fprintf(stderr, "%s\n", opts->help); 479 return; 480 } 481 if (!full && (opts->flags & PARSE_OPT_HIDDEN)) 482 return; 483 484 pos = fprintf(stderr, " "); 485 if (opts->short_name) 486 pos += fprintf(stderr, "-%c", opts->short_name); 487 else 488 pos += fprintf(stderr, " "); 489 490 if (opts->long_name && opts->short_name) 491 pos += fprintf(stderr, ", "); 492 if (opts->long_name) 493 pos += fprintf(stderr, "--%s", opts->long_name); 494 495 switch (opts->type) { 496 case OPTION_ARGUMENT: 497 break; 498 case OPTION_LONG: 499 case OPTION_U64: 500 case OPTION_INTEGER: 501 case OPTION_UINTEGER: 502 if (opts->flags & PARSE_OPT_OPTARG) 503 if (opts->long_name) 504 pos += fprintf(stderr, "[=<n>]"); 505 else 506 pos += fprintf(stderr, "[<n>]"); 507 else 508 pos += fprintf(stderr, " <n>"); 509 break; 510 case OPTION_CALLBACK: 511 if (opts->flags & PARSE_OPT_NOARG) 512 break; 513 /* FALLTHROUGH */ 514 case OPTION_STRING: 515 if (opts->argh) { 516 if (opts->flags & PARSE_OPT_OPTARG) 517 if (opts->long_name) 518 pos += fprintf(stderr, "[=<%s>]", opts->argh); 519 else 520 pos += fprintf(stderr, "[<%s>]", opts->argh); 521 else 522 pos += fprintf(stderr, " <%s>", opts->argh); 523 } else { 524 if (opts->flags & PARSE_OPT_OPTARG) 525 if (opts->long_name) 526 pos += fprintf(stderr, "[=...]"); 527 else 528 pos += fprintf(stderr, "[...]"); 529 else 530 pos += fprintf(stderr, " ..."); 531 } 532 break; 533 default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */ 534 case OPTION_END: 535 case OPTION_GROUP: 536 case OPTION_BIT: 537 case OPTION_BOOLEAN: 538 case OPTION_INCR: 539 case OPTION_SET_UINT: 540 case OPTION_SET_PTR: 541 break; 542 } 543 544 if (pos <= USAGE_OPTS_WIDTH) 545 pad = USAGE_OPTS_WIDTH - pos; 546 else { 547 fputc('\n', stderr); 548 pad = USAGE_OPTS_WIDTH; 549 } 550 fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help); 551} 552 553int usage_with_options_internal(const char * const *usagestr, 554 const struct option *opts, int full) 555{ 556 if (!usagestr) 557 return PARSE_OPT_HELP; 558 559 fprintf(stderr, "\n usage: %s\n", *usagestr++); 560 while (*usagestr && **usagestr) 561 fprintf(stderr, " or: %s\n", *usagestr++); 562 while (*usagestr) { 563 fprintf(stderr, "%s%s\n", 564 **usagestr ? " " : "", 565 *usagestr); 566 usagestr++; 567 } 568 569 if (opts->type != OPTION_GROUP) 570 fputc('\n', stderr); 571 572 for ( ; opts->type != OPTION_END; opts++) 573 print_option_help(opts, full); 574 575 fputc('\n', stderr); 576 577 return PARSE_OPT_HELP; 578} 579 580void usage_with_options(const char * const *usagestr, 581 const struct option *opts) 582{ 583 exit_browser(false); 584 usage_with_options_internal(usagestr, opts, 0); 585 exit(129); 586} 587 588int parse_options_usage(const char * const *usagestr, 589 const struct option *opts, 590 const char *optstr, bool short_opt) 591{ 592 if (!usagestr) 593 goto opt; 594 595 fprintf(stderr, "\n usage: %s\n", *usagestr++); 596 while (*usagestr && **usagestr) 597 fprintf(stderr, " or: %s\n", *usagestr++); 598 while (*usagestr) { 599 fprintf(stderr, "%s%s\n", 600 **usagestr ? " " : "", 601 *usagestr); 602 usagestr++; 603 } 604 fputc('\n', stderr); 605 606opt: 607 for ( ; opts->type != OPTION_END; opts++) { 608 if (short_opt) { 609 if (opts->short_name == *optstr) 610 break; 611 continue; 612 } 613 614 if (opts->long_name == NULL) 615 continue; 616 617 if (!prefixcmp(optstr, opts->long_name)) 618 break; 619 if (!prefixcmp(optstr, "no-") && 620 !prefixcmp(optstr + 3, opts->long_name)) 621 break; 622 } 623 624 if (opts->type != OPTION_END) 625 print_option_help(opts, 0); 626 627 return PARSE_OPT_HELP; 628} 629 630 631int parse_opt_verbosity_cb(const struct option *opt, 632 const char *arg __maybe_unused, 633 int unset) 634{ 635 int *target = opt->value; 636 637 if (unset) 638 /* --no-quiet, --no-verbose */ 639 *target = 0; 640 else if (opt->short_name == 'v') { 641 if (*target >= 0) 642 (*target)++; 643 else 644 *target = 1; 645 } else { 646 if (*target <= 0) 647 (*target)--; 648 else 649 *target = -1; 650 } 651 return 0; 652}