chiark / gitweb /
architecture: Add cris
[elogind.git] / src / shared / strv.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2010 Lennart Poettering
7
8   systemd is free software; you can redistribute it and/or modify it
9   under the terms of the GNU Lesser General Public License as published by
10   the Free Software Foundation; either version 2.1 of the License, or
11   (at your option) any later version.
12
13   systemd is distributed in the hope that it will be useful, but
14   WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16   Lesser General Public License for more details.
17
18   You should have received a copy of the GNU Lesser General Public License
19   along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <assert.h>
23 #include <stdlib.h>
24 #include <stdarg.h>
25 #include <string.h>
26 #include <errno.h>
27
28 #include "util.h"
29 #include "strv.h"
30
31 char *strv_find(char **l, const char *name) {
32         char **i;
33
34         assert(name);
35
36         STRV_FOREACH(i, l)
37                 if (streq(*i, name))
38                         return *i;
39
40         return NULL;
41 }
42
43 char *strv_find_prefix(char **l, const char *name) {
44         char **i;
45
46         assert(name);
47
48         STRV_FOREACH(i, l)
49                 if (startswith(*i, name))
50                         return *i;
51
52         return NULL;
53 }
54
55 void strv_free(char **l) {
56         char **k;
57
58         if (!l)
59                 return;
60
61         for (k = l; *k; k++)
62                 free(*k);
63
64         free(l);
65 }
66
67 char **strv_copy(char * const *l) {
68         char **r, **k;
69
70         k = r = new(char*, strv_length(l) + 1);
71         if (!r)
72                 return NULL;
73
74         if (l)
75                 for (; *l; k++, l++) {
76                         *k = strdup(*l);
77                         if (!*k) {
78                                 strv_free(r);
79                                 return NULL;
80                         }
81                 }
82
83         *k = NULL;
84         return r;
85 }
86
87 unsigned strv_length(char * const *l) {
88         unsigned n = 0;
89
90         if (!l)
91                 return 0;
92
93         for (; *l; l++)
94                 n++;
95
96         return n;
97 }
98
99 char **strv_new_ap(const char *x, va_list ap) {
100         const char *s;
101         char **a;
102         unsigned n = 0, i = 0;
103         va_list aq;
104
105         /* As a special trick we ignore all listed strings that equal
106          * (const char*) -1. This is supposed to be used with the
107          * STRV_IFNOTNULL() macro to include possibly NULL strings in
108          * the string list. */
109
110         if (x) {
111                 n = x == (const char*) -1 ? 0 : 1;
112
113                 va_copy(aq, ap);
114                 while ((s = va_arg(aq, const char*))) {
115                         if (s == (const char*) -1)
116                                 continue;
117
118                         n++;
119                 }
120
121                 va_end(aq);
122         }
123
124         a = new(char*, n+1);
125         if (!a)
126                 return NULL;
127
128         if (x) {
129                 if (x != (const char*) -1) {
130                         a[i] = strdup(x);
131                         if (!a[i])
132                                 goto fail;
133                         i++;
134                 }
135
136                 while ((s = va_arg(ap, const char*))) {
137
138                         if (s == (const char*) -1)
139                                 continue;
140
141                         a[i] = strdup(s);
142                         if (!a[i])
143                                 goto fail;
144
145                         i++;
146                 }
147         }
148
149         a[i] = NULL;
150
151         return a;
152
153 fail:
154         strv_free(a);
155         return NULL;
156 }
157
158 char **strv_new(const char *x, ...) {
159         char **r;
160         va_list ap;
161
162         va_start(ap, x);
163         r = strv_new_ap(x, ap);
164         va_end(ap);
165
166         return r;
167 }
168
169 int strv_extend_strv(char ***a, char **b) {
170         int r;
171         char **s;
172
173         STRV_FOREACH(s, b) {
174                 r = strv_extend(a, *s);
175                 if (r < 0)
176                         return r;
177         }
178
179         return 0;
180 }
181
182 int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
183         int r;
184         char **s;
185
186         STRV_FOREACH(s, b) {
187                 char *v;
188
189                 v = strappend(*s, suffix);
190                 if (!v)
191                         return -ENOMEM;
192
193                 r = strv_push(a, v);
194                 if (r < 0) {
195                         free(v);
196                         return r;
197                 }
198         }
199
200         return 0;
201 }
202
203 char **strv_split(const char *s, const char *separator) {
204         char *state;
205         char *w;
206         size_t l;
207         unsigned n, i;
208         char **r;
209
210         assert(s);
211
212         n = 0;
213         FOREACH_WORD_SEPARATOR(w, l, s, separator, state)
214                 n++;
215
216         r = new(char*, n+1);
217         if (!r)
218                 return NULL;
219
220         i = 0;
221         FOREACH_WORD_SEPARATOR(w, l, s, separator, state) {
222                 r[i] = strndup(w, l);
223                 if (!r[i]) {
224                         strv_free(r);
225                         return NULL;
226                 }
227
228                 i++;
229         }
230
231         r[i] = NULL;
232         return r;
233 }
234
235 char **strv_split_quoted(const char *s) {
236         char *state;
237         char *w;
238         size_t l;
239         unsigned n, i;
240         char **r;
241
242         assert(s);
243
244         n = 0;
245         FOREACH_WORD_QUOTED(w, l, s, state)
246                 n++;
247
248         r = new(char*, n+1);
249         if (!r)
250                 return NULL;
251
252         i = 0;
253         FOREACH_WORD_QUOTED(w, l, s, state) {
254                 r[i] = cunescape_length(w, l);
255                 if (!r[i]) {
256                         strv_free(r);
257                         return NULL;
258                 }
259                 i++;
260         }
261
262         r[i] = NULL;
263         return r;
264 }
265
266 char **strv_split_newlines(const char *s) {
267         char **l;
268         unsigned n;
269
270         assert(s);
271
272         /* Special version of strv_split() that splits on newlines and
273          * suppresses an empty string at the end */
274
275         l = strv_split(s, NEWLINE);
276         if (!l)
277                 return NULL;
278
279         n = strv_length(l);
280         if (n <= 0)
281                 return l;
282
283         if (isempty(l[n-1])) {
284                 free(l[n-1]);
285                 l[n-1] = NULL;
286         }
287
288         return l;
289 }
290
291 char *strv_join(char **l, const char *separator) {
292         char *r, *e;
293         char **s;
294         size_t n, k;
295
296         if (!separator)
297                 separator = " ";
298
299         k = strlen(separator);
300
301         n = 0;
302         STRV_FOREACH(s, l) {
303                 if (n != 0)
304                         n += k;
305                 n += strlen(*s);
306         }
307
308         r = new(char, n+1);
309         if (!r)
310                 return NULL;
311
312         e = r;
313         STRV_FOREACH(s, l) {
314                 if (e != r)
315                         e = stpcpy(e, separator);
316
317                 e = stpcpy(e, *s);
318         }
319
320         *e = 0;
321
322         return r;
323 }
324
325 char *strv_join_quoted(char **l) {
326         char *buf = NULL;
327         char **s;
328         size_t allocated = 0, len = 0;
329
330         STRV_FOREACH(s, l) {
331                 /* assuming here that escaped string cannot be more
332                  * than twice as long, and reserving space for the
333                  * separator and quotes.
334                  */
335                 _cleanup_free_ char *esc = NULL;
336                 size_t needed;
337
338                 if (!GREEDY_REALLOC(buf, allocated,
339                                     len + strlen(*s) * 2 + 3))
340                         goto oom;
341
342                 esc = cescape(*s);
343                 if (!esc)
344                         goto oom;
345
346                 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
347                                   len > 0 ? " " : "", esc);
348                 assert(needed < allocated - len);
349                 len += needed;
350         }
351
352         if (!buf)
353                 buf = malloc0(1);
354
355         return buf;
356
357  oom:
358         free(buf);
359         return NULL;
360 }
361
362 int strv_push(char ***l, char *value) {
363         char **c;
364         unsigned n;
365
366         if (!value)
367                 return 0;
368
369         n = strv_length(*l);
370         c = realloc(*l, sizeof(char*) * (n + 2));
371         if (!c)
372                 return -ENOMEM;
373
374         c[n] = value;
375         c[n+1] = NULL;
376
377         *l = c;
378         return 0;
379 }
380
381 int strv_consume(char ***l, char *value) {
382         int r;
383
384         r = strv_push(l, value);
385         if (r < 0)
386                 free(value);
387
388         return r;
389 }
390
391 int strv_extend(char ***l, const char *value) {
392         char *v;
393
394         if (!value)
395                 return 0;
396
397         v = strdup(value);
398         if (!v)
399                 return -ENOMEM;
400
401         return strv_consume(l, v);
402 }
403
404 char **strv_uniq(char **l) {
405         char **i;
406
407         /* Drops duplicate entries. The first identical string will be
408          * kept, the others dropped */
409
410         STRV_FOREACH(i, l)
411                 strv_remove(i+1, *i);
412
413         return l;
414 }
415
416 char **strv_remove(char **l, const char *s) {
417         char **f, **t;
418
419         if (!l)
420                 return NULL;
421
422         assert(s);
423
424         /* Drops every occurrence of s in the string list, edits
425          * in-place. */
426
427         for (f = t = l; *f; f++)
428                 if (streq(*f, s))
429                         free(*f);
430                 else
431                         *(t++) = *f;
432
433         *t = NULL;
434         return l;
435 }
436
437 char **strv_parse_nulstr(const char *s, size_t l) {
438         const char *p;
439         unsigned c = 0, i = 0;
440         char **v;
441
442         assert(s || l <= 0);
443
444         if (l <= 0)
445                 return new0(char*, 1);
446
447         for (p = s; p < s + l; p++)
448                 if (*p == 0)
449                         c++;
450
451         if (s[l-1] != 0)
452                 c++;
453
454         v = new0(char*, c+1);
455         if (!v)
456                 return NULL;
457
458         p = s;
459         while (p < s + l) {
460                 const char *e;
461
462                 e = memchr(p, 0, s + l - p);
463
464                 v[i] = strndup(p, e ? e - p : s + l - p);
465                 if (!v[i]) {
466                         strv_free(v);
467                         return NULL;
468                 }
469
470                 i++;
471
472                 if (!e)
473                         break;
474
475                 p = e + 1;
476         }
477
478         assert(i == c);
479
480         return v;
481 }
482
483 char **strv_split_nulstr(const char *s) {
484         const char *i;
485         char **r = NULL;
486
487         NULSTR_FOREACH(i, s)
488                 if (strv_extend(&r, i) < 0) {
489                         strv_free(r);
490                         return NULL;
491                 }
492
493         if (!r)
494                 return strv_new(NULL, NULL);
495
496         return r;
497 }
498
499 bool strv_overlap(char **a, char **b) {
500         char **i;
501
502         STRV_FOREACH(i, a)
503                 if (strv_contains(b, *i))
504                         return true;
505
506         return false;
507 }
508
509 static int str_compare(const void *_a, const void *_b) {
510         const char **a = (const char**) _a, **b = (const char**) _b;
511
512         return strcmp(*a, *b);
513 }
514
515 char **strv_sort(char **l) {
516
517         if (strv_isempty(l))
518                 return l;
519
520         qsort(l, strv_length(l), sizeof(char*), str_compare);
521         return l;
522 }
523
524 void strv_print(char **l) {
525         char **s;
526
527         STRV_FOREACH(s, l)
528                 puts(*s);
529 }