2 * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com>
4 * Licensed under the GPLv2.
16 struct rb_node
*strlist__node_new(struct rblist
*rblist
, const void *entry
)
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
));
24 if (strlist
->dupstr
) {
40 static void str_node__delete(struct str_node
*snode
, bool dupstr
)
43 zfree((char **)&snode
->s
);
48 void strlist__node_delete(struct rblist
*rblist
, struct rb_node
*rb_node
)
50 struct strlist
*slist
= container_of(rblist
, struct strlist
, rblist
);
51 struct str_node
*snode
= container_of(rb_node
, struct str_node
, rb_node
);
53 str_node__delete(snode
, slist
->dupstr
);
56 static int strlist__node_cmp(struct rb_node
*rb_node
, const void *entry
)
58 const char *str
= entry
;
59 struct str_node
*snode
= container_of(rb_node
, struct str_node
, rb_node
);
61 return strcmp(snode
->s
, str
);
64 int strlist__add(struct strlist
*slist
, const char *new_entry
)
66 return rblist__add_node(&slist
->rblist
, new_entry
);
69 int strlist__load(struct strlist
*slist
, const char *filename
)
73 FILE *fp
= fopen(filename
, "r");
78 while (fgets(entry
, sizeof(entry
), fp
) != NULL
) {
79 const size_t len
= strlen(entry
);
83 entry
[len
- 1] = '\0';
85 err
= strlist__add(slist
, entry
);
96 void strlist__remove(struct strlist
*slist
, struct str_node
*snode
)
98 rblist__remove_node(&slist
->rblist
, &snode
->rb_node
);
101 struct str_node
*strlist__find(struct strlist
*slist
, const char *entry
)
103 struct str_node
*snode
= NULL
;
104 struct rb_node
*rb_node
= rblist__find(&slist
->rblist
, entry
);
107 snode
= container_of(rb_node
, struct str_node
, rb_node
);
112 static int strlist__parse_list_entry(struct strlist
*slist
, const char *s
,
113 const char *subst_dir
)
118 if (strncmp(s
, "file://", 7) == 0)
119 return strlist__load(slist
, s
+ 7);
123 if (asprintf(&subst
, "%s/%s", subst_dir
, s
) < 0)
126 if (access(subst
, F_OK
) == 0) {
127 err
= strlist__load(slist
, subst
);
131 if (slist
->file_only
) {
137 err
= strlist__add(slist
, s
);
143 static int strlist__parse_list(struct strlist
*slist
, const char *s
, const char *subst_dir
)
148 while ((sep
= strchr(s
, ',')) != NULL
) {
150 err
= strlist__parse_list_entry(slist
, s
, subst_dir
);
157 return *s
? strlist__parse_list_entry(slist
, s
, subst_dir
) : 0;
160 struct strlist
*strlist__new(const char *list
, const struct strlist_config
*config
)
162 struct strlist
*slist
= malloc(sizeof(*slist
));
166 bool file_only
= false;
167 const char *dirname
= NULL
;
170 dupstr
= !config
->dont_dupstr
;
171 dirname
= config
->dirname
;
172 file_only
= config
->file_only
;
175 rblist__init(&slist
->rblist
);
176 slist
->rblist
.node_cmp
= strlist__node_cmp
;
177 slist
->rblist
.node_new
= strlist__node_new
;
178 slist
->rblist
.node_delete
= strlist__node_delete
;
180 slist
->dupstr
= dupstr
;
181 slist
->file_only
= file_only
;
183 if (list
&& strlist__parse_list(slist
, list
, dirname
) != 0)
193 void strlist__delete(struct strlist
*slist
)
196 rblist__delete(&slist
->rblist
);
199 struct str_node
*strlist__entry(const struct strlist
*slist
, unsigned int idx
)
201 struct str_node
*snode
= NULL
;
202 struct rb_node
*rb_node
;
204 rb_node
= rblist__entry(&slist
->rblist
, idx
);
206 snode
= container_of(rb_node
, struct str_node
, rb_node
);