aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf
diff options
context:
space:
mode:
authorNamhyung Kim <namhyung@kernel.org>2014-10-22 11:15:48 -0400
committerArnaldo Carvalho de Melo <acme@redhat.com>2014-10-29 08:32:47 -0400
commit42bd71d0812ecd955cf65a14375ebe6a3195d979 (patch)
tree503b3356e0786f3c901171d2752e0e22327bd4ed /tools/perf
parentf45d20ffb654f4559648da402b1608e747d46942 (diff)
perf tools: Add support for exclusive option
Some options cannot be used at the same time. To handle such options add a new PARSE_OPT_EXCLUSIVE flag and show error message if more than one of them is used. Signed-off-by: Namhyung Kim <namhyung@kernel.org> Reviewed-by: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Acked-by: Hemant Kumar <hemant@linux.vnet.ibm.com> Cc: David Ahern <dsahern@gmail.com> Cc: Hemant Kumar <hemant@linux.vnet.ibm.com> Cc: Ingo Molnar <mingo@kernel.org> Cc: Jiri Olsa <jolsa@redhat.com> Cc: Masami Hiramatsu <masami.hiramatsu.pt@hitachi.com> Cc: Peter Zijlstra <peterz@infradead.org> Link: http://lkml.kernel.org/r/1413990949-13953-5-git-send-email-namhyung@kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/util/parse-options.c59
-rw-r--r--tools/perf/util/parse-options.h2
2 files changed, 50 insertions, 11 deletions
diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c
index b6016101b40b..f62dee7bd924 100644
--- a/tools/perf/util/parse-options.c
+++ b/tools/perf/util/parse-options.c
@@ -45,6 +45,23 @@ static int get_value(struct parse_opt_ctx_t *p,
45 if (opt->flags & PARSE_OPT_DISABLED) 45 if (opt->flags & PARSE_OPT_DISABLED)
46 return opterror(opt, "is not usable", flags); 46 return opterror(opt, "is not usable", flags);
47 47
48 if (opt->flags & PARSE_OPT_EXCLUSIVE) {
49 if (p->excl_opt) {
50 char msg[128];
51
52 if (((flags & OPT_SHORT) && p->excl_opt->short_name) ||
53 p->excl_opt->long_name == NULL) {
54 scnprintf(msg, sizeof(msg), "cannot be used with switch `%c'",
55 p->excl_opt->short_name);
56 } else {
57 scnprintf(msg, sizeof(msg), "cannot be used with %s",
58 p->excl_opt->long_name);
59 }
60 opterror(opt, msg, flags);
61 return -3;
62 }
63 p->excl_opt = opt;
64 }
48 if (!(flags & OPT_SHORT) && p->opt) { 65 if (!(flags & OPT_SHORT) && p->opt) {
49 switch (opt->type) { 66 switch (opt->type) {
50 case OPTION_CALLBACK: 67 case OPTION_CALLBACK:
@@ -345,13 +362,14 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
345 const char * const usagestr[]) 362 const char * const usagestr[])
346{ 363{
347 int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP); 364 int internal_help = !(ctx->flags & PARSE_OPT_NO_INTERNAL_HELP);
365 int excl_short_opt = 1;
366 const char *arg;
348 367
349 /* we must reset ->opt, unknown short option leave it dangling */ 368 /* we must reset ->opt, unknown short option leave it dangling */
350 ctx->opt = NULL; 369 ctx->opt = NULL;
351 370
352 for (; ctx->argc; ctx->argc--, ctx->argv++) { 371 for (; ctx->argc; ctx->argc--, ctx->argv++) {
353 const char *arg = ctx->argv[0]; 372 arg = ctx->argv[0];
354
355 if (*arg != '-' || !arg[1]) { 373 if (*arg != '-' || !arg[1]) {
356 if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION) 374 if (ctx->flags & PARSE_OPT_STOP_AT_NON_OPTION)
357 break; 375 break;
@@ -360,19 +378,21 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
360 } 378 }
361 379
362 if (arg[1] != '-') { 380 if (arg[1] != '-') {
363 ctx->opt = arg + 1; 381 ctx->opt = ++arg;
364 if (internal_help && *ctx->opt == 'h') 382 if (internal_help && *ctx->opt == 'h')
365 return usage_with_options_internal(usagestr, options, 0); 383 return usage_with_options_internal(usagestr, options, 0);
366 switch (parse_short_opt(ctx, options)) { 384 switch (parse_short_opt(ctx, options)) {
367 case -1: 385 case -1:
368 return parse_options_usage(usagestr, options, arg + 1, 1); 386 return parse_options_usage(usagestr, options, arg, 1);
369 case -2: 387 case -2:
370 goto unknown; 388 goto unknown;
389 case -3:
390 goto exclusive;
371 default: 391 default:
372 break; 392 break;
373 } 393 }
374 if (ctx->opt) 394 if (ctx->opt)
375 check_typos(arg + 1, options); 395 check_typos(arg, options);
376 while (ctx->opt) { 396 while (ctx->opt) {
377 if (internal_help && *ctx->opt == 'h') 397 if (internal_help && *ctx->opt == 'h')
378 return usage_with_options_internal(usagestr, options, 0); 398 return usage_with_options_internal(usagestr, options, 0);
@@ -389,6 +409,8 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
389 ctx->argv[0] = strdup(ctx->opt - 1); 409 ctx->argv[0] = strdup(ctx->opt - 1);
390 *(char *)ctx->argv[0] = '-'; 410 *(char *)ctx->argv[0] = '-';
391 goto unknown; 411 goto unknown;
412 case -3:
413 goto exclusive;
392 default: 414 default:
393 break; 415 break;
394 } 416 }
@@ -404,19 +426,23 @@ int parse_options_step(struct parse_opt_ctx_t *ctx,
404 break; 426 break;
405 } 427 }
406 428
407 if (internal_help && !strcmp(arg + 2, "help-all")) 429 arg += 2;
430 if (internal_help && !strcmp(arg, "help-all"))
408 return usage_with_options_internal(usagestr, options, 1); 431 return usage_with_options_internal(usagestr, options, 1);
409 if (internal_help && !strcmp(arg + 2, "help")) 432 if (internal_help && !strcmp(arg, "help"))
410 return usage_with_options_internal(usagestr, options, 0); 433 return usage_with_options_internal(usagestr, options, 0);
411 if (!strcmp(arg + 2, "list-opts")) 434 if (!strcmp(arg, "list-opts"))
412 return PARSE_OPT_LIST_OPTS; 435 return PARSE_OPT_LIST_OPTS;
413 if (!strcmp(arg + 2, "list-cmds")) 436 if (!strcmp(arg, "list-cmds"))
414 return PARSE_OPT_LIST_SUBCMDS; 437 return PARSE_OPT_LIST_SUBCMDS;
415 switch (parse_long_opt(ctx, arg + 2, options)) { 438 switch (parse_long_opt(ctx, arg, options)) {
416 case -1: 439 case -1:
417 return parse_options_usage(usagestr, options, arg + 2, 0); 440 return parse_options_usage(usagestr, options, arg, 0);
418 case -2: 441 case -2:
419 goto unknown; 442 goto unknown;
443 case -3:
444 excl_short_opt = 0;
445 goto exclusive;
420 default: 446 default:
421 break; 447 break;
422 } 448 }
@@ -428,6 +454,17 @@ unknown:
428 ctx->opt = NULL; 454 ctx->opt = NULL;
429 } 455 }
430 return PARSE_OPT_DONE; 456 return PARSE_OPT_DONE;
457
458exclusive:
459 parse_options_usage(usagestr, options, arg, excl_short_opt);
460 if ((excl_short_opt && ctx->excl_opt->short_name) ||
461 ctx->excl_opt->long_name == NULL) {
462 char opt = ctx->excl_opt->short_name;
463 parse_options_usage(NULL, options, &opt, 1);
464 } else {
465 parse_options_usage(NULL, options, ctx->excl_opt->long_name, 0);
466 }
467 return PARSE_OPT_HELP;
431} 468}
432 469
433int parse_options_end(struct parse_opt_ctx_t *ctx) 470int parse_options_end(struct parse_opt_ctx_t *ctx)
diff --git a/tools/perf/util/parse-options.h b/tools/perf/util/parse-options.h
index b7c80dbc7627..97b153fb4999 100644
--- a/tools/perf/util/parse-options.h
+++ b/tools/perf/util/parse-options.h
@@ -39,6 +39,7 @@ enum parse_opt_option_flags {
39 PARSE_OPT_HIDDEN = 8, 39 PARSE_OPT_HIDDEN = 8,
40 PARSE_OPT_LASTARG_DEFAULT = 16, 40 PARSE_OPT_LASTARG_DEFAULT = 16,
41 PARSE_OPT_DISABLED = 32, 41 PARSE_OPT_DISABLED = 32,
42 PARSE_OPT_EXCLUSIVE = 64,
42}; 43};
43 44
44struct option; 45struct option;
@@ -174,6 +175,7 @@ struct parse_opt_ctx_t {
174 const char **out; 175 const char **out;
175 int argc, cpidx; 176 int argc, cpidx;
176 const char *opt; 177 const char *opt;
178 const struct option *excl_opt;
177 int flags; 179 int flags;
178}; 180};
179 181