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