1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
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.
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.
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/>.
27 #include "alloc-util.h"
29 #include "string-util.h"
33 char *strv_find(char **l, const char *name) {
45 char *strv_find_prefix(char **l, const char *name) {
51 if (startswith(*i, name))
57 char *strv_find_startswith(char **l, const char *name) {
62 /* Like strv_find_prefix, but actually returns only the
63 * suffix, not the whole item */
66 e = startswith(*i, name);
74 void strv_clear(char **l) {
86 char **strv_free(char **l) {
92 char **strv_free_erase(char **l) {
101 char **strv_copy(char * const *l) {
104 k = r = new(char*, strv_length(l) + 1);
109 for (; *l; k++, l++) {
121 unsigned strv_length(char * const *l) {
133 char **strv_new_ap(const char *x, va_list ap) {
136 unsigned n = 0, i = 0;
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. */
145 n = x == (const char*) -1 ? 0 : 1;
148 while ((s = va_arg(aq, const char*))) {
149 if (s == (const char*) -1)
163 if (x != (const char*) -1) {
170 while ((s = va_arg(ap, const char*))) {
172 if (s == (const char*) -1)
192 char **strv_new(const char *x, ...) {
197 r = strv_new_ap(x, ap);
203 int strv_extend_strv(char ***a, char **b, bool filter_duplicates) {
205 size_t p, q, i = 0, j;
215 t = realloc(*a, sizeof(char*) * (p + q + 1));
224 if (filter_duplicates && strv_contains(t, *s))
240 for (j = 0; j < i; j++)
247 /// UNNEEDED by elogind
249 int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
256 v = strappend(*s, suffix);
271 char **strv_split(const char *s, const char *separator) {
272 const char *word, *state;
280 FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
288 FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
289 r[i] = strndup(word, l);
302 /// UNNEEDED by elogind
304 char **strv_split_newlines(const char *s) {
310 /* Special version of strv_split() that splits on newlines and
311 * suppresses an empty string at the end */
313 l = strv_split(s, NEWLINE);
321 if (isempty(l[n - 1]))
322 l[n-1] = mfree(l[n-1]);
327 int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
328 _cleanup_strv_free_ char **l = NULL;
329 size_t n = 0, allocated = 0;
336 _cleanup_free_ char *word = NULL;
338 r = extract_first_word(&s, &word, separators, flags);
344 if (!GREEDY_REALLOC(l, allocated, n + 2))
366 char *strv_join(char **l, const char *separator) {
374 k = strlen(separator);
390 e = stpcpy(e, separator);
400 /// UNNEEDED by elogind
402 char *strv_join_quoted(char **l) {
405 size_t allocated = 0, len = 0;
408 /* assuming here that escaped string cannot be more
409 * than twice as long, and reserving space for the
410 * separator and quotes.
412 _cleanup_free_ char *esc = NULL;
415 if (!GREEDY_REALLOC(buf, allocated,
416 len + strlen(*s) * 2 + 3))
423 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
424 len > 0 ? " " : "", esc);
425 assert(needed < allocated - len);
440 int strv_push(char ***l, char *value) {
449 /* Increase and check for overflow */
454 c = realloc_multiply(*l, sizeof(char*), m);
465 int strv_push_pair(char ***l, char *a, char *b) {
474 /* increase and check for overflow */
475 m = n + !!a + !!b + 1;
479 c = realloc_multiply(*l, sizeof(char*), m);
493 int strv_push_prepend(char ***l, char *value) {
502 /* increase and check for overflow */
511 for (i = 0; i < n; i++)
523 int strv_consume(char ***l, char *value) {
526 r = strv_push(l, value);
533 /// UNNEEDED by elogind
535 int strv_consume_pair(char ***l, char *a, char *b) {
538 r = strv_push_pair(l, a, b);
548 int strv_consume_prepend(char ***l, char *value) {
551 r = strv_push_prepend(l, value);
558 int strv_extend(char ***l, const char *value) {
568 return strv_consume(l, v);
571 char **strv_uniq(char **l) {
574 /* Drops duplicate entries. The first identical string will be
575 * kept, the others dropped */
578 strv_remove(i+1, *i);
583 /// UNNEEDED by elogind
585 bool strv_is_uniq(char **l) {
589 if (strv_find(i+1, *i))
596 char **strv_remove(char **l, const char *s) {
604 /* Drops every occurrence of s in the string list, edits
607 for (f = t = l; *f; f++)
617 char **strv_parse_nulstr(const char *s, size_t l) {
619 unsigned c = 0, i = 0;
625 return new0(char*, 1);
627 for (p = s; p < s + l; p++)
634 v = new0(char*, c+1);
642 e = memchr(p, 0, s + l - p);
644 v[i] = strndup(p, e ? e - p : s + l - p);
663 char **strv_split_nulstr(const char *s) {
668 if (strv_extend(&r, i) < 0) {
674 return strv_new(NULL, NULL);
679 /// UNNEEDED by elogind
681 int strv_make_nulstr(char **l, char **p, size_t *q) {
682 size_t n_allocated = 0, n = 0;
683 _cleanup_free_ char *m = NULL;
694 if (!GREEDY_REALLOC(m, n_allocated, n + z + 1))
697 memcpy(m + n, *i, z + 1);
716 bool strv_overlap(char **a, char **b) {
720 if (strv_contains(b, *i))
727 static int str_compare(const void *_a, const void *_b) {
728 const char **a = (const char**) _a, **b = (const char**) _b;
730 return strcmp(*a, *b);
733 char **strv_sort(char **l) {
738 qsort(l, strv_length(l), sizeof(char*), str_compare);
742 /// UNNEEDED by elogind
744 bool strv_equal(char **a, char **b) {
747 return strv_isempty(b);
752 for ( ; *a || *b; ++a, ++b)
753 if (!streq_ptr(*a, *b))
759 void strv_print(char **l) {
766 int strv_extendf(char ***l, const char *format, ...) {
771 va_start(ap, format);
772 r = vasprintf(&x, format, ap);
778 return strv_consume(l, x);
781 char **strv_reverse(char **l) {
788 for (i = 0; i < n / 2; i++) {
799 char **strv_shell_escape(char **l, const char *bad) {
802 /* Escapes every character in every string in l that is in bad,
803 * edits in-place, does not roll-back on error. */
808 v = shell_escape(*s, bad);
819 bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
822 STRV_FOREACH(p, patterns)
823 if (fnmatch(*p, s, 0) == 0)
829 char ***strv_free_free(char ***l) {
842 char **strv_skip(char **l, size_t n) {
854 int strv_extend_n(char ***l, const char *value, size_t n) {
865 /* Adds the value value n times to l */
869 nl = realloc(*l, sizeof(char*) * (k + n + 1));
875 for (i = k; i < k + n; i++) {
876 nl[i] = strdup(value);
885 for (j = k; j < i; j++)