chiark / gitweb /
Prep v228: Add remaining updates from upstream (2/3)
[elogind.git] / src / basic / 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 <errno.h>
23 #include <stdarg.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "alloc-util.h"
28 #include "escape.h"
29 #include "string-util.h"
30 #include "strv.h"
31 #include "util.h"
32
33 char *strv_find(char **l, const char *name) {
34         char **i;
35
36         assert(name);
37
38         STRV_FOREACH(i, l)
39                 if (streq(*i, name))
40                         return *i;
41
42         return NULL;
43 }
44
45 char *strv_find_prefix(char **l, const char *name) {
46         char **i;
47
48         assert(name);
49
50         STRV_FOREACH(i, l)
51                 if (startswith(*i, name))
52                         return *i;
53
54         return NULL;
55 }
56
57 char *strv_find_startswith(char **l, const char *name) {
58         char **i, *e;
59
60         assert(name);
61
62         /* Like strv_find_prefix, but actually returns only the
63          * suffix, not the whole item */
64
65         STRV_FOREACH(i, l) {
66                 e = startswith(*i, name);
67                 if (e)
68                         return e;
69         }
70
71         return NULL;
72 }
73
74 void strv_clear(char **l) {
75         char **k;
76
77         if (!l)
78                 return;
79
80         for (k = l; *k; k++)
81                 free(*k);
82
83         *l = NULL;
84 }
85
86 char **strv_free(char **l) {
87         strv_clear(l);
88         free(l);
89         return NULL;
90 }
91
92 char **strv_free_erase(char **l) {
93         char **i;
94
95         STRV_FOREACH(i, l)
96                 string_erase(*i);
97
98         return strv_free(l);
99 }
100
101 char **strv_copy(char * const *l) {
102         char **r, **k;
103
104         k = r = new(char*, strv_length(l) + 1);
105         if (!r)
106                 return NULL;
107
108         if (l)
109                 for (; *l; k++, l++) {
110                         *k = strdup(*l);
111                         if (!*k) {
112                                 strv_free(r);
113                                 return NULL;
114                         }
115                 }
116
117         *k = NULL;
118         return r;
119 }
120
121 unsigned strv_length(char * const *l) {
122         unsigned n = 0;
123
124         if (!l)
125                 return 0;
126
127         for (; *l; l++)
128                 n++;
129
130         return n;
131 }
132
133 char **strv_new_ap(const char *x, va_list ap) {
134         const char *s;
135         char **a;
136         unsigned n = 0, i = 0;
137         va_list aq;
138
139         /* As a special trick we ignore all listed strings that equal
140          * (const char*) -1. This is supposed to be used with the
141          * STRV_IFNOTNULL() macro to include possibly NULL strings in
142          * the string list. */
143
144         if (x) {
145                 n = x == (const char*) -1 ? 0 : 1;
146
147                 va_copy(aq, ap);
148                 while ((s = va_arg(aq, const char*))) {
149                         if (s == (const char*) -1)
150                                 continue;
151
152                         n++;
153                 }
154
155                 va_end(aq);
156         }
157
158         a = new(char*, n+1);
159         if (!a)
160                 return NULL;
161
162         if (x) {
163                 if (x != (const char*) -1) {
164                         a[i] = strdup(x);
165                         if (!a[i])
166                                 goto fail;
167                         i++;
168                 }
169
170                 while ((s = va_arg(ap, const char*))) {
171
172                         if (s == (const char*) -1)
173                                 continue;
174
175                         a[i] = strdup(s);
176                         if (!a[i])
177                                 goto fail;
178
179                         i++;
180                 }
181         }
182
183         a[i] = NULL;
184
185         return a;
186
187 fail:
188         strv_free(a);
189         return NULL;
190 }
191
192 char **strv_new(const char *x, ...) {
193         char **r;
194         va_list ap;
195
196         va_start(ap, x);
197         r = strv_new_ap(x, ap);
198         va_end(ap);
199
200         return r;
201 }
202
203 int strv_extend_strv(char ***a, char **b, bool filter_duplicates) {
204         char **s, **t;
205         size_t p, q, i = 0, j;
206
207         assert(a);
208
209         if (strv_isempty(b))
210                 return 0;
211
212         p = strv_length(*a);
213         q = strv_length(b);
214
215         t = realloc(*a, sizeof(char*) * (p + q + 1));
216         if (!t)
217                 return -ENOMEM;
218
219         t[p] = NULL;
220         *a = t;
221
222         STRV_FOREACH(s, b) {
223
224                 if (filter_duplicates && strv_contains(t, *s))
225                         continue;
226
227                 t[p+i] = strdup(*s);
228                 if (!t[p+i])
229                         goto rollback;
230
231                 i++;
232                 t[p+i] = NULL;
233         }
234
235         assert(i <= q);
236
237         return (int) i;
238
239 rollback:
240         for (j = 0; j < i; j++)
241                 free(t[p + j]);
242
243         t[p] = NULL;
244         return -ENOMEM;
245 }
246
247 /// UNNEEDED by elogind
248 #if 0
249 int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
250         int r;
251         char **s;
252
253         STRV_FOREACH(s, b) {
254                 char *v;
255
256                 v = strappend(*s, suffix);
257                 if (!v)
258                         return -ENOMEM;
259
260                 r = strv_push(a, v);
261                 if (r < 0) {
262                         free(v);
263                         return r;
264                 }
265         }
266
267         return 0;
268 }
269 #endif // 0
270
271 char **strv_split(const char *s, const char *separator) {
272         const char *word, *state;
273         size_t l;
274         unsigned n, i;
275         char **r;
276
277         assert(s);
278
279         n = 0;
280         FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
281                 n++;
282
283         r = new(char*, n+1);
284         if (!r)
285                 return NULL;
286
287         i = 0;
288         FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
289                 r[i] = strndup(word, l);
290                 if (!r[i]) {
291                         strv_free(r);
292                         return NULL;
293                 }
294
295                 i++;
296         }
297
298         r[i] = NULL;
299         return r;
300 }
301
302 /// UNNEEDED by elogind
303 #if 0
304 char **strv_split_newlines(const char *s) {
305         char **l;
306         unsigned n;
307
308         assert(s);
309
310         /* Special version of strv_split() that splits on newlines and
311          * suppresses an empty string at the end */
312
313         l = strv_split(s, NEWLINE);
314         if (!l)
315                 return NULL;
316
317         n = strv_length(l);
318         if (n <= 0)
319                 return l;
320
321         if (isempty(l[n - 1]))
322                 l[n-1] = mfree(l[n-1]);
323
324         return l;
325 }
326
327 int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
328         _cleanup_strv_free_ char **l = NULL;
329         size_t n = 0, allocated = 0;
330         int r;
331
332         assert(t);
333         assert(s);
334
335         for (;;) {
336                 _cleanup_free_ char *word = NULL;
337
338                 r = extract_first_word(&s, &word, separators, flags);
339                 if (r < 0)
340                         return r;
341                 if (r == 0)
342                         break;
343
344                 if (!GREEDY_REALLOC(l, allocated, n + 2))
345                         return -ENOMEM;
346
347                 l[n++] = word;
348                 word = NULL;
349
350                 l[n] = NULL;
351         }
352
353         if (!l) {
354                 l = new0(char*, 1);
355                 if (!l)
356                         return -ENOMEM;
357         }
358
359         *t = l;
360         l = NULL;
361
362         return (int) n;
363 }
364 #endif // 0
365
366 char *strv_join(char **l, const char *separator) {
367         char *r, *e;
368         char **s;
369         size_t n, k;
370
371         if (!separator)
372                 separator = " ";
373
374         k = strlen(separator);
375
376         n = 0;
377         STRV_FOREACH(s, l) {
378                 if (n != 0)
379                         n += k;
380                 n += strlen(*s);
381         }
382
383         r = new(char, n+1);
384         if (!r)
385                 return NULL;
386
387         e = r;
388         STRV_FOREACH(s, l) {
389                 if (e != r)
390                         e = stpcpy(e, separator);
391
392                 e = stpcpy(e, *s);
393         }
394
395         *e = 0;
396
397         return r;
398 }
399
400 /// UNNEEDED by elogind
401 #if 0
402 char *strv_join_quoted(char **l) {
403         char *buf = NULL;
404         char **s;
405         size_t allocated = 0, len = 0;
406
407         STRV_FOREACH(s, l) {
408                 /* assuming here that escaped string cannot be more
409                  * than twice as long, and reserving space for the
410                  * separator and quotes.
411                  */
412                 _cleanup_free_ char *esc = NULL;
413                 size_t needed;
414
415                 if (!GREEDY_REALLOC(buf, allocated,
416                                     len + strlen(*s) * 2 + 3))
417                         goto oom;
418
419                 esc = cescape(*s);
420                 if (!esc)
421                         goto oom;
422
423                 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
424                                   len > 0 ? " " : "", esc);
425                 assert(needed < allocated - len);
426                 len += needed;
427         }
428
429         if (!buf)
430                 buf = malloc0(1);
431
432         return buf;
433
434  oom:
435         free(buf);
436         return NULL;
437 }
438 #endif // 0
439
440 int strv_push(char ***l, char *value) {
441         char **c;
442         unsigned n, m;
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 = realloc_multiply(*l, sizeof(char*), m);
455         if (!c)
456                 return -ENOMEM;
457
458         c[n] = value;
459         c[n+1] = NULL;
460
461         *l = c;
462         return 0;
463 }
464
465 int strv_push_pair(char ***l, char *a, char *b) {
466         char **c;
467         unsigned n, m;
468
469         if (!a && !b)
470                 return 0;
471
472         n = strv_length(*l);
473
474         /* increase and check for overflow */
475         m = n + !!a + !!b + 1;
476         if (m < n)
477                 return -ENOMEM;
478
479         c = realloc_multiply(*l, sizeof(char*), m);
480         if (!c)
481                 return -ENOMEM;
482
483         if (a)
484                 c[n++] = a;
485         if (b)
486                 c[n++] = b;
487         c[n] = NULL;
488
489         *l = c;
490         return 0;
491 }
492
493 int strv_push_prepend(char ***l, char *value) {
494         char **c;
495         unsigned n, m, i;
496
497         if (!value)
498                 return 0;
499
500         n = strv_length(*l);
501
502         /* increase and check for overflow */
503         m = n + 2;
504         if (m < n)
505                 return -ENOMEM;
506
507         c = new(char*, m);
508         if (!c)
509                 return -ENOMEM;
510
511         for (i = 0; i < n; i++)
512                 c[i+1] = (*l)[i];
513
514         c[0] = value;
515         c[n+1] = NULL;
516
517         free(*l);
518         *l = c;
519
520         return 0;
521 }
522
523 int strv_consume(char ***l, char *value) {
524         int r;
525
526         r = strv_push(l, value);
527         if (r < 0)
528                 free(value);
529
530         return r;
531 }
532
533 /// UNNEEDED by elogind
534 #if 0
535 int strv_consume_pair(char ***l, char *a, char *b) {
536         int r;
537
538         r = strv_push_pair(l, a, b);
539         if (r < 0) {
540                 free(a);
541                 free(b);
542         }
543
544         return r;
545 }
546 #endif // 0
547
548 int strv_consume_prepend(char ***l, char *value) {
549         int r;
550
551         r = strv_push_prepend(l, value);
552         if (r < 0)
553                 free(value);
554
555         return r;
556 }
557
558 int strv_extend(char ***l, const char *value) {
559         char *v;
560
561         if (!value)
562                 return 0;
563
564         v = strdup(value);
565         if (!v)
566                 return -ENOMEM;
567
568         return strv_consume(l, v);
569 }
570
571 char **strv_uniq(char **l) {
572         char **i;
573
574         /* Drops duplicate entries. The first identical string will be
575          * kept, the others dropped */
576
577         STRV_FOREACH(i, l)
578                 strv_remove(i+1, *i);
579
580         return l;
581 }
582
583 /// UNNEEDED by elogind
584 #if 0
585 bool strv_is_uniq(char **l) {
586         char **i;
587
588         STRV_FOREACH(i, l)
589                 if (strv_find(i+1, *i))
590                         return false;
591
592         return true;
593 }
594 #endif // 0
595
596 char **strv_remove(char **l, const char *s) {
597         char **f, **t;
598
599         if (!l)
600                 return NULL;
601
602         assert(s);
603
604         /* Drops every occurrence of s in the string list, edits
605          * in-place. */
606
607         for (f = t = l; *f; f++)
608                 if (streq(*f, s))
609                         free(*f);
610                 else
611                         *(t++) = *f;
612
613         *t = NULL;
614         return l;
615 }
616
617 char **strv_parse_nulstr(const char *s, size_t l) {
618         const char *p;
619         unsigned c = 0, i = 0;
620         char **v;
621
622         assert(s || l <= 0);
623
624         if (l <= 0)
625                 return new0(char*, 1);
626
627         for (p = s; p < s + l; p++)
628                 if (*p == 0)
629                         c++;
630
631         if (s[l-1] != 0)
632                 c++;
633
634         v = new0(char*, c+1);
635         if (!v)
636                 return NULL;
637
638         p = s;
639         while (p < s + l) {
640                 const char *e;
641
642                 e = memchr(p, 0, s + l - p);
643
644                 v[i] = strndup(p, e ? e - p : s + l - p);
645                 if (!v[i]) {
646                         strv_free(v);
647                         return NULL;
648                 }
649
650                 i++;
651
652                 if (!e)
653                         break;
654
655                 p = e + 1;
656         }
657
658         assert(i == c);
659
660         return v;
661 }
662
663 char **strv_split_nulstr(const char *s) {
664         const char *i;
665         char **r = NULL;
666
667         NULSTR_FOREACH(i, s)
668                 if (strv_extend(&r, i) < 0) {
669                         strv_free(r);
670                         return NULL;
671                 }
672
673         if (!r)
674                 return strv_new(NULL, NULL);
675
676         return r;
677 }
678
679 /// UNNEEDED by elogind
680 #if 0
681 int strv_make_nulstr(char **l, char **p, size_t *q) {
682         size_t n_allocated = 0, n = 0;
683         _cleanup_free_ char *m = NULL;
684         char **i;
685
686         assert(p);
687         assert(q);
688
689         STRV_FOREACH(i, l) {
690                 size_t z;
691
692                 z = strlen(*i);
693
694                 if (!GREEDY_REALLOC(m, n_allocated, n + z + 1))
695                         return -ENOMEM;
696
697                 memcpy(m + n, *i, z + 1);
698                 n += z + 1;
699         }
700
701         if (!m) {
702                 m = new0(char, 1);
703                 if (!m)
704                         return -ENOMEM;
705                 n = 0;
706         }
707
708         *p = m;
709         *q = n;
710
711         m = NULL;
712
713         return 0;
714 }
715
716 bool strv_overlap(char **a, char **b) {
717         char **i;
718
719         STRV_FOREACH(i, a)
720                 if (strv_contains(b, *i))
721                         return true;
722
723         return false;
724 }
725 #endif // 0
726
727 static int str_compare(const void *_a, const void *_b) {
728         const char **a = (const char**) _a, **b = (const char**) _b;
729
730         return strcmp(*a, *b);
731 }
732
733 char **strv_sort(char **l) {
734
735         if (strv_isempty(l))
736                 return l;
737
738         qsort(l, strv_length(l), sizeof(char*), str_compare);
739         return l;
740 }
741
742 /// UNNEEDED by elogind
743 #if 0
744 bool strv_equal(char **a, char **b) {
745
746         if (strv_isempty(a))
747                 return strv_isempty(b);
748
749         if (strv_isempty(b))
750                 return false;
751
752         for ( ; *a || *b; ++a, ++b)
753                 if (!streq_ptr(*a, *b))
754                         return false;
755
756         return true;
757 }
758
759 void strv_print(char **l) {
760         char **s;
761
762         STRV_FOREACH(s, l)
763                 puts(*s);
764 }
765
766 int strv_extendf(char ***l, const char *format, ...) {
767         va_list ap;
768         char *x;
769         int r;
770
771         va_start(ap, format);
772         r = vasprintf(&x, format, ap);
773         va_end(ap);
774
775         if (r < 0)
776                 return -ENOMEM;
777
778         return strv_consume(l, x);
779 }
780
781 char **strv_reverse(char **l) {
782         unsigned n, i;
783
784         n = strv_length(l);
785         if (n <= 1)
786                 return l;
787
788         for (i = 0; i < n / 2; i++) {
789                 char *t;
790
791                 t = l[i];
792                 l[i] = l[n-1-i];
793                 l[n-1-i] = t;
794         }
795
796         return l;
797 }
798
799 char **strv_shell_escape(char **l, const char *bad) {
800         char **s;
801
802         /* Escapes every character in every string in l that is in bad,
803          * edits in-place, does not roll-back on error. */
804
805         STRV_FOREACH(s, l) {
806                 char *v;
807
808                 v = shell_escape(*s, bad);
809                 if (!v)
810                         return NULL;
811
812                 free(*s);
813                 *s = v;
814         }
815
816         return l;
817 }
818
819 bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
820         char* const* p;
821
822         STRV_FOREACH(p, patterns)
823                 if (fnmatch(*p, s, 0) == 0)
824                         return true;
825
826         return false;
827 }
828
829 char ***strv_free_free(char ***l) {
830         char ***i;
831
832         if (!l)
833                 return NULL;
834
835         for (i = l; *i; i++)
836                 strv_free(*i);
837
838         free(l);
839         return NULL;
840 }
841
842 char **strv_skip(char **l, size_t n) {
843
844         while (n > 0) {
845                 if (strv_isempty(l))
846                         return l;
847
848                 l++, n--;
849         }
850
851         return l;
852 }
853
854 int strv_extend_n(char ***l, const char *value, size_t n) {
855         size_t i, j, k;
856         char **nl;
857
858         assert(l);
859
860         if (!value)
861                 return 0;
862         if (n == 0)
863                 return 0;
864
865         /* Adds the value value n times to l */
866
867         k = strv_length(*l);
868
869         nl = realloc(*l, sizeof(char*) * (k + n + 1));
870         if (!nl)
871                 return -ENOMEM;
872
873         *l = nl;
874
875         for (i = k; i < k + n; i++) {
876                 nl[i] = strdup(value);
877                 if (!nl[i])
878                         goto rollback;
879         }
880
881         nl[i] = NULL;
882         return 0;
883
884 rollback:
885         for (j = k; j < i; j++)
886                 free(nl[j]);
887
888         nl[k] = NULL;
889         return -ENOMEM;
890 }
891 #endif // 0