git

Форк
0
/
parse-options.c 
1332 строки · 34.9 Кб
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
{
20
	if (opt->long_name && opt->short_name)
21
		bug("switch '%c' (--%s) %s", opt->short_name,
22
		    opt->long_name, reason);
23
	else if (opt->long_name)
24
		bug("option '%s' %s", opt->long_name, reason);
25
	else
26
		bug("switch '%c' %s", opt->short_name, reason);
27
}
28

29
static const char *optname(const struct option *opt, enum opt_parsed flags)
30
{
31
	static struct strbuf sb = STRBUF_INIT;
32

33
	strbuf_reset(&sb);
34
	if (flags & OPT_SHORT)
35
		strbuf_addf(&sb, "switch `%c'", opt->short_name);
36
	else if (flags & OPT_UNSET)
37
		strbuf_addf(&sb, "option `no-%s'", opt->long_name);
38
	else if (flags == OPT_LONG)
39
		strbuf_addf(&sb, "option `%s'", opt->long_name);
40
	else
41
		BUG("optname() got unknown flags %d", flags);
42

43
	return sb.buf;
44
}
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
{
50
	if (p->opt) {
51
		*arg = p->opt;
52
		p->opt = NULL;
53
	} else if (p->argc == 1 && (opt->flags & PARSE_OPT_LASTARG_DEFAULT)) {
54
		*arg = (const char *)opt->defval;
55
	} else if (p->argc > 1) {
56
		p->argc--;
57
		*arg = *++p->argv;
58
	} else
59
		return error(_("%s requires a value"), optname(opt, flags));
60
	return 0;
61
}
62

63
static void fix_filename(const char *prefix, char **file)
64
{
65
	if (!file || !*file)
66
		; /* leave as NULL */
67
	else
68
		*file = prefix_filename_except_for_dash(prefix, *file);
69
}
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
{
76
	const char *s, *arg;
77
	const int unset = flags & OPT_UNSET;
78
	int err;
79

80
	if (unset && p->opt)
81
		return error(_("%s takes no value"), optname(opt, flags));
82
	if (unset && (opt->flags & PARSE_OPT_NONEG))
83
		return error(_("%s isn't available"), optname(opt, flags));
84
	if (!(flags & OPT_SHORT) && p->opt && (opt->flags & PARSE_OPT_NOARG))
85
		return error(_("%s takes no value"), optname(opt, flags));
86

87
	switch (opt->type) {
88
	case OPTION_LOWLEVEL_CALLBACK:
89
		return opt->ll_callback(p, opt, NULL, unset);
90

91
	case OPTION_BIT:
92
		if (unset)
93
			*(int *)opt->value &= ~opt->defval;
94
		else
95
			*(int *)opt->value |= opt->defval;
96
		return 0;
97

98
	case OPTION_NEGBIT:
99
		if (unset)
100
			*(int *)opt->value |= opt->defval;
101
		else
102
			*(int *)opt->value &= ~opt->defval;
103
		return 0;
104

105
	case OPTION_BITOP:
106
		if (unset)
107
			BUG("BITOP can't have unset form");
108
		*(int *)opt->value &= ~opt->extra;
109
		*(int *)opt->value |= opt->defval;
110
		return 0;
111

112
	case OPTION_COUNTUP:
113
		if (*(int *)opt->value < 0)
114
			*(int *)opt->value = 0;
115
		*(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
116
		return 0;
117

118
	case OPTION_SET_INT:
119
		*(int *)opt->value = unset ? 0 : opt->defval;
120
		return 0;
121

122
	case OPTION_STRING:
123
		if (unset)
124
			*(const char **)opt->value = NULL;
125
		else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
126
			*(const char **)opt->value = (const char *)opt->defval;
127
		else
128
			return get_arg(p, opt, flags, (const char **)opt->value);
129
		return 0;
130

131
	case OPTION_FILENAME:
132
		err = 0;
133
		if (unset)
134
			*(const char **)opt->value = NULL;
135
		else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
136
			*(const char **)opt->value = (const char *)opt->defval;
137
		else
138
			err = get_arg(p, opt, flags, (const char **)opt->value);
139

140
		if (!err)
141
			fix_filename(p->prefix, (char **)opt->value);
142
		return err;
143

144
	case OPTION_CALLBACK:
145
	{
146
		const char *p_arg = NULL;
147
		int p_unset;
148

149
		if (unset)
150
			p_unset = 1;
151
		else if (opt->flags & PARSE_OPT_NOARG)
152
			p_unset = 0;
153
		else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
154
			p_unset = 0;
155
		else if (get_arg(p, opt, flags, &arg))
156
			return -1;
157
		else {
158
			p_unset = 0;
159
			p_arg = arg;
160
		}
161
		if (opt->flags & PARSE_OPT_CMDMODE)
162
			*argp = p_arg;
163
		if (opt->callback)
164
			return (*opt->callback)(opt, p_arg, p_unset) ? (-1) : 0;
165
		else
166
			return (*opt->ll_callback)(p, opt, p_arg, p_unset);
167
	}
168
	case OPTION_INTEGER:
169
		if (unset) {
170
			*(int *)opt->value = 0;
171
			return 0;
172
		}
173
		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
174
			*(int *)opt->value = opt->defval;
175
			return 0;
176
		}
177
		if (get_arg(p, opt, flags, &arg))
178
			return -1;
179
		if (!*arg)
180
			return error(_("%s expects a numerical value"),
181
				     optname(opt, flags));
182
		*(int *)opt->value = strtol(arg, (char **)&s, 10);
183
		if (*s)
184
			return error(_("%s expects a numerical value"),
185
				     optname(opt, flags));
186
		return 0;
187

188
	case OPTION_MAGNITUDE:
189
		if (unset) {
190
			*(unsigned long *)opt->value = 0;
191
			return 0;
192
		}
193
		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
194
			*(unsigned long *)opt->value = opt->defval;
195
			return 0;
196
		}
197
		if (get_arg(p, opt, flags, &arg))
198
			return -1;
199
		if (!git_parse_ulong(arg, opt->value))
200
			return error(_("%s expects a non-negative integer value"
201
				       " with an optional k/m/g suffix"),
202
				     optname(opt, flags));
203
		return 0;
204

205
	default:
206
		BUG("opt->type %d should not happen", opt->type);
207
	}
