Coverage Report

Created: 2025-12-31 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/git/parse-options.c
Line
Count
Source
1
#include "git-compat-util.h"
2
#include "parse-options.h"
3
#include "abspath.h"
4
#include "parse.h"
5
#include "gettext.h"
6
#include "strbuf.h"
7
#include "string-list.h"
8
#include "utf8.h"
9
10
static int disallow_abbreviated_options;
11
12
enum opt_parsed {
13
  OPT_LONG  = 0,
14
  OPT_SHORT = 1<<0,
15
  OPT_UNSET = 1<<1,
16
};
17
18
static void optbug(const struct option *opt, const char *reason)
19
0
{
20
0
  if (opt->long_name && opt->short_name)
21
0
    bug("switch '%c' (--%s) %s", opt->short_name,
22
0
        opt->long_name, reason);
23
0
  else if (opt->long_name)
24
0
    bug("option '%s' %s", opt->long_name, reason);
25
0
  else
26
0
    bug("switch '%c' %s", opt->short_name, reason);
27
0
}
28
29
static const char *optname(const struct option *opt, enum opt_parsed flags)
30
0
{
31
0
  static struct strbuf sb = STRBUF_INIT;
32
33
0
  strbuf_reset(&sb);
34
0
  if (flags & OPT_SHORT)
35
0
    strbuf_addf(&sb, "switch `%c'", opt->short_name);
36
0
  else if (flags & OPT_UNSET)
37
0
    strbuf_addf(&sb, "option `no-%s'", opt->long_name);
38
0
  else if (flags == OPT_LONG)
39
0
    strbuf_addf(&sb, "option `%s'", opt->long_name);
40
0
  else
41
0
    BUG("optname() got unknown flags %d", flags);
42
43
0
  return sb.buf;
44
0
}
45
46
static enum parse_opt_result get_arg(struct parse_opt_ctx_t *p,
47
             const struct option *opt,
48
             enum opt_parsed flags, const char **arg)
49
0
{
50
0
  if (p->opt) {
51
0
    *arg = p->opt;
52
0
    p->opt = NULL;
53
0
  } else if (p->argc == 1 && (opt->flags & PARSE_OPT_LASTARG_DEFAULT)) {
54
0
    *arg = (const char *)opt->defval;
55
0
  } else if (p->argc > 1) {
56
0
    p->argc--;
57
0
    *arg = *++p->argv;
58
0
  } else
59
0
    return error(_("%s requires a value"), optname(opt, flags));
60
0
  return 0;
61
0
}
62
63
static char *fix_filename(const char *prefix, const char *file)
64
0
{
65
0
  if (!file || !*file)
66
0
    return NULL;
67
0
  else
68
0
    return prefix_filename_except_for_dash(prefix, file);
69
0
}
70
71
static int do_get_int_value(const void *value, size_t precision, intmax_t *ret)
72
0
{
73
0
  switch (precision) {
74
0
  case sizeof(int8_t):
75
0
    *ret = *(int8_t *)value;
76
0
    return 0;
77
0
  case sizeof(int16_t):
78
0
    *ret = *(int16_t *)value;
79
0
    return 0;
80
0
  case sizeof(int32_t):
81
0
    *ret = *(int32_t *)value;
82
0
    return 0;
83
0
  case sizeof(int64_t):
84
0
    *ret = *(int64_t *)value;
85
0
    return 0;
86
0
  default:
87
0
    return -1;
88
0
  }
89
0
}
90
91
static intmax_t get_int_value(const struct option *opt, enum opt_parsed flags)
92
0
{
93
0
  intmax_t ret;
94
0
  if (do_get_int_value(opt->value, opt->precision, &ret))
95
0
    BUG("invalid precision for option %s", optname(opt, flags));
96
0
  return ret;
97
0
}
98
99
static enum parse_opt_result set_int_value(const struct option *opt,
100
             enum opt_parsed flags,
101
             intmax_t value)
102
0
{
103
0
  switch (opt->precision) {
104
0
  case sizeof(int8_t):
105
0
    *(int8_t *)opt->value = value;
106
0
    return 0;
107
0
  case sizeof(int16_t):
108
0
    *(int16_t *)opt->value = value;
109
0
    return 0;
110
0
  case sizeof(int32_t):
111
0
    *(int32_t *)opt->value = value;
112
0
    return 0;
113
0
  case sizeof(int64_t):
114
0
    *(int64_t *)opt->value = value;
115
0
    return 0;
116
0
  default:
117
0
    BUG("invalid precision for option %s", optname(opt, flags));
118
0
  }
119
0
}
120
121
static int signed_int_fits(intmax_t value, size_t precision)
122
0
{
123
0
  size_t bits = precision * CHAR_BIT;
124
0
  intmax_t upper_bound = INTMAX_MAX >> (bitsizeof(intmax_t) - bits);
125
0
  intmax_t lower_bound = -upper_bound - 1;
126
0
  return lower_bound <= value && value <= upper_bound;
127
0
}
128
129
static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
130
            const struct option *opt,
131
            enum opt_parsed flags,
132
            const char **argp)
