2 * Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
3 * Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
5 * This file is part of LVM2.
7 * This copyrighted material is made available to anyone wishing to use,
8 * modify, copy, or redistribute it subject to the terms and conditions
9 * of the GNU Lesser General Public License v.2.1.
11 * You should have received a copy of the GNU Lesser General Public License
12 * along with this program; if not, write to the Free Software Foundation,
13 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 #include "lib/misc/lib.h"
17 #include "lib/datastruct/str_list.h"
19 struct dm_list *str_list_create(struct dm_pool *mem)
23 if (!(sl = dm_pool_alloc(mem, sizeof(struct dm_list)))) {
24 log_errno(ENOMEM, "str_list allocation failed");
33 static int _str_list_add_no_dup_check(struct dm_pool *mem, struct dm_list *sll, const char *str, int as_first)
35 struct dm_str_list *sln;
40 if (!(sln = dm_pool_alloc(mem, sizeof(*sln))))
45 dm_list_add_h(sll, &sln->list);
47 dm_list_add(sll, &sln->list);
52 int str_list_add_no_dup_check(struct dm_pool *mem, struct dm_list *sll, const char *str)
54 return _str_list_add_no_dup_check(mem, sll, str, 0);
57 int str_list_add_h_no_dup_check(struct dm_pool *mem, struct dm_list *sll, const char *str)
59 return _str_list_add_no_dup_check(mem, sll, str, 1);
62 int str_list_add(struct dm_pool *mem, struct dm_list *sll, const char *str)
67 /* Already in list? */
68 if (str_list_match_item(sll, str))
71 return str_list_add_no_dup_check(mem, sll, str);
74 /* Add contents of sll2 to sll */
75 int str_list_add_list(struct dm_pool *mem, struct dm_list *sll, struct dm_list *sll2)
77 struct dm_str_list *sl;
82 dm_list_iterate_items(sl, sll2)
83 if (!str_list_add(mem, sll, sl->str))
89 void str_list_del(struct dm_list *sll, const char *str)
91 struct dm_list *slh, *slht;
93 dm_list_iterate_safe(slh, slht, sll)
94 if (!strcmp(str, dm_list_item(slh, struct dm_str_list)->str))
98 void str_list_wipe(struct dm_list *sll)
100 struct dm_list *slh, *slht;
102 dm_list_iterate_safe(slh, slht, sll)
106 int str_list_dup(struct dm_pool *mem, struct dm_list *sllnew,
107 const struct dm_list *sllold)
109 struct dm_str_list *sl;
111 dm_list_init(sllnew);
113 dm_list_iterate_items(sl, sllold) {
114 if (!str_list_add(mem, sllnew, dm_pool_strdup(mem, sl->str)))
124 int str_list_match_item(const struct dm_list *sll, const char *str)
126 struct dm_str_list *sl;
128 dm_list_iterate_items(sl, sll)
129 if (!strcmp(str, sl->str))
136 * Is at least one item on both lists?
137 * If tag_matched is non-NULL, it is set to the tag that matched.
139 int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2, const char **tag_matched)
141 struct dm_str_list *sl;
143 dm_list_iterate_items(sl, sll)
144 if (str_list_match_item(sll2, sl->str)) {
146 *tag_matched = sl->str;
154 * Do both lists contain the same set of items?
156 int str_list_lists_equal(const struct dm_list *sll, const struct dm_list *sll2)
158 struct dm_str_list *sl;
160 if (dm_list_size(sll) != dm_list_size(sll2))
163 dm_list_iterate_items(sl, sll)
164 if (!str_list_match_item(sll2, sl->str))
170 char *str_list_to_str(struct dm_pool *mem, const struct dm_list *list,
173 size_t delim_len = strlen(delim);
174 unsigned list_size = dm_list_size(list);
175 struct dm_str_list *sl;
180 dm_list_iterate_items(sl, list)
181 len += strlen(sl->str);
183 len += ((list_size - 1) * delim_len);
185 str = dm_pool_alloc(mem, len+1);
187 log_error("str_list_to_str: string allocation failed.");
193 dm_list_iterate_items(sl, list) {
194 len = strlen(sl->str);
195 memcpy(p, sl->str, len);
198 if (++i != list_size) {
199 memcpy(p, delim, delim_len);
207 struct dm_list *str_to_str_list(struct dm_pool *mem, const char *str,
208 const char *delim, int ignore_multiple_delim)
210 size_t delim_len = strlen(delim);
211 struct dm_list *list;
212 const char *p1, *p2, *next;
216 if (!(list = str_list_create(mem))) {
217 log_error("str_to_str_list: string list allocation failed.");
223 if (!(p2 = strstr(p1, delim)))
224 next = p2 = str + strlen(str);
226 next = p2 + delim_len;
229 str_item = dm_pool_alloc(mem, len+1);
231 log_error("str_to_str_list: string list item allocation failed.");
234 memcpy(str_item, p1, len);
235 str_item[len] = '\0';
237 if (!str_list_add_no_dup_check(mem, list, str_item))
240 if (ignore_multiple_delim) {
241 while (!strncmp(next, delim, delim_len))
250 dm_pool_free(mem, list);