Coverage Report

Created: 2026-10-17 07:15

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