]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/strv.c
Merge pull request #2075 from phomes/includes-cleanup-basic
[thirdparty/systemd.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 <fnmatch.h>
24 #include <stdarg.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include "alloc-util.h"
30 #include "escape.h"
31 #include "extract-word.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 free(l);
92 return NULL;
93 }
94
95 char **strv_free_erase(char **l) {
96 char **i;
97
98 STRV_FOREACH(i, l)
99 string_erase(*i);
100
101 return strv_free(l);
102 }
103
104 char **strv_copy(char * const *l) {
105 char **r, **k;
106
107 k = r = new(char*, strv_length(l) + 1);
108 if (!r)
109 return NULL;
110
111 if (l)
112 for (; *l; k++, l++) {
113 *k = strdup(*l);
114 if (!*k) {
115 strv_free(r);
116 return NULL;
117 }
118 }
119
120 *k = NULL;
121 return r;
122 }
123
124 unsigned strv_length(char * const *l) {
125 unsigned n = 0;
126
127 if (!l)
128 return 0;
129
130 for (; *l; l++)
131 n++;
132
133 return n;
134 }
135
136 char **strv_new_ap(const char *x, va_list ap) {
137 const char *s;
138 char **a;
139 unsigned n = 0, i = 0;
140 va_list aq;
141
142 /* As a special trick we ignore all listed strings that equal
143 * (const char*) -1. This is supposed to be used with the
144 * STRV_IFNOTNULL() macro to include possibly NULL strings in
145 * the string list. */
146
147 if (x) {
148 n = x == (const char*) -1 ? 0 : 1;
149
150 va_copy(aq, ap);
151 while ((s = va_arg(aq, const char*))) {
152 if (s == (const char*) -1)
153 continue;
154
155 n++;
156 }
157
158 va_end(aq);
159 }
160
161 a = new(char*, n+1);
162 if (!a)
163 return NULL;
164
165 if (x) {
166 if (x != (const char*) -1) {
167 a[i] = strdup(x);
168 if (!a[i])
169 goto fail;
170 i++;
171 }
172
173 while ((s = va_arg(ap, const char*))) {
174
175 if (s == (const char*) -1)
176 continue;
177
178 a[i] = strdup(s);
179 if (!a[i])
180 goto fail;
181
182 i++;
183 }
184 }
185
186 a[i] = NULL;
187
188 return a;
189
190 fail:
191 strv_free(a);
192 return NULL;
193 }
194
195 char **strv_new(const char *x, ...) {
196 char **r;
197 va_list ap;
198
199 va_start(ap, x);
200 r = strv_new_ap(x, ap);
201 va_end(ap);
202
203 return r;
204 }
205
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 = realloc(*a, sizeof(char*) * (p + q + 1));
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
271 char **strv_split(const char *s, const char *separator) {
272 const char *word, *state;
273 size_t l;
274 unsigned n, i;
275 char **r;
276
277 assert(s);
278
279 n = 0;
280 FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
281 n++;
282
283 r = new(char*, n+1);
284 if (!r)
285 return NULL;
286
287 i = 0;
288 FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
289 r[i] = strndup(word, l);
290 if (!r[i]) {
291 strv_free(r);
292 return NULL;
293 }
294
295 i++;
296 }
297
298 r[i] = NULL;
299 return r;
300 }
301
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
363 char *strv_join(char **l, const char *separator) {
364 char *r, *e;
365 char **s;
366 size_t n, k;
367
368 if (!separator)
369 separator = " ";
370
371 k = strlen(separator);
372
373 n = 0;
374 STRV_FOREACH(s, l) {
375 if (n != 0)
376 n += k;
377 n += strlen(*s);
378 }
379
380 r = new(char, n+1);
381 if (!r)
382 return NULL;
383
384 e = r;
385 STRV_FOREACH(s, l) {
386 if (e != r)
387 e = stpcpy(e, separator);
388
389 e = stpcpy(e, *s);
390 }
391
392 *e = 0;
393
394 return r;
395 }
396
397 char *strv_join_quoted(char **l) {
398 char *buf = NULL;
399 char **s;
400 size_t allocated = 0, len = 0;
401
402 STRV_FOREACH(s, l) {
403 /* assuming here that escaped string cannot be more
404 * than twice as long, and reserving space for the
405 * separator and quotes.
406 */
407 _cleanup_free_ char *esc = NULL;
408 size_t needed;
409
410 if (!GREEDY_REALLOC(buf, allocated,
411 len + strlen(*s) * 2 + 3))
412 goto oom;
413
414 esc = cescape(*s);
415 if (!esc)
416 goto oom;
417
418 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
419 len > 0 ? " " : "", esc);
420 assert(needed < allocated - len);
421 len += needed;
422 }
423
424 if (!buf)
425 buf = malloc0(1);
426
427 return buf;
428
429 oom:
430 free(buf);
431 return NULL;
432 }
433
434 int strv_push(char ***l, char *value) {
435 char **c;
436 unsigned n, m;
437
438 if (!value)
439 return 0;
440
441 n = strv_length(*l);
442
443 /* Increase and check for overflow */
444 m = n + 2;
445 if (m < n)
446 return -ENOMEM;
447
448 c = realloc_multiply(*l, sizeof(char*), m);
449 if (!c)
450 return -ENOMEM;
451
452 c[n] = value;
453 c[n+1] = NULL;
454
455 *l = c;
456 return 0;
457 }
458
459 int strv_push_pair(char ***l, char *a, char *b) {
460 char **c;
461 unsigned n, m;
462
463 if (!a && !b)
464 return 0;
465
466 n = strv_length(*l);
467
468 /* increase and check for overflow */
469 m = n + !!a + !!b + 1;
470 if (m < n)
471 return -ENOMEM;
472
473 c = realloc_multiply(*l, sizeof(char*), m);
474 if (!c)
475 return -ENOMEM;
476
477 if (a)
478 c[n++] = a;
479 if (b)
480 c[n++] = b;
481 c[n] = NULL;
482
483 *l = c;
484 return 0;
485 }
486
487 int strv_push_prepend(char ***l, char *value) {
488 char **c;
489 unsigned n, m, i;
490
491 if (!value)
492 return 0;
493
494 n = strv_length(*l);
495
496 /* increase and check for overflow */
497 m = n + 2;
498 if (m < n)
499 return -ENOMEM;
500
501 c = new(char*, m);
502 if (!c)
503 return -ENOMEM;
504
505 for (i = 0; i < n; i++)
506 c[i+1] = (*l)[i];
507
508 c[0] = value;
509 c[n+1] = NULL;
510
511 free(*l);
512 *l = c;
513
514 return 0;
515 }
516
517 int strv_consume(char ***l, char *value) {
518 int r;
519
520 r = strv_push(l, value);
521 if (r < 0)
522 free(value);
523
524 return r;
525 }
526
527 int strv_consume_pair(char ***l, char *a, char *b) {
528 int r;
529
530 r = strv_push_pair(l, a, b);
531 if (r < 0) {
532 free(a);
533 free(b);
534 }
535
536 return r;
537 }
538
539 int strv_consume_prepend(char ***l, char *value) {
540 int r;
541
542 r = strv_push_prepend(l, value);
543 if (r < 0)
544 free(value);
545
546 return r;
547 }
548
549 int strv_extend(char ***l, const char *value) {
550 char *v;
551
552 if (!value)
553 return 0;
554
555 v = strdup(value);
556 if (!v)
557 return -ENOMEM;
558
559 return strv_consume(l, v);
560 }
561
562 char **strv_uniq(char **l) {
563 char **i;
564
565 /* Drops duplicate entries. The first identical string will be
566 * kept, the others dropped */
567
568 STRV_FOREACH(i, l)
569 strv_remove(i+1, *i);
570
571 return l;
572 }
573
574 bool strv_is_uniq(char **l) {
575 char **i;
576
577 STRV_FOREACH(i, l)
578 if (strv_find(i+1, *i))
579 return false;
580
581 return true;
582 }
583
584 char **strv_remove(char **l, const char *s) {
585 char **f, **t;
586
587 if (!l)
588 return NULL;
589
590 assert(s);
591
592 /* Drops every occurrence of s in the string list, edits
593 * in-place. */
594
595 for (f = t = l; *f; f++)
596 if (streq(*f, s))
597 free(*f);
598 else
599 *(t++) = *f;
600
601 *t = NULL;
602 return l;
603 }
604
605 char **strv_parse_nulstr(const char *s, size_t l) {
606 const char *p;
607 unsigned c = 0, i = 0;
608 char **v;
609
610 assert(s || l <= 0);
611
612 if (l <= 0)
613 return new0(char*, 1);
614
615 for (p = s; p < s + l; p++)
616 if (*p == 0)
617 c++;
618
619 if (s[l-1] != 0)
620 c++;
621
622 v = new0(char*, c+1);
623 if (!v)
624 return NULL;
625
626 p = s;
627 while (p < s + l) {
628 const char *e;
629
630 e = memchr(p, 0, s + l - p);
631
632 v[i] = strndup(p, e ? e - p : s + l - p);
633 if (!v[i]) {
634 strv_free(v);
635 return NULL;
636 }
637
638 i++;
639
640 if (!e)
641 break;
642
643 p = e + 1;
644 }
645
646 assert(i == c);
647
648 return v;
649 }
650
651 char **strv_split_nulstr(const char *s) {
652 const char *i;
653 char **r = NULL;
654
655 NULSTR_FOREACH(i, s)
656 if (strv_extend(&r, i) < 0) {
657 strv_free(r);
658 return NULL;
659 }
660
661 if (!r)
662 return strv_new(NULL, NULL);
663
664 return r;
665 }
666
667 int strv_make_nulstr(char **l, char **p, size_t *q) {
668 size_t n_allocated = 0, n = 0;
669 _cleanup_free_ char *m = NULL;
670 char **i;
671
672 assert(p);
673 assert(q);
674
675 STRV_FOREACH(i, l) {
676 size_t z;
677
678 z = strlen(*i);
679
680 if (!GREEDY_REALLOC(m, n_allocated, n + z + 1))
681 return -ENOMEM;
682
683 memcpy(m + n, *i, z + 1);
684 n += z + 1;
685 }
686
687 if (!m) {
688 m = new0(char, 1);
689 if (!m)
690 return -ENOMEM;
691 n = 0;
692 }
693
694 *p = m;
695 *q = n;
696
697 m = NULL;
698
699 return 0;
700 }
701
702 bool strv_overlap(char **a, char **b) {
703 char **i;
704
705 STRV_FOREACH(i, a)
706 if (strv_contains(b, *i))
707 return true;
708
709 return false;
710 }
711
712 static int str_compare(const void *_a, const void *_b) {
713 const char **a = (const char**) _a, **b = (const char**) _b;
714
715 return strcmp(*a, *b);
716 }
717
718 char **strv_sort(char **l) {
719
720 if (strv_isempty(l))
721 return l;
722
723 qsort(l, strv_length(l), sizeof(char*), str_compare);
724 return l;
725 }
726
727 bool strv_equal(char **a, char **b) {
728
729 if (strv_isempty(a))
730 return strv_isempty(b);
731
732 if (strv_isempty(b))
733 return false;
734
735 for ( ; *a || *b; ++a, ++b)
736 if (!streq_ptr(*a, *b))
737 return false;
738
739 return true;
740 }
741
742 void strv_print(char **l) {
743 char **s;
744
745 STRV_FOREACH(s, l)
746 puts(*s);
747 }
748
749 int strv_extendf(char ***l, const char *format, ...) {
750 va_list ap;
751 char *x;
752 int r;
753
754 va_start(ap, format);
755 r = vasprintf(&x, format, ap);
756 va_end(ap);
757
758 if (r < 0)
759 return -ENOMEM;
760
761 return strv_consume(l, x);
762 }
763
764 char **strv_reverse(char **l) {
765 unsigned n, i;
766
767 n = strv_length(l);
768 if (n <= 1)
769 return l;
770
771 for (i = 0; i < n / 2; i++) {
772 char *t;
773
774 t = l[i];
775 l[i] = l[n-1-i];
776 l[n-1-i] = t;
777 }
778
779 return l;
780 }
781
782 char **strv_shell_escape(char **l, const char *bad) {
783 char **s;
784
785 /* Escapes every character in every string in l that is in bad,
786 * edits in-place, does not roll-back on error. */
787
788 STRV_FOREACH(s, l) {
789 char *v;
790
791 v = shell_escape(*s, bad);
792 if (!v)
793 return NULL;
794
795 free(*s);
796 *s = v;
797 }
798
799 return l;
800 }
801
802 bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
803 char* const* p;
804
805 STRV_FOREACH(p, patterns)
806 if (fnmatch(*p, s, 0) == 0)
807 return true;
808
809 return false;
810 }
811
812 char ***strv_free_free(char ***l) {
813 char ***i;
814
815 if (!l)
816 return NULL;
817
818 for (i = l; *i; i++)
819 strv_free(*i);
820
821 free(l);
822 return NULL;
823 }
824
825 char **strv_skip(char **l, size_t n) {
826
827 while (n > 0) {
828 if (strv_isempty(l))
829 return l;
830
831 l++, n--;
832 }
833
834 return l;
835 }
836
837 int strv_extend_n(char ***l, const char *value, size_t n) {
838 size_t i, j, k;
839 char **nl;
840
841 assert(l);
842
843 if (!value)
844 return 0;
845 if (n == 0)
846 return 0;
847
848 /* Adds the value value n times to l */
849
850 k = strv_length(*l);
851
852 nl = realloc(*l, sizeof(char*) * (k + n + 1));
853 if (!nl)
854 return -ENOMEM;
855
856 *l = nl;
857
858 for (i = k; i < k + n; i++) {
859 nl[i] = strdup(value);
860 if (!nl[i])
861 goto rollback;
862 }
863
864 nl[i] = NULL;
865 return 0;
866
867 rollback:
868 for (j = k; j < i; j++)
869 free(nl[j]);
870
871 nl[k] = NULL;
872 return -ENOMEM;
873 }