208
}
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
{
221
	ctx->cmdmode_list = NULL;
222

223
	for (; opts->type != OPTION_END; opts++) {
224
		struct parse_opt_cmdmode_list *elem = ctx->cmdmode_list;
225
		int *value_ptr = opts->value;
226

227
		if (!(opts->flags & PARSE_OPT_CMDMODE) || !value_ptr)
228
			continue;
229

230
		while (elem && elem->value_ptr != value_ptr)
231
			elem = elem->next;
232
		if (elem)
233
			continue;
234

235
		CALLOC_ARRAY(elem, 1);
236
		elem->value_ptr = value_ptr;
237
		elem->value = *value_ptr;
238
		elem->next = ctx->cmdmode_list;
239
		ctx->cmdmode_list = elem;
240
	}
241
}
242

243
static char *optnamearg(const struct option *opt, const char *arg,
244
			enum opt_parsed flags)
245
{
246
	if (flags & OPT_SHORT)
247
		return xstrfmt("-%c%s", opt->short_name, arg ? arg : "");
248
	return xstrfmt("--%s%s%s%s", flags & OPT_UNSET ? "no-" : "",
249
		       opt->long_name, arg ? "=" : "", arg ? arg : "");
250
}
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
{
256
	const char *arg = NULL;
257
	enum parse_opt_result result = do_get_value(p, opt, flags, &arg);
258
	struct parse_opt_cmdmode_list *elem = p->cmdmode_list;
259
	char *opt_name, *other_opt_name;
260

261
	for (; elem; elem = elem->next) {
262
		if (*elem->value_ptr == elem->value)
263
			continue;
264

265
		if (elem->opt &&
266
		    (elem->opt->flags | opt->flags) & PARSE_OPT_CMDMODE)
267
			break;
268

269
		elem->opt = opt;
270
		elem->arg = arg;
271
		elem->flags = flags;
272
		elem->value = *elem->value_ptr;
273
	}
274

275
	if (result || !elem)
276
		return result;
277

278
	opt_name = optnamearg(opt, arg, flags);
279
	other_opt_name = optnamearg(elem->opt, elem->arg, elem->flags);
280
	error(_("options '%s' and '%s' cannot be used together"),
281
	      opt_name, other_opt_name);
282
	free(opt_name);
283
	free(other_opt_name);
284
	return -1;
285
}
286

287
static enum parse_opt_result parse_short_opt(struct parse_opt_ctx_t *p,
288
					     const struct option *options)
289
{
290
	const struct option *numopt = NULL;
291

292
	for (; options->type != OPTION_END; options++) {
293
		if (options->short_name == *p->opt) {
294
			p->opt = p->opt[1] ? p->opt + 1 : NULL;
295
			return get_value(p, options, OPT_SHORT);
296
		}
297

298
		/*
299
		 * Handle the numerical option later, explicit one-digit
300
		 * options take precedence over it.
301
		 */
302
		if (options->type == OPTION_NUMBER)
303
			numopt = options;
304
	}
305
	if (numopt && isdigit(*p->opt)) {
306
		size_t len = 1;
307
		char *arg;
308
		int rc;
309

310
		while (isdigit(p->opt[len]))
311
			len++;
312
		arg = xmemdupz(p->opt, len);
313
		p->opt = p->opt[len] ? p->opt + len : NULL;
314
		if (numopt->callback)
315
			rc = (*numopt->callback)(numopt, arg, 0) ? (-1) : 0;
316
		else
317
			rc = (*numopt->ll_callback)(p, numopt, arg, 0);
318
		free(arg);
319
		return rc;
320
	}
321
	return PARSE_OPT_UNKNOWN;
322
}
323

