Coverage Report

Created: 2024-09-16 06:10

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