133
0
{
134
0
  const char *arg;
135
0
  const int unset = flags & OPT_UNSET;
136
137
0
  if (unset && p->opt)
138
0
    return error(_("%s takes no value"), optname(opt, flags));
139
0
  if (unset && (opt->flags & PARSE_OPT_NONEG))
140
0
    return error(_("%s isn't available"), optname(opt, flags));
141
0
  if (!(flags & OPT_SHORT) && p->opt && (opt->flags & PARSE_OPT_NOARG))
142
0
    return error(_("%s takes no value"), optname(opt, flags));
143
144
0
  switch (opt->type) {
145
0
  case OPTION_LOWLEVEL_CALLBACK:
146
0
    return opt->ll_callback(p, opt, NULL, unset);
147
148
0
  case OPTION_BIT:
149
0
  {
150
0
    intmax_t value = get_int_value(opt, flags);
151
0
    if (unset)
152
0
      value &= ~opt->defval;
153
0
    else
154
0
      value |= opt->defval;
155
0
    return set_int_value(opt, flags, value);
156
0
  }
157
158
0
  case OPTION_NEGBIT:
159
0
  {
160
0
    intmax_t value = get_int_value(opt, flags);
161
0
    if (unset)
162
0
      value |= opt->defval;
163
0
    else
164
0
      value &= ~opt->defval;
165
0
    return set_int_value(opt, flags, value);
166
0
  }
167
168
0
  case OPTION_BITOP:
169
0
  {
170
0
    intmax_t value = get_int_value(opt, flags);
171
0
    if (unset)
172
0
      BUG("BITOP can't have unset form");
173
0
    value &= ~opt->extra;
174
0
    value |= opt->defval;
175
0
    return set_int_value(opt, flags, value);
176
0
  }
177
178
0
  case OPTION_COUNTUP:
179
0
  {
180
0
    size_t bits = CHAR_BIT * opt->precision;
181
0
    intmax_t upper_bound = INTMAX_MAX >> (bitsizeof(intmax_t) - bits);
182
0
    intmax_t value = get_int_value(opt, flags);
183
184
0
    if (value < 0)
185
0
      value = 0;
186
0
    if (unset)
187
0
      value = 0;
188
0
    else if (value < upper_bound)
189
0
      value++;
190
0
    else
191
0
      return error(_("value for %s exceeds %"PRIdMAX),
192
0
             optname(opt, flags), upper_bound);
193
0
    return set_int_value(opt, flags, value);
194
0
  }
195
196
0
  case OPTION_SET_INT:
197
0
    return set_int_value(opt, flags, unset ? 0 : opt->defval);
198
199
0
  case OPTION_STRING:
200
0
    if (unset)
201
0
      *(const char **)opt->value = NULL;
202
0
    else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
203
0
      *(const char **)opt->value = (const char *)opt->defval;
204
0
    else
205
0
      return get_arg(p, opt, flags, (const char **)opt->value);
206
0
    return 0;
207
208
0
  case OPTION_FILENAME:
209
0
  {
210
0
    const char *value;
211
0
    bool is_optional;
212
213
0
    if (unset)
214
0
      value = NULL;
215
0
    else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
216
0
      value = (const char *)opt->defval;
217
0
    else {
218
0
      int err = get_arg(p, opt, flags, &value);
219
0
      if (err)
220
0
        return err;
221
0
    }
222
0
    if (!value)
223
0
      return 0;
224
225
0
    is_optional = skip_prefix(value, ":(optional)", &value);
226
0
    value = fix_filename(p->prefix, value);
227
0
    if (is_optional && is_missing_file(value)) {
228
0
      free((char *)value);
229
0
    } else {
230
0
      FREE_AND_NULL(*(char **)opt->value);
231
0
      *(const char **)opt->value = value;
232
0
    }
233
0
    return 0;
234
0
  }
235
0
  case OPTION_CALLBACK:
236
0
  {
237
0
    const char *p_arg = NULL;
238
0
    int p_unset;
239
240
0
    if (unset)
241
0
      p_unset = 1;
242
0
    else if (opt->flags & PARSE_OPT_NOARG)
243
0
      p_unset = 0;
244
0
    else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
245
0
      p_unset = 0;
246
0
    else if (get_arg(p, opt, flags, &arg))
247
0
      return -1;
248
0
    else {
249
0
      p_unset = 0;
250
0
      p_arg = arg;
251
0
    }
252
0
    if (opt->flags & PARSE_OPT_CMDMODE)
253
0
      *argp = p_arg;
254
0
    if (opt->callback)
255
0
      return (*opt->callback)(opt, p_arg, p_unset) ? (-1) : 0;
256
0
    else
257
0
      return (*opt->ll_callback)(p, opt, p_arg, p_unset);
258
0
  }
259
0
  case OPTION_INTEGER:
260
0
  {
261
0
    intmax_t upper_bound = INTMAX_MAX >> (bitsizeof(intmax_t) - CHAR_BIT * opt->precision);
262
0
    intmax_t lower_bound = -upper_bound - 1;
263
0
    intmax_t value;
264
265
0
    if (unset) {
266
0
      value = 0;
267
0
    } else if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
268
0
      value = opt->defval;
269
0
    } else if (get_arg(p, opt, flags, &arg)) {
270
0
      return -1;
271
0
    } else if (!*arg) {
272
0
      return error(_("%s expects a numerical value"),
273
0
             optname(opt, flags));
274
0
    } else if (!git_parse_signed(arg, &value, upper_bound)) {
275
0
      if (errno == ERANGE)
276
0
        return error(_("value %s for %s not in range [%"PRIdMAX",%"PRIdMAX"]"),
277
0
               arg, optname(opt, flags), lower_bound, upper_bound);
278
279
0
      return error(_("%s expects an integer value with an optional k/m/g suffix"),
280
0
             optname(opt, flags));
281
0
    }
282
283
0
    if (value < lower_bound)
284
0
      return error(_("value %s for %s not in range [%"PRIdMAX",%"PRIdMAX"]"),
285
0
             arg, optname(opt, flags), (intmax_t)lower_bound, (intmax_t)upper_bound);
286
287
0
    return set_int_value(opt, flags, value);
288
0
  }
289
0
  case OPTION_UNSIGNED:
290
0
  {
291
0
    uintmax_t upper_bound = UINTMAX_MAX >> (bitsizeof(uintmax_t) - CHAR_BIT * opt->precision);
292
0
    uintmax_t value;
293
294
0
    if (unset) {
295
0
      value = 0;
296
0
    } else if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
297
0
      value = opt->defval;
298
0
    } else if (get_arg(p, opt, flags, &arg)) {
299
0
      return -1;
300
0
    } else if (!*arg) {
301
0
      return error(_("%s expects a numerical value"),
302
0
             optname(opt, flags));
303
0
    } else if (!git_parse_unsigned(arg, &value, upper_bound)) {
304
0
      if (errno == ERANGE)
305
0
        return error(_("value %s for %s not in range [%"PRIdMAX",%"PRIdMAX"]"),
306
0
               arg, optname(opt, flags), (uintmax_t) 0, upper_bound);
307
308
0
      return error(_("%s expects a non-negative integer value"
309
0
               " with an optional k/m/g suffix"),
310
0
             optname(opt, flags));
311
0
    }
312
313
0
    switch (opt->precision) {
314
0
    case 1:
315
0
      *(uint8_t *)opt->value = value;
316
0
      return 0;
317
0
    case 2:
318
0
      *(uint16_t *)opt->value = value;
319
0
      return 0;
320
0
    case 4:
321
0
      *(uint32_t *)opt->value = value;
322
0
      return 0;
323
0
    case 8:
324
0
      *(uint64_t *)opt->value = value;
325
0
      return 0;
326
0
    default:
327
0
      BUG("invalid precision for option %s",
328
0
          optname(opt, flags));
329
0
    }
330
0
  }
331
332
0
  default:
333
0
    BUG("opt->type %d should not happen", opt->type);
334
0
  }
335
0
}
336
337
struct parse_opt_cmdmode_list {
338
  intmax_t value;
339
  void *value_ptr;
340
  size_t precision;
341
  const struct option *opt;
342
  const char *arg;
343
  enum opt_parsed flags;
344
  struct parse_opt_cmdmode_list *next;
345
};
346
347
static void build_cmdmode_list(struct parse_opt_ctx_t *ctx,
348
             const struct option *opts)
349
0
{
350
0
  ctx->cmdmode_list = NULL;
351
352
0
  for (; opts->type != OPTION_END; opts++) {
353
0
    struct parse_opt_cmdmode_list *elem = ctx->cmdmode_list;
354
0
    void *value_ptr = opts->value;
355
356
0
    if (!(opts->flags & PARSE_OPT_CMDMODE) || !value_ptr)
357
0
      continue;
358
359
0
    while (elem && elem->value_ptr != value_ptr)
360
0
      elem = elem->next;
361
0
    if (elem)
362
0
      continue;
363
364
0
    CALLOC_ARRAY(elem, 1);
365
0
    elem->value_ptr = value_ptr;
366
0
    elem->precision = opts->precision;
367
0
    if (do_get_int_value(value_ptr, opts->precision, &elem->value))
368
0
      optbug(opts, "has invalid precision");
369
0
    elem->next = ctx->cmdmode_list;
370
0
    ctx->cmdmode_list = elem;
371
0
  }
372
0
  BUG_if_bug("invalid 'struct option'");
373
0
}
374
375
static char *optnamearg(const struct option *opt, const char *arg,
376
      enum opt_parsed flags)
377
0
{
378
0
  if (flags & OPT_SHORT)
379
0
    return xstrfmt("-%c%s", opt->short_name, arg ? arg : "");
380
0
  return xstrfmt("--%s%s%s%s", flags & OPT_UNSET ? "no-" : "",
381
0
           opt->long_name, arg ? "=" : "", arg ? arg : "");
382
0
}
383
384
static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
385
               const struct option *opt,
386
               enum opt_parsed flags)
387
0
{
388
0
  const char *arg = NULL;
389
0
  enum parse_opt_result result = do_get_value(p, opt, flags, &arg);
390
0
  struct parse_opt_cmdmode_list *elem = p->cmdmode_list;
391
0
  char *opt_name, *other_opt_name;
392
393
0
  for (; elem; elem = elem->next) {
394
0
    intmax_t new_value;
395
396
0
    if (do_get_int_value(elem->value_ptr, elem->precision,
397
0
             &new_value))
398
0
      BUG("impossible: invalid precision");
399
400
0
    if (new_value == elem->value)
401
0
      continue;
402
403
0
    if (elem->opt &&
404
0
        (elem->opt->flags | opt->flags) & PARSE_OPT_CMDMODE)
405
0
      break;
406
407
0
    elem->opt = opt;
408
0
    elem->arg = arg;
409
0
    elem->flags = flags;
410
0
    elem->value = new_value;
411
0
  }
412
413
0
  if (result || !elem)
414
0
    return result;
415
416
0
  opt_name = optnamearg(opt, arg, flags);
417
0
  other_opt_name = optnamearg(elem->opt, elem->arg, elem->flags);
418
0
  error(_("options '%s' and '%s' cannot be used together"),
419
0
        opt_name, other_opt_name);
420
0
  free(opt_name);
421
0
  free(other_opt_name);
422
0
  return -1;
423
0
}
424
425
static enum parse_opt_result parse_short_opt(struct parse_opt_ctx_t *p,
426
               const struct option *options)