324
static int has_string(const char *it, const char **array)
325
{
326
	while (*array)
327
		if (!strcmp(it, *(array++)))
328
			return 1;
329
	return 0;
330
}
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
{
336
	const char **group;
337

338
	if (!ctx->alias_groups)
339
		return 0;
340

341
	if (!one_opt->long_name || !another_opt->long_name)
342
		return 0;
343

344
	for (group = ctx->alias_groups; *group; group += 3) {
345
		/* it and other are from the same family? */
346
		if (has_string(one_opt->long_name, group) &&
347
		    has_string(another_opt->long_name, group))
348
			return 1;
349
	}
350
	return 0;
351
}
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
{
363
	if (p->flags & PARSE_OPT_KEEP_UNKNOWN_OPT)
364
		return;
365
	if (abbrev->option &&
366
	    !(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
		ambiguous->option = abbrev->option;
374
		ambiguous->flags = abbrev->flags;
375
	}
376
	abbrev->option = option;
377
	abbrev->flags = flags;
378
}
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
{
384
	const char *arg_end = strchrnul(arg, '=');
385
	const char *arg_start = arg;
386
	enum opt_parsed flags = OPT_LONG;
387
	int arg_starts_with_no_no = 0;
388
	struct parsed_option abbrev = { .option = NULL, .flags = OPT_LONG };
389
	struct parsed_option ambiguous = { .option = NULL, .flags = OPT_LONG };
390

391
	if (skip_prefix(arg_start, "no-", &arg_start)) {
392
		if (skip_prefix(arg_start, "no-", &arg_start))
393
			arg_starts_with_no_no = 1;
394
		else
395
			flags |= OPT_UNSET;
396
	}
397

398
	for (; options->type != OPTION_END; options++) {
399
		const char *rest, *long_name = options->long_name;
400
		enum opt_parsed opt_flags = OPT_LONG;
401
		int allow_unset = !(options->flags & PARSE_OPT_NONEG);
402

403
		if (options->type == OPTION_SUBCOMMAND)
404
			continue;
405
		if (!long_name)
406
			continue;
407

408
		if (skip_prefix(long_name, "no-", &long_name))
409
			opt_flags |= OPT_UNSET;
410
		else if (arg_starts_with_no_no)
411
			continue;
412

413
		if (((flags ^ opt_flags) & OPT_UNSET) && !allow_unset)
414
			continue;
415

416
		if (skip_prefix(arg_start, long_name, &rest)) {
417
			if (*rest == '=')
418
				p->opt = rest + 1;
419
			else if (*rest)
420
				continue;
421
			return get_value(p, options, flags ^ opt_flags);
422
		}
423

424
		/* abbreviated? */
425
		if (!strncmp(long_name, arg_start, arg_end - arg_start))
426
			register_abbrev(p, options, flags ^ opt_flags,
427
					&abbrev, &ambiguous);
428

429
		/* negated and abbreviated very much? */
430
		if (allow_unset && starts_with("no-", arg))
431
			register_abbrev(p, options, OPT_UNSET ^ opt_flags,
432
					&abbrev, &ambiguous);
433
	}
434

435
	if (disallow_abbreviated_options && (ambiguous.option || abbrev.option))
436
		die("disallowed abbreviated or ambiguous option '%.*s'",
437
		    (int)(arg_end - arg), arg);
438

439
	if (ambiguous.option) {
440
		error(_("ambiguous option: %s "
441
			"(could be --%s%s or --%s%s)"),
442
			arg,
443
			(ambiguous.flags & OPT_UNSET) ?  "no-" : "",
444
			ambiguous.option->long_name,
445
			(abbrev.flags & OPT_UNSET) ?  "no-" : "",
446
			abbrev.option->long_name);
447
		return PARSE_OPT_HELP;
448
	}
449
	if (abbrev.option) {
450
		if (*arg_end)
451
			p->opt = arg_end + 1;
452
		return get_value(p, abbrev.option, abbrev.flags);
453
	}
454
	return PARSE_OPT_UNKNOWN;
455
}
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
{
461
	for (; options->type != OPTION_END; options++) {
462
		if (!(options->flags & PARSE_OPT_NODASH))
463
			continue;
464
		if (options->short_name == arg[0] && arg[1] == '\0')
465
			return get_value(p, options, OPT_SHORT);
466
	}
467
	return PARSE_OPT_ERROR;
468
}
469

470
static enum parse_opt_result parse_subcommand(const char *arg,
471
					      const struct option *options)
472
{
473
	for (; options->type != OPTION_END; options++)
474
		if (options->type == OPTION_SUBCOMMAND &&
475
		    !strcmp(options->long_name, arg)) {
476
			*(parse_opt_subcommand_fn **)options->value = options->subcommand_fn;
477
			return PARSE_OPT_SUBCOMMAND;
478
		}
479

480
	return PARSE_OPT_UNKNOWN;
481
}
482

483
static void check_typos(const char *arg, const struct option *options)
484
{
485
	if (strlen(arg) < 3)
486
		return;
487

488
	if (starts_with(arg, "no-")) {
489
		error(_("did you mean `--%s` (with two dashes)?"), arg);
490
		exit(129);
491
	}
492

493
	for (; options->type != OPTION_END; options++) {
494
		if (!options->long_name)
495
			continue;
496
		if (starts_with(options->long_name, arg)) {
497
			error(_("did you mean `--%s` (with two dashes)?"), arg);
498
			exit(129);
499
		}
500
	}
501
}
502

503
static void parse_options_check(const struct option *opts)
504
{
505
	char short_opts[128];
506
	void *subcommand_value = NULL;
507

508
	memset(short_opts, '\0', sizeof(short_opts));
509
	for (; opts->type != OPTION_END; opts++) {
510
		if ((opts->flags & PARSE_OPT_LASTARG_DEFAULT) &&
511
		    (opts->flags & PARSE_OPT_OPTARG))
512
			optbug(opts, "uses incompatible flags "
513
			       "LASTARG_DEFAULT and OPTARG");
514
		if (opts->short_name) {
515
			if (0x7F <= opts->short_name)
516
				optbug(opts, "invalid short name");
517
			else if (short_opts[opts->short_name]++)
518
				optbug(opts, "short name already used");
519
		}
520
		if (opts->flags & PARSE_OPT_NODASH &&
521
		    ((opts->flags & PARSE_OPT_OPTARG) ||
522
		     !(opts->flags & PARSE_OPT_NOARG) ||
523
		     !(opts->flags & PARSE_OPT_NONEG) ||
524
		     opts->long_name))
525
			optbug(opts, "uses feature "
526
			       "not supported for dashless options");
527
		if (opts->type == OPTION_SET_INT && !opts->defval &&
528
		    opts->long_name && !(opts->flags & PARSE_OPT_NONEG))
529
			optbug(opts, "OPTION_SET_INT 0 should not be negatable");
530
		switch (opts->type) {
531
		case OPTION_COUNTUP:
532
		case OPTION_BIT:
533
		case OPTION_NEGBIT:
534
		case OPTION_SET_INT:
535
		case OPTION_NUMBER:
536
			if ((opts->flags & PARSE_OPT_OPTARG) ||
537
			    !(opts->flags & PARSE_OPT_NOARG))
538
				optbug(opts, "should not accept an argument");
539
			break;
540
		case OPTION_CALLBACK:
541
			if (!opts->callback && !opts->ll_callback)
542
				optbug(opts, "OPTION_CALLBACK needs one callback");
543
			else if (opts->callback && opts->ll_callback)
544
				optbug(opts, "OPTION_CALLBACK can't have two callbacks");
545
			break;
546
		case OPTION_LOWLEVEL_CALLBACK:
547
			if (!opts->ll_callback)
548
				optbug(opts, "OPTION_LOWLEVEL_CALLBACK needs a callback");
549
			if (opts->callback)
550
				optbug(opts, "OPTION_LOWLEVEL_CALLBACK needs no high level callback");
551
			break;
552
		case OPTION_ALIAS:
553
			optbug(opts, "OPT_ALIAS() should not remain at this point. "
554
			       "Are you using parse_options_step() directly?\n"
555
			       "That case is not supported yet.");
556
			break;
557
		case OPTION_SUBCOMMAND:
558
			if (!opts->value || !opts->subcommand_fn)
559
				optbug(opts, "OPTION_SUBCOMMAND needs a value and a subcommand function");
560
			if (!subcommand_value)
561
				subcommand_value = opts->value;
562
			else if (subcommand_value != opts->value)
563
				optbug(opts, "all OPTION_SUBCOMMANDs need the same value");
564
			break;
565
		default:
566
			; /* ok. (usually accepts an argument) */
567
		}
568
		if (opts->argh &&
569
		    strcspn(opts->argh, " _") != strlen(opts->argh))
570
			optbug(opts, "multi-word argh should use dash to separate words");
571
	}
572
	BUG_if_bug("invalid 'struct option'");
573
}
574

575
static int has_subcommands(const struct option *options)
576
{
577
	for (; options->type != OPTION_END; options++)
578
		if (options->type == OPTION_SUBCOMMAND)
579
			return 1;
580
	return 0;
581
}
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
{
588
	ctx->argc = argc;
589
	ctx->argv = argv;
590
	if (!(flags & PARSE_OPT_ONE_SHOT)) {
591
		ctx->argc--;
592
		ctx->argv++;
593
	}
594
	ctx->total = ctx->argc;
595
	ctx->out   = argv;
596
	ctx->prefix = prefix;
597
	ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
598
	ctx->flags = flags;
599
	ctx->has_subcommands = has_subcommands(options);
600
	if (!ctx->has_subcommands && (flags & PARSE_OPT_SUBCOMMAND_OPTIONAL))
601
		BUG("Using PARSE_OPT_SUBCOMMAND_OPTIONAL without subcommands");
602
	if (ctx->has_subcommands) {
603
		if (flags & PARSE_OPT_STOP_AT_NON_OPTION)
604
			BUG("subcommands are incompatible with PARSE_OPT_STOP_AT_NON_OPTION");
605
		if (!(flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)) {
606
			if (flags & PARSE_OPT_KEEP_UNKNOWN_OPT)
607
				BUG("subcommands are incompatible with PARSE_OPT_KEEP_UNKNOWN_OPT unless in combination with PARSE_OPT_SUBCOMMAND_OPTIONAL");
608
			if (flags & PARSE_OPT_KEEP_DASHDASH)
609
				BUG("subcommands are incompatible with PARSE_OPT_KEEP_DASHDASH unless in combination with PARSE_OPT_SUBCOMMAND_OPTIONAL");
610
		}
611
	}
612
	if ((flags & PARSE_OPT_KEEP_UNKNOWN_OPT) &&
613
	    (flags & PARSE_OPT_STOP_AT_NON_OPTION) &&
614
	    !(flags & PARSE_OPT_ONE_SHOT))
615
		BUG("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
616
	if ((flags & PARSE_OPT_ONE_SHOT) &&
617
	    (flags & PARSE_OPT_KEEP_ARGV0))
618
		BUG("Can't keep argv0 if you don't have it");
619
	parse_options_check(options);
620
	build_cmdmode_list(ctx, options);
621
}
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
{
628
	memset(ctx, 0, sizeof(*ctx));
629
	parse_options_start_1(ctx, argc, argv, prefix, options, flags);
630
}
631

632
static void show_negated_gitcomp(const struct option *opts, int show_all,
633
				 int nr_noopts)
634
{
635
	int printed_dashdash = 0;
636

637
	for (; opts->type != OPTION_END; opts++) {
638
		int has_unset_form = 0;
639
		const char *name;
640

641
		if (!opts->long_name)
642
			continue;
643
		if (!show_all &&
644
			(opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE)))
645
			continue;
646
		if (opts->flags & PARSE_OPT_NONEG)
647
			continue;
648

649
		switch (opts->type) {
650
		case OPTION_STRING:
651
		case OPTION_FILENAME:
652
		case OPTION_INTEGER:
653
		case OPTION_MAGNITUDE:
654
		case OPTION_CALLBACK:
655
		case OPTION_BIT:
656
		case OPTION_NEGBIT:
657
		case OPTION_COUNTUP:
658
		case OPTION_SET_INT:
659
			has_unset_form = 1;
660
			break;
661
		default:
662
			break;
663
		}
664
		if (!has_unset_form)
665
			continue;
666

667
		if (skip_prefix(opts->long_name, "no-", &name)) {
668
			if (nr_noopts < 0)
669
				printf(" --%s", name);
670
		} else if (nr_noopts >= 0) {
671
			if (nr_noopts && !printed_dashdash) {
672
				printf(" --");
673
				printed_dashdash = 1;
674
			}
675
			printf(" --no-%s", opts->long_name);
676
			nr_noopts++;
677
		}
678
	}
679
}
680

681
static int show_gitcomp(const struct option *opts, int show_all)
682
{
683
	const struct option *original_opts = opts;
684
	int nr_noopts = 0;
685

686
	for (; opts->type != OPTION_END; opts++) {
687
		const char *prefix = "--";
688
		const char *suffix = "";
689

690
		if (!opts->long_name)
691
			continue;
692
		if (!show_all &&
693
			(opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE | PARSE_OPT_FROM_ALIAS)))
694
			continue;
695

696
		switch (opts->type) {
697
		case OPTION_SUBCOMMAND:
698
			prefix = "";
699
			break;
700
		case OPTION_GROUP:
701
			continue;
702
		case OPTION_STRING:
703
		case OPTION_FILENAME:
704
		case OPTION_INTEGER:
705
		case OPTION_MAGNITUDE:
706
		case OPTION_CALLBACK:
707
			if (opts->flags & PARSE_OPT_NOARG)
708
				break;
709
			if (opts->flags & PARSE_OPT_OPTARG)
710
				break;
711
			if (opts->flags & PARSE_OPT_LASTARG_DEFAULT)
712
				break;
713
			suffix = "=";
714
			break;
715
		default:
716
			break;
717
		}
718
		if (opts->flags & PARSE_OPT_COMP_ARG)
719
			suffix = "=";
720
		if (starts_with(opts->long_name, "no-"))
721
			nr_noopts++;
722
		printf("%s%s%s%s", opts == original_opts ? "" : " ",
723
		       prefix, opts->long_name, suffix);
724
	}
725
	show_negated_gitcomp(original_opts, show_all, -1);
726
	show_negated_gitcomp(original_opts, show_all, nr_noopts);
727
	fputc('\n', stdout);
728
	return PARSE_OPT_COMPLETE;
729
}
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
{
743
	struct option *newopt;
744
	int i, nr, alias;
745
	int nr_aliases = 0;
746

747
	for (nr = 0; options[nr].type != OPTION_END; nr++) {
748
		if (options[nr].type == OPTION_ALIAS)
749
			nr_aliases++;
750
	}
751

752
	if (!nr_aliases)
753
		return NULL;
754

755
	DUP_ARRAY(newopt, options, nr + 1);
756

757
	/* each alias has two string pointers and NULL */
758
	CALLOC_ARRAY(ctx->alias_groups, 3 * (nr_aliases + 1));
759

760
	for (alias = 0, i = 0; i < nr; i++) {
761
		int short_name;
762
		const char *long_name;
763
		const char *source;
764
		struct strbuf help = STRBUF_INIT;
765
		int j;
766

767
		if (newopt[i].type != OPTION_ALIAS)
768
			continue;
769

770
		short_name = newopt[i].short_name;
771
		long_name = newopt[i].long_name;
772
		source = newopt[i].value;
773

774
		if (!long_name)
775
			BUG("An alias must have long option name");
776
		strbuf_addf(&help, _("alias of --%s"), source);
777

778
		for (j = 0; j < nr; j++) {
779
			const char *name = options[j].long_name;
780

781
			if (!name || strcmp(name, source))
782
				continue;
783

784
			if (options[j].type == OPTION_ALIAS)
785
				BUG("No please. Nested aliases are not supported.");
786

787
			memcpy(newopt + i, options + j, sizeof(*newopt));
788
			newopt[i].short_name = short_name;
789
			newopt[i].long_name = long_name;
790
			newopt[i].help = strbuf_detach(&help, NULL);
791
			newopt[i].flags |= PARSE_OPT_FROM_ALIAS;
792
			break;
793
		}
794

795
		if (j == nr)
796
			BUG("could not find source option '%s' of alias '%s'",
797
			    source, newopt[i].long_name);
798
		ctx->alias_groups[alias * 3 + 0] = newopt[i].long_name;
799
		ctx->alias_groups[alias * 3 + 1] = options[j].long_name;
800
		ctx->alias_groups[alias * 3 + 2] = NULL;
801
		alias++;
802
	}
803

804
	return newopt;
805
}
806

