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 /// UNNEEDED by elogind
206 int strv_extend_strv_concat(char ***a, char **b, const char *suffix) {
213 v = strappend(*s, suffix);
228 char **strv_split(const char *s, const char *separator) {
229 const char *word, *state;
237 FOREACH_WORD_SEPARATOR(word, l, s, separator, state)
245 FOREACH_WORD_SEPARATOR(word, l, s, separator, state) {
246 r[i] = strndup(word, l);
259 /// UNNEEDED by elogind
261 char **strv_split_newlines(const char *s) {
267 /* Special version of strv_split() that splits on newlines and
268 * suppresses an empty string at the end */
270 l = strv_split(s, NEWLINE);
278 if (isempty(l[n-1])) {
279 l[n-1] = mfree(l[n-1]);
285 int strv_split_extract(char ***t, const char *s, const char *separators, ExtractFlags flags) {
286 size_t n = 0, allocated = 0;
287 _cleanup_strv_free_ char **l = NULL;
294 _cleanup_free_ char *word = NULL;
296 r = extract_first_word(&s, &word, separators, flags);
303 if (!GREEDY_REALLOC(l, allocated, n + 2))
322 char *strv_join(char **l, const char *separator) {
330 k = strlen(separator);
346 e = stpcpy(e, separator);
356 /// UNNEEDED by elogind
358 char *strv_join_quoted(char **l) {
361 size_t allocated = 0, len = 0;
364 /* assuming here that escaped string cannot be more
365 * than twice as long, and reserving space for the
366 * separator and quotes.
368 _cleanup_free_ char *esc = NULL;
371 if (!GREEDY_REALLOC(buf, allocated,
372 len + strlen(*s) * 2 + 3))
379 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
380 len > 0 ? " " : "", esc);
381 assert(needed < allocated - len);
396 int strv_push(char ***l, char *value) {
405 /* Increase and check for overflow */
410 c = realloc_multiply(*l, sizeof(char*), m);
421 int strv_push_pair(char ***l, char *a, char *b) {
430 /* increase and check for overflow */
431 m = n + !!a + !!b + 1;
435 c = realloc_multiply(*l, sizeof(char*), m);
449 int strv_push_prepend(char ***l, char *value) {
458 /* increase and check for overflow */
467 for (i = 0; i < n; i++)
479 int strv_consume(char ***l, char *value) {
482 r = strv_push(l, value);
489 /// UNNEEDED by elogind
491 int strv_consume_pair(char ***l, char *a, char *b) {
494 r = strv_push_pair(l, a, b);
504 int strv_consume_prepend(char ***l, char *value) {
507 r = strv_push_prepend(l, value);
514 int strv_extend(char ***l, const char *value) {
524 return strv_consume(l, v);
527 char **strv_uniq(char **l) {
530 /* Drops duplicate entries. The first identical string will be
531 * kept, the others dropped */
534 strv_remove(i+1, *i);
539 /// UNNEEDED by elogind
541 bool strv_is_uniq(char **l) {
545 if (strv_find(i+1, *i))
552 char **strv_remove(char **l, const char *s) {
560 /* Drops every occurrence of s in the string list, edits
563 for (f = t = l; *f; f++)
573 char **strv_parse_nulstr(const char *s, size_t l) {
575 unsigned c = 0, i = 0;
581 return new0(char*, 1);
583 for (p = s; p < s + l; p++)
590 v = new0(char*, c+1);
598 e = memchr(p, 0, s + l - p);
600 v[i] = strndup(p, e ? e - p : s + l - p);
619 char **strv_split_nulstr(const char *s) {
624 if (strv_extend(&r, i) < 0) {
630 return strv_new(NULL, NULL);
635 /// UNNEEDED by elogind
637 bool strv_overlap(char **a, char **b) {
641 if (strv_contains(b, *i))
647 static int str_compare(const void *_a, const void *_b) {
648 const char **a = (const char**) _a, **b = (const char**) _b;
650 return strcmp(*a, *b);
653 char **strv_sort(char **l) {
658 qsort(l, strv_length(l), sizeof(char*), str_compare);
662 bool strv_equal(char **a, char **b) {
666 for ( ; *a || *b; ++a, ++b)
667 if (!streq_ptr(*a, *b))
673 void strv_print(char **l) {
680 int strv_extendf(char ***l, const char *format, ...) {
685 va_start(ap, format);
686 r = vasprintf(&x, format, ap);
692 return strv_consume(l, x);
695 char **strv_reverse(char **l) {
702 for (i = 0; i < n / 2; i++) {
713 char **strv_shell_escape(char **l, const char *bad) {
716 /* Escapes every character in every string in l that is in bad,
717 * edits in-place, does not roll-back on error. */
722 v = shell_escape(*s, bad);
734 bool strv_fnmatch(char* const* patterns, const char *s, int flags) {
737 STRV_FOREACH(p, patterns)
738 if (fnmatch(*p, s, 0) == 0)