427
0
{
428
0
  const struct option *numopt = NULL;
429
430
0
  for (; options->type != OPTION_END; options++) {
431
0
    if (options->short_name == *p->opt) {
432
0
      p->opt = p->opt[1] ? p->opt + 1 : NULL;
433
0
      return get_value(p, options, OPT_SHORT);
434
0
    }
435
436
    /*
437
     * Handle the numerical option later, explicit one-digit
438
     * options take precedence over it.
439
     */
440
0
    if (options->type == OPTION_NUMBER)
441
0
      numopt = options;
442
0
  }
443
0
  if (numopt && isdigit(*p->opt)) {
444
0
    size_t len = 1;
445
0
    char *arg;
446
0
    int rc;
447
448
0
    while (isdigit(p->opt[len]))
449
0
      len++;
450
0
    arg = xmemdupz(p->opt, len);
451
0
    p->opt = p->opt[len] ? p->opt + len : NULL;
452
0
    if (numopt->callback)
453
0
      rc = (*numopt->callback)(numopt, arg, 0) ? (-1) : 0;
454
0
    else
455
0
      rc = (*numopt->ll_callback)(p, numopt, arg, 0);
456
0
    free(arg);
457
0
    return rc;
458
0
  }
459
0
  return PARSE_OPT_UNKNOWN;
460
0
}
461
462
static int has_string(const char *it, const char **array)
463
0
{
464
0
  while (*array)
465
0
    if (!strcmp(it, *(array++)))
466
0
      return 1;
467
0
  return 0;
468
0
}
469
470
static int is_alias(struct parse_opt_ctx_t *ctx,
471
        const struct option *one_opt,
472
        const struct option *another_opt)
473
0
{
474
0
  const char **group;
475
476
0
  if (!ctx->alias_groups)
477
0
    return 0;
478
479
0
  if (!one_opt->long_name || !another_opt->long_name)
480
0
    return 0;
481
482
0
  for (group = ctx->alias_groups; *group; group += 3) {
483
    /* it and other are from the same family? */
484
0
    if (has_string(one_opt->long_name, group) &&
485
0
        has_string(another_opt->long_name, group))
486
0
      return 1;
487
0
  }
488
0
  return 0;
489
0
}
490
491
struct parsed_option {
492
  const struct option *option;
493
  enum opt_parsed flags;
494
};
495
496
static void register_abbrev(struct parse_opt_ctx_t *p,
497
          const struct option *option, enum opt_parsed flags,
498
          struct parsed_option *abbrev,
499
          struct parsed_option *ambiguous)
500
0
{
501
0
  if (p->flags & PARSE_OPT_KEEP_UNKNOWN_OPT)
502
0
    return;
503
0
  if (abbrev->option &&
504
0
      !(abbrev->flags == flags && is_alias(p, abbrev->option, option))) {
505
    /*
506
     * If this is abbreviated, it is
507
     * ambiguous. So when there is no
508
     * exact match later, we need to
509
     * error out.
510
     */
511
0
    ambiguous->option = abbrev->option;
512
0
    ambiguous->flags = abbrev->flags;
513
0
  }
514
0
  abbrev->option = option;
515
0
  abbrev->flags = flags;
516
0
}
517
518
static enum parse_opt_result parse_long_opt(
519
  struct parse_opt_ctx_t *p, const char *arg,
520
  const struct option *options)
521
0
{
522
0
  const char *arg_end = strchrnul(arg, '=');
523
0
  const char *arg_start = arg;
524
0
  enum opt_parsed flags = OPT_LONG;
525
0
  int arg_starts_with_no_no = 0;
526
0
  struct parsed_option abbrev = { .option = NULL, .flags = OPT_LONG };
527
0
  struct parsed_option ambiguous = { .option = NULL, .flags = OPT_LONG };
528
529
0
  if (skip_prefix(arg_start, "no-", &arg_start)) {
530
0
    if (skip_prefix(arg_start, "no-", &arg_start))
531
0
      arg_starts_with_no_no = 1;
532
0
    else
533
0
      flags |= OPT_UNSET;
534
0
  }
535
536
0
  for (; options->type != OPTION_END; options++) {
537
0
    const char *rest, *long_name = options->long_name;
538
0
    enum opt_parsed opt_flags = OPT_LONG;
539
0
    int allow_unset = !(options->flags & PARSE_OPT_NONEG);
540
541
0
    if (options->type == OPTION_SUBCOMMAND)
542
0
      continue;
543
0
    if (!long_name)
544
0
      continue;
545
546
0
    if (skip_prefix(long_name, "no-", &long_name))
547
0
      opt_flags |= OPT_UNSET;
548
0
    else if (arg_starts_with_no_no)
549
0
      continue;
550
551
0
    if (((flags ^ opt_flags) & OPT_UNSET) && !allow_unset)
552
0
      continue;
553
554
0
    if (skip_prefix(arg_start, long_name, &rest)) {
555
0
      if (*rest == '=')
556
0
        p->opt = rest + 1;
557
0
      else if (*rest)
558
0
        continue;
559
0
      return get_value(p, options, flags ^ opt_flags);
560
0
    }
561
562
    /* abbreviated? */
563
0
    if (!strncmp(long_name, arg_start, arg_end - arg_start))
564
0
      register_abbrev(p, options, flags ^ opt_flags,
565
0
          &abbrev, &ambiguous);
566
567
    /* negated and abbreviated very much? */
568
0
    if (allow_unset && starts_with("no-", arg))
569
0
      register_abbrev(p, options, OPT_UNSET ^ opt_flags,
570
0
          &abbrev, &ambiguous);
571
0
  }
572
573
0
  if (disallow_abbreviated_options && (ambiguous.option || abbrev.option))
574
0
    die("disallowed abbreviated or ambiguous option '%.*s'",
575
0
        (int)(arg_end - arg), arg);
576
577
0
  if (ambiguous.option) {
578
0
    error(_("ambiguous option: %s "
579
0
      "(could be --%s%s or --%s%s)"),
580
0
      arg,
581
0
      (ambiguous.flags & OPT_UNSET) ?  "no-" : "",
582
0
      ambiguous.option->long_name,
583
0
      (abbrev.flags & OPT_UNSET) ?  "no-" : "",
584
0
      abbrev.option->long_name);
585
0
    return PARSE_OPT_HELP;
586
0
  }
587
0
  if (abbrev.option) {
588
0
    if (*arg_end)
589
0
      p->opt = arg_end + 1;
590
0
    return get_value(p, abbrev.option, abbrev.flags);
591
0
  }
592
0
  return PARSE_OPT_UNKNOWN;
593
0
}
594
595
static enum parse_opt_result parse_nodash_opt(struct parse_opt_ctx_t *p,
596
                const char *arg,
597
                const struct option *options)
598
0
{
599
0
  for (; options->type != OPTION_END; options++) {
600
0
    if (!(options->flags & PARSE_OPT_NODASH))
601
0
      continue;
602
0
    if (options->short_name == arg[0] && arg[1] == '\0')
603
0
      return get_value(p, options, OPT_SHORT);
604
0
  }
605
0
  return PARSE_OPT_ERROR;
606
0
}
607
608
static enum parse_opt_result parse_subcommand(const char *arg,
609
                const struct option *options)
