Linux Perf
strlist.c
Go to the documentation of this file.
1 /*
2  * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com>
3  *
4  * Licensed under the GPLv2.
5  */
6 
7 #include "strlist.h"
8 #include "util.h"
9 #include <errno.h>
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <unistd.h>
14 
15 static
16 struct rb_node *strlist__node_new(struct rblist *rblist, const void *entry)
17 {
18  const char *s = entry;
19  struct rb_node *rc = NULL;
20  struct strlist *strlist = container_of(rblist, struct strlist, rblist);
21  struct str_node *snode = malloc(sizeof(*snode));
22 
23  if (snode != NULL) {
24  if (strlist->dupstr) {
25  s = strdup(s);
26  if (s == NULL)
27  goto out_delete;
28  }
29  snode->s = s;
30  rc = &snode->rb_node;
31  }
32 
33  return rc;
34 
35 out_delete:
36  free(snode);
37  return NULL;
38 }
39 
40 static void str_node__delete(struct str_node *snode, bool dupstr)
41 {
42  if (dupstr)
43  zfree((char **)&snode->s);
44  free(snode);
45 }
46 
47 static
49 {
50  struct strlist *slist = container_of(rblist, struct strlist, rblist);
51  struct str_node *snode = container_of(rb_node, struct str_node, rb_node);
52 
53  str_node__delete(snode, slist->dupstr);
54 }
55 
56 static int strlist__node_cmp(struct rb_node *rb_node, const void *entry)
57 {
58  const char *str = entry;
59  struct str_node *snode = container_of(rb_node, struct str_node, rb_node);
60 
61  return strcmp(snode->s, str);
62 }
63 
64 int strlist__add(struct strlist *slist, const char *new_entry)
65 {
66  return rblist__add_node(&slist->rblist, new_entry);
67 }
68 
69 int strlist__load(struct strlist *slist, const char *filename)
70 {
71  char entry[1024];
72  int err;
73  FILE *fp = fopen(filename, "r");
74 
75  if (fp == NULL)
76  return -errno;
77 
78  while (fgets(entry, sizeof(entry), fp) != NULL) {
79  const size_t len = strlen(entry);
80 
81  if (len == 0)
82  continue;
83  entry[len - 1] = '\0';
84 
85  err = strlist__add(slist, entry);
86  if (err != 0)
87  goto out;
88  }
89 
90  err = 0;
91 out:
92  fclose(fp);
93  return err;
94 }
95 
96 void strlist__remove(struct strlist *slist, struct str_node *snode)
97 {
98  rblist__remove_node(&slist->rblist, &snode->rb_node);
99 }
100 
101 struct str_node *strlist__find(struct strlist *slist, const char *entry)
102 {
103  struct str_node *snode = NULL;
104  struct rb_node *rb_node = rblist__find(&slist->rblist, entry);
105 
106  if (rb_node)
107  snode = container_of(rb_node, struct str_node, rb_node);
108 
109  return snode;
110 }
111 
112 static int strlist__parse_list_entry(struct strlist *slist, const char *s,
113  const char *subst_dir)
114 {
115  int err;
116  char *subst = NULL;
117 
118  if (strncmp(s, "file://", 7) == 0)
119  return strlist__load(slist, s + 7);
120 
121  if (subst_dir) {
122  err = -ENOMEM;
123  if (asprintf(&subst, "%s/%s", subst_dir, s) < 0)
124  goto out;
125 
126  if (access(subst, F_OK) == 0) {
127  err = strlist__load(slist, subst);
128  goto out;
129  }
130 
131  if (slist->file_only) {
132  err = -ENOENT;
133  goto out;
134  }
135  }
136 
137  err = strlist__add(slist, s);
138 out:
139  free(subst);
140  return err;
141 }
142 
143 static int strlist__parse_list(struct strlist *slist, const char *s, const char *subst_dir)
144 {
145  char *sep;
146  int err;
147 
148  while ((sep = strchr(s, ',')) != NULL) {
149  *sep = '\0';
150  err = strlist__parse_list_entry(slist, s, subst_dir);
151  *sep = ',';
152  if (err != 0)
153  return err;
154  s = sep + 1;
155  }
156 
157  return *s ? strlist__parse_list_entry(slist, s, subst_dir) : 0;
158 }
159 
160 struct strlist *strlist__new(const char *list, const struct strlist_config *config)
161 {
162  struct strlist *slist = malloc(sizeof(*slist));
163 
164  if (slist != NULL) {
165  bool dupstr = true;
166  bool file_only = false;
167  const char *dirname = NULL;
168 
169  if (config) {
170  dupstr = !config->dont_dupstr;
171  dirname = config->dirname;
172  file_only = config->file_only;
173  }
174 
175  rblist__init(&slist->rblist);
179 
180  slist->dupstr = dupstr;
181  slist->file_only = file_only;
182 
183  if (list && strlist__parse_list(slist, list, dirname) != 0)
184  goto out_error;
185  }
186 
187  return slist;
188 out_error:
189  free(slist);
190  return NULL;
191 }
192 
193 void strlist__delete(struct strlist *slist)
194 {
195  if (slist != NULL)
196  rblist__delete(&slist->rblist);
197 }
198 
199 struct str_node *strlist__entry(const struct strlist *slist, unsigned int idx)
200 {
201  struct str_node *snode = NULL;
202  struct rb_node *rb_node;
203 
204  rb_node = rblist__entry(&slist->rblist, idx);
205  if (rb_node)
206  snode = container_of(rb_node, struct str_node, rb_node);
207 
208  return snode;
209 }
bool file_only
Definition: strlist.h:18
const char * filename
Definition: hists_common.c:26
int int err
Definition: 5sec.c:44
int strlist__add(struct strlist *slist, const char *new_entry)
Definition: strlist.c:64
void rblist__delete(struct rblist *rblist)
Definition: rblist.c:115
#define config
Definition: rblist.h:22
static void str_node__delete(struct str_node *snode, bool dupstr)
Definition: strlist.c:40
int(* node_cmp)(struct rb_node *rbn, const void *entry)
Definition: rblist.h:26
static int strlist__node_cmp(struct rb_node *rb_node, const void *entry)
Definition: strlist.c:56
int strlist__load(struct strlist *slist, const char *filename)
Definition: strlist.c:69
static int strlist__parse_list_entry(struct strlist *slist, const char *s, const char *subst_dir)
Definition: strlist.c:112
void(* node_delete)(struct rblist *rblist, struct rb_node *rb_node)
Definition: rblist.h:28
struct str_node * strlist__find(struct strlist *slist, const char *entry)
Definition: strlist.c:101
void * malloc(YYSIZE_T)
struct rb_node * rblist__find(struct rblist *rblist, const void *entry)
Definition: rblist.c:84
struct rb_node * rblist__entry(const struct rblist *rblist, unsigned int idx)
Definition: rblist.c:123
bool dont_dupstr
Definition: strlist.h:27
bool dupstr
Definition: strlist.h:17
static int entry(u64 ip, struct unwind_info *ui)
Definition: unwind-libdw.c:71
struct str_node * strlist__entry(const struct strlist *slist, unsigned int idx)
Definition: strlist.c:199
static int str(yyscan_t scanner, int token)
static int strlist__parse_list(struct strlist *slist, const char *s, const char *subst_dir)
Definition: strlist.c:143
static struct rb_node * strlist__node_new(struct rblist *rblist, const void *entry)
Definition: strlist.c:16
#define zfree(ptr)
Definition: util.h:25
struct rb_node *(* node_new)(struct rblist *rlist, const void *new_entry)
Definition: rblist.h:27
void rblist__init(struct rblist *rblist)
Definition: rblist.c:94
struct rb_node rb_node
Definition: strlist.h:11
struct rblist rblist
Definition: strlist.h:16
int rblist__add_node(struct rblist *rblist, const void *new_entry)
Definition: rblist.c:14
void strlist__remove(struct strlist *slist, struct str_node *snode)
Definition: strlist.c:96
void strlist__delete(struct strlist *slist)
Definition: strlist.c:193
const char * dirname
Definition: strlist.h:29
void free(void *)
static void strlist__node_delete(struct rblist *rblist, struct rb_node *rb_node)
Definition: strlist.c:48
void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node)
Definition: rblist.c:44
bool file_only
Definition: strlist.h:28
const char * s
Definition: strlist.h:12
struct strlist * strlist__new(const char *list, const struct strlist_config *config)
Definition: strlist.c:160