~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to lib/util/util_strlist.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* 
 
2
   Unix SMB/CIFS implementation.
 
3
   
 
4
   Copyright (C) Andrew Tridgell 2005
 
5
   Copyright (C) Jelmer Vernooij 2005
 
6
   
 
7
   This program is free software; you can redistribute it and/or modify
 
8
   it under the terms of the GNU General Public License as published by
 
9
   the Free Software Foundation; either version 3 of the License, or
 
10
   (at your option) any later version.
 
11
   
 
12
   This program is distributed in the hope that it will be useful,
 
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
   GNU General Public License for more details.
 
16
   
 
17
   You should have received a copy of the GNU General Public License
 
18
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
19
*/
 
20
 
 
21
#include "includes.h"
 
22
#include "system/locale.h"
 
23
 
 
24
#undef strcasecmp
 
25
 
 
26
/**
 
27
 * @file
 
28
 * @brief String list manipulation
 
29
 */
 
30
 
 
31
/**
 
32
  build a null terminated list of strings from a input string and a
 
33
  separator list. The separator list must contain characters less than
 
34
  or equal to 0x2f for this to work correctly on multi-byte strings
 
35
*/
 
36
_PUBLIC_ char **str_list_make(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
 
37
{
 
38
        int num_elements = 0;
 
39
        char **ret = NULL;
 
40
 
 
41
        if (sep == NULL) {
 
42
                sep = LIST_SEP;
 
43
        }
 
44
 
 
45
        ret = talloc_array(mem_ctx, char *, 1);
 
46
        if (ret == NULL) {
 
47
                return NULL;
 
48
        }
 
49
 
 
50
        while (string && *string) {
 
51
                size_t len = strcspn(string, sep);
 
52
                char **ret2;
 
53
                
 
54
                if (len == 0) {
 
55
                        string += strspn(string, sep);
 
56
                        continue;
 
57
                }
 
58
 
 
59
                ret2 = talloc_realloc(mem_ctx, ret, char *, num_elements+2);
 
60
                if (ret2 == NULL) {
 
61
                        talloc_free(ret);
 
62
                        return NULL;
 
63
                }
 
64
                ret = ret2;
 
65
 
 
66
                ret[num_elements] = talloc_strndup(ret, string, len);
 
67
                if (ret[num_elements] == NULL) {
 
68
                        talloc_free(ret);
 
69
                        return NULL;
 
70
                }
 
71
 
 
72
                num_elements++;
 
73
                string += len;
 
74
        }
 
75
 
 
76
        ret[num_elements] = NULL;
 
77
 
 
78
        return ret;
 
79
}
 
80
 
 
81
/**
 
82
 * build a null terminated list of strings from an argv-like input string 
 
83
 * Entries are seperated by spaces and can be enclosed by quotes. 
 
84
 * Does NOT support escaping
 
85
 */
 
86
_PUBLIC_ const char **str_list_make_shell(TALLOC_CTX *mem_ctx, const char *string, const char *sep)
 
87
{
 
88
        int num_elements = 0;
 
89
        const char **ret = NULL;
 
90
 
 
91
        ret = talloc_array(mem_ctx, const char *, 1);
 
92
        if (ret == NULL) {
 
93
                return NULL;
 
94
        }
 
95
 
 
96
        if (sep == NULL)
 
97
                sep = " \t\n\r";
 
98
 
 
99
        while (string && *string) {
 
100
                size_t len = strcspn(string, sep);
 
101
                char *element;
 
102
                const char **ret2;
 
103
                
 
104
                if (len == 0) {
 
105
                        string += strspn(string, sep);
 
106
                        continue;
 
107
                }
 
108
 
 
109
                if (*string == '\"') {
 
110
                        string++;
 
111
                        len = strcspn(string, "\"");
 
112
                        element = talloc_strndup(ret, string, len);
 
113
                        string += len + 1;
 
114
                } else {
 
115
                        element = talloc_strndup(ret, string, len);
 
116
                        string += len;
 
117
                }
 
118
 
 
119
                if (element == NULL) {
 
120
                        talloc_free(ret);
 
121
                        return NULL;
 
122
                }
 
123
 
 
124
                ret2 = talloc_realloc(mem_ctx, ret, const char *, num_elements+2);
 
125
                if (ret2 == NULL) {
 
126
                        talloc_free(ret);
 
127
                        return NULL;
 
128
                }
 
129
                ret = ret2;
 
130
 
 
131
                ret[num_elements] = element;    
 
132
 
 
133
                num_elements++;
 
134
        }
 
135
 
 
136
        ret[num_elements] = NULL;
 
137
 
 
138
        return ret;
 
139
 
 
140
}
 
141
 
 
142
/**
 
143
 * join a list back to one string 
 
144
 */
 
145
_PUBLIC_ char *str_list_join(TALLOC_CTX *mem_ctx, const char **list, char seperator)
 
146
{
 
147
        char *ret = NULL;
 
148
        int i;
 
149
        
 
150
        if (list[0] == NULL)
 
151
                return talloc_strdup(mem_ctx, "");
 
152
 
 
153
        ret = talloc_strdup(mem_ctx, list[0]);
 
154
 
 
155
        for (i = 1; list[i]; i++) {
 
156
                ret = talloc_asprintf_append_buffer(ret, "%c%s", seperator, list[i]);
 
157
        }
 
158
 
 
159
        return ret;
 
160
}
 
161
 
 
162
/** join a list back to one (shell-like) string; entries 
 
163
 * seperated by spaces, using quotes where necessary */
 
164
_PUBLIC_ char *str_list_join_shell(TALLOC_CTX *mem_ctx, const char **list, char sep)
 
165
{
 
166
        char *ret = NULL;
 
167
        int i;
 
168
        
 
169
        if (list[0] == NULL)
 
170
                return talloc_strdup(mem_ctx, "");
 
171
 
 
172
        if (strchr(list[0], ' ') || strlen(list[0]) == 0) 
 
173
                ret = talloc_asprintf(mem_ctx, "\"%s\"", list[0]);
 
174
        else 
 
175
                ret = talloc_strdup(mem_ctx, list[0]);
 
176
 
 
177
        for (i = 1; list[i]; i++) {
 
178
                if (strchr(list[i], ' ') || strlen(list[i]) == 0) 
 
179
                        ret = talloc_asprintf_append_buffer(ret, "%c\"%s\"", sep, list[i]);
 
180
                else 
 
181
                        ret = talloc_asprintf_append_buffer(ret, "%c%s", sep, list[i]);
 
182
        }
 
183
 
 
184
        return ret;
 
185
}
 
186
 
 
187
/**
 
188
  return the number of elements in a string list
 
189
*/
 
190
_PUBLIC_ size_t str_list_length(const char * const*list)
 
191
{
 
192
        size_t ret;
 
193
        for (ret=0;list && list[ret];ret++) /* noop */ ;
 
194
        return ret;
 
195
}
 
196
 
 
197
 
 
198
/**
 
199
  copy a string list
 
200
*/
 
201
_PUBLIC_ char **str_list_copy(TALLOC_CTX *mem_ctx, const char **list)
 
202
{
 
203
        int i;
 
204
        char **ret;
 
205
 
 
206
        if (list == NULL)
 
207
                return NULL;
 
208
        
 
209
        ret = talloc_array(mem_ctx, char *, str_list_length(list)+1);
 
210
        if (ret == NULL) 
 
211
                return NULL;
 
212
 
 
213
        for (i=0;list && list[i];i++) {
 
214
                ret[i] = talloc_strdup(ret, list[i]);
 
215
                if (ret[i] == NULL) {
 
216
                        talloc_free(ret);
 
217
                        return NULL;
 
218
                }
 
219
        }
 
220
        ret[i] = NULL;
 
221
        return ret;
 
222
}
 
223
 
 
224
/**
 
225
   Return true if all the elements of the list match exactly.
 
226
 */
 
227
_PUBLIC_ bool str_list_equal(const char **list1, const char **list2)
 
228
{
 
229
        int i;
 
230
        
 
231
        if (list1 == NULL || list2 == NULL) {
 
232
                return (list1 == list2); 
 
233
        }
 
234
        
 
235
        for (i=0;list1[i] && list2[i];i++) {
 
236
                if (strcmp(list1[i], list2[i]) != 0) {
 
237
                        return false;
 
238
                }
 
239
        }
 
240
        if (list1[i] || list2[i]) {
 
241
                return false;
 
242
        }
 
243
        return true;
 
244
}
 
245
 
 
246
 
 
247
/**
 
248
  add an entry to a string list
 
249
*/
 
250
_PUBLIC_ const char **str_list_add(const char **list, const char *s)
 
251
{
 
252
        size_t len = str_list_length(list);
 
253
        const char **ret;
 
254
 
 
255
        ret = talloc_realloc(NULL, list, const char *, len+2);
 
256
        if (ret == NULL) return NULL;
 
257
 
 
258
        ret[len] = talloc_strdup(ret, s);
 
259
        if (ret[len] == NULL) return NULL;
 
260
 
 
261
        ret[len+1] = NULL;
 
262
 
 
263
        return ret;
 
264
}
 
265
 
 
266
/**
 
267
  remove an entry from a string list
 
268
*/
 
269
_PUBLIC_ void str_list_remove(const char **list, const char *s)
 
270
{
 
271
        int i;
 
272
 
 
273
        for (i=0;list[i];i++) {
 
274
                if (strcmp(list[i], s) == 0) break;
 
275
        }
 
276
        if (!list[i]) return;
 
277
 
 
278
        for (;list[i];i++) {
 
279
                list[i] = list[i+1];
 
280
        }
 
281
}
 
282
 
 
283
 
 
284
/**
 
285
  return true if a string is in a list
 
286
*/
 
287
_PUBLIC_ bool str_list_check(const char **list, const char *s)
 
288
{
 
289
        int i;
 
290
 
 
291
        for (i=0;list[i];i++) {
 
292
                if (strcmp(list[i], s) == 0) return true;
 
293
        }
 
294
        return false;
 
295
}
 
296
 
 
297
/**
 
298
  return true if a string is in a list, case insensitively
 
299
*/
 
300
_PUBLIC_ bool str_list_check_ci(const char **list, const char *s)
 
301
{
 
302
        int i;
 
303
 
 
304
        for (i=0;list[i];i++) {
 
305
                if (strcasecmp(list[i], s) == 0) return true;
 
306
        }
 
307
        return false;
 
308
}
 
309
 
 
310