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