root/tools/perf/util/parse-branch-options.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. parse_branch_str
  2. parse_branch_stack

   1 // SPDX-License-Identifier: GPL-2.0
   2 #include "util/debug.h"
   3 #include "util/event.h"
   4 #include <subcmd/parse-options.h>
   5 #include "util/parse-branch-options.h"
   6 #include <stdlib.h>
   7 #include <string.h>
   8 
   9 #define BRANCH_OPT(n, m) \
  10         { .name = n, .mode = (m) }
  11 
  12 #define BRANCH_END { .name = NULL }
  13 
  14 struct branch_mode {
  15         const char *name;
  16         int mode;
  17 };
  18 
  19 static const struct branch_mode branch_modes[] = {
  20         BRANCH_OPT("u", PERF_SAMPLE_BRANCH_USER),
  21         BRANCH_OPT("k", PERF_SAMPLE_BRANCH_KERNEL),
  22         BRANCH_OPT("hv", PERF_SAMPLE_BRANCH_HV),
  23         BRANCH_OPT("any", PERF_SAMPLE_BRANCH_ANY),
  24         BRANCH_OPT("any_call", PERF_SAMPLE_BRANCH_ANY_CALL),
  25         BRANCH_OPT("any_ret", PERF_SAMPLE_BRANCH_ANY_RETURN),
  26         BRANCH_OPT("ind_call", PERF_SAMPLE_BRANCH_IND_CALL),
  27         BRANCH_OPT("abort_tx", PERF_SAMPLE_BRANCH_ABORT_TX),
  28         BRANCH_OPT("in_tx", PERF_SAMPLE_BRANCH_IN_TX),
  29         BRANCH_OPT("no_tx", PERF_SAMPLE_BRANCH_NO_TX),
  30         BRANCH_OPT("cond", PERF_SAMPLE_BRANCH_COND),
  31         BRANCH_OPT("ind_jmp", PERF_SAMPLE_BRANCH_IND_JUMP),
  32         BRANCH_OPT("call", PERF_SAMPLE_BRANCH_CALL),
  33         BRANCH_OPT("save_type", PERF_SAMPLE_BRANCH_TYPE_SAVE),
  34         BRANCH_OPT("stack", PERF_SAMPLE_BRANCH_CALL_STACK),
  35         BRANCH_END
  36 };
  37 
  38 int parse_branch_str(const char *str, __u64 *mode)
  39 {
  40 #define ONLY_PLM \
  41         (PERF_SAMPLE_BRANCH_USER        |\
  42          PERF_SAMPLE_BRANCH_KERNEL      |\
  43          PERF_SAMPLE_BRANCH_HV)
  44 
  45         int ret = 0;
  46         char *p, *s;
  47         char *os = NULL;
  48         const struct branch_mode *br;
  49 
  50         if (str == NULL) {
  51                 *mode = PERF_SAMPLE_BRANCH_ANY;
  52                 return 0;
  53         }
  54 
  55         /* because str is read-only */
  56         s = os = strdup(str);
  57         if (!s)
  58                 return -1;
  59 
  60         for (;;) {
  61                 p = strchr(s, ',');
  62                 if (p)
  63                         *p = '\0';
  64 
  65                 for (br = branch_modes; br->name; br++) {
  66                         if (!strcasecmp(s, br->name))
  67                                 break;
  68                 }
  69                 if (!br->name) {
  70                         ret = -1;
  71                         pr_warning("unknown branch filter %s,"
  72                                     " check man page\n", s);
  73                         goto error;
  74                 }
  75 
  76                 *mode |= br->mode;
  77 
  78                 if (!p)
  79                         break;
  80 
  81                 s = p + 1;
  82         }
  83 
  84         /* default to any branch */
  85         if ((*mode & ~ONLY_PLM) == 0) {
  86                 *mode = PERF_SAMPLE_BRANCH_ANY;
  87         }
  88 error:
  89         free(os);
  90         return ret;
  91 }
  92 
  93 int
  94 parse_branch_stack(const struct option *opt, const char *str, int unset)
  95 {
  96         __u64 *mode = (__u64 *)opt->value;
  97 
  98         if (unset)
  99                 return 0;
 100 
 101         /*
 102          * cannot set it twice, -b + --branch-filter for instance
 103          */
 104         if (*mode)
 105                 return -1;
 106 
 107         return parse_branch_str(str, mode);
 108 }

/* [<][>][^][v][top][bottom][index][help] */