OSDN Git Service

Merge branch 'ob/imap-send-ssl-verify' into maint-1.8.1
[git-core/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"
6 #include "utf8.h"
7
8 static int parse_options_usage(struct parse_opt_ctx_t *ctx,
9                                const char * const *usagestr,
10                                const struct option *opts, int err);
11
12 #define OPT_SHORT 1
13 #define OPT_UNSET 2
14
15 int optbug(const struct option *opt, const char *reason)
16 {
17         if (opt->long_name)
18                 return error("BUG: option '%s' %s", opt->long_name, reason);
19         return error("BUG: switch '%c' %s", opt->short_name, reason);
20 }
21
22 int opterror(const struct option *opt, const char *reason, int flags)
23 {
24         if (flags & OPT_SHORT)
25                 return error("switch `%c' %s", opt->short_name, reason);
26         if (flags & OPT_UNSET)
27                 return error("option `no-%s' %s", opt->long_name, reason);
28         return error("option `%s' %s", opt->long_name, reason);
29 }
30
31 static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt,
32                    int flags, const char **arg)
33 {
34         if (p->opt) {
35                 *arg = p->opt;
36                 p->opt = NULL;
37         } else if (p->argc == 1 && (opt->flags & PARSE_OPT_LASTARG_DEFAULT)) {
38                 *arg = (const char *)opt->defval;
39         } else if (p->argc > 1) {
40                 p->argc--;
41                 *arg = *++p->argv;
42         } else
43                 return opterror(opt, "requires a value", flags);
44         return 0;
45 }
46
47 static void fix_filename(const char *prefix, const char **file)
48 {
49         if (!file || !*file || !prefix || is_absolute_path(*file)
50             || !strcmp("-", *file))
51                 return;
52         *file = xstrdup(prefix_filename(prefix, strlen(prefix), *file));
53 }
54
55 static int get_value(struct parse_opt_ctx_t *p,
56                      const struct option *opt, int flags)
57 {
58         const char *s, *arg;
59         const int unset = flags & OPT_UNSET;
60         int err;
61
62         if (unset && p->opt)
63                 return opterror(opt, "takes no value", flags);
64         if (unset && (opt->flags & PARSE_OPT_NONEG))
65                 return opterror(opt, "isn't available", flags);
66         if (!(flags & OPT_SHORT) && p->opt && (opt->flags & PARSE_OPT_NOARG))
67                 return opterror(opt, "takes no value", flags);
68
69         switch (opt->type) {
70         case OPTION_LOWLEVEL_CALLBACK:
71                 return (*(parse_opt_ll_cb *)opt->callback)(p, opt, unset);
72
73         case OPTION_BIT:
74                 if (unset)
75                         *(int *)opt->value &= ~opt->defval;
76                 else
77                         *(int *)opt->value |= opt->defval;
78                 return 0;
79
80         case OPTION_NEGBIT:
81                 if (unset)
82                         *(int *)opt->value |= opt->defval;
83                 else
84                         *(int *)opt->value &= ~opt->defval;
85                 return 0;
86
87         case OPTION_COUNTUP:
88                 *(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
89                 return 0;
90
91         case OPTION_SET_INT:
92                 *(int *)opt->value = unset ? 0 : opt->defval;
93                 return 0;
94
95         case OPTION_SET_PTR:
96                 *(void **)opt->value = unset ? NULL : (void *)opt->defval;
97                 return 0;
98
99         case OPTION_STRING:
100                 if (unset)
101                         *(const char **)opt->value = NULL;
102                 else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
103                         *(const char **)opt->value = (const char *)opt->defval;
104                 else
105                         return get_arg(p, opt, flags, (const char **)opt->value);
106                 return 0;
107
108         case OPTION_FILENAME:
109                 err = 0;
110                 if (unset)
111                         *(const char **)opt->value = NULL;
112                 else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
113                         *(const char **)opt->value = (const char *)opt->defval;
114                 else
115                         err = get_arg(p, opt, flags, (const char **)opt->value);
116
117                 if (!err)
118                         fix_filename(p->prefix, (const char **)opt->value);
119                 return err;
120
121         case OPTION_CALLBACK:
122                 if (unset)
123                         return (*opt->callback)(opt, NULL, 1) ? (-1) : 0;
124                 if (opt->flags & PARSE_OPT_NOARG)
125                         return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
126                 if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
127                         return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
128                 if (get_arg(p, opt, flags, &arg))
129                         return -1;
130                 return (*opt->callback)(opt, arg, 0) ? (-1) : 0;
131
132         case OPTION_INTEGER:
133                 if (unset) {
134                         *(int *)opt->value = 0;
135                         return 0;
136                 }
137                 if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
138                         *(int *)opt->value = opt->defval;
139                         return 0;
140                 }
141                 if (get_arg(p, opt, flags, &arg))
142                         return -1;
143                 *(int *)opt->value = strtol(arg, (char **)&s, 10);
144                 if (*s)
145                         return opterror(opt, "expects a numerical value", flags);
146                 return 0;
147
148         default:
149                 die("should not happen, someone must be hit on the forehead");
150         }
151 }
152
153 static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *options)
154 {
155         const struct option *numopt = NULL;
156
157         for (; options->type != OPTION_END; options++) {
158                 if (options->short_name == *p->opt) {
159                         p->opt = p->opt[1] ? p->opt + 1 : NULL;
160                         return get_value(p, options, OPT_SHORT);
161                 }
162
163                 /*
164                  * Handle the numerical option later, explicit one-digit
165                  * options take precedence over it.
166                  */
167                 if (options->type == OPTION_NUMBER)
168                         numopt = options;
169         }
170         if (numopt && isdigit(*p->opt)) {
171                 size_t len = 1;
172                 char *arg;
173                 int rc;
174
175                 while (isdigit(p->opt[len]))
176                         len++;
177                 arg = xmemdupz(p->opt, len);
178                 p->opt = p->opt[len] ? p->opt + len : NULL;
179                 rc = (*numopt->callback)(numopt, arg, 0) ? (-1) : 0;
180                 free(arg);
181                 return rc;
182         }
183         return -2;
184 }
185
186 static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
187                           const struct option *options)
188 {
189         const char *arg_end = strchr(arg, '=');
190         const struct option *abbrev_option = NULL, *ambiguous_option = NULL;
191         int abbrev_flags = 0, ambiguous_flags = 0;
192
193         if (!arg_end)
194                 arg_end = arg + strlen(arg);
195
196         for (; options->type != OPTION_END; options++) {
197                 const char *rest, *long_name = options->long_name;
198                 int flags = 0, opt_flags = 0;
199
200                 if (!long_name)
201                         continue;
202
203 again:
204                 rest = skip_prefix(arg, long_name);
205                 if (options->type == OPTION_ARGUMENT) {
206                         if (!rest)
207                                 continue;
208                         if (*rest == '=')
209                                 return opterror(options, "takes no value", flags);
210                         if (*rest)
211                                 continue;
212                         p->out[p->cpidx++] = arg - 2;
213                         return 0;
214                 }
215                 if (!rest) {
216                         /* abbreviated? */
217                         if (!strncmp(long_name, arg, arg_end - arg)) {
218 is_abbreviated:
219                                 if (abbrev_option) {
220                                         /*
221                                          * If this is abbreviated, it is
222                                          * ambiguous. So when there is no
223                                          * exact match later, we need to
224                                          * error out.
225                                          */
226                                         ambiguous_option = abbrev_option;
227                                         ambiguous_flags = abbrev_flags;
228                                 }
229                                 if (!(flags & OPT_UNSET) && *arg_end)
230                                         p->opt = arg_end + 1;
231                                 abbrev_option = options;
232                                 abbrev_flags = flags ^ opt_flags;
233                                 continue;
234                         }
235                         /* negation allowed? */
236                         if (options->flags & PARSE_OPT_NONEG)
237                                 continue;
238                         /* negated and abbreviated very much? */
239                         if (!prefixcmp("no-", arg)) {
240                                 flags |= OPT_UNSET;
241                                 goto is_abbreviated;
242                         }
243                         /* negated? */
244                         if (prefixcmp(arg, "no-")) {
245                                 if (!prefixcmp(long_name, "no-")) {
246                                         long_name += 3;
247                                         opt_flags |= OPT_UNSET;
248                                         goto again;
249                                 }
250                                 continue;
251                         }
252                         flags |= OPT_UNSET;
253                         rest = skip_prefix(arg + 3, long_name);
254                         /* abbreviated and negated? */
255                         if (!rest && !prefixcmp(long_name, arg + 3))
256                                 goto is_abbreviated;
257                         if (!rest)
258                                 continue;
259                 }
260                 if (*rest) {
261                         if (*rest != '=')
262                                 continue;
263                         p->opt = rest + 1;
264                 }
265                 return get_value(p, options, flags ^ opt_flags);
266         }
267
268         if (ambiguous_option)
269                 return error("Ambiguous option: %s "
270                         "(could be --%s%s or --%s%s)",
271                         arg,
272                         (ambiguous_flags & OPT_UNSET) ?  "no-" : "",
273                         ambiguous_option->long_name,
274                         (abbrev_flags & OPT_UNSET) ?  "no-" : "",
275                         abbrev_option->long_name);
276         if (abbrev_option)
277                 return get_value(p, abbrev_option, abbrev_flags);
278         return -2;
279 }
280
281 static int parse_nodash_opt(struct parse_opt_ctx_t *p, const char *arg,
282                             const struct option *options)
283 {
284         for (; options->type != OPTION_END; options++) {
285                 if (!(options->flags & PARSE_OPT_NODASH))
286                         continue;
287                 if (options->short_name == arg[0] && arg[1] == '\0')
288                         return get_value(p, options, OPT_SHORT);
289         }
290         return -2;
291 }
292
293 static void check_typos(const char *arg, const struct option *options)
294 {
295         if (strlen(arg) < 3)
296                 return;
297
298         if (!prefixcmp(arg, "no-")) {
299                 error ("did you mean `--%s` (with two dashes ?)", arg);
300                 exit(129);
301         }
302
303         for (; options->type != OPTION_END; options++) {
304                 if (!options->long_name)
305                         continue;
306                 if (!prefixcmp(options->long_name, arg)) {
307                         error ("did you mean `--%s` (with two dashes ?)", arg);
308                         exit(129);
309                 }
310         }
311 }
312
313 static void parse_options_check(const struct option *opts)
314 {
315         int err = 0;
316
317         for (; opts->type != OPTION_END; opts++) {
318                 if ((opts->flags & PARSE_OPT_LASTARG_DEFAULT) &&
319                     (opts->flags & PARSE_OPT_OPTARG))
320                         err |= optbug(opts, "uses incompatible flags "
321                                         "LASTARG_DEFAULT and OPTARG");
322                 if (opts->flags & PARSE_OPT_NODASH &&
323                     ((opts->flags & PARSE_OPT_OPTARG) ||
324                      !(opts->flags & PARSE_OPT_NOARG) ||
325                      !(opts->flags & PARSE_OPT_NONEG) ||
326                      opts->long_name))
327                         err |= optbug(opts, "uses feature "
328                                         "not supported for dashless options");
329                 switch (opts->type) {
330                 case OPTION_COUNTUP:
331                 case OPTION_BIT:
332                 case OPTION_NEGBIT:
333                 case OPTION_SET_INT:
334                 case OPTION_SET_PTR:
335                 case OPTION_NUMBER:
336                         if ((opts->flags & PARSE_OPT_OPTARG) ||
337                             !(opts->flags & PARSE_OPT_NOARG))
338                                 err |= optbug(opts, "should not accept an argument");
339                 default:
340                         ; /* ok. (usually accepts an argument) */
341                 }
342         }
343         if (err)
344                 exit(128);
345 }
346
347 void parse_options_start(struct parse_opt_ctx_t *ctx,
348                          int argc, const char **argv, const char *prefix,
349                          const struct option *options, int flags)
350 {
351         memset(ctx, 0, sizeof(*ctx));
352         ctx->argc = argc - 1;
353         ctx->argv = argv + 1;
354         ctx->out  = argv;
355         ctx->prefix = prefix;
356         ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
357         ctx->flags = flags;
358         if ((flags & PARSE_OPT_KEEP_UNKNOWN) &&
359             (flags & PARSE_OPT_STOP_AT_NON_OPTION))
360                 die("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
361         parse_options_check(options);
362 }
363
364 static int usage_with_options_internal(struct parse_opt_ctx_t *,
365                                        const char * const *,
366                                        const struct option *, int, int);
367
368 int parse_options_step(struct parse_opt_ctx_t *ctx,
369                        const struct option *options,
370                        const char * const usagestr[])
371 {
372         int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
373
374         /* we must reset ->opt, unknown short option leave it dangling */
375         ctx->opt = NULL;
376
377         for (; ctx->argc; ctx->argc--, ctx->argv++) {
378                 const char *arg = ctx->argv[0];
379
380                 if (*arg != '-' || !arg[1]) {
381                         if (parse_nodash_opt(ctx, arg, options) == 0)
382                                 continue;
383                         if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
384                                 return PARSE_OPT_NON_OPTION;
385                         ctx->out[ctx->cpidx++] = ctx->argv[0];
386                         continue;
387                 }
388
389                 if (arg[1] != '-') {
390                         ctx->opt = arg + 1;
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                                 if (ctx->opt)
398                                         check_typos(arg + 1, options);
399                                 goto unknown;
400                         }
401                         if (ctx->opt)
402                                 check_typos(arg + 1, options);
403                         while (ctx->opt) {
404                                 if (internal_help && *ctx->opt == 'h')
405                                         return parse_options_usage(ctx, usagestr, options, 0);
406                                 switch (parse_short_opt(ctx, options)) {
407                                 case -1:
408                                         return parse_options_usage(ctx, usagestr, options, 1);
409                                 case -2:
410                                         /* fake a short option thing to hide the fact that we may have
411                                          * started to parse aggregated stuff
412                                          *
413                                          * This is leaky, too bad.
414                                          */
415                                         ctx->argv[0] = xstrdup(ctx->opt - 1);
416                                         *(char *)ctx->argv[0] = '-';
417                                         goto unknown;
418                                 }
419                         }
420                         continue;
421                 }
422
423                 if (!arg[2]) { /* "--" */
424                         if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
425                                 ctx->argc--;
426                                 ctx->argv++;
427                         }
428                         break;
429                 }
430
431                 if (internal_help && !strcmp(arg + 2, "help-all"))
432                         return usage_with_options_internal(ctx, usagestr, options, 1, 0);
433                 if (internal_help && !strcmp(arg + 2, "help"))
434                         return parse_options_usage(ctx, usagestr, options, 0);
435                 switch (parse_long_opt(ctx, arg + 2, options)) {
436                 case -1:
437                         return parse_options_usage(ctx, usagestr, options, 1);
438                 case -2:
439                         goto unknown;
440                 }
441                 continue;
442 unknown:
443                 if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN))
444                         return PARSE_OPT_UNKNOWN;
445                 ctx->out[ctx->cpidx++] = ctx->argv[0];
446                 ctx->opt = NULL;
447         }
448         return PARSE_OPT_DONE;
449 }
450
451 int parse_options_end(struct parse_opt_ctx_t *ctx)
452 {
453         memmove(ctx->out + ctx->cpidx, ctx->argv, ctx->argc * sizeof(*ctx->out));
454         ctx->out[ctx->cpidx + ctx->argc] = NULL;
455         return ctx->cpidx + ctx->argc;
456 }
457
458 int parse_options(int argc, const char **argv, const char *prefix,
459                   const struct option *options, const char * const usagestr[],
460                   int flags)
461 {
462         struct parse_opt_ctx_t ctx;
463
464         parse_options_start(&ctx, argc, argv, prefix, options, flags);
465         switch (parse_options_step(&ctx, options, usagestr)) {
466         case PARSE_OPT_HELP:
467                 exit(129);
468         case PARSE_OPT_NON_OPTION:
469         case PARSE_OPT_DONE:
470                 break;
471         default: /* PARSE_OPT_UNKNOWN */
472                 if (ctx.argv[0][1] == '-') {
473                         error("unknown option `%s'", ctx.argv[0] + 2);
474                 } else if (isascii(*ctx.opt)) {
475                         error("unknown switch `%c'", *ctx.opt);
476                 } else {
477                         error("unknown non-ascii option in string: `%s'",
478                               ctx.argv[0]);
479                 }
480                 usage_with_options(usagestr, options);
481         }
482
483         precompose_argv(argc, argv);
484         return parse_options_end(&ctx);
485 }
486
487 static int usage_argh(const struct option *opts, FILE *outfile)
488 {
489         const char *s;
490         int literal = (opts->flags & PARSE_OPT_LITERAL_ARGHELP) || !opts->argh;
491         if (opts->flags & PARSE_OPT_OPTARG)
492                 if (opts->long_name)
493                         s = literal ? "[=%s]" : "[=<%s>]";
494                 else
495                         s = literal ? "[%s]" : "[<%s>]";
496         else
497                 s = literal ? " %s" : " <%s>";
498         return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("..."));
499 }
500
501 #define USAGE_OPTS_WIDTH 24
502 #define USAGE_GAP         2
503
504 static int usage_with_options_internal(struct parse_opt_ctx_t *ctx,
505                                        const char * const *usagestr,
506                                        const struct option *opts, int full, int err)
507 {
508         FILE *outfile = err ? stderr : stdout;
509
510         if (!usagestr)
511                 return PARSE_OPT_HELP;
512
513         if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
514                 fprintf(outfile, "cat <<\\EOF\n");
515
516         fprintf_ln(outfile, _("usage: %s"), _(*usagestr++));
517         while (*usagestr && **usagestr)
518                 /* TRANSLATORS: the colon here should align with the
519                    one in "usage: %s" translation */
520                 fprintf_ln(outfile, _("   or: %s"), _(*usagestr++));
521         while (*usagestr) {
522                 if (**usagestr)
523                         fprintf_ln(outfile, _("    %s"), _(*usagestr));
524                 else
525                         putchar('\n');
526                 usagestr++;
527         }
528
529         if (opts->type != OPTION_GROUP)
530                 fputc('\n', outfile);
531
532         for (; opts->type != OPTION_END; opts++) {
533                 size_t pos;
534                 int pad;
535
536                 if (opts->type == OPTION_GROUP) {
537                         fputc('\n', outfile);
538                         if (*opts->help)
539                                 fprintf(outfile, "%s\n", _(opts->help));
540                         continue;
541                 }
542                 if (!full && (opts->flags & PARSE_OPT_HIDDEN))
543                         continue;
544
545                 pos = fprintf(outfile, "    ");
546                 if (opts->short_name) {
547                         if (opts->flags & PARSE_OPT_NODASH)
548                                 pos += fprintf(outfile, "%c", opts->short_name);
549                         else
550                                 pos += fprintf(outfile, "-%c", opts->short_name);
551                 }
552                 if (opts->long_name && opts->short_name)
553                         pos += fprintf(outfile, ", ");
554                 if (opts->long_name)
555                         pos += fprintf(outfile, "--%s", opts->long_name);
556                 if (opts->type == OPTION_NUMBER)
557                         pos += utf8_fprintf(outfile, _("-NUM"));
558
559                 if ((opts->flags & PARSE_OPT_LITERAL_ARGHELP) ||
560                     !(opts->flags & PARSE_OPT_NOARG))
561                         pos += usage_argh(opts, outfile);
562
563                 if (pos <= USAGE_OPTS_WIDTH)
564                         pad = USAGE_OPTS_WIDTH - pos;
565                 else {
566                         fputc('\n', outfile);
567                         pad = USAGE_OPTS_WIDTH;
568                 }
569                 fprintf(outfile, "%*s%s\n", pad + USAGE_GAP, "", _(opts->help));
570         }
571         fputc('\n', outfile);
572
573         if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
574                 fputs("EOF\n", outfile);
575
576         return PARSE_OPT_HELP;
577 }
578
579 void NORETURN usage_with_options(const char * const *usagestr,
580                         const struct option *opts)
581 {
582         usage_with_options_internal(NULL, usagestr, opts, 0, 1);
583         exit(129);
584 }
585
586 void NORETURN usage_msg_opt(const char *msg,
587                    const char * const *usagestr,
588                    const struct option *options)
589 {
590         fprintf(stderr, "%s\n\n", msg);
591         usage_with_options(usagestr, options);
592 }
593
594 static int parse_options_usage(struct parse_opt_ctx_t *ctx,
595                                const char * const *usagestr,
596                                const struct option *opts, int err)
597 {
598         return usage_with_options_internal(ctx, usagestr, opts, 0, err);
599 }
600