THIS IS A TEST INSTANCE ONLY! REPOSITORIES CAN BE DELETED AT ANY TIME!

Git Source Code Mirror - This is a publish-only repository and all pull requests are ignored. Please follow Documentation/SubmittingPatches procedure for any of your improvements.
git
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1012 lines
26KB

  1. #include "git-compat-util.h"
  2. #include "parse-options.h"
  3. #include "cache.h"
  4. #include "config.h"
  5. #include "commit.h"
  6. #include "color.h"
  7. #include "utf8.h"
  8. static int disallow_abbreviated_options;
  9. #define OPT_SHORT 1
  10. #define OPT_UNSET 2
  11. int optbug(const struct option *opt, const char *reason)
  12. {
  13. if (opt->long_name) {
  14. if (opt->short_name)
  15. return error("BUG: switch '%c' (--%s) %s",
  16. opt->short_name, opt->long_name, reason);
  17. return error("BUG: option '%s' %s", opt->long_name, reason);
  18. }
  19. return error("BUG: switch '%c' %s", opt->short_name, reason);
  20. }
  21. static enum parse_opt_result get_arg(struct parse_opt_ctx_t *p,
  22. const struct option *opt,
  23. int flags, const char **arg)
  24. {
  25. if (p->opt) {
  26. *arg = p->opt;
  27. p->opt = NULL;
  28. } else if (p->argc == 1 && (opt->flags & PARSE_OPT_LASTARG_DEFAULT)) {
  29. *arg = (const char *)opt->defval;
  30. } else if (p->argc > 1) {
  31. p->argc--;
  32. *arg = *++p->argv;
  33. } else
  34. return error(_("%s requires a value"), optname(opt, flags));
  35. return 0;
  36. }
  37. static void fix_filename(const char *prefix, const char **file)
  38. {
  39. if (!file || !*file || !prefix || is_absolute_path(*file)
  40. || !strcmp("-", *file))
  41. return;
  42. *file = prefix_filename(prefix, *file);
  43. }
  44. static enum parse_opt_result opt_command_mode_error(
  45. const struct option *opt,
  46. const struct option *all_opts,
  47. int flags)
  48. {
  49. const struct option *that;
  50. struct strbuf that_name = STRBUF_INIT;
  51. /*
  52. * Find the other option that was used to set the variable
  53. * already, and report that this is not compatible with it.
  54. */
  55. for (that = all_opts; that->type != OPTION_END; that++) {
  56. if (that == opt ||
  57. that->type != OPTION_CMDMODE ||
  58. that->value != opt->value ||
  59. that->defval != *(int *)opt->value)
  60. continue;
  61. if (that->long_name)
  62. strbuf_addf(&that_name, "--%s", that->long_name);
  63. else
  64. strbuf_addf(&that_name, "-%c", that->short_name);
  65. error(_("%s is incompatible with %s"),
  66. optname(opt, flags), that_name.buf);
  67. strbuf_release(&that_name);
  68. return PARSE_OPT_ERROR;
  69. }
  70. return error(_("%s : incompatible with something else"),
  71. optname(opt, flags));
  72. }
  73. static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
  74. const struct option *opt,
  75. const struct option *all_opts,
  76. int flags)
  77. {
  78. const char *s, *arg;
  79. const int unset = flags & OPT_UNSET;
  80. int err;
  81. if (unset && p->opt)
  82. return error(_("%s takes no value"), optname(opt, flags));
  83. if (unset && (opt->flags & PARSE_OPT_NONEG))
  84. return error(_("%s isn't available"), optname(opt, flags));
  85. if (!(flags & OPT_SHORT) && p->opt && (opt->flags & PARSE_OPT_NOARG))
  86. return error(_("%s takes no value"), optname(opt, flags));
  87. switch (opt->type) {
  88. case OPTION_LOWLEVEL_CALLBACK:
  89. return opt->ll_callback(p, opt, NULL, unset);
  90. case OPTION_BIT:
  91. if (unset)
  92. *(int *)opt->value &= ~opt->defval;
  93. else
  94. *(int *)opt->value |= opt->defval;
  95. return 0;
  96. case OPTION_NEGBIT:
  97. if (unset)
  98. *(int *)opt->value |= opt->defval;
  99. else
  100. *(int *)opt->value &= ~opt->defval;
  101. return 0;
  102. case OPTION_BITOP:
  103. if (unset)
  104. BUG("BITOP can't have unset form");
  105. *(int *)opt->value &= ~opt->extra;
  106. *(int *)opt->value |= opt->defval;
  107. return 0;
  108. case OPTION_COUNTUP:
  109. if (*(int *)opt->value < 0)
  110. *(int *)opt->value = 0;
  111. *(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
  112. return 0;
  113. case OPTION_SET_INT:
  114. *(int *)opt->value = unset ? 0 : opt->defval;
  115. return 0;
  116. case OPTION_CMDMODE:
  117. /*
  118. * Giving the same mode option twice, although is unnecessary,
  119. * is not a grave error, so let it pass.
  120. */
  121. if (*(int *)opt->value && *(int *)opt->value != opt->defval)
  122. return opt_command_mode_error(opt, all_opts, flags);
  123. *(int *)opt->value = opt->defval;
  124. return 0;
  125. case OPTION_STRING:
  126. if (unset)
  127. *(const char **)opt->value = NULL;
  128. else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
  129. *(const char **)opt->value = (const char *)opt->defval;
  130. else
  131. return get_arg(p, opt, flags, (const char **)opt->value);
  132. return 0;
  133. case OPTION_FILENAME:
  134. err = 0;
  135. if (unset)
  136. *(const char **)opt->value = NULL;
  137. else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
  138. *(const char **)opt->value = (const char *)opt->defval;
  139. else
  140. err = get_arg(p, opt, flags, (const char **)opt->value);
  141. if (!err)
  142. fix_filename(p->prefix, (const char **)opt->value);
  143. return err;
  144. case OPTION_CALLBACK:
  145. {
  146. const char *p_arg = NULL;
  147. int p_unset;
  148. if (unset)
  149. p_unset = 1;
  150. else if (opt->flags & PARSE_OPT_NOARG)
  151. p_unset = 0;
  152. else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
  153. p_unset = 0;
  154. else if (get_arg(p, opt, flags, &arg))
  155. return -1;
  156. else {
  157. p_unset = 0;
  158. p_arg = arg;
  159. }
  160. if (opt->callback)
  161. return (*opt->callback)(opt, p_arg, p_unset) ? (-1) : 0;
  162. else
  163. return (*opt->ll_callback)(p, opt, p_arg, p_unset);
  164. }
  165. case OPTION_INTEGER:
  166. if (unset) {
  167. *(int *)opt->value = 0;
  168. return 0;
  169. }
  170. if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
  171. *(int *)opt->value = opt->defval;
  172. return 0;
  173. }
  174. if (get_arg(p, opt, flags, &arg))
  175. return -1;
  176. if (!*arg)
  177. return error(_("%s expects a numerical value"),
  178. optname(opt, flags));
  179. *(int *)opt->value = strtol(arg, (char **)&s, 10);
  180. if (*s)
  181. return error(_("%s expects a numerical value"),
  182. optname(opt, flags));
  183. return 0;
  184. case OPTION_MAGNITUDE:
  185. if (unset) {
  186. *(unsigned long *)opt->value = 0;
  187. return 0;
  188. }
  189. if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
  190. *(unsigned long *)opt->value = opt->defval;
  191. return 0;
  192. }
  193. if (get_arg(p, opt, flags, &arg))
  194. return -1;
  195. if (!git_parse_ulong(arg, opt->value))
  196. return error(_("%s expects a non-negative integer value"
  197. " with an optional k/m/g suffix"),
  198. optname(opt, flags));
  199. return 0;
  200. default:
  201. BUG("opt->type %d should not happen", opt->type);
  202. }
  203. }
  204. static enum parse_opt_result parse_short_opt(struct parse_opt_ctx_t *p,
  205. const struct option *options)
  206. {
  207. const struct option *all_opts = options;
  208. const struct option *numopt = NULL;
  209. for (; options->type != OPTION_END; options++) {
  210. if (options->short_name == *p->opt) {
  211. p->opt = p->opt[1] ? p->opt + 1 : NULL;
  212. return get_value(p, options, all_opts, OPT_SHORT);
  213. }
  214. /*
  215. * Handle the numerical option later, explicit one-digit
  216. * options take precedence over it.
  217. */
  218. if (options->type == OPTION_NUMBER)
  219. numopt = options;
  220. }
  221. if (numopt && isdigit(*p->opt)) {
  222. size_t len = 1;
  223. char *arg;
  224. int rc;
  225. while (isdigit(p->opt[len]))
  226. len++;
  227. arg = xmemdupz(p->opt, len);
  228. p->opt = p->opt[len] ? p->opt + len : NULL;
  229. if (numopt->callback)
  230. rc = (*numopt->callback)(numopt, arg, 0) ? (-1) : 0;
  231. else
  232. rc = (*numopt->ll_callback)(p, numopt, arg, 0);
  233. free(arg);
  234. return rc;
  235. }
  236. return PARSE_OPT_UNKNOWN;
  237. }
  238. static int has_string(const char *it, const char **array)
  239. {
  240. while (*array)
  241. if (!strcmp(it, *(array++)))
  242. return 1;
  243. return 0;
  244. }
  245. static int is_alias(struct parse_opt_ctx_t *ctx,
  246. const struct option *one_opt,
  247. const struct option *another_opt)
  248. {
  249. const char **group;
  250. if (!ctx->alias_groups)
  251. return 0;
  252. if (!one_opt->long_name || !another_opt->long_name)
  253. return 0;
  254. for (group = ctx->alias_groups; *group; group += 3) {
  255. /* it and other are from the same family? */
  256. if (has_string(one_opt->long_name, group) &&
  257. has_string(another_opt->long_name, group))
  258. return 1;
  259. }
  260. return 0;
  261. }
  262. static enum parse_opt_result parse_long_opt(
  263. struct parse_opt_ctx_t *p, const char *arg,
  264. const struct option *options)
  265. {
  266. const struct option *all_opts = options;
  267. const char *arg_end = strchrnul(arg, '=');
  268. const struct option *abbrev_option = NULL, *ambiguous_option = NULL;
  269. int abbrev_flags = 0, ambiguous_flags = 0;
  270. for (; options->type != OPTION_END; options++) {
  271. const char *rest, *long_name = options->long_name;
  272. int flags = 0, opt_flags = 0;
  273. if (!long_name)
  274. continue;
  275. again:
  276. if (!skip_prefix(arg, long_name, &rest))
  277. rest = NULL;
  278. if (options->type == OPTION_ARGUMENT) {
  279. if (!rest)
  280. continue;
  281. if (*rest == '=')
  282. return error(_("%s takes no value"),
  283. optname(options, flags));
  284. if (*rest)
  285. continue;
  286. if (options->value)
  287. *(int *)options->value = options->defval;
  288. p->out[p->cpidx++] = arg - 2;
  289. return PARSE_OPT_DONE;
  290. }
  291. if (!rest) {
  292. /* abbreviated? */
  293. if (!(p->flags & PARSE_OPT_KEEP_UNKNOWN) &&
  294. !strncmp(long_name, arg, arg_end - arg)) {
  295. is_abbreviated:
  296. if (abbrev_option &&
  297. !is_alias(p, abbrev_option, options)) {
  298. /*
  299. * If this is abbreviated, it is
  300. * ambiguous. So when there is no
  301. * exact match later, we need to
  302. * error out.
  303. */
  304. ambiguous_option = abbrev_option;
  305. ambiguous_flags = abbrev_flags;
  306. }
  307. if (!(flags & OPT_UNSET) && *arg_end)
  308. p->opt = arg_end + 1;
  309. abbrev_option = options;
  310. abbrev_flags = flags ^ opt_flags;
  311. continue;
  312. }
  313. /* negation allowed? */
  314. if (options->flags & PARSE_OPT_NONEG)
  315. continue;
  316. /* negated and abbreviated very much? */
  317. if (starts_with("no-", arg)) {
  318. flags |= OPT_UNSET;
  319. goto is_abbreviated;
  320. }
  321. /* negated? */
  322. if (!starts_with(arg, "no-")) {
  323. if (starts_with(long_name, "no-")) {
  324. long_name += 3;
  325. opt_flags |= OPT_UNSET;
  326. goto again;
  327. }
  328. continue;
  329. }
  330. flags |= OPT_UNSET;
  331. if (!skip_prefix(arg + 3, long_name, &rest)) {
  332. /* abbreviated and negated? */
  333. if (starts_with(long_name, arg + 3))
  334. goto is_abbreviated;
  335. else
  336. continue;
  337. }
  338. }
  339. if (*rest) {
  340. if (*rest != '=')
  341. continue;
  342. p->opt = rest + 1;
  343. }
  344. return get_value(p, options, all_opts, flags ^ opt_flags);
  345. }
  346. if (disallow_abbreviated_options && (ambiguous_option || abbrev_option))
  347. die("disallowed abbreviated or ambiguous option '%.*s'",
  348. (int)(arg_end - arg), arg);
  349. if (ambiguous_option) {
  350. error(_("ambiguous option: %s "
  351. "(could be --%s%s or --%s%s)"),
  352. arg,
  353. (ambiguous_flags & OPT_UNSET) ? "no-" : "",
  354. ambiguous_option->long_name,
  355. (abbrev_flags & OPT_UNSET) ? "no-" : "",
  356. abbrev_option->long_name);
  357. return PARSE_OPT_HELP;
  358. }
  359. if (abbrev_option)
  360. return get_value(p, abbrev_option, all_opts, abbrev_flags);
  361. return PARSE_OPT_UNKNOWN;
  362. }
  363. static int parse_nodash_opt(struct parse_opt_ctx_t *p, const char *arg,
  364. const struct option *options)
  365. {
  366. const struct option *all_opts = options;
  367. for (; options->type != OPTION_END; options++) {
  368. if (!(options->flags & PARSE_OPT_NODASH))
  369. continue;
  370. if (options->short_name == arg[0] && arg[1] == '\0')
  371. return get_value(p, options, all_opts, OPT_SHORT);
  372. }
  373. return -2;
  374. }
  375. static void check_typos(const char *arg, const struct option *options)
  376. {
  377. if (strlen(arg) < 3)
  378. return;
  379. if (starts_with(arg, "no-")) {
  380. error(_("did you mean `--%s` (with two dashes ?)"), arg);
  381. exit(129);
  382. }
  383. for (; options->type != OPTION_END; options++) {
  384. if (!options->long_name)
  385. continue;
  386. if (starts_with(options->long_name, arg)) {
  387. error(_("did you mean `--%s` (with two dashes ?)"), arg);
  388. exit(129);
  389. }
  390. }
  391. }
  392. static void parse_options_check(const struct option *opts)
  393. {
  394. int err = 0;
  395. char short_opts[128];
  396. memset(short_opts, '\0', sizeof(short_opts));
  397. for (; opts->type != OPTION_END; opts++) {
  398. if ((opts->flags & PARSE_OPT_LASTARG_DEFAULT) &&
  399. (opts->flags & PARSE_OPT_OPTARG))
  400. err |= optbug(opts, "uses incompatible flags "
  401. "LASTARG_DEFAULT and OPTARG");
  402. if (opts->short_name) {
  403. if (0x7F <= opts->short_name)
  404. err |= optbug(opts, "invalid short name");
  405. else if (short_opts[opts->short_name]++)
  406. err |= optbug(opts, "short name already used");
  407. }
  408. if (opts->flags & PARSE_OPT_NODASH &&
  409. ((opts->flags & PARSE_OPT_OPTARG) ||
  410. !(opts->flags & PARSE_OPT_NOARG) ||
  411. !(opts->flags & PARSE_OPT_NONEG) ||
  412. opts->long_name))
  413. err |= optbug(opts, "uses feature "
  414. "not supported for dashless options");
  415. switch (opts->type) {
  416. case OPTION_COUNTUP:
  417. case OPTION_BIT:
  418. case OPTION_NEGBIT:
  419. case OPTION_SET_INT:
  420. case OPTION_NUMBER:
  421. if ((opts->flags & PARSE_OPT_OPTARG) ||
  422. !(opts->flags & PARSE_OPT_NOARG))
  423. err |= optbug(opts, "should not accept an argument");
  424. break;
  425. case OPTION_CALLBACK:
  426. if (!opts->callback && !opts->ll_callback)
  427. BUG("OPTION_CALLBACK needs one callback");
  428. if (opts->callback && opts->ll_callback)
  429. BUG("OPTION_CALLBACK can't have two callbacks");
  430. break;
  431. case OPTION_LOWLEVEL_CALLBACK:
  432. if (!opts->ll_callback)
  433. BUG("OPTION_LOWLEVEL_CALLBACK needs a callback");
  434. if (opts->callback)
  435. BUG("OPTION_LOWLEVEL_CALLBACK needs no high level callback");
  436. break;
  437. case OPTION_ALIAS:
  438. BUG("OPT_ALIAS() should not remain at this point. "
  439. "Are you using parse_options_step() directly?\n"
  440. "That case is not supported yet.");
  441. default:
  442. ; /* ok. (usually accepts an argument) */
  443. }
  444. if (opts->argh &&
  445. strcspn(opts->argh, " _") != strlen(opts->argh))
  446. err |= optbug(opts, "multi-word argh should use dash to separate words");
  447. }
  448. if (err)
  449. exit(128);
  450. }
  451. static void parse_options_start_1(struct parse_opt_ctx_t *ctx,
  452. int argc, const char **argv, const char *prefix,
  453. const struct option *options, int flags)
  454. {
  455. ctx->argc = argc;
  456. ctx->argv = argv;
  457. if (!(flags & PARSE_OPT_ONE_SHOT)) {
  458. ctx->argc--;
  459. ctx->argv++;
  460. }
  461. ctx->total = ctx->argc;
  462. ctx->out = argv;
  463. ctx->prefix = prefix;
  464. ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
  465. ctx->flags = flags;
  466. if ((flags & PARSE_OPT_KEEP_UNKNOWN) &&
  467. (flags & PARSE_OPT_STOP_AT_NON_OPTION) &&
  468. !(flags & PARSE_OPT_ONE_SHOT))
  469. BUG("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
  470. if ((flags & PARSE_OPT_ONE_SHOT) &&
  471. (flags & PARSE_OPT_KEEP_ARGV0))
  472. BUG("Can't keep argv0 if you don't have it");
  473. parse_options_check(options);
  474. }
  475. void parse_options_start(struct parse_opt_ctx_t *ctx,
  476. int argc, const char **argv, const char *prefix,
  477. const struct option *options, int flags)
  478. {
  479. memset(ctx, 0, sizeof(*ctx));
  480. parse_options_start_1(ctx, argc, argv, prefix, options, flags);
  481. }
  482. static void show_negated_gitcomp(const struct option *opts, int nr_noopts)
  483. {
  484. int printed_dashdash = 0;
  485. for (; opts->type != OPTION_END; opts++) {
  486. int has_unset_form = 0;
  487. const char *name;
  488. if (!opts->long_name)
  489. continue;
  490. if (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE))
  491. continue;
  492. if (opts->flags & PARSE_OPT_NONEG)
  493. continue;
  494. switch (opts->type) {
  495. case OPTION_STRING:
  496. case OPTION_FILENAME:
  497. case OPTION_INTEGER:
  498. case OPTION_MAGNITUDE:
  499. case OPTION_CALLBACK:
  500. case OPTION_BIT:
  501. case OPTION_NEGBIT:
  502. case OPTION_COUNTUP:
  503. case OPTION_SET_INT:
  504. has_unset_form = 1;
  505. break;
  506. default:
  507. break;
  508. }
  509. if (!has_unset_form)
  510. continue;
  511. if (skip_prefix(opts->long_name, "no-", &name)) {
  512. if (nr_noopts < 0)
  513. printf(" --%s", name);
  514. } else if (nr_noopts >= 0) {
  515. if (nr_noopts && !printed_dashdash) {
  516. printf(" --");
  517. printed_dashdash = 1;
  518. }
  519. printf(" --no-%s", opts->long_name);
  520. nr_noopts++;
  521. }
  522. }
  523. }
  524. static int show_gitcomp(const struct option *opts)
  525. {
  526. const struct option *original_opts = opts;
  527. int nr_noopts = 0;
  528. for (; opts->type != OPTION_END; opts++) {
  529. const char *suffix = "";
  530. if (!opts->long_name)
  531. continue;
  532. if (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE))
  533. continue;
  534. switch (opts->type) {
  535. case OPTION_GROUP:
  536. continue;
  537. case OPTION_STRING:
  538. case OPTION_FILENAME:
  539. case OPTION_INTEGER:
  540. case OPTION_MAGNITUDE:
  541. case OPTION_CALLBACK:
  542. if (opts->flags & PARSE_OPT_NOARG)
  543. break;
  544. if (opts->flags & PARSE_OPT_OPTARG)
  545. break;
  546. if (opts->flags & PARSE_OPT_LASTARG_DEFAULT)
  547. break;
  548. suffix = "=";
  549. break;
  550. default:
  551. break;
  552. }
  553. if (opts->flags & PARSE_OPT_COMP_ARG)
  554. suffix = "=";
  555. if (starts_with(opts->long_name, "no-"))
  556. nr_noopts++;
  557. printf(" --%s%s", opts->long_name, suffix);
  558. }
  559. show_negated_gitcomp(original_opts, -1);
  560. show_negated_gitcomp(original_opts, nr_noopts);
  561. fputc('\n', stdout);
  562. return PARSE_OPT_COMPLETE;
  563. }
  564. /*
  565. * Scan and may produce a new option[] array, which should be used
  566. * instead of the original 'options'.
  567. *
  568. * Right now this is only used to preprocess and substitue
  569. * OPTION_ALIAS.
  570. */
  571. static struct option *preprocess_options(struct parse_opt_ctx_t *ctx,
  572. const struct option *options)
  573. {
  574. struct option *newopt;
  575. int i, nr, alias;
  576. int nr_aliases = 0;
  577. for (nr = 0; options[nr].type != OPTION_END; nr++) {
  578. if (options[nr].type == OPTION_ALIAS)
  579. nr_aliases++;
  580. }
  581. if (!nr_aliases)
  582. return NULL;
  583. ALLOC_ARRAY(newopt, nr + 1);
  584. COPY_ARRAY(newopt, options, nr + 1);
  585. /* each alias has two string pointers and NULL */
  586. CALLOC_ARRAY(ctx->alias_groups, 3 * (nr_aliases + 1));
  587. for (alias = 0, i = 0; i < nr; i++) {
  588. int short_name;
  589. const char *long_name;
  590. const char *source;
  591. int j;
  592. if (newopt[i].type != OPTION_ALIAS)
  593. continue;
  594. short_name = newopt[i].short_name;
  595. long_name = newopt[i].long_name;
  596. source = newopt[i].value;
  597. if (!long_name)
  598. BUG("An alias must have long option name");
  599. for (j = 0; j < nr; j++) {
  600. const char *name = options[j].long_name;
  601. if (!name || strcmp(name, source))
  602. continue;
  603. if (options[j].type == OPTION_ALIAS)
  604. BUG("No please. Nested aliases are not supported.");
  605. /*
  606. * NEEDSWORK: this is a bit inconsistent because
  607. * usage_with_options() on the original options[] will print
  608. * help string as "alias of %s" but "git cmd -h" will
  609. * print the original help string.
  610. */
  611. memcpy(newopt + i, options + j, sizeof(*newopt));
  612. newopt[i].short_name = short_name;
  613. newopt[i].long_name = long_name;
  614. break;
  615. }
  616. if (j == nr)
  617. BUG("could not find source option '%s' of alias '%s'",
  618. source, newopt[i].long_name);
  619. ctx->alias_groups[alias * 3 + 0] = newopt[i].long_name;
  620. ctx->alias_groups[alias * 3 + 1] = options[j].long_name;
  621. ctx->alias_groups[alias * 3 + 2] = NULL;
  622. alias++;
  623. }
  624. return newopt;
  625. }
  626. static int usage_with_options_internal(struct parse_opt_ctx_t *,
  627. const char * const *,
  628. const struct option *, int, int);
  629. int parse_options_step(struct parse_opt_ctx_t *ctx,
  630. const struct option *options,
  631. const char * const usagestr[])
  632. {
  633. int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
  634. /* we must reset ->opt, unknown short option leave it dangling */
  635. ctx->opt = NULL;
  636. for (; ctx->argc; ctx->argc--, ctx->argv++) {
  637. const char *arg = ctx->argv[0];
  638. if (ctx->flags & PARSE_OPT_ONE_SHOT &&
  639. ctx->argc != ctx->total)
  640. break;
  641. if (*arg != '-' || !arg[1]) {
  642. if (parse_nodash_opt(ctx, arg, options) == 0)
  643. continue;
  644. if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
  645. return PARSE_OPT_NON_OPTION;
  646. ctx->out[ctx->cpidx++] = ctx->argv[0];
  647. continue;
  648. }
  649. /* lone -h asks for help */
  650. if (internal_help && ctx->total == 1 && !strcmp(arg + 1, "h"))
  651. goto show_usage;
  652. /* lone --git-completion-helper is asked by git-completion.bash */
  653. if (ctx->total == 1 && !strcmp(arg + 1, "-git-completion-helper"))
  654. return show_gitcomp(options);
  655. if (arg[1] != '-') {
  656. ctx->opt = arg + 1;
  657. switch (parse_short_opt(ctx, options)) {
  658. case PARSE_OPT_ERROR:
  659. return PARSE_OPT_ERROR;
  660. case PARSE_OPT_UNKNOWN:
  661. if (ctx->opt)
  662. check_typos(arg + 1, options);
  663. if (internal_help && *ctx->opt == 'h')
  664. goto show_usage;
  665. goto unknown;
  666. case PARSE_OPT_NON_OPTION:
  667. case PARSE_OPT_HELP:
  668. case PARSE_OPT_COMPLETE:
  669. BUG("parse_short_opt() cannot return these");
  670. case PARSE_OPT_DONE:
  671. break;
  672. }
  673. if (ctx->opt)
  674. check_typos(arg + 1, options);
  675. while (ctx->opt) {
  676. switch (parse_short_opt(ctx, options)) {
  677. case PARSE_OPT_ERROR:
  678. return PARSE_OPT_ERROR;
  679. case PARSE_OPT_UNKNOWN:
  680. if (internal_help && *ctx->opt == 'h')
  681. goto show_usage;
  682. /* fake a short option thing to hide the fact that we may have
  683. * started to parse aggregated stuff
  684. *
  685. * This is leaky, too bad.
  686. */
  687. ctx->argv[0] = xstrdup(ctx->opt - 1);
  688. *(char *)ctx->argv[0] = '-';
  689. goto unknown;
  690. case PARSE_OPT_NON_OPTION:
  691. case PARSE_OPT_COMPLETE:
  692. case PARSE_OPT_HELP:
  693. BUG("parse_short_opt() cannot return these");
  694. case PARSE_OPT_DONE:
  695. break;
  696. }
  697. }
  698. continue;
  699. }
  700. if (!arg[2] /* "--" */ ||
  701. !strcmp(arg + 2, "end-of-options")) {
  702. if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
  703. ctx->argc--;
  704. ctx->argv++;
  705. }
  706. break;
  707. }
  708. if (internal_help && !strcmp(arg + 2, "help-all"))
  709. return usage_with_options_internal(ctx, usagestr, options, 1, 0);
  710. if (internal_help && !strcmp(arg + 2, "help"))
  711. goto show_usage;
  712. switch (parse_long_opt(ctx, arg + 2, options)) {
  713. case PARSE_OPT_ERROR:
  714. return PARSE_OPT_ERROR;
  715. case PARSE_OPT_UNKNOWN:
  716. goto unknown;
  717. case PARSE_OPT_HELP:
  718. goto show_usage;
  719. case PARSE_OPT_NON_OPTION:
  720. case PARSE_OPT_COMPLETE:
  721. BUG("parse_long_opt() cannot return these");
  722. case PARSE_OPT_DONE:
  723. break;
  724. }
  725. continue;
  726. unknown:
  727. if (ctx->flags & PARSE_OPT_ONE_SHOT)
  728. break;
  729. if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN))
  730. return PARSE_OPT_UNKNOWN;
  731. ctx->out[ctx->cpidx++] = ctx->argv[0];
  732. ctx->opt = NULL;
  733. }
  734. return PARSE_OPT_DONE;
  735. show_usage:
  736. return usage_with_options_internal(ctx, usagestr, options, 0, 0);
  737. }
  738. int parse_options_end(struct parse_opt_ctx_t *ctx)
  739. {
  740. if (ctx->flags & PARSE_OPT_ONE_SHOT)
  741. return ctx->total - ctx->argc;
  742. MOVE_ARRAY(ctx->out + ctx->cpidx, ctx->argv, ctx->argc);
  743. ctx->out[ctx->cpidx + ctx->argc] = NULL;
  744. return ctx->cpidx + ctx->argc;
  745. }
  746. int parse_options(int argc, const char **argv, const char *prefix,
  747. const struct option *options, const char * const usagestr[],
  748. int flags)
  749. {
  750. struct parse_opt_ctx_t ctx;
  751. struct option *real_options;
  752. disallow_abbreviated_options =
  753. git_env_bool("GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS", 0);
  754. memset(&ctx, 0, sizeof(ctx));
  755. real_options = preprocess_options(&ctx, options);
  756. if (real_options)
  757. options = real_options;
  758. parse_options_start_1(&ctx, argc, argv, prefix, options, flags);
  759. switch (parse_options_step(&ctx, options, usagestr)) {
  760. case PARSE_OPT_HELP:
  761. case PARSE_OPT_ERROR:
  762. exit(129);
  763. case PARSE_OPT_COMPLETE:
  764. exit(0);
  765. case PARSE_OPT_NON_OPTION:
  766. case PARSE_OPT_DONE:
  767. break;
  768. default: /* PARSE_OPT_UNKNOWN */
  769. if (ctx.argv[0][1] == '-') {
  770. error(_("unknown option `%s'"), ctx.argv[0] + 2);
  771. } else if (isascii(*ctx.opt)) {
  772. error(_("unknown switch `%c'"), *ctx.opt);
  773. } else {
  774. error(_("unknown non-ascii option in string: `%s'"),
  775. ctx.argv[0]);
  776. }
  777. usage_with_options(usagestr, options);
  778. }
  779. precompose_argv(argc, argv);
  780. free(real_options);
  781. free(ctx.alias_groups);
  782. return parse_options_end(&ctx);
  783. }
  784. static int usage_argh(const struct option *opts, FILE *outfile)
  785. {
  786. const char *s;
  787. int literal = (opts->flags & PARSE_OPT_LITERAL_ARGHELP) ||
  788. !opts->argh || !!strpbrk(opts->argh, "()<>[]|");
  789. if (opts->flags & PARSE_OPT_OPTARG)
  790. if (opts->long_name)
  791. s = literal ? "[=%s]" : "[=<%s>]";
  792. else
  793. s = literal ? "[%s]" : "[<%s>]";
  794. else
  795. s = literal ? " %s" : " <%s>";
  796. return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("..."));
  797. }
  798. #define USAGE_OPTS_WIDTH 24
  799. #define USAGE_GAP 2
  800. static int usage_with_options_internal(struct parse_opt_ctx_t *ctx,
  801. const char * const *usagestr,
  802. const struct option *opts, int full, int err)
  803. {
  804. FILE *outfile = err ? stderr : stdout;
  805. int need_newline;
  806. if (!usagestr)
  807. return PARSE_OPT_HELP;
  808. if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
  809. fprintf(outfile, "cat <<\\EOF\n");
  810. fprintf_ln(outfile, _("usage: %s"), _(*usagestr++));
  811. while (*usagestr && **usagestr)
  812. /*
  813. * TRANSLATORS: the colon here should align with the
  814. * one in "usage: %s" translation.
  815. */
  816. fprintf_ln(outfile, _(" or: %s"), _(*usagestr++));
  817. while (*usagestr) {
  818. if (**usagestr)
  819. fprintf_ln(outfile, _(" %s"), _(*usagestr));
  820. else
  821. fputc('\n', outfile);
  822. usagestr++;
  823. }
  824. need_newline = 1;
  825. for (; opts->type != OPTION_END; opts++) {
  826. size_t pos;
  827. int pad;
  828. if (opts->type == OPTION_GROUP) {
  829. fputc('\n', outfile);
  830. need_newline = 0;
  831. if (*opts->help)
  832. fprintf(outfile, "%s\n", _(opts->help));
  833. continue;
  834. }
  835. if (!full && (opts->flags & PARSE_OPT_HIDDEN))
  836. continue;
  837. if (need_newline) {
  838. fputc('\n', outfile);
  839. need_newline = 0;
  840. }
  841. pos = fprintf(outfile, " ");
  842. if (opts->short_name) {
  843. if (opts->flags & PARSE_OPT_NODASH)
  844. pos += fprintf(outfile, "%c", opts->short_name);
  845. else
  846. pos += fprintf(outfile, "-%c", opts->short_name);
  847. }
  848. if (opts->long_name && opts->short_name)
  849. pos += fprintf(outfile, ", ");
  850. if (opts->long_name)
  851. pos += fprintf(outfile, "--%s", opts->long_name);
  852. if (opts->type == OPTION_NUMBER)
  853. pos += utf8_fprintf(outfile, _("-NUM"));
  854. if ((opts->flags & PARSE_OPT_LITERAL_ARGHELP) ||
  855. !(opts->flags & PARSE_OPT_NOARG))
  856. pos += usage_argh(opts, outfile);
  857. if (pos <= USAGE_OPTS_WIDTH)
  858. pad = USAGE_OPTS_WIDTH - pos;
  859. else {
  860. fputc('\n', outfile);
  861. pad = USAGE_OPTS_WIDTH;
  862. }
  863. if (opts->type == OPTION_ALIAS) {
  864. fprintf(outfile, "%*s", pad + USAGE_GAP, "");
  865. fprintf_ln(outfile, _("alias of --%s"),
  866. (const char *)opts->value);
  867. continue;
  868. }
  869. fprintf(outfile, "%*s%s\n", pad + USAGE_GAP, "", _(opts->help));
  870. }
  871. fputc('\n', outfile);
  872. if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
  873. fputs("EOF\n", outfile);
  874. return PARSE_OPT_HELP;
  875. }
  876. void NORETURN usage_with_options(const char * const *usagestr,
  877. const struct option *opts)
  878. {
  879. usage_with_options_internal(NULL, usagestr, opts, 0, 1);
  880. exit(129);
  881. }
  882. void NORETURN usage_msg_opt(const char *msg,
  883. const char * const *usagestr,
  884. const struct option *options)
  885. {
  886. fprintf(stderr, "fatal: %s\n\n", msg);
  887. usage_with_options(usagestr, options);
  888. }
  889. const char *optname(const struct option *opt, int flags)
  890. {
  891. static struct strbuf sb = STRBUF_INIT;
  892. strbuf_reset(&sb);
  893. if (flags & OPT_SHORT)
  894. strbuf_addf(&sb, "switch `%c'", opt->short_name);
  895. else if (flags & OPT_UNSET)
  896. strbuf_addf(&sb, "option `no-%s'", opt->long_name);
  897. else
  898. strbuf_addf(&sb, "option `%s'", opt->long_name);
  899. return sb.buf;
  900. }