]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/strv.c
tree-wide: sort includes in *.h
[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 <stdarg.h>
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "alloc-util.h"
28 #include "escape.h"
29 #include "string-util.h"
30 #include "strv.h"
31 #include "util.h"
32
33 char *strv_find(char **l, const char *name) {
34 char **i;
35
36 assert(name);
37
38 STRV_FOREACH(i, l)
39 if (streq(*i, name))
40 return *i;
41
42 return NULL;
43 }
44
45 char *strv_find_prefix(char **l, const char *name) {
46 char **i;
47
48 assert(name);
49
50 STRV_FOREACH(i, l)
51 if (startswith(*i, name))
52 return *i;
53
54 return NULL;
55 }
56
57 char *strv_find_startswith(char **l, const char *name) {
58 char **i, *e;
59
60 assert(name);
61
62 /* Like strv_find_prefix, but actually returns only the
63 * suffix, not the whole item */
64
65 STRV_FOREACH(i, l) {
66 e = startswith(*i, name);
67 if (e)
68 return e;
69 }
70
71 return NULL;
72 }
73
74 void strv_clear(char **l) {
75 char **k;
76
77 if (!l)
78 return;
79
80 for (k = l; *k; k++)
81 free(*k);
82
83 *l = NULL;
84 }
85
86 char **strv_free(char **l) {
87 strv_clear(l);
88 free(l);
89 return NULL;
90 }
91
92 char **strv_free_erase(char **l) {
93 char **i;
94
95 STRV_FOREACH(i, l)
96 string_erase(*i);
97
98 return strv_free(l);
99 }
100
101 char **strv_copy(char * const *l) {
102 char **r, **k;
103
104 k = r = new(char*, strv_length(l) + 1);
105 if (!r)
106 return NULL;
107
108 if (l)
109 for (; *l; k++, l++) {
110 *k = strdup(*l);
111 if (!*k) {
112 strv_free(r);
113 return NULL;
114 }
115 }
116
117 *k = NULL;
118 return r;
119 }
120
121 unsigned strv_length(char * const *l) {
122 unsigned n = 0;
123
124 if (!l)
125 return 0;
126
127 for (; *l; l++)
128 n++;
129
130 return n;
131 }
132
133 char **strv_new_ap(const char *x, va_list ap) {
134 const char *s;
135 char **a;
136 unsigned n = 0, i = 0;
137 va_list aq;
138
139 /* As a special trick we ignore all listed strings that equal
140 * (const char*) -1. This is supposed to be used with the
141 * STRV_IFNOTNULL() macro to include possibly NULL strings in
142 * the string list. */
143
144 if (x) {
145 n = x == (const char*) -1 ? 0 : 1;
146
147 va_copy(aq, ap);
148 while ((s = va_arg(aq, const char*))) {
149 if (s == (const char*) -1)
150 continue;
151
152 n++;
153 }
154
155 va_end(aq);
156 }
157
158 a = new(char*, n+1);
159 if (!a)
160 return NULL;
161
162 if (x) {
163 if (x != (const char*) -1) {
164 a[i] = strdup(x);
165 if (!a[i])
166 goto fail;
167 i++;
168 }
169
170 while ((s = va_arg(ap, const char*))) {
171
172 if (s == (const char*) -1)
173 continue;
174
175 a[i] = strdup(s);
176 if (!a[i])
177 goto fail;
178
179 i++;
180 }
181 }
182
183 a[i] = NULL;
184
185 return a;
186
187 fail:
188 strv_free(a);
189 return NULL;
190 }
191
192 char **strv_new(const char *x, ...) {
193 char **r;
194 va_list ap;
195
196 va_start(ap, x);
197 r = strv_new_ap(x, ap);
198 va_end(ap);
199
200 return r;
201 }
202
203 int strv_extend_strv(char ***a, char **b, bool filter_duplicates) {
204 char **s, **t;
205 size_t p, q, i = 0, j;
206
207 assert(a);
208
209 if (strv_isempty(b))
210 return 0;
211
212 p = strv_length(*a);
213 q = strv_length(b);
214
215 t = realloc(*a, sizeof(char*) * (p + q + 1));
216 if (!t)
217 return -ENOMEM;
218
219 t[p] = NULL;
220 *a = t;
221
222 STRV_FOREACH(s, b) {
223
224 if (filter_duplicates && strv_contains(t, *s))
225 continue;
226
227 t[p+i] = strdup(*s);
228 if (!t[p+i])
229 goto rollback;
230
231 i++;
232 t[p+i] = NULL;
233 }
234
235 assert(i <= q);
236
237 return (int) i;
238
239 rollback:
240 for (j = 0; j < i; j++)
241 free(t[p + j]);
242
243 t[p] = NULL;
244 return -ENOMEM;
245 }
246
247 int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
248 int r;
249 char **s;
250
251 STRV_FOREACH(s, b) {
252 char *v;
253
254 v = strappend(*s, suffix);
255 if (!v)
256 return -ENOMEM;
257
258 r = strv_push(a, v);
259 if (r < 0) {
260 free(v);
261 return r;
262 }
263 }
264
265 return 0;
266 }
267
268 char **strv_split(const char *s, const char *separator) {
269 const char *word, *state;
270 size_t l;
271 unsigned n, i;
272 char **r;
273
274 assert(s);
275
276 n = 0;
277 FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
278 n++;
279
280 r = new(char*, n+1);
281 if (!r)
282 return NULL;
283
284 i = 0;
285 FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
286 r[i] = strndup(word, l);
287 if (!r[i]) {
288 strv_free(r);
289 return NULL;
290 }
291
292 i++;
293 }
294
295 r[i] = NULL;
296 return r;
297 }
298
299 char **strv_split_newlines(const char *s) {
300 char **l;
301 unsigned n;
302
303 assert(s);
304
305 /* Special version of strv_split() that splits on newlines and
306 * suppresses an empty string at the end */
307
308 l = strv_split(s, NEWLINE);
309 if (!l)
310 return NULL;
311
312 n = strv_length(l);
313 if (n <= 0)
314 return l;
315
316 if (isempty(l[n - 1]))
317 l[n - 1] = mfree(l[n - 1]);
318
319 return l;
320 }
321
322 int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
323 _cleanup_strv_free_ char **l = NULL;
324 size_t n = 0, allocated = 0;
325 int r;
326
327 assert(t);
328 assert(s);
329
330 for (;;) {
331 _cleanup_free_ char *word = NULL;
332
333 r = extract_first_word(&s, &word, separators, flags);
334 if (r < 0)
335 return r;
336 if (r == 0)
337 break;
338
339 if (!GREEDY_REALLOC(l, allocated, n + 2))
340 return -ENOMEM;
341
342 l[n++] = word;
343 word = NULL;
344
345 l[n] = NULL;
346 }
347
348 if (!l) {
349 l = new0(char*, 1);
350 if (!l)
351 return -ENOMEM;
352 }
353
354 *t = l;
355 l = NULL;
356
357 return (int) n;
358 }
359
360 char *strv_join(char **l, const char *separator) {
361 char *r, *e;
362 char **s;
363 size_t n, k;
364
365 if (!separator)
366 separator = " ";
367
368 k = strlen(separator);
369
370 n = 0;
371 STRV_FOREACH(s, l) {
372 if (n != 0)
373 n += k;
374 n += strlen(*s);
375 }
376
377 r = new(char, n+1);
378 if (!r)
379 return NULL;
380
381 e = r;
382 STRV_FOREACH(s, l) {
383 if (e != r)
384 e = stpcpy(e, separator);
385
386 e = stpcpy(e, *s);
387 }
388
389 *e = 0;
390
391 return r;
392 }
393
394 char *strv_join_quoted(char **l) {
395 char *buf = NULL;
396 char **s;
397 size_t allocated = 0, len = 0;
398
399 STRV_FOREACH(s, l) {
400 /* assuming here that escaped string cannot be more
401 * than twice as long, and reserving space for the
402 * separator and quotes.
403 */
404 _cleanup_free_ char *esc = NULL;
405 size_t needed;
406
407 if (!GREEDY_REALLOC(buf, allocated,
408 len + strlen(*s) * 2 + 3))
409 goto oom;
410
411 esc = cescape(*s);
412 if (!esc)
413 goto oom;
414
415 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
416 len > 0 ? " " : "", esc);
417 assert(needed < allocated - len);
418 len += needed;
419 }
420
421 if (!buf)
422 buf = malloc0(1);
423
424 return buf;
425
426 oom:
427 free(buf);
428 return NULL;
429 }
430
431 int strv_push(char ***l, char *value) {
432 char **c;
433 unsigned n, m;
434
435 if (!value)
436 return 0;
437
438 n = strv_length(*l);
439
440 /* Increase and check for overflow */
441 m = n + 2;
442 if (m < n)
443 return -ENOMEM;
444
445 c = realloc_multiply(*l, sizeof(char*), m);
446 if (!c)
447 return -ENOMEM;
448
449 c[n] = value;
450 c[n+1] = NULL;
451
452 *l = c;
453 return 0;
454 }
455
456 int strv_push_pair(char ***l, char *a, char *b) {
457 char **c;
458 unsigned n, m;
459
460 if (!a && !b)
461 return 0;
462
463 n = strv_length(*l);
464
465 /* increase and check for overflow */
466 m = n + !!a + !!b + 1;
467 if (m < n)
468 return -ENOMEM;
469
470 c = realloc_multiply(*l, sizeof(char*), m);
471 if (!c)
472 return -ENOMEM;
473
474 if (a)
475 c[n++] = a;
476 if (b)
477 c[n++] = b;
478 c[n] = NULL;
479
480 *l = c;
481 return 0;
482 }
483
484 int strv_push_prepend(char ***l, char *value) {
485 char **c;
486 unsigned n, m, i;
487
488 if (!value)
489 return 0;
490
491 n = strv_length(*l);
492
493 /* increase and check for overflow */
494 m = n + 2;
495 if (m < n)
496 return -ENOMEM;
497
498 c = new(char*, m);
499 if (!c)
500 return -ENOMEM;
501
502 for (i = 0; i < n; i++)
503 c[i+1] = (*l)[i];
504
505 c[0] = value;
506 c[n+1] = NULL;
507
508 free(*l);
509 *l = c;
510
511 return 0;
512 }
513
514 int strv_consume(char ***l, char *value) {
515 int r;
516
517 r = strv_push(l, value);
518 if (r < 0)
519 free(value);
520
521 return r;
522 }
523
524 int strv_consume_pair(char ***l, char *a, char *b) {
525 int r;
526
527 r = strv_push_pair(l, a, b);
528 if (r < 0) {
529 free(a);
530 free(b);
531 }
532
533 return r;
534 }
535
536 int strv_consume_prepend(char ***l, char *value) {
537 int r;
538
539 r = strv_push_prepend(l, value);
540 if (r < 0)
541 free(value);
542
543 return r;
544 }
545
546 int strv_extend(char ***l, const char *value) {
547 char *v;
548
549 if (!value)
550 return 0;
551
552 v = strdup(value);
553 if (!v)
554 return -ENOMEM;
555
556 return strv_consume(l, v);
557 }
558
559 char **strv_uniq(char **l) {
560 char **i;
561
562 /* Drops duplicate entries. The first identical string will be
563 * kept, the others dropped */
564
565 STRV_FOREACH(i, l)
566 strv_remove(i+1, *i);
567
568 return l;
569 }
570
571 bool strv_is_uniq(char **l) {
572 char **i;
573
574 STRV_FOREACH(i, l)
575 if (strv_find(i+1, *i))
576 return false;
577
578 return true;
579 }
580
581 char **strv_remove(char **l, const char *s) {
582 char **f, **t;
583
584 if (!l)
585 return NULL;
586
587 assert(s);
588
589 /* Drops every occurrence of s in the string list, edits
590 * in-place. */
591
592 for (f = t = l; *f; f++)
593 if (streq(*f, s))
594 free(*f);
595 else
596 *(t++) = *f;
597
598 *t = NULL;
599 return l;
600 }
601
602 char **strv_parse_nulstr(const char *s, size_t l) {
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 size_t n_allocated = 0, n = 0;
666 _cleanup_free_ char *m = NULL;
667 char **i;
668
669 assert(p);
670 assert(q);
671
672 STRV_FOREACH(i, l) {
673 size_t z;
674
675 z = strlen(*i);
676
677 if (!GREEDY_REALLOC(m, n_allocated, n + z + 1))
678 return -ENOMEM;
679
680 memcpy(m + n, *i, z + 1);
681 n += z + 1;
682 }
683
684 if (!m) {
685 m = new0(char, 1);
686 if (!m)
687 return -ENOMEM;
688 n = 0;
689 }
690
691 *p = m;
692 *q = n;
693
694 m = NULL;
695
696 return 0;
697 }
698
699 bool strv_overlap(char **a, char **b) {
700 char **i;
701
702 STRV_FOREACH(i, a)
703 if (strv_contains(b, *i))
704 return true;
705
706 return false;
707 }
708
709 static int str_compare(const void *_a, const void *_b) {
710 const char **a = (const char**) _a, **b = (const char**) _b;
711
712 return strcmp(*a, *b);
713 }
714
715 char **strv_sort(char **l) {
716
717 if (strv_isempty(l))
718 return l;
719
720 qsort(l, strv_length(l), sizeof(char*), str_compare);
721 return l;
722 }
723
724 bool strv_equal(char **a, char **b) {
725
726 if (strv_isempty(a))
727 return strv_isempty(b);
728
729 if (strv_isempty(b))
730 return false;
731
732 for ( ; *a || *b; ++a, ++b)
733 if (!streq_ptr(*a, *b))
734 return false;
735
736 return true;
737 }
738
739 void strv_print(char **l) {
740 char **s;
741
742 STRV_FOREACH(s, l)
743 puts(*s);
744 }
745
746 int strv_extendf(char ***l, const char *format, ...) {
747 va_list ap;
748 char *x;
749 int r;
750
751 va_start(ap, format);
752 r = vasprintf(&x, format, ap);
753 va_end(ap);
754
755 if (r < 0)
756 return -ENOMEM;
757
758 return strv_consume(l, x);
759 }
760
761 char **strv_reverse(char **l) {
762 unsigned n, i;
763
764 n = strv_length(l);
765 if (n <= 1)
766 return l;
767
768 for (i = 0; i < n / 2; i++) {
769 char *t;
770
771 t = l[i];
772 l[i] = l[n-1-i];
773 l[n-1-i] = t;
774 }
775
776 return l;
777 }
778
779 char **strv_shell_escape(char **l, const char *bad) {
780 char **s;
781
782 /* Escapes every character in every string in l that is in bad,
783 * edits in-place, does not roll-back on error. */
784
785 STRV_FOREACH(s, l) {
786 char *v;
787
788 v = shell_escape(*s, bad);
789 if (!v)
790 return NULL;
791
792 free(*s);
793 *s = v;
794 }
795
796 return l;
797 }
798
799 bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
800 char* const* p;
801
802 STRV_FOREACH(p, patterns)
803 if (fnmatch(*p, s, 0) == 0)
804 return true;
805
806 return false;
807 }
808
809 char ***strv_free_free(char ***l) {
810 char ***i;
811
812 if (!l)
813 return NULL;
814
815 for (i = l; *i; i++)
816 strv_free(*i);
817
818 free(l);
819 return NULL;
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 value n times to l */
846
847 k = strv_length(*l);
848
849 nl = realloc(*l, sizeof(char*) * (k + n + 1));
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 }