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