807
static void free_preprocessed_options(struct option *options)
808
{
809
	int i;
810

811
	if (!options)
812
		return;
813

814
	for (i = 0; options[i].type != OPTION_END; i++) {
815
		if (options[i].flags & PARSE_OPT_FROM_ALIAS)
816
			free((void *)options[i].help);
817
	}
818
	free(options);
819
}
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
{
830
	int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
831

832
	/* we must reset ->opt, unknown short option leave it dangling */
833
	ctx->opt = NULL;
834

835
	for (; ctx->argc; ctx->argc--, ctx->argv++) {
836
		const char *arg = ctx->argv[0];
837

838
		if (ctx->flags & PARSE_OPT_ONE_SHOT &&
839
		    ctx->argc != ctx->total)
840
			break;
841

842
		if (*arg != '-' || !arg[1]) {
843
			if (parse_nodash_opt(ctx, arg, options) == 0)
844
				continue;
845
			if (!ctx->has_subcommands) {
846
				if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
847
					return PARSE_OPT_NON_OPTION;
848
				ctx->out[ctx->cpidx++] = ctx->argv[0];
849
				continue;
850
			}
851
			switch (parse_subcommand(arg, options)) {
852
			case PARSE_OPT_SUBCOMMAND:
853
				return PARSE_OPT_SUBCOMMAND;
854
			case PARSE_OPT_UNKNOWN:
855
				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
					return PARSE_OPT_DONE;
867
				error(_("unknown subcommand: `%s'"), arg);
868
				usage_with_options(usagestr, options);
869
			case PARSE_OPT_COMPLETE:
870
			case PARSE_OPT_HELP:
871
			case PARSE_OPT_ERROR:
872
			case PARSE_OPT_DONE:
873
			case PARSE_OPT_NON_OPTION:
874
				/* Impossible. */
875
				BUG("parse_subcommand() cannot return these");
876
			}
877
		}
878

879
		/* lone -h asks for help */
880
		if (internal_help && ctx->total == 1 && !strcmp(arg + 1, "h"))
881
			goto show_usage;
882

883
		/*
884
		 * lone --git-completion-helper and --git-completion-helper-all
885
		 * are asked by git-completion.bash
886
		 */
887
		if (ctx->total == 1 && !strcmp(arg, "--git-completion-helper"))
888
			return show_gitcomp(options, 0);
889
		if (ctx->total == 1 && !strcmp(arg, "--git-completion-helper-all"))
890
			return show_gitcomp(options, 1);
891

892
		if (arg[1] != '-') {
893
			ctx->opt = arg + 1;
894
			switch (parse_short_opt(ctx, options)) {
895
			case PARSE_OPT_ERROR:
896
				return PARSE_OPT_ERROR;
897
			case PARSE_OPT_UNKNOWN:
898
				if (ctx->opt)
899
					check_typos(arg + 1, options);
900
				if (internal_help && *ctx->opt == 'h')
901
					goto show_usage;
902
				goto unknown;
903
			case PARSE_OPT_NON_OPTION:
904
			case PARSE_OPT_SUBCOMMAND:
905
			case PARSE_OPT_HELP:
906
			case PARSE_OPT_COMPLETE:
907
				BUG("parse_short_opt() cannot return these");
908
			case PARSE_OPT_DONE:
909
				break;
910
			}
911
			if (ctx->opt)
912
				check_typos(arg + 1, options);
913
			while (ctx->opt) {
914
				switch (parse_short_opt(ctx, options)) {
915
				case PARSE_OPT_ERROR:
916
					return PARSE_OPT_ERROR;
917
				case PARSE_OPT_UNKNOWN:
918
					if (internal_help && *ctx->opt == 'h')
919
						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
					ctx->argv[0] = xstrdup(ctx->opt - 1);
927
					*(char *)ctx->argv[0] = '-';
928
					goto unknown;
929
				case PARSE_OPT_NON_OPTION:
930
				case PARSE_OPT_SUBCOMMAND:
931
				case PARSE_OPT_COMPLETE:
932
				case PARSE_OPT_HELP:
933
					BUG("parse_short_opt() cannot return these");
934
				case PARSE_OPT_DONE:
935
					break;
936
				}
937
			}
938
			continue;
939
		}
940

941
		if (!arg[2] /* "--" */) {
942
			if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
943
				ctx->argc--;
944
				ctx->argv++;
945
			}
946
			break;
947
		} else if (!strcmp(arg + 2, "end-of-options")) {
948
			if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN_OPT)) {
949
				ctx->argc--;
950
				ctx->argv++;
951
			}
