#include "git-compat-util.h"
#include "parse-options.h"
#include "abspath.h"
#include "parse.h"
#include "gettext.h"
#include "strbuf.h"
#include "string-list.h"
#include "strmap.h"
#include "utf8.h"

static int disallow_abbreviated_options;

enum opt_parsed {
	OPT_LONG  = 0,
	OPT_SHORT = 1<<0,
	OPT_UNSET = 1<<1,
};

static void optbug(const struct option *opt, const char *reason)
{
	if (opt->long_name && opt->short_name)
		bug("switch '%c' (--%s) %s", opt->short_name,
		    opt->long_name, reason);
	else if (opt->long_name)
		bug("option '%s' %s", opt->long_name, reason);
	else
		bug("switch '%c' %s", opt->short_name, reason);
}

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

	strbuf_reset(&sb);
	if (flags & OPT_SHORT)
		strbuf_addf(&sb, "switch `%c'", opt->short_name);
	else if (flags & OPT_UNSET)
		strbuf_addf(&sb, "option `no-%s'", opt->long_name);
	else if (flags == OPT_LONG)
		strbuf_addf(&sb, "option `%s'", opt->long_name);
	else
		BUG("optname() got unknown flags %d", flags);

	return sb.buf;
}

static enum parse_opt_result get_arg(struct parse_opt_ctx_t *p,
				     const struct option *opt,
				     enum opt_parsed flags, const char **arg)
{
	if (p->opt) {
		*arg = p->opt;
		p->opt = NULL;
	} else if (p->argc == 1 && (opt->flags & PARSE_OPT_LASTARG_DEFAULT)) {
		*arg = (const char *)opt->defval;
	} else if (p->argc > 1) {
		p->argc--;
		*arg = *++p->argv;
	} else
		return error(_("%s requires a value"), optname(opt, flags));
	return 0;
}

static char *fix_filename(const char *prefix, const char *file)
{
	if (!file || !*file)
		return NULL;
	else
		return prefix_filename_except_for_dash(prefix, file);
}

static int do_get_int_value(const void *value, size_t precision, intmax_t *ret)
{
	switch (precision) {
	case sizeof(int8_t):
		*ret = *(int8_t *)value;
		return 0;
	case sizeof(int16_t):
		*ret = *(int16_t *)value;
		return 0;
	case sizeof(int32_t):
		*ret = *(int32_t *)value;
		return 0;
	case sizeof(int64_t):
		*ret = *(int64_t *)value;
		return 0;
	default:
		return -1;
	}
}

static intmax_t get_int_value(const struct option *opt, enum opt_parsed flags)
{
	intmax_t ret;
	if (do_get_int_value(opt->value, opt->precision, &ret))
		BUG("invalid precision for option %s", optname(opt, flags));
	return ret;
}

static enum parse_opt_result set_int_value(const struct option *opt,
					   enum opt_parsed flags,
					   intmax_t value)
{
	switch (opt->precision) {
	case sizeof(int8_t):
		*(int8_t *)opt->value = value;
		return 0;
	case sizeof(int16_t):
		*(int16_t *)opt->value = value;
		return 0;
	case sizeof(int32_t):
		*(int32_t *)opt->value = value;
		return 0;
	case sizeof(int64_t):
		*(int64_t *)opt->value = value;
		return 0;
	default:
		BUG("invalid precision for option %s", optname(opt, flags));
	}
}

static int signed_int_fits(intmax_t value, size_t precision)
{
	size_t bits = precision * CHAR_BIT;
	intmax_t upper_bound = INTMAX_MAX >> (bitsizeof(intmax_t) - bits);
	intmax_t lower_bound = -upper_bound - 1;
	return lower_bound <= value && value <= upper_bound;
}

