chiark / gitweb /
0ac66b927c167d166a4918c7c85fbca5f2cc7780
[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         const char *word, *state;
205         size_t l;
206         unsigned n, i;
207         char **r;
208
209         assert(s);
210
211         n = 0;
212         FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
213                 n++;
214
215         r = new(char*, n+1);
216         if (!r)
217                 return NULL;
218
219         i = 0;
220         FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
221                 r[i] = strndup(word, l);
222                 if (!r[i]) {
223                         strv_free(r);
224                         return NULL;
225                 }
226
227                 i++;
228         }
229
230         r[i] = NULL;
231         return r;
232 }
233
234 char **strv_split_quoted(const char *s) {
235         const char *word, *state;
236         size_t l;
237         unsigned n, i;
238         char **r;
239
240         assert(s);
241
242         n = 0;
243         FOREACH_WORD_QUOTED(word, l, s, state)
244                 n++;
245         if (*state)
246                 /* bad syntax */
247                 return NULL;
248
249         r = new(char*, n+1);
250         if (!r)
251                 return NULL;
252
253         i = 0;
254         FOREACH_WORD_QUOTED(word, l, s, state) {
255                 r[i] = cunescape_length(word, l);
256                 if (!r[i]) {
257                         strv_free(r);
258                         return NULL;
259                 }
260                 i++;
261         }
262
263         r[i] = NULL;
264         return r;
265 }
266
267 char **strv_split_newlines(const char *s) {
268         char **l;
269         unsigned n;
270
271         assert(s);
272
273         /* Special version of strv_split() that splits on newlines and
274          * suppresses an empty string at the end */
275
276         l = strv_split(s, NEWLINE);
277         if (!l)
278                 return NULL;
279
280         n = strv_length(l);
281         if (n <= 0)
282                 return l;
283
284         if (isempty(l[n-1])) {
285                 free(l[n-1]);
286                 l[n-1] = NULL;
287         }
288
289         return l;
290 }
291
292 char *strv_join(char **l, const char *separator) {
293         char *r, *e;
294         char **s;
295         size_t n, k;
296
297         if (!separator)
298                 separator = " ";
299
300         k = strlen(separator);
301
302         n = 0;
303         STRV_FOREACH(s, l) {
304                 if (n != 0)
305                         n += k;
306                 n += strlen(*s);
307         }
308
309         r = new(char, n+1);
310         if (!r)
311                 return NULL;
312
313         e = r;
314         STRV_FOREACH(s, l) {
315                 if (e != r)
316                         e = stpcpy(e, separator);
317
318                 e = stpcpy(e, *s);
319         }
320
321         *e = 0;
322
323         return r;
324 }
325
326 char *strv_join_quoted(char **l) {
327         char *buf = NULL;
328         char **s;
329         size_t allocated = 0, len = 0;
330
331         STRV_FOREACH(s, l) {
332                 /* assuming here that escaped string cannot be more
333                  * than twice as long, and reserving space for the
334                  * separator and quotes.
335                  */
336                 _cleanup_free_ char *esc = NULL;
337                 size_t needed;
338
339                 if (!GREEDY_REALLOC(buf, allocated,
340                                     len + strlen(*s) * 2 + 3))
341                         goto oom;
342
343                 esc = cescape(*s);
344                 if (!esc)
345                         goto oom;
346
347                 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
348                                   len > 0 ? " " : "", esc);
349                 assert(needed < allocated - len);
350                 len += needed;
351         }
352
353         if (!buf)
354                 buf = malloc0(1);
355
356         return buf;
357
358  oom:
359         free(buf);
360         return NULL;
361 }
362
363 int strv_push(char ***l, char *value) {
364         char **c;
365         unsigned n;
366
367         if (!value)
368                 return 0;
369
370         n = strv_length(*l);
371         c = realloc(*l, sizeof(char*) * (n + 2));
372         if (!c)
373                 return -ENOMEM;
374
375         c[n] = value;
376         c[n+1] = NULL;
377
378         *l = c;
379         return 0;
380 }
381
382 int strv_push_prepend(char ***l, char *value) {
383         char **c;
384         unsigned n, i;
385
386         if (!value)
387                 return 0;
388
389         n = strv_length(*l);
390         c = new(char*, n + 2);
391         if (!c)
392                 return -ENOMEM;
393
394         for (i = 0; i < n; i++)
395                 c[i+1] = (*l)[i];
396
397         c[0] = value;
398         c[n+1] = NULL;
399
400         free(*l);
401         *l = c;
402
403         return 0;
404 }
405
406 int strv_consume(char ***l, char *value) {
407         int r;
408
409         r = strv_push(l, value);
410         if (r < 0)
411                 free(value);
412
413         return r;
414 }
415
416 int strv_consume_prepend(char ***l, char *value) {
417         int r;
418
419         r = strv_push_prepend(l, value);
420         if (r < 0)
421                 free(value);
422
423         return r;
424 }
425
426 int strv_extend(char ***l, const char *value) {
427         char *v;
428
429         if (!value)
430                 return 0;
431
432         v = strdup(value);
433         if (!v)
434                 return -ENOMEM;
435
436         return strv_consume(l, v);
437 }
438
439 char **strv_uniq(char **l) {
440         char **i;
441
442         /* Drops duplicate entries. The first identical string will be
443          * kept, the others dropped */
444
445         STRV_FOREACH(i, l)
446                 strv_remove(i+1, *i);
447
448         return l;
449 }
450
451 char **strv_remove(char **l, const char *s) {
452         char **f, **t;
453
454         if (!l)
455                 return NULL;
456
457         assert(s);
458
459         /* Drops every occurrence of s in the string list, edits
460          * in-place. */
461
462         for (f = t = l; *f; f++)
463                 if (streq(*f, s))
464                         free(*f);
465                 else
466                         *(t++) = *f;
467
468         *t = NULL;
469         return l;
470 }
471
472 char **strv_parse_nulstr(const char *s, size_t l) {
473         const char *p;
474         unsigned c = 0, i = 0;
475         char **v;
476
477         assert(s || l <= 0);
478
479         if (l <= 0)
480                 return new0(char*, 1);
481
482         for (p = s; p < s + l; p++)
483                 if (*p == 0)
484                         c++;
485
486         if (s[l-1] != 0)
487                 c++;
488
489         v = new0(char*, c+1);
490         if (!v)
491                 return NULL;
492
493         p = s;
494         while (p < s + l) {
495                 const char *e;
496
497                 e = memchr(p, 0, s + l - p);
498
499                 v[i] = strndup(p, e ? e - p : s + l - p);
500                 if (!v[i]) {
501                         strv_free(v);
502                         return NULL;
503                 }
504
505                 i++;
506
507                 if (!e)
508                         break;
509
510                 p = e + 1;
511         }
512
513         assert(i == c);
514
515         return v;
516 }
517
518 char **strv_split_nulstr(const char *s) {
519         const char *i;
520         char **r = NULL;
521
522         NULSTR_FOREACH(i, s)
523                 if (strv_extend(&r, i) < 0) {
524                         strv_free(r);
525                         return NULL;
526                 }
527
528         if (!r)
529                 return strv_new(NULL, NULL);
530
531         return r;
532 }
533
534 bool strv_overlap(char **a, char **b) {
535         char **i;
536
537         STRV_FOREACH(i, a)
538                 if (strv_contains(b, *i))
539                         return true;
540
541         return false;
542 }
543
544 static int str_compare(const void *_a, const void *_b) {
545         const char **a = (const char**) _a, **b = (const char**) _b;
546
547         return strcmp(*a, *b);
548 }
549
550 char **strv_sort(char **l) {
551
552         if (strv_isempty(l))
553                 return l;
554
555         qsort(l, strv_length(l), sizeof(char*), str_compare);
556         return l;
557 }
558
559 void strv_print(char **l) {
560         char **s;
561
562         STRV_FOREACH(s, l)
563                 puts(*s);
564 }
565
566 int strv_extendf(char ***l, const char *format, ...) {
567         va_list ap;
568         char *x;
569         int r;
570
571         va_start(ap, format);
572         r = vasprintf(&x, format, ap);
573         va_end(ap);
574
575         if (r < 0)
576                 return -ENOMEM;
577
578         return strv_consume(l, x);
579 }