chiark / gitweb /
8e509988963d2bfae0555a4f0f46623a99d9b7f8
[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 #if 0 /// UNNEEDED by elogind
204 int strv_extend_strv(char ***a, char **b, bool filter_duplicates) {
205         char **s, **t;
206         size_t p, q, i = 0, j;
207
208         assert(a);
209
210         if (strv_isempty(b))
211                 return 0;
212
213         p = strv_length(*a);
214         q = strv_length(b);
215
216         t = realloc(*a, sizeof(char*) * (p + q + 1));
217         if (!t)
218                 return -ENOMEM;
219
220         t[p] = NULL;
221         *a = t;
222
223         STRV_FOREACH(s, b) {
224
225                 if (filter_duplicates && strv_contains(t, *s))
226                         continue;
227
228                 t[p+i] = strdup(*s);
229                 if (!t[p+i])
230                         goto rollback;
231
232                 i++;
233                 t[p+i] = NULL;
234         }
235
236         assert(i <= q);
237
238         return (int) i;
239
240 rollback:
241         for (j = 0; j < i; j++)
242                 free(t[p + j]);
243
244         t[p] = NULL;
245         return -ENOMEM;
246 }
247
248 int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
249         int r;
250         char **s;
251
252         STRV_FOREACH(s, b) {
253                 char *v;
254
255                 v = strappend(*s, suffix);
256                 if (!v)
257                         return -ENOMEM;
258
259                 r = strv_push(a, v);
260                 if (r < 0) {
261                         free(v);
262                         return r;
263                 }
264         }
265
266         return 0;
267 }
268 #endif // 0
269
270 char **strv_split(const char *s, const char *separator) {
271         const char *word, *state;
272         size_t l;
273         unsigned n, i;
274         char **r;
275
276         assert(s);
277
278         n = 0;
279         FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
280                 n++;
281
282         r = new(char*, n+1);
283         if (!r)
284                 return NULL;
285
286         i = 0;
287         FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
288                 r[i] = strndup(word, l);
289                 if (!r[i]) {
290                         strv_free(r);
291                         return NULL;
292                 }
293
294                 i++;
295         }
296
297         r[i] = NULL;
298         return r;
299 }
300
301 #if 0 /// UNNEEDED by elogind
302 char **strv_split_newlines(const char *s) {
303         char **l;
304         unsigned n;
305
306         assert(s);
307
308         /* Special version of strv_split() that splits on newlines and
309          * suppresses an empty string at the end */
310
311         l = strv_split(s, NEWLINE);
312         if (!l)
313                 return NULL;
314
315         n = strv_length(l);
316         if (n <= 0)
317                 return l;
318
319         if (isempty(l[n - 1]))
320                 l[n-1] = mfree(l[n-1]);
321
322         return l;
323 }
324
325 int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
326         _cleanup_strv_free_ char **l = NULL;
327         size_t n = 0, allocated = 0;
328         int r;
329
330         assert(t);
331         assert(s);
332
333         for (;;) {
334                 _cleanup_free_ char *word = NULL;
335
336                 r = extract_first_word(&s, &word, separators, flags);
337                 if (r < 0)
338                         return r;
339                 if (r == 0)
340                         break;
341
342                 if (!GREEDY_REALLOC(l, allocated, n + 2))
343                         return -ENOMEM;
344
345                 l[n++] = word;
346                 word = NULL;
347
348                 l[n] = NULL;
349         }
350
351         if (!l) {
352                 l = new0(char*, 1);
353                 if (!l)
354                         return -ENOMEM;
355         }
356
357         *t = l;
358         l = NULL;
359
360         return (int) n;
361 }
362 #endif // 0
363
364 char *strv_join(char **l, const char *separator) {
365         char *r, *e;
366         char **s;
367         size_t n, k;
368
369         if (!separator)
370                 separator = " ";
371
372         k = strlen(separator);
373
374         n = 0;
375         STRV_FOREACH(s, l) {
376                 if (n != 0)
377                         n += k;
378                 n += strlen(*s);
379         }
380
381         r = new(char, n+1);
382         if (!r)
383                 return NULL;
384
385         e = r;
386         STRV_FOREACH(s, l) {
387                 if (e != r)
388                         e = stpcpy(e, separator);
389
390                 e = stpcpy(e, *s);
391         }
392
393         *e = 0;
394
395         return r;
396 }
397
398 #if 0 /// UNNEEDED by elogind
399 char *strv_join_quoted(char **l) {
400         char *buf = NULL;
401         char **s;
402         size_t allocated = 0, len = 0;
403
404         STRV_FOREACH(s, l) {
405                 /* assuming here that escaped string cannot be more
406                  * than twice as long, and reserving space for the
407                  * separator and quotes.
408                  */
409                 _cleanup_free_ char *esc = NULL;
410                 size_t needed;
411
412                 if (!GREEDY_REALLOC(buf, allocated,
413                                     len + strlen(*s) * 2 + 3))
414                         goto oom;
415
416                 esc = cescape(*s);
417                 if (!esc)
418                         goto oom;
419
420                 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
421                                   len > 0 ? " " : "", esc);
422                 assert(needed < allocated - len);
423                 len += needed;
424         }
425
426         if (!buf)
427                 buf = malloc0(1);
428
429         return buf;
430
431  oom:
432         free(buf);
433         return NULL;
434 }
435 #endif // 0
436
437 int strv_push(char ***l, char *value) {
438         char **c;
439         unsigned n, m;
440
441         if (!value)
442                 return 0;
443
444         n = strv_length(*l);
445
446         /* Increase and check for overflow */
447         m = n + 2;
448         if (m < n)
449                 return -ENOMEM;
450
451         c = realloc_multiply(*l, sizeof(char*), m);
452         if (!c)
453                 return -ENOMEM;
454
455         c[n] = value;
456         c[n+1] = NULL;
457
458         *l = c;
459         return 0;
460 }
461
462 int strv_push_pair(char ***l, char *a, char *b) {
463         char **c;
464         unsigned n, m;
465
466         if (!a && !b)
467                 return 0;
468
469         n = strv_length(*l);
470
471         /* increase and check for overflow */
472         m = n + !!a + !!b + 1;
473         if (m < n)
474                 return -ENOMEM;
475
476         c = realloc_multiply(*l, sizeof(char*), m);
477         if (!c)
478                 return -ENOMEM;
479
480         if (a)
481                 c[n++] = a;
482         if (b)
483                 c[n++] = b;
484         c[n] = NULL;
485
486         *l = c;
487         return 0;
488 }
489
490 int strv_push_prepend(char ***l, char *value) {
491         char **c;
492         unsigned n, m, i;
493
494         if (!value)
495                 return 0;
496
497         n = strv_length(*l);
498
499         /* increase and check for overflow */
500         m = n + 2;
501         if (m < n)
502                 return -ENOMEM;
503
504         c = new(char*, m);
505         if (!c)
506                 return -ENOMEM;
507
508         for (i = 0; i < n; i++)
509                 c[i+1] = (*l)[i];
510
511         c[0] = value;
512         c[n+1] = NULL;
513
514         free(*l);
515         *l = c;
516
517         return 0;
518 }
519
520 int strv_consume(char ***l, char *value) {
521         int r;
522
523         r = strv_push(l, value);
524         if (r < 0)
525                 free(value);
526
527         return r;
528 }
529
530 #if 0 /// UNNEEDED by elogind
531 int strv_consume_pair(char ***l, char *a, char *b) {
532         int r;
533
534         r = strv_push_pair(l, a, b);
535         if (r < 0) {
536                 free(a);
537                 free(b);
538         }
539
540         return r;
541 }
542 #endif // 0
543
544 int strv_consume_prepend(char ***l, char *value) {
545         int r;
546
547         r = strv_push_prepend(l, value);
548         if (r < 0)
549                 free(value);
550
551         return r;
552 }
553
554 int strv_extend(char ***l, const char *value) {
555         char *v;
556
557         if (!value)
558                 return 0;
559
560         v = strdup(value);
561         if (!v)
562                 return -ENOMEM;
563
564         return strv_consume(l, v);
565 }
566
567 char **strv_uniq(char **l) {
568         char **i;
569
570         /* Drops duplicate entries. The first identical string will be
571          * kept, the others dropped */
572
573         STRV_FOREACH(i, l)
574                 strv_remove(i+1, *i);
575
576         return l;
577 }
578
579 #if 0 /// UNNEEDED by elogind
580 bool strv_is_uniq(char **l) {
581         char **i;
582
583         STRV_FOREACH(i, l)
584                 if (strv_find(i+1, *i))
585                         return false;
586
587         return true;
588 }
589 #endif // 0
590
591 char **strv_remove(char **l, const char *s) {
592         char **f, **t;
593
594         if (!l)
595                 return NULL;
596
597         assert(s);
598
599         /* Drops every occurrence of s in the string list, edits
600          * in-place. */
601
602         for (f = t = l; *f; f++)
603                 if (streq(*f, s))
604                         free(*f);
605                 else
606                         *(t++) = *f;
607
608         *t = NULL;
609         return l;
610 }
611
612 char **strv_parse_nulstr(const char *s, size_t l) {
613         const char *p;
614         unsigned c = 0, i = 0;
615         char **v;
616
617         assert(s || l <= 0);
618
619         if (l <= 0)
620                 return new0(char*, 1);
621
622         for (p = s; p < s + l; p++)
623                 if (*p == 0)
624                         c++;
625
626         if (s[l-1] != 0)
627                 c++;
628
629         v = new0(char*, c+1);
630         if (!v)
631                 return NULL;
632
633         p = s;
634         while (p < s + l) {
635                 const char *e;
636
637                 e = memchr(p, 0, s + l - p);
638
639                 v[i] = strndup(p, e ? e - p : s + l - p);
640                 if (!v[i]) {
641                         strv_free(v);
642                         return NULL;
643                 }
644
645                 i++;
646
647                 if (!e)
648                         break;
649
650                 p = e + 1;
651         }
652
653         assert(i == c);
654
655         return v;
656 }
657
658 char **strv_split_nulstr(const char *s) {
659         const char *i;
660         char **r = NULL;
661
662         NULSTR_FOREACH(i, s)
663                 if (strv_extend(&r, i) < 0) {
664                         strv_free(r);
665                         return NULL;
666                 }
667
668         if (!r)
669                 return strv_new(NULL, NULL);
670
671         return r;
672 }
673
674 #if 0 /// UNNEEDED by elogind
675 int strv_make_nulstr(char **l, char **p, size_t *q) {
676         size_t n_allocated = 0, n = 0;
677         _cleanup_free_ char *m = NULL;
678         char **i;
679
680         assert(p);
681         assert(q);
682
683         STRV_FOREACH(i, l) {
684                 size_t z;
685
686                 z = strlen(*i);
687
688                 if (!GREEDY_REALLOC(m, n_allocated, n + z + 1))
689                         return -ENOMEM;
690
691                 memcpy(m + n, *i, z + 1);
692                 n += z + 1;
693         }
694
695         if (!m) {
696                 m = new0(char, 1);
697                 if (!m)
698                         return -ENOMEM;
699                 n = 0;
700         }
701
702         *p = m;
703         *q = n;
704
705         m = NULL;
706
707         return 0;
708 }
709
710 bool strv_overlap(char **a, char **b) {
711         char **i;
712
713         STRV_FOREACH(i, a)
714                 if (strv_contains(b, *i))
715                         return true;
716
717         return false;
718 }
719 #endif // 0
720
721 static int str_compare(const void *_a, const void *_b) {
722         const char **a = (const char**) _a, **b = (const char**) _b;
723
724         return strcmp(*a, *b);
725 }
726
727 char **strv_sort(char **l) {
728
729         if (strv_isempty(l))
730                 return l;
731
732         qsort(l, strv_length(l), sizeof(char*), str_compare);
733         return l;
734 }
735
736 #if 0 /// UNNEEDED by elogind
737 bool strv_equal(char **a, char **b) {
738
739         if (strv_isempty(a))
740                 return strv_isempty(b);
741
742         if (strv_isempty(b))
743                 return false;
744
745         for ( ; *a || *b; ++a, ++b)
746                 if (!streq_ptr(*a, *b))
747                         return false;
748
749         return true;
750 }
751
752 void strv_print(char **l) {
753         char **s;
754
755         STRV_FOREACH(s, l)
756                 puts(*s);
757 }
758
759 int strv_extendf(char ***l, const char *format, ...) {
760         va_list ap;
761         char *x;
762         int r;
763
764         va_start(ap, format);
765         r = vasprintf(&x, format, ap);
766         va_end(ap);
767
768         if (r < 0)
769                 return -ENOMEM;
770
771         return strv_consume(l, x);
772 }
773
774 char **strv_reverse(char **l) {
775         unsigned n, i;
776
777         n = strv_length(l);
778         if (n <= 1)
779                 return l;
780
781         for (i = 0; i < n / 2; i++) {
782                 char *t;
783
784                 t = l[i];
785                 l[i] = l[n-1-i];
786                 l[n-1-i] = t;
787         }
788
789         return l;
790 }
791
792 char **strv_shell_escape(char **l, const char *bad) {
793         char **s;
794
795         /* Escapes every character in every string in l that is in bad,
796          * edits in-place, does not roll-back on error. */
797
798         STRV_FOREACH(s, l) {
799                 char *v;
800
801                 v = shell_escape(*s, bad);
802                 if (!v)
803                         return NULL;
804
805                 free(*s);
806                 *s = v;
807         }
808
809         return l;
810 }
811
812 bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
813         char* const* p;
814
815         STRV_FOREACH(p, patterns)
816                 if (fnmatch(*p, s, 0) == 0)
817                         return true;
818
819         return false;
820 }
821
822 char ***strv_free_free(char ***l) {
823         char ***i;
824
825         if (!l)
826                 return NULL;
827
828         for (i = l; *i; i++)
829                 strv_free(*i);
830
831         free(l);
832         return NULL;
833 }
834
835 char **strv_skip(char **l, size_t n) {
836
837         while (n > 0) {
838                 if (strv_isempty(l))
839                         return l;
840
841                 l++, n--;
842         }
843
844         return l;
845 }
846
847 int strv_extend_n(char ***l, const char *value, size_t n) {
848         size_t i, j, k;
849         char **nl;
850
851         assert(l);
852
853         if (!value)
854                 return 0;
855         if (n == 0)
856                 return 0;
857
858         /* Adds the value value n times to l */
859
860         k = strv_length(*l);
861
862         nl = realloc(*l, sizeof(char*) * (k + n + 1));
863         if (!nl)
864                 return -ENOMEM;
865
866         *l = nl;
867
868         for (i = k; i < k + n; i++) {
869                 nl[i] = strdup(value);
870                 if (!nl[i])
871                         goto rollback;
872         }
873
874         nl[i] = NULL;
875         return 0;
876
877 rollback:
878         for (j = k; j < i; j++)
879                 free(nl[j]);
880
881         nl[k] = NULL;
882         return -ENOMEM;
883 }
884 #endif // 0