r9797: - let us parse replication packets with linked attributes fine,
[samba.git] / source / lib / util_strlist.c
1 /* 
2    Unix SMB/CIFS implementation.
3    
4    Copyright (C) Andrew Tridgell 2005
5    
6    This program is free software; you can redistribute it and/or modify
7    it under the terms of the GNU General Public License as published by
8    the Free Software Foundation; either version 2 of the License, or
9    (at your option) any later version.
10    
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15    
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21 #include "includes.h"
22
23 /*
24   build a null terminated list of strings from a input string and a
25   separator list. The sepatator list must contain characters less than
26   or equal to 0x2f for this to work correctly on multi-byte strings
27 */
28 const char **str_list_make(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
29 {
30         int num_elements = 0;
31         const char **ret = NULL;
32
33         if (sep == NULL) {
34                 sep = LIST_SEP;
35         }
36
37         ret = talloc_array(mem_ctx, const char *, 1);
38         if (ret == NULL) {
39                 return NULL;
40         }
41
42         while (string && *string) {
43                 size_t len = strcspn(string, sep);
44                 const char **ret2;
45                 
46                 if (len == 0) {
47                         string += strspn(string, sep);
48                         continue;
49                 }
50
51                 ret2 = talloc_realloc(mem_ctx, ret, const char *, num_elements+2);
52                 if (ret2 == NULL) {
53                         talloc_free(ret);
54                         return NULL;
55                 }
56                 ret = ret2;
57
58                 ret[num_elements] = talloc_strndup(ret, string, len);
59                 if (ret[num_elements] == NULL) {
60                         talloc_free(ret);
61                         return NULL;
62                 }
63
64                 num_elements++;
65                 string += len;
66         }
67
68         ret[num_elements] = NULL;
69
70         return ret;
71 }
72
73 /*
74   return the number of elements in a string list
75 */
76 size_t str_list_length(const char **list)
77 {
78         size_t ret;
79         for (ret=0;list && list[ret];ret++) /* noop */ ;
80         return ret;
81 }
82
83
84 /*
85   copy a string list
86 */
87 const char **str_list_copy(TALLOC_CTX *mem_ctx, const char **list)
88 {
89         int i;
90         const char **ret = talloc_array(mem_ctx, const char *, str_list_length(list)+1);
91         if (ret == NULL) return NULL;
92
93         for (i=0;list && list[i];i++) {
94                 ret[i] = talloc_strdup(ret, list[i]);
95                 if (ret[i] == NULL) {
96                         talloc_free(ret);
97                         return NULL;
98                 }
99         }
100         ret[i] = NULL;
101         return ret;
102 }
103
104 /*
105    Return true if all the elements of the list match exactly.
106  */
107 BOOL str_list_equal(const char **list1, const char **list2)
108 {
109         int i;
110         
111         if (list1 == NULL || list2 == NULL) {
112                 return (list1 == list2); 
113         }
114         
115         for (i=0;list1[i] && list2[i];i++) {
116                 if (strcmp(list1[i], list2[i]) != 0) {
117                         return False;
118                 }
119         }
120         if (list1[i] || list2[i]) {
121                 return False;
122         }
123         return True;
124 }
125
126
127 /*
128   add an entry to a string list
129 */
130 const char **str_list_add(const char **list, const char *s)
131 {
132         size_t len = str_list_length(list);
133         const char **ret;
134
135         ret = talloc_realloc(NULL, list, const char *, len+2);
136         if (ret == NULL) return NULL;
137
138         ret[len] = talloc_strdup(ret, s);
139         if (ret[len] == NULL) return NULL;
140
141         ret[len+1] = NULL;
142
143         return ret;
144 }
145
146 /*
147   remove an entry from a string list
148 */
149 void str_list_remove(const char **list, const char *s)
150 {
151         int i;
152
153         for (i=0;list[i];i++) {
154                 if (strcmp(list[i], s) == 0) break;
155         }
156         if (!list[i]) return;
157
158         for (;list[i];i++) {
159                 list[i] = list[i+1];
160         }
161 }
162
163
164 /*
165   return True if a string is in a list
166 */
167 BOOL str_list_check(const char **list, const char *s)
168 {
169         int i;
170
171         for (i=0;list[i];i++) {
172                 if (strcmp(list[i], s) == 0) return True;
173         }
174         return False;
175 }
176
177 /*
178   return True if a string is in a list, case insensitively
179 */
180 BOOL str_list_check_ci(const char **list, const char *s)
181 {
182         int i;
183
184         for (i=0;list[i];i++) {
185                 if (strcasecmp(list[i], s) == 0) return True;
186         }
187         return False;
188 }