]>
git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/strv.c
07ac8834bee29ad6f71ec66947869d32686df67f
1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
15 #include "alloc-util.h"
17 #include "extract-word.h"
19 #include "string-util.h"
23 char *strv_find(char **l
, const char *name
) {
35 char *strv_find_prefix(char **l
, const char *name
) {
41 if (startswith(*i
, name
))
47 char *strv_find_startswith(char **l
, const char *name
) {
52 /* Like strv_find_prefix, but actually returns only the
53 * suffix, not the whole item */
56 e
= startswith(*i
, name
);
64 void strv_clear(char **l
) {
76 char **strv_free(char **l
) {
81 char **strv_free_erase(char **l
) {
90 char **strv_copy(char * const *l
) {
93 k
= r
= new(char*, strv_length(l
) + 1);
98 for (; *l
; k
++, l
++) {
110 unsigned strv_length(char * const *l
) {
122 char **strv_new_ap(const char *x
, va_list ap
) {
125 unsigned n
= 0, i
= 0;
128 /* As a special trick we ignore all listed strings that equal
129 * STRV_IGNORE. This is supposed to be used with the
130 * STRV_IFNOTNULL() macro to include possibly NULL strings in
131 * the string list. */
134 n
= x
== STRV_IGNORE
? 0 : 1;
137 while ((s
= va_arg(aq
, const char*))) {
138 if (s
== STRV_IGNORE
)
152 if (x
!= STRV_IGNORE
) {
159 while ((s
= va_arg(ap
, const char*))) {
161 if (s
== STRV_IGNORE
)
181 char **strv_new(const char *x
, ...) {
186 r
= strv_new_ap(x
, ap
);
192 int strv_extend_strv(char ***a
, char **b
, bool filter_duplicates
) {
194 size_t p
, q
, i
= 0, j
;
204 t
= reallocarray(*a
, p
+ q
+ 1, sizeof(char *));
213 if (filter_duplicates
&& strv_contains(t
, *s
))
229 for (j
= 0; j
< i
; j
++)
236 int strv_extend_strv_concat(char ***a
, char **b
, const char *suffix
) {
243 v
= strappend(*s
, suffix
);
257 char **strv_split(const char *s
, const char *separator
) {
258 const char *word
, *state
;
266 FOREACH_WORD_SEPARATOR(word
, l
, s
, separator
, state
)
274 FOREACH_WORD_SEPARATOR(word
, l
, s
, separator
, state
) {
275 r
[i
] = strndup(word
, l
);
288 char **strv_split_newlines(const char *s
) {
294 /* Special version of strv_split() that splits on newlines and
295 * suppresses an empty string at the end */
297 l
= strv_split(s
, NEWLINE
);
305 if (isempty(l
[n
- 1]))
306 l
[n
- 1] = mfree(l
[n
- 1]);
311 int strv_split_extract(char ***t
, const char *s
, const char *separators
, ExtractFlags flags
) {
312 _cleanup_strv_free_
char **l
= NULL
;
313 size_t n
= 0, allocated
= 0;
320 _cleanup_free_
char *word
= NULL
;
322 r
= extract_first_word(&s
, &word
, separators
, flags
);
328 if (!GREEDY_REALLOC(l
, allocated
, n
+ 2))
331 l
[n
++] = TAKE_PTR(word
);
347 char *strv_join(char **l
, const char *separator
) {
355 k
= strlen(separator
);
371 e
= stpcpy(e
, separator
);
381 int strv_push(char ***l
, char *value
) {
390 /* Increase and check for overflow */
395 c
= reallocarray(*l
, m
, sizeof(char*));
406 int strv_push_pair(char ***l
, char *a
, char *b
) {
415 /* increase and check for overflow */
416 m
= n
+ !!a
+ !!b
+ 1;
420 c
= reallocarray(*l
, m
, sizeof(char*));
434 int strv_insert(char ***l
, unsigned position
, char *value
) {
442 position
= MIN(position
, n
);
444 /* increase and check for overflow */
453 for (i
= 0; i
< position
; i
++)
456 for (i
= position
; i
< n
; i
++)
467 int strv_consume(char ***l
, char *value
) {
470 r
= strv_push(l
, value
);
477 int strv_consume_pair(char ***l
, char *a
, char *b
) {
480 r
= strv_push_pair(l
, a
, b
);
489 int strv_consume_prepend(char ***l
, char *value
) {
492 r
= strv_push_prepend(l
, value
);
499 int strv_extend(char ***l
, const char *value
) {
509 return strv_consume(l
, v
);
512 int strv_extend_front(char ***l
, const char *value
) {
518 /* Like strv_extend(), but prepends rather than appends the new entry */
525 /* Increase and overflow check. */
534 c
= reallocarray(*l
, m
, sizeof(char*));
540 memmove(c
+1, c
, n
* sizeof(char*));
548 char **strv_uniq(char **l
) {
551 /* Drops duplicate entries. The first identical string will be
552 * kept, the others dropped */
555 strv_remove(i
+1, *i
);
560 bool strv_is_uniq(char **l
) {
564 if (strv_find(i
+1, *i
))
570 char **strv_remove(char **l
, const char *s
) {
578 /* Drops every occurrence of s in the string list, edits
581 for (f
= t
= l
; *f
; f
++)
591 char **strv_parse_nulstr(const char *s
, size_t l
) {
592 /* l is the length of the input data, which will be split at NULs into
593 * elements of the resulting strv. Hence, the number of items in the resulting strv
594 * will be equal to one plus the number of NUL bytes in the l bytes starting at s,
595 * unless s[l-1] is NUL, in which case the final empty string is not stored in
596 * the resulting strv, and length is equal to the number of NUL bytes.
598 * Note that contrary to a normal nulstr which cannot contain empty strings, because
599 * the input data is terminated by any two consequent NUL bytes, this parser accepts
600 * empty strings in s.
604 unsigned c
= 0, i
= 0;
610 return new0(char*, 1);
612 for (p
= s
; p
< s
+ l
; p
++)
619 v
= new0(char*, c
+1);
627 e
= memchr(p
, 0, s
+ l
- p
);
629 v
[i
] = strndup(p
, e
? e
- p
: s
+ l
- p
);
648 char **strv_split_nulstr(const char *s
) {
653 if (strv_extend(&r
, i
) < 0) {
659 return strv_new(NULL
, NULL
);
664 int strv_make_nulstr(char **l
, char **p
, size_t *q
) {
665 /* A valid nulstr with two NULs at the end will be created, but
666 * q will be the length without the two trailing NULs. Thus the output
667 * string is a valid nulstr and can be iterated over using NULSTR_FOREACH,
668 * and can also be parsed by strv_parse_nulstr as long as the length
669 * is provided separately.
672 size_t n_allocated
= 0, n
= 0;
673 _cleanup_free_
char *m
= NULL
;
684 if (!GREEDY_REALLOC(m
, n_allocated
, n
+ z
+ 2))
687 memcpy(m
+ n
, *i
, z
+ 1);
697 /* make sure there is a second extra NUL at the end of resulting nulstr */
709 bool strv_overlap(char **a
, char **b
) {
713 if (strv_contains(b
, *i
))
719 static int str_compare(const void *_a
, const void *_b
) {
720 const char **a
= (const char**) _a
, **b
= (const char**) _b
;
722 return strcmp(*a
, *b
);
725 char **strv_sort(char **l
) {
726 qsort_safe(l
, strv_length(l
), sizeof(char*), str_compare
);
730 bool strv_equal(char **a
, char **b
) {
733 return strv_isempty(b
);
738 for ( ; *a
|| *b
; ++a
, ++b
)
739 if (!streq_ptr(*a
, *b
))
745 void strv_print(char **l
) {
752 int strv_extendf(char ***l
, const char *format
, ...) {
757 va_start(ap
, format
);
758 r
= vasprintf(&x
, format
, ap
);
764 return strv_consume(l
, x
);
767 char **strv_reverse(char **l
) {
774 for (i
= 0; i
< n
/ 2; i
++)
775 SWAP_TWO(l
[i
], l
[n
-1-i
]);
780 char **strv_shell_escape(char **l
, const char *bad
) {
783 /* Escapes every character in every string in l that is in bad,
784 * edits in-place, does not roll-back on error. */
789 v
= shell_escape(*s
, bad
);
800 bool strv_fnmatch(char* const* patterns
, const char *s
, int flags
) {
803 STRV_FOREACH(p
, patterns
)
804 if (fnmatch(*p
, s
, flags
) == 0)
810 char ***strv_free_free(char ***l
) {
822 char **strv_skip(char **l
, size_t n
) {
834 int strv_extend_n(char ***l
, const char *value
, size_t n
) {
845 /* Adds the value n times to l */
849 nl
= reallocarray(*l
, k
+ n
+ 1, sizeof(char *));
855 for (i
= k
; i
< k
+ n
; i
++) {
856 nl
[i
] = strdup(value
);
865 for (j
= k
; j
< i
; j
++)
872 int fputstrv(FILE *f
, char **l
, const char *separator
, bool *space
) {
877 /* Like fputs(), but for strv, and with a less stupid argument order */
883 r
= fputs_with_space(f
, *s
, separator
, space
);