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/>.
31 char *strv_find(char **l, const char *name) {
43 char *strv_find_prefix(char **l, const char *name) {
49 if (startswith(*i, name))
55 void strv_free(char **l) {
67 char **strv_copy(char * const *l) {
70 k = r = new(char*, strv_length(l) + 1);
75 for (; *l; k++, l++) {
87 unsigned strv_length(char * const *l) {
99 char **strv_new_ap(const char *x, va_list ap) {
102 unsigned n = 0, i = 0;
105 /* As a special trick we ignore all listed strings that equal
106 * (const char*) -1. This is supposed to be used with the
107 * STRV_IFNOTNULL() macro to include possibly NULL strings in
108 * the string list. */
111 n = x == (const char*) -1 ? 0 : 1;
114 while ((s = va_arg(aq, const char*))) {
115 if (s == (const char*) -1)
129 if (x != (const char*) -1) {
136 while ((s = va_arg(ap, const char*))) {
138 if (s == (const char*) -1)
158 char **strv_new(const char *x, ...) {
163 r = strv_new_ap(x, ap);
169 char **strv_merge(char **a, char **b) {
178 r = new(char*, strv_length(a) + strv_length(b) + 1);
182 for (k = r; *a; k++, a++) {
188 for (; *b; k++, b++) {
202 char **strv_merge_concat(char **a, char **b, const char *suffix) {
205 /* Like strv_merge(), but appends suffix to all strings in b, before adding */
210 r = new(char*, strv_length(a) + strv_length(b) + 1);
216 for (; *a; k++, a++) {
222 for (; *b; k++, b++) {
223 *k = strappend(*b, suffix);
237 char **strv_split(const char *s, const char *separator) {
247 FOREACH_WORD_SEPARATOR(w, l, s, separator, state)
255 FOREACH_WORD_SEPARATOR(w, l, s, separator, state) {
256 r[i] = strndup(w, l);
269 char **strv_split_quoted(const char *s) {
279 FOREACH_WORD_QUOTED(w, l, s, state)
287 FOREACH_WORD_QUOTED(w, l, s, state) {
288 r[i] = cunescape_length(w, l);
300 char **strv_split_newlines(const char *s) {
306 /* Special version of strv_split() that splits on newlines and
307 * suppresses an empty string at the end */
309 l = strv_split(s, NEWLINE);
317 if (isempty(l[n-1])) {
325 char *strv_join(char **l, const char *separator) {
333 k = strlen(separator);
349 e = stpcpy(e, separator);
359 char *strv_join_quoted(char **l) {
362 size_t allocated = 0, len = 0;
365 /* assuming here that escaped string cannot be more
366 * than twice as long, and reserving space for the
367 * separator and quotes.
369 _cleanup_free_ char *esc = NULL;
372 if (!GREEDY_REALLOC(buf, allocated,
373 len + strlen(*s) * 2 + 3))
380 needed = snprintf(buf + len, allocated - len, "%s\"%s\"",
381 len > 0 ? " " : "", esc);
382 assert(needed < allocated - len);
396 char **strv_append(char **l, const char *s) {
400 return strv_new(s, NULL);
405 r = new(char*, strv_length(l)+2);
409 for (k = r; *l; k++, l++) {
427 char **strv_appendf(char **l, const char *format, ...) {
429 _cleanup_free_ char *s = NULL;
432 va_start(ap, format);
433 r = vasprintf(&s, format, ap);
439 return strv_append(l, s);
442 int strv_push(char ***l, char *value) {
450 c = realloc(*l, sizeof(char*) * (n + 2));
461 int strv_extend(char ***l, const char *value) {
479 char **strv_uniq(char **l) {
482 /* Drops duplicate entries. The first identical string will be
483 * kept, the others dropped */
486 strv_remove(i+1, *i);
491 char **strv_remove(char **l, const char *s) {
499 /* Drops every occurrence of s in the string list, edits
502 for (f = t = l; *f; f++) {
516 char **strv_remove_prefix(char **l, const char *s) {
524 /* Drops every occurrence of a string prefixed with s in the
525 * string list, edits in-place. */
527 for (f = t = l; *f; f++) {
529 if (startswith(*f, s)) {
541 char **strv_parse_nulstr(const char *s, size_t l) {
543 unsigned c = 0, i = 0;
549 return strv_new(NULL, NULL);
551 for (p = s; p < s + l; p++)
558 v = new0(char*, c+1);
566 e = memchr(p, 0, s + l - p);
568 v[i] = strndup(p, e ? e - p : s + l - p);
587 char **strv_split_nulstr(const char *s) {
592 if (strv_extend(&r, i) < 0) {
598 return strv_new(NULL, NULL);
603 bool strv_overlap(char **a, char **b) {
616 static int str_compare(const void *_a, const void *_b) {
617 const char **a = (const char**) _a, **b = (const char**) _b;
619 return strcmp(*a, *b);
622 char **strv_sort(char **l) {
627 qsort(l, strv_length(l), sizeof(char*), str_compare);
631 void strv_print(char **l) {