perf session: create_kernel_maps should use ->host_machine
[deliverable/linux.git] / tools / perf / util / parse-options.c
CommitLineData
07800601
IM
1#include "util.h"
2#include "parse-options.h"
3#include "cache.h"
4
5#define OPT_SHORT 1
6#define OPT_UNSET 2
7
8static int opterror(const struct option *opt, const char *reason, int flags)
9{
10 if (flags & OPT_SHORT)
11 return error("switch `%c' %s", opt->short_name, reason);
12 if (flags & OPT_UNSET)
13 return error("option `no-%s' %s", opt->long_name, reason);
14 return error("option `%s' %s", opt->long_name, reason);
15}
16
17static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt,
18 int flags, const char **arg)
19{
20 if (p->opt) {
21 *arg = p->opt;
22 p->opt = NULL;
5a4b1817
FW
23 } else if ((opt->flags & PARSE_OPT_LASTARG_DEFAULT) && (p->argc == 1 ||
24 **(p->argv + 1) == '-')) {
07800601
IM
25 *arg = (const char *)opt->defval;
26 } else if (p->argc > 1) {
27 p->argc--;
28 *arg = *++p->argv;
29 } else
30 return opterror(opt, "requires a value", flags);
31 return 0;
32}
33
34static int get_value(struct parse_opt_ctx_t *p,
35 const struct option *opt, int flags)
36{
233f0b95 37 const char *s, *arg = NULL;
07800601
IM
38 const int unset = flags & OPT_UNSET;
39
40 if (unset && p->opt)
41 return opterror(opt, "takes no value", flags);
42 if (unset && (opt->flags & PARSE_OPT_NONEG))
43 return opterror(opt, "isn't available", flags);
44
45 if (!(flags & OPT_SHORT) && p->opt) {
46 switch (opt->type) {
47 case OPTION_CALLBACK:
48 if (!(opt->flags & PARSE_OPT_NOARG))
49 break;
50 /* FALLTHROUGH */
51 case OPTION_BOOLEAN:
c0555642 52 case OPTION_INCR:
07800601
IM
53 case OPTION_BIT:
54 case OPTION_SET_INT:
55 case OPTION_SET_PTR:
56 return opterror(opt, "takes no value", flags);
83a0944f
IM
57 case OPTION_END:
58 case OPTION_ARGUMENT:
59 case OPTION_GROUP:
60 case OPTION_STRING:
61 case OPTION_INTEGER:
62 case OPTION_LONG:
07800601
IM
63 default:
64 break;
65 }
66 }
67
68 switch (opt->type) {
69 case OPTION_BIT:
70 if (unset)
71 *(int *)opt->value &= ~opt->defval;
72 else
73 *(int *)opt->value |= opt->defval;
74 return 0;
75
76 case OPTION_BOOLEAN:
c0555642
IM
77 *(bool *)opt->value = unset ? false : true;
78 return 0;
79
80 case OPTION_INCR:
07800601
IM
81 *(int *)opt->value = unset ? 0 : *(int *)opt->value + 1;
82 return 0;
83
84 case OPTION_SET_INT:
85 *(int *)opt->value = unset ? 0 : opt->defval;
86 return 0;
87
88 case OPTION_SET_PTR:
89 *(void **)opt->value = unset ? NULL : (void *)opt->defval;
90 return 0;
91
92 case OPTION_STRING:
93 if (unset)
94 *(const char **)opt->value = NULL;
95 else if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
96 *(const char **)opt->value = (const char *)opt->defval;
97 else
98 return get_arg(p, opt, flags, (const char **)opt->value);
99 return 0;
100
101 case OPTION_CALLBACK:
102 if (unset)
103 return (*opt->callback)(opt, NULL, 1) ? (-1) : 0;
104 if (opt->flags & PARSE_OPT_NOARG)
105 return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
106 if (opt->flags & PARSE_OPT_OPTARG && !p->opt)
107 return (*opt->callback)(opt, NULL, 0) ? (-1) : 0;
108 if (get_arg(p, opt, flags, &arg))
109 return -1;
110 return (*opt->callback)(opt, arg, 0) ? (-1) : 0;
111
112 case OPTION_INTEGER:
113 if (unset) {
114 *(int *)opt->value = 0;
115 return 0;
116 }
117 if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
118 *(int *)opt->value = opt->defval;
119 return 0;
120 }
121 if (get_arg(p, opt, flags, &arg))
122 return -1;
123 *(int *)opt->value = strtol(arg, (char **)&s, 10);
124 if (*s)
125 return opterror(opt, "expects a numerical value", flags);
e61078a0
PZ
126 return 0;
127
128 case OPTION_LONG:
129 if (unset) {
130 *(long *)opt->value = 0;
131 return 0;
132 }
133 if (opt->flags & PARSE_OPT_OPTARG && !p->opt) {
134 *(long *)opt->value = opt->defval;
135 return 0;
136 }
137 if (get_arg(p, opt, flags, &arg))
138 return -1;
139 *(long *)opt->value = strtol(arg, (char **)&s, 10);
140 if (*s)
141 return opterror(opt, "expects a numerical value", flags);
07800601
IM
142 return 0;
143
83a0944f
IM
144 case OPTION_END:
145 case OPTION_ARGUMENT:
146 case OPTION_GROUP:
07800601
IM
147 default:
148 die("should not happen, someone must be hit on the forehead");
149 }
150}
151
152static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *options)
153{
154 for (; options->type != OPTION_END; options++) {
155 if (options->short_name == *p->opt) {
156 p->opt = p->opt[1] ? p->opt + 1 : NULL;
157 return get_value(p, options, OPT_SHORT);
158 }
159 }
160 return -2;
161}
162
163static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg,
164 const struct option *options)
165{
166 const char *arg_end = strchr(arg, '=');
167 const struct option *abbrev_option = NULL, *ambiguous_option = NULL;
168 int abbrev_flags = 0, ambiguous_flags = 0;
169
170 if (!arg_end)
171 arg_end = arg + strlen(arg);
172
173 for (; options->type != OPTION_END; options++) {
174 const char *rest;
175 int flags = 0;
176
177 if (!options->long_name)
178 continue;
179
180 rest = skip_prefix(arg, options->long_name);
181 if (options->type == OPTION_ARGUMENT) {
182 if (!rest)
183 continue;
184 if (*rest == '=')
185 return opterror(options, "takes no value", flags);
186 if (*rest)
187 continue;
188 p->out[p->cpidx++] = arg - 2;
189 return 0;
190 }
191 if (!rest) {
192 /* abbreviated? */
193 if (!strncmp(options->long_name, arg, arg_end - arg)) {
194is_abbreviated:
195 if (abbrev_option) {
196 /*
197 * If this is abbreviated, it is
198 * ambiguous. So when there is no
199 * exact match later, we need to
200 * error out.
201 */
202 ambiguous_option = abbrev_option;
203 ambiguous_flags = abbrev_flags;
204 }
205 if (!(flags & OPT_UNSET) && *arg_end)
206 p->opt = arg_end + 1;
207 abbrev_option = options;
208 abbrev_flags = flags;
209 continue;
210 }
211 /* negated and abbreviated very much? */
212 if (!prefixcmp("no-", arg)) {
213 flags |= OPT_UNSET;
214 goto is_abbreviated;
215 }
216 /* negated? */
217 if (strncmp(arg, "no-", 3))
218 continue;
219 flags |= OPT_UNSET;
220 rest = skip_prefix(arg + 3, options->long_name);
221 /* abbreviated and negated? */
222 if (!rest && !prefixcmp(options->long_name, arg + 3))
223 goto is_abbreviated;
224 if (!rest)
225 continue;
226 }
227 if (*rest) {
228 if (*rest != '=')
229 continue;
230 p->opt = rest + 1;
231 }
232 return get_value(p, options, flags);
233 }
234
235 if (ambiguous_option)
236 return error("Ambiguous option: %s "
237 "(could be --%s%s or --%s%s)",
238 arg,
239 (ambiguous_flags & OPT_UNSET) ? "no-" : "",
240 ambiguous_option->long_name,
241 (abbrev_flags & OPT_UNSET) ? "no-" : "",
242 abbrev_option->long_name);
243 if (abbrev_option)
244 return get_value(p, abbrev_option, abbrev_flags);
245 return -2;
246}
247
248static void check_typos(const char *arg, const struct option *options)
249{
250 if (strlen(arg) < 3)
251 return;
252
253 if (!prefixcmp(arg, "no-")) {
254 error ("did you mean `--%s` (with two dashes ?)", arg);
255 exit(129);
256 }
257
258 for (; options->type != OPTION_END; options++) {
259 if (!options->long_name)
260 continue;
261 if (!prefixcmp(options->long_name, arg)) {
262 error ("did you mean `--%s` (with two dashes ?)", arg);
263 exit(129);
264 }
265 }
266}
267
268void parse_options_start(struct parse_opt_ctx_t *ctx,
269 int argc, const char **argv, int flags)
270{
271 memset(ctx, 0, sizeof(*ctx));
272 ctx->argc = argc - 1;
273 ctx->argv = argv + 1;
274 ctx->out = argv;
275 ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0);
276 ctx->flags = flags;
277 if ((flags & PARSE_OPT_KEEP_UNKNOWN) &&
278 (flags & PARSE_OPT_STOP_AT_NON_OPTION))
279 die("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together");
280}
281
282static int usage_with_options_internal(const char * const *,
283 const struct option *, int);
284
285int parse_options_step(struct parse_opt_ctx_t *ctx,
286 const struct option *options,
287 const char * const usagestr[])
288{
289 int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
290
291 /* we must reset ->opt, unknown short option leave it dangling */
292 ctx->opt = NULL;
293
294 for (; ctx->argc; ctx->argc--, ctx->argv++) {
295 const char *arg = ctx->argv[0];
296
297 if (*arg != '-' || !arg[1]) {
298 if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
299 break;
300 ctx->out[ctx->cpidx++] = ctx->argv[0];
301 continue;
302 }
303
304 if (arg[1] != '-') {
305 ctx->opt = arg + 1;
306 if (internal_help && *ctx->opt == 'h')
307 return parse_options_usage(usagestr, options);
308 switch (parse_short_opt(ctx, options)) {
309 case -1:
310 return parse_options_usage(usagestr, options);
311 case -2:
312 goto unknown;
83a0944f
IM
313 default:
314 break;
07800601
IM
315 }
316 if (ctx->opt)
317 check_typos(arg + 1, options);
318 while (ctx->opt) {
319 if (internal_help && *ctx->opt == 'h')
320 return parse_options_usage(usagestr, options);
321 switch (parse_short_opt(ctx, options)) {
322 case -1:
323 return parse_options_usage(usagestr, options);
324 case -2:
325 /* fake a short option thing to hide the fact that we may have
326 * started to parse aggregated stuff
327 *
328 * This is leaky, too bad.
329 */
330 ctx->argv[0] = strdup(ctx->opt - 1);
331 *(char *)ctx->argv[0] = '-';
332 goto unknown;
83a0944f
IM
333 default:
334 break;
07800601
IM
335 }
336 }
337 continue;
338 }
339
340 if (!arg[2]) { /* "--" */
341 if (!(ctx->flags & PARSE_OPT_KEEP_DASHDASH)) {
342 ctx->argc--;
343 ctx->argv++;
344 }
345 break;
346 }
347
348 if (internal_help && !strcmp(arg + 2, "help-all"))
349 return usage_with_options_internal(usagestr, options, 1);
350 if (internal_help && !strcmp(arg + 2, "help"))
351 return parse_options_usage(usagestr, options);
352 switch (parse_long_opt(ctx, arg + 2, options)) {
353 case -1:
354 return parse_options_usage(usagestr, options);
355 case -2:
356 goto unknown;
83a0944f
IM
357 default:
358 break;
07800601
IM
359 }
360 continue;
361unknown:
362 if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN))
363 return PARSE_OPT_UNKNOWN;
364 ctx->out[ctx->cpidx++] = ctx->argv[0];
365 ctx->opt = NULL;
366 }
367 return PARSE_OPT_DONE;
368}
369
370int parse_options_end(struct parse_opt_ctx_t *ctx)
371{
372 memmove(ctx->out + ctx->cpidx, ctx->argv, ctx->argc * sizeof(*ctx->out));
373 ctx->out[ctx->cpidx + ctx->argc] = NULL;
374 return ctx->cpidx + ctx->argc;
375}
376
377int parse_options(int argc, const char **argv, const struct option *options,
378 const char * const usagestr[], int flags)
379{
380 struct parse_opt_ctx_t ctx;
381
382 parse_options_start(&ctx, argc, argv, flags);
383 switch (parse_options_step(&ctx, options, usagestr)) {
384 case PARSE_OPT_HELP:
385 exit(129);
386 case PARSE_OPT_DONE:
387 break;
388 default: /* PARSE_OPT_UNKNOWN */
389 if (ctx.argv[0][1] == '-') {
390 error("unknown option `%s'", ctx.argv[0] + 2);
391 } else {
392 error("unknown switch `%c'", *ctx.opt);
393 }
394 usage_with_options(usagestr, options);
395 }
396
397 return parse_options_end(&ctx);
398}
399
400#define USAGE_OPTS_WIDTH 24
401#define USAGE_GAP 2
402
403int usage_with_options_internal(const char * const *usagestr,
404 const struct option *opts, int full)
405{
406 if (!usagestr)
407 return PARSE_OPT_HELP;
408
502fc5c7 409 fprintf(stderr, "\n usage: %s\n", *usagestr++);
07800601 410 while (*usagestr && **usagestr)
6e6b754f 411 fprintf(stderr, " or: %s\n", *usagestr++);
07800601
IM
412 while (*usagestr) {
413 fprintf(stderr, "%s%s\n",
414 **usagestr ? " " : "",
415 *usagestr);
416 usagestr++;
417 }
418
419 if (opts->type != OPTION_GROUP)
420 fputc('\n', stderr);
421
422 for (; opts->type != OPTION_END; opts++) {
423 size_t pos;
424 int pad;
425
426 if (opts->type == OPTION_GROUP) {
427 fputc('\n', stderr);
428 if (*opts->help)
429 fprintf(stderr, "%s\n", opts->help);
430 continue;
431 }
432 if (!full && (opts->flags & PARSE_OPT_HIDDEN))
433 continue;
434
435 pos = fprintf(stderr, " ");
436 if (opts->short_name)
437 pos += fprintf(stderr, "-%c", opts->short_name);
bc3abfb1
LZ
438 else
439 pos += fprintf(stderr, " ");
440
07800601
IM
441 if (opts->long_name && opts->short_name)
442 pos += fprintf(stderr, ", ");
443 if (opts->long_name)
444 pos += fprintf(stderr, "--%s", opts->long_name);
445
446 switch (opts->type) {
447 case OPTION_ARGUMENT:
448 break;
449 case OPTION_INTEGER:
450 if (opts->flags & PARSE_OPT_OPTARG)
451 if (opts->long_name)
452 pos += fprintf(stderr, "[=<n>]");
453 else
454 pos += fprintf(stderr, "[<n>]");
455 else
456 pos += fprintf(stderr, " <n>");
457 break;
458 case OPTION_CALLBACK:
459 if (opts->flags & PARSE_OPT_NOARG)
460 break;
461 /* FALLTHROUGH */
462 case OPTION_STRING:
463 if (opts->argh) {
464 if (opts->flags & PARSE_OPT_OPTARG)
465 if (opts->long_name)
466 pos += fprintf(stderr, "[=<%s>]", opts->argh);
467 else
468 pos += fprintf(stderr, "[<%s>]", opts->argh);
469 else
470 pos += fprintf(stderr, " <%s>", opts->argh);
471 } else {
472 if (opts->flags & PARSE_OPT_OPTARG)
473 if (opts->long_name)
474 pos += fprintf(stderr, "[=...]");
475 else
476 pos += fprintf(stderr, "[...]");
477 else
478 pos += fprintf(stderr, " ...");
479 }
480 break;
481 default: /* OPTION_{BIT,BOOLEAN,SET_INT,SET_PTR} */
83a0944f
IM
482 case OPTION_END:
483 case OPTION_GROUP:
484 case OPTION_BIT:
485 case OPTION_BOOLEAN:
c0555642 486 case OPTION_INCR:
83a0944f
IM
487 case OPTION_SET_INT:
488 case OPTION_SET_PTR:
489 case OPTION_LONG:
07800601
IM
490 break;
491 }
492
493 if (pos <= USAGE_OPTS_WIDTH)
494 pad = USAGE_OPTS_WIDTH - pos;
495 else {
496 fputc('\n', stderr);
497 pad = USAGE_OPTS_WIDTH;
498 }
499 fprintf(stderr, "%*s%s\n", pad + USAGE_GAP, "", opts->help);
500 }
501 fputc('\n', stderr);
502
503 return PARSE_OPT_HELP;
504}
505
506void usage_with_options(const char * const *usagestr,
507 const struct option *opts)
508{
478b0973 509 exit_browser(false);
07800601
IM
510 usage_with_options_internal(usagestr, opts, 0);
511 exit(129);
512}
513
514int parse_options_usage(const char * const *usagestr,
515 const struct option *opts)
516{
517 return usage_with_options_internal(usagestr, opts, 0);
518}
519
520
f37a291c 521int parse_opt_verbosity_cb(const struct option *opt, const char *arg __used,
07800601
IM
522 int unset)
523{
524 int *target = opt->value;
525
526 if (unset)
527 /* --no-quiet, --no-verbose */
528 *target = 0;
529 else if (opt->short_name == 'v') {
530 if (*target >= 0)
531 (*target)++;
532 else
533 *target = 1;
534 } else {
535 if (*target <= 0)
536 (*target)--;
537 else
538 *target = -1;
539 }
540 return 0;
541}
This page took 0.123365 seconds and 5 git commands to generate.