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