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