Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.15.
   1// SPDX-License-Identifier: GPL-2.0
   2#include <linux/compiler.h>
   3#include <linux/string.h>
   4#include <linux/types.h>
   5#include <stdio.h>
   6#include <stdlib.h>
   7#include <stdint.h>
   8#include <string.h>
   9#include <ctype.h>
  10#include "subcmd-util.h"
  11#include "parse-options.h"
  12#include "subcmd-config.h"
  13#include "pager.h"
  14
  15#define OPT_SHORT 1
  16#define OPT_UNSET 2
  17
  18char *error_buf;
  19
  20static int opterror(const struct option *opt, const char *reason, int flags)
  21{
  22	if (flags & OPT_SHORT)
  23		fprintf(stderr, " Error: switch `%c' %s", opt->short_name, reason);
  24	else if (flags & OPT_UNSET)
  25		fprintf(stderr, " Error: option `no-%s' %s", opt->long_name, reason);
  26	else
  27		fprintf(stderr, " Error: option `%s' %s", opt->long_name, reason);
  28
  29	return -1;
  30}
  31
  32static const char *skip_prefix(const char *str, const char *prefix)
  33{
  34	size_t len = strlen(prefix);
  35	return strncmp(str, prefix, len) ? NULL : str + len;
  36}
  37
  38static void optwarning(const struct option *opt, const char *reason, int flags)
  39{
  40	if (flags & OPT_SHORT)
  41		fprintf(stderr, " Warning: switch `%c' %s", opt->short_name, reason);
  42	else if (flags & OPT_UNSET)
  43		fprintf(stderr, " Warning: option `no-%s' %s", opt->long_name, reason);
  44	else
  45		fprintf(stderr, " Warning: option `%s' %s", opt->long_name, reason);
  46}
  47
  48static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt,
  49		   int flags, const char **arg)
  50{
  51	const char *res;
  52
  53	if (p->opt) {
  54		res = p->opt;
  55		p->opt = NULL;
  56	} else if ((opt->flags & PARSE_OPT_LASTARG_DEFAULT) && (p->argc == 1 ||
  57		    **(p->argv + 1) == '-')) {
  58		res = (const char *)opt->defval;
  59	} else if (p->argc > 1) {
  60		p->argc--;
  61		res = *++p->argv;
  62	} else
  63		return opterror(opt, "requires a value", flags);
  64	if (arg)
  65		*arg = res;
  66	return 0;
  67}
  68
  69static int get_value(struct parse_opt_ctx_t *p,
  70		     const struct option *opt, int flags)
  71{
  72	const char *s, *arg = NULL;
  73	const int unset = flags & OPT_UNSET;
  74	int err;
  75
  76	if (unset && p->opt)
  77		return opterror(opt, "takes no value", flags);
  78	if (unset && (opt->flags & PARSE_OPT_NONEG))
  79		return opterror(opt, "isn't available", flags);
  80	if (opt->flags & PARSE_OPT_DISABLED)
  81		return opterror(opt, "is not usable", flags);
  82
  83	if (opt->flags & PARSE_OPT_EXCLUSIVE) {
  84		if (p->excl_opt && p->excl_opt != opt) {
  85			char msg[128];
  86
  87			if (((flags & OPT_SHORT) && p->excl_opt->short_name) ||
  88			    p->excl_opt->long_name == NULL) {
  89				snprintf(msg, sizeof(msg), "cannot be used with switch `%c'",
  90					 p->excl_opt->short_name);
  91			} else {
  92				snprintf(msg, sizeof(msg), "cannot be used with %s",
  93					 p->excl_opt->long_name);
  94			}
  95			opterror(opt, msg, flags);
  96			return -3;
  97		}
  98		p->excl_opt = opt;
  99	}
 100	if (!(flags & OPT_SHORT) && p->opt) {
 101		switch (opt->type) {
 102		case OPTION_CALLBACK:
 103			if (!(opt->flags & PARSE_OPT_NOARG))
 104				break;
 105			/* FALLTHROUGH */
 106		case OPTION_BOOLEAN:
 107		case OPTION_INCR:
 108		case OPTION_BIT:
 109		case OPTION_SET_UINT:
 110		case OPTION_SET_PTR:
 111			return opterror(opt, "takes no value", flags);
 112		case OPTION_END:
 113		case OPTION_ARGUMENT:
 114		case OPTION_GROUP:
 115		case OPTION_STRING:
 116		case OPTION_INTEGER:
 117		case OPTION_UINTEGER:
 118		case OPTION_LONG:
 119		case OPTION_ULONG:
 120		case OPTION_U64:
 121		default:
 122			break;
 123		}
 124	}
 125
 126	if (opt->flags & PARSE_OPT_NOBUILD) {
 127		char reason[128];
 128		bool noarg = false;
 129
 130		err = snprintf(reason, sizeof(reason),
 131				opt->flags & PARSE_OPT_CANSKIP ?
 132					"is being ignored because %s " :
 133					"is not available because %s",
 134				opt->build_opt);
 135		reason[sizeof(reason) - 1] = '\0';
 136
 137		if (err < 0)
 138			strncpy(reason, opt->flags & PARSE_OPT_CANSKIP ?
 139					"is being ignored" :
 140					"is not available",
 141					sizeof(reason));
 142
 143		if (!(opt->flags & PARSE_OPT_CANSKIP))
 144			return opterror(opt, reason, flags);
 145
 146		err = 0;
 147		if (unset)
 148			noarg = true;
 149		if (opt->flags & PARSE_OPT_NOARG)
 150			noarg = true;
 151		if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
 152			noarg = true;
 153
 154		switch (opt->type) {
 155		case OPTION_BOOLEAN:
 156		case OPTION_INCR:
 157		case OPTION_BIT:
 158		case OPTION_SET_UINT:
 159		case OPTION_SET_PTR:
 160		case OPTION_END:
 161		case OPTION_ARGUMENT:
 162		case OPTION_GROUP:
 163			noarg = true;
 164			break;
 165		case OPTION_CALLBACK:
 166		case OPTION_STRING:
 167		case OPTION_INTEGER:
 168		case OPTION_UINTEGER:
 169		case OPTION_LONG:
 170		case OPTION_ULONG:
 171		case OPTION_U64:
 172		default:
 173			break;
 174		}
 175
 176		if (!noarg)
 177			err = get_arg(p, opt, flags, NULL);
 178		if (err)
 179			return err;
 180
 181		optwarning(opt, reason, flags);
 182		return 0;
 183	}
 184
 185	switch (opt->type) {
 186	case OPTION_BIT:
 187		if (unset)
 188			*(int *)opt->value &= ~opt->defval;
 189		else
 190			*(int *)opt->value |= opt->defval;
 191		return 0;
 192
 193	case OPTION_BOOLEAN:
 194		*(bool *)opt->value = unset ? false : true;
 195		if (opt->set)
 196			*(bool *)opt->set = true;
 197		return 0;
 198
 199	case OPTION_INCR:
 200		*(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
 201		return 0;
 202
 203	case OPTION_SET_UINT:
 204		*(unsigned int *)opt->value = unset ? 0 : opt->defval;
 205		return 0;
 206
 207	case OPTION_SET_PTR:
 208		*(void **)opt->value = unset ? NULL : (void *)opt->defval;
 209		return 0;
 210
 211	case OPTION_STRING:
 212		err = 0;
 213		if (unset)
 214			*(const char **)opt->value = NULL;
 215		else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
 216			*(const char **)opt->value = (const char *)opt->defval;
 217		else
 218			err = get_arg(p, opt, flags, (const char **)opt->value);
 219
 220		if (opt->set)
 221			*(bool *)opt->set = true;
 222
 223		/* PARSE_OPT_NOEMPTY: Allow NULL but disallow empty string. */
 224		if (opt->flags & PARSE_OPT_NOEMPTY) {
 225			const char *val = *(const char **)opt->value;
 226
 227			if (!val)
 228				return err;
 229
 230			/* Similar to unset if we are given an empty string. */
 231			if (val[0] == '\0') {
 232				*(const char **)opt->value = NULL;
 233				return 0;
 234			}
 235		}
 236
 237		return err;
 238
 239	case OPTION_CALLBACK:
 240		if (opt->set)
 241			*(bool *)opt->set = true;
 242
 243		if (unset)
 244			return (*opt->callback)(opt, NULL, 1) ? (-1) : 0;
 245		if (opt->flags & PARSE_OPT_NOARG)
 246			return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
 247		if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
 248			return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
 249		if (get_arg(p, opt, flags, &arg))
 250			return -1;
 251		return (*opt->callback)(opt, arg, 0) ? (-1) : 0;
 252
 253	case OPTION_INTEGER:
 254		if (unset) {
 255			*(int *)opt->value = 0;
 256			return 0;
 257		}
 258		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
 259			*(int *)opt->value = opt->defval;
 260			return 0;
 261		}
 262		if (get_arg(p, opt, flags, &arg))
 263			return -1;
 264		*(int *)opt->value = strtol(arg, (char **)&s, 10);
 265		if (*s)
 266			return opterror(opt, "expects a numerical value", flags);
 267		return 0;
 268
 269	case OPTION_UINTEGER:
 270		if (unset) {
 271			*(unsigned int *)opt->value = 0;
 272			return 0;
 273		}
 274		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
 275			*(unsigned int *)opt->value = opt->defval;
 276			return 0;
 277		}
 278		if (get_arg(p, opt, flags, &arg))
 279			return -1;
 280		if (arg[0] == '-')
 281			return opterror(opt, "expects an unsigned numerical value", flags);
 282		*(unsigned int *)opt->value = strtol(arg, (char **)&s, 10);
 283		if (*s)
 284			return opterror(opt, "expects a numerical value", flags);
 285		return 0;
 286
 287	case OPTION_LONG:
 288		if (unset) {
 289			*(long *)opt->value = 0;
 290			return 0;
 291		}
 292		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
 293			*(long *)opt->value = opt->defval;
 294			return 0;
 295		}
 296		if (get_arg(p, opt, flags, &arg))
 297			return -1;
 298		*(long *)opt->value = strtol(arg, (char **)&s, 10);
 299		if (*s)
 300			return opterror(opt, "expects a numerical value", flags);
 301		return 0;
 302
 303	case OPTION_ULONG:
 304		if (unset) {
 305			*(unsigned long *)opt->value = 0;
 306			return 0;
 307		}
 308		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
 309			*(unsigned long *)opt->value = opt->defval;
 310			return 0;
 311		}
 312		if (get_arg(p, opt, flags, &arg))
 313			return -1;
 314		*(unsigned long *)opt->value = strtoul(arg, (char **)&s, 10);
 315		if (*s)
 316			return opterror(opt, "expects a numerical value", flags);
 317		return 0;
 318
 319	case OPTION_U64:
 320		if (unset) {
 321			*(u64 *)opt->value = 0;
 322			return 0;
 323		}
 324		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
 325			*(u64 *)opt->value = opt->defval;
 326			return 0;
 327		}
 328		if (get_arg(p, opt, flags, &arg))
 329			return -1;
 330		if (arg[0] == '-')
 331			return opterror(opt, "expects an unsigned numerical value", flags);
 332		*(u64 *)opt->value = strtoull(arg, (char **)&s, 10);
 333		if (*s)
 334			return opterror(opt, "expects a numerical value", flags);
 335		return 0;
 336
 337	case OPTION_END:
 338	case OPTION_ARGUMENT:
 339	case OPTION_GROUP:
 340	default:
 341		die("should not happen, someone must be hit on the forehead");
 342	}
 343}
 344
 345static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *options)
 346{
 347retry:
 348	for (; options->type != OPTION_END; options++) {
 349		if (options->short_name == *p->opt) {
 350			p->opt = p->opt[1] ? p->opt + 1 : NULL;
 351			return get_value(p, options, OPT_SHORT);
 352		}
 353	}
 354
 355	if (options->parent) {
 356		options = options->parent;
 357		goto retry;
 358	}
 359
 360	return -2;
 361}
 362
 363static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
 364                          const struct option *options)
 365{
 366	const char *arg_end = strchr(arg, '=');
 367	const struct option *abbrev_option = NULL, *ambiguous_option = NULL;
 368	int abbrev_flags = 0, ambiguous_flags = 0;
 369
 370	if (!arg_end)
 371		arg_end = arg + strlen(arg);
 372
 373retry:
 374	for (; options->type != OPTION_END; options++) {
 375		const char *rest;
 376		int flags = 0;
 377
 378		if (!options->long_name)
 379			continue;
 380
 381		rest = skip_prefix(arg, options->long_name);
 382		if (options->type == OPTION_ARGUMENT) {
 383			if (!rest)
 384				continue;
 385			if (*rest == '=')
 386				return opterror(options, "takes no value", flags);
 387			if (*rest)
 388				continue;
 389			p->out[p->cpidx++] = arg - 2;
 390			return 0;
 391		}
 392		if (!rest) {
 393			if (strstarts(options->long_name, "no-")) {
 394				/*
 395				 * The long name itself starts with "no-", so
 396				 * accept the option without "no-" so that users
 397				 * do not have to enter "no-no-" to get the
 398				 * negation.
 399				 */
 400				rest = skip_prefix(arg, options->long_name + 3);
 401				if (rest) {
 402					flags |= OPT_UNSET;
 403					goto match;
 404				}
 405				/* Abbreviated case */
 406				if (strstarts(options->long_name + 3, arg)) {
 407					flags |= OPT_UNSET;
 408					goto is_abbreviated;
 409				}
 410			}
 411			/* abbreviated? */
 412			if (!strncmp(options->long_name, arg, arg_end - arg)) {
 413is_abbreviated:
 414				if (abbrev_option) {
 415					/*
 416					 * If this is abbreviated, it is
 417					 * ambiguous. So when there is no
 418					 * exact match later, we need to
 419					 * error out.
 420					 */
 421					ambiguous_option = abbrev_option;
 422					ambiguous_flags = abbrev_flags;
 423				}
 424				if (!(flags & OPT_UNSET) && *arg_end)
 425					p->opt = arg_end + 1;
 426				abbrev_option = options;
 427				abbrev_flags = flags;
 428				continue;
 429			}
 430			/* negated and abbreviated very much? */
 431			if (strstarts("no-", arg)) {
 432				flags |= OPT_UNSET;
 433				goto is_abbreviated;
 434			}
 435			/* negated? */
 436			if (strncmp(arg, "no-", 3))
 437				continue;
 438			flags |= OPT_UNSET;
 439			rest = skip_prefix(arg + 3, options->long_name);
 440			/* abbreviated and negated? */
 441			if (!rest && strstarts(options->long_name, arg + 3))
 442				goto is_abbreviated;
 443			if (!rest)
 444				continue;
 445		}
 446match:
 447		if (*rest) {
 448			if (*rest != '=')
 449				continue;
 450			p->opt = rest + 1;
 451		}
 452		return get_value(p, options, flags);
 453	}
 454
 455	if (ambiguous_option) {
 456		 fprintf(stderr,
 457			 " Error: Ambiguous option: %s (could be --%s%s or --%s%s)\n",
 458			 arg,
 459			 (ambiguous_flags & OPT_UNSET) ?  "no-" : "",
 460			 ambiguous_option->long_name,
 461			 (abbrev_flags & OPT_UNSET) ?  "no-" : "",
 462			 abbrev_option->long_name);
 463		 return -1;
 464	}
 465	if (abbrev_option)
 466		return get_value(p, abbrev_option, abbrev_flags);
 467
 468	if (options->parent) {
 469		options = options->parent;
 470		goto retry;
 471	}
 472
 473	return -2;
 474}
 475
 476static void check_typos(const char *arg, const struct option *options)
 477{
 478	if (strlen(arg) < 3)
 479		return;
 480
 481	if (strstarts(arg, "no-")) {
 482		fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)\n", arg);
 483		exit(129);
 484	}
 485
 486	for (; options->type != OPTION_END; options++) {
 487		if (!options->long_name)
 488			continue;
 489		if (strstarts(options->long_name, arg)) {
 490			fprintf(stderr, " Error: did you mean `--%s` (with two dashes ?)\n", arg);
 491			exit(129);
 492		}
 493	}
 494}
 495
 496static void parse_options_start(struct parse_opt_ctx_t *ctx,
 497				int argc, const char **argv, int flags)
 498{
 499	memset(ctx, 0, sizeof(*ctx));
 500	ctx->argc = argc - 1;
 501	ctx->argv = argv + 1;
 502	ctx->out  = argv;
 503	ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
 504	ctx->flags = flags;
 505	if ((flags & PARSE_OPT_KEEP_UNKNOWN) &&
 506	    (flags & PARSE_OPT_STOP_AT_NON_OPTION))
 507		die("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
 508}
 509
 510static int usage_with_options_internal(const char * const *,
 511				       const struct option *, int,
 512				       struct parse_opt_ctx_t *);
 513
 514static int parse_options_step(struct parse_opt_ctx_t *ctx,
 515			      const struct option *options,
 516			      const char * const usagestr[])
 517{
 518	int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
 519	int excl_short_opt = 1;
 520	const char *arg;
 521
 522	/* we must reset ->opt, unknown short option leave it dangling */
 523	ctx->opt = NULL;
 524
 525	for (; ctx->argc; ctx->argc--, ctx->argv++) {
 526		arg = ctx->argv[0];
 527		if (*arg != '-' || !arg[1]) {
 528			if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
 529				break;
 530			ctx->out[ctx->cpidx++] = ctx->argv[0];
 531			continue;
 532		}
 533
 534		if (arg[1] != '-') {
 535			ctx->opt = ++arg;
 536			if (internal_help && *ctx->opt == 'h') {
 537				return usage_with_options_internal(usagestr, options, 0, ctx);
 538			}
 539			switch (parse_short_opt(ctx, options)) {
 540			case -1:
 541				return parse_options_usage(usagestr, options, arg, 1);
 542			case -2:
 543				goto unknown;
 544			case -3:
 545				goto exclusive;
 546			default:
 547				break;
 548			}
 549			if (ctx->opt)
 550				check_typos(arg, options);
 551			while (ctx->opt) {
 552				if (internal_help && *ctx->opt == 'h')
 553					return usage_with_options_internal(usagestr, options, 0, ctx);
 554				arg = ctx->opt;
 555				switch (parse_short_opt(ctx, options)) {
 556				case -1:
 557					return parse_options_usage(usagestr, options, arg, 1);
 558				case -2:
 559					/* fake a short option thing to hide the fact that we may have
 560					 * started to parse aggregated stuff
 561					 *
 562					 * This is leaky, too bad.
 563					 */
 564					ctx->argv[0] = strdup(ctx->opt - 1);
 565					*(char *)ctx->argv[0] = '-';
 566					goto unknown;
 567				case -3:
 568					goto exclusive;
 569				default:
 570					break;
 571				}
 572			}
 573			continue;
 574		}
 575
 576		if (!arg[2]) { /* "--" */
 577			if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
 578				ctx->argc--;
 579				ctx->argv++;
 580			}
 581			break;
 582		}
 583
 584		arg += 2;
 585		if (internal_help && !strcmp(arg, "help-all"))
 586			return usage_with_options_internal(usagestr, options, 1, ctx);
 587		if (internal_help && !strcmp(arg, "help"))
 588			return usage_with_options_internal(usagestr, options, 0, ctx);
 589		if (!strcmp(arg, "list-opts"))
 590			return PARSE_OPT_LIST_OPTS;
 591		if (!strcmp(arg, "list-cmds"))
 592			return PARSE_OPT_LIST_SUBCMDS;
 593		switch (parse_long_opt(ctx, arg, options)) {
 594		case -1:
 595			return parse_options_usage(usagestr, options, arg, 0);
 596		case -2:
 597			goto unknown;
 598		case -3:
 599			excl_short_opt = 0;
 600			goto exclusive;
 601		default:
 602			break;
 603		}
 604		continue;
 605unknown:
 606		if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN))
 607			return PARSE_OPT_UNKNOWN;
 608		ctx->out[ctx->cpidx++] = ctx->argv[0];
 609		ctx->opt = NULL;
 610	}
 611	return PARSE_OPT_DONE;
 612
 613exclusive:
 614	parse_options_usage(usagestr, options, arg, excl_short_opt);
 615	if ((excl_short_opt && ctx->excl_opt->short_name) ||
 616	    ctx->excl_opt->long_name == NULL) {
 617		char opt = ctx->excl_opt->short_name;
 618		parse_options_usage(NULL, options, &opt, 1);
 619	} else {
 620		parse_options_usage(NULL, options, ctx->excl_opt->long_name, 0);
 621	}
 622	return PARSE_OPT_HELP;
 623}
 624
 625static int parse_options_end(struct parse_opt_ctx_t *ctx)
 626{
 627	memmove(ctx->out + ctx->cpidx, ctx->argv, ctx->argc * sizeof(*ctx->out));
 628	ctx->out[ctx->cpidx + ctx->argc] = NULL;
 629	return ctx->cpidx + ctx->argc;
 630}
 631
 632int parse_options_subcommand(int argc, const char **argv, const struct option *options,
 633			const char *const subcommands[], const char *usagestr[], int flags)
 634{
 635	struct parse_opt_ctx_t ctx;
 636	char *buf = NULL;
 637
 638	/* build usage string if it's not provided */
 639	if (subcommands && !usagestr[0]) {
 640		astrcatf(&buf, "%s %s [<options>] {", subcmd_config.exec_name, argv[0]);
 641
 642		for (int i = 0; subcommands[i]; i++) {
 643			if (i)
 644				astrcat(&buf, "|");
 645			astrcat(&buf, subcommands[i]);
 646		}
 647		astrcat(&buf, "}");
 648
 649		usagestr[0] = buf;
 650	}
 651
 652	parse_options_start(&ctx, argc, argv, flags);
 653	switch (parse_options_step(&ctx, options, usagestr)) {
 654	case PARSE_OPT_HELP:
 655		exit(129);
 656	case PARSE_OPT_DONE:
 657		break;
 658	case PARSE_OPT_LIST_OPTS:
 659		while (options->type != OPTION_END) {
 660			if (options->long_name)
 661				printf("--%s ", options->long_name);
 662			options++;
 663		}
 664		putchar('\n');
 665		exit(130);
 666	case PARSE_OPT_LIST_SUBCMDS:
 667		if (subcommands) {
 668			for (int i = 0; subcommands[i]; i++)
 669				printf("%s ", subcommands[i]);
 670		}
 671		putchar('\n');
 672		exit(130);
 673	default: /* PARSE_OPT_UNKNOWN */
 674		if (ctx.argv[0][1] == '-')
 675			astrcatf(&error_buf, "unknown option `%s'",
 676				 ctx.argv[0] + 2);
 677		else
 678			astrcatf(&error_buf, "unknown switch `%c'", *ctx.opt);
 679		usage_with_options(usagestr, options);
 680	}
 681	if (buf) {
 682		usagestr[0] = NULL;
 683		free(buf);
 684	}
 685	return parse_options_end(&ctx);
 686}
 687
 688int parse_options(int argc, const char **argv, const struct option *options,
 689		  const char * const usagestr[], int flags)
 690{
 691	return parse_options_subcommand(argc, argv, options, NULL,
 692					(const char **) usagestr, flags);
 693}
 694
 695#define USAGE_OPTS_WIDTH 24
 696#define USAGE_GAP         2
 697
 698static void print_option_help(const struct option *opts, int full)
 699{
 700	size_t pos;
 701	int pad;
 702
 703	if (opts->type == OPTION_GROUP) {
 704		fputc('\n', stderr);
 705		if (*opts->help)
 706			fprintf(stderr, "%s\n", opts->help);
 707		return;
 708	}
 709	if (!full && (opts->flags & PARSE_OPT_HIDDEN))
 710		return;
 711	if (opts->flags & PARSE_OPT_DISABLED)
 712		return;
 713
 714	pos = fprintf(stderr, "    ");
 715	if (opts->short_name)
 716		pos += fprintf(stderr, "-%c", opts->short_name);
 717	else
 718		pos += fprintf(stderr, "    ");
 719
 720	if (opts->long_name && opts->short_name)
 721		pos += fprintf(stderr, ", ");
 722	if (opts->long_name)
 723		pos += fprintf(stderr, "--%s", opts->long_name);
 724
 725	switch (opts->type) {
 726	case OPTION_ARGUMENT:
 727		break;
 728	case OPTION_LONG:
 729	case OPTION_ULONG:
 730	case OPTION_U64:
 731	case OPTION_INTEGER:
 732	case OPTION_UINTEGER:
 733		if (opts->flags & PARSE_OPT_OPTARG)
 734			if (opts->long_name)
 735				pos += fprintf(stderr, "[=<n>]");
 736			else
 737				pos += fprintf(stderr, "[<n>]");
 738		else
 739			pos += fprintf(stderr, " <n>");
 740		break;
 741	case OPTION_CALLBACK:
 742		if (opts->flags & PARSE_OPT_NOARG)
 743			break;
 744		/* FALLTHROUGH */
 745	case OPTION_STRING:
 746		if (opts->argh) {
 747			if (opts->flags & PARSE_OPT_OPTARG)
 748				if (opts->long_name)
 749					pos += fprintf(stderr, "[=<%s>]", opts->argh);
 750				else
 751					pos += fprintf(stderr, "[<%s>]", opts->argh);
 752			else
 753				pos += fprintf(stderr, " <%s>", opts->argh);
 754		} else {
 755			if (opts->flags & PARSE_OPT_OPTARG)
 756				if (opts->long_name)
 757					pos += fprintf(stderr, "[=...]");
 758				else
 759					pos += fprintf(stderr, "[...]");
 760			else
 761				pos += fprintf(stderr, " ...");
 762		}
 763		break;
 764	default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
 765	case OPTION_END:
 766	case OPTION_GROUP:
 767	case OPTION_BIT:
 768	case OPTION_BOOLEAN:
 769	case OPTION_INCR:
 770	case OPTION_SET_UINT:
 771	case OPTION_SET_PTR:
 772		break;
 773	}
 774
 775	if (pos <= USAGE_OPTS_WIDTH)
 776		pad = USAGE_OPTS_WIDTH - pos;
 777	else {
 778		fputc('\n', stderr);
 779		pad = USAGE_OPTS_WIDTH;
 780	}
 781	fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
 782	if (opts->flags & PARSE_OPT_NOBUILD)
 783		fprintf(stderr, "%*s(not built-in because %s)\n",
 784			USAGE_OPTS_WIDTH + USAGE_GAP, "",
 785			opts->build_opt);
 786}
 787
 788static int option__cmp(const void *va, const void *vb)
 789{
 790	const struct option *a = va, *b = vb;
 791	int sa = tolower(a->short_name), sb = tolower(b->short_name), ret;
 792
 793	if (sa == 0)
 794		sa = 'z' + 1;
 795	if (sb == 0)
 796		sb = 'z' + 1;
 797
 798	ret = sa - sb;
 799
 800	if (ret == 0) {
 801		const char *la = a->long_name ?: "",
 802			   *lb = b->long_name ?: "";
 803		ret = strcmp(la, lb);
 804	}
 805
 806	return ret;
 807}
 808
 809static struct option *options__order(const struct option *opts)
 810{
 811	int nr_opts = 0, nr_group = 0, len;
 812	const struct option *o = opts;
 813	struct option *opt, *ordered, *group;
 814
 815	for (o = opts; o->type != OPTION_END; o++)
 816		++nr_opts;
 817
 818	len = sizeof(*o) * (nr_opts + 1);
 819	ordered = malloc(len);
 820	if (!ordered)
 821		goto out;
 822	memcpy(ordered, opts, len);
 823
 824	/* sort each option group individually */
 825	for (opt = group = ordered; opt->type != OPTION_END; opt++) {
 826		if (opt->type == OPTION_GROUP) {
 827			qsort(group, nr_group, sizeof(*opt), option__cmp);
 828			group = opt + 1;
 829			nr_group = 0;
 830			continue;
 831		}
 832		nr_group++;
 833	}
 834	qsort(group, nr_group, sizeof(*opt), option__cmp);
 835
 836out:
 837	return ordered;
 838}
 839
 840static bool option__in_argv(const struct option *opt, const struct parse_opt_ctx_t *ctx)
 841{
 842	int i;
 843
 844	for (i = 1; i < ctx->argc; ++i) {
 845		const char *arg = ctx->argv[i];
 846
 847		if (arg[0] != '-') {
 848			if (arg[1] == '\0') {
 849				if (arg[0] == opt->short_name)
 850					return true;
 851				continue;
 852			}
 853
 854			if (opt->long_name && strcmp(opt->long_name, arg) == 0)
 855				return true;
 856
 857			if (opt->help && strcasestr(opt->help, arg) != NULL)
 858				return true;
 859
 860			continue;
 861		}
 862
 863		if (arg[1] == opt->short_name ||
 864		    (arg[1] == '-' && opt->long_name && strcmp(opt->long_name, arg + 2) == 0))
 865			return true;
 866	}
 867
 868	return false;
 869}
 870
 871static int usage_with_options_internal(const char * const *usagestr,
 872				       const struct option *opts, int full,
 873				       struct parse_opt_ctx_t *ctx)
 874{
 875	struct option *ordered;
 876
 877	if (!usagestr)
 878		return PARSE_OPT_HELP;
 879
 880	setup_pager();
 881
 882	if (error_buf) {
 883		fprintf(stderr, "  Error: %s\n", error_buf);
 884		zfree(&error_buf);
 885	}
 886
 887	fprintf(stderr, "\n Usage: %s\n", *usagestr++);
 888	while (*usagestr && **usagestr)
 889		fprintf(stderr, "    or: %s\n", *usagestr++);
 890	while (*usagestr) {
 891		fprintf(stderr, "%s%s\n",
 892				**usagestr ? "    " : "",
 893				*usagestr);
 894		usagestr++;
 895	}
 896
 897	if (opts->type != OPTION_GROUP)
 898		fputc('\n', stderr);
 899
 900	ordered = options__order(opts);
 901	if (ordered)
 902		opts = ordered;
 903
 904	for (  ; opts->type != OPTION_END; opts++) {
 905		if (ctx && ctx->argc > 1 && !option__in_argv(opts, ctx))
 906			continue;
 907		print_option_help(opts, full);
 908	}
 909
 910	fputc('\n', stderr);
 911
 912	free(ordered);
 913
 914	return PARSE_OPT_HELP;
 915}
 916
 917void usage_with_options(const char * const *usagestr,
 918			const struct option *opts)
 919{
 920	usage_with_options_internal(usagestr, opts, 0, NULL);
 921	exit(129);
 922}
 923
 924void usage_with_options_msg(const char * const *usagestr,
 925			    const struct option *opts, const char *fmt, ...)
 926{
 927	va_list ap;
 928	char *tmp = error_buf;
 929
 930	va_start(ap, fmt);
 931	if (vasprintf(&error_buf, fmt, ap) == -1)
 932		die("vasprintf failed");
 933	va_end(ap);
 934
 935	free(tmp);
 936
 937	usage_with_options_internal(usagestr, opts, 0, NULL);
 938	exit(129);
 939}
 940
 941int parse_options_usage(const char * const *usagestr,
 942			const struct option *opts,
 943			const char *optstr, bool short_opt)
 944{
 945	if (!usagestr)
 946		goto opt;
 947
 948	fprintf(stderr, "\n Usage: %s\n", *usagestr++);
 949	while (*usagestr && **usagestr)
 950		fprintf(stderr, "    or: %s\n", *usagestr++);
 951	while (*usagestr) {
 952		fprintf(stderr, "%s%s\n",
 953				**usagestr ? "    " : "",
 954				*usagestr);
 955		usagestr++;
 956	}
 957	fputc('\n', stderr);
 958
 959opt:
 960	for (  ; opts->type != OPTION_END; opts++) {
 961		if (short_opt) {
 962			if (opts->short_name == *optstr) {
 963				print_option_help(opts, 0);
 964				break;
 965			}
 966			continue;
 967		}
 968
 969		if (opts->long_name == NULL)
 970			continue;
 971
 972		if (strstarts(opts->long_name, optstr))
 973			print_option_help(opts, 0);
 974		if (strstarts("no-", optstr) &&
 975		    strstarts(opts->long_name, optstr + 3))
 976			print_option_help(opts, 0);
 977	}
 978
 979	return PARSE_OPT_HELP;
 980}
 981
 982
 983int parse_opt_verbosity_cb(const struct option *opt,
 984			   const char *arg __maybe_unused,
 985			   int unset)
 986{
 987	int *target = opt->value;
 988
 989	if (unset)
 990		/* --no-quiet, --no-verbose */
 991		*target = 0;
 992	else if (opt->short_name == 'v') {
 993		if (*target >= 0)
 994			(*target)++;
 995		else
 996			*target = 1;
 997	} else {
 998		if (*target <= 0)
 999			(*target)--;
1000		else
1001			*target = -1;
1002	}
1003	return 0;
1004}
1005
1006static struct option *
1007find_option(struct option *opts, int shortopt, const char *longopt)
1008{
1009	for (; opts->type != OPTION_END; opts++) {
1010		if ((shortopt && opts->short_name == shortopt) ||
1011		    (opts->long_name && longopt &&
1012		     !strcmp(opts->long_name, longopt)))
1013			return opts;
1014	}
1015	return NULL;
1016}
1017
1018void set_option_flag(struct option *opts, int shortopt, const char *longopt,
1019		     int flag)
1020{
1021	struct option *opt = find_option(opts, shortopt, longopt);
1022
1023	if (opt)
1024		opt->flags |= flag;
1025	return;
1026}
1027
1028void set_option_nobuild(struct option *opts, int shortopt,
1029			const char *longopt,
1030			const char *build_opt,
1031			bool can_skip)
1032{
1033	struct option *opt = find_option(opts, shortopt, longopt);
1034
1035	if (!opt)
1036		return;
1037
1038	opt->flags |= PARSE_OPT_NOBUILD;
1039	opt->flags |= can_skip ? PARSE_OPT_CANSKIP : 0;
1040	opt->build_opt = build_opt;
1041}