static enum parse_opt_result do_get_value(struct parse_opt_ctx_t *p,
					  const struct option *opt,
					  enum opt_parsed flags,
					  const char **argp)
{
	const char *arg;
	const int unset = flags & OPT_UNSET;

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

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

	case OPTION_BIT:
	{
		intmax_t value = get_int_value(opt, flags);
		if (unset)
			value &= ~opt->defval;
		else
			value |= opt->defval;
		return set_int_value(opt, flags, value);
	}

	case OPTION_NEGBIT:
	{
		intmax_t value = get_int_value(opt, flags);
		if (unset)
			value |= opt->defval;
		else
			value &= ~opt->defval;
		return set_int_value(opt, flags, value);
	}

	case OPTION_BITOP:
	{
		intmax_t value = get_int_value(opt, flags);
		if (unset)
			BUG("BITOP can't have unset form");
		value &= ~opt->extra;
		value |= opt->defval;
		return set_int_value(opt, flags, value);
	}

	case OPTION_COUNTUP:
	{
		size_t bits = CHAR_BIT * opt->precision;
		intmax_t upper_bound = INTMAX_MAX >> (bitsizeof(intmax_t) - bits);
		intmax_t value = get_int_value(opt, flags);

		if (value < 0)
			value = 0;
		if (unset)
			value = 0;
		else if (value < upper_bound)
			value++;
		else
			return error(_("value for %s exceeds %"PRIdMAX),
				     optname(opt, flags), upper_bound);
		return set_int_value(opt, flags, value);
	}

	case OPTION_SET_INT:
		return set_int_value(opt, flags, unset ? 0 : opt->defval);

	case OPTION_STRING:
		if (unset)
			*(const char **)opt->value = NULL;
		else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
			*(const char **)opt->value = (const char *)opt->defval;
		else
			return get_arg(p, opt, flags, (const char **)opt->value);
		return 0;

	case OPTION_FILENAME:
	{
		const char *value;
		bool is_optional;

		if (unset)
			value = NULL;
		else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
			value = (const char *)opt->defval;
		else {
			int err = get_arg(p, opt, flags, &value);
			if (err)
				return err;
		}
		if (!value)
			return 0;

		is_optional = skip_prefix(value, ":(optional)", &value);
		value = fix_filename(p->prefix, value);
		if (is_optional && is_missing_file(value)) {
			free((char *)value);
		} else {
			FREE_AND_NULL(*(char **)opt->value);
			*(const char **)opt->value = value;
		}
		return 0;
	}
	case OPTION_CALLBACK:
	{
		const char *p_arg = NULL;
		int p_unset;

		if (unset)
			p_unset = 1;
		else if (opt->flags & PARSE_OPT_NOARG)
			p_unset = 0;
		else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
			p_unset = 0;
		else if (get_arg(p, opt, flags, &arg))
			return -1;
		else {
			p_unset = 0;
			p_arg = arg;
		}
		if (opt->flags & PARSE_OPT_CMDMODE)
			*argp = p_arg;
		if (opt->callback)
			return (*opt->callback)(opt, p_arg, p_unset) ? (-1) : 0;
		else
			return (*opt->ll_callback)(p, opt, p_arg, p_unset);
	}
	case OPTION_INTEGER:
	{
		intmax_t upper_bound = INTMAX_MAX >> (bitsizeof(intmax_t) - CHAR_BIT * opt->precision);
		intmax_t lower_bound = -upper_bound - 1;
		intmax_t value;

		if (unset) {
			value = 0;
		} else if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
			value = opt->defval;
		} else if (get_arg(p, opt, flags, &arg)) {
			return -1;
		} else if (!*arg) {
			return error(_("%s expects a numerical value"),
				     optname(opt, flags));
		} else if (!git_parse_signed(arg, &value, upper_bound)) {
			if (errno == ERANGE)
				return error(_("value %s for %s not in range [%"PRIdMAX",%"PRIdMAX"]"),
					     arg, optname(opt, flags), lower_bound, upper_bound);

			return error(_("%s expects an integer value with an optional k/m/g suffix"),
				     optname(opt, flags));
		}

		if (value < lower_bound)
			return error(_("value %s for %s not in range [%"PRIdMAX",%"PRIdMAX"]"),
				     arg, optname(opt, flags), (intmax_t)lower_bound, (intmax_t)upper_bound);

		return set_int_value(opt, flags, value);
	}
	case OPTION_UNSIGNED:
	{
		uintmax_t upper_bound = UINTMAX_MAX >> (bitsizeof(uintmax_t) - CHAR_BIT * opt->precision);
		uintmax_t value;

		if (unset) {
			value = 0;
		} else if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
			value = opt->defval;
		} else if (get_arg(p, opt, flags, &arg)) {
			return -1;
		} else if (!*arg) {
			return error(_("%s expects a numerical value"),
				     optname(opt, flags));
		} else if (!git_parse_unsigned(arg, &value, upper_bound)) {
			if (errno == ERANGE)
				return error(_("value %s for %s not in range [%"PRIdMAX",%"PRIdMAX"]"),
					     arg, optname(opt, flags), (uintmax_t) 0, upper_bound);

			return error(_("%s expects a non-negative integer value"
				       " with an optional k/m/g suffix"),
				     optname(opt, flags));
		}

		switch (opt->precision) {
		case 1:
			*(uint8_t *)opt->value = value;
			return 0;
		case 2:
			*(uint16_t *)opt->value = value;
			return 0;
		case 4:
			*(uint32_t *)opt->value = value;
			return 0;
		case 8:
			*(uint64_t *)opt->value = value;
			return 0;
		default:
			BUG("invalid precision for option %s",
			    optname(opt, flags));
		}
	}

	default:
		BUG("opt->type %d should not happen", opt->type);
	}
}

struct parse_opt_cmdmode_list {
	intmax_t value;
	void *value_ptr;
	size_t precision;
	const struct option *opt;
	const char *arg;
	enum opt_parsed flags;
	struct parse_opt_cmdmode_list *next;
};

static void build_cmdmode_list(struct parse_opt_ctx_t *ctx,
			       const struct option *opts)
{
	ctx->cmdmode_list = NULL;

	for (; opts->type != OPTION_END; opts++) {
		struct parse_opt_cmdmode_list *elem = ctx->cmdmode_list;
		void *value_ptr = opts->value;

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

		while (elem && elem->value_ptr != value_ptr)
			elem = elem->next;
		if (elem)
			continue;

		CALLOC_ARRAY(elem, 1);
		elem->value_ptr = value_ptr;
		elem->precision = opts->precision;
		if (do_get_int_value(value_ptr, opts->precision, &elem->value))
			optbug(opts, "has invalid precision");
		elem->next = ctx->cmdmode_list;
		ctx->cmdmode_list = elem;
	}
	BUG_if_bug("invalid 'struct option'");
}

static char *optnamearg(const struct option *opt, const char *arg,
			enum opt_parsed flags)
{
	if (flags & OPT_SHORT)
		return xstrfmt("-%c%s", opt->short_name, arg ? arg : "");
	return xstrfmt("--%s%s%s%s", flags & OPT_UNSET ? "no-" : "",
		       opt->long_name, arg ? "=" : "", arg ? arg : "");
}

static enum parse_opt_result get_value(struct parse_opt_ctx_t *p,
				       const struct option *opt,
				       enum opt_parsed flags)
{
	const char *arg = NULL;
	enum parse_opt_result result = do_get_value(p, opt, flags, &arg);
	struct parse_opt_cmdmode_list *elem = p->cmdmode_list;
	char *opt_name, *other_opt_name;

