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) {
196 r = strv_extend(a, *s);
204 int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
211 v = strappend(*s, suffix);
225 char **strv_split(const char *s, const char *separator) {
226 const char *word, *state;
234 FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
242 FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
243 r[i] = strndup(word, l);
256 /// UNNEEDED by elogind
258 char **strv_split_newlines(const char *s) {
264 /* Special version of strv_split() that splits on newlines and
265 * suppresses an empty string at the end */
267 l = strv_split(s, NEWLINE);
275 if (isempty(l[n-1])) {
284 int strv_split_quoted(char ***t, const char *s, UnquoteFlags flags) {
285 size_t n = 0, allocated = 0;
286 _cleanup_strv_free_ char **l = NULL;
293 _cleanup_free_ char *word = NULL;
295 r = unquote_first_word(&s, &word, flags);
301 if (!GREEDY_REALLOC(l, allocated, n + 2))
319 char *strv_join(char **l, const char *separator) {
327 k = strlen(separator);
343 e = stpcpy(e, separator);
353 char *strv_join_quoted(char **l) {
356 size_t allocated = 0, len = 0;
359 /* assuming here that escaped string cannot be more
360 * than twice as long, and reserving space for the
361 * separator and quotes.
363 _cleanup_free_ char *esc = NULL;
366 if (!GREEDY_REALLOC(buf, allocated,
367 len + strlen(*s) * 2 + 3))
374 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
375 len > 0 ? " " : "", esc);
376 assert(needed < allocated - len);
390 int strv_push(char ***l, char *value) {
399 /* Increase and check for overflow */
404 c = realloc_multiply(*l, sizeof(char*), m);
415 int strv_push_pair(char ***l, char *a, char *b) {
424 /* increase and check for overflow */
425 m = n + !!a + !!b + 1;
429 c = realloc_multiply(*l, sizeof(char*), m);
443 int strv_push_prepend(char ***l, char *value) {
452 /* increase and check for overflow */
461 for (i = 0; i < n; i++)
473 int strv_consume(char ***l, char *value) {
476 r = strv_push(l, value);
483 /// UNNEEDED by elogind
485 int strv_consume_pair(char ***l, char *a, char *b) {
488 r = strv_push_pair(l, a, b);
498 int strv_consume_prepend(char ***l, char *value) {
501 r = strv_push_prepend(l, value);
508 int strv_extend(char ***l, const char *value) {
518 return strv_consume(l, v);
521 char **strv_uniq(char **l) {
524 /* Drops duplicate entries. The first identical string will be
525 * kept, the others dropped */
528 strv_remove(i+1, *i);
533 /// UNNEEDED by elogind
535 bool strv_is_uniq(char **l) {
539 if (strv_find(i+1, *i))
546 char **strv_remove(char **l, const char *s) {
554 /* Drops every occurrence of s in the string list, edits
557 for (f = t = l; *f; f++)
567 char **strv_parse_nulstr(const char *s, size_t l) {
569 unsigned c = 0, i = 0;
575 return new0(char*, 1);
577 for (p = s; p < s + l; p++)
584 v = new0(char*, c+1);
592 e = memchr(p, 0, s + l - p);
594 v[i] = strndup(p, e ? e - p : s + l - p);
613 char **strv_split_nulstr(const char *s) {
618 if (strv_extend(&r, i) < 0) {
624 return strv_new(NULL, NULL);
629 bool strv_overlap(char **a, char **b) {
633 if (strv_contains(b, *i))
639 static int str_compare(const void *_a, const void *_b) {
640 const char **a = (const char**) _a, **b = (const char**) _b;
642 return strcmp(*a, *b);
645 char **strv_sort(char **l) {
650 qsort(l, strv_length(l), sizeof(char*), str_compare);
654 /// UNNEEDED by elogind
656 bool strv_equal(char **a, char **b) {
660 for ( ; *a || *b; ++a, ++b)
661 if (!streq_ptr(*a, *b))
668 void strv_print(char **l) {
675 /// UNNEEDED by elogind
677 int strv_extendf(char ***l, const char *format, ...) {
682 va_start(ap, format);
683 r = vasprintf(&x, format, ap);
689 return strv_consume(l, x);
692 char **strv_reverse(char **l) {
699 for (i = 0; i < n / 2; i++) {
711 bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
714 STRV_FOREACH(p, patterns)
715 if (fnmatch(*p, s, 0) == 0)