#include <linux/compiler.h>
#include <linux/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <ctype.h>
#include "subcmd-util.h"
#include "parse-options.h"
#include "subcmd-config.h"
#include "pager.h"

#define OPT_SHORT 1
#define OPT_UNSET 2

char *error_buf;

static int opterror(const struct option *opt, const char *reason, int flags)
{
	if (flags & OPT_SHORT)
		fprintf(stderr, " Error: switch `%c' %s", opt->short_name, reason);
	else if (flags & OPT_UNSET)
		fprintf(stderr, " Error: option `no-%s' %s", opt->long_name, reason);
	else
		fprintf(stderr, " Error: option `%s' %s", opt->long_name, reason);

	return -1;
}

static const char *skip_prefix(const char *str, const char *prefix)
{
	size_t len = strlen(prefix);
	return strncmp(str, prefix, len) ? NULL : str + len;
}

static void optwarning(const struct option *opt, const char *reason, int flags)
{
	if (flags & OPT_SHORT)
		fprintf(stderr, " Warning: switch `%c' %s", opt->short_name, reason);
	else if (flags & OPT_UNSET)
		fprintf(stderr, " Warning: option `no-%s' %s", opt->long_name, reason);
	else
		fprintf(stderr, " Warning: option `%s' %s", opt->long_name, reason);
}

static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt,
		   int flags, const char **arg)
{
	const char *res;

	if (p->opt) {
		res = p->opt;
		p->opt = NULL;
	} else if ((opt->flags & PARSE_OPT_LASTARG_DEFAULT) && (p->argc == 1 ||
		    **(p->argv + 1) == '-')) {
		res = (const char *)opt->defval;
	} else if (p->argc > 1) {
		p->argc--;
		res = *++p->argv;
	} else
		return opterror(opt, "requires a value", flags);
	if (arg)
		*arg = res;
	return 0;
}

