2 * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com>
4 * Licensed under the GPLv2.
13 static struct str_node
*str_node__new(const char *s
, bool dupstr
)
15 struct str_node
*self
= malloc(sizeof(*self
));
33 static void str_node__delete(struct str_node
*self
, bool dupstr
)
36 free((void *)self
->s
);
40 int strlist__add(struct strlist
*self
, const char *new_entry
)
42 struct rb_node
**p
= &self
->entries
.rb_node
;
43 struct rb_node
*parent
= NULL
;
50 sn
= rb_entry(parent
, struct str_node
, rb_node
);
51 rc
= strcmp(sn
->s
, new_entry
);
61 sn
= str_node__new(new_entry
, self
->dupstr
);
65 rb_link_node(&sn
->rb_node
, parent
, p
);
66 rb_insert_color(&sn
->rb_node
, &self
->entries
);
72 int strlist__load(struct strlist
*self
, const char *filename
)
76 FILE *fp
= fopen(filename
, "r");
81 while (fgets(entry
, sizeof(entry
), fp
) != NULL
) {
82 const size_t len
= strlen(entry
);
86 entry
[len
- 1] = '\0';
88 err
= strlist__add(self
, entry
);
99 void strlist__remove(struct strlist
*self
, struct str_node
*sn
)
101 rb_erase(&sn
->rb_node
, &self
->entries
);
102 str_node__delete(sn
, self
->dupstr
);
105 bool strlist__has_entry(struct strlist
*self
, const char *entry
)
107 struct rb_node
**p
= &self
->entries
.rb_node
;
108 struct rb_node
*parent
= NULL
;
115 sn
= rb_entry(parent
, struct str_node
, rb_node
);
116 rc
= strcmp(sn
->s
, entry
);
129 static int strlist__parse_list_entry(struct strlist
*self
, const char *s
)
131 if (strncmp(s
, "file://", 7) == 0)
132 return strlist__load(self
, s
+ 7);
134 return strlist__add(self
, s
);
137 int strlist__parse_list(struct strlist
*self
, const char *s
)
142 while ((sep
= strchr(s
, ',')) != NULL
) {
144 err
= strlist__parse_list_entry(self
, s
);
151 return *s
? strlist__parse_list_entry(self
, s
) : 0;
154 struct strlist
*strlist__new(bool dupstr
, const char *slist
)
156 struct strlist
*self
= malloc(sizeof(*self
));
159 self
->entries
= RB_ROOT
;
160 self
->dupstr
= dupstr
;
161 self
->nr_entries
= 0;
162 if (slist
&& strlist__parse_list(self
, slist
) != 0)
172 void strlist__delete(struct strlist
*self
)
175 struct str_node
*pos
;
176 struct rb_node
*next
= rb_first(&self
->entries
);
179 pos
= rb_entry(next
, struct str_node
, rb_node
);
180 next
= rb_next(&pos
->rb_node
);
181 strlist__remove(self
, pos
);
183 self
->entries
= RB_ROOT
;
188 struct str_node
*strlist__entry(const struct strlist
*self
, unsigned int idx
)
192 for (nd
= rb_first(&self
->entries
); nd
; nd
= rb_next(nd
)) {
193 struct str_node
*pos
= rb_entry(nd
, struct str_node
, rb_node
);