Linux Audio

Check our new training course

Loading...
v6.2
   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, len;
 810	const struct option *o = opts;
 811	struct option *opt, *ordered, *group;
 812
 813	for (o = opts; o->type != OPTION_END; o++)
 814		++nr_opts;
 815
 816	len = sizeof(*o) * (nr_opts + 1);
 817	ordered = malloc(len);
 818	if (!ordered)
 819		goto out;
 820	memcpy(ordered, opts, len);
 821
 822	/* sort each option group individually */
 823	for (opt = group = ordered; opt->type != OPTION_END; opt++) {
 824		if (opt->type == OPTION_GROUP) {
 825			qsort(group, nr_group, sizeof(*opt), option__cmp);
 826			group = opt + 1;
 827			nr_group = 0;
 828			continue;
 829		}
 830		nr_group++;
 831	}
 832	qsort(group, nr_group, sizeof(*opt), option__cmp);
 833
 834out:
 835	return ordered;
 836}
 837
 838static bool option__in_argv(const struct option *opt, const struct parse_opt_ctx_t *ctx)
 839{
 840	int i;
 841
 842	for (i = 1; i < ctx->argc; ++i) {
 843		const char *arg = ctx->argv[i];
 844
 845		if (arg[0] != '-') {
 846			if (arg[1] == '\0') {
 847				if (arg[0] == opt->short_name)
 848					return true;
 849				continue;
 850			}
 851
 852			if (opt->long_name && strcmp(opt->long_name, arg) == 0)
 853				return true;
 854
 855			if (opt->help && strcasestr(opt->help, arg) != NULL)
 856				return true;
 857
 858			continue;
 859		}
 860
 861		if (arg[1] == opt->short_name ||
 862		    (arg[1] == '-' && opt->long_name && strcmp(opt->long_name, arg + 2) == 0))
 863			return true;
 864	}
 865
 866	return false;
 867}
 868
 869static int usage_with_options_internal(const char * const *usagestr,
 870				       const struct option *opts, int full,
 871				       struct parse_opt_ctx_t *ctx)
 872{
 873	struct option *ordered;
 874
 875	if (!usagestr)
 876		return PARSE_OPT_HELP;
 877
 878	setup_pager();
 879
 880	if (error_buf) {
 881		fprintf(stderr, "  Error: %s\n", error_buf);
 882		zfree(&error_buf);
 883	}
 884
 885	fprintf(stderr, "\n Usage: %s\n", *usagestr++);
 886	while (*usagestr && **usagestr)
 887		fprintf(stderr, "    or: %s\n", *usagestr++);
 888	while (*usagestr) {
 889		fprintf(stderr, "%s%s\n",
 890				**usagestr ? "    " : "",
 891				*usagestr);
 892		usagestr++;
 893	}
 894
 895	if (opts->type != OPTION_GROUP)
 896		fputc('\n', stderr);
 897
 898	ordered = options__order(opts);
 899	if (ordered)
 900		opts = ordered;
 901
 902	for (  ; opts->type != OPTION_END; opts++) {
 903		if (ctx && ctx->argc > 1 && !option__in_argv(opts, ctx))
 904			continue;
 905		print_option_help(opts, full);
 906	}
 907
 908	fputc('\n', stderr);
 909
 910	free(ordered);
 911
 912	return PARSE_OPT_HELP;
 913}
 914
 915void usage_with_options(const char * const *usagestr,
 916			const struct option *opts)
 917{
 918	usage_with_options_internal(usagestr, opts, 0, NULL);
 919	exit(129);
 920}
 921
 922void usage_with_options_msg(const char * const *usagestr,
 923			    const struct option *opts, const char *fmt, ...)
 924{
 925	va_list ap;
 926	char *tmp = error_buf;
 927
 928	va_start(ap, fmt);
 929	if (vasprintf(&error_buf, fmt, ap) == -1)
 930		die("vasprintf failed");
 931	va_end(ap);
 932
 933	free(tmp);
 934
 935	usage_with_options_internal(usagestr, opts, 0, NULL);
 936	exit(129);
 937}
 938
 939int parse_options_usage(const char * const *usagestr,
 940			const struct option *opts,
 941			const char *optstr, bool short_opt)
 942{
 943	if (!usagestr)
 944		goto opt;
 945
 946	fprintf(stderr, "\n Usage: %s\n", *usagestr++);
 947	while (*usagestr && **usagestr)
 948		fprintf(stderr, "    or: %s\n", *usagestr++);
 949	while (*usagestr) {
 950		fprintf(stderr, "%s%s\n",
 951				**usagestr ? "    " : "",
 952				*usagestr);
 953		usagestr++;
 954	}
 955	fputc('\n', stderr);
 956
 957opt:
 958	for (  ; opts->type != OPTION_END; opts++) {
 959		if (short_opt) {
 960			if (opts->short_name == *optstr) {
 961				print_option_help(opts, 0);
 962				break;
 963			}
 964			continue;
 965		}
 966
 967		if (opts->long_name == NULL)
 968			continue;
 969
 970		if (strstarts(opts->long_name, optstr))
 971			print_option_help(opts, 0);
 972		if (strstarts("no-", optstr) &&
 973		    strstarts(opts->long_name, optstr + 3))
 974			print_option_help(opts, 0);
 975	}
 976
 977	return PARSE_OPT_HELP;
 978}
 979
 980
 981int parse_opt_verbosity_cb(const struct option *opt,
 982			   const char *arg __maybe_unused,
 983			   int unset)
 984{
 985	int *target = opt->value;
 986
 987	if (unset)
 988		/* --no-quiet, --no-verbose */
 989		*target = 0;
 990	else if (opt->short_name == 'v') {
 991		if (*target >= 0)
 992			(*target)++;
 993		else
 994			*target = 1;
 995	} else {
 996		if (*target <= 0)
 997			(*target)--;
 998		else
 999			*target = -1;
1000	}
1001	return 0;
1002}
1003
1004static struct option *
1005find_option(struct option *opts, int shortopt, const char *longopt)
1006{
1007	for (; opts->type != OPTION_END; opts++) {
1008		if ((shortopt && opts->short_name == shortopt) ||
1009		    (opts->long_name && longopt &&
1010		     !strcmp(opts->long_name, longopt)))
1011			return opts;
1012	}
1013	return NULL;
1014}
1015
1016void set_option_flag(struct option *opts, int shortopt, const char *longopt,
1017		     int flag)
1018{
1019	struct option *opt = find_option(opts, shortopt, longopt);
1020
1021	if (opt)
1022		opt->flags |= flag;
1023	return;
1024}
1025
1026void set_option_nobuild(struct option *opts, int shortopt,
1027			const char *longopt,
1028			const char *build_opt,
1029			bool can_skip)
1030{
1031	struct option *opt = find_option(opts, shortopt, longopt);
1032
1033	if (!opt)
1034		return;
1035
1036	opt->flags |= PARSE_OPT_NOBUILD;
1037	opt->flags |= can_skip ? PARSE_OPT_CANSKIP : 0;
1038	opt->build_opt = build_opt;
1039}
v6.8
   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, len;
 810	const struct option *o = opts;
 811	struct option *opt, *ordered, *group;
 812
 813	for (o = opts; o->type != OPTION_END; o++)
 814		++nr_opts;
 815
 816	len = sizeof(*o) * (nr_opts + 1);
 817	ordered = malloc(len);
 818	if (!ordered)
 819		goto out;
 820	memcpy(ordered, opts, len);
 821
 822	/* sort each option group individually */
 823	for (opt = group = ordered; opt->type != OPTION_END; opt++) {
 824		if (opt->type == OPTION_GROUP) {
 825			qsort(group, nr_group, sizeof(*opt), option__cmp);
 826			group = opt + 1;
 827			nr_group = 0;
 828			continue;
 829		}
 830		nr_group++;
 831	}
 832	qsort(group, nr_group, sizeof(*opt), option__cmp);
 833
 834out:
 835	return ordered;
 836}
 837
 838static bool option__in_argv(const struct option *opt, const struct parse_opt_ctx_t *ctx)
 839{
 840	int i;
 841
 842	for (i = 1; i < ctx->argc; ++i) {
 843		const char *arg = ctx->argv[i];
 844
 845		if (arg[0] != '-') {
 846			if (arg[1] == '\0') {
 847				if (arg[0] == opt->short_name)
 848					return true;
 849				continue;
 850			}
 851
 852			if (opt->long_name && strcmp(opt->long_name, arg) == 0)
 853				return true;
 854
 855			if (opt->help && strcasestr(opt->help, arg) != NULL)
 856				return true;
 857
 858			continue;
 859		}
 860
 861		if (arg[1] == opt->short_name ||
 862		    (arg[1] == '-' && opt->long_name && strcmp(opt->long_name, arg + 2) == 0))
 863			return true;
 864	}
 865
 866	return false;
 867}
 868
 869static int usage_with_options_internal(const char * const *usagestr,
 870				       const struct option *opts, int full,
 871				       struct parse_opt_ctx_t *ctx)
 872{
 873	struct option *ordered;
 874
 875	if (!usagestr)
 876		return PARSE_OPT_HELP;
 877
 878	setup_pager();
 879
 880	if (error_buf) {
 881		fprintf(stderr, "  Error: %s\n", error_buf);
 882		zfree(&error_buf);
 883	}
 884
 885	fprintf(stderr, "\n Usage: %s\n", *usagestr++);
 886	while (*usagestr && **usagestr)
 887		fprintf(stderr, "    or: %s\n", *usagestr++);
 888	while (*usagestr) {
 889		fprintf(stderr, "%s%s\n",
 890				**usagestr ? "    " : "",
 891				*usagestr);
 892		usagestr++;
 893	}
 894
 895	if (opts->type != OPTION_GROUP)
 896		fputc('\n', stderr);
 897
 898	ordered = options__order(opts);
 899	if (ordered)
 900		opts = ordered;
 901
 902	for (  ; opts->type != OPTION_END; opts++) {
 903		if (ctx && ctx->argc > 1 && !option__in_argv(opts, ctx))
 904			continue;
 905		print_option_help(opts, full);
 906	}
 907
 908	fputc('\n', stderr);
 909
 910	free(ordered);
 911
 912	return PARSE_OPT_HELP;
 913}
 914
 915void usage_with_options(const char * const *usagestr,
 916			const struct option *opts)
 917{
 918	usage_with_options_internal(usagestr, opts, 0, NULL);
 919	exit(129);
 920}
 921
 922void usage_with_options_msg(const char * const *usagestr,
 923			    const struct option *opts, const char *fmt, ...)
 924{
 925	va_list ap;
 926	char *tmp = error_buf;
 927
 928	va_start(ap, fmt);
 929	if (vasprintf(&error_buf, fmt, ap) == -1)
 930		die("vasprintf failed");
 931	va_end(ap);
 932
 933	free(tmp);
 934
 935	usage_with_options_internal(usagestr, opts, 0, NULL);
 936	exit(129);
 937}
 938
 939int parse_options_usage(const char * const *usagestr,
 940			const struct option *opts,
 941			const char *optstr, bool short_opt)
 942{
 943	if (!usagestr)
 944		goto opt;
 945
 946	fprintf(stderr, "\n Usage: %s\n", *usagestr++);
 947	while (*usagestr && **usagestr)
 948		fprintf(stderr, "    or: %s\n", *usagestr++);
 949	while (*usagestr) {
 950		fprintf(stderr, "%s%s\n",
 951				**usagestr ? "    " : "",
 952				*usagestr);
 953		usagestr++;
 954	}
 955	fputc('\n', stderr);
 956
 957opt:
 958	for (  ; opts->type != OPTION_END; opts++) {
 959		if (short_opt) {
 960			if (opts->short_name == *optstr) {
 961				print_option_help(opts, 0);
 962				break;
 963			}
 964			continue;
 965		}
 966
 967		if (opts->long_name == NULL)
 968			continue;
 969
 970		if (strstarts(opts->long_name, optstr))
 971			print_option_help(opts, 0);
 972		if (strstarts("no-", optstr) &&
 973		    strstarts(opts->long_name, optstr + 3))
 974			print_option_help(opts, 0);
 975	}
 976
 977	return PARSE_OPT_HELP;
 978}
 979
 980
 981int parse_opt_verbosity_cb(const struct option *opt,
 982			   const char *arg __maybe_unused,
 983			   int unset)
 984{
 985	int *target = opt->value;
 986
 987	if (unset)
 988		/* --no-quiet, --no-verbose */
 989		*target = 0;
 990	else if (opt->short_name == 'v') {
 991		if (*target >= 0)
 992			(*target)++;
 993		else
 994			*target = 1;
 995	} else {
 996		if (*target <= 0)
 997			(*target)--;
 998		else
 999			*target = -1;
1000	}
1001	return 0;
1002}
1003
1004static struct option *
1005find_option(struct option *opts, int shortopt, const char *longopt)
1006{
1007	for (; opts->type != OPTION_END; opts++) {
1008		if ((shortopt && opts->short_name == shortopt) ||
1009		    (opts->long_name && longopt &&
1010		     !strcmp(opts->long_name, longopt)))
1011			return opts;
1012	}
1013	return NULL;
1014}
1015
1016void set_option_flag(struct option *opts, int shortopt, const char *longopt,
1017		     int flag)
1018{
1019	struct option *opt = find_option(opts, shortopt, longopt);
1020
1021	if (opt)
1022		opt->flags |= flag;
1023	return;
1024}
1025
1026void set_option_nobuild(struct option *opts, int shortopt,
1027			const char *longopt,
1028			const char *build_opt,
1029			bool can_skip)
1030{
1031	struct option *opt = find_option(opts, shortopt, longopt);
1032
1033	if (!opt)
1034		return;
1035
1036	opt->flags |= PARSE_OPT_NOBUILD;
1037	opt->flags |= can_skip ? PARSE_OPT_CANSKIP : 0;
1038	opt->build_opt = build_opt;
1039}