static int get_value(struct parse_opt_ctx_t *p,
		     const struct option *opt, int flags)
{
	const char *s, *arg = NULL;
	const int unset = flags & OPT_UNSET;
	int err;

	if (unset && p->opt)
		return opterror(opt, "takes no value", flags);
	if (unset && (opt->flags & PARSE_OPT_NONEG))
		return opterror(opt, "isn't available", flags);
	if (opt->flags & PARSE_OPT_DISABLED)
		return opterror(opt, "is not usable", flags);

	if (opt->flags & PARSE_OPT_EXCLUSIVE) {
		if (p->excl_opt && p->excl_opt != opt) {
			char msg[128];

			if (((flags & OPT_SHORT) && p->excl_opt->short_name) ||
			    p->excl_opt->long_name == NULL) {
				snprintf(msg, sizeof(msg), "cannot be used with switch `%c'",
					 p->excl_opt->short_name);
			} else {
				snprintf(msg, sizeof(msg), "cannot be used with %s",
					 p->excl_opt->long_name);
			}
			opterror(opt, msg, flags);
			return -3;
		}
		p->excl_opt = opt;
	}
	if (!(flags & OPT_SHORT) && p->opt) {
		switch (opt->type) {
		case OPTION_CALLBACK:
			if (!(opt->flags & PARSE_OPT_NOARG))
				break;
			/* FALLTHROUGH */
		case OPTION_BOOLEAN:
		case OPTION_INCR:
		case OPTION_BIT:
		case OPTION_SET_UINT:
		case OPTION_SET_PTR:
			return opterror(opt, "takes no value", flags);
		case OPTION_END:
		case OPTION_ARGUMENT:
		case OPTION_GROUP:
		case OPTION_STRING:
		case OPTION_INTEGER:
		case OPTION_UINTEGER:
		case OPTION_LONG:
		case OPTION_U64:
		default:
			break;
		}
	}

	if (opt->flags & PARSE_OPT_NOBUILD) {
		char reason[128];
		bool noarg = false;

		err = snprintf(reason, sizeof(reason),
				opt->flags & PARSE_OPT_CANSKIP ?
					"is being ignored because %s " :
					"is not available because %s",
				opt->build_opt);
		reason[sizeof(reason) - 1] = '\0';

		if (err < 0)
			strncpy(reason, opt->flags & PARSE_OPT_CANSKIP ?
					"is being ignored" :
					"is not available",
					sizeof(reason));

		if (!(opt->flags & PARSE_OPT_CANSKIP))
			return opterror(opt, reason, flags);

		err = 0;
		if (unset)
			noarg = true;
		if (opt->flags & PARSE_OPT_NOARG)
			noarg = true;
		if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
			noarg = true;

		switch (opt->type) {
		case OPTION_BOOLEAN:
		case OPTION_INCR:
		case OPTION_BIT:
		case OPTION_SET_UINT:
		case OPTION_SET_PTR:
		case OPTION_END:
		case OPTION_ARGUMENT:
		case OPTION_GROUP:
			noarg = true;
			break;
		case OPTION_CALLBACK:
		case OPTION_STRING:
		case OPTION_INTEGER:
		case OPTION_UINTEGER:
		case OPTION_LONG:
		case OPTION_U64:
		default:
			break;
		}

		if (!noarg)
			err = get_arg(p, opt, flags, NULL);
		if (err)
			return err;

		optwarning(opt, reason, flags);
		return 0;
	}

	switch (opt->type) {
	case OPTION_BIT:
		if (unset)
			*(int *)opt->value &= ~opt->defval;
		else
			*(int *)opt->value |= opt->defval;
		return 0;

	case OPTION_BOOLEAN:
		*(bool *)opt->value = unset ? false : true;
		if (opt->set)
			*(bool *)opt->set = true;
		return 0;

	case OPTION_INCR:
		*(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
		return 0;

	case OPTION_SET_UINT:
		*(unsigned int *)opt->value = unset ? 0 : opt->defval;
		return 0;

	case OPTION_SET_PTR:
		*(void **)opt->value = unset ? NULL : (void *)opt->defval;
		return 0;

	case OPTION_STRING:
		err = 0;
		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
			err = get_arg(p, opt, flags, (const char **)opt->value);

		/* PARSE_OPT_NOEMPTY: Allow NULL but disallow empty string. */
		if (opt->flags & PARSE_OPT_NOEMPTY) {
			const char *val = *(const char **)opt->value;

			if (!val)
				return err;

			/* Similar to unset if we are given an empty string. */
			if (val[0] == '\0') {
				*(const char **)opt->value = NULL;
				return 0;
			}
		}

		return err;

	case OPTION_CALLBACK:
		if (unset)
			return (*opt->callback)(opt, NULL, 1) ? (-1) : 0;
		if (opt->flags & PARSE_OPT_NOARG)
			return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
		if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
			return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
		if (get_arg(p, opt, flags, &arg))
			return -1;
		return (*opt->callback)(opt, arg, 0) ? (-1) : 0;

	case OPTION_INTEGER:
		if (unset) {
			*(int *)opt->value = 0;
			return 0;
		}
		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
			*(int *)opt->value = opt->defval;
			return 0;
		}
		if (get_arg(p, opt, flags, &arg))
			return -1;
		*(int *)opt->value = strtol(arg, (char **)&s, 10);
		if (*s)
			return opterror(opt, "expects a numerical value", flags);
		return 0;

	case OPTION_UINTEGER:
		if (unset) {
			*(unsigned int *)opt->value = 0;
			return 0;
		}
		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
			*(unsigned int *)opt->value = opt->defval;
			return 0;
		}
		if (get_arg(p, opt, flags, &arg))
			return -1;
		*(unsigned int *)opt->value = strtol(arg, (char **)&s, 10);
		if (*s)
			return opterror(opt, "expects a numerical value", flags);
		return 0;

	case OPTION_LONG:
		if (unset) {
			*(long *)opt->value = 0;
			return 0;
		}
		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
			*(long *)opt->value = opt->defval;
			return 0;
		}
		if (get_arg(p, opt, flags, &arg))
			return -1;
		*(long *)opt->value = strtol(arg, (char **)&s, 10);
		if (*s)
			return opterror(opt, "expects a numerical value", flags);
		return 0;

	case OPTION_U64:
		if (unset) {
			*(u64 *)opt->value = 0;
			return 0;
		}
		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
			*(u64 *)opt->value = opt->defval;
			return 0;
		}
		if (get_arg(p, opt, flags, &arg))
			return -1;
		*(u64 *)opt->value = strtoull(arg, (char **)&s, 10);
		if (*s)
			return opterror(opt, "expects a numerical value", flags);
		return 0;

	case OPTION_END:
	case OPTION_ARGUMENT:
	case OPTION_GROUP:
	default:
		die("should not happen, someone must be hit on the forehead");
	}
}

