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/>.
30 char *strv_find(char **l, const char *name) {
42 char *strv_find_prefix(char **l, const char *name) {
48 if (startswith(*i, name))
54 char *strv_find_startswith(char **l, const char *name) {
59 /* Like strv_find_prefix, but actually returns only the
60 * suffix, not the whole item */
63 e = startswith(*i, name);
71 void strv_clear(char **l) {
83 char **strv_free(char **l) {
89 char **strv_copy(char * const *l) {
92 k = r = new(char*, strv_length(l) + 1);
97 for (; *l; k++, l++) {
109 unsigned strv_length(char * const *l) {
121 char **strv_new_ap(const char *x, va_list ap) {
124 unsigned n = 0, i = 0;
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. */
133 n = x == (const char*) -1 ? 0 : 1;
136 while ((s = va_arg(aq, const char*))) {
137 if (s == (const char*) -1)
151 if (x != (const char*) -1) {
158 while ((s = va_arg(ap, const char*))) {
160 if (s == (const char*) -1)
180 char **strv_new(const char *x, ...) {
185 r = strv_new_ap(x, ap);
191 int strv_extend_strv(char ***a, char **b, bool filter_duplicates) {
193 size_t p, q, i = 0, j;
203 t = realloc(*a, sizeof(char*) * (p + q + 1));
212 if (filter_duplicates && strv_contains(t, *s))
228 for (j = 0; j < i; j++)
235 /// UNNEEDED by elogind
237 int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
244 v = strappend(*s, suffix);
259 char **strv_split(const char *s, const char *separator) {
260 const char *word, *state;
268 FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
276 FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
277 r[i] = strndup(word, l);
290 /// UNNEEDED by elogind
292 char **strv_split_newlines(const char *s) {
298 /* Special version of strv_split() that splits on newlines and
299 * suppresses an empty string at the end */
301 l = strv_split(s, NEWLINE);
309 if (isempty(l[n - 1]))
310 l[n-1] = mfree(l[n-1]);
315 int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
316 _cleanup_strv_free_ char **l = NULL;
317 size_t n = 0, allocated = 0;
324 _cleanup_free_ char *word = NULL;
326 r = extract_first_word(&s, &word, separators, flags);
332 if (!GREEDY_REALLOC(l, allocated, n + 2))
354 char *strv_join(char **l, const char *separator) {
362 k = strlen(separator);
378 e = stpcpy(e, separator);
388 /// UNNEEDED by elogind
390 char *strv_join_quoted(char **l) {
393 size_t allocated = 0, len = 0;
396 /* assuming here that escaped string cannot be more
397 * than twice as long, and reserving space for the
398 * separator and quotes.
400 _cleanup_free_ char *esc = NULL;
403 if (!GREEDY_REALLOC(buf, allocated,
404 len + strlen(*s) * 2 + 3))
411 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
412 len > 0 ? " " : "", esc);
413 assert(needed < allocated - len);
428 int strv_push(char ***l, char *value) {
437 /* Increase and check for overflow */
442 c = realloc_multiply(*l, sizeof(char*), m);
453 int strv_push_pair(char ***l, char *a, char *b) {
462 /* increase and check for overflow */
463 m = n + !!a + !!b + 1;
467 c = realloc_multiply(*l, sizeof(char*), m);
481 int strv_push_prepend(char ***l, char *value) {
490 /* increase and check for overflow */
499 for (i = 0; i < n; i++)
511 int strv_consume(char ***l, char *value) {
514 r = strv_push(l, value);
521 /// UNNEEDED by elogind
523 int strv_consume_pair(char ***l, char *a, char *b) {
526 r = strv_push_pair(l, a, b);
536 int strv_consume_prepend(char ***l, char *value) {
539 r = strv_push_prepend(l, value);
546 int strv_extend(char ***l, const char *value) {
556 return strv_consume(l, v);
559 char **strv_uniq(char **l) {
562 /* Drops duplicate entries. The first identical string will be
563 * kept, the others dropped */
566 strv_remove(i+1, *i);
571 /// UNNEEDED by elogind
573 bool strv_is_uniq(char **l) {
577 if (strv_find(i+1, *i))
584 char **strv_remove(char **l, const char *s) {
592 /* Drops every occurrence of s in the string list, edits
595 for (f = t = l; *f; f++)
605 char **strv_parse_nulstr(const char *s, size_t l) {
607 unsigned c = 0, i = 0;
613 return new0(char*, 1);
615 for (p = s; p < s + l; p++)
622 v = new0(char*, c+1);
630 e = memchr(p, 0, s + l - p);
632 v[i] = strndup(p, e ? e - p : s + l - p);
651 char **strv_split_nulstr(const char *s) {
656 if (strv_extend(&r, i) < 0) {
662 return strv_new(NULL, NULL);
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;
680 if (!GREEDY_REALLOC(m, n_allocated, n + z + 1))
683 memcpy(m + n, *i, z + 1);
702 /// UNNEEDED by elogind
704 bool strv_overlap(char **a, char **b) {
708 if (strv_contains(b, *i))
714 static int str_compare(const void *_a, const void *_b) {
715 const char **a = (const char**) _a, **b = (const char**) _b;
717 return strcmp(*a, *b);
720 char **strv_sort(char **l) {
725 qsort(l, strv_length(l), sizeof(char*), str_compare);
729 bool strv_equal(char **a, char **b) {
732 return strv_isempty(b);
737 for ( ; *a || *b; ++a, ++b)
738 if (!streq_ptr(*a, *b))
744 void strv_print(char **l) {
751 int strv_extendf(char ***l, const char *format, ...) {
756 va_start(ap, format);
757 r = vasprintf(&x, format, ap);
763 return strv_consume(l, x);
766 char **strv_reverse(char **l) {
773 for (i = 0; i < n / 2; i++) {
784 char **strv_shell_escape(char **l, const char *bad) {
787 /* Escapes every character in every string in l that is in bad,
788 * edits in-place, does not roll-back on error. */
793 v = shell_escape(*s, bad);
805 bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
808 STRV_FOREACH(p, patterns)
809 if (fnmatch(*p, s, 0) == 0)
815 char ***strv_free_free(char ***l) {
828 char **strv_skip(char **l, size_t n) {
840 int strv_extend_n(char ***l, const char *value, size_t n) {
851 /* Adds the value value n times to l */
855 nl = realloc(*l, sizeof(char*) * (k + n + 1));
861 for (i = k; i < k + n; i++) {
862 nl[i] = strdup(value);
871 for (j = k; j < i; j++)