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