static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *options)
{
	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);
		}
	}
	return -2;
}

static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
                          const struct option *options)
{
	const char *arg_end = strchr(arg, '=');
	const struct option *abbrev_option = NULL, *ambiguous_option = NULL;
	int abbrev_flags = 0, ambiguous_flags = 0;

	if (!arg_end)
		arg_end = arg + strlen(arg);

	for (; options->type != OPTION_END; options++) {
		const char *rest;
		int flags = 0;

		if (!options->long_name)
			continue;

		rest = skip_prefix(arg, options->long_name);
		if (options->type == OPTION_ARGUMENT) {
			if (!rest)
				continue;
			if (*rest == '=')
				return opterror(options, "takes no value", flags);
			if (*rest)
				continue;
			p->out[p->cpidx++] = arg - 2;
			return 0;
		}
		if (!rest) {
			if (!prefixcmp(options->long_name, "no-")) {
				/*
				 * The long name itself starts with "no-", so
				 * accept the option without "no-" so that users
				 * do not have to enter "no-no-" to get the
				 * negation.
				 */
				rest = skip_prefix(arg, options->long_name + 3);
				if (rest) {
					flags |= OPT_UNSET;
					goto match;
				}
				/* Abbreviated case */
				if (!prefixcmp(options->long_name + 3, arg)) {
					flags |= OPT_UNSET;
					goto is_abbreviated;
				}
			}
			/* abbreviated? */
			if (!strncmp(options->long_name, arg, arg_end - arg)) {
is_abbreviated:
				if (abbrev_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;
				}
				if (!(flags & OPT_UNSET) && *arg_end)
					p->opt = arg_end + 1;
				abbrev_option = options;
				abbrev_flags = flags;
				continue;
			}
			/* negated and abbreviated very much? */
			if (!prefixcmp("no-", arg)) {
				flags |= OPT_UNSET;
				goto is_abbreviated;
			}
			/* negated? */
			if (strncmp(arg, "no-", 3))
				continue;
			flags |= OPT_UNSET;
			rest = skip_prefix(arg + 3, options->long_name);
			/* abbreviated and negated? */
			if (!rest && !prefixcmp(options->long_name, arg + 3))
				goto is_abbreviated;
			if (!rest)
				continue;
		}
match:
		if (*rest) {
			if (*rest != '=')
				continue;
			p->opt = rest + 1;
		}
		return get_value(p, options, flags);
	}

	if (ambiguous_option) {
		 fprintf(stderr,
			 " 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 -1;
	}
	if (abbrev_option)
		return get_value(p, abbrev_option, abbrev_flags);
	return -2;
}

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

	if (!prefixcmp(arg, "no-")) {
		fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)", arg);
		exit(129);
	}

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

static void parse_options_start(struct parse_opt_ctx_t *ctx,
				int argc, const char **argv, int flags)
{
	memset(ctx, 0, sizeof(*ctx));
	ctx->argc = argc - 1;
	ctx->argv = argv + 1;
	ctx->out  = argv;
	ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
	ctx->flags = flags;
	if ((flags & PARSE_OPT_KEEP_UNKNOWN) &&
	    (flags & PARSE_OPT_STOP_AT_NON_OPTION))
		die("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
}

static int usage_with_options_internal(const char * const *,
				       const struct option *, int,
				       struct parse_opt_ctx_t *);

static int 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);
	int excl_short_opt = 1;
	const char *arg;

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

	for (; ctx->argc; ctx->argc--, ctx->argv++) {
		arg = ctx->argv[0];
		if (*arg != '-' || !arg[1]) {
			if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
				break;
			ctx->out[ctx->cpidx++] = ctx->argv[0];
			continue;
		}

		if (arg[1] != '-') {
			ctx->opt = ++arg;
			if (internal_help && *ctx->opt == 'h') {
				return usage_with_options_internal(usagestr, options, 0, ctx);
			}
			switch (parse_short_opt(ctx, options)) {
			case -1:
				return parse_options_usage(usagestr, options, arg, 1);
			case -2:
				goto unknown;
			case -3:
				goto exclusive;
			default:
				break;
			}
			if (ctx->opt)
				check_typos(arg, options);
			while (ctx->opt) {
				if (internal_help && *ctx->opt == 'h')
					return usage_with_options_internal(usagestr, options, 0, ctx);
				arg = ctx->opt;
				switch (parse_short_opt(ctx, options)) {
				case -1:
					return parse_options_usage(usagestr, options, arg, 1);
				case -2:
					/* 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] = strdup(ctx->opt - 1);
					*(char *)ctx->argv[0] = '-';
					goto unknown;
				case -3:
					goto exclusive;
				default:
					break;
				}
			}
			continue;
		}

		if (!arg[2]) { /* "--" */
			if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
				ctx->argc--;
				ctx->argv++;
			}
			break;
		}

		arg += 2;
		if (internal_help && !strcmp(arg, "help-all"))
			return usage_with_options_internal(usagestr, options, 1, ctx);
		if (internal_help && !strcmp(arg, "help"))
			return usage_with_options_internal(usagestr, options, 0, ctx);
		if (!strcmp(arg, "list-opts"))
			return PARSE_OPT_LIST_OPTS;
		if (!strcmp(arg, "list-cmds"))
			return PARSE_OPT_LIST_SUBCMDS;
		switch (parse_long_opt(ctx, arg, options)) {
		case -1:
			return parse_options_usage(usagestr, options, arg, 0);
		case -2:
			goto unknown;
		case -3:
			excl_short_opt = 0;
			goto exclusive;
		default:
			break;
		}
		continue;
unknown:
		if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN))
			return PARSE_OPT_UNKNOWN;
		ctx->out[ctx->cpidx++] = ctx->argv[0];
		ctx->opt = NULL;
	}
	return PARSE_OPT_DONE;

