parse-options.c 20 KB

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