952
			break;
953
		}
954

955
		if (internal_help && !strcmp(arg + 2, "help-all"))
956
			return usage_with_options_internal(ctx, usagestr, options, 1, 0);
957
		if (internal_help && !strcmp(arg + 2, "help"))
958
			goto show_usage;
959
		switch (parse_long_opt(ctx, arg + 2, options)) {
960
		case PARSE_OPT_ERROR:
961
			return PARSE_OPT_ERROR;
962
		case PARSE_OPT_UNKNOWN:
963
			goto unknown;
964
		case PARSE_OPT_HELP:
965
			goto show_usage;
966
		case PARSE_OPT_NON_OPTION:
967
		case PARSE_OPT_SUBCOMMAND:
968
		case PARSE_OPT_COMPLETE:
969
			BUG("parse_long_opt() cannot return these");
970
		case PARSE_OPT_DONE:
971
			break;
972
		}
973
		continue;
974
unknown:
975
		if (ctx->flags & PARSE_OPT_ONE_SHOT)
976
			break;
977
		if (ctx->has_subcommands &&
978
		    (ctx->flags & PARSE_OPT_SUBCOMMAND_OPTIONAL) &&
979
		    (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
			return PARSE_OPT_DONE;
988
		}
989
		if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN_OPT))
990
			return PARSE_OPT_UNKNOWN;