exclusive:
	parse_options_usage(usagestr, options, arg, excl_short_opt);
	if ((excl_short_opt && ctx->excl_opt->short_name) ||
	    ctx->excl_opt->long_name == NULL) {
		char opt = ctx->excl_opt->short_name;
		parse_options_usage(NULL, options, &opt, 1);
	} else {
		parse_options_usage(NULL, options, ctx->excl_opt->long_name, 0);
	}
	return PARSE_OPT_HELP;
}

static int parse_options_end(struct parse_opt_ctx_t *ctx)
{
	memmove(ctx->out + ctx->cpidx, ctx->argv, ctx->argc * sizeof(*ctx->out));
	ctx->out[ctx->cpidx + ctx->argc] = NULL;
	return ctx->cpidx + ctx->argc;
}

int parse_options_subcommand(int argc, const char **argv, const struct option *options,
			const char *const subcommands[], const char *usagestr[], int flags)
{
	struct parse_opt_ctx_t ctx;

	/* build usage string if it's not provided */
	if (subcommands && !usagestr[0]) {
		char *buf = NULL;

		astrcatf(&buf, "%s %s [<options>] {", subcmd_config.exec_name, argv[0]);

		for (int i = 0; subcommands[i]; i++) {
			if (i)
				astrcat(&buf, "|");
			astrcat(&buf, subcommands[i]);
		}
		astrcat(&buf, "}");

		usagestr[0] = buf;
	}

	parse_options_start(&ctx, argc, argv, flags);
	switch (parse_options_step(&ctx, options, usagestr)) {
	case PARSE_OPT_HELP:
		exit(129);
	case PARSE_OPT_DONE:
		break;
	case PARSE_OPT_LIST_OPTS:
		while (options->type != OPTION_END) {
			if (options->long_name)
				printf("--%s ", options->long_name);
			options++;
		}
		putchar('\n');
		exit(130);
	case PARSE_OPT_LIST_SUBCMDS:
		if (subcommands) {
			for (int i = 0; subcommands[i]; i++)
				printf("%s ", subcommands[i]);
		}
		putchar('\n');
		exit(130);
	default: /* PARSE_OPT_UNKNOWN */
		if (ctx.argv[0][1] == '-')
			astrcatf(&error_buf, "unknown option `%s'",
				 ctx.argv[0] + 2);
		else
			astrcatf(&error_buf, "unknown switch `%c'", *ctx.opt);
		usage_with_options(usagestr, options);
	}

	return parse_options_end(&ctx);
}

int parse_options(int argc, const char **argv, const struct option *options,
		  const char * const usagestr[], int flags)
{
	return parse_options_subcommand(argc, argv, options, NULL,
					(const char **) usagestr, flags);
}

#define USAGE_OPTS_WIDTH 24
#define USAGE_GAP         2

