1 // SPDX-License-Identifier: GPL-2.0-only
3 * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com>
12 #include <linux/zalloc.h>
15 struct rb_node
*strlist__node_new(struct rblist
*rblist
, const void *entry
)
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
));
23 if (strlist
->dupstr
) {
39 static void str_node__delete(struct str_node
*snode
, bool dupstr
)
42 zfree((char **)&snode
->s
);
47 void strlist__node_delete(struct rblist
*rblist
, struct rb_node
*rb_node
)
49 struct strlist
*slist
= container_of(rblist
, struct strlist
, rblist
);
50 struct str_node
*snode
= container_of(rb_node
, struct str_node
, rb_node
);
52 str_node__delete(snode
, slist
->dupstr
);
55 static int strlist__node_cmp(struct rb_node
*rb_node
, const void *entry
)
57 const char *str
= entry
;
58 struct str_node
*snode
= container_of(rb_node
, struct str_node
, rb_node
);
60 return strcmp(snode
->s
, str
);
63 int strlist__add(struct strlist
*slist
, const char *new_entry
)
65 return rblist__add_node(&slist
->rblist
, new_entry
);
68 int strlist__load(struct strlist
*slist
, const char *filename
)
72 FILE *fp
= fopen(filename
, "r");
77 while (fgets(entry
, sizeof(entry
), fp
) != NULL
) {
78 const size_t len
= strlen(entry
);
82 entry
[len
- 1] = '\0';
84 err
= strlist__add(slist
, entry
);
95 void strlist__remove(struct strlist
*slist
, struct str_node
*snode
)
97 rblist__remove_node(&slist
->rblist
, &snode
->rb_node
);
100 struct str_node
*strlist__find(struct strlist
*slist
, const char *entry
)
102 struct str_node
*snode
= NULL
;
103 struct rb_node
*rb_node
= rblist__find(&slist
->rblist
, entry
);
106 snode
= container_of(rb_node
, struct str_node
, rb_node
);
111 static int strlist__parse_list_entry(struct strlist
*slist
, const char *s
,
112 const char *subst_dir
)
117 if (strncmp(s
, "file://", 7) == 0)
118 return strlist__load(slist
, s
+ 7);
122 if (asprintf(&subst
, "%s/%s", subst_dir
, s
) < 0)
125 if (access(subst
, F_OK
) == 0) {
126 err
= strlist__load(slist
, subst
);
130 if (slist
->file_only
) {
136 err
= strlist__add(slist
, s
);
142 static int strlist__parse_list(struct strlist
*slist
, const char *s
, const char *subst_dir
)
147 while ((sep
= strchr(s
, ',')) != NULL
) {
149 err
= strlist__parse_list_entry(slist
, s
, subst_dir
);
156 return *s
? strlist__parse_list_entry(slist
, s
, subst_dir
) : 0;
159 struct strlist
*strlist__new(const char *list
, const struct strlist_config
*config
)
161 struct strlist
*slist
= malloc(sizeof(*slist
));
165 bool file_only
= false;
166 const char *dirname
= NULL
;
169 dupstr
= !config
->dont_dupstr
;
170 dirname
= config
->dirname
;
171 file_only
= config
->file_only
;
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
;
179 slist
->dupstr
= dupstr
;
180 slist
->file_only
= file_only
;
182 if (list
&& strlist__parse_list(slist
, list
, dirname
) != 0)
192 void strlist__delete(struct strlist
*slist
)
195 rblist__delete(&slist
->rblist
);
198 struct str_node
*strlist__entry(const struct strlist
*slist
, unsigned int idx
)
200 struct str_node
*snode
= NULL
;
201 struct rb_node
*rb_node
;
203 rb_node
= rblist__entry(&slist
->rblist
, idx
);
205 snode
= container_of(rb_node
, struct str_node
, rb_node
);