]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/strv.c
Merge pull request #3572 from poettering/machinectl-shell-fix
[thirdparty/systemd.git] / src / basic / strv.c
CommitLineData
a7334b09
LP
1/***
2 This file is part of systemd.
3
4 Copyright 2010 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
a7334b09
LP
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 14 Lesser General Public License for more details.
a7334b09 15
5430f7f2 16 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18***/
19
07630cea 20#include <errno.h>
11c3a366 21#include <fnmatch.h>
60918275 22#include <stdarg.h>
11c3a366 23#include <stdio.h>
07630cea 24#include <stdlib.h>
60918275
LP
25#include <string.h>
26
b5efdb8a 27#include "alloc-util.h"
4f5dd394 28#include "escape.h"
11c3a366 29#include "extract-word.h"
d390f8ef 30#include "fileio.h"
07630cea 31#include "string-util.h"
60918275 32#include "strv.h"
cf0fbc49 33#include "util.h"
60918275
LP
34
35char *strv_find(char **l, const char *name) {
5f9a22c3
LP
36 char **i;
37
60918275
LP
38 assert(name);
39
5f9a22c3
LP
40 STRV_FOREACH(i, l)
41 if (streq(*i, name))
42 return *i;
60918275
LP
43
44 return NULL;
45}
46
a4bfb399
LP
47char *strv_find_prefix(char **l, const char *name) {
48 char **i;
49
50 assert(name);
51
52 STRV_FOREACH(i, l)
53 if (startswith(*i, name))
54 return *i;
55
56 return NULL;
57}
58
28849dba
LP
59char *strv_find_startswith(char **l, const char *name) {
60 char **i, *e;
61
62 assert(name);
63
64 /* Like strv_find_prefix, but actually returns only the
65 * suffix, not the whole item */
66
67 STRV_FOREACH(i, l) {
68 e = startswith(*i, name);
69 if (e)
70 return e;
71 }
72
73 return NULL;
74}
75
dd9c7723 76void strv_clear(char **l) {
60918275
LP
77 char **k;
78
79 if (!l)
80 return;
81
82 for (k = l; *k; k++)
83 free(*k);
84
dd9c7723
TG
85 *l = NULL;
86}
87
33c2ce7b 88char **strv_free(char **l) {
dd9c7723 89 strv_clear(l);
60918275 90 free(l);
33c2ce7b 91 return NULL;
60918275
LP
92}
93
ab84f5b9
ZJS
94char **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
2fd9ae2e 103char **strv_copy(char * const *l) {
60918275
LP
104 char **r, **k;
105
1fd8d04e
LP
106 k = r = new(char*, strv_length(l) + 1);
107 if (!r)
60918275
LP
108 return NULL;
109
ede27aab 110 if (l)
1fd8d04e
LP
111 for (; *l; k++, l++) {
112 *k = strdup(*l);
113 if (!*k) {
114 strv_free(r);
115 return NULL;
116 }
117 }
60918275
LP
118
119 *k = NULL;
120 return r;
60918275
LP
121}
122
2fd9ae2e 123unsigned strv_length(char * const *l) {
60918275
LP
124 unsigned n = 0;
125
126 if (!l)
127 return 0;
128
129 for (; *l; l++)
130 n++;
131
132 return n;
133}
134
257eca1a 135char **strv_new_ap(const char *x, va_list ap) {
60918275
LP
136 const char *s;
137 char **a;
138 unsigned n = 0, i = 0;
257eca1a
LP
139 va_list aq;
140
07719a21
LP
141 /* As a special trick we ignore all listed strings that equal
142 * (const char*) -1. This is supposed to be used with the
143 * STRV_IFNOTNULL() macro to include possibly NULL strings in
144 * the string list. */
145
60918275 146 if (x) {
07719a21 147 n = x == (const char*) -1 ? 0 : 1;
60918275 148
257eca1a 149 va_copy(aq, ap);
07719a21
LP
150 while ((s = va_arg(aq, const char*))) {
151 if (s == (const char*) -1)
152 continue;
153
60918275 154 n++;
07719a21
LP
155 }
156
257eca1a 157 va_end(aq);
60918275
LP
158 }
159
07719a21
LP
160 a = new(char*, n+1);
161 if (!a)
60918275
LP
162 return NULL;
163
164 if (x) {
07719a21
LP
165 if (x != (const char*) -1) {
166 a[i] = strdup(x);
167 if (!a[i])
168 goto fail;
169 i++;
60918275
LP
170 }
171
60918275 172 while ((s = va_arg(ap, const char*))) {
07719a21
LP
173
174 if (s == (const char*) -1)
175 continue;
176
177 a[i] = strdup(s);
178 if (!a[i])
60918275
LP
179 goto fail;
180
181 i++;
182 }
60918275
LP
183 }
184
185 a[i] = NULL;
257eca1a 186
60918275
LP
187 return a;
188
189fail:
1fd8d04e 190 strv_free(a);
60918275
LP
191 return NULL;
192}
034c6ed7 193
257eca1a
LP
194char **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
e287086b
LP
205int 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;
07719a21 223
e3e45d4f 224 STRV_FOREACH(s, b) {
e287086b
LP
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;
07719a21 235 }
034c6ed7 236
e287086b
LP
237 assert(i <= q);
238
239 return (int) i;
240
241rollback:
242 for (j = 0; j < i; j++)
243 free(t[p + j]);
244
245 t[p] = NULL;
246 return -ENOMEM;
5f9a22c3
LP
247}
248
e3e45d4f
SP
249int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
250 int r;
251 char **s;
5f9a22c3 252
e3e45d4f
SP
253 STRV_FOREACH(s, b) {
254 char *v;
5f9a22c3 255
e3e45d4f
SP
256 v = strappend(*s, suffix);
257 if (!v)
258 return -ENOMEM;
5f9a22c3 259
e3e45d4f
SP
260 r = strv_push(a, v);
261 if (r < 0) {
262 free(v);
263 return r;
8ea913b2 264 }
8ea913b2 265 }
5f9a22c3 266
e3e45d4f 267 return 0;
5f9a22c3
LP
268}
269
270char **strv_split(const char *s, const char *separator) {
a2a5291b 271 const char *word, *state;
5f9a22c3
LP
272 size_t l;
273 unsigned n, i;
274 char **r;
275
276 assert(s);
277
278 n = 0;
a2a5291b 279 FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
5f9a22c3
LP
280 n++;
281
1fd8d04e
LP
282 r = new(char*, n+1);
283 if (!r)
5f9a22c3
LP
284 return NULL;
285
286 i = 0;
a2a5291b
ZJS
287 FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
288 r[i] = strndup(word, l);
1fd8d04e 289 if (!r[i]) {
5f9a22c3
LP
290 strv_free(r);
291 return NULL;
292 }
293
1fd8d04e
LP
294 i++;
295 }
296
5f9a22c3
LP
297 r[i] = NULL;
298 return r;
299}
300
26d04f86
LP
301char **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
ece174c5 318 if (isempty(l[n - 1]))
a1e58e8e 319 l[n - 1] = mfree(l[n - 1]);
26d04f86
LP
320
321 return l;
322}
323
8adaf7bd 324int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
f88e6be5 325 _cleanup_strv_free_ char **l = NULL;
8dd4c05b 326 size_t n = 0, allocated = 0;
f88e6be5
LP
327 int r;
328
329 assert(t);
330 assert(s);
331
332 for (;;) {
333 _cleanup_free_ char *word = NULL;
334
8adaf7bd 335 r = extract_first_word(&s, &word, separators, flags);
f88e6be5
LP
336 if (r < 0)
337 return r;
ece174c5 338 if (r == 0)
f88e6be5
LP
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
8dd4c05b 350 if (!l) {
f88e6be5 351 l = new0(char*, 1);
8dd4c05b
LP
352 if (!l)
353 return -ENOMEM;
354 }
f88e6be5
LP
355
356 *t = l;
357 l = NULL;
358
8dd4c05b 359 return (int) n;
f88e6be5
LP
360}
361
5f9a22c3
LP
362char *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) {
afe773b0 374 if (s != l)
5f9a22c3
LP
375 n += k;
376 n += strlen(*s);
377 }
378
1fd8d04e
LP
379 r = new(char, n+1);
380 if (!r)
5f9a22c3
LP
381 return NULL;
382
383 e = r;
384 STRV_FOREACH(s, l) {
afe773b0 385 if (s != l)
5f9a22c3
LP
386 e = stpcpy(e, separator);
387
388 e = stpcpy(e, *s);
389 }
390
8d49745c
LP
391 *e = 0;
392
5f9a22c3
LP
393 return r;
394}
395
a6fde353
ZJS
396char *strv_join_quoted(char **l) {
397 char *buf = NULL;
398 char **s;
399 size_t allocated = 0, len = 0;
400
401 STRV_FOREACH(s, l) {
402 /* assuming here that escaped string cannot be more
403 * than twice as long, and reserving space for the
404 * separator and quotes.
405 */
406 _cleanup_free_ char *esc = NULL;
407 size_t needed;
408
409 if (!GREEDY_REALLOC(buf, allocated,
410 len + strlen(*s) * 2 + 3))
411 goto oom;
412
413 esc = cescape(*s);
414 if (!esc)
415 goto oom;
416
417 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
418 len > 0 ? " " : "", esc);
419 assert(needed < allocated - len);
420 len += needed;
421 }
422
423 if (!buf)
424 buf = malloc0(1);
425
426 return buf;
427
428 oom:
429 free(buf);
430 return NULL;
431}
432
4468addc 433int strv_push(char ***l, char *value) {
5926ccca 434 char **c;
97569e15 435 unsigned n, m;
5926ccca
LP
436
437 if (!value)
438 return 0;
439
82dde599 440 n = strv_length(*l);
97569e15 441
98940a3c 442 /* Increase and check for overflow */
97569e15
LP
443 m = n + 2;
444 if (m < n)
445 return -ENOMEM;
446
14f27b4e 447 c = realloc_multiply(*l, sizeof(char*), m);
4468addc 448 if (!c)
82dde599 449 return -ENOMEM;
82dde599 450
4468addc 451 c[n] = value;
82dde599
LP
452 c[n+1] = NULL;
453
5926ccca
LP
454 *l = c;
455 return 0;
456}
457
98940a3c
LP
458int strv_push_pair(char ***l, char *a, char *b) {
459 char **c;
460 unsigned n, m;
461
462 if (!a && !b)
463 return 0;
464
465 n = strv_length(*l);
466
467 /* increase and check for overflow */
468 m = n + !!a + !!b + 1;
469 if (m < n)
470 return -ENOMEM;
471
472 c = realloc_multiply(*l, sizeof(char*), m);
473 if (!c)
474 return -ENOMEM;
475
476 if (a)
477 c[n++] = a;
478 if (b)
479 c[n++] = b;
480 c[n] = NULL;
481
482 *l = c;
483 return 0;
484}
485
9a00f57a
LP
486int strv_push_prepend(char ***l, char *value) {
487 char **c;
97569e15 488 unsigned n, m, i;
9a00f57a
LP
489
490 if (!value)
491 return 0;
492
493 n = strv_length(*l);
97569e15
LP
494
495 /* increase and check for overflow */
496 m = n + 2;
497 if (m < n)
498 return -ENOMEM;
499
500 c = new(char*, m);
9a00f57a
LP
501 if (!c)
502 return -ENOMEM;
503
504 for (i = 0; i < n; i++)
505 c[i+1] = (*l)[i];
506
507 c[0] = value;
508 c[n+1] = NULL;
509
510 free(*l);
511 *l = c;
512
513 return 0;
514}
515
6e18964d
ZJS
516int strv_consume(char ***l, char *value) {
517 int r;
518
519 r = strv_push(l, value);
520 if (r < 0)
521 free(value);
522
9a00f57a
LP
523 return r;
524}
525
98940a3c
LP
526int strv_consume_pair(char ***l, char *a, char *b) {
527 int r;
528
529 r = strv_push_pair(l, a, b);
530 if (r < 0) {
531 free(a);
532 free(b);
533 }
534
535 return r;
536}
537
9a00f57a
LP
538int strv_consume_prepend(char ***l, char *value) {
539 int r;
540
541 r = strv_push_prepend(l, value);
542 if (r < 0)
543 free(value);
544
6e18964d
ZJS
545 return r;
546}
547
4468addc
LP
548int strv_extend(char ***l, const char *value) {
549 char *v;
4468addc
LP
550
551 if (!value)
552 return 0;
553
554 v = strdup(value);
555 if (!v)
556 return -ENOMEM;
557
6e18964d 558 return strv_consume(l, v);
4468addc
LP
559}
560
4f4afc88
LP
561int strv_extend_front(char ***l, const char *value) {
562 size_t n, m;
563 char *v, **c;
564
565 assert(l);
566
567 /* Like strv_extend(), but prepends rather than appends the new entry */
568
569 if (!value)
570 return 0;
571
572 n = strv_length(*l);
573
574 /* Increase and overflow check. */
575 m = n + 2;
576 if (m < n)
577 return -ENOMEM;
578
579 v = strdup(value);
580 if (!v)
581 return -ENOMEM;
582
583 c = realloc_multiply(*l, sizeof(char*), m);
584 if (!c) {
585 free(v);
586 return -ENOMEM;
587 }
588
589 memmove(c+1, c, n * sizeof(char*));
590 c[0] = v;
591 c[n+1] = NULL;
592
593 *l = c;
594 return 0;
595}
596
5f9a22c3 597char **strv_uniq(char **l) {
cba8922f
LP
598 char **i;
599
5f9a22c3
LP
600 /* Drops duplicate entries. The first identical string will be
601 * kept, the others dropped */
602
cba8922f 603 STRV_FOREACH(i, l)
5f9a22c3
LP
604 strv_remove(i+1, *i);
605
606 return l;
607}
608
e1dd6790
LP
609bool strv_is_uniq(char **l) {
610 char **i;
611
612 STRV_FOREACH(i, l)
613 if (strv_find(i+1, *i))
614 return false;
615
616 return true;
617}
618
5f9a22c3
LP
619char **strv_remove(char **l, const char *s) {
620 char **f, **t;
621
622 if (!l)
623 return NULL;
624
5d6ab905
LP
625 assert(s);
626
627 /* Drops every occurrence of s in the string list, edits
628 * in-place. */
5f9a22c3 629
e3e45d4f
SP
630 for (f = t = l; *f; f++)
631 if (streq(*f, s))
71ecc858 632 free(*f);
e3e45d4f
SP
633 else
634 *(t++) = *f;
71ecc858
LP
635
636 *t = NULL;
637 return l;
638}
639
21bc923a
LP
640char **strv_parse_nulstr(const char *s, size_t l) {
641 const char *p;
642 unsigned c = 0, i = 0;
643 char **v;
644
645 assert(s || l <= 0);
646
647 if (l <= 0)
49b832c5 648 return new0(char*, 1);
21bc923a
LP
649
650 for (p = s; p < s + l; p++)
651 if (*p == 0)
652 c++;
653
654 if (s[l-1] != 0)
655 c++;
656
1fd8d04e
LP
657 v = new0(char*, c+1);
658 if (!v)
21bc923a
LP
659 return NULL;
660
661 p = s;
662 while (p < s + l) {
663 const char *e;
664
665 e = memchr(p, 0, s + l - p);
666
1fd8d04e
LP
667 v[i] = strndup(p, e ? e - p : s + l - p);
668 if (!v[i]) {
21bc923a
LP
669 strv_free(v);
670 return NULL;
671 }
672
1fd8d04e
LP
673 i++;
674
21bc923a
LP
675 if (!e)
676 break;
677
678 p = e + 1;
679 }
680
681 assert(i == c);
682
683 return v;
684}
0c85a4f3 685
fabe5c0e
LP
686char **strv_split_nulstr(const char *s) {
687 const char *i;
688 char **r = NULL;
689
690 NULSTR_FOREACH(i, s)
691 if (strv_extend(&r, i) < 0) {
692 strv_free(r);
693 return NULL;
694 }
695
696 if (!r)
697 return strv_new(NULL, NULL);
698
699 return r;
700}
701
e287086b
LP
702int strv_make_nulstr(char **l, char **p, size_t *q) {
703 size_t n_allocated = 0, n = 0;
704 _cleanup_free_ char *m = NULL;
705 char **i;
706
707 assert(p);
708 assert(q);
709
710 STRV_FOREACH(i, l) {
711 size_t z;
712
713 z = strlen(*i);
714
715 if (!GREEDY_REALLOC(m, n_allocated, n + z + 1))
716 return -ENOMEM;
717
718 memcpy(m + n, *i, z + 1);
719 n += z + 1;
720 }
721
722 if (!m) {
723 m = new0(char, 1);
724 if (!m)
725 return -ENOMEM;
726 n = 0;
727 }
728
729 *p = m;
730 *q = n;
731
732 m = NULL;
733
734 return 0;
735}
736
0c85a4f3 737bool strv_overlap(char **a, char **b) {
e3e45d4f 738 char **i;
0c85a4f3 739
e3e45d4f
SP
740 STRV_FOREACH(i, a)
741 if (strv_contains(b, *i))
742 return true;
0c85a4f3
LP
743
744 return false;
745}
857a493d
LP
746
747static int str_compare(const void *_a, const void *_b) {
748 const char **a = (const char**) _a, **b = (const char**) _b;
749
750 return strcmp(*a, *b);
751}
752
753char **strv_sort(char **l) {
754
755 if (strv_isempty(l))
756 return l;
757
758 qsort(l, strv_length(l), sizeof(char*), str_compare);
759 return l;
760}
7c2d8094 761
0f84a72e 762bool strv_equal(char **a, char **b) {
e287086b
LP
763
764 if (strv_isempty(a))
765 return strv_isempty(b);
766
767 if (strv_isempty(b))
768 return false;
0f84a72e
DH
769
770 for ( ; *a || *b; ++a, ++b)
771 if (!streq_ptr(*a, *b))
772 return false;
773
774 return true;
775}
776
7c2d8094
TA
777void strv_print(char **l) {
778 char **s;
779
7c2d8094
TA
780 STRV_FOREACH(s, l)
781 puts(*s);
782}
4de33e7f
LP
783
784int strv_extendf(char ***l, const char *format, ...) {
785 va_list ap;
786 char *x;
787 int r;
788
789 va_start(ap, format);
790 r = vasprintf(&x, format, ap);
791 va_end(ap);
792
793 if (r < 0)
794 return -ENOMEM;
795
796 return strv_consume(l, x);
797}
e1dd6790
LP
798
799char **strv_reverse(char **l) {
800 unsigned n, i;
801
802 n = strv_length(l);
803 if (n <= 1)
804 return l;
805
806 for (i = 0; i < n / 2; i++) {
8a3134b2 807 SWAP_TWO(l[i], l[n-1-i]);
e1dd6790
LP
808 }
809
810 return l;
811}
bceccd5e 812
04c14b25
RM
813char **strv_shell_escape(char **l, const char *bad) {
814 char **s;
815
816 /* Escapes every character in every string in l that is in bad,
817 * edits in-place, does not roll-back on error. */
818
819 STRV_FOREACH(s, l) {
820 char *v;
821
822 v = shell_escape(*s, bad);
823 if (!v)
824 return NULL;
825
826 free(*s);
827 *s = v;
828 }
829
830 return l;
831}
832
2404701e 833bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
bceccd5e
ZJS
834 char* const* p;
835
836 STRV_FOREACH(p, patterns)
837 if (fnmatch(*p, s, 0) == 0)
838 return true;
839
840 return false;
841}
fe382237
LP
842
843char ***strv_free_free(char ***l) {
844 char ***i;
845
846 if (!l)
847 return NULL;
848
849 for (i = l; *i; i++)
850 strv_free(*i);
851
852 free(l);
853 return NULL;
854}
e3ead6bb
LP
855
856char **strv_skip(char **l, size_t n) {
857
858 while (n > 0) {
859 if (strv_isempty(l))
860 return l;
861
862 l++, n--;
863 }
864
865 return l;
866}
8dd4c05b
LP
867
868int strv_extend_n(char ***l, const char *value, size_t n) {
869 size_t i, j, k;
870 char **nl;
871
872 assert(l);
873
874 if (!value)
875 return 0;
876 if (n == 0)
877 return 0;
878
879 /* Adds the value value n times to l */
880
881 k = strv_length(*l);
882
883 nl = realloc(*l, sizeof(char*) * (k + n + 1));
884 if (!nl)
885 return -ENOMEM;
886
887 *l = nl;
888
889 for (i = k; i < k + n; i++) {
890 nl[i] = strdup(value);
891 if (!nl[i])
892 goto rollback;
893 }
894
895 nl[i] = NULL;
896 return 0;
897
898rollback:
6fff8ac4 899 for (j = k; j < i; j++)
8dd4c05b
LP
900 free(nl[j]);
901
902 nl[k] = NULL;
5b700370 903 return -ENOMEM;
8dd4c05b 904}
3df9bec5
LP
905
906int fputstrv(FILE *f, char **l, const char *separator, bool *space) {
907 bool b = false;
908 char **s;
909 int r;
910
911 /* Like fputs(), but for strv, and with a less stupid argument order */
912
3df9bec5
LP
913 if (!space)
914 space = &b;
915
916 STRV_FOREACH(s, l) {
d390f8ef 917 r = fputs_with_space(f, *s, separator, space);
3df9bec5
LP
918 if (r < 0)
919 return r;
3df9bec5
LP
920 }
921
922 return 0;
923}