1#include "util.h"
2#include "parse-options.h"
3#include "cache.h"
4#include "header.h"
5
6#define OPT_SHORT 1
7#define OPT_UNSET 2
8
9static int opterror(const struct option *opt, const char *reason, int flags)
10{
11	if (flags & OPT_SHORT)
12		return error("switch `%c' %s", opt->short_name, reason);
13	if (flags & OPT_UNSET)
14		return error("option `no-%s' %s", opt->long_name, reason);
15	return error("option `%s' %s", opt->long_name, reason);
16}
17
18static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt,
19		   int flags, const char **arg)
20{
21	if (p->opt) {
22		*arg = p->opt;
23		p->opt = NULL;
24	} else if ((opt->flags & PARSE_OPT_LASTARG_DEFAULT) && (p->argc == 1 ||
25		    **(p->argv + 1) == '-')) {
26		*arg = (const char *)opt->defval;
27	} else if (p->argc > 1) {
28		p->argc--;
29		*arg = *++p->argv;
30	} else
31		return opterror(opt, "requires a value", flags);
32	return 0;
33}
34
35static int get_value(struct parse_opt_ctx_t *p,
36		     const struct option *opt, int flags)
37{
38	const char *s, *arg = NULL;
39	const int unset = flags & OPT_UNSET;
40	int err;
41
42	if (unset && p->opt)
43		return opterror(opt, "takes no value", flags);
44	if (unset && (opt->flags & PARSE_OPT_NONEG))
45		return opterror(opt, "isn't available", flags);
46	if (opt->flags & PARSE_OPT_DISABLED)
47		return opterror(opt, "is not usable", flags);
48
49	if (opt->flags & PARSE_OPT_EXCLUSIVE) {
50		if (p->excl_opt && p->excl_opt != opt) {
51			char msg[128];
52
53			if (((flags & OPT_SHORT) && p->excl_opt->short_name) ||
54			    p->excl_opt->long_name == NULL) {
55				scnprintf(msg, sizeof(msg), "cannot be used with switch `%c'",
56					  p->excl_opt->short_name);
57			} else {
58				scnprintf(msg, sizeof(msg), "cannot be used with %s",
59					  p->excl_opt->long_name);
60			}
61			opterror(opt, msg, flags);
62			return -3;
63		}
64		p->excl_opt = opt;
65	}
66	if (!(flags & OPT_SHORT) && p->opt) {
67		switch (opt->type) {
68		case OPTION_CALLBACK:
69			if (!(opt->flags & PARSE_OPT_NOARG))
70				break;
71			/* FALLTHROUGH */
72		case OPTION_BOOLEAN:
73		case OPTION_INCR:
74		case OPTION_BIT:
75		case OPTION_SET_UINT:
76		case OPTION_SET_PTR:
77			return opterror(opt, "takes no value", flags);
78		case OPTION_END:
79		case OPTION_ARGUMENT:
80		case OPTION_GROUP:
81		case OPTION_STRING:
82		case OPTION_INTEGER:
83		case OPTION_UINTEGER:
84		case OPTION_LONG:
85		case OPTION_U64:
86		default:
87			break;
88		}
89	}
90
91	switch (opt->type) {
92	case OPTION_BIT:
93		if (unset)
94			*(int *)opt->value &= ~opt->defval;
95		else
96			*(int *)opt->value |= opt->defval;
97		return 0;
98
99	case OPTION_BOOLEAN:
100		*(bool *)opt->value = unset ? false : true;
101		if (opt->set)
102			*(bool *)opt->set = true;
103		return 0;
104
105	case OPTION_INCR:
106		*(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
107		return 0;
108
109	case OPTION_SET_UINT:
110		*(unsigned int *)opt->value = unset ? 0 : opt->defval;
111		return 0;
112
113	case OPTION_SET_PTR:
114		*(void **)opt->value = unset ? NULL : (void *)opt->defval;
115		return 0;
116
117	case OPTION_STRING:
118		err = 0;
119		if (unset)
120			*(const char **)opt->value = NULL;
121		else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
122			*(const char **)opt->value = (const char *)opt->defval;
123		else
124			err = get_arg(p, opt, flags, (const char **)opt->value);
125
126		/* PARSE_OPT_NOEMPTY: Allow NULL but disallow empty string. */
127		if (opt->flags & PARSE_OPT_NOEMPTY) {
128			const char *val = *(const char **)opt->value;
129
130			if (!val)
131				return err;
132
133			/* Similar to unset if we are given an empty string. */
134			if (val[0] == '\0') {
135				*(const char **)opt->value = NULL;
136				return 0;
137			}
138		}
139
140		return err;
141
142	case OPTION_CALLBACK:
143		if (unset)
144			return (*opt->callback)(opt, NULL, 1) ? (-1) : 0;
145		if (opt->flags & PARSE_OPT_NOARG)
146			return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
147		if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
148			return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
149		if (get_arg(p, opt, flags, &arg))
150			return -1;
151		return (*opt->callback)(opt, arg, 0) ? (-1) : 0;
152
153	case OPTION_INTEGER:
154		if (unset) {
155			*(int *)opt->value = 0;
156			return 0;
157		}
158		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
159			*(int *)opt->value = opt->defval;
160			return 0;
161		}
162		if (get_arg(p, opt, flags, &arg))
163			return -1;
164		*(int *)opt->value = strtol(arg, (char **)&s, 10);
165		if (*s)
166			return opterror(opt, "expects a numerical value", flags);
167		return 0;
168
169	case OPTION_UINTEGER:
170		if (unset) {
171			*(unsigned int *)opt->value = 0;
172			return 0;
173		}
174		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
175			*(unsigned int *)opt->value = opt->defval;
176			return 0;
177		}
178		if (get_arg(p, opt, flags, &arg))
179			return -1;
180		*(unsigned int *)opt->value = strtol(arg, (char **)&s, 10);
181		if (*s)
182			return opterror(opt, "expects a numerical value", flags);
183		return 0;
184
185	case OPTION_LONG:
186		if (unset) {
187			*(long *)opt->value = 0;
188			return 0;
189		}
190		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
191			*(long *)opt->value = opt->defval;
192			return 0;
193		}
194		if (get_arg(p, opt, flags, &arg))
195			return -1;
196		*(long *)opt->value = strtol(arg, (char **)&s, 10);
197		if (*s)
198			return opterror(opt, "expects a numerical value", flags);
199		return 0;
200
201	case OPTION_U64:
202		if (unset) {
203			*(u64 *)opt->value = 0;
204			return 0;
205		}
206		if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
207			*(u64 *)opt->value = opt->defval;
208			return 0;
209		}
210		if (get_arg(p, opt, flags, &arg))
211			return -1;
212		*(u64 *)opt->value = strtoull(arg, (char **)&s, 10);
213		if (*s)
214			return opterror(opt, "expects a numerical value", flags);
215		return 0;
216
217	case OPTION_END:
218	case OPTION_ARGUMENT:
219	case OPTION_GROUP:
220	default:
221		die("should not happen, someone must be hit on the forehead");
222	}
223}
224
225static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *options)
226{
227	for (; options->type != OPTION_END; options++) {
228		if (options->short_name == *p->opt) {
229			p->opt = p->opt[1] ? p->opt + 1 : NULL;
230			return get_value(p, options, OPT_SHORT);
231		}
232	}
233	return -2;
234}
235
236static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
237                          const struct option *options)
238{
239	const char *arg_end = strchr(arg, '=');
240	const struct option *abbrev_option = NULL, *ambiguous_option = NULL;
241	int abbrev_flags = 0, ambiguous_flags = 0;
242
243	if (!arg_end)
244		arg_end = arg + strlen(arg);
245
246	for (; options->type != OPTION_END; options++) {
247		const char *rest;
248		int flags = 0;
249
250		if (!options->long_name)
251			continue;
252
253		rest = skip_prefix(arg, options->long_name);
254		if (options->type == OPTION_ARGUMENT) {
255			if (!rest)
256				continue;
257			if (*rest == '=')
258				return opterror(options, "takes no value", flags);
259			if (*rest)
260				continue;
261			p->out[p->cpidx++] = arg - 2;
262			return 0;
263		}
264		if (!rest) {
265			if (!prefixcmp(options->long_name, "no-")) {
266				/*
267				 * The long name itself starts with "no-", so
268				 * accept the option without "no-" so that users
269				 * do not have to enter "no-no-" to get the
270				 * negation.
271				 */
272				rest = skip_prefix(arg, options->long_name + 3);
273				if (rest) {
274					flags |= OPT_UNSET;
275					goto match;
276				}
277				/* Abbreviated case */
278				if (!prefixcmp(options->long_name + 3, arg)) {
279					flags |= OPT_UNSET;
280					goto is_abbreviated;
281				}
282			}
283			/* abbreviated? */
284			if (!strncmp(options->long_name, arg, arg_end - arg)) {
285is_abbreviated:
286				if (abbrev_option) {
287					/*
288					 * If this is abbreviated, it is
289					 * ambiguous. So when there is no
290					 * exact match later, we need to
291					 * error out.
292					 */
293					ambiguous_option = abbrev_option;
294					ambiguous_flags = abbrev_flags;
295				}
296				if (!(flags & OPT_UNSET) && *arg_end)
297					p->opt = arg_end + 1;
298				abbrev_option = options;
299				abbrev_flags = flags;
300				continue;
301			}
302			/* negated and abbreviated very much? */
303			if (!prefixcmp("no-", arg)) {
304				flags |= OPT_UNSET;
305				goto is_abbreviated;
306			}
307			/* negated? */
308			if (strncmp(arg, "no-", 3))
309				continue;
310			flags |= OPT_UNSET;
311			rest = skip_prefix(arg + 3, options->long_name);
312			/* abbreviated and negated? */
313			if (!rest && !prefixcmp(options->long_name, arg + 3))
314				goto is_abbreviated;
315			if (!rest)
316				continue;
317		}
318match:
319		if (*rest) {
320			if (*rest != '=')
321				continue;
322			p->opt = rest + 1;
323		}
324		return get_value(p, options, flags);
325	}
326
327	if (ambiguous_option)
328		return error("Ambiguous option: %s "
329			"(could be --%s%s or --%s%s)",
330			arg,
331			(ambiguous_flags & OPT_UNSET) ?  "no-" : "",
332			ambiguous_option->long_name,
333			(abbrev_flags & OPT_UNSET) ?  "no-" : "",
334			abbrev_option->long_name);
335	if (abbrev_option)
336		return get_value(p, abbrev_option, abbrev_flags);
337	return -2;
338}
339
340static void check_typos(const char *arg, const struct option *options)
341{
342	if (strlen(arg) < 3)
343		return;
344
345	if (!prefixcmp(arg, "no-")) {
346		error ("did you mean `--%s` (with two dashes ?)", arg);
347		exit(129);
348	}
349
350	for (; options->type != OPTION_END; options++) {
351		if (!options->long_name)
352			continue;
353		if (!prefixcmp(options->long_name, arg)) {
354			error ("did you mean `--%s` (with two dashes ?)", arg);
355			exit(129);
356		}
357	}
358}
359
360void parse_options_start(struct parse_opt_ctx_t *ctx,
361			 int argc, const char **argv, int flags)
362{
363	memset(ctx, 0, sizeof(*ctx));
364	ctx->argc = argc - 1;
365	ctx->argv = argv + 1;
366	ctx->out  = argv;
367	ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
368	ctx->flags = flags;
369	if ((flags & PARSE_OPT_KEEP_UNKNOWN) &&
370	    (flags & PARSE_OPT_STOP_AT_NON_OPTION))
371		die("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
372}
373
374static int usage_with_options_internal(const char * const *,
375				       const struct option *, int);
376
377int parse_options_step(struct parse_opt_ctx_t *ctx,
378		       const struct option *options,
379		       const char * const usagestr[])
380{
381	int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
382	int excl_short_opt = 1;
383	const char *arg;
384
385	/* we must reset ->opt, unknown short option leave it dangling */
386	ctx->opt = NULL;
387
388	for (; ctx->argc; ctx->argc--, ctx->argv++) {
389		arg = ctx->argv[0];
390		if (*arg != '-' || !arg[1]) {
391			if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
392				break;
393			ctx->out[ctx->cpidx++] = ctx->argv[0];
394			continue;
395		}
396
397		if (arg[1] != '-') {
398			ctx->opt = ++arg;
399			if (internal_help && *ctx->opt == 'h')
400				return usage_with_options_internal(usagestr, options, 0);
401			switch (parse_short_opt(ctx, options)) {
402			case -1:
403				return parse_options_usage(usagestr, options, arg, 1);
404			case -2:
405				goto unknown;
406			case -3:
407				goto exclusive;
408			default:
409				break;
410			}
411			if (ctx->opt)
412				check_typos(arg, options);
413			while (ctx->opt) {
414				if (internal_help && *ctx->opt == 'h')
415					return usage_with_options_internal(usagestr, options, 0);
416				arg = ctx->opt;
417				switch (parse_short_opt(ctx, options)) {
418				case -1:
419					return parse_options_usage(usagestr, options, arg, 1);
420				case -2:
421					/* fake a short option thing to hide the fact that we may have
422					 * started to parse aggregated stuff
423					 *
424					 * This is leaky, too bad.
425					 */
426					ctx->argv[0] = strdup(ctx->opt - 1);
427					*(char *)ctx->argv[0] = '-';
428					goto unknown;
429				case -3:
430					goto exclusive;
431				default:
432					break;
433				}
434			}
435			continue;
436		}
437
438		if (!arg[2]) { /* "--" */
439			if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
440				ctx->argc--;
441				ctx->argv++;
442			}
443			break;
444		}
445
446		arg += 2;
447		if (internal_help && !strcmp(arg, "help-all"))
448			return usage_with_options_internal(usagestr, options, 1);
449		if (internal_help && !strcmp(arg, "help"))
450			return usage_with_options_internal(usagestr, options, 0);
451		if (!strcmp(arg, "list-opts"))
452			return PARSE_OPT_LIST_OPTS;
453		if (!strcmp(arg, "list-cmds"))
454			return PARSE_OPT_LIST_SUBCMDS;
455		switch (parse_long_opt(ctx, arg, options)) {
456		case -1:
457			return parse_options_usage(usagestr, options, arg, 0);
458		case -2:
459			goto unknown;
460		case -3:
461			excl_short_opt = 0;
462			goto exclusive;
463		default:
464			break;
465		}
466		continue;
467unknown:
468		if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN))
469			return PARSE_OPT_UNKNOWN;
470		ctx->out[ctx->cpidx++] = ctx->argv[0];
471		ctx->opt = NULL;
472	}
473	return PARSE_OPT_DONE;
474
475exclusive:
476	parse_options_usage(usagestr, options, arg, excl_short_opt);
477	if ((excl_short_opt && ctx->excl_opt->short_name) ||
478	    ctx->excl_opt->long_name == NULL) {
479		char opt = ctx->excl_opt->short_name;
480		parse_options_usage(NULL, options, &opt, 1);
481	} else {
482		parse_options_usage(NULL, options, ctx->excl_opt->long_name, 0);
483	}
484	return PARSE_OPT_HELP;
485}
486
487int parse_options_end(struct parse_opt_ctx_t *ctx)
488{
489	memmove(ctx->out + ctx->cpidx, ctx->argv, ctx->argc * sizeof(*ctx->out));
490	ctx->out[ctx->cpidx + ctx->argc] = NULL;
491	return ctx->cpidx + ctx->argc;
492}
493
494int parse_options_subcommand(int argc, const char **argv, const struct option *options,
495			const char *const subcommands[], const char *usagestr[], int flags)
496{
497	struct parse_opt_ctx_t ctx;
498
499	perf_header__set_cmdline(argc, argv);
500
501	/* build usage string if it's not provided */
502	if (subcommands && !usagestr[0]) {
503		struct strbuf buf = STRBUF_INIT;
504
505		strbuf_addf(&buf, "perf %s [<options>] {", argv[0]);
506		for (int i = 0; subcommands[i]; i++) {
507			if (i)
508				strbuf_addstr(&buf, "|");
509			strbuf_addstr(&buf, subcommands[i]);
510		}
511		strbuf_addstr(&buf, "}");
512
513		usagestr[0] = strdup(buf.buf);
514		strbuf_release(&buf);
515	}
516
517	parse_options_start(&ctx, argc, argv, flags);
518	switch (parse_options_step(&ctx, options, usagestr)) {
519	case PARSE_OPT_HELP:
520		exit(129);
521	case PARSE_OPT_DONE:
522		break;
523	case PARSE_OPT_LIST_OPTS:
524		while (options->type != OPTION_END) {
525			if (options->long_name)
526				printf("--%s ", options->long_name);
527			options++;
528		}
529		putchar('\n');
530		exit(130);
531	case PARSE_OPT_LIST_SUBCMDS:
532		if (subcommands) {
533			for (int i = 0; subcommands[i]; i++)
534				printf("%s ", subcommands[i]);
535		}
536		putchar('\n');
537		exit(130);
538	default: /* PARSE_OPT_UNKNOWN */
539		if (ctx.argv[0][1] == '-') {
540			error("unknown option `%s'", ctx.argv[0] + 2);
541		} else {
542			error("unknown switch `%c'", *ctx.opt);
543		}
544		usage_with_options(usagestr, options);
545	}
546
547	return parse_options_end(&ctx);
548}
549
550int parse_options(int argc, const char **argv, const struct option *options,
551		  const char * const usagestr[], int flags)
552{
553	return parse_options_subcommand(argc, argv, options, NULL,
554					(const char **) usagestr, flags);
555}
556
557#define USAGE_OPTS_WIDTH 24
558#define USAGE_GAP         2
559
560static void print_option_help(const struct option *opts, int full)
561{
562	size_t pos;
563	int pad;
564
565	if (opts->type == OPTION_GROUP) {
566		fputc('\n', stderr);
567		if (*opts->help)
568			fprintf(stderr, "%s\n", opts->help);
569		return;
570	}
571	if (!full && (opts->flags & PARSE_OPT_HIDDEN))
572		return;
573	if (opts->flags & PARSE_OPT_DISABLED)
574		return;
575
576	pos = fprintf(stderr, "    ");
577	if (opts->short_name)
578		pos += fprintf(stderr, "-%c", opts->short_name);
579	else
580		pos += fprintf(stderr, "    ");
581
582	if (opts->long_name && opts->short_name)
583		pos += fprintf(stderr, ", ");
584	if (opts->long_name)
585		pos += fprintf(stderr, "--%s", opts->long_name);
586
587	switch (opts->type) {
588	case OPTION_ARGUMENT:
589		break;
590	case OPTION_LONG:
591	case OPTION_U64:
592	case OPTION_INTEGER:
593	case OPTION_UINTEGER:
594		if (opts->flags & PARSE_OPT_OPTARG)
595			if (opts->long_name)
596				pos += fprintf(stderr, "[=<n>]");
597			else
598				pos += fprintf(stderr, "[<n>]");
599		else
600			pos += fprintf(stderr, " <n>");
601		break;
602	case OPTION_CALLBACK:
603		if (opts->flags & PARSE_OPT_NOARG)
604			break;
605		/* FALLTHROUGH */
606	case OPTION_STRING:
607		if (opts->argh) {
608			if (opts->flags & PARSE_OPT_OPTARG)
609				if (opts->long_name)
610					pos += fprintf(stderr, "[=<%s>]", opts->argh);
611				else
612					pos += fprintf(stderr, "[<%s>]", opts->argh);
613			else
614				pos += fprintf(stderr, " <%s>", opts->argh);
615		} else {
616			if (opts->flags & PARSE_OPT_OPTARG)
617				if (opts->long_name)
618					pos += fprintf(stderr, "[=...]");
619				else
620					pos += fprintf(stderr, "[...]");
621			else
622				pos += fprintf(stderr, " ...");
623		}
624		break;
625	default: /* OPTION_{BIT,BOOLEAN,SET_UINT,SET_PTR} */
626	case OPTION_END:
627	case OPTION_GROUP:
628	case OPTION_BIT:
629	case OPTION_BOOLEAN:
630	case OPTION_INCR:
631	case OPTION_SET_UINT:
632	case OPTION_SET_PTR:
633		break;
634	}
635
636	if (pos <= USAGE_OPTS_WIDTH)
637		pad = USAGE_OPTS_WIDTH - pos;
638	else {
639		fputc('\n', stderr);
640		pad = USAGE_OPTS_WIDTH;
641	}
642	fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
643}
644
645int usage_with_options_internal(const char * const *usagestr,
646				const struct option *opts, int full)
647{
648	if (!usagestr)
649		return PARSE_OPT_HELP;
650
651	fprintf(stderr, "\n usage: %s\n", *usagestr++);
652	while (*usagestr && **usagestr)
653		fprintf(stderr, "    or: %s\n", *usagestr++);
654	while (*usagestr) {
655		fprintf(stderr, "%s%s\n",
656				**usagestr ? "    " : "",
657				*usagestr);
658		usagestr++;
659	}
660
661	if (opts->type != OPTION_GROUP)
662		fputc('\n', stderr);
663
664	for (  ; opts->type != OPTION_END; opts++)
665		print_option_help(opts, full);
666
667	fputc('\n', stderr);
668
669	return PARSE_OPT_HELP;
670}
671
672void usage_with_options(const char * const *usagestr,
673			const struct option *opts)
674{
675	exit_browser(false);
676	usage_with_options_internal(usagestr, opts, 0);
677	exit(129);
678}
679
680int parse_options_usage(const char * const *usagestr,
681			const struct option *opts,
682			const char *optstr, bool short_opt)
683{
684	if (!usagestr)
685		goto opt;
686
687	fprintf(stderr, "\n usage: %s\n", *usagestr++);
688	while (*usagestr && **usagestr)
689		fprintf(stderr, "    or: %s\n", *usagestr++);
690	while (*usagestr) {
691		fprintf(stderr, "%s%s\n",
692				**usagestr ? "    " : "",
693				*usagestr);
694		usagestr++;
695	}
696	fputc('\n', stderr);
697
698opt:
699	for (  ; opts->type != OPTION_END; opts++) {
700		if (short_opt) {
701			if (opts->short_name == *optstr)
702				break;
703			continue;
704		}
705
706		if (opts->long_name == NULL)
707			continue;
708
709		if (!prefixcmp(optstr, opts->long_name))
710			break;
711		if (!prefixcmp(optstr, "no-") &&
712		    !prefixcmp(optstr + 3, opts->long_name))
713			break;
714	}
715
716	if (opts->type != OPTION_END)
717		print_option_help(opts, 0);
718
719	return PARSE_OPT_HELP;
720}
721
722
723int parse_opt_verbosity_cb(const struct option *opt,
724			   const char *arg __maybe_unused,
725			   int unset)
726{
727	int *target = opt->value;
728
729	if (unset)
730		/* --no-quiet, --no-verbose */
731		*target = 0;
732	else if (opt->short_name == 'v') {
733		if (*target >= 0)
734			(*target)++;
735		else
736			*target = 1;
737	} else {
738		if (*target <= 0)
739			(*target)--;
740		else
741			*target = -1;
742	}
743	return 0;
744}
745
746void set_option_flag(struct option *opts, int shortopt, const char *longopt,
747		     int flag)
748{
749	for (; opts->type != OPTION_END; opts++) {
750		if ((shortopt && opts->short_name == shortopt) ||
751		    (opts->long_name && longopt &&
752		     !strcmp(opts->long_name, longopt))) {
753			opts->flags |= flag;
754			break;
755		}
756	}
757}
758