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
 637	/* build usage string if it's not provided */
 638	if (subcommands && !usagestr[0]) {
 639		char *buf = NULL;
 640
 641		astrcatf(&buf, "%s %s [<options>] {", subcmd_config.exec_name, argv[0]);
 642
 643		for (int i = 0; subcommands[i]; i++) {
 644			if (i)
 645				astrcat(&buf, "|");
 646			astrcat(&buf, subcommands[i]);
 647		}
 648		astrcat(&buf, "}");
 649
 650		usagestr[0] = buf;
 651	}
 652
 653	parse_options_start(&ctx, argc, argv, flags);
 654	switch (parse_options_step(&ctx, options, usagestr)) {
 655	case PARSE_OPT_HELP:
 656		exit(129);
 657	case PARSE_OPT_DONE:
 658		break;
 659	case PARSE_OPT_LIST_OPTS:
 660		while (options->type != OPTION_END) {
 661			if (options->long_name)
 662				printf("--%s ", options->long_name);
 663			options++;
 664		}
 665		putchar('\n');
 666		exit(130);
 667	case PARSE_OPT_LIST_SUBCMDS:
 668		if (subcommands) {
 669			for (int i = 0; subcommands[i]; i++)
 670				printf("%s ", subcommands[i]);
 671		}
 672		putchar('\n');
 673		exit(130);
 674	default: /* PARSE_OPT_UNKNOWN */
 675		if (ctx.argv[0][1] == '-')
 676			astrcatf(&error_buf, "unknown option `%s'",
 677				 ctx.argv[0] + 2);
 678		else
 679			astrcatf(&error_buf, "unknown switch `%c'", *ctx.opt);
 680		usage_with_options(usagestr, options);
 681	}
 682
 683	return parse_options_end(&ctx);
 684}
 685
 686int parse_options(int argc, const char **argv, const struct option *options,
 687		  const char * const usagestr[], int flags)
 688{
 689	return parse_options_subcommand(argc, argv, options, NULL,
 690					(const char **) usagestr, flags);
 691}
 692
 693#define USAGE_OPTS_WIDTH 24
 694#define USAGE_GAP         2
 695
 696static void print_option_help(const struct option *opts, int full)
 697{
 698	size_t pos;
 699	int pad;
 700
 701	if (opts->type == OPTION_GROUP) {
 702		fputc('\n', stderr);
 703		if (*opts->help)
 704			fprintf(stderr, "%s\n", opts->help);
 705		return;
 706	}
 707	if (!full && (opts->flags & PARSE_OPT_HIDDEN))
 708		return;
 709	if (opts->flags & PARSE_OPT_DISABLED)
 710		return;
 711
 712	pos = fprintf(stderr, "    ");
 713	if (opts->short_name)
 714		pos += fprintf(stderr, "-%c", opts->short_name);
 715	else
 716		pos += fprintf(stderr, "    ");
 717
 718	if (opts->long_name && opts->short_name)
 719		pos += fprintf(stderr, ", ");
 720	if (opts->long_name)
 721		pos += fprintf(stderr, "--%s", opts->long_name);
 722
 723	switch (opts->type) {
 724	case OPTION_ARGUMENT:
 725		break;
 726	case OPTION_LONG:
 727	case OPTION_ULONG:
 728	case OPTION_U64:
 729	case OPTION_INTEGER:
 730	case OPTION_UINTEGER:
 731		if (opts->flags & PARSE_OPT_OPTARG)
 732			if (opts->long_name)
 733				pos += fprintf(stderr, "[=<n>]");
 734			else
 735				pos += fprintf(stderr, "[<n>]");
 736		else
 737			pos += fprintf(stderr, " <n>");
 738		break;
 739	case OPTION_CALLBACK:
 740		if (opts->flags & PARSE_OPT_NOARG)
 741			break;
 742		/* FALLTHROUGH */
 743	case OPTION_STRING:
 744		if (opts->argh) {
 745			if (opts->flags & PARSE_OPT_OPTARG)
 746				if (opts->long_name)
 747					pos += fprintf(stderr, "[=<%s>]", opts->argh);
 748				else
 749					pos += fprintf(stderr, "[<%s>]", opts->argh);
 750			else
 751				pos += fprintf(stderr, " <%s>", opts->argh);
 752		} else {
 753			if (opts->flags & PARSE_OPT_OPTARG)
 754				if (opts->long_name)
 755					pos += fprintf(stderr, "[=...]");
 756				else
 757					pos += fprintf(stderr, "[...]");
 758			else
 759				pos += fprintf(stderr, " ...");
 760		}
 761		break;
 762	default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
 763	case OPTION_END:
 764	case OPTION_GROUP:
 765	case OPTION_BIT:
 766	case OPTION_BOOLEAN:
 767	case OPTION_INCR:
 768	case OPTION_SET_UINT:
 769	case OPTION_SET_PTR:
 770		break;
 771	}
 772
 773	if (pos <= USAGE_OPTS_WIDTH)
 774		pad = USAGE_OPTS_WIDTH - pos;
 775	else {
 776		fputc('\n', stderr);
 777		pad = USAGE_OPTS_WIDTH;
 778	}
 779	fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
 780	if (opts->flags & PARSE_OPT_NOBUILD)
 781		fprintf(stderr, "%*s(not built-in because %s)\n",
 782			USAGE_OPTS_WIDTH + USAGE_GAP, "",
 783			opts->build_opt);
 784}
 785
 786static int option__cmp(const void *va, const void *vb)
 787{
 788	const struct option *a = va, *b = vb;
 789	int sa = tolower(a->short_name), sb = tolower(b->short_name), ret;
 790
 791	if (sa == 0)
 792		sa = 'z' + 1;
 793	if (sb == 0)
 794		sb = 'z' + 1;
 795
 796	ret = sa - sb;
 797
 798	if (ret == 0) {
 799		const char *la = a->long_name ?: "",
 800			   *lb = b->long_name ?: "";
 801		ret = strcmp(la, lb);
 802	}
 803
 804	return ret;
 805}
 806
 807static struct option *options__order(const struct option *opts)
 808{
 809	int nr_opts = 0, nr_group = 0, nr_parent = 0, len;
 810	const struct option *o = NULL, *p = opts;
 811	struct option *opt, *ordered = NULL, *group;
 812
 813	/* flatten the options that have parents */
 814	for (p = opts; p != NULL; p = o->parent) {
 815		for (o = p; o->type != OPTION_END; o++)
 816			++nr_opts;
 817
 818		/*
 819		 * the length is given by the number of options plus a null
 820		 * terminator for the last loop iteration.
 821		 */
 822		len = sizeof(*o) * (nr_opts + !o->parent);
 823		group = realloc(ordered, len);
 824		if (!group)
 825			goto out;
 826		ordered = group;
 827		memcpy(&ordered[nr_parent], p, sizeof(*o) * (nr_opts - nr_parent));
 828
 829		nr_parent = nr_opts;
 830	}
 831	/* copy the last OPTION_END */
 832	memcpy(&ordered[nr_opts], o, sizeof(*o));
 833
 834	/* sort each option group individually */
 835	for (opt = group = ordered; opt->type != OPTION_END; opt++) {
 836		if (opt->type == OPTION_GROUP) {
 837			qsort(group, nr_group, sizeof(*opt), option__cmp);
 838			group = opt + 1;
 839			nr_group = 0;
 840			continue;
 841		}
 842		nr_group++;
 843	}
 844	qsort(group, nr_group, sizeof(*opt), option__cmp);
 845
 846out:
 847	return ordered;
 848}
 849
 850static bool option__in_argv(const struct option *opt, const struct parse_opt_ctx_t *ctx)
 851{
 852	int i;
 853
 854	for (i = 1; i < ctx->argc; ++i) {
 855		const char *arg = ctx->argv[i];
 856
 857		if (arg[0] != '-') {
 858			if (arg[1] == '\0') {
 859				if (arg[0] == opt->short_name)
 860					return true;
 861				continue;
 862			}
 863
 864			if (opt->long_name && strcmp(opt->long_name, arg) == 0)
 865				return true;
 866
 867			if (opt->help && strcasestr(opt->help, arg) != NULL)
 868				return true;
 869
 870			continue;
 871		}
 872
 873		if (arg[1] == opt->short_name ||
 874		    (arg[1] == '-' && opt->long_name && strcmp(opt->long_name, arg + 2) == 0))
 875			return true;
 876	}
 877
 878	return false;
 879}
 880
 881static int usage_with_options_internal(const char * const *usagestr,
 882				       const struct option *opts, int full,
 883				       struct parse_opt_ctx_t *ctx)
 884{
 885	struct option *ordered;
 886
 887	if (!usagestr)
 888		return PARSE_OPT_HELP;
 889
 890	setup_pager();
 891
 892	if (error_buf) {
 893		fprintf(stderr, "  Error: %s\n", error_buf);
 894		zfree(&error_buf);
 895	}
 896
 897	fprintf(stderr, "\n Usage: %s\n", *usagestr++);
 898	while (*usagestr && **usagestr)
 899		fprintf(stderr, "    or: %s\n", *usagestr++);
 900	while (*usagestr) {
 901		fprintf(stderr, "%s%s\n",
 902				**usagestr ? "    " : "",
 903				*usagestr);
 904		usagestr++;
 905	}
 906
 907	if (opts->type != OPTION_GROUP)
 908		fputc('\n', stderr);
 909
 910	ordered = options__order(opts);
 911	if (ordered)
 912		opts = ordered;
 913
 914	for (  ; opts->type != OPTION_END; opts++) {
 915		if (ctx && ctx->argc > 1 && !option__in_argv(opts, ctx))
 916			continue;
 917		print_option_help(opts, full);
 918	}
 919
 920	fputc('\n', stderr);
 921
 922	free(ordered);
 923
 924	return PARSE_OPT_HELP;
 925}
 926
 927void usage_with_options(const char * const *usagestr,
 928			const struct option *opts)
 929{
 930	usage_with_options_internal(usagestr, opts, 0, NULL);
 931	exit(129);
 932}
 933
 934void usage_with_options_msg(const char * const *usagestr,
 935			    const struct option *opts, const char *fmt, ...)
 936{
 937	va_list ap;
 938	char *tmp = error_buf;
 939
 940	va_start(ap, fmt);
 941	if (vasprintf(&error_buf, fmt, ap) == -1)
 942		die("vasprintf failed");
 943	va_end(ap);
 944
 945	free(tmp);
 946
 947	usage_with_options_internal(usagestr, opts, 0, NULL);
 948	exit(129);
 949}
 950
 951int parse_options_usage(const char * const *usagestr,
 952			const struct option *opts,
 953			const char *optstr, bool short_opt)
 954{
 955	if (!usagestr)
 956		goto opt;
 957
 958	fprintf(stderr, "\n Usage: %s\n", *usagestr++);
 959	while (*usagestr && **usagestr)
 960		fprintf(stderr, "    or: %s\n", *usagestr++);
 961	while (*usagestr) {
 962		fprintf(stderr, "%s%s\n",
 963				**usagestr ? "    " : "",
 964				*usagestr);
 965		usagestr++;
 966	}
 967	fputc('\n', stderr);
 968
 969opt:
 970	for (  ; opts->type != OPTION_END; opts++) {
 971		if (short_opt) {
 972			if (opts->short_name == *optstr) {
 973				print_option_help(opts, 0);
 974				break;
 975			}
 976			continue;
 977		}
 978
 979		if (opts->long_name == NULL)
 980			continue;
 981
 982		if (strstarts(opts->long_name, optstr))
 983			print_option_help(opts, 0);
 984		if (strstarts("no-", optstr) &&
 985		    strstarts(opts->long_name, optstr + 3))
 986			print_option_help(opts, 0);
 987	}
 988
 989	return PARSE_OPT_HELP;
 990}
 991
 992
 993int parse_opt_verbosity_cb(const struct option *opt,
 994			   const char *arg __maybe_unused,
 995			   int unset)
 996{
 997	int *target = opt->value;
 998
 999	if (unset)
1000		/* --no-quiet, --no-verbose */
1001		*target = 0;
1002	else if (opt->short_name == 'v') {
1003		if (*target >= 0)
1004			(*target)++;
1005		else
1006			*target = 1;
1007	} else {
1008		if (*target <= 0)
1009			(*target)--;
1010		else
1011			*target = -1;
1012	}
1013	return 0;
1014}
1015
1016static struct option *
1017find_option(struct option *opts, int shortopt, const char *longopt)
1018{
1019	for (; opts->type != OPTION_END; opts++) {
1020		if ((shortopt && opts->short_name == shortopt) ||
1021		    (opts->long_name && longopt &&
1022		     !strcmp(opts->long_name, longopt)))
1023			return opts;
1024	}
1025	return NULL;
1026}
1027
1028void set_option_flag(struct option *opts, int shortopt, const char *longopt,
1029		     int flag)
1030{
1031	struct option *opt = find_option(opts, shortopt, longopt);
1032
1033	if (opt)
1034		opt->flags |= flag;
1035	return;
1036}
1037
1038void set_option_nobuild(struct option *opts, int shortopt,
1039			const char *longopt,
1040			const char *build_opt,
1041			bool can_skip)
1042{
1043	struct option *opt = find_option(opts, shortopt, longopt);
1044
1045	if (!opt)
1046		return;
1047
1048	opt->flags |= PARSE_OPT_NOBUILD;
1049	opt->flags |= can_skip ? PARSE_OPT_CANSKIP : 0;
1050	opt->build_opt = build_opt;
1051}