610
0
{
611
0
  for (; options->type != OPTION_END; options++)
612
0
    if (options->type == OPTION_SUBCOMMAND &&
613
0
        !strcmp(options->long_name, arg)) {
614
0
      *(parse_opt_subcommand_fn **)options->value = options->subcommand_fn;
615
0
      return PARSE_OPT_SUBCOMMAND;
616
0
    }
617
618
0
  return PARSE_OPT_UNKNOWN;
619
0
}
620
621
static void check_typos(const char *arg, const struct option *options)
622
0
{
623
0
  if (strlen(arg) < 3)
624
0
    return;
625
626
0
  if (starts_with(arg, "no-")) {
627
0
    error(_("did you mean `--%s` (with two dashes)?"), arg);
628
0
    exit(129);
629
0
  }
630
631
0
  for (; options->type != OPTION_END; options++) {
632
0
    if (!options->long_name)
633
0
      continue;
634
0
    if (starts_with(options->long_name, arg)) {
635
0
      error(_("did you mean `--%s` (with two dashes)?"), arg);
636
0
      exit(129);
637
0
    }
638
0
  }
639
0
}
640
641
static void parse_options_check(const struct option *opts)
642
0
{
643
0
  char short_opts[128];
644
0
  void *subcommand_value = NULL;
645
646
0
  memset(short_opts, '\0', sizeof(short_opts));
647
0
  for (; opts->type != OPTION_END; opts++) {
648
0
    if ((opts->flags & PARSE_OPT_LASTARG_DEFAULT) &&
649
0
        (opts->flags & PARSE_OPT_OPTARG))
650
0
      optbug(opts, "uses incompatible flags "
651
0
             "LASTARG_DEFAULT and OPTARG");
652
0
    if (opts->short_name) {
653
0
      if (0x7F <= opts->short_name)
654
0
        optbug(opts, "invalid short name");
655
0
      else if (short_opts[opts->short_name]++)
656
0
        optbug(opts, "short name already used");
657
0
    }
658
0
    if (opts->flags & PARSE_OPT_NODASH &&
659
0
        ((opts->flags & PARSE_OPT_OPTARG) ||
660
0
         !(opts->flags & PARSE_OPT_NOARG) ||
661
0
         !(opts->flags & PARSE_OPT_NONEG) ||
662
0
         opts->long_name))
663
0
      optbug(opts, "uses feature "
664
0
             "not supported for dashless options");
665
0
    if (opts->type == OPTION_SET_INT && !opts->defval &&
666
0
        opts->long_name && !(opts->flags & PARSE_OPT_NONEG))
667
0
      optbug(opts, "OPTION_SET_INT 0 should not be negatable");
668
0
    switch (opts->type) {
669
0
    case OPTION_SET_INT:
670
0
    case OPTION_BIT:
671
0
    case OPTION_NEGBIT:
672
0
    case OPTION_BITOP:
673
0
    case OPTION_COUNTUP:
674
0
      if (!signed_int_fits(opts->defval, opts->precision))
675
0
        optbug(opts, "has invalid defval");
676
      /* fallthru */
677
0
    case OPTION_NUMBER:
678
0
      if ((opts->flags & PARSE_OPT_OPTARG) ||
679
0
          !(opts->flags & PARSE_OPT_NOARG))
680
0
        optbug(opts, "should not accept an argument");
681
0
      break;
682
0
    case OPTION_CALLBACK:
683
0
      if (!opts->callback && !opts->ll_callback)
684
0
        optbug(opts, "OPTION_CALLBACK needs one callback");
685
0
      else if (opts->callback && opts->ll_callback)
686
0
        optbug(opts, "OPTION_CALLBACK can't have two callbacks");
687
0
      break;
688
0
    case OPTION_LOWLEVEL_CALLBACK:
689
0
      if (!opts->ll_callback)
690
0
        optbug(opts, "OPTION_LOWLEVEL_CALLBACK needs a callback");
691
0
      if (opts->callback)
692
0
        optbug(opts, "OPTION_LOWLEVEL_CALLBACK needs no high level callback");
693
0
      break;
694
0
    case OPTION_ALIAS:
695
0
      optbug(opts, "OPT_ALIAS() should not remain at this point. "
696
0
             "Are you using parse_options_step() directly?\n"
697
0
             "That case is not supported yet.");
698
0
      break;
699
0
    case OPTION_SUBCOMMAND:
700
0
      if (!opts->value || !opts->subcommand_fn)
701
0
        optbug(opts, "OPTION_SUBCOMMAND needs a value and a subcommand function");
702
0
      if (!subcommand_value)
703
0
        subcommand_value = opts->value;
704
0
      else if (subcommand_value != opts->value)
705
0
        optbug(opts, "all OPTION_SUBCOMMANDs need the same value");
706
0
      break;
707
0
    default:
708
0
      ; /* ok. (usually accepts an argument) */
709
0
    }
710
0
    if (opts->argh &&
711
0
        strcspn(opts->argh, " _") != strlen(opts->argh))
712
0
      optbug(opts, "multi-word argh should use dash to separate words");
713
0
  }
714
0
  BUG_if_bug("invalid 'struct option'");
715
0
}
716
717
static int has_subcommands(const struct option *options)
718
0
{
719
0
  for (; options->type != OPTION_END; options++)
720
0
    if (options->type == OPTION_SUBCOMMAND)
721
0
      return 1;
722
0
  return 0;
723
0
}
724
725
static void parse_options_start_1(struct parse_opt_ctx_t *ctx,
726
          int argc, const char **argv, const char *prefix,
727
          const struct option *options,
728
          enum parse_opt_flags flags)
