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