static void print_option_help(const struct option *opts, int full)
{
	size_t pos;
	int pad;

	if (opts->type == OPTION_GROUP) {
		fputc('\n', stderr);
		if (*opts->help)
			fprintf(stderr, "%s\n", opts->help);
		return;
	}
	if (!full && (opts->flags & PARSE_OPT_HIDDEN))
		return;
	if (opts->flags & PARSE_OPT_DISABLED)
		return;

	pos = fprintf(stderr, "    ");
	if (opts->short_name)
		pos += fprintf(stderr, "-%c", opts->short_name);
	else
		pos += fprintf(stderr, "    ");

	if (opts->long_name && opts->short_name)
		pos += fprintf(stderr, ", ");
	if (opts->long_name)
		pos += fprintf(stderr, "--%s", opts->long_name);

	switch (opts->type) {
	case OPTION_ARGUMENT:
		break;
	case OPTION_LONG:
	case OPTION_U64:
	case OPTION_INTEGER:
	case OPTION_UINTEGER:
		if (opts->flags & PARSE_OPT_OPTARG)
			if (opts->long_name)
				pos += fprintf(stderr, "[=<n>]");
			else
				pos += fprintf(stderr, "[<n>]");
		else
			pos += fprintf(stderr, " <n>");
		break;
	case OPTION_CALLBACK:
		if (opts->flags & PARSE_OPT_NOARG)
			break;
		/* FALLTHROUGH */
	case OPTION_STRING:
		if (opts->argh) {
			if (opts->flags & PARSE_OPT_OPTARG)
				if (opts->long_name)
					pos += fprintf(stderr, "[=<%s>]", opts->argh);
				else
					pos += fprintf(stderr, "[<%s>]", opts->argh);
			else
				pos += fprintf(stderr, " <%s>", opts->argh);
		} else {
			if (opts->flags & PARSE_OPT_OPTARG)
				if (opts->long_name)
					pos += fprintf(stderr, "[=...]");
				else
					pos += fprintf(stderr, "[...]");
			else
				pos += fprintf(stderr, " ...");
		}
		break;
	default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
	case OPTION_END:
	case OPTION_GROUP:
	case OPTION_BIT:
	case OPTION_BOOLEAN:
	case OPTION_INCR:
	case OPTION_SET_UINT:
	case OPTION_SET_PTR:
		break;
	}

	if (pos <= USAGE_OPTS_WIDTH)
		pad = USAGE_OPTS_WIDTH - pos;
	else {
		fputc('\n', stderr);
		pad = USAGE_OPTS_WIDTH;
	}
	fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
	if (opts->flags & PARSE_OPT_NOBUILD)
		fprintf(stderr, "%*s(not built-in because %s)\n",
			USAGE_OPTS_WIDTH + USAGE_GAP, "",
			opts->build_opt);
}

static int option__cmp(const void *va, const void *vb)
{
	const struct option *a = va, *b = vb;
	int sa = tolower(a->short_name), sb = tolower(b->short_name), ret;

	if (sa == 0)
		sa = 'z' + 1;
	if (sb == 0)
		sb = 'z' + 1;

	ret = sa - sb;

	if (ret == 0) {
		const char *la = a->long_name ?: "",
			   *lb = b->long_name ?: "";
		ret = strcmp(la, lb);
	}

	return ret;
}

static struct option *options__order(const struct option *opts)
{
	int nr_opts = 0, len;
	const struct option *o = opts;
	struct option *ordered;

	for (o = opts; o->type != OPTION_END; o++)
		++nr_opts;

	len = sizeof(*o) * (nr_opts + 1);
	ordered = malloc(len);
	if (!ordered)
		goto out;
	memcpy(ordered, opts, len);

	qsort(ordered, nr_opts, sizeof(*o), option__cmp);
out:
	return ordered;
}

static bool option__in_argv(const struct option *opt, const struct parse_opt_ctx_t *ctx)
{
	int i;

	for (i = 1; i < ctx->argc; ++i) {
		const char *arg = ctx->argv[i];

		if (arg[0] != '-') {
			if (arg[1] == '\0') {
				if (arg[0] == opt->short_name)
					return true;
				continue;
			}

			if (opt->long_name && strcmp(opt->long_name, arg) == 0)
				return true;

			if (opt->help && strcasestr(opt->help, arg) != NULL)
				return true;

			continue;
		}

		if (arg[1] == opt->short_name ||
		    (arg[1] == '-' && opt->long_name && strcmp(opt->long_name, arg + 2) == 0))
			return true;
	}

	return false;
}