729
0
{
730
0
  ctx->argc = argc;
731
0
  ctx->argv = argv;
732
0
  if (!(flags & PARSE_OPT_ONE_SHOT)) {
733
0
    ctx->argc--;
734
0
    ctx->argv++;
735
0
  }
736
0
  ctx->total = ctx->argc;
737
0
  ctx->out   = argv;
738
0
  ctx->prefix = prefix;
739
0
  ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
740
0
  ctx->flags = flags;
741
0
  ctx->has_subcommands = has_subcommands(options);
742
0
  if (!ctx->has_subcommands && (flags & PARSE_OPT_SUBCOMMAND_OPTIONAL))
743
0
    BUG("Using PARSE_OPT_SUBCOMMAND_OPTIONAL without subcommands");
744
0
  if (ctx->has_subcommands) {
745
0
    if (flags & PARSE_OPT_STOP_AT_NON_OPTION)
746
0
      BUG("subcommands are incompatible with PARSE_OPT_STOP_AT_NON_OPTION");
747
0
    if (!(flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)) {
748
0
      if (flags & PARSE_OPT_KEEP_UNKNOWN_OPT)
749
0
        BUG("subcommands are incompatible with PARSE_OPT_KEEP_UNKNOWN_OPT unless in combination with PARSE_OPT_SUBCOMMAND_OPTIONAL");
750
0
      if (flags & PARSE_OPT_KEEP_DASHDASH)
751
0
        BUG("subcommands are incompatible with PARSE_OPT_KEEP_DASHDASH unless in combination with PARSE_OPT_SUBCOMMAND_OPTIONAL");
752
0
    }
753
0
  }
754
0
  if ((flags & PARSE_OPT_KEEP_UNKNOWN_OPT) &&
755
0
      (flags & PARSE_OPT_STOP_AT_NON_OPTION) &&
756
0
      !(flags & PARSE_OPT_ONE_SHOT))
757
0
    BUG("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
758
0
  if ((flags & PARSE_OPT_ONE_SHOT) &&
759
0
      (flags & PARSE_OPT_KEEP_ARGV0))
760
0
    BUG("Can't keep argv0 if you don't have it");
761
0
  parse_options_check(options);
762
0
  build_cmdmode_list(ctx, options);
763
0
}
764
765
void parse_options_start(struct parse_opt_ctx_t *ctx,
766
       int argc, const char **argv, const char *prefix,
767
       const struct option *options,
768
       enum parse_opt_flags flags)
769
0
{
770
0
  memset(ctx, 0, sizeof(*ctx));
771
0
  parse_options_start_1(ctx, argc, argv, prefix, options, flags);
772
0
}
773
774
static void show_negated_gitcomp(const struct option *opts, int show_all,
775
         int nr_noopts)
776
0
{
777
0
  int printed_dashdash = 0;
778
779
0
  for (; opts->type != OPTION_END; opts++) {
780
0
    int has_unset_form = 0;
781
0
    const char *name;
782
783
0
    if (!opts->long_name)
784
0
      continue;
785
0
    if (!show_all &&
786
0
      (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE)))
787
0
      continue;
788
0
    if (opts->flags & PARSE_OPT_NONEG)
789
0
      continue;
790
791
0
    switch (opts->type) {
792
0
    case OPTION_STRING:
793
0
    case OPTION_FILENAME:
794
0
    case OPTION_INTEGER:
795
0
    case OPTION_UNSIGNED:
796
0
    case OPTION_CALLBACK:
797
0
    case OPTION_BIT:
798
0
    case OPTION_NEGBIT:
799
0
    case OPTION_COUNTUP:
800
0
    case OPTION_SET_INT:
801
0
      has_unset_form = 1;
802
0
      break;
803
0
    default:
804
0
      break;
805
0
    }
806
0
    if (!has_unset_form)
807
0
      continue;
808
809
0
    if (skip_prefix(opts->long_name, "no-", &name)) {
810
0
      if (nr_noopts < 0)
811
0
        printf(" --%s", name);
812
0
    } else if (nr_noopts >= 0) {
813
0
      if (nr_noopts && !printed_dashdash) {
814
0
        printf(" --");
815
0
        printed_dashdash = 1;
816
0
      }
817
0
      printf(" --no-%s", opts->long_name);
818
0
      nr_noopts++;
819
0
    }
820
0
  }
821
0
}
822
823
static int show_gitcomp(const struct option *opts, int show_all)
824
0
{
825
0
  const struct option *original_opts = opts;
826
0
  int nr_noopts = 0;
827
828
0
  for (; opts->type != OPTION_END; opts++) {
829
0
    const char *prefix = "--";
830
0
    const char *suffix = "";
831
832
0
    if (!opts->long_name)
833
0
      continue;
834
0
    if (!show_all &&
835
0
      (opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE | PARSE_OPT_FROM_ALIAS)))
836
0
      continue;
837
838
0
    switch (opts->type) {
839
0
    case OPTION_SUBCOMMAND:
840
0
      prefix = "";
841
0
      break;
842
0
    case OPTION_GROUP:
843
0
      continue;
844
0
    case OPTION_STRING:
845
0
    case OPTION_FILENAME:
846
0
    case OPTION_INTEGER:
847
0
    case OPTION_UNSIGNED:
848
0
    case OPTION_CALLBACK:
849
0
      if (opts->flags & PARSE_OPT_NOARG)
850
0
        break;
851
0
      if (opts->flags & PARSE_OPT_OPTARG)
852
0
        break;
853
0
      if (opts->flags & PARSE_OPT_LASTARG_DEFAULT)
854
0
        break;
855
0
      suffix = "=";
856
0
      break;
857
0
    default:
858
0
      break;
859
0
    }
860
0
    if (opts->flags & PARSE_OPT_COMP_ARG)
861
0
      suffix = "=";
862
0
    if (starts_with(opts->long_name, "no-"))
863
0
      nr_noopts++;
864
0
    printf("%s%s%s%s", opts == original_opts ? "" : " ",
865
0
           prefix, opts->long_name, suffix);
866
0
  }
867
0
  show_negated_gitcomp(original_opts, show_all, -1);
868
0
  show_negated_gitcomp(original_opts, show_all, nr_noopts);
869
0
  fputc('\n', stdout);
870
0
  return PARSE_OPT_COMPLETE;
871
0
}
872
873
/*
874
 * Scan and may produce a new option[] array, which should be used
875
 * instead of the original 'options'.
876
 *
877
 * Right now this is only used to preprocess and substitute
878
 * OPTION_ALIAS.
879
 *
880
 * The returned options should be freed using free_preprocessed_options.
881
 */
882
static struct option *preprocess_options(struct parse_opt_ctx_t *ctx,
883
           const struct option *options)
884
0
{
885
0
  struct option *newopt;
886
0
  int i, nr, alias;
887
0
  int nr_aliases = 0;
888
889
0
  for (nr = 0; options[nr].type != OPTION_END; nr++) {
890
0
    if (options[nr].type == OPTION_ALIAS)
891
0
      nr_aliases++;
892
0
  }
893
894
0
  if (!nr_aliases)
895
0
    return NULL;
896
897
0
  DUP_ARRAY(newopt, options, nr + 1);
898
899
  /* each alias has two string pointers and NULL */
900
0
  CALLOC_ARRAY(ctx->alias_groups, 3 * (nr_aliases + 1));
901
902
0
  for (alias = 0, i = 0; i < nr; i++) {
903
0
    int short_name;
904
0
    const char *long_name;
905
0
    const char *source;
906
0
    struct strbuf help = STRBUF_INIT;
907
0
    int j;
908
909
0
    if (newopt[i].type != OPTION_ALIAS)
910
0
      continue;
911
912
0
    short_name = newopt[i].short_name;
913
0
    long_name = newopt[i].long_name;
914
0
    source = newopt[i].value;
915
916
0
    if (!long_name)
917
0
      BUG("An alias must have long option name");
918
0
    strbuf_addf(&help, _("alias of --%s"), source);
919
920
0
    for (j = 0; j < nr; j++) {
921
0
      const char *name = options[j].long_name;
922
923
0
      if (!name || strcmp(name, source))
924
0
        continue;
925
926
0
      if (options[j].type == OPTION_ALIAS)
927
0
        BUG("No please. Nested aliases are not supported.");
928
929
0
      memcpy(newopt + i, options + j, sizeof(*newopt));
930
0
      newopt[i].short_name = short_name;
931
0
      newopt[i].long_name = long_name;
932
0
      newopt[i].help = strbuf_detach(&help, NULL);
933
0
      newopt[i].flags |= PARSE_OPT_FROM_ALIAS;
934
0
      break;
935
0
    }
936
937
0
    if (j == nr)
938
0
      BUG("could not find source option '%s' of alias '%s'",
939
0
          source, newopt[i].long_name);
940
0
    ctx->alias_groups[alias * 3 + 0] = newopt[i].long_name;
941
0
    ctx->alias_groups[alias * 3 + 1] = options[j].long_name;
942
0
    ctx->alias_groups[alias * 3 + 2] = NULL;
943
0
    alias++;
944
0
  }
945
946
0
  return newopt;
947
0
}
948
949
static void free_preprocessed_options(struct option *options)
950
0
{
951
0
  int i;
952
953
0
  if (!options)
954
0
    return;
955
956
0
  for (i = 0; options[i].type != OPTION_END; i++) {
957
0
    if (options[i].flags & PARSE_OPT_FROM_ALIAS)
958
0
      free((void *)options[i].help);
959
0
  }
960
0
  free(options);
961
0
}
962
963
0
#define USAGE_NORMAL 0
964
0
#define USAGE_FULL 1
965
0
#define USAGE_TO_STDOUT 0
966
0
#define USAGE_TO_STDERR 1
967
968
static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t *,
969
               const char * const *,
970
               const struct option *,
971
               int full_usage,
972
               int usage_to_stderr);
973
974
enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
975
           const struct option *options,
976
           const char * const usagestr[])
