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