Linux-libre 4.4.228-gnu
[librecmc/linux-libre.git] / tools / perf / util / parse-regs-options.c
1 #include "perf.h"
2 #include "util/util.h"
3 #include "util/debug.h"
4 #include "util/parse-options.h"
5 #include "util/parse-regs-options.h"
6
7 int
8 parse_regs(const struct option *opt, const char *str, int unset)
9 {
10         uint64_t *mode = (uint64_t *)opt->value;
11         const struct sample_reg *r;
12         char *s, *os = NULL, *p;
13         int ret = -1;
14
15         if (unset)
16                 return 0;
17
18         /*
19          * cannot set it twice
20          */
21         if (*mode)
22                 return -1;
23
24         /* str may be NULL in case no arg is passed to -I */
25         if (str) {
26                 /* because str is read-only */
27                 s = os = strdup(str);
28                 if (!s)
29                         return -1;
30
31                 for (;;) {
32                         p = strchr(s, ',');
33                         if (p)
34                                 *p = '\0';
35
36                         if (!strcmp(s, "?")) {
37                                 fprintf(stderr, "available registers: ");
38                                 for (r = sample_reg_masks; r->name; r++) {
39                                         fprintf(stderr, "%s ", r->name);
40                                 }
41                                 fputc('\n', stderr);
42                                 /* just printing available regs */
43                                 return -1;
44                         }
45                         for (r = sample_reg_masks; r->name; r++) {
46                                 if (!strcasecmp(s, r->name))
47                                         break;
48                         }
49                         if (!r->name) {
50                                 ui__warning("unknown register %s,"
51                                             " check man page\n", s);
52                                 goto error;
53                         }
54
55                         *mode |= r->mask;
56
57                         if (!p)
58                                 break;
59
60                         s = p + 1;
61                 }
62         }
63         ret = 0;
64
65         /* default to all possible regs */
66         if (*mode == 0)
67                 *mode = PERF_REGS_MASK;
68 error:
69         free(os);
70         return ret;
71 }