977
0
{
978
0
  int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
979
980
  /* we must reset ->opt, unknown short option leave it dangling */
981
0
  ctx->opt = NULL;
982
983
0
  for (; ctx->argc; ctx->argc--, ctx->argv++) {
984
0
    const char *arg = ctx->argv[0];
985
986
0
    if (ctx->flags & PARSE_OPT_ONE_SHOT &&
987
0
        ctx->argc != ctx->total)
988
0
      break;
989
990
0
    if (*arg != '-' || !arg[1]) {
991
0
      if (parse_nodash_opt(ctx, arg, options) == 0)
992
0
        continue;
993
0
      if (!ctx->has_subcommands) {
994
0
        if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
995
0
          return PARSE_OPT_NON_OPTION;
996
0
        ctx->out[ctx->cpidx++] = ctx->argv[0];
997
0
        continue;
998
0
      }
999
0
      switch (parse_subcommand(arg, options)) {
1000
0
      case PARSE_OPT_SUBCOMMAND:
1001
0
        return PARSE_OPT_SUBCOMMAND;
1002
0
      case PARSE_OPT_UNKNOWN:
1003
0
        if (ctx->flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)
1004
          /*
1005
           * arg is neither a short or long
1006
           * option nor a subcommand.  Since
1007
           * this command has a default
1008
           * operation mode, we have to treat
1009
           * this arg and all remaining args
1010
           * as args meant to that default
1011
           * operation mode.
1012
           * So we are done parsing.
1013
           */
1014
0
          return PARSE_OPT_DONE;
1015
0
        error(_("unknown subcommand: `%s'"), arg);
1016
0
        usage_with_options(usagestr, options);
1017
0
      case PARSE_OPT_COMPLETE:
1018
0
      case PARSE_OPT_HELP:
1019
0
      case PARSE_OPT_ERROR:
1020
0
      case PARSE_OPT_DONE:
1021
0
      case PARSE_OPT_NON_OPTION:
1022
        /* Impossible. */
1023
0
        BUG("parse_subcommand() cannot return these");
1024
0
      }
1025
0
    }
1026
1027
    /* lone -h asks for help */
1028
0
    if (internal_help && ctx->total == 1 && !strcmp(arg + 1, "h"))
1029
0
      goto show_usage;
1030
1031
    /*
1032
     * lone --git-completion-helper and --git-completion-helper-all
1033
     * are asked by git-completion.bash
1034
     */
1035
0
    if (ctx->total == 1 && !strcmp(arg, "--git-completion-helper"))
1036
0
      return show_gitcomp(options, 0);
1037
0
    if (ctx->total == 1 && !strcmp(arg, "--git-completion-helper-all"))
1038
0
      return show_gitcomp(options, 1);
1039
1040
0
    if (arg[1] != '-') {
1041
0
      ctx->opt = arg + 1;
1042
0
      switch (parse_short_opt(ctx, options)) {
1043
0
      case PARSE_OPT_ERROR:
1044
0
        return PARSE_OPT_ERROR;
1045
0
      case PARSE_OPT_UNKNOWN:
1046
0
        if (ctx->opt)
1047
0
          check_typos(arg + 1, options);
1048
0
        if (internal_help && *ctx->opt == 'h')
1049
0
          goto show_usage;
1050
0
        goto unknown;
1051
0
      case PARSE_OPT_NON_OPTION:
1052
0
      case PARSE_OPT_SUBCOMMAND:
1053
0
      case PARSE_OPT_HELP:
1054
0
      case PARSE_OPT_COMPLETE:
1055
0
        BUG("parse_short_opt() cannot return these");
1056
0
      case PARSE_OPT_DONE:
1057
0
        break;
1058
0
      }
1059
0
      if (ctx->opt)
1060
0
        check_typos(arg + 1, options);
1061
0
      while (ctx->opt) {
1062
0
        switch (parse_short_opt(ctx, options)) {
1063
0
        case PARSE_OPT_ERROR:
1064
0
          return PARSE_OPT_ERROR;
1065
0
        case PARSE_OPT_UNKNOWN:
1066
0
          if (internal_help && *ctx->opt == 'h')
1067
0
            goto show_usage;
1068
1069
          /* fake a short option thing to hide the fact that we may have
1070
           * started to parse aggregated stuff
1071
           *
1072
           * This is leaky, too bad.
1073
           */
1074
0
          ctx->argv[0] = xstrdup(ctx->opt - 1);
1075
0
          *(char *)ctx->argv[0] = '-';
1076
0
          goto unknown;
1077
0
        case PARSE_OPT_NON_OPTION:
1078
0
        case PARSE_OPT_SUBCOMMAND:
1079
0
        case PARSE_OPT_COMPLETE:
1080
0
        case PARSE_OPT_HELP:
1081
0
          BUG("parse_short_opt() cannot return these");
1082
0
        case PARSE_OPT_DONE:
1083
0
          break;
1084
0
        }
1085
0
      }
1086
0
      continue;
1087
0
    }
1088
1089
0
    if (!arg[2] /* "--" */) {
1090
0
      if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
1091
0
        ctx->argc--;
1092
0
        ctx->argv++;
1093
0
      }
1094
0
      break;
1095
0
    } else if (!strcmp(arg + 2, "end-of-options")) {
1096
0
      if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN_OPT)) {
1097
0
        ctx->argc--;
1098
0
        ctx->argv++;
1099
0
      }
1100
0
      break;
1101
0
    }
1102
1103
0
    if (internal_help && !strcmp(arg + 2, "help-all"))
1104
0
      return usage_with_options_internal(ctx, usagestr, options,
1105
0
                 USAGE_FULL, USAGE_TO_STDOUT);
1106
0
    if (internal_help && !strcmp(arg + 2, "help"))
1107
0
      goto show_usage;
1108
0
    switch (parse_long_opt(ctx, arg + 2, options)) {
1109
0
    case PARSE_OPT_ERROR:
1110
0
      return PARSE_OPT_ERROR;
1111
0
    case PARSE_OPT_UNKNOWN:
1112
0
      goto unknown;
1113
0
    case PARSE_OPT_HELP:
1114
0
      goto show_usage;
1115
0
    case PARSE_OPT_NON_OPTION:
1116
0
    case PARSE_OPT_SUBCOMMAND:
1117
0
    case PARSE_OPT_COMPLETE:
1118
0
      BUG("parse_long_opt() cannot return these");
1119
0
    case PARSE_OPT_DONE:
1120
0
      break;
1121
0
    }
1122
0
    continue;
1123
0
unknown:
1124
0
    if (ctx->flags & PARSE_OPT_ONE_SHOT)
1125
0
      break;
1126
0
    if (ctx->has_subcommands &&
1127
0
        (ctx->flags & PARSE_OPT_SUBCOMMAND_OPTIONAL) &&
1128
0
        (ctx->flags & PARSE_OPT_KEEP_UNKNOWN_OPT)) {
1129
      /*
1130
       * Found an unknown option given to a command with
1131
       * subcommands that has a default operation mode:
1132
       * we treat this option and all remaining args as
1133
       * arguments meant to that default operation mode.
1134
       * So we are done parsing.
1135
       */
1136
0
      return PARSE_OPT_DONE;
1137
0
    }
1138
0
    if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN_OPT))
1139
0
      return PARSE_OPT_UNKNOWN;
1140
0
    ctx->out[ctx->cpidx++] = ctx->argv[0];
1141
0
    ctx->opt = NULL;
1142
0
  }
1143
0
  return PARSE_OPT_DONE;
1144
1145
0
 show_usage:
1146
0
  return usage_with_options_internal(ctx, usagestr, options,
1147
0
             USAGE_NORMAL, USAGE_TO_STDOUT);
1148
0
}
1149
1150
int parse_options_end(struct parse_opt_ctx_t *ctx)
1151
0
{
1152
0
  if (ctx->flags & PARSE_OPT_ONE_SHOT)
1153
0
    return ctx->total - ctx->argc;
1154
1155
0
  MOVE_ARRAY(ctx->out + ctx->cpidx, ctx->argv, ctx->argc);
1156
0
  ctx->out[ctx->cpidx + ctx->argc] = NULL;
1157
0
  return ctx->cpidx + ctx->argc;
1158
0
}
1159
1160
int parse_options(int argc, const char **argv,
1161
      const char *prefix,
1162
      const struct option *options,
1163
      const char * const usagestr[],
1164
      enum parse_opt_flags flags)
