]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/strv.h
man: improve Description= documentation (#38101)
[thirdparty/systemd.git] / src / basic / strv.h
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
c2f1db8f 2#pragma once
60918275 3
0c15577a
DDM
4#include "forward.h"
5#include "strv-fundamental.h" /* IWYU pragma: export */
60918275 6
14337c37
ZJS
7char* strv_find(char * const *l, const char *name) _pure_;
8char* strv_find_case(char * const *l, const char *name) _pure_;
9char* strv_find_prefix(char * const *l, const char *name) _pure_;
10char* strv_find_startswith(char * const *l, const char *name) _pure_;
ffdf4978 11char* strv_find_closest(char * const *l, const char *name) _pure_;
2ed74695
LB
12/* Given two vectors, the first a list of keys and the second a list of key-value pairs, returns the value
13 * of the first key from the first vector that is found in the second vector. */
14char* strv_find_first_field(char * const *needles, char * const *haystack) _pure_;
a4bfb399 15
ddd6a22a
LP
16#define strv_contains(l, s) (!!strv_find((l), (s)))
17#define strv_contains_case(l, s) (!!strv_find_case((l), (s)))
18
14337c37 19char** strv_free(char **l);
14bf2c9d 20DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free);
dfb33a97
LP
21#define _cleanup_strv_free_ _cleanup_(strv_freep)
22
14337c37 23char** strv_free_erase(char **l);
ab84f5b9
ZJS
24DEFINE_TRIVIAL_CLEANUP_FUNC(char**, strv_free_erase);
25#define _cleanup_strv_free_erase_ _cleanup_(strv_free_erasep)
26
6da2ea9f 27void strv_free_many(char ***strvs, size_t n) _nonnull_if_nonzero_(1, 2);
a39cba25 28
4ea517a6
LP
29char** strv_copy_n(char * const *l, size_t n);
30static inline char** strv_copy(char * const *l) {
31 return strv_copy_n(l, SIZE_MAX);
32}
5058bd7e
LN
33int strv_copy_unless_empty(char * const *l, char ***ret);
34
da6053d0 35size_t strv_length(char * const *l) _pure_;
60918275 36
479ddcdf 37int strv_extend_strv(char ***a, char * const *b, bool filter_duplicates);
8a7ade74
MY
38int strv_extend_strv_consume(char ***a, char **b, bool filter_duplicates);
39
9bc74930
ZJS
40int strv_extend_strv_biconcat(char ***a, const char *prefix, const char* const *b, const char *suffix);
41static inline int strv_extend_strv_concat(char ***a, const char* const *b, const char *suffix) {
42 return strv_extend_strv_biconcat(a, NULL, b, suffix);
43}
8a7ade74 44
82443be5 45int strv_prepend(char ***l, const char *value);
3ec3ae68
ZJS
46
47/* _with_size() are lower-level functions where the size can be provided externally,
48 * which allows us to skip iterating over the strv to find the end, which saves
49 * a bit of time and reduces the complexity of appending from O(n²) to O(n). */
50
51int strv_extend_with_size(char ***l, size_t *n, const char *value);
52static inline int strv_extend(char ***l, const char *value) {
53 return strv_extend_with_size(l, NULL, value);
54}
55
80f1e209
LP
56int strv_extend_many_internal(char ***l, const char *value, ...);
57#define strv_extend_many(l, ...) strv_extend_many_internal(l, __VA_ARGS__, POINTER_MAX)
58
400102ec 59int strv_extendf(char ***l, const char *format, ...) _printf_(2,3);
3ec3ae68
ZJS
60
61int strv_push_with_size(char ***l, size_t *n, char *value);
62static inline int strv_push(char ***l, char *value) {
63 return strv_push_with_size(l, NULL, value);
64}
98940a3c 65int strv_push_pair(char ***l, char *a, char *b);
3ec3ae68 66
da6053d0 67int strv_insert(char ***l, size_t position, char *value);
6e888894
ZJS
68
69static inline int strv_push_prepend(char ***l, char *value) {
70 return strv_insert(l, 0, value);
71}
72
3ec3ae68
ZJS
73int strv_consume_with_size(char ***l, size_t *n, char *value);
74static inline int strv_consume(char ***l, char *value) {
75 return strv_consume_with_size(l, NULL, value);
76}
77
98940a3c 78int strv_consume_pair(char ***l, char *a, char *b);
9a00f57a 79int strv_consume_prepend(char ***l, char *value);
034c6ed7 80
14337c37
ZJS
81char** strv_remove(char **l, const char *s);
82char** strv_uniq(char **l);
180341e7 83bool strv_is_uniq(char * const *l) _pure_;
5f9a22c3 84
180341e7 85int strv_compare(char * const *a, char * const *b) _pure_;
8b75798d
YW
86static inline bool strv_equal(char * const *a, char * const *b) {
87 return strv_compare(a, b) == 0;
88}
0f84a72e 89
180341e7 90bool strv_equal_ignore_order(char * const *a, char * const *b) _pure_;
5072f426 91
14337c37
ZJS
92char** strv_new_internal(const char *x, ...) _sentinel_;
93char** strv_new_ap(const char *x, va_list ap);
bea1a013 94#define strv_new(...) strv_new_internal(__VA_ARGS__, NULL)
60918275 95
66032ef4 96#define STRV_IGNORE ((const char *) POINTER_MAX)
f9d14060 97
07719a21 98static inline const char* STRV_IFNOTNULL(const char *x) {
1da3cb81 99 return x ?: STRV_IGNORE;
07719a21
LP
100}
101
2fd9ae2e 102static inline bool strv_isempty(char * const *l) {
5f9a22c3
LP
103 return !l || !*l;
104}
105
90e30d76 106int strv_split_full(char ***t, const char *s, const char *separators, ExtractFlags flags);
6553db60 107char** strv_split(const char *s, const char *separators);
f385c447 108
3c318caa 109int strv_split_and_extend_full(char ***t, const char *s, const char *separators, bool filter_duplicates, ExtractFlags flags);
6553db60 110int strv_split_and_extend(char ***t, const char *s, const char *separators, bool filter_duplicates);
3c318caa 111
f385c447 112int strv_split_newlines_full(char ***ret, const char *s, ExtractFlags flags);
6553db60 113char** strv_split_newlines(const char *s);
f88e6be5 114
a082edd5
LB
115/* Given a string containing white-space separated tuples of words themselves separated by ':',
116 * returns a vector of strings. If the second element in a tuple is missing, the corresponding
117 * string in the vector is an empty string. */
118int strv_split_colon_pairs(char ***t, const char *s);
119
e5f2d77b 120char* strv_join_full(char * const *l, const char *separator, const char *prefix, bool escape_separator);
479ddcdf 121static inline char *strv_join(char * const *l, const char *separator) {
d4d9f034 122 return strv_join_full(l, separator, NULL, false);
2b9a7d2e 123}
5f9a22c3 124
479ddcdf 125bool strv_overlap(char * const *a, char * const *b) _pure_;
0c85a4f3 126
de010b0b
YW
127#define _STRV_FOREACH_BACKWARDS(s, l, h, i) \
128 for (typeof(*(l)) *s, *h = (l), *i = ({ \
129 size_t _len = strv_length(h); \
130 _len > 0 ? h + _len - 1 : NULL; \
131 }); \
9b01798b 132 (s = i); \
3e3ee420 133 i = PTR_SUB1(i, h))
de010b0b
YW
134
135#define STRV_FOREACH_BACKWARDS(s, l) \
136 _STRV_FOREACH_BACKWARDS(s, l, UNIQ_T(h, UNIQ), UNIQ_T(i, UNIQ))
60918275 137
de010b0b 138#define _STRV_FOREACH_PAIR(x, y, l, i) \
e671bdc5 139 for (typeof(*(l)) *x, *y, *i = (l); \
de010b0b
YW
140 i && *(x = i) && *(y = i + 1); \
141 i += 2)
857a493d 142
de010b0b
YW
143#define STRV_FOREACH_PAIR(x, y, l) \
144 _STRV_FOREACH_PAIR(x, y, l, UNIQ_T(i, UNIQ))
246aa6dd 145
14337c37 146char** strv_sort(char **l);
3dc546ad 147char** strv_sort_uniq(char **l);
00546c18
YW
148void strv_print_full(char * const *l, const char *prefix);
149static inline void strv_print(char * const *l) {
150 strv_print_full(l, NULL);
151}
250a918d 152
eba8b541
MY
153char* startswith_strv(const char *s, char * const *l);
154
155#define STARTSWITH_SET(p, ...) \
156 startswith_strv(p, STRV_MAKE(__VA_ARGS__))
157
2e6f012b
MY
158char* endswith_strv(const char *s, char * const *l);
159
160#define ENDSWITH_SET(p, ...) \
161 endswith_strv(p, STRV_MAKE(__VA_ARGS__))
162
53ede806 163#define STR_IN_SET(x, ...) strv_contains(STRV_MAKE(__VA_ARGS__), x)
c7bf9d51
ZJS
164#define STRPTR_IN_SET(x, ...) \
165 ({ \
166 const char* _x = (x); \
167 _x && strv_contains(STRV_MAKE(__VA_ARGS__), _x); \
168 })
c4a7b2c5 169
ddd6a22a
LP
170#define STRCASE_IN_SET(x, ...) strv_contains_case(STRV_MAKE(__VA_ARGS__), x)
171#define STRCASEPTR_IN_SET(x, ...) \
172 ({ \
173 const char* _x = (x); \
174 _x && strv_contains_case(STRV_MAKE(__VA_ARGS__), _x); \
175 })
176
f85b12d6 177#define _FOREACH_STRING(uniq, x, y, ...) \
5980d463 178 for (const char *x, * const*UNIQ_T(l, uniq) = STRV_MAKE_CONST(({ x = y; }), ##__VA_ARGS__); \
66a64081 179 x; \
f85b12d6
LP
180 x = *(++UNIQ_T(l, uniq)))
181
182#define FOREACH_STRING(x, y, ...) \
183 _FOREACH_STRING(UNIQ, x, y, ##__VA_ARGS__)
e1dd6790 184
14337c37
ZJS
185char** strv_reverse(char **l);
186char** strv_shell_escape(char **l, const char *bad);
bceccd5e 187
bcfc0e88 188bool strv_fnmatch_full(char* const* patterns, const char *s, int flags, size_t *ret_matched_pos);
191a3f16
ZJS
189static inline bool strv_fnmatch(char* const* patterns, const char *s) {
190 return strv_fnmatch_full(patterns, s, 0, NULL);
0ef84b80 191}
2404701e 192static inline bool strv_fnmatch_or_empty(char* const* patterns, const char *s, int flags) {
bceccd5e
ZJS
193 assert(s);
194 return strv_isempty(patterns) ||
191a3f16 195 strv_fnmatch_full(patterns, s, flags, NULL);
bceccd5e 196}
fe382237 197
14337c37 198char** strv_skip(char **l, size_t n);
8dd4c05b
LP
199
200int strv_extend_n(char ***l, const char *value, size_t n);
3df9bec5 201
6658f7c7
DDM
202int strv_extend_assignment(char ***l, const char *lhs, const char *rhs);
203
479ddcdf 204int fputstrv(FILE *f, char * const *l, const char *separator, bool *space);
b302a50d
LP
205
206#define strv_free_and_replace(a, b) \
fc4c10b2 207 free_and_replace_full(a, b, strv_free)
cde79109 208
c540875c 209void string_strv_hashmap_remove(Hashmap *h, const char *key, const char *value);
0c15577a 210void string_strv_ordered_hashmap_remove(OrderedHashmap *h, const char *key, const char *value);
01655aec
DDM
211int string_strv_hashmap_put(Hashmap **h, const char *key, const char *value);
212int string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value);
aca09301
LP
213
214int strv_rebreak_lines(char **l, size_t width, char ***ret);
428146dc 215
3ab19c1f 216char** strv_filter_prefix(char * const *l, const char *prefix);