~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/perf/util/strlist.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php