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