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/>.
29 #include "alloc-util.h"
31 #include "extract-word.h"
32 #include "string-util.h"
36 char *strv_find(char **l, const char *name) {
48 char *strv_find_prefix(char **l, const char *name) {
54 if (startswith(*i, name))
60 char *strv_find_startswith(char **l, const char *name) {
65 /* Like strv_find_prefix, but actually returns only the
66 * suffix, not the whole item */
69 e = startswith(*i, name);
77 void strv_clear(char **l) {
89 char **strv_free(char **l) {
95 char **strv_free_erase(char **l) {
104 char **strv_copy(char * const *l) {
107 k = r = new(char*, strv_length(l) + 1);
112 for (; *l; k++, l++) {
124 unsigned strv_length(char * const *l) {
136 char **strv_new_ap(const char *x, va_list ap) {
139 unsigned n = 0, i = 0;
142 /* As a special trick we ignore all listed strings that equal
143 * (const char*) -1. This is supposed to be used with the
144 * STRV_IFNOTNULL() macro to include possibly NULL strings in
145 * the string list. */
148 n = x == (const char*) -1 ? 0 : 1;
151 while ((s = va_arg(aq, const char*))) {
152 if (s == (const char*) -1)
166 if (x != (const char*) -1) {
173 while ((s = va_arg(ap, const char*))) {
175 if (s == (const char*) -1)
195 char **strv_new(const char *x, ...) {
200 r = strv_new_ap(x, ap);
206 #if 0 /// UNNEEDED by elogind
207 int strv_extend_strv(char ***a, char **b, bool filter_duplicates) {
209 size_t p, q, i = 0, j;
219 t = realloc(*a, sizeof(char*) * (p + q + 1));
228 if (filter_duplicates && strv_contains(t, *s))
244 for (j = 0; j < i; j++)
251 int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
258 v = strappend(*s, suffix);
273 char **strv_split(const char *s, const char *separator) {
274 const char *word, *state;
282 FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
290 FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
291 r[i] = strndup(word, l);
304 #if 0 /// UNNEEDED by elogind
305 char **strv_split_newlines(const char *s) {
311 /* Special version of strv_split() that splits on newlines and
312 * suppresses an empty string at the end */
314 l = strv_split(s, NEWLINE);
322 if (isempty(l[n - 1]))
323 l[n-1] = mfree(l[n-1]);
328 int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
329 _cleanup_strv_free_ char **l = NULL;
330 size_t n = 0, allocated = 0;
337 _cleanup_free_ char *word = NULL;
339 r = extract_first_word(&s, &word, separators, flags);
345 if (!GREEDY_REALLOC(l, allocated, n + 2))
367 char *strv_join(char **l, const char *separator) {
375 k = strlen(separator);
391 e = stpcpy(e, separator);
401 #if 0 /// 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 #if 0 /// UNNEEDED by elogind
534 int strv_consume_pair(char ***l, char *a, char *b) {
537 r = strv_push_pair(l, a, b);
547 int strv_consume_prepend(char ***l, char *value) {
550 r = strv_push_prepend(l, value);
557 int strv_extend(char ***l, const char *value) {
567 return strv_consume(l, v);
570 char **strv_uniq(char **l) {
573 /* Drops duplicate entries. The first identical string will be
574 * kept, the others dropped */
577 strv_remove(i+1, *i);
582 #if 0 /// UNNEEDED by elogind
583 bool strv_is_uniq(char **l) {
587 if (strv_find(i+1, *i))
594 char **strv_remove(char **l, const char *s) {
602 /* Drops every occurrence of s in the string list, edits
605 for (f = t = l; *f; f++)
615 char **strv_parse_nulstr(const char *s, size_t l) {
617 unsigned c = 0, i = 0;
623 return new0(char*, 1);
625 for (p = s; p < s + l; p++)
632 v = new0(char*, c+1);
640 e = memchr(p, 0, s + l - p);
642 v[i] = strndup(p, e ? e - p : s + l - p);
661 char **strv_split_nulstr(const char *s) {
666 if (strv_extend(&r, i) < 0) {
672 return strv_new(NULL, NULL);
677 #if 0 /// UNNEEDED by elogind
678 int strv_make_nulstr(char **l, char **p, size_t *q) {
679 size_t n_allocated = 0, n = 0;
680 _cleanup_free_ char *m = NULL;
691 if (!GREEDY_REALLOC(m, n_allocated, n + z + 1))
694 memcpy(m + n, *i, z + 1);
713 bool strv_overlap(char **a, char **b) {
717 if (strv_contains(b, *i))
724 static int str_compare(const void *_a, const void *_b) {
725 const char **a = (const char**) _a, **b = (const char**) _b;
727 return strcmp(*a, *b);
730 char **strv_sort(char **l) {
735 qsort(l, strv_length(l), sizeof(char*), str_compare);
739 #if 0 /// UNNEEDED by elogind
740 bool strv_equal(char **a, char **b) {
743 return strv_isempty(b);
748 for ( ; *a || *b; ++a, ++b)
749 if (!streq_ptr(*a, *b))
755 void strv_print(char **l) {
762 int strv_extendf(char ***l, const char *format, ...) {
767 va_start(ap, format);
768 r = vasprintf(&x, format, ap);
774 return strv_consume(l, x);
777 char **strv_reverse(char **l) {
784 for (i = 0; i < n / 2; i++) {
795 char **strv_shell_escape(char **l, const char *bad) {
798 /* Escapes every character in every string in l that is in bad,
799 * edits in-place, does not roll-back on error. */
804 v = shell_escape(*s, bad);
815 bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
818 STRV_FOREACH(p, patterns)
819 if (fnmatch(*p, s, 0) == 0)
825 char ***strv_free_free(char ***l) {
838 char **strv_skip(char **l, size_t n) {
850 int strv_extend_n(char ***l, const char *value, size_t n) {
861 /* Adds the value value n times to l */
865 nl = realloc(*l, sizeof(char*) * (k + n + 1));
871 for (i = k; i < k + n; i++) {
872 nl[i] = strdup(value);
881 for (j = k; j < i; j++)