991
		ctx->out[ctx->cpidx++] = ctx->argv[0];
992
		ctx->opt = NULL;
993
	}
994
	return PARSE_OPT_DONE;
995

996
 show_usage:
997
	return usage_with_options_internal(ctx, usagestr, options, 0, 0);
998
}
999

1000
int parse_options_end(struct parse_opt_ctx_t *ctx)
1001
{
1002
	if (ctx->flags & PARSE_OPT_ONE_SHOT)
1003
		return ctx->total - ctx->argc;
1004

1005
	MOVE_ARRAY(ctx->out + ctx->cpidx, ctx->argv, ctx->argc);
1006
	ctx->out[ctx->cpidx + ctx->argc] = NULL;
1007
	return ctx->cpidx + ctx->argc;
1008
}
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
{
1016
	struct parse_opt_ctx_t ctx;
1017
	struct option *real_options;
1018

1019
	disallow_abbreviated_options =
1020
		git_env_bool("GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS", 0);
1021

1022
	memset(&ctx, 0, sizeof(ctx));
1023
	real_options = preprocess_options(&ctx, options);
1024
	if (real_options)
1025
		options = real_options;
1026
	parse_options_start_1(&ctx, argc, argv, prefix, options, flags);
1027
	switch (parse_options_step(&ctx, options, usagestr)) {
1028
	case PARSE_OPT_HELP:
1029
	case PARSE_OPT_ERROR:
1030
		exit(129);
1031
	case PARSE_OPT_COMPLETE:
1032
		exit(0);
1033
	case PARSE_OPT_NON_OPTION:
1034
	case PARSE_OPT_SUBCOMMAND:
1035
		break;
1036
	case PARSE_OPT_DONE:
1037
		if (ctx.has_subcommands &&
1038
		    !(flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)) {
1039
			error(_("need a subcommand"));
1040
			usage_with_options(usagestr, options);
1041
		}
1042
		break;
1043
	case PARSE_OPT_UNKNOWN:
1044
		if (ctx.argv[0][1] == '-') {
1045
			error(_("unknown option `%s'"), ctx.argv[0] + 2);
1046
		} else if (isascii(*ctx.opt)) {
1047
			error(_("unknown switch `%c'"), *ctx.opt);
1048
		} else {
1049
			error(_("unknown non-ascii option in string: `%s'"),
1050
			      ctx.argv[0]);
1051
		}
1052
		usage_with_options(usagestr, options);
1053
	}
1054

1055
	precompose_argv_prefix(argc, argv, NULL);
1056
	free_preprocessed_options(real_options);
1057
	free(ctx.alias_groups);
1058
	for (struct parse_opt_cmdmode_list *elem = ctx.cmdmode_list; elem;) {
1059
		struct parse_opt_cmdmode_list *next = elem->next;
1060
		free(elem);
1061
		elem = next;
1062
	}
1063
	return parse_options_end(&ctx);
1064
}
1065