	for (; elem; elem = elem->next) {
		intmax_t new_value;

		if (do_get_int_value(elem->value_ptr, elem->precision,
				     &new_value))
			BUG("impossible: invalid precision");

		if (new_value == elem->value)
			continue;

		if (elem->opt &&
		    (elem->opt->flags | opt->flags) & PARSE_OPT_CMDMODE)
			break;

		elem->opt = opt;
		elem->arg = arg;
		elem->flags = flags;
		elem->value = new_value;
	}

	if (result || !elem)
		return result;

	opt_name = optnamearg(opt, arg, flags);
	other_opt_name = optnamearg(elem->opt, elem->arg, elem->flags);
	error(_("options '%s' and '%s' cannot be used together"),
	      opt_name, other_opt_name);
	free(opt_name);
	free(other_opt_name);
	return -1;
}

static enum parse_opt_result parse_short_opt(struct parse_opt_ctx_t *p,
					     const struct option *options)
{
	const struct option *numopt = NULL;

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

		/*
		 * Handle the numerical option later, explicit one-digit
		 * options take precedence over it.
		 */
		if (options->type == OPTION_NUMBER)
			numopt = options;
	}
	if (numopt && isdigit(*p->opt)) {
		size_t len = 1;
		char *arg;
		int rc;

		while (isdigit(p->opt[len]))
			len++;
		arg = xmemdupz(p->opt, len);
		p->opt = p->opt[len] ? p->opt + len : NULL;
		if (numopt->callback)
			rc = (*numopt->callback)(numopt, arg, 0) ? (-1) : 0;
		else
			rc = (*numopt->ll_callback)(p, numopt, arg, 0);
		free(arg);
		return rc;
	}
	return PARSE_OPT_UNKNOWN;
}

static int has_string(const char *it, const char **array)
{
	while (*array)
		if (!strcmp(it, *(array++)))
			return 1;
	return 0;
}

static int is_alias(struct parse_opt_ctx_t *ctx,
		    const struct option *one_opt,
		    const struct option *another_opt)
{
	const char **group;

	if (!ctx->alias_groups)
		return 0;

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

	for (group = ctx->alias_groups; *group; group += 3) {
		/* it and other are from the same family? */
		if (has_string(one_opt->long_name, group) &&
		    has_string(another_opt->long_name, group))
			return 1;
	}
	return 0;
}

struct parsed_option {
	const struct option *option;
	enum opt_parsed flags;
};

static void register_abbrev(struct parse_opt_ctx_t *p,
			    const struct option *option, enum opt_parsed flags,
			    struct parsed_option *abbrev,
			    struct parsed_option *ambiguous)
{
	if (p->flags & PARSE_OPT_KEEP_UNKNOWN_OPT)
		return;
	if (abbrev->option &&
	    !(abbrev->flags == flags && is_alias(p, abbrev->option, option))) {
		/*
		 * If this is abbreviated, it is
		 * ambiguous. So when there is no
		 * exact match later, we need to
		 * error out.
		 */
		ambiguous->option = abbrev->option;
		ambiguous->flags = abbrev->flags;
	}
	abbrev->option = option;
	abbrev->flags = flags;
}

static enum parse_opt_result parse_long_opt(
	struct parse_opt_ctx_t *p, const char *arg,
	const struct option *options)
{
	const char *arg_end = strchrnul(arg, '=');
	const char *arg_start = arg;
	enum opt_parsed flags = OPT_LONG;
	int arg_starts_with_no_no = 0;
	struct parsed_option abbrev = { .option = NULL, .flags = OPT_LONG };
	struct parsed_option ambiguous = { .option = NULL, .flags = OPT_LONG };

	if (skip_prefix(arg_start, "no-", &arg_start)) {
		if (skip_prefix(arg_start, "no-", &arg_start))
			arg_starts_with_no_no = 1;
		else
			flags |= OPT_UNSET;
	}

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

		if (options->type == OPTION_SUBCOMMAND)
			continue;
		if (!long_name)
			continue;

		if (skip_prefix(long_name, "no-", &long_name))
			opt_flags |= OPT_UNSET;
		else if (arg_starts_with_no_no)
			continue;

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

		if (skip_prefix(arg_start, long_name, &rest)) {
			if (*rest == '=')
				p->opt = rest + 1;
			else if (*rest)
				continue;
			return get_value(p, options, flags ^ opt_flags);
		}

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

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

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

	if (ambiguous.option) {
		error(_("ambiguous option: %s "
			"(could be --%s%s or --%s%s)"),
			arg,
			(ambiguous.flags & OPT_UNSET) ?  "no-" : "",
			ambiguous.option->long_name,
			(abbrev.flags & OPT_UNSET) ?  "no-" : "",
			abbrev.option->long_name);
		return PARSE_OPT_HELP;
	}
	if (abbrev.option) {
		if (*arg_end)
			p->opt = arg_end + 1;
		return get_value(p, abbrev.option, abbrev.flags);
	}
	return PARSE_OPT_UNKNOWN;
}

static enum parse_opt_result parse_nodash_opt(struct parse_opt_ctx_t *p,
					      const char *arg,
					      const struct option *options)
{
	for (; options->type != OPTION_END; options++) {
		if (!(options->flags & PARSE_OPT_NODASH))
			continue;
		if (options->short_name == arg[0] && arg[1] == '\0')
			return get_value(p, options, OPT_SHORT);
	}
	return PARSE_OPT_ERROR;
}

static enum parse_opt_result parse_subcommand(const char *arg,
					      const struct option *options)
{
	for (; options->type != OPTION_END; options++)
		if (options->type == OPTION_SUBCOMMAND &&
		    !strcmp(options->long_name, arg)) {
			*(parse_opt_subcommand_fn **)options->value = options->subcommand_fn;
			return PARSE_OPT_SUBCOMMAND;
		}

	return PARSE_OPT_UNKNOWN;
}

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

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

	for (; options->type != OPTION_END; options++) {
		if (!options->long_name)
			continue;
		if (starts_with(options->long_name, arg)) {
			error(_("did you mean `--%s` (with two dashes)?"), arg);
			exit(129);
		}
	}
}

