]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/strv.c
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 char **strv_split_newlines(const char *s
) {
262 /* Special version of strv_split() that splits on newlines and
263 * suppresses an empty string at the end */
265 l
= strv_split(s
, NEWLINE
);
273 if (isempty(l
[n
- 1]))
274 l
[n
- 1] = mfree(l
[n
- 1]);
279 int strv_split_extract(char ***t
, const char *s
, const char *separators
, ExtractFlags flags
) {
280 _cleanup_strv_free_
char **l
= NULL
;
281 size_t n
= 0, allocated
= 0;
288 _cleanup_free_
char *word
= NULL
;
290 r
= extract_first_word(&s
, &word
, separators
, flags
);
296 if (!GREEDY_REALLOC(l
, allocated
, n
+ 2))
317 char *strv_join(char **l
, const char *separator
) {
325 k
= strlen(separator
);
341 e
= stpcpy(e
, separator
);
351 char *strv_join_quoted(char **l
) {
354 size_t allocated
= 0, len
= 0;
357 /* assuming here that escaped string cannot be more
358 * than twice as long, and reserving space for the
359 * separator and quotes.
361 _cleanup_free_
char *esc
= NULL
;
364 if (!GREEDY_REALLOC(buf
, allocated
,
365 len
+ strlen(*s
) * 2 + 3))
372 needed
= snprintf(buf
+ len
, allocated
- len
, "%s\"%s\"",
373 len
> 0 ? " " : "", esc
);
374 assert(needed
< allocated
- len
);
388 int strv_push(char ***l
, char *value
) {
397 /* Increase and check for overflow */
402 c
= realloc_multiply(*l
, sizeof(char*), m
);
413 int strv_push_pair(char ***l
, char *a
, char *b
) {
422 /* increase and check for overflow */
423 m
= n
+ !!a
+ !!b
+ 1;
427 c
= realloc_multiply(*l
, sizeof(char*), m
);
441 int strv_push_prepend(char ***l
, char *value
) {
450 /* increase and check for overflow */
459 for (i
= 0; i
< n
; i
++)
471 int strv_consume(char ***l
, char *value
) {
474 r
= strv_push(l
, value
);
481 int strv_consume_pair(char ***l
, char *a
, char *b
) {
484 r
= strv_push_pair(l
, a
, b
);
493 int strv_consume_prepend(char ***l
, char *value
) {
496 r
= strv_push_prepend(l
, value
);
503 int strv_extend(char ***l
, const char *value
) {
513 return strv_consume(l
, v
);
516 char **strv_uniq(char **l
) {
519 /* Drops duplicate entries. The first identical string will be
520 * kept, the others dropped */
523 strv_remove(i
+1, *i
);
528 bool strv_is_uniq(char **l
) {
532 if (strv_find(i
+1, *i
))
538 char **strv_remove(char **l
, const char *s
) {
546 /* Drops every occurrence of s in the string list, edits
549 for (f
= t
= l
; *f
; f
++)
559 char **strv_parse_nulstr(const char *s
, size_t l
) {
561 unsigned c
= 0, i
= 0;
567 return new0(char*, 1);
569 for (p
= s
; p
< s
+ l
; p
++)
576 v
= new0(char*, c
+1);
584 e
= memchr(p
, 0, s
+ l
- p
);
586 v
[i
] = strndup(p
, e
? e
- p
: s
+ l
- p
);
605 char **strv_split_nulstr(const char *s
) {
610 if (strv_extend(&r
, i
) < 0) {
616 return strv_new(NULL
, NULL
);
621 bool strv_overlap(char **a
, char **b
) {
625 if (strv_contains(b
, *i
))
631 static int str_compare(const void *_a
, const void *_b
) {
632 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
634 return strcmp(*a
, *b
);
637 char **strv_sort(char **l
) {
642 qsort(l
, strv_length(l
), sizeof(char*), str_compare
);
646 bool strv_equal(char **a
, char **b
) {
650 for ( ; *a
|| *b
; ++a
, ++b
)
651 if (!streq_ptr(*a
, *b
))
657 void strv_print(char **l
) {
664 int strv_extendf(char ***l
, const char *format
, ...) {
669 va_start(ap
, format
);
670 r
= vasprintf(&x
, format
, ap
);
676 return strv_consume(l
, x
);
679 char **strv_reverse(char **l
) {
686 for (i
= 0; i
< n
/ 2; i
++) {
697 char **strv_shell_escape(char **l
, const char *bad
) {
700 /* Escapes every character in every string in l that is in bad,
701 * edits in-place, does not roll-back on error. */
706 v
= shell_escape(*s
, bad
);
717 bool strv_fnmatch(char* const* patterns
, const char *s
, int flags
) {
720 STRV_FOREACH(p
, patterns
)
721 if (fnmatch(*p
, s
, 0) == 0)
727 char ***strv_free_free(char ***l
) {
740 char **strv_skip(char **l
, size_t n
) {
752 int strv_extend_n(char ***l
, const char *value
, size_t n
) {
763 /* Adds the value value n times to l */
767 nl
= realloc(*l
, sizeof(char*) * (k
+ n
+ 1));
773 for (i
= k
; i
< k
+ n
; i
++) {
774 nl
[i
] = strdup(value
);
783 for (j
= k
; j
< i
; i
++)