1066
static int usage_argh(const struct option *opts, FILE *outfile)
1067
{
1068
	const char *s;
1069
	int literal = (opts->flags & PARSE_OPT_LITERAL_ARGHELP) ||
1070
		!opts->argh || !!strpbrk(opts->argh, "()<>[]|");
1071
	if (opts->flags & PARSE_OPT_OPTARG)
1072
		if (opts->long_name)
1073
			s = literal ? "[=%s]" : "[=<%s>]";
1074
		else
1075
			s = literal ? "[%s]" : "[<%s>]";
1076
	else
1077
		s = literal ? " %s" : " <%s>";
1078
	return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("..."));
1079
}
1080

1081
static int usage_indent(FILE *outfile)
1082
{
1083
	return fprintf(outfile, "    ");
1084
}
1085

1086
#define USAGE_OPTS_WIDTH 26
1087

1088
static void usage_padding(FILE *outfile, size_t pos)
1089
{
1090
	if (pos < USAGE_OPTS_WIDTH)
1091
		fprintf(outfile, "%*s", USAGE_OPTS_WIDTH - (int)pos, "");
1092
	else
1093
		fprintf(outfile, "\n%*s", USAGE_OPTS_WIDTH, "");
1094
}
1095

1096
static const struct option *find_option_by_long_name(const struct option *opts,
1097
						     const char *long_name)