static void parse_options_check(const struct option *opts)
{
	char short_opts[128];
	bool saw_number_option = false;
	void *subcommand_value = NULL;

	memset(short_opts, '\0', sizeof(short_opts));
	for (; opts->type != OPTION_END; opts++) {
		if ((opts->flags & PARSE_OPT_LASTARG_DEFAULT) &&
		    (opts->flags & PARSE_OPT_OPTARG))
			optbug(opts, "uses incompatible flags "
			       "LASTARG_DEFAULT and OPTARG");
		if (opts->short_name) {
			if (0x7F <= opts->short_name)
				optbug(opts, "invalid short name");
			else if (short_opts[opts->short_name]++)
				optbug(opts, "short name already used");
		}
		if (opts->type == OPTION_NUMBER) {
			if (saw_number_option)
				optbug(opts, "duplicate numerical option");
			saw_number_option = true;
		}
		if (opts->flags & PARSE_OPT_NODASH &&
		    ((opts->flags & PARSE_OPT_OPTARG) ||
		     !(opts->flags & PARSE_OPT_NOARG) ||
		     !(opts->flags & PARSE_OPT_NONEG) ||
		     opts->long_name))
			optbug(opts, "uses feature "
			       "not supported for dashless options");
		if (opts->type == OPTION_SET_INT && !opts->defval &&
		    opts->long_name && !(opts->flags & PARSE_OPT_NONEG))
			optbug(opts, "OPTION_SET_INT 0 should not be negatable");
		switch (opts->type) {
		case OPTION_SET_INT:
		case OPTION_BIT:
		case OPTION_NEGBIT:
		case OPTION_BITOP:
		case OPTION_COUNTUP:
			if (!signed_int_fits(opts->defval, opts->precision))
				optbug(opts, "has invalid defval");
			/* fallthru */
		case OPTION_NUMBER:
			if ((opts->flags & PARSE_OPT_OPTARG) ||
			    !(opts->flags & PARSE_OPT_NOARG))
				optbug(opts, "should not accept an argument");
			break;
		case OPTION_CALLBACK:
			if (!opts->callback && !opts->ll_callback)
				optbug(opts, "OPTION_CALLBACK needs one callback");
			else if (opts->callback && opts->ll_callback)
				optbug(opts, "OPTION_CALLBACK can't have two callbacks");
			break;
		case OPTION_LOWLEVEL_CALLBACK:
			if (!opts->ll_callback)
				optbug(opts, "OPTION_LOWLEVEL_CALLBACK needs a callback");
			if (opts->callback)
				optbug(opts, "OPTION_LOWLEVEL_CALLBACK needs no high level callback");
			break;
		case OPTION_ALIAS:
			optbug(opts, "OPT_ALIAS() should not remain at this point. "
			       "Are you using parse_options_step() directly?\n"
			       "That case is not supported yet.");
			break;
		case OPTION_SUBCOMMAND:
			if (!opts->value || !opts->subcommand_fn)
				optbug(opts, "OPTION_SUBCOMMAND needs a value and a subcommand function");
			if (!subcommand_value)
				subcommand_value = opts->value;
			else if (subcommand_value != opts->value)
				optbug(opts, "all OPTION_SUBCOMMANDs need the same value");
			break;
		default:
			; /* ok. (usually accepts an argument) */
		}
		if (opts->argh &&
		    strcspn(opts->argh, " _") != strlen(opts->argh))
			optbug(opts, "multi-word argh should use dash to separate words");
	}
	BUG_if_bug("invalid 'struct option'");
}

static void parse_options_check_harder(const struct option *opts)
{
	struct strset long_names = STRSET_INIT;

	for (; opts->type != OPTION_END; opts++) {
		if (opts->long_name) {
			if (!strset_add(&long_names, opts->long_name))
				optbug(opts, "long name already used");
		}
	}
	BUG_if_bug("invalid 'struct option'");
	strset_clear(&long_names);
}

static int has_subcommands(const struct option *options)
{
	for (; options->type != OPTION_END; options++)
		if (options->type == OPTION_SUBCOMMAND)
			return 1;
	return 0;
}

static void parse_options_start_1(struct parse_opt_ctx_t *ctx,
				  int argc, const char **argv, const char *prefix,
				  const struct option *options,
				  enum parse_opt_flags flags)
{
	ctx->argc = argc;
	ctx->argv = argv;
	if (!(flags & PARSE_OPT_ONE_SHOT)) {
		ctx->argc--;
		ctx->argv++;
	}
	ctx->total = ctx->argc;
	ctx->out   = argv;
	ctx->prefix = prefix;
	ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
	ctx->flags = flags;
	ctx->has_subcommands = has_subcommands(options);
	if (!ctx->has_subcommands && (flags & PARSE_OPT_SUBCOMMAND_OPTIONAL))
		BUG("Using PARSE_OPT_SUBCOMMAND_OPTIONAL without subcommands");
	if (ctx->has_subcommands) {
		if (flags & PARSE_OPT_STOP_AT_NON_OPTION)
			BUG("subcommands are incompatible with PARSE_OPT_STOP_AT_NON_OPTION");
		if (!(flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)) {
			if (flags & PARSE_OPT_KEEP_UNKNOWN_OPT)
				BUG("subcommands are incompatible with PARSE_OPT_KEEP_UNKNOWN_OPT unless in combination with PARSE_OPT_SUBCOMMAND_OPTIONAL");
			if (flags & PARSE_OPT_KEEP_DASHDASH)
				BUG("subcommands are incompatible with PARSE_OPT_KEEP_DASHDASH unless in combination with PARSE_OPT_SUBCOMMAND_OPTIONAL");
		}
	}
	if ((flags & PARSE_OPT_KEEP_UNKNOWN_OPT) &&
	    (flags & PARSE_OPT_STOP_AT_NON_OPTION) &&
	    !(flags & PARSE_OPT_ONE_SHOT))
		BUG("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
	if ((flags & PARSE_OPT_ONE_SHOT) &&
	    (flags & PARSE_OPT_KEEP_ARGV0))
		BUG("Can't keep argv0 if you don't have it");
	parse_options_check(options);
	build_cmdmode_list(ctx, options);
}

void parse_options_start(struct parse_opt_ctx_t *ctx,
			 int argc, const char **argv, const char *prefix,
			 const struct option *options,
			 enum parse_opt_flags flags)
{
	memset(ctx, 0, sizeof(*ctx));
	parse_options_start_1(ctx, argc, argv, prefix, options, flags);
}

static void show_negated_gitcomp(const struct option *opts, int show_all,
				 int nr_noopts)
{
	int printed_dashdash = 0;

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

		if (!opts->long_name)
			continue;
		if (!show_all &&
			(opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE)))
			continue;
		if (opts->flags & PARSE_OPT_NONEG)
			continue;

