]>
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/>.
28 #include "string-util.h"
32 char *strv_find(char **l
, const char *name
) {
44 char *strv_find_prefix(char **l
, const char *name
) {
50 if (startswith(*i
, name
))
56 char *strv_find_startswith(char **l
, const char *name
) {
61 /* Like strv_find_prefix, but actually returns only the
62 * suffix, not the whole item */
65 e
= startswith(*i
, name
);
73 void strv_clear(char **l
) {
85 char **strv_free(char **l
) {
91 char **strv_free_erase(char **l
) {
100 char **strv_copy(char * const *l
) {
103 k
= r
= new(char*, strv_length(l
) + 1);
108 for (; *l
; k
++, l
++) {
120 unsigned strv_length(char * const *l
) {
132 char **strv_new_ap(const char *x
, va_list ap
) {
135 unsigned n
= 0, i
= 0;
138 /* As a special trick we ignore all listed strings that equal
139 * (const char*) -1. This is supposed to be used with the
140 * STRV_IFNOTNULL() macro to include possibly NULL strings in
141 * the string list. */
144 n
= x
== (const char*) -1 ? 0 : 1;
147 while ((s
= va_arg(aq
, const char*))) {
148 if (s
== (const char*) -1)
162 if (x
!= (const char*) -1) {
169 while ((s
= va_arg(ap
, const char*))) {
171 if (s
== (const char*) -1)
191 char **strv_new(const char *x
, ...) {
196 r
= strv_new_ap(x
, ap
);
202 int strv_extend_strv(char ***a
, char **b
, bool filter_duplicates
) {
204 size_t p
, q
, i
= 0, j
;
214 t
= realloc(*a
, sizeof(char*) * (p
+ q
+ 1));
223 if (filter_duplicates
&& strv_contains(t
, *s
))
239 for (j
= 0; j
< i
; j
++)
246 int strv_extend_strv_concat(char ***a
, char **b
, const char *suffix
) {
253 v
= strappend(*s
, suffix
);
267 char **strv_split(const char *s
, const char *separator
) {
268 const char *word
, *state
;
276 FOREACH_WORD_SEPARATOR(word
, l
, s
, separator
, state
)
284 FOREACH_WORD_SEPARATOR(word
, l
, s
, separator
, state
) {
285 r
[i
] = strndup(word
, l
);
298 char **strv_split_newlines(const char *s
) {
304 /* Special version of strv_split() that splits on newlines and
305 * suppresses an empty string at the end */
307 l
= strv_split(s
, NEWLINE
);
315 if (isempty(l
[n
- 1]))
316 l
[n
- 1] = mfree(l
[n
- 1]);
321 int strv_split_extract(char ***t
, const char *s
, const char *separators
, ExtractFlags flags
) {
322 _cleanup_strv_free_
char **l
= NULL
;
323 size_t n
= 0, allocated
= 0;
330 _cleanup_free_
char *word
= NULL
;
332 r
= extract_first_word(&s
, &word
, separators
, flags
);
338 if (!GREEDY_REALLOC(l
, allocated
, n
+ 2))
359 char *strv_join(char **l
, const char *separator
) {
367 k
= strlen(separator
);
383 e
= stpcpy(e
, separator
);
393 char *strv_join_quoted(char **l
) {
396 size_t allocated
= 0, len
= 0;
399 /* assuming here that escaped string cannot be more
400 * than twice as long, and reserving space for the
401 * separator and quotes.
403 _cleanup_free_
char *esc
= NULL
;
406 if (!GREEDY_REALLOC(buf
, allocated
,
407 len
+ strlen(*s
) * 2 + 3))
414 needed
= snprintf(buf
+ len
, allocated
- len
, "%s\"%s\"",
415 len
> 0 ? " " : "", esc
);
416 assert(needed
< allocated
- len
);
430 int strv_push(char ***l
, char *value
) {
439 /* Increase and check for overflow */
444 c
= realloc_multiply(*l
, sizeof(char*), m
);
455 int strv_push_pair(char ***l
, char *a
, char *b
) {
464 /* increase and check for overflow */
465 m
= n
+ !!a
+ !!b
+ 1;
469 c
= realloc_multiply(*l
, sizeof(char*), m
);
483 int strv_push_prepend(char ***l
, char *value
) {
492 /* increase and check for overflow */
501 for (i
= 0; i
< n
; i
++)
513 int strv_consume(char ***l
, char *value
) {
516 r
= strv_push(l
, value
);
523 int strv_consume_pair(char ***l
, char *a
, char *b
) {
526 r
= strv_push_pair(l
, a
, b
);
535 int strv_consume_prepend(char ***l
, char *value
) {
538 r
= strv_push_prepend(l
, value
);
545 int strv_extend(char ***l
, const char *value
) {
555 return strv_consume(l
, v
);
558 char **strv_uniq(char **l
) {
561 /* Drops duplicate entries. The first identical string will be
562 * kept, the others dropped */
565 strv_remove(i
+1, *i
);
570 bool strv_is_uniq(char **l
) {
574 if (strv_find(i
+1, *i
))
580 char **strv_remove(char **l
, const char *s
) {
588 /* Drops every occurrence of s in the string list, edits
591 for (f
= t
= l
; *f
; f
++)
601 char **strv_parse_nulstr(const char *s
, size_t l
) {
603 unsigned c
= 0, i
= 0;
609 return new0(char*, 1);
611 for (p
= s
; p
< s
+ l
; p
++)
618 v
= new0(char*, c
+1);
626 e
= memchr(p
, 0, s
+ l
- p
);
628 v
[i
] = strndup(p
, e
? e
- p
: s
+ l
- p
);
647 char **strv_split_nulstr(const char *s
) {
652 if (strv_extend(&r
, i
) < 0) {
658 return strv_new(NULL
, NULL
);
663 int strv_make_nulstr(char **l
, char **p
, size_t *q
) {
664 size_t n_allocated
= 0, n
= 0;
665 _cleanup_free_
char *m
= NULL
;
676 if (!GREEDY_REALLOC(m
, n_allocated
, n
+ z
+ 1))
679 memcpy(m
+ n
, *i
, z
+ 1);
698 bool strv_overlap(char **a
, char **b
) {
702 if (strv_contains(b
, *i
))
708 static int str_compare(const void *_a
, const void *_b
) {
709 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
711 return strcmp(*a
, *b
);
714 char **strv_sort(char **l
) {
719 qsort(l
, strv_length(l
), sizeof(char*), str_compare
);
723 bool strv_equal(char **a
, char **b
) {
726 return strv_isempty(b
);
731 for ( ; *a
|| *b
; ++a
, ++b
)
732 if (!streq_ptr(*a
, *b
))
738 void strv_print(char **l
) {
745 int strv_extendf(char ***l
, const char *format
, ...) {
750 va_start(ap
, format
);
751 r
= vasprintf(&x
, format
, ap
);
757 return strv_consume(l
, x
);
760 char **strv_reverse(char **l
) {
767 for (i
= 0; i
< n
/ 2; i
++) {
778 char **strv_shell_escape(char **l
, const char *bad
) {
781 /* Escapes every character in every string in l that is in bad,
782 * edits in-place, does not roll-back on error. */
787 v
= shell_escape(*s
, bad
);
798 bool strv_fnmatch(char* const* patterns
, const char *s
, int flags
) {
801 STRV_FOREACH(p
, patterns
)
802 if (fnmatch(*p
, s
, 0) == 0)
808 char ***strv_free_free(char ***l
) {
821 char **strv_skip(char **l
, size_t n
) {
833 int strv_extend_n(char ***l
, const char *value
, size_t n
) {
844 /* Adds the value value n times to l */
848 nl
= realloc(*l
, sizeof(char*) * (k
+ n
+ 1));
854 for (i
= k
; i
< k
+ n
; i
++) {
855 nl
[i
] = strdup(value
);
864 for (j
= k
; j
< i
; j
++)