1165
0
{
1166
0
  struct parse_opt_ctx_t ctx;
1167
0
  struct option *real_options;
1168
1169
0
  disallow_abbreviated_options =
1170
0
    git_env_bool("GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS", 0);
1171
1172
0
  memset(&ctx, 0, sizeof(ctx));
1173
0
  real_options = preprocess_options(&ctx, options);
1174
0
  if (real_options)
1175
0
    options = real_options;
1176
0
  parse_options_start_1(&ctx, argc, argv, prefix, options, flags);
1177
0
  switch (parse_options_step(&ctx, options, usagestr)) {
1178
0
  case PARSE_OPT_HELP:
1179
0
  case PARSE_OPT_ERROR:
1180
0
    exit(129);
1181
0
  case PARSE_OPT_COMPLETE:
1182
0
    exit(0);
1183
0
  case PARSE_OPT_NON_OPTION:
1184
0
  case PARSE_OPT_SUBCOMMAND:
1185
0
    break;
1186
0
  case PARSE_OPT_DONE:
1187
0
    if (ctx.has_subcommands &&
1188
0
        !(flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)) {
1189
0
      error(_("need a subcommand"));
1190
0
      usage_with_options(usagestr, options);
1191
0
    }
1192
0
    break;
1193
0
  case PARSE_OPT_UNKNOWN:
1194
0
    if (ctx.argv[0][1] == '-') {
1195
0
      error(_("unknown option `%s'"), ctx.argv[0] + 2);
1196
0
    } else if (isascii(*ctx.opt)) {
1197
0
      error(_("unknown switch `%c'"), *ctx.opt);
1198
0
    } else {
1199
0
      error(_("unknown non-ascii option in string: `%s'"),
1200
0
            ctx.argv[0]);
1201
0
    }
1202
0
    usage_with_options(usagestr, options);
1203
0
  }
1204
1205
0
  precompose_argv_prefix(argc, argv, NULL);
1206
0
  free_preprocessed_options(real_options);
1207
0
  free(ctx.alias_groups);
1208
0
  for (struct parse_opt_cmdmode_list *elem = ctx.cmdmode_list; elem;) {
1209
0
    struct parse_opt_cmdmode_list *next = elem->next;
1210
0
    free(elem);
1211
0
    elem = next;
1212
0
  }
1213
0
  return parse_options_end(&ctx);
1214
0
}
1215
1216
static int usage_argh(const struct option *opts, FILE *outfile)
1217
0
{
1218
0
  const char *s;
1219
0
  int literal = (opts->flags & PARSE_OPT_LITERAL_ARGHELP) ||
1220
0
    !opts->argh || !!strpbrk(opts->argh, "()<>[]|");
1221
0
  if (opts->flags & PARSE_OPT_OPTARG)
1222
0
    if (opts->long_name)
1223
      /*
1224
       * TRANSLATORS: The "<%s>" part of this string
1225
       * stands for an optional value given to a command
1226
       * line option in the long form, and "<>" is there
1227
       * as a convention to signal that it is a
1228
       * placeholder (i.e. the user should substitute it
1229
       * with the real value).  If your language uses a
1230
       * different convention, you can change "<%s>" part
1231
       * to match yours, e.g. it might use "|%s|" instead,
1232
       * or if the alphabet is different enough it may use
1233
       * "%s" without any placeholder signal.  Most
1234
       * translations leave this message as is.
1235
       */
1236
0
      s = literal ? "[=%s]" : _("[=<%s>]");
1237
0
    else
1238
      /*
1239
       * TRANSLATORS: The "<%s>" part of this string
1240
       * stands for an optional value given to a command
1241
       * line option in the short form, and "<>" is there
1242
       * as a convention to signal that it is a
1243
       * placeholder (i.e. the user should substitute it
1244
       * with the real value).  If your language uses a
1245
       * different convention, you can change "<%s>" part
1246
       * to match yours, e.g. it might use "|%s|" instead,
1247
       * or if the alphabet is different enough it may use
1248
       * "%s" without any placeholder signal.  Most
1249
       * translations leave this message as is.
1250
       */
1251
0
      s = literal ? "[%s]" : _("[<%s>]");
1252
0
  else
1253
    /*
1254
     * TRANSLATORS: The "<%s>" part of this string stands for a
1255
     * value given to a command line option, and "<>" is there
1256
     * as a convention to signal that it is a placeholder
1257
     * (i.e. the user should substitute it with the real value).
1258
     * If your language uses a different convention, you can
1259
     * change "<%s>" part to match yours, e.g. it might use
1260
     * "|%s|" instead, or if the alphabet is different enough it
1261
     * may use "%s" without any placeholder signal.  Most
1262
     * translations leave this message as is.
1263
     */
1264
0
    s = literal ? " %s" : _(" <%s>");
1265
0
  return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("..."));
1266
0
}
1267
1268
static int usage_indent(FILE *outfile)
1269
0
{
1270
0
  return fprintf(outfile, "    ");
1271
0
}
1272
1273
0
#define USAGE_OPTS_WIDTH 26
1274
1275
static void usage_padding(FILE *outfile, size_t pos)
1276
0
{
1277
0
  if (pos < USAGE_OPTS_WIDTH)
1278
0
    fprintf(outfile, "%*s", USAGE_OPTS_WIDTH - (int)pos, "");
1279
0
  else
1280
0
    fprintf(outfile, "\n%*s", USAGE_OPTS_WIDTH, "");
1281
0
}
1282
1283
static const struct option *find_option_by_long_name(const struct option *opts,
1284
                 const char *long_name)
1285
0
{
1286
0
  for (; opts->type != OPTION_END; opts++) {
1287
0
    if (opts->long_name && !strcmp(opts->long_name, long_name))
1288
0
      return opts;
1289
0
  }
1290
0
  return NULL;
1291
0
}
1292
1293
static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t *ctx,
1294
               const char * const *usagestr,
1295
               const struct option *opts,
1296
               int full, int err)