		switch (opts->type) {
		case OPTION_STRING:
		case OPTION_FILENAME:
		case OPTION_INTEGER:
		case OPTION_UNSIGNED:
		case OPTION_CALLBACK:
		case OPTION_BIT:
		case OPTION_NEGBIT:
		case OPTION_COUNTUP:
		case OPTION_SET_INT:
			has_unset_form = 1;
			break;
		default:
			break;
		}
		if (!has_unset_form)
			continue;

		if (skip_prefix(opts->long_name, "no-", &name)) {
			if (nr_noopts < 0)
				printf(" --%s", name);
		} else if (nr_noopts >= 0) {
			if (nr_noopts && !printed_dashdash) {
				printf(" --");
				printed_dashdash = 1;
			}
			printf(" --no-%s", opts->long_name);
			nr_noopts++;
		}
	}
}

static int show_gitcomp(const struct option *opts, int show_all)
{
	const struct option *original_opts = opts;
	int nr_noopts = 0;

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

		if (!opts->long_name)
			continue;
		if (!show_all &&
			(opts->flags & (PARSE_OPT_HIDDEN | PARSE_OPT_NOCOMPLETE | PARSE_OPT_FROM_ALIAS)))
			continue;

		switch (opts->type) {
		case OPTION_SUBCOMMAND:
			prefix = "";
			break;
		case OPTION_GROUP:
			continue;
		case OPTION_STRING:
		case OPTION_FILENAME:
		case OPTION_INTEGER:
		case OPTION_UNSIGNED:
		case OPTION_CALLBACK:
			if (opts->flags & PARSE_OPT_NOARG)
				break;
			if (opts->flags & PARSE_OPT_OPTARG)
				break;
			if (opts->flags & PARSE_OPT_LASTARG_DEFAULT)
				break;
			suffix = "=";
			break;
		default:
			break;
		}
		if (opts->flags & PARSE_OPT_COMP_ARG)
			suffix = "=";
		if (starts_with(opts->long_name, "no-"))
			nr_noopts++;
		printf("%s%s%s%s", opts == original_opts ? "" : " ",
		       prefix, opts->long_name, suffix);
	}
	show_negated_gitcomp(original_opts, show_all, -1);
	show_negated_gitcomp(original_opts, show_all, nr_noopts);
	fputc('\n', stdout);
	return PARSE_OPT_COMPLETE;
}

/*
 * Scan and may produce a new option[] array, which should be used
 * instead of the original 'options'.
 *
 * Right now this is only used to preprocess and substitute
 * OPTION_ALIAS.
 *
 * The returned options should be freed using free_preprocessed_options.
 */
static struct option *preprocess_options(struct parse_opt_ctx_t *ctx,
					 const struct option *options)
{
	struct option *newopt;
	int i, nr, alias;
	int nr_aliases = 0;

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

	if (!nr_aliases)
		return NULL;

	DUP_ARRAY(newopt, options, nr + 1);

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

	for (alias = 0, i = 0; i < nr; i++) {
		int short_name;
		const char *long_name;
		const char *source;
		struct strbuf help = STRBUF_INIT;
		int j;

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

		short_name = newopt[i].short_name;
		long_name = newopt[i].long_name;
		source = newopt[i].value;

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

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

			if (!name || strcmp(name, source))
				continue;

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

			memcpy(newopt + i, options + j, sizeof(*newopt));
			newopt[i].short_name = short_name;
			newopt[i].long_name = long_name;
			newopt[i].help = strbuf_detach(&help, NULL);
			newopt[i].flags |= PARSE_OPT_FROM_ALIAS;
			break;
		}

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

	return newopt;
}

static void free_preprocessed_options(struct option *options)
{
	int i;

	if (!options)
		return;

	for (i = 0; options[i].type != OPTION_END; i++) {
		if (options[i].flags & PARSE_OPT_FROM_ALIAS)
			free((void *)options[i].help);
	}
	free(options);
}

#define USAGE_NORMAL 0
#define USAGE_FULL 1
#define USAGE_TO_STDOUT 0
#define USAGE_TO_STDERR 1

static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t *,
							 const char * const *,
							 const struct option *,
							 int full_usage,
							 int usage_to_stderr);

enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx,
					 const struct option *options,
					 const char * const usagestr[])
{
	int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);

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

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

		if (ctx->flags & PARSE_OPT_ONE_SHOT &&
		    ctx->argc != ctx->total)
			break;

		if (*arg != '-' || !arg[1]) {
			if (parse_nodash_opt(ctx, arg, options) == 0)
				continue;
			if (!ctx->has_subcommands) {
				if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
					return PARSE_OPT_NON_OPTION;
				ctx->out[ctx->cpidx++] = ctx->argv[0];
				continue;
			}
			switch (parse_subcommand(arg, options)) {
			case PARSE_OPT_SUBCOMMAND:
				return PARSE_OPT_SUBCOMMAND;
			case PARSE_OPT_UNKNOWN:
				if (ctx->flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)
					/*
					 * arg is neither a short or long
					 * option nor a subcommand.  Since
					 * this command has a default
					 * operation mode, we have to treat
					 * this arg and all remaining args
					 * as args meant to that default
					 * operation mode.
					 * So we are done parsing.
					 */
					return PARSE_OPT_DONE;
				error(_("unknown subcommand: `%s'"), arg);
				usage_with_options(usagestr, options);
			case PARSE_OPT_COMPLETE:
			case PARSE_OPT_HELP:
			case PARSE_OPT_ERROR:
			case PARSE_OPT_DONE:
			case PARSE_OPT_NON_OPTION:
				/* Impossible. */
				BUG("parse_subcommand() cannot return these");
			}
		}

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

		/*
		 * lone --git-completion-helper and --git-completion-helper-all
		 * are asked by git-completion.bash
		 */
		if (ctx->total == 1 && !strcmp(arg, "--git-completion-helper"))
			return show_gitcomp(options, 0);
		if (ctx->total == 1 && !strcmp(arg, "--git-completion-helper-all"))
			return show_gitcomp(options, 1);

		if (arg[1] != '-') {
			ctx->opt = arg + 1;
			switch (parse_short_opt(ctx, options)) {
			case PARSE_OPT_ERROR:
				return PARSE_OPT_ERROR;
			case PARSE_OPT_UNKNOWN:
				if (ctx->opt)
					check_typos(arg + 1, options);
				if (internal_help && *ctx->opt == 'h')
					goto show_usage;
				goto unknown;
			case PARSE_OPT_NON_OPTION:
			case PARSE_OPT_SUBCOMMAND:
			case PARSE_OPT_HELP:
			case PARSE_OPT_COMPLETE:
				BUG("parse_short_opt() cannot return these");
			case PARSE_OPT_DONE:
				break;
			}
			if (ctx->opt)
				check_typos(arg + 1, options);
			while (ctx->opt) {
				switch (parse_short_opt(ctx, options)) {
				case PARSE_OPT_ERROR:
					return PARSE_OPT_ERROR;
				case PARSE_OPT_UNKNOWN:
					if (internal_help && *ctx->opt == 'h')
						goto show_usage;

					/* fake a short option thing to hide the fact that we may have
					 * started to parse aggregated stuff
					 *
					 * This is leaky, too bad.
					 */
					ctx->argv[0] = xstrdup(ctx->opt - 1);
					*(char *)ctx->argv[0] = '-';
					goto unknown;
				case PARSE_OPT_NON_OPTION:
				case PARSE_OPT_SUBCOMMAND:
				case PARSE_OPT_COMPLETE:
				case PARSE_OPT_HELP:
					BUG("parse_short_opt() cannot return these");
				case PARSE_OPT_DONE:
					break;
				}
			}
			continue;
		}

		if (!arg[2] /* "--" */) {
			if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
				ctx->argc--;
				ctx->argv++;
			}
			break;
		} else if (!strcmp(arg + 2, "end-of-options")) {
			if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN_OPT)) {
				ctx->argc--;
				ctx->argv++;
			}
			break;
		}

		if (internal_help && !strcmp(arg + 2, "help-all"))
			return usage_with_options_internal(ctx, usagestr, options,
							   USAGE_FULL, USAGE_TO_STDOUT);
		if (internal_help && !strcmp(arg + 2, "help"))
			goto show_usage;
		switch (parse_long_opt(ctx, arg + 2, options)) {
		case PARSE_OPT_ERROR:
			return PARSE_OPT_ERROR;
		case PARSE_OPT_UNKNOWN:
			goto unknown;
		case PARSE_OPT_HELP:
			goto show_usage;
		case PARSE_OPT_NON_OPTION:
		case PARSE_OPT_SUBCOMMAND:
		case PARSE_OPT_COMPLETE:
			BUG("parse_long_opt() cannot return these");
		case PARSE_OPT_DONE:
			break;
		}
		continue;
unknown:
		if (ctx->flags & PARSE_OPT_ONE_SHOT)
			break;
		if (ctx->has_subcommands &&
		    (ctx->flags & PARSE_OPT_SUBCOMMAND_OPTIONAL) &&
		    (ctx->flags & PARSE_OPT_KEEP_UNKNOWN_OPT)) {
			/*
			 * Found an unknown option given to a command with
			 * subcommands that has a default operation mode:
			 * we treat this option and all remaining args as
			 * arguments meant to that default operation mode.
			 * So we are done parsing.
			 */
			return PARSE_OPT_DONE;
		}
		if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN_OPT))
			return PARSE_OPT_UNKNOWN;
		ctx->out[ctx->cpidx++] = ctx->argv[0];
		ctx->opt = NULL;
	}
	return PARSE_OPT_DONE;

 show_usage:
	return usage_with_options_internal(ctx, usagestr, options,
					   USAGE_NORMAL, USAGE_TO_STDOUT);
}

int parse_options_end(struct parse_opt_ctx_t *ctx)
{
	if (ctx->flags & PARSE_OPT_ONE_SHOT)
		return ctx->total - ctx->argc;

	MOVE_ARRAY(ctx->out + ctx->cpidx, ctx->argv, ctx->argc);
	ctx->out[ctx->cpidx + ctx->argc] = NULL;
	return ctx->cpidx + ctx->argc;
}

int parse_options(int argc, const char **argv,
		  const char *prefix,
		  const struct option *options,
		  const char * const usagestr[],
		  enum parse_opt_flags flags)
{
	struct parse_opt_ctx_t ctx;
	struct option *real_options;

