1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
9 #include "alloc-util.h"
11 #include "extract-word.h"
13 #include "memory-util.h"
14 #include "nulstr-util.h"
15 #include "sort-util.h"
16 #include "string-util.h"
19 char* strv_find(char * const *l
, const char *name
) {
31 char* strv_find_case(char * const *l
, const char *name
) {
37 if (strcaseeq(*i
, name
))
43 char* strv_find_prefix(char * const *l
, const char *name
) {
49 if (startswith(*i
, name
))
55 char* strv_find_startswith(char * const *l
, const char *name
) {
60 /* Like strv_find_prefix, but actually returns only the
61 * suffix, not the whole item */
64 e
= startswith(*i
, name
);
72 char** strv_free(char **l
) {
76 for (char **k
= l
; *k
; k
++)
82 char** strv_free_erase(char **l
) {
91 char** strv_copy(char * const *l
) {
94 k
= r
= new(char*, strv_length(l
) + 1);
99 for (; *l
; k
++, l
++) {
111 size_t strv_length(char * const *l
) {
123 char** strv_new_ap(const char *x
, va_list ap
) {
124 _cleanup_strv_free_
char **a
= NULL
;
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 for (const char *s
= x
; s
; s
= va_arg(aq
, const char*)) {
135 if (s
== STRV_IGNORE
)
146 for (const char *s
= x
; s
; s
= va_arg(ap
, const char*)) {
147 if (s
== STRV_IGNORE
)
162 char** strv_new_internal(const char *x
, ...) {
167 r
= strv_new_ap(x
, ap
);
173 int strv_extend_strv(char ***a
, char * const *b
, bool filter_duplicates
) {
174 char * const *s
, **t
;
185 if (p
>= SIZE_MAX
- q
)
188 t
= reallocarray(*a
, GREEDY_ALLOC_ROUND_UP(p
+ q
+ 1), sizeof(char *));
196 if (filter_duplicates
&& strv_contains(t
, *s
))
212 for (size_t j
= 0; j
< i
; j
++)
219 int strv_extend_strv_concat(char ***a
, char * const *b
, const char *suffix
) {
226 v
= strjoin(*s
, suffix
);
240 int strv_split_newlines_full(char ***ret
, const char *s
, ExtractFlags flags
) {
241 _cleanup_strv_free_
char **l
= NULL
;
247 /* Special version of strv_split_full() that splits on newlines and
248 * suppresses an empty string at the end. */
250 r
= strv_split_full(&l
, s
, NEWLINE
, flags
);
255 if (n
> 0 && isempty(l
[n
- 1])) {
256 l
[n
- 1] = mfree(l
[n
- 1]);
264 int strv_split_full(char ***t
, const char *s
, const char *separators
, ExtractFlags flags
) {
265 _cleanup_strv_free_
char **l
= NULL
;
273 _cleanup_free_
char *word
= NULL
;
275 r
= extract_first_word(&s
, &word
, separators
, flags
);
281 if (!GREEDY_REALLOC(l
, n
+ 2))
284 l
[n
++] = TAKE_PTR(word
);
299 int strv_split_and_extend_full(char ***t
, const char *s
, const char *separators
, bool filter_duplicates
, ExtractFlags flags
) {
300 _cleanup_strv_free_
char **l
= NULL
;
306 r
= strv_split_full(&l
, s
, separators
, flags
);
310 r
= strv_extend_strv(t
, l
, filter_duplicates
);
314 return (int) strv_length(*t
);
317 int strv_split_colon_pairs(char ***t
, const char *s
) {
318 _cleanup_strv_free_
char **l
= NULL
;
326 _cleanup_free_
char *first
= NULL
, *second
= NULL
, *tuple
= NULL
, *second_or_empty
= NULL
;
328 r
= extract_first_word(&s
, &tuple
, NULL
, EXTRACT_UNQUOTE
|EXTRACT_RETAIN_ESCAPE
);
334 const char *p
= tuple
;
335 r
= extract_many_words(&p
, ":", EXTRACT_CUNESCAPE
|EXTRACT_UNESCAPE_SEPARATORS
,
336 &first
, &second
, NULL
);
341 /* Enforce that at most 2 colon-separated words are contained in each group */
345 second_or_empty
= strdup(strempty(second
));
346 if (!second_or_empty
)
349 if (!GREEDY_REALLOC(l
, n
+ 3))
352 l
[n
++] = TAKE_PTR(first
);
353 l
[n
++] = TAKE_PTR(second_or_empty
);
369 char* strv_join_full(char * const *l
, const char *separator
, const char *prefix
, bool unescape_separators
) {
377 k
= strlen(separator
);
378 m
= strlen_ptr(prefix
);
380 if (unescape_separators
) /* If there separator is multi-char, we won't know how to escape it. */
388 bool needs_escaping
= unescape_separators
&& strchr(*s
, separator
[0]);
390 n
+= m
+ strlen(*s
) * (1 + needs_escaping
);
400 e
= stpcpy(e
, separator
);
403 e
= stpcpy(e
, prefix
);
405 bool needs_escaping
= unescape_separators
&& strchr(*s
, separator
[0]);
408 for (size_t i
= 0; (*s
)[i
]; i
++) {
409 if ((*s
)[i
] == separator
[0])
422 int strv_push(char ***l
, char *value
) {
431 /* Check for overflow */
435 c
= reallocarray(*l
, GREEDY_ALLOC_ROUND_UP(n
+ 2), sizeof(char*));
446 int strv_push_pair(char ***l
, char *a
, char *b
) {
455 /* Check for overflow */
459 /* increase and check for overflow */
460 c
= reallocarray(*l
, GREEDY_ALLOC_ROUND_UP(n
+ !!a
+ !!b
+ 1), sizeof(char*));
474 int strv_insert(char ***l
, size_t position
, char *value
) {
482 position
= MIN(position
, n
);
484 /* increase and check for overflow */
493 for (size_t i
= 0; i
< position
; i
++)
496 for (size_t i
= position
; i
< n
; i
++)
500 return free_and_replace(*l
, c
);
503 int strv_consume(char ***l
, char *value
) {
506 r
= strv_push(l
, value
);
513 int strv_consume_pair(char ***l
, char *a
, char *b
) {
516 r
= strv_push_pair(l
, a
, b
);
525 int strv_consume_prepend(char ***l
, char *value
) {
528 r
= strv_push_prepend(l
, value
);
535 int strv_prepend(char ***l
, const char *value
) {
545 return strv_consume_prepend(l
, v
);
548 int strv_extend(char ***l
, const char *value
) {
558 return strv_consume(l
, v
);
561 int strv_extend_front(char ***l
, const char *value
) {
567 /* Like strv_extend(), but prepends rather than appends the new entry */
574 /* Increase and overflow check. */
583 c
= reallocarray(*l
, m
, sizeof(char*));
589 memmove(c
+1, c
, n
* sizeof(char*));
597 char** strv_uniq(char **l
) {
600 /* Drops duplicate entries. The first identical string will be
601 * kept, the others dropped */
604 strv_remove(i
+1, *i
);
609 bool strv_is_uniq(char * const *l
) {
613 if (strv_contains(i
+1, *i
))
619 char** strv_remove(char **l
, const char *s
) {
627 /* Drops every occurrence of s in the string list, edits
630 for (f
= t
= l
; *f
; f
++)
640 char** strv_parse_nulstr(const char *s
, size_t l
) {
641 /* l is the length of the input data, which will be split at NULs into
642 * elements of the resulting strv. Hence, the number of items in the resulting strv
643 * will be equal to one plus the number of NUL bytes in the l bytes starting at s,
644 * unless s[l-1] is NUL, in which case the final empty string is not stored in
645 * the resulting strv, and length is equal to the number of NUL bytes.
647 * Note that contrary to a normal nulstr which cannot contain empty strings, because
648 * the input data is terminated by any two consequent NUL bytes, this parser accepts
649 * empty strings in s.
658 return new0(char*, 1);
660 for (const char *p
= s
; p
< s
+ l
; p
++)
667 v
= new0(char*, c
+1);
671 for (const char *p
= s
; p
< s
+ l
; ) {
674 e
= memchr(p
, 0, s
+ l
- p
);
676 v
[i
] = strndup(p
, e
? e
- p
: s
+ l
- p
);
695 char** strv_split_nulstr(const char *s
) {
700 if (strv_extend(&r
, i
) < 0) {
706 return strv_new(NULL
);
711 int strv_make_nulstr(char * const *l
, char **ret
, size_t *ret_size
) {
712 /* A valid nulstr with two NULs at the end will be created, but
713 * q will be the length without the two trailing NULs. Thus the output
714 * string is a valid nulstr and can be iterated over using NULSTR_FOREACH,
715 * and can also be parsed by strv_parse_nulstr as long as the length
716 * is provided separately.
719 _cleanup_free_
char *m
= NULL
;
731 if (!GREEDY_REALLOC(m
, n
+ z
+ 2))
734 memcpy(m
+ n
, *i
, z
+ 1);
744 /* make sure there is a second extra NUL at the end of resulting nulstr */
756 bool strv_overlap(char * const *a
, char * const *b
) {
760 if (strv_contains(b
, *i
))
766 static int str_compare(char * const *a
, char * const *b
) {
767 return strcmp(*a
, *b
);
770 char** strv_sort(char **l
) {
771 typesafe_qsort(l
, strv_length(l
), str_compare
);
775 int strv_compare(char * const *a
, char * const *b
) {
778 if (strv_isempty(a
)) {
788 for ( ; *a
|| *b
; ++a
, ++b
) {
789 r
= strcmp_ptr(*a
, *b
);
797 void strv_print(char * const *l
) {
804 int strv_extendf(char ***l
, const char *format
, ...) {
809 va_start(ap
, format
);
810 r
= vasprintf(&x
, format
, ap
);
816 return strv_consume(l
, x
);
819 char** strv_reverse(char **l
) {
826 for (size_t i
= 0; i
< n
/ 2; i
++)
827 SWAP_TWO(l
[i
], l
[n
-1-i
]);
832 char** strv_shell_escape(char **l
, const char *bad
) {
835 /* Escapes every character in every string in l that is in bad,
836 * edits in-place, does not roll-back on error. */
841 v
= shell_escape(*s
, bad
);
852 bool strv_fnmatch_full(char* const* patterns
, const char *s
, int flags
, size_t *matched_pos
) {
853 for (size_t i
= 0; patterns
&& patterns
[i
]; i
++)
854 if (fnmatch(patterns
[i
], s
, flags
) == 0) {
863 char** strv_skip(char **l
, size_t n
) {
875 int strv_extend_n(char ***l
, const char *value
, size_t n
) {
886 /* Adds the value n times to l */
889 if (n
>= SIZE_MAX
- k
)
892 nl
= reallocarray(*l
, GREEDY_ALLOC_ROUND_UP(k
+ n
+ 1), sizeof(char *));
898 for (i
= k
; i
< k
+ n
; i
++) {
899 nl
[i
] = strdup(value
);
908 for (size_t j
= k
; j
< i
; j
++)
915 int fputstrv(FILE *f
, char * const *l
, const char *separator
, bool *space
) {
920 /* Like fputs(), but for strv, and with a less stupid argument order */
926 r
= fputs_with_space(f
, *s
, separator
, space
);
934 static int string_strv_hashmap_put_internal(Hashmap
*h
, const char *key
, const char *value
) {
938 l
= hashmap_get(h
, key
);
940 /* A list for this key already exists, let's append to it if it is not listed yet */
941 if (strv_contains(l
, value
))
944 r
= strv_extend(&l
, value
);
948 assert_se(hashmap_update(h
, key
, l
) >= 0);
950 /* No list for this key exists yet, create one */
951 _cleanup_strv_free_
char **l2
= NULL
;
952 _cleanup_free_
char *t
= NULL
;
958 r
= strv_extend(&l2
, value
);
962 r
= hashmap_put(h
, t
, l2
);
972 int _string_strv_hashmap_put(Hashmap
**h
, const char *key
, const char *value HASHMAP_DEBUG_PARAMS
) {
975 r
= _hashmap_ensure_allocated(h
, &string_strv_hash_ops HASHMAP_DEBUG_PASS_ARGS
);
979 return string_strv_hashmap_put_internal(*h
, key
, value
);
982 int _string_strv_ordered_hashmap_put(OrderedHashmap
**h
, const char *key
, const char *value HASHMAP_DEBUG_PARAMS
) {
985 r
= _ordered_hashmap_ensure_allocated(h
, &string_strv_hash_ops HASHMAP_DEBUG_PASS_ARGS
);
989 return string_strv_hashmap_put_internal(PLAIN_HASHMAP(*h
), key
, value
);
992 DEFINE_HASH_OPS_FULL(string_strv_hash_ops
, char, string_hash_func
, string_compare_func
, free
, char*, strv_free
);