1297
0
{
1298
0
  const struct option *all_opts = opts;
1299
0
  FILE *outfile = err ? stderr : stdout;
1300
0
  int need_newline;
1301
1302
0
  const char *usage_prefix = _("usage: %s");
1303
  /*
1304
   * The translation could be anything, but we can count on
1305
   * msgfmt(1)'s --check option to have asserted that "%s" is in
1306
   * the translation. So compute the length of the "usage: "
1307
   * part. We are assuming that the translator wasn't overly
1308
   * clever and used e.g. "%1$s" instead of "%s", there's only
1309
   * one "%s" in "usage_prefix" above, so there's no reason to
1310
   * do so even with a RTL language.
1311
   */
1312
0
  size_t usage_len = strlen(usage_prefix) - strlen("%s");
1313
  /*
1314
   * TRANSLATORS: the colon here should align with the
1315
   * one in "usage: %s" translation.
1316
   */
1317
0
  const char *or_prefix = _("   or: %s");
1318
  /*
1319
   * TRANSLATORS: You should only need to translate this format
1320
   * string if your language is a RTL language (e.g. Arabic,
1321
   * Hebrew etc.), not if it's a LTR language (e.g. German,
1322
   * Russian, Chinese etc.).
1323
   *
1324
   * When a translated usage string has an embedded "\n" it's
1325
   * because options have wrapped to the next line. The line
1326
   * after the "\n" will then be padded to align with the
1327
   * command name, such as N_("git cmd [opt]\n<8
1328
   * spaces>[opt2]"), where the 8 spaces are the same length as
1329
   * "git cmd ".
1330
   *
1331
   * This format string prints out that already-translated
1332
   * line. The "%*s" is whitespace padding to account for the
1333
   * padding at the start of the line that we add in this
1334
   * function. The "%s" is a line in the (hopefully already
1335
   * translated) N_() usage string, which contained embedded
1336
   * newlines before we split it up.
1337
   */
1338
0
  const char *usage_continued = _("%*s%s");
1339
0
  const char *prefix = usage_prefix;
1340
0
  int saw_empty_line = 0;
1341
1342
0
  if (!usagestr)
1343
0
    return PARSE_OPT_HELP;
1344
1345
0
  if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
1346
0
    fprintf(outfile, "cat <<\\EOF\n");
1347
1348
0
  while (*usagestr) {
1349
0
    const char *str = _(*usagestr++);
1350
0
    struct string_list list = STRING_LIST_INIT_DUP;
1351
0
    unsigned int j;
1352
1353
0
    if (!saw_empty_line && !*str)
1354
0
      saw_empty_line = 1;
1355
1356
0
    string_list_split(&list, str, "\n", -1);
1357
0
    for (j = 0; j < list.nr; j++) {
1358
0
      const char *line = list.items[j].string;
1359
1360
0
      if (saw_empty_line && *line)
1361
0
        fprintf_ln(outfile, _("    %s"), line);
1362
0
      else if (saw_empty_line)
1363
0
        fputc('\n', outfile);
1364
0
      else if (!j)
1365
0
        fprintf_ln(outfile, prefix, line);
1366
0
      else
1367
0
        fprintf_ln(outfile, usage_continued,
1368
0
             (int)usage_len, "", line);
1369
0
    }
1370
0
    string_list_clear(&list, 0);
1371
1372
0
    prefix = or_prefix;
1373
0
  }
1374
1375
0
  need_newline = 1;
1376
1377
0
  for (; opts->type != OPTION_END; opts++) {
1378
0
    size_t pos;
1379
0
    const char *cp, *np;
1380
0
    const char *positive_name = NULL;
1381
1382
0
    if (opts->type == OPTION_SUBCOMMAND)
1383
0
      continue;
1384
0
    if (opts->type == OPTION_GROUP) {
1385
0
      fputc('\n', outfile);
1386
0
      need_newline = 0;
1387
0
      if (*opts->help)
1388
0
        fprintf(outfile, "%s\n", _(opts->help));
1389
0
      continue;
1390
0
    }
1391
0
    if (!full && (opts->flags & PARSE_OPT_HIDDEN))
1392
0
      continue;
1393
1394
0
    if (need_newline) {
1395
0
      fputc('\n', outfile);
1396
0
      need_newline = 0;
1397
0
    }
1398
1399
0
    pos = usage_indent(outfile);
1400
0
    if (opts->short_name) {
1401
0
      if (opts->flags & PARSE_OPT_NODASH)
1402
0
        pos += fprintf(outfile, "%c", opts->short_name);
1403
0
      else
1404
0
        pos += fprintf(outfile, "-%c", opts->short_name);
1405
0
    }
1406
0
    if (opts->long_name && opts->short_name)
1407
0
      pos += fprintf(outfile, ", ");
1408
0
    if (opts->long_name) {
1409
0
      const char *long_name = opts->long_name;
1410
0
      if ((opts->flags & PARSE_OPT_NONEG) ||
1411
0
          skip_prefix(long_name, "no-", &positive_name))
1412
0
        pos += fprintf(outfile, "--%s", long_name);
1413
0
      else
1414
0
        pos += fprintf(outfile, "--[no-]%s", long_name);
1415
0
    }
1416
1417
0
    if (opts->type == OPTION_NUMBER)
1418
0
      pos += utf8_fprintf(outfile, _("-NUM"));
1419
1420
0
    if ((opts->flags & PARSE_OPT_LITERAL_ARGHELP) ||
1421
0
        !(opts->flags & PARSE_OPT_NOARG))
1422
0
      pos += usage_argh(opts, outfile);
1423
1424
0
    if (opts->type == OPTION_ALIAS) {
1425
0
      usage_padding(outfile, pos);
1426
0
      fprintf_ln(outfile, _("alias of --%s"),
1427
0
           (const char *)opts->value);
1428
0
      continue;
1429
0
    }
1430
1431
0
    for (cp = opts->help ? _(opts->help) : ""; *cp; cp = np) {
1432
0
      np = strchrnul(cp, '\n');
1433
0
      if (*np)
1434
0
        np++;
1435
0
      usage_padding(outfile, pos);
1436
0
      fwrite(cp, 1, np - cp, outfile);
1437
0
      pos = 0;
1438
0
    }
1439
0
    fputc('\n', outfile);
1440
1441
0
    if (positive_name) {
1442
0
      if (find_option_by_long_name(all_opts, positive_name))
1443
0
        continue;
1444
0
      pos = usage_indent(outfile);
1445
0
      pos += fprintf(outfile, "--%s", positive_name);
1446
0
      usage_padding(outfile, pos);
1447
0
      fprintf_ln(outfile, _("opposite of --no-%s"),
1448
0
           positive_name);
1449
0
    }
1450
0
  }
1451
0
  fputc('\n', outfile);
1452
1453
0
  if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
1454
0
    fputs("EOF\n", outfile);
1455
1456
0
  return PARSE_OPT_HELP;
1457
0
}
1458
1459
void NORETURN usage_with_options(const char * const *usagestr,
1460
      const struct option *opts)
1461
0
{
1462
0
  usage_with_options_internal(NULL, usagestr, opts,
1463
0
            USAGE_NORMAL, USAGE_TO_STDERR);
1464
0
  exit(129);
1465
0
}
1466
1467
void show_usage_with_options_if_asked(int ac, const char **av,
1468
              const char * const *usagestr,
1469
              const struct option *opts)
1470
0
{
1471
0
  if (ac == 2) {
1472
0
    if (!strcmp(av[1], "-h")) {
1473
0
      usage_with_options_internal(NULL, usagestr, opts,
1474
0
                USAGE_NORMAL, USAGE_TO_STDOUT);
1475
0
      exit(129);
1476
0
    } else if (!strcmp(av[1], "--help-all")) {
1477
0
      usage_with_options_internal(NULL, usagestr, opts,
1478
0
                USAGE_FULL, USAGE_TO_STDOUT);
1479
0
      exit(129);
1480
0
    }
1481
0
  }
1482
0
}
1483
1484
void NORETURN usage_msg_opt(const char *msg,
1485
       const char * const *usagestr,
1486
       const struct option *options)
1487
0
{
1488
0
  die_message("%s\n", msg); /* The extra \n is intentional */
1489
0
  usage_with_options(usagestr, options);
1490
0
}
1491
1492
void NORETURN usage_msg_optf(const char * const fmt,
1493
           const char * const *usagestr,
1494
           const struct option *options, ...)
1495
0
{
1496
0
  struct strbuf msg = STRBUF_INIT;
1497
0
  va_list ap;
1498
0
  va_start(ap, options);
1499
0
  strbuf_vaddf(&msg, fmt, ap);
1500
0
  va_end(ap);
1501
1502
0
  usage_msg_opt(msg.buf, usagestr, options);
1503
0
}
1504
1505
void die_for_incompatible_opt4(int opt1, const char *opt1_name,
1506
             int opt2, const char *opt2_name,
1507
             int opt3, const char *opt3_name,
1508
             int opt4, const char *opt4_name)
1509
0
{
1510
0
  int count = 0;
1511
0
  const char *options[4];
1512
1513
0
  if (opt1)
1514
0
    options[count++] = opt1_name;
1515
0
  if (opt2)
1516
0
    options[count++] = opt2_name;
1517
0
  if (opt3)
1518
0
    options[count++] = opt3_name;
1519
0
  if (opt4)
1520
0
    options[count++] = opt4_name;
1521
0
  switch (count) {
1522
0
  case 4:
1523
0
    die(_("options '%s', '%s', '%s', and '%s' cannot be used together"),
1524
0
        opt1_name, opt2_name, opt3_name, opt4_name);
1525
0
    break;
1526
0
  case 3:
1527
0
    die(_("options '%s', '%s', and '%s' cannot be used together"),
1528
0
        options[0], options[1], options[2]);
1529
0
    break;
1530
0
  case 2:
1531
0
    die(_("options '%s' and '%s' cannot be used together"),
1532
0
        options[0], options[1]);
1533
0
    break;
1534
0
  default:
1535
0
    break;
1536
0
  }
1537
0
}