	disallow_abbreviated_options =
		git_env_bool("GIT_TEST_DISALLOW_ABBREVIATED_OPTIONS", 0);

	memset(&ctx, 0, sizeof(ctx));
	real_options = preprocess_options(&ctx, options);
	if (real_options)
		options = real_options;
	parse_options_start_1(&ctx, argc, argv, prefix, options, flags);
	switch (parse_options_step(&ctx, options, usagestr)) {
	case PARSE_OPT_HELP:
	case PARSE_OPT_ERROR:
		exit(129);
	case PARSE_OPT_COMPLETE:
		exit(0);
	case PARSE_OPT_NON_OPTION:
	case PARSE_OPT_SUBCOMMAND:
		break;
	case PARSE_OPT_DONE:
		if (ctx.has_subcommands &&
		    !(flags & PARSE_OPT_SUBCOMMAND_OPTIONAL)) {
			error(_("need a subcommand"));
			usage_with_options(usagestr, options);
		}
		break;
	case PARSE_OPT_UNKNOWN:
		if (ctx.argv[0][1] == '-') {
			error(_("unknown option `%s'"), ctx.argv[0] + 2);
		} else if (isascii(*ctx.opt)) {
			error(_("unknown switch `%c'"), *ctx.opt);
		} else {
			error(_("unknown non-ascii option in string: `%s'"),
			      ctx.argv[0]);
		}
		usage_with_options(usagestr, options);
	}

	precompose_argv_prefix(argc, argv, NULL);
	free_preprocessed_options(real_options);
	free(ctx.alias_groups);
	for (struct parse_opt_cmdmode_list *elem = ctx.cmdmode_list; elem;) {
		struct parse_opt_cmdmode_list *next = elem->next;
		free(elem);
		elem = next;
	}
	return parse_options_end(&ctx);
}

static int usage_argh(const struct option *opts, FILE *outfile)
{
	const char *s;
	int literal = (opts->flags & PARSE_OPT_LITERAL_ARGHELP) ||
		!opts->argh || !!strpbrk(opts->argh, "()<>[]|");
	if (opts->flags & PARSE_OPT_OPTARG)
		if (opts->long_name)
			/*
			 * TRANSLATORS: The "<%s>" part of this string
			 * stands for an optional value given to a command
			 * line option in the long form, and "<>" is there
			 * as a convention to signal that it is a
			 * placeholder (i.e. the user should substitute it
			 * with the real value).  If your language uses a
			 * different convention, you can change "<%s>" part
			 * to match yours, e.g. it might use "|%s|" instead,
			 * or if the alphabet is different enough it may use
			 * "%s" without any placeholder signal.  Most
			 * translations leave this message as is.
			 */
			s = literal ? "[=%s]" : _("[=<%s>]");
		else
			/*
			 * TRANSLATORS: The "<%s>" part of this string
			 * stands for an optional value given to a command
			 * line option in the short form, and "<>" is there
			 * as a convention to signal that it is a
			 * placeholder (i.e. the user should substitute it
			 * with the real value).  If your language uses a
			 * different convention, you can change "<%s>" part
			 * to match yours, e.g. it might use "|%s|" instead,
			 * or if the alphabet is different enough it may use
			 * "%s" without any placeholder signal.  Most
			 * translations leave this message as is.
			 */
			s = literal ? "[%s]" : _("[<%s>]");
	else
		/*
		 * TRANSLATORS: The "<%s>" part of this string stands for a
		 * value given to a command line option, and "<>" is there
		 * as a convention to signal that it is a placeholder
		 * (i.e. the user should substitute it with the real value).
		 * If your language uses a different convention, you can
		 * change "<%s>" part to match yours, e.g. it might use
		 * "|%s|" instead, or if the alphabet is different enough it
		 * may use "%s" without any placeholder signal.  Most
		 * translations leave this message as is.
		 */
		s = literal ? " %s" : _(" <%s>");
	return utf8_fprintf(outfile, s, opts->argh ? _(opts->argh) : _("..."));
}

static int usage_indent(FILE *outfile)
{
	return fprintf(outfile, "    ");
}

#define USAGE_OPTS_WIDTH 26

static void usage_padding(FILE *outfile, size_t pos)
{
	if (pos < USAGE_OPTS_WIDTH)
		fprintf(outfile, "%*s", USAGE_OPTS_WIDTH - (int)pos, "");
	else
		fprintf(outfile, "\n%*s", USAGE_OPTS_WIDTH, "");
}

static const struct option *find_option_by_long_name(const struct option *opts,
						     const char *long_name)
{
	for (; opts->type != OPTION_END; opts++) {
		if (opts->long_name && !strcmp(opts->long_name, long_name))
			return opts;
	}
	return NULL;
}

