]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/strv.c
Merge pull request #8297 from filbranden/udevrule1
[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 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 int strv_extend_strv(char ***a, char **b, bool filter_duplicates) {
206 char **s, **t;
207 size_t p, q, i = 0, j;
208
209 assert(a);
210
211 if (strv_isempty(b))
212 return 0;
213
214 p = strv_length(*a);
215 q = strv_length(b);
216
217 t = realloc(*a, sizeof(char*) * (p + q + 1));
218 if (!t)
219 return -ENOMEM;
220
221 t[p] = NULL;
222 *a = t;
223
224 STRV_FOREACH(s, b) {
225
226 if (filter_duplicates && strv_contains(t, *s))
227 continue;
228
229 t[p+i] = strdup(*s);
230 if (!t[p+i])
231 goto rollback;
232
233 i++;
234 t[p+i] = NULL;
235 }
236
237 assert(i <= q);
238
239 return (int) i;
240
241 rollback:
242 for (j = 0; j < i; j++)
243 free(t[p + j]);
244
245 t[p] = NULL;
246 return -ENOMEM;
247 }
248
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
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 char **strv_split_newlines(const char *s) {
302 char **l;
303 unsigned n;
304
305 assert(s);
306
307 /* Special version of strv_split() that splits on newlines and
308 * suppresses an empty string at the end */
309
310 l = strv_split(s, NEWLINE);
311 if (!l)
312 return NULL;
313
314 n = strv_length(l);
315 if (n <= 0)
316 return l;
317
318 if (isempty(l[n - 1]))
319 l[n - 1] = mfree(l[n - 1]);
320
321 return l;
322 }
323
324 int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
325 _cleanup_strv_free_ char **l = NULL;
326 size_t n = 0, allocated = 0;
327 int r;
328
329 assert(t);
330 assert(s);
331
332 for (;;) {
333 _cleanup_free_ char *word = NULL;
334
335 r = extract_first_word(&s, &word, separators, flags);
336 if (r < 0)
337 return r;
338 if (r == 0)
339 break;
340
341 if (!GREEDY_REALLOC(l, allocated, n + 2))
342 return -ENOMEM;
343
344 l[n++] = word;
345 word = NULL;
346
347 l[n] = NULL;
348 }
349
350 if (!l) {
351 l = new0(char*, 1);
352 if (!l)
353 return -ENOMEM;
354 }
355
356 *t = l;
357 l = NULL;
358
359 return (int) n;
360 }
361
362 char *strv_join(char **l, const char *separator) {
363 char *r, *e;
364 char **s;
365 size_t n, k;
366
367 if (!separator)
368 separator = " ";
369
370 k = strlen(separator);
371
372 n = 0;
373 STRV_FOREACH(s, l) {
374 if (s != l)
375 n += k;
376 n += strlen(*s);
377 }
378
379 r = new(char, n+1);
380 if (!r)
381 return NULL;
382
383 e = r;
384 STRV_FOREACH(s, l) {
385 if (s != l)
386 e = stpcpy(e, separator);
387
388 e = stpcpy(e, *s);
389 }
390
391 *e = 0;
392
393 return r;
394 }
395
396 int strv_push(char ***l, char *value) {
397 char **c;
398 unsigned n, m;
399
400 if (!value)
401 return 0;
402
403 n = strv_length(*l);
404
405 /* Increase and check for overflow */
406 m = n + 2;
407 if (m < n)
408 return -ENOMEM;
409
410 c = reallocarray(*l, m, sizeof(char*));
411 if (!c)
412 return -ENOMEM;
413
414 c[n] = value;
415 c[n+1] = NULL;
416
417 *l = c;
418 return 0;
419 }
420
421 int strv_push_pair(char ***l, char *a, char *b) {
422 char **c;
423 unsigned n, m;
424
425 if (!a && !b)
426 return 0;
427
428 n = strv_length(*l);
429
430 /* increase and check for overflow */
431 m = n + !!a + !!b + 1;
432 if (m < n)
433 return -ENOMEM;
434
435 c = reallocarray(*l, m, sizeof(char*));
436 if (!c)
437 return -ENOMEM;
438
439 if (a)
440 c[n++] = a;
441 if (b)
442 c[n++] = b;
443 c[n] = NULL;
444
445 *l = c;
446 return 0;
447 }
448
449 int strv_insert(char ***l, unsigned position, char *value) {
450 char **c;
451 unsigned n, m, i;
452
453 if (!value)
454 return 0;
455
456 n = strv_length(*l);
457 position = MIN(position, n);
458
459 /* increase and check for overflow */
460 m = n + 2;
461 if (m < n)
462 return -ENOMEM;
463
464 c = new(char*, m);
465 if (!c)
466 return -ENOMEM;
467
468 for (i = 0; i < position; i++)
469 c[i] = (*l)[i];
470 c[position] = value;
471 for (i = position; i < n; i++)
472 c[i+1] = (*l)[i];
473
474 c[n+1] = NULL;
475
476 free(*l);
477 *l = c;
478
479 return 0;
480 }
481
482 int strv_consume(char ***l, char *value) {
483 int r;
484
485 r = strv_push(l, value);
486 if (r < 0)
487 free(value);
488
489 return r;
490 }
491
492 int strv_consume_pair(char ***l, char *a, char *b) {
493 int r;
494
495 r = strv_push_pair(l, a, b);
496 if (r < 0) {
497 free(a);
498 free(b);
499 }
500
501 return r;
502 }
503
504 int strv_consume_prepend(char ***l, char *value) {
505 int r;
506
507 r = strv_push_prepend(l, value);
508 if (r < 0)
509 free(value);
510
511 return r;
512 }
513
514 int strv_extend(char ***l, const char *value) {
515 char *v;
516
517 if (!value)
518 return 0;
519
520 v = strdup(value);
521 if (!v)
522 return -ENOMEM;
523
524 return strv_consume(l, v);
525 }
526
527 int strv_extend_front(char ***l, const char *value) {
528 size_t n, m;
529 char *v, **c;
530
531 assert(l);
532
533 /* Like strv_extend(), but prepends rather than appends the new entry */
534
535 if (!value)
536 return 0;
537
538 n = strv_length(*l);
539
540 /* Increase and overflow check. */
541 m = n + 2;
542 if (m < n)
543 return -ENOMEM;
544
545 v = strdup(value);
546 if (!v)
547 return -ENOMEM;
548
549 c = reallocarray(*l, m, sizeof(char*));
550 if (!c) {
551 free(v);
552 return -ENOMEM;
553 }
554
555 memmove(c+1, c, n * sizeof(char*));
556 c[0] = v;
557 c[n+1] = NULL;
558
559 *l = c;
560 return 0;
561 }
562
563 char **strv_uniq(char **l) {
564 char **i;
565
566 /* Drops duplicate entries. The first identical string will be
567 * kept, the others dropped */
568
569 STRV_FOREACH(i, l)
570 strv_remove(i+1, *i);
571
572 return l;
573 }
574
575 bool strv_is_uniq(char **l) {
576 char **i;
577
578 STRV_FOREACH(i, l)
579 if (strv_find(i+1, *i))
580 return false;
581
582 return true;
583 }
584
585 char **strv_remove(char **l, const char *s) {
586 char **f, **t;
587
588 if (!l)
589 return NULL;
590
591 assert(s);
592
593 /* Drops every occurrence of s in the string list, edits
594 * in-place. */
595
596 for (f = t = l; *f; f++)
597 if (streq(*f, s))
598 free(*f);
599 else
600 *(t++) = *f;
601
602 *t = NULL;
603 return l;
604 }
605
606 char **strv_parse_nulstr(const char *s, size_t l) {
607 /* l is the length of the input data, which will be split at NULs into
608 * elements of the resulting strv. Hence, the number of items in the resulting strv
609 * will be equal to one plus the number of NUL bytes in the l bytes starting at s,
610 * unless s[l-1] is NUL, in which case the final empty string is not stored in
611 * the resulting strv, and length is equal to the number of NUL bytes.
612 *
613 * Note that contrary to a normal nulstr which cannot contain empty strings, because
614 * the input data is terminated by any two consequent NUL bytes, this parser accepts
615 * empty strings in s.
616 */
617
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 int strv_make_nulstr(char **l, char **p, size_t *q) {
680 /* A valid nulstr with two NULs at the end will be created, but
681 * q will be the length without the two trailing NULs. Thus the output
682 * string is a valid nulstr and can be iterated over using NULSTR_FOREACH,
683 * and can also be parsed by strv_parse_nulstr as long as the length
684 * is provided separately.
685 */
686
687 size_t n_allocated = 0, n = 0;
688 _cleanup_free_ char *m = NULL;
689 char **i;
690
691 assert(p);
692 assert(q);
693
694 STRV_FOREACH(i, l) {
695 size_t z;
696
697 z = strlen(*i);
698
699 if (!GREEDY_REALLOC(m, n_allocated, n + z + 2))
700 return -ENOMEM;
701
702 memcpy(m + n, *i, z + 1);
703 n += z + 1;
704 }
705
706 if (!m) {
707 m = new0(char, 1);
708 if (!m)
709 return -ENOMEM;
710 n = 1;
711 } else
712 /* make sure there is a second extra NUL at the end of resulting nulstr */
713 m[n] = '\0';
714
715 assert(n > 0);
716 *p = m;
717 *q = n - 1;
718
719 m = NULL;
720
721 return 0;
722 }
723
724 bool strv_overlap(char **a, char **b) {
725 char **i;
726
727 STRV_FOREACH(i, a)
728 if (strv_contains(b, *i))
729 return true;
730
731 return false;
732 }
733
734 static int str_compare(const void *_a, const void *_b) {
735 const char **a = (const char**) _a, **b = (const char**) _b;
736
737 return strcmp(*a, *b);
738 }
739
740 char **strv_sort(char **l) {
741 qsort_safe(l, strv_length(l), sizeof(char*), str_compare);
742 return l;
743 }
744
745 bool strv_equal(char **a, char **b) {
746
747 if (strv_isempty(a))
748 return strv_isempty(b);
749
750 if (strv_isempty(b))
751 return false;
752
753 for ( ; *a || *b; ++a, ++b)
754 if (!streq_ptr(*a, *b))
755 return false;
756
757 return true;
758 }
759
760 void strv_print(char **l) {
761 char **s;
762
763 STRV_FOREACH(s, l)
764 puts(*s);
765 }
766
767 int strv_extendf(char ***l, const char *format, ...) {
768 va_list ap;
769 char *x;
770 int r;
771
772 va_start(ap, format);
773 r = vasprintf(&x, format, ap);
774 va_end(ap);
775
776 if (r < 0)
777 return -ENOMEM;
778
779 return strv_consume(l, x);
780 }
781
782 char **strv_reverse(char **l) {
783 unsigned n, i;
784
785 n = strv_length(l);
786 if (n <= 1)
787 return l;
788
789 for (i = 0; i < n / 2; i++)
790 SWAP_TWO(l[i], l[n-1-i]);
791
792 return l;
793 }
794
795 char **strv_shell_escape(char **l, const char *bad) {
796 char **s;
797
798 /* Escapes every character in every string in l that is in bad,
799 * edits in-place, does not roll-back on error. */
800
801 STRV_FOREACH(s, l) {
802 char *v;
803
804 v = shell_escape(*s, bad);
805 if (!v)
806 return NULL;
807
808 free(*s);
809 *s = v;
810 }
811
812 return l;
813 }
814
815 bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
816 char* const* p;
817
818 STRV_FOREACH(p, patterns)
819 if (fnmatch(*p, s, flags) == 0)
820 return true;
821
822 return false;
823 }
824
825 char ***strv_free_free(char ***l) {
826 char ***i;
827
828 if (!l)
829 return NULL;
830
831 for (i = l; *i; i++)
832 strv_free(*i);
833
834 return mfree(l);
835 }
836
837 char **strv_skip(char **l, size_t n) {
838
839 while (n > 0) {
840 if (strv_isempty(l))
841 return l;
842
843 l++, n--;
844 }
845
846 return l;
847 }
848
849 int strv_extend_n(char ***l, const char *value, size_t n) {
850 size_t i, j, k;
851 char **nl;
852
853 assert(l);
854
855 if (!value)
856 return 0;
857 if (n == 0)
858 return 0;
859
860 /* Adds the value n times to l */
861
862 k = strv_length(*l);
863
864 nl = realloc(*l, sizeof(char*) * (k + n + 1));
865 if (!nl)
866 return -ENOMEM;
867
868 *l = nl;
869
870 for (i = k; i < k + n; i++) {
871 nl[i] = strdup(value);
872 if (!nl[i])
873 goto rollback;
874 }
875
876 nl[i] = NULL;
877 return 0;
878
879 rollback:
880 for (j = k; j < i; j++)
881 free(nl[j]);
882
883 nl[k] = NULL;
884 return -ENOMEM;
885 }
886
887 int fputstrv(FILE *f, char **l, const char *separator, bool *space) {
888 bool b = false;
889 char **s;
890 int r;
891
892 /* Like fputs(), but for strv, and with a less stupid argument order */
893
894 if (!space)
895 space = &b;
896
897 STRV_FOREACH(s, l) {
898 r = fputs_with_space(f, *s, separator, space);
899 if (r < 0)
900 return r;
901 }
902
903 return 0;
904 }