2 * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com>
4 * Licensed under the GPLv2.
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
);
131 err
= strlist__add(slist
, s
);
137 static int strlist__parse_list(struct strlist
*slist
, const char *s
, const char *subst_dir
)
142 while ((sep
= strchr(s
, ',')) != NULL
) {
144 err
= strlist__parse_list_entry(slist
, s
, subst_dir
);
151 return *s
? strlist__parse_list_entry(slist
, s
, subst_dir
) : 0;
154 struct strlist
*strlist__new(const char *list
, const struct strlist_config
*config
)
156 struct strlist
*slist
= malloc(sizeof(*slist
));
160 const char *dirname
= NULL
;
163 dupstr
= !config
->dont_dupstr
;
164 dirname
= config
->dirname
;
167 rblist__init(&slist
->rblist
);
168 slist
->rblist
.node_cmp
= strlist__node_cmp
;
169 slist
->rblist
.node_new
= strlist__node_new
;
170 slist
->rblist
.node_delete
= strlist__node_delete
;
172 slist
->dupstr
= dupstr
;
174 if (list
&& strlist__parse_list(slist
, list
, dirname
) != 0)
184 void strlist__delete(struct strlist
*slist
)
187 rblist__delete(&slist
->rblist
);
190 struct str_node
*strlist__entry(const struct strlist
*slist
, unsigned int idx
)
192 struct str_node
*snode
= NULL
;
193 struct rb_node
*rb_node
;
195 rb_node
= rblist__entry(&slist
->rblist
, idx
);
197 snode
= container_of(rb_node
, struct str_node
, rb_node
);