static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t *ctx,
							 const char * const *usagestr,
							 const struct option *opts,
							 int full, int err)
{
	const struct option *all_opts = opts;
	FILE *outfile = err ? stderr : stdout;
	int need_newline;

	const char *usage_prefix = _("usage: %s");
	/*
	 * The translation could be anything, but we can count on
	 * msgfmt(1)'s --check option to have asserted that "%s" is in
	 * the translation. So compute the length of the "usage: "
	 * part. We are assuming that the translator wasn't overly
	 * clever and used e.g. "%1$s" instead of "%s", there's only
	 * one "%s" in "usage_prefix" above, so there's no reason to
	 * do so even with a RTL language.
	 */
	size_t usage_len = strlen(usage_prefix) - strlen("%s");
	/*
	 * TRANSLATORS: the colon here should align with the
	 * one in "usage: %s" translation.
	 */
	const char *or_prefix = _("   or: %s");
	/*
	 * TRANSLATORS: You should only need to translate this format
	 * string if your language is a RTL language (e.g. Arabic,
	 * Hebrew etc.), not if it's a LTR language (e.g. German,
	 * Russian, Chinese etc.).
	 *
	 * When a translated usage string has an embedded "\n" it's
	 * because options have wrapped to the next line. The line
	 * after the "\n" will then be padded to align with the
	 * command name, such as N_("git cmd [opt]\n<8
	 * spaces>[opt2]"), where the 8 spaces are the same length as
	 * "git cmd ".
	 *
	 * This format string prints out that already-translated
	 * line. The "%*s" is whitespace padding to account for the
	 * padding at the start of the line that we add in this
	 * function. The "%s" is a line in the (hopefully already
	 * translated) N_() usage string, which contained embedded
	 * newlines before we split it up.
	 */
	const char *usage_continued = _("%*s%s");
	const char *prefix = usage_prefix;
	int saw_empty_line = 0;

	parse_options_check_harder(opts);

	if (!usagestr)
		return PARSE_OPT_HELP;

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

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

		if (!saw_empty_line && !*str)
			saw_empty_line = 1;

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

			if (saw_empty_line && *line)
				fprintf_ln(outfile, _("    %s"), line);
			else if (saw_empty_line)
				fputc('\n', outfile);
			else if (!j)
				fprintf_ln(outfile, prefix, line);
			else
				fprintf_ln(outfile, usage_continued,
					   (int)usage_len, "", line);
		}
		string_list_clear(&list, 0);

		prefix = or_prefix;
	}

	need_newline = 1;

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

		if (opts->type == OPTION_SUBCOMMAND)
			continue;
		if (opts->type == OPTION_GROUP) {
			fputc('\n', outfile);
			need_newline = 0;
			if (*opts->help)
				fprintf(outfile, "%s\n", _(opts->help));
			continue;
		}
		if (!full && (opts->flags & PARSE_OPT_HIDDEN))
			continue;

		if (need_newline) {
			fputc('\n', outfile);
			need_newline = 0;
		}

		pos = usage_indent(outfile);
		if (opts->short_name) {
			if (opts->flags & PARSE_OPT_NODASH)
				pos += fprintf(outfile, "%c", opts->short_name);
			else
				pos += fprintf(outfile, "-%c", opts->short_name);
		}
		if (opts->long_name && opts->short_name)
			pos += fprintf(outfile, ", ");
		if (opts->long_name) {
			const char *long_name = opts->long_name;
			if ((opts->flags & PARSE_OPT_NONEG) ||
			    skip_prefix(long_name, "no-", &positive_name))
				pos += fprintf(outfile, "--%s", long_name);
			else
				pos += fprintf(outfile, "--[no-]%s", long_name);
		}

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

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

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

		for (cp = opts->help ? _(opts->help) : ""; *cp; cp = np) {
			np = strchrnul(cp, '\n');
			if (*np)
				np++;
			usage_padding(outfile, pos);
			fwrite(cp, 1, np - cp, outfile);
			pos = 0;
		}
		fputc('\n', outfile);

		if (positive_name) {
			if (find_option_by_long_name(all_opts, positive_name))
				continue;
			pos = usage_indent(outfile);
			pos += fprintf(outfile, "--%s", positive_name);
			usage_padding(outfile, pos);
			fprintf_ln(outfile, _("opposite of --no-%s"),
				   positive_name);
		}
	}
	fputc('\n', outfile);

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

	return PARSE_OPT_HELP;
}

void NORETURN usage_with_options(const char * const *usagestr,
			const struct option *opts)
{
	usage_with_options_internal(NULL, usagestr, opts,
				    USAGE_NORMAL, USAGE_TO_STDERR);
	exit(129);
}

void show_usage_with_options_if_asked(int ac, const char **av,
				      const char * const *usagestr,
				      const struct option *opts)
{
	if (ac == 2) {
		if (!strcmp(av[1], "-h")) {
			usage_with_options_internal(NULL, usagestr, opts,
						    USAGE_NORMAL, USAGE_TO_STDOUT);
			exit(129);
		} else if (!strcmp(av[1], "--help-all")) {
			usage_with_options_internal(NULL, usagestr, opts,
						    USAGE_FULL, USAGE_TO_STDOUT);
			exit(129);
		}
	}
}

void NORETURN usage_msg_opt(const char *msg,
		   const char * const *usagestr,
		   const struct option *options)
{
	die_message("%s\n", msg); /* The extra \n is intentional */
	usage_with_options(usagestr, options);
}

void NORETURN usage_msg_optf(const char * const fmt,
			     const char * const *usagestr,
			     const struct option *options, ...)
{
	struct strbuf msg = STRBUF_INIT;
	va_list ap;
	va_start(ap, options);
	strbuf_vaddf(&msg, fmt, ap);
	va_end(ap);

	usage_msg_opt(msg.buf, usagestr, options);
}

void die_for_incompatible_opt4(int opt1, const char *opt1_name,
			       int opt2, const char *opt2_name,
			       int opt3, const char *opt3_name,
			       int opt4, const char *opt4_name)
{
	int count = 0;
	const char *options[4];

	if (opt1)
		options[count++] = opt1_name;
	if (opt2)
		options[count++] = opt2_name;
	if (opt3)
		options[count++] = opt3_name;
	if (opt4)
		options[count++] = opt4_name;
	switch (count) {
	case 4:
		die(_("options '%s', '%s', '%s', and '%s' cannot be used together"),
		    opt1_name, opt2_name, opt3_name, opt4_name);
		break;
	case 3:
		die(_("options '%s', '%s', and '%s' cannot be used together"),
		    options[0], options[1], options[2]);
		break;
	case 2:
		die(_("options '%s' and '%s' cannot be used together"),
		    options[0], options[1]);
		break;
	default:
		break;
	}
}
