chiark / gitweb /
core: use raw_clone instead of fork in signal handler
[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 char *strv_find_startswith(char **l, const char *name) {
56         char **i, *e;
57
58         assert(name);
59
60         /* Like strv_find_prefix, but actually returns only the
61          * suffix, not the whole item */
62
63         STRV_FOREACH(i, l) {
64                 e = startswith(*i, name);
65                 if (e)
66                         return e;
67         }
68
69         return NULL;
70 }
71
72 void strv_clear(char **l) {
73         char **k;
74
75         if (!l)
76                 return;
77
78         for (k = l; *k; k++)
79                 free(*k);
80
81         *l = NULL;
82 }
83
84 void strv_free(char **l) {
85         strv_clear(l);
86         free(l);
87 }
88
89 char **strv_copy(char * const *l) {
90         char **r, **k;
91
92         k = r = new(char*, strv_length(l) + 1);
93         if (!r)
94                 return NULL;
95
96         if (l)
97                 for (; *l; k++, l++) {
98                         *k = strdup(*l);
99                         if (!*k) {
100                                 strv_free(r);
101                                 return NULL;
102                         }
103                 }
104
105         *k = NULL;
106         return r;
107 }
108
109 unsigned strv_length(char * const *l) {
110         unsigned n = 0;
111
112         if (!l)
113                 return 0;
114
115         for (; *l; l++)
116                 n++;
117
118         return n;
119 }
120
121 char **strv_new_ap(const char *x, va_list ap) {
122         const char *s;
123         char **a;
124         unsigned n = 0, i = 0;
125         va_list aq;
126
127         /* As a special trick we ignore all listed strings that equal
128          * (const char*) -1. This is supposed to be used with the
129          * STRV_IFNOTNULL() macro to include possibly NULL strings in
130          * the string list. */
131
132         if (x) {
133                 n = x == (const char*) -1 ? 0 : 1;
134
135                 va_copy(aq, ap);
136                 while ((s = va_arg(aq, const char*))) {
137                         if (s == (const char*) -1)
138                                 continue;
139
140                         n++;
141                 }
142
143                 va_end(aq);
144         }
145
146         a = new(char*, n+1);
147         if (!a)
148                 return NULL;
149
150         if (x) {
151                 if (x != (const char*) -1) {
152                         a[i] = strdup(x);
153                         if (!a[i])
154                                 goto fail;
155                         i++;
156                 }
157
158                 while ((s = va_arg(ap, const char*))) {
159
160                         if (s == (const char*) -1)
161                                 continue;
162
163                         a[i] = strdup(s);
164                         if (!a[i])
165                                 goto fail;
166
167                         i++;
168                 }
169         }
170
171         a[i] = NULL;
172
173         return a;
174
175 fail:
176         strv_free(a);
177         return NULL;
178 }
179
180 char **strv_new(const char *x, ...) {
181         char **r;
182         va_list ap;
183
184         va_start(ap, x);
185         r = strv_new_ap(x, ap);
186         va_end(ap);
187
188         return r;
189 }
190
191 int strv_extend_strv(char ***a, char **b) {
192         int r;
193         char **s;
194
195         STRV_FOREACH(s, b) {
196                 r = strv_extend(a, *s);
197                 if (r < 0)
198                         return r;
199         }
200
201         return 0;
202 }
203
204 int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
205         int r;
206         char **s;
207
208         STRV_FOREACH(s, b) {
209                 char *v;
210
211                 v = strappend(*s, suffix);
212                 if (!v)
213                         return -ENOMEM;
214
215                 r = strv_push(a, v);
216                 if (r < 0) {
217                         free(v);
218                         return r;
219                 }
220         }
221
222         return 0;
223 }
224
225 char **strv_split(const char *s, const char *separator) {
226         const char *word, *state;
227         size_t l;
228         unsigned n, i;
229         char **r;
230
231         assert(s);
232
233         n = 0;
234         FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
235                 n++;
236
237         r = new(char*, n+1);
238         if (!r)
239                 return NULL;
240
241         i = 0;
242         FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
243                 r[i] = strndup(word, l);
244                 if (!r[i]) {
245                         strv_free(r);
246                         return NULL;
247                 }
248
249                 i++;
250         }
251
252         r[i] = NULL;
253         return r;
254 }
255
256 char **strv_split_newlines(const char *s) {
257         char **l;
258         unsigned n;
259
260         assert(s);
261
262         /* Special version of strv_split() that splits on newlines and
263          * suppresses an empty string at the end */
264
265         l = strv_split(s, NEWLINE);
266         if (!l)
267                 return NULL;
268
269         n = strv_length(l);
270         if (n <= 0)
271                 return l;
272
273         if (isempty(l[n-1])) {
274                 free(l[n-1]);
275                 l[n-1] = NULL;
276         }
277
278         return l;
279 }
280
281 int strv_split_quoted(char ***t, const char *s, bool relax) {
282         size_t n = 0, allocated = 0;
283         _cleanup_strv_free_ char **l = NULL;
284         int r;
285
286         assert(t);
287         assert(s);
288
289         for (;;) {
290                 _cleanup_free_ char *word = NULL;
291
292                 r = unquote_first_word(&s, &word, relax);
293                 if (r < 0)
294                         return r;
295                 if (r == 0)
296                         break;
297
298                 if (!GREEDY_REALLOC(l, allocated, n + 2))
299                         return -ENOMEM;
300
301                 l[n++] = word;
302                 word = NULL;
303
304                 l[n] = NULL;
305         }
306
307         if (!l)
308                 l = new0(char*, 1);
309
310         *t = l;
311         l = NULL;
312
313         return 0;
314 }
315
316 char *strv_join(char **l, const char *separator) {
317         char *r, *e;
318         char **s;
319         size_t n, k;
320
321         if (!separator)
322                 separator = " ";
323
324         k = strlen(separator);
325
326         n = 0;
327         STRV_FOREACH(s, l) {
328                 if (n != 0)
329                         n += k;
330                 n += strlen(*s);
331         }
332
333         r = new(char, n+1);
334         if (!r)
335                 return NULL;
336
337         e = r;
338         STRV_FOREACH(s, l) {
339                 if (e != r)
340                         e = stpcpy(e, separator);
341
342                 e = stpcpy(e, *s);
343         }
344
345         *e = 0;
346
347         return r;
348 }
349
350 char *strv_join_quoted(char **l) {
351         char *buf = NULL;
352         char **s;
353         size_t allocated = 0, len = 0;
354
355         STRV_FOREACH(s, l) {
356                 /* assuming here that escaped string cannot be more
357                  * than twice as long, and reserving space for the
358                  * separator and quotes.
359                  */
360                 _cleanup_free_ char *esc = NULL;
361                 size_t needed;
362
363                 if (!GREEDY_REALLOC(buf, allocated,
364                                     len + strlen(*s) * 2 + 3))
365                         goto oom;
366
367                 esc = cescape(*s);
368                 if (!esc)
369                         goto oom;
370
371                 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
372                                   len > 0 ? " " : "", esc);
373                 assert(needed < allocated - len);
374                 len += needed;
375         }
376
377         if (!buf)
378                 buf = malloc0(1);
379
380         return buf;
381
382  oom:
383         free(buf);
384         return NULL;
385 }
386
387 int strv_push(char ***l, char *value) {
388         char **c;
389         unsigned n, m;
390
391         if (!value)
392                 return 0;
393
394         n = strv_length(*l);
395
396         /* Increase and check for overflow */
397         m = n + 2;
398         if (m < n)
399                 return -ENOMEM;
400
401         c = realloc_multiply(*l, sizeof(char*), m);
402         if (!c)
403                 return -ENOMEM;
404
405         c[n] = value;
406         c[n+1] = NULL;
407
408         *l = c;
409         return 0;
410 }
411
412 int strv_push_pair(char ***l, char *a, char *b) {
413         char **c;
414         unsigned n, m;
415
416         if (!a && !b)
417                 return 0;
418
419         n = strv_length(*l);
420
421         /* increase and check for overflow */
422         m = n + !!a + !!b + 1;
423         if (m < n)
424                 return -ENOMEM;
425
426         c = realloc_multiply(*l, sizeof(char*), m);
427         if (!c)
428                 return -ENOMEM;
429
430         if (a)
431                 c[n++] = a;
432         if (b)
433                 c[n++] = b;
434         c[n] = NULL;
435
436         *l = c;
437         return 0;
438 }
439
440 int strv_push_prepend(char ***l, char *value) {
441         char **c;
442         unsigned n, m, i;
443
444         if (!value)
445                 return 0;
446
447         n = strv_length(*l);
448
449         /* increase and check for overflow */
450         m = n + 2;
451         if (m < n)
452                 return -ENOMEM;
453
454         c = new(char*, m);
455         if (!c)
456                 return -ENOMEM;
457
458         for (i = 0; i < n; i++)
459                 c[i+1] = (*l)[i];
460
461         c[0] = value;
462         c[n+1] = NULL;
463
464         free(*l);
465         *l = c;
466
467         return 0;
468 }
469
470 int strv_consume(char ***l, char *value) {
471         int r;
472
473         r = strv_push(l, value);
474         if (r < 0)
475                 free(value);
476
477         return r;
478 }
479
480 int strv_consume_pair(char ***l, char *a, char *b) {
481         int r;
482
483         r = strv_push_pair(l, a, b);
484         if (r < 0) {
485                 free(a);
486                 free(b);
487         }
488
489         return r;
490 }
491
492 int strv_consume_prepend(char ***l, char *value) {
493         int r;
494
495         r = strv_push_prepend(l, value);
496         if (r < 0)
497                 free(value);
498
499         return r;
500 }
501
502 int strv_extend(char ***l, const char *value) {
503         char *v;
504
505         if (!value)
506                 return 0;
507
508         v = strdup(value);
509         if (!v)
510                 return -ENOMEM;
511
512         return strv_consume(l, v);
513 }
514
515 char **strv_uniq(char **l) {
516         char **i;
517
518         /* Drops duplicate entries. The first identical string will be
519          * kept, the others dropped */
520
521         STRV_FOREACH(i, l)
522                 strv_remove(i+1, *i);
523
524         return l;
525 }
526
527 char **strv_remove(char **l, const char *s) {
528         char **f, **t;
529
530         if (!l)
531                 return NULL;
532
533         assert(s);
534
535         /* Drops every occurrence of s in the string list, edits
536          * in-place. */
537
538         for (f = t = l; *f; f++)
539                 if (streq(*f, s))
540                         free(*f);
541                 else
542                         *(t++) = *f;
543
544         *t = NULL;
545         return l;
546 }
547
548 char **strv_parse_nulstr(const char *s, size_t l) {
549         const char *p;
550         unsigned c = 0, i = 0;
551         char **v;
552
553         assert(s || l <= 0);
554
555         if (l <= 0)
556                 return new0(char*, 1);
557
558         for (p = s; p < s + l; p++)
559                 if (*p == 0)
560                         c++;
561
562         if (s[l-1] != 0)
563                 c++;
564
565         v = new0(char*, c+1);
566         if (!v)
567                 return NULL;
568
569         p = s;
570         while (p < s + l) {
571                 const char *e;
572
573                 e = memchr(p, 0, s + l - p);
574
575                 v[i] = strndup(p, e ? e - p : s + l - p);
576                 if (!v[i]) {
577                         strv_free(v);
578                         return NULL;
579                 }
580
581                 i++;
582
583                 if (!e)
584                         break;
585
586                 p = e + 1;
587         }
588
589         assert(i == c);
590
591         return v;
592 }
593
594 char **strv_split_nulstr(const char *s) {
595         const char *i;
596         char **r = NULL;
597
598         NULSTR_FOREACH(i, s)
599                 if (strv_extend(&r, i) < 0) {
600                         strv_free(r);
601                         return NULL;
602                 }
603
604         if (!r)
605                 return strv_new(NULL, NULL);
606
607         return r;
608 }
609
610 bool strv_overlap(char **a, char **b) {
611         char **i;
612
613         STRV_FOREACH(i, a)
614                 if (strv_contains(b, *i))
615                         return true;
616
617         return false;
618 }
619
620 static int str_compare(const void *_a, const void *_b) {
621         const char **a = (const char**) _a, **b = (const char**) _b;
622
623         return strcmp(*a, *b);
624 }
625
626 char **strv_sort(char **l) {
627
628         if (strv_isempty(l))
629                 return l;
630
631         qsort(l, strv_length(l), sizeof(char*), str_compare);
632         return l;
633 }
634
635 bool strv_equal(char **a, char **b) {
636         if (!a || !b)
637                 return a == b;
638
639         for ( ; *a || *b; ++a, ++b)
640                 if (!streq_ptr(*a, *b))
641                         return false;
642
643         return true;
644 }
645
646 void strv_print(char **l) {
647         char **s;
648
649         STRV_FOREACH(s, l)
650                 puts(*s);
651 }
652
653 int strv_extendf(char ***l, const char *format, ...) {
654         va_list ap;
655         char *x;
656         int r;
657
658         va_start(ap, format);
659         r = vasprintf(&x, format, ap);
660         va_end(ap);
661
662         if (r < 0)
663                 return -ENOMEM;
664
665         return strv_consume(l, x);
666 }