1098
{
1099
	for (; opts->type != OPTION_END; opts++) {
1100
		if (opts->long_name && !strcmp(opts->long_name, long_name))
1101
			return opts;
1102
	}
1103
	return NULL;
1104
}
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
{
1111
	const struct option *all_opts = opts;
1112
	FILE *outfile = err ? stderr : stdout;
1113
	int need_newline;
1114

1115
	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
	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
	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
	const char *usage_continued = _("%*s%s");
1152
	const char *prefix = usage_prefix;
1153
	int saw_empty_line = 0;
1154

1155
	if (!usagestr)
1156
		return PARSE_OPT_HELP;
1157

1158
	if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
1159
		fprintf(outfile, "cat <<\\EOF\n");
1160

1161
	while (*usagestr) {
1162
		const char *str = _(*usagestr++);
1163
		struct string_list list = STRING_LIST_INIT_DUP;
1164
		unsigned int j;
1165

1166
		if (!saw_empty_line && !*str)
1167
			saw_empty_line = 1;
1168

1169
		string_list_split(&list, str, '\n', -1);
1170
		for (j = 0; j < list.nr; j++) {
1171
			const char *line = list.items[j].string;
1172

1173
			if (saw_empty_line && *line)
1174
				fprintf_ln(outfile, _("    %s"), line);
1175
			else if (saw_empty_line)
1176
				fputc('\n', outfile);
1177
			else if (!j)
1178
				fprintf_ln(outfile, prefix, line);
1179
			else
1180
				fprintf_ln(outfile, usage_continued,
1181
					   (int)usage_len, "", line);
1182
		}
1183
		string_list_clear(&list, 0);
1184

1185
		prefix = or_prefix;
1186
	}
1187

1188
	need_newline = 1;
1189

1190
	for (; opts->type != OPTION_END; opts++) {
1191
		size_t pos;
1192
		const char *cp, *np;
1193
		const char *positive_name = NULL;
1194

1195
		if (opts->type == OPTION_SUBCOMMAND)
1196
			continue;
1197
		if (opts->type == OPTION_GROUP) {
1198
			fputc('\n', outfile);
1199
			need_newline = 0;
1200
			if (*opts->help)
1201
				fprintf(outfile, "%s\n", _(opts->help));
1202
			continue;
1203
		}
1204
		if (!full && (opts->flags & PARSE_OPT_HIDDEN))
1205
			continue;
1206

1207
		if (need_newline) {
1208
			fputc('\n', outfile);
1209
			need_newline = 0;
1210
		}
1211

1212
		pos = usage_indent(outfile);
1213
		if (opts->short_name) {
1214
			if (opts->flags & PARSE_OPT_NODASH)
1215
				pos += fprintf(outfile, "%c", opts->short_name);
1216
			else
1217
				pos += fprintf(outfile, "-%c", opts->short_name);
1218
		}
1219
		if (opts->long_name && opts->short_name)
1220
			pos += fprintf(outfile, ", ");
1221
		if (opts->long_name) {
1222
			const char *long_name = opts->long_name;
1223
			if ((opts->flags & PARSE_OPT_NONEG) ||
1224
			    skip_prefix(long_name, "no-", &positive_name))
1225
				pos += fprintf(outfile, "--%s", long_name);
1226
			else
1227
				pos += fprintf(outfile, "--[no-]%s", long_name);
1228
		}
1229

1230
		if (opts->type == OPTION_NUMBER)
1231
			pos += utf8_fprintf(outfile, _("-NUM"));
1232

1233
		if ((opts->flags & PARSE_OPT_LITERAL_ARGHELP) ||
1234
		    !(opts->flags & PARSE_OPT_NOARG))
1235
			pos += usage_argh(opts, outfile);
1236

1237
		if (opts->type == OPTION_ALIAS) {
1238
			usage_padding(outfile, pos);
1239
			fprintf_ln(outfile, _("alias of --%s"),
1240
				   (const char *)opts->value);
1241
			continue;
1242
		}
1243

1244
		for (cp = opts->help ? _(opts->help) : ""; *cp; cp = np) {
1245
			np = strchrnul(cp, '\n');
1246
			if (*np)
1247
				np++;
1248
			usage_padding(outfile, pos);
1249
			fwrite(cp, 1, np - cp, outfile);
1250
			pos = 0;
1251
		}
1252
		fputc('\n', outfile);
1253

1254
		if (positive_name) {
1255
			if (find_option_by_long_name(all_opts, positive_name))
1256
				continue;
1257
			pos = usage_indent(outfile);
1258
			pos += fprintf(outfile, "--%s", positive_name);
1259
			usage_padding(outfile, pos);
1260
			fprintf_ln(outfile, _("opposite of --no-%s"),
1261
				   positive_name);
1262
		}
1263
	}
1264
	fputc('\n', outfile);
1265

1266
	if (!err && ctx && ctx->flags & PARSE_OPT_SHELL_EVAL)
1267
		fputs("EOF\n", outfile);
1268

1269
	return PARSE_OPT_HELP;
1270
}
1271

1272
void NORETURN usage_with_options(const char * const *usagestr,
1273
			const struct option *opts)
1274
{
1275
	usage_with_options_internal(NULL, usagestr, opts, 0, 1);
1276
	exit(129);
1277
}
1278

1279
void NORETURN usage_msg_opt(const char *msg,
1280
		   const char * const *usagestr,
1281
		   const struct option *options)
1282
{
1283
	die_message("%s\n", msg); /* The extra \n is intentional */
1284
	usage_with_options(usagestr, options);
1285
}
1286

1287
void NORETURN usage_msg_optf(const char * const fmt,
1288
			     const char * const *usagestr,
1289
			     const struct option *options, ...)
1290
{
1291
	struct strbuf msg = STRBUF_INIT;
1292
	va_list ap;
1293
	va_start(ap, options);
1294
	strbuf_vaddf(&msg, fmt, ap);
1295
	va_end(ap);
1296

1297
	usage_msg_opt(msg.buf, usagestr, options);
1298
}
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
{
1305
	int count = 0;
1306
	const char *options[4];
1307

1308
	if (opt1)
1309
		options[count++] = opt1_name;
1310
	if (opt2)
1311
		options[count++] = opt2_name;
1312
	if (opt3)
1313
		options[count++] = opt3_name;
1314
	if (opt4)
1315
		options[count++] = opt4_name;
1316
	switch (count) {
1317
	case 4:
1318
		die(_("options '%s', '%s', '%s', and '%s' cannot be used together"),
1319
		    opt1_name, opt2_name, opt3_name, opt4_name);
1320
		break;
1321
	case 3:
1322
		die(_("options '%s', '%s', and '%s' cannot be used together"),
1323
		    options[0], options[1], options[2]);
1324
		break;
1325
	case 2:
1326
		die(_("options '%s' and '%s' cannot be used together"),
1327
		    options[0], options[1]);
1328
		break;
1329
	default:
1330
		break;
1331
	}
1332
}
1333

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.