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 #if 0 /// UNNEEDED by elogind
204 int strv_extend_strv(char ***a, char **b, bool filter_duplicates) {
206 size_t p, q, i = 0, j;
216 t = realloc(*a, sizeof(char*) * (p + q + 1));
225 if (filter_duplicates && strv_contains(t, *s))
241 for (j = 0; j < i; j++)
248 int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
255 v = strappend(*s, suffix);
270 char **strv_split(const char *s, const char *separator) {
271 const char *word, *state;
279 FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
287 FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
288 r[i] = strndup(word, l);
301 #if 0 /// UNNEEDED by elogind
302 char **strv_split_newlines(const char *s) {
308 /* Special version of strv_split() that splits on newlines and
309 * suppresses an empty string at the end */
311 l = strv_split(s, NEWLINE);
319 if (isempty(l[n - 1]))
320 l[n-1] = mfree(l[n-1]);
325 int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
326 _cleanup_strv_free_ char **l = NULL;
327 size_t n = 0, allocated = 0;
334 _cleanup_free_ char *word = NULL;
336 r = extract_first_word(&s, &word, separators, flags);
342 if (!GREEDY_REALLOC(l, allocated, n + 2))
364 char *strv_join(char **l, const char *separator) {
372 k = strlen(separator);
388 e = stpcpy(e, separator);
398 #if 0 /// UNNEEDED by elogind
399 char *strv_join_quoted(char **l) {
402 size_t allocated = 0, len = 0;
405 /* assuming here that escaped string cannot be more
406 * than twice as long, and reserving space for the
407 * separator and quotes.
409 _cleanup_free_ char *esc = NULL;
412 if (!GREEDY_REALLOC(buf, allocated,
413 len + strlen(*s) * 2 + 3))
420 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
421 len > 0 ? " " : "", esc);
422 assert(needed < allocated - len);
437 int strv_push(char ***l, char *value) {
446 /* Increase and check for overflow */
451 c = realloc_multiply(*l, sizeof(char*), m);
462 int strv_push_pair(char ***l, char *a, char *b) {
471 /* increase and check for overflow */
472 m = n + !!a + !!b + 1;
476 c = realloc_multiply(*l, sizeof(char*), m);
490 int strv_push_prepend(char ***l, char *value) {
499 /* increase and check for overflow */
508 for (i = 0; i < n; i++)
520 int strv_consume(char ***l, char *value) {
523 r = strv_push(l, value);
530 #if 0 /// UNNEEDED by elogind
531 int strv_consume_pair(char ***l, char *a, char *b) {
534 r = strv_push_pair(l, a, b);
544 int strv_consume_prepend(char ***l, char *value) {
547 r = strv_push_prepend(l, value);
554 int strv_extend(char ***l, const char *value) {
564 return strv_consume(l, v);
567 char **strv_uniq(char **l) {
570 /* Drops duplicate entries. The first identical string will be
571 * kept, the others dropped */
574 strv_remove(i+1, *i);
579 #if 0 /// UNNEEDED by elogind
580 bool strv_is_uniq(char **l) {
584 if (strv_find(i+1, *i))
591 char **strv_remove(char **l, const char *s) {
599 /* Drops every occurrence of s in the string list, edits
602 for (f = t = l; *f; f++)
612 char **strv_parse_nulstr(const char *s, size_t l) {
614 unsigned c = 0, i = 0;
620 return new0(char*, 1);
622 for (p = s; p < s + l; p++)
629 v = new0(char*, c+1);
637 e = memchr(p, 0, s + l - p);
639 v[i] = strndup(p, e ? e - p : s + l - p);
658 char **strv_split_nulstr(const char *s) {
663 if (strv_extend(&r, i) < 0) {
669 return strv_new(NULL, NULL);
674 #if 0 /// UNNEEDED by elogind
675 int strv_make_nulstr(char **l, char **p, size_t *q) {
676 size_t n_allocated = 0, n = 0;
677 _cleanup_free_ char *m = NULL;
688 if (!GREEDY_REALLOC(m, n_allocated, n + z + 1))
691 memcpy(m + n, *i, z + 1);
710 bool strv_overlap(char **a, char **b) {
714 if (strv_contains(b, *i))
721 static int str_compare(const void *_a, const void *_b) {
722 const char **a = (const char**) _a, **b = (const char**) _b;
724 return strcmp(*a, *b);
727 char **strv_sort(char **l) {
732 qsort(l, strv_length(l), sizeof(char*), str_compare);
736 #if 0 /// UNNEEDED by elogind
737 bool strv_equal(char **a, char **b) {
740 return strv_isempty(b);
745 for ( ; *a || *b; ++a, ++b)
746 if (!streq_ptr(*a, *b))
752 void strv_print(char **l) {
759 int strv_extendf(char ***l, const char *format, ...) {
764 va_start(ap, format);
765 r = vasprintf(&x, format, ap);
771 return strv_consume(l, x);
774 char **strv_reverse(char **l) {
781 for (i = 0; i < n / 2; i++) {
792 char **strv_shell_escape(char **l, const char *bad) {
795 /* Escapes every character in every string in l that is in bad,
796 * edits in-place, does not roll-back on error. */
801 v = shell_escape(*s, bad);
812 bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
815 STRV_FOREACH(p, patterns)
816 if (fnmatch(*p, s, 0) == 0)
822 char ***strv_free_free(char ***l) {
835 char **strv_skip(char **l, size_t n) {
847 int strv_extend_n(char ***l, const char *value, size_t n) {
858 /* Adds the value value n times to l */
862 nl = realloc(*l, sizeof(char*) * (k + n + 1));
868 for (i = k; i < k + n; i++) {
869 nl[i] = strdup(value);
878 for (j = k; j < i; j++)