static int usage_with_options_internal(const char * const *usagestr,
				       const struct option *opts, int full,
				       struct parse_opt_ctx_t *ctx)
{
	struct option *ordered;

	if (!usagestr)
		return PARSE_OPT_HELP;

	setup_pager();

	if (error_buf) {
		fprintf(stderr, "  Error: %s\n", error_buf);
		zfree(&error_buf);
	}

	fprintf(stderr, "\n Usage: %s\n", *usagestr++);
	while (*usagestr && **usagestr)
		fprintf(stderr, "    or: %s\n", *usagestr++);
	while (*usagestr) {
		fprintf(stderr, "%s%s\n",
				**usagestr ? "    " : "",
				*usagestr);
		usagestr++;
	}

	if (opts->type != OPTION_GROUP)
		fputc('\n', stderr);

	ordered = options__order(opts);
	if (ordered)
		opts = ordered;

	for (  ; opts->type != OPTION_END; opts++) {
		if (ctx && ctx->argc > 1 && !option__in_argv(opts, ctx))
			continue;
		print_option_help(opts, full);
	}

	fputc('\n', stderr);

	free(ordered);

	return PARSE_OPT_HELP;
}

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

void usage_with_options_msg(const char * const *usagestr,
			    const struct option *opts, const char *fmt, ...)
{
	va_list ap;
	char *tmp = error_buf;

	va_start(ap, fmt);
	if (vasprintf(&error_buf, fmt, ap) == -1)
		die("vasprintf failed");
	va_end(ap);

	free(tmp);

	usage_with_options_internal(usagestr, opts, 0, NULL);
	exit(129);
}

int parse_options_usage(const char * const *usagestr,
			const struct option *opts,
			const char *optstr, bool short_opt)
{
	if (!usagestr)
		goto opt;

	fprintf(stderr, "\n Usage: %s\n", *usagestr++);
	while (*usagestr && **usagestr)
		fprintf(stderr, "    or: %s\n", *usagestr++);
	while (*usagestr) {
		fprintf(stderr, "%s%s\n",
				**usagestr ? "    " : "",
				*usagestr);
		usagestr++;
	}
	fputc('\n', stderr);

opt:
	for (  ; opts->type != OPTION_END; opts++) {
		if (short_opt) {
			if (opts->short_name == *optstr) {
				print_option_help(opts, 0);
				break;
			}
			continue;
		}

		if (opts->long_name == NULL)
			continue;

		if (!prefixcmp(opts->long_name, optstr))
			print_option_help(opts, 0);
		if (!prefixcmp("no-", optstr) &&
		    !prefixcmp(opts->long_name, optstr + 3))
			print_option_help(opts, 0);
	}

	return PARSE_OPT_HELP;
}


int parse_opt_verbosity_cb(const struct option *opt,
			   const char *arg __maybe_unused,
			   int unset)
{
	int *target = opt->value;

	if (unset)
		/* --no-quiet, --no-verbose */
		*target = 0;
	else if (opt->short_name == 'v') {
		if (*target >= 0)
			(*target)++;
		else
			*target = 1;
	} else {
		if (*target <= 0)
			(*target)--;
		else
			*target = -1;
	}
	return 0;
}

static struct option *
find_option(struct option *opts, int shortopt, const char *longopt)
{
	for (; opts->type != OPTION_END; opts++) {
		if ((shortopt && opts->short_name == shortopt) ||
		    (opts->long_name && longopt &&
		     !strcmp(opts->long_name, longopt)))
			return opts;
	}
	return NULL;
}

void set_option_flag(struct option *opts, int shortopt, const char *longopt,
		     int flag)
{
	struct option *opt = find_option(opts, shortopt, longopt);

	if (opt)
		opt->flags |= flag;
	return;
}

void set_option_nobuild(struct option *opts, int shortopt,
			const char *longopt,
			const char *build_opt,
			bool can_skip)
{
	struct option *opt = find_option(opts, shortopt, longopt);

	if (!opt)
		return;

	opt->flags |= PARSE_OPT_NOBUILD;
	opt->flags |= can_skip ? PARSE_OPT_CANSKIP : 0;
	opt->build_opt = build_opt;
}
