Code

parse-options: never suppress arghelp if LITERAL_ARGHELP is set
[git.git] / parse-options.c
1 #include "git-compat-util.h"
2 #include "parse-options.h"
3 #include "cache.h"
4 #include "commit.h"
5 #include "color.h"
7 static int parse_options_usage(struct parse_opt_ctx_t *ctx,
8                                const char * const *usagestr,
9                                const struct option *opts, int err);
11 #define OPT_SHORT 1
12 #define OPT_UNSET 2
14 static int optbug(const struct option *opt, const char *reason)
15 {
16         if (opt->long_name)
17                 return error("BUG: option '%s' %s", opt->long_name, reason);
18         return error("BUG: switch '%c' %s", opt->short_name, reason);
19 }
21 static int opterror(const struct option *opt, const char *reason, int flags)
22 {
23         if (flags & OPT_SHORT)
24                 return error("switch `%c' %s", opt->short_name, reason);
25         if (flags & OPT_UNSET)
26                 return error("option `no-%s' %s", opt->long_name, reason);
27         return error("option `%s' %s", opt->long_name, reason);
28 }
30 static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt,
31                    int flags, const char **arg)
32 {
33         if (p->opt) {
34                 *arg = p->opt;
35                 p->opt = NULL;
36         } else if (p->argc == 1 && (opt->flags & PARSE_OPT_LASTARG_DEFAULT)) {
37                 *arg = (const char *)opt->defval;
38         } else if (p->argc > 1) {
39                 p->argc--;
40                 *arg = *++p->argv;
41         } else
42                 return opterror(opt, "requires a value", flags);
43         return 0;
44 }
46 static void fix_filename(const char *prefix, const char **file)
47 {
48         if (!file || !*file || !prefix || is_absolute_path(*file)
49             || !strcmp("-", *file))
50                 return;
51         *file = xstrdup(prefix_filename(prefix, strlen(prefix), *file));
52 }
54 static int get_value(struct parse_opt_ctx_t *p,
55                      const struct option *opt, int flags)
56 {
57         const char *s, *arg;
58         const int unset = flags & OPT_UNSET;
59         int err;
61         if (unset && p->opt)
62                 return opterror(opt, "takes no value", flags);
63         if (unset && (opt->flags & PARSE_OPT_NONEG))
64                 return opterror(opt, "isn't available", flags);
65         if (!(flags & OPT_SHORT) && p->opt && (opt->flags & PARSE_OPT_NOARG))
66                 return opterror(opt, "takes no value", flags);
68         switch (opt->type) {
69         case OPTION_BIT:
70                 if (unset)
71                         *(int *)opt->value &= ~opt->defval;
72                 else
73                         *(int *)opt->value |= opt->defval;
74                 return 0;
76         case OPTION_NEGBIT:
77                 if (unset)
78                         *(int *)opt->value |= opt->defval;
79                 else
80                         *(int *)opt->value &= ~opt->defval;
81                 return 0;
83         case OPTION_BOOLEAN:
84                 *(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
85                 return 0;
87         case OPTION_SET_INT:
88                 *(int *)opt->value = unset ? 0 : opt->defval;
89                 return 0;
91         case OPTION_SET_PTR:
92                 *(void **)opt->value = unset ? NULL : (void *)opt->defval;
93                 return 0;
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;
104         case OPTION_FILENAME:
105                 err = 0;
106                 if (unset)
107                         *(const char **)opt->value = NULL;
108                 else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
109                         *(const char **)opt->value = (const char *)opt->defval;
110                 else
111                         err = get_arg(p, opt, flags, (const char **)opt->value);
113                 if (!err)
114                         fix_filename(p->prefix, (const char **)opt->value);
115                 return err;
117         case OPTION_CALLBACK:
118                 if (unset)
119                         return (*opt->callback)(opt, NULL, 1) ? (-1) : 0;
120                 if (opt->flags & PARSE_OPT_NOARG)
121                         return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
122                 if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
123                         return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
124                 if (get_arg(p, opt, flags, &arg))
125                         return -1;
126                 return (*opt->callback)(opt, arg, 0) ? (-1) : 0;
128         case OPTION_INTEGER:
129                 if (unset) {
130                         *(int *)opt->value = 0;
131                         return 0;
132                 }
133                 if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
134                         *(int *)opt->value = opt->defval;
135                         return 0;
136                 }
137                 if (get_arg(p, opt, flags, &arg))
138                         return -1;
139                 *(int *)opt->value = strtol(arg, (char **)&s, 10);
140                 if (*s)
141                         return opterror(opt, "expects a numerical value", flags);
142                 return 0;
144         default:
145                 die("should not happen, someone must be hit on the forehead");
146         }
149 static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *options)
151         const struct option *numopt = NULL;
153         for (; options->type != OPTION_END; options++) {
154                 if (options->short_name == *p->opt) {
155                         p->opt = p->opt[1] ? p->opt + 1 : NULL;
156                         return get_value(p, options, OPT_SHORT);
157                 }
159                 /*
160                  * Handle the numerical option later, explicit one-digit
161                  * options take precedence over it.
162                  */
163                 if (options->type == OPTION_NUMBER)
164                         numopt = options;
165         }
166         if (numopt && isdigit(*p->opt)) {
167                 size_t len = 1;
168                 char *arg;
169                 int rc;
171                 while (isdigit(p->opt[len]))
172                         len++;
173                 arg = xmemdupz(p->opt, len);
174                 p->opt = p->opt[len] ? p->opt + len : NULL;
175                 rc = (*numopt->callback)(numopt, arg, 0) ? (-1) : 0;
176                 free(arg);
177                 return rc;
178         }
179         return -2;
182 static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
183                           const struct option *options)
185         const char *arg_end = strchr(arg, '=');
186         const struct option *abbrev_option = NULL, *ambiguous_option = NULL;
187         int abbrev_flags = 0, ambiguous_flags = 0;
189         if (!arg_end)
190                 arg_end = arg + strlen(arg);
192         for (; options->type != OPTION_END; options++) {
193                 const char *rest;
194                 int flags = 0;
196                 if (!options->long_name)
197                         continue;
199                 rest = skip_prefix(arg, options->long_name);
200                 if (options->type == OPTION_ARGUMENT) {
201                         if (!rest)
202                                 continue;
203                         if (*rest == '=')
204                                 return opterror(options, "takes no value", flags);
205                         if (*rest)
206                                 continue;
207                         p->out[p->cpidx++] = arg - 2;
208                         return 0;
209                 }
210                 if (!rest) {
211                         /* abbreviated? */
212                         if (!strncmp(options->long_name, arg, arg_end - arg)) {
213 is_abbreviated:
214                                 if (abbrev_option) {
215                                         /*
216                                          * If this is abbreviated, it is
217                                          * ambiguous. So when there is no
218                                          * exact match later, we need to
219                                          * error out.
220                                          */
221                                         ambiguous_option = abbrev_option;
222                                         ambiguous_flags = abbrev_flags;
223                                 }
224                                 if (!(flags & OPT_UNSET) && *arg_end)
225                                         p->opt = arg_end + 1;
226                                 abbrev_option = options;
227                                 abbrev_flags = flags;
228                                 continue;
229                         }
230                         /* negation allowed? */
231                         if (options->flags & PARSE_OPT_NONEG)
232                                 continue;
233                         /* negated and abbreviated very much? */
234                         if (!prefixcmp("no-", arg)) {
235                                 flags |= OPT_UNSET;
236                                 goto is_abbreviated;
237                         }
238                         /* negated? */
239                         if (strncmp(arg, "no-", 3))
240                                 continue;
241                         flags |= OPT_UNSET;
242                         rest = skip_prefix(arg + 3, options->long_name);
243                         /* abbreviated and negated? */
244                         if (!rest && !prefixcmp(options->long_name, arg + 3))
245                                 goto is_abbreviated;
246                         if (!rest)
247                                 continue;
248                 }
249                 if (*rest) {
250                         if (*rest != '=')
251                                 continue;
252                         p->opt = rest + 1;
253                 }
254                 return get_value(p, options, flags);
255         }
257         if (ambiguous_option)
258                 return error("Ambiguous option: %s "
259                         "(could be --%s%s or --%s%s)",
260                         arg,
261                         (ambiguous_flags & OPT_UNSET) ?  "no-" : "",
262                         ambiguous_option->long_name,
263                         (abbrev_flags & OPT_UNSET) ?  "no-" : "",
264                         abbrev_option->long_name);
265         if (abbrev_option)
266                 return get_value(p, abbrev_option, abbrev_flags);
267         return -2;
270 static int parse_nodash_opt(struct parse_opt_ctx_t *p, const char *arg,
271                             const struct option *options)
273         for (; options->type != OPTION_END; options++) {
274                 if (!(options->flags & PARSE_OPT_NODASH))
275                         continue;
276                 if (options->short_name == arg[0] && arg[1] == '\0')
277                         return get_value(p, options, OPT_SHORT);
278         }
279         return -2;
282 static void check_typos(const char *arg, const struct option *options)
284         if (strlen(arg) < 3)
285                 return;
287         if (!prefixcmp(arg, "no-")) {
288                 error ("did you mean `--%s` (with two dashes ?)", arg);
289                 exit(129);
290         }
292         for (; options->type != OPTION_END; options++) {
293                 if (!options->long_name)
294                         continue;
295                 if (!prefixcmp(options->long_name, arg)) {
296                         error ("did you mean `--%s` (with two dashes ?)", arg);
297                         exit(129);
298                 }
299         }
302 static void parse_options_check(const struct option *opts)
304         int err = 0;
306         for (; opts->type != OPTION_END; opts++) {
307                 if ((opts->flags & PARSE_OPT_LASTARG_DEFAULT) &&
308                     (opts->flags & PARSE_OPT_OPTARG))
309                         err |= optbug(opts, "uses incompatible flags "
310                                         "LASTARG_DEFAULT and OPTARG");
311                 if (opts->flags & PARSE_OPT_NODASH &&
312                     ((opts->flags & PARSE_OPT_OPTARG) ||
313                      !(opts->flags & PARSE_OPT_NOARG) ||
314                      !(opts->flags & PARSE_OPT_NONEG) ||
315                      opts->long_name))
316                         err |= optbug(opts, "uses feature "
317                                         "not supported for dashless options");
318                 switch (opts->type) {
319                 case OPTION_BOOLEAN:
320                 case OPTION_BIT:
321                 case OPTION_NEGBIT:
322                 case OPTION_SET_INT:
323                 case OPTION_SET_PTR:
324                 case OPTION_NUMBER:
325                         if ((opts->flags & PARSE_OPT_OPTARG) ||
326                             !(opts->flags & PARSE_OPT_NOARG))
327                                 err |= optbug(opts, "should not accept an argument");
328                 default:
329                         ; /* ok. (usually accepts an argument) */
330                 }
331         }
332         if (err)
333                 exit(128);
336 void parse_options_start(struct parse_opt_ctx_t *ctx,
337                          int argc, const char **argv, const char *prefix,
338                          const struct option *options, int flags)
340         memset(ctx, 0, sizeof(*ctx));
341         ctx->argc = argc - 1;
342         ctx->argv = argv + 1;
343         ctx->out  = argv;
344         ctx->prefix = prefix;
345         ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
346         ctx->flags = flags;
347         if ((flags & PARSE_OPT_KEEP_UNKNOWN) &&
348             (flags & PARSE_OPT_STOP_AT_NON_OPTION))
349                 die("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
350         parse_options_check(options);
353 static int usage_with_options_internal(struct parse_opt_ctx_t *,
354                                        const char * const *,
355                                        const struct option *, int, int);
357 int parse_options_step(struct parse_opt_ctx_t *ctx,
358                        const struct option *options,
359                        const char * const usagestr[])
361         int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
363         /* we must reset ->opt, unknown short option leave it dangling */
364         ctx->opt = NULL;
366         for (; ctx->argc; ctx->argc--, ctx->argv++) {
367                 const char *arg = ctx->argv[0];
369                 if (*arg != '-' || !arg[1]) {
370                         if (parse_nodash_opt(ctx, arg, options) == 0)
371                                 continue;
372                         if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
373                                 break;
374                         ctx->out[ctx->cpidx++] = ctx->argv[0];
375                         continue;
376                 }
378                 if (arg[1] != '-') {
379                         ctx->opt = arg + 1;
380                         if (internal_help && *ctx->opt == 'h')
381                                 return parse_options_usage(ctx, usagestr, options, 0);
382                         switch (parse_short_opt(ctx, options)) {
383                         case -1:
384                                 return parse_options_usage(ctx, usagestr, options, 1);
385                         case -2:
386                                 goto unknown;
387                         }
388                         if (ctx->opt)
389                                 check_typos(arg + 1, options);
390                         while (ctx->opt) {
391                                 if (internal_help && *ctx->opt == 'h')
392                                         return parse_options_usage(ctx, usagestr, options, 0);
393                                 switch (parse_short_opt(ctx, options)) {
394                                 case -1:
395                                         return parse_options_usage(ctx, usagestr, options, 1);
396                                 case -2:
397                                         /* fake a short option thing to hide the fact that we may have
398                                          * started to parse aggregated stuff
399                                          *
400                                          * This is leaky, too bad.
401                                          */
402                                         ctx->argv[0] = xstrdup(ctx->opt - 1);
403                                         *(char *)ctx->argv[0] = '-';
404                                         goto unknown;
405                                 }
406                         }
407                         continue;
408                 }
410                 if (!arg[2]) { /* "--" */
411                         if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
412                                 ctx->argc--;
413                                 ctx->argv++;
414                         }
415                         break;
416                 }
418                 if (internal_help && !strcmp(arg + 2, "help-all"))
419                         return usage_with_options_internal(ctx, usagestr, options, 1, 0);
420                 if (internal_help && !strcmp(arg + 2, "help"))
421                         return parse_options_usage(ctx, usagestr, options, 0);
422                 switch (parse_long_opt(ctx, arg + 2, options)) {
423                 case -1:
424                         return parse_options_usage(ctx, usagestr, options, 1);
425                 case -2:
426                         goto unknown;
427                 }
428                 continue;
429 unknown:
430                 if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN))
431                         return PARSE_OPT_UNKNOWN;
432                 ctx->out[ctx->cpidx++] = ctx->argv[0];
433                 ctx->opt = NULL;
434         }
435         return PARSE_OPT_DONE;
438 int parse_options_end(struct parse_opt_ctx_t *ctx)
440         memmove(ctx->out + ctx->cpidx, ctx->argv, ctx->argc * sizeof(*ctx->out));
441         ctx->out[ctx->cpidx + ctx->argc] = NULL;
442         return ctx->cpidx + ctx->argc;
445 int parse_options(int argc, const char **argv, const char *prefix,
446                   const struct option *options, const char * const usagestr[],
447                   int flags)
449         struct parse_opt_ctx_t ctx;
451         parse_options_start(&ctx, argc, argv, prefix, options, flags);
452         switch (parse_options_step(&ctx, options, usagestr)) {
453         case PARSE_OPT_HELP:
454                 exit(129);
455         case PARSE_OPT_DONE:
456                 break;
457         default: /* PARSE_OPT_UNKNOWN */
458                 if (ctx.argv[0][1] == '-') {
459                         error("unknown option `%s'", ctx.argv[0] + 2);
460                 } else {
461                         error("unknown switch `%c'", *ctx.opt);
462                 }
463                 usage_with_options(usagestr, options);
464         }
466         return parse_options_end(&ctx);
469 static int usage_argh(const struct option *opts, FILE *outfile)
471         const char *s;
472         int literal = (opts->flags & PARSE_OPT_LITERAL_ARGHELP) || !opts->argh;
473         if (opts->flags & PARSE_OPT_OPTARG)
474                 if (opts->long_name)
475                         s = literal ? "[=%s]" : "[=<%s>]";
476                 else
477                         s = literal ? "[%s]" : "[<%s>]";
478         else
479                 s = literal ? " %s" : " <%s>";
480         return fprintf(outfile, s, opts->argh ? opts->argh : "...");
483 #define USAGE_OPTS_WIDTH 24
484 #define USAGE_GAP         2
486 static int usage_with_options_internal(struct parse_opt_ctx_t *ctx,
487                                        const char * const *usagestr,
488                                        const struct option *opts, int full, int err)
490         FILE *outfile = err ? stderr : stdout;
492         if (!usagestr)
493                 return PARSE_OPT_HELP;
495         if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
496                 fprintf(outfile, "cat <<\\EOF\n");
498         fprintf(outfile, "usage: %s\n", *usagestr++);
499         while (*usagestr && **usagestr)
500                 fprintf(outfile, "   or: %s\n", *usagestr++);
501         while (*usagestr) {
502                 fprintf(outfile, "%s%s\n",
503                                 **usagestr ? "    " : "",
504                                 *usagestr);
505                 usagestr++;
506         }
508         if (opts->type != OPTION_GROUP)
509                 fputc('\n', outfile);
511         for (; opts->type != OPTION_END; opts++) {
512                 size_t pos;
513                 int pad;
515                 if (opts->type == OPTION_GROUP) {
516                         fputc('\n', outfile);
517                         if (*opts->help)
518                                 fprintf(outfile, "%s\n", opts->help);
519                         continue;
520                 }
521                 if (!full && (opts->flags & PARSE_OPT_HIDDEN))
522                         continue;
524                 pos = fprintf(outfile, "    ");
525                 if (opts->short_name && !(opts->flags & PARSE_OPT_NEGHELP)) {
526                         if (opts->flags & PARSE_OPT_NODASH)
527                                 pos += fprintf(outfile, "%c", opts->short_name);
528                         else
529                                 pos += fprintf(outfile, "-%c", opts->short_name);
530                 }
531                 if (opts->long_name && opts->short_name)
532                         pos += fprintf(outfile, ", ");
533                 if (opts->long_name)
534                         pos += fprintf(outfile, "--%s%s",
535                                 (opts->flags & PARSE_OPT_NEGHELP) ?  "no-" : "",
536                                 opts->long_name);
537                 if (opts->type == OPTION_NUMBER)
538                         pos += fprintf(outfile, "-NUM");
540                 if ((opts->flags & PARSE_OPT_LITERAL_ARGHELP) ||
541                     !(opts->flags & PARSE_OPT_NOARG))
542                         pos += usage_argh(opts, outfile);
544                 if (pos <= USAGE_OPTS_WIDTH)
545                         pad = USAGE_OPTS_WIDTH - pos;
546                 else {
547                         fputc('\n', outfile);
548                         pad = USAGE_OPTS_WIDTH;
549                 }
550                 fprintf(outfile, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
551         }
552         fputc('\n', outfile);
554         if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
555                 fputs("EOF\n", outfile);
557         return PARSE_OPT_HELP;
560 void usage_with_options(const char * const *usagestr,
561                         const struct option *opts)
563         usage_with_options_internal(NULL, usagestr, opts, 0, 1);
564         exit(129);
567 void usage_msg_opt(const char *msg,
568                    const char * const *usagestr,
569                    const struct option *options)
571         fprintf(stderr, "%s\n\n", msg);
572         usage_with_options(usagestr, options);
575 static int parse_options_usage(struct parse_opt_ctx_t *ctx,
576                                const char * const *usagestr,
577                                const struct option *opts, int err)
579         return usage_with_options_internal(ctx, usagestr, opts, 0, err);
583 /*----- some often used options -----*/
584 #include "cache.h"
586 int parse_opt_abbrev_cb(const struct option *opt, const char *arg, int unset)
588         int v;
590         if (!arg) {
591                 v = unset ? 0 : DEFAULT_ABBREV;
592         } else {
593                 v = strtol(arg, (char **)&arg, 10);
594                 if (*arg)
595                         return opterror(opt, "expects a numerical value", 0);
596                 if (v && v < MINIMUM_ABBREV)
597                         v = MINIMUM_ABBREV;
598                 else if (v > 40)
599                         v = 40;
600         }
601         *(int *)(opt->value) = v;
602         return 0;
605 int parse_opt_approxidate_cb(const struct option *opt, const char *arg,
606                              int unset)
608         *(unsigned long *)(opt->value) = approxidate(arg);
609         return 0;
612 int parse_opt_color_flag_cb(const struct option *opt, const char *arg,
613                             int unset)
615         int value;
617         if (!arg)
618                 arg = unset ? "never" : (const char *)opt->defval;
619         value = git_config_colorbool(NULL, arg, -1);
620         if (value < 0)
621                 return opterror(opt,
622                         "expects \"always\", \"auto\", or \"never\"", 0);
623         *(int *)opt->value = value;
624         return 0;
627 int parse_opt_verbosity_cb(const struct option *opt, const char *arg,
628                            int unset)
630         int *target = opt->value;
632         if (unset)
633                 /* --no-quiet, --no-verbose */
634                 *target = 0;
635         else if (opt->short_name == 'v') {
636                 if (*target >= 0)
637                         (*target)++;
638                 else
639                         *target = 1;
640         } else {
641                 if (*target <= 0)
642                         (*target)--;
643                 else
644                         *target = -1;
645         }
646         return 0;
649 int parse_opt_with_commit(const struct option *opt, const char *arg, int unset)
651         unsigned char sha1[20];
652         struct commit *commit;
654         if (!arg)
655                 return -1;
656         if (get_sha1(arg, sha1))
657                 return error("malformed object name %s", arg);
658         commit = lookup_commit_reference(sha1);
659         if (!commit)
660                 return error("no such commit %s", arg);
661         commit_list_insert(commit, opt->value);
662         return 0;
665 int parse_opt_tertiary(const struct option *opt, const char *arg, int unset)
667         int *target = opt->value;
668         *target = unset ? 2 : 1;
669         return 0;
672 int parse_options_concat(struct option *dst, size_t dst_size, struct option *src)
674         int i, j;
676         for (i = 0; i < dst_size; i++)
677                 if (dst[i].type == OPTION_END)
678                         break;
679         for (j = 0; i < dst_size; i++, j++) {
680                 dst[i] = src[j];
681                 if (src[j].type == OPTION_END)
682                         return 0;
683         }
684         return -1;