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