/src/systemd/src/basic/string-util.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | | #pragma once |
3 | | |
4 | | #include <string.h> |
5 | | |
6 | | #include "alloc-util.h" |
7 | | #include "forward.h" |
8 | | #include "string-util-fundamental.h" /* IWYU pragma: export */ |
9 | | |
10 | 0 | static inline char* strstr_ptr(const char *haystack, const char *needle) { |
11 | 0 | if (!haystack || !needle) |
12 | 0 | return NULL; |
13 | 0 | return strstr(haystack, needle); |
14 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:strstr_ptr Unexecuted instantiation: dhcp-option.c:strstr_ptr Unexecuted instantiation: sd-dhcp-client-id.c:strstr_ptr Unexecuted instantiation: sd-dhcp-duid.c:strstr_ptr Unexecuted instantiation: sd-dhcp-lease.c:strstr_ptr Unexecuted instantiation: sd-dns-resolver.c:strstr_ptr Unexecuted instantiation: network-internal.c:strstr_ptr |
15 | | |
16 | 0 | static inline char* strstrafter(const char *haystack, const char *needle) { |
17 | 0 | char *p; |
18 | 0 |
|
19 | 0 | /* Returns NULL if not found, or pointer to first character after needle if found */ |
20 | 0 |
|
21 | 0 | p = strstr_ptr(haystack, needle); |
22 | 0 | if (!p) |
23 | 0 | return NULL; |
24 | 0 |
|
25 | 0 | return p + strlen(needle); |
26 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:strstrafter Unexecuted instantiation: dhcp-option.c:strstrafter Unexecuted instantiation: sd-dhcp-client-id.c:strstrafter Unexecuted instantiation: sd-dhcp-duid.c:strstrafter Unexecuted instantiation: sd-dhcp-lease.c:strstrafter Unexecuted instantiation: sd-dns-resolver.c:strstrafter Unexecuted instantiation: network-internal.c:strstrafter |
27 | | |
28 | 0 | static inline const char* strnull(const char *s) { |
29 | 0 | return s ?: "(null)"; |
30 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:strnull Unexecuted instantiation: dhcp-option.c:strnull Unexecuted instantiation: sd-dhcp-client-id.c:strnull Unexecuted instantiation: sd-dhcp-duid.c:strnull Unexecuted instantiation: sd-dhcp-lease.c:strnull Unexecuted instantiation: sd-dns-resolver.c:strnull Unexecuted instantiation: network-internal.c:strnull |
31 | | |
32 | 0 | static inline const char* strna(const char *s) { |
33 | 0 | return s ?: "n/a"; |
34 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:strna Unexecuted instantiation: dhcp-option.c:strna Unexecuted instantiation: sd-dhcp-client-id.c:strna Unexecuted instantiation: sd-dhcp-duid.c:strna Unexecuted instantiation: sd-dhcp-lease.c:strna Unexecuted instantiation: sd-dns-resolver.c:strna Unexecuted instantiation: network-internal.c:strna |
35 | | |
36 | 0 | static inline const char* true_false(bool b) { |
37 | 0 | return b ? "true" : "false"; |
38 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:true_false Unexecuted instantiation: dhcp-option.c:true_false Unexecuted instantiation: sd-dhcp-client-id.c:true_false Unexecuted instantiation: sd-dhcp-duid.c:true_false Unexecuted instantiation: sd-dhcp-lease.c:true_false Unexecuted instantiation: sd-dns-resolver.c:true_false Unexecuted instantiation: network-internal.c:true_false |
39 | | |
40 | 0 | static inline const char* plus_minus(bool b) { |
41 | 0 | return b ? "+" : "-"; |
42 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:plus_minus Unexecuted instantiation: dhcp-option.c:plus_minus Unexecuted instantiation: sd-dhcp-client-id.c:plus_minus Unexecuted instantiation: sd-dhcp-duid.c:plus_minus Unexecuted instantiation: sd-dhcp-lease.c:plus_minus Unexecuted instantiation: sd-dns-resolver.c:plus_minus Unexecuted instantiation: network-internal.c:plus_minus |
43 | | |
44 | 0 | static inline const char* one_zero(bool b) { |
45 | 0 | return b ? "1" : "0"; |
46 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:one_zero Unexecuted instantiation: dhcp-option.c:one_zero Unexecuted instantiation: sd-dhcp-client-id.c:one_zero Unexecuted instantiation: sd-dhcp-duid.c:one_zero Unexecuted instantiation: sd-dhcp-lease.c:one_zero Unexecuted instantiation: sd-dns-resolver.c:one_zero Unexecuted instantiation: network-internal.c:one_zero |
47 | | |
48 | 0 | static inline const char* enable_disable(bool b) { |
49 | 0 | return b ? "enable" : "disable"; |
50 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:enable_disable Unexecuted instantiation: dhcp-option.c:enable_disable Unexecuted instantiation: sd-dhcp-client-id.c:enable_disable Unexecuted instantiation: sd-dhcp-duid.c:enable_disable Unexecuted instantiation: sd-dhcp-lease.c:enable_disable Unexecuted instantiation: sd-dns-resolver.c:enable_disable Unexecuted instantiation: network-internal.c:enable_disable |
51 | | |
52 | 0 | static inline const char* enabled_disabled(bool b) { |
53 | 0 | return b ? "enabled" : "disabled"; |
54 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:enabled_disabled Unexecuted instantiation: dhcp-option.c:enabled_disabled Unexecuted instantiation: sd-dhcp-client-id.c:enabled_disabled Unexecuted instantiation: sd-dhcp-duid.c:enabled_disabled Unexecuted instantiation: sd-dhcp-lease.c:enabled_disabled Unexecuted instantiation: sd-dns-resolver.c:enabled_disabled Unexecuted instantiation: network-internal.c:enabled_disabled |
55 | | |
56 | | /* This macro's return pointer will have the "const" qualifier set or unset the same way as the input |
57 | | * pointer. */ |
58 | | #define empty_to_null(p) \ |
59 | | ({ \ |
60 | | const char *_p = (p); \ |
61 | | (typeof(p)) (isempty(_p) ? NULL : _p); \ |
62 | | }) |
63 | | |
64 | 0 | static inline const char* empty_to_na(const char *p) { |
65 | 0 | return isempty(p) ? "n/a" : p; |
66 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:empty_to_na Unexecuted instantiation: dhcp-option.c:empty_to_na Unexecuted instantiation: sd-dhcp-client-id.c:empty_to_na Unexecuted instantiation: sd-dhcp-duid.c:empty_to_na Unexecuted instantiation: sd-dhcp-lease.c:empty_to_na Unexecuted instantiation: sd-dns-resolver.c:empty_to_na Unexecuted instantiation: network-internal.c:empty_to_na |
67 | | |
68 | 0 | static inline const char* empty_to_dash(const char *str) { |
69 | 0 | return isempty(str) ? "-" : str; |
70 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:empty_to_dash Unexecuted instantiation: dhcp-option.c:empty_to_dash Unexecuted instantiation: sd-dhcp-client-id.c:empty_to_dash Unexecuted instantiation: sd-dhcp-duid.c:empty_to_dash Unexecuted instantiation: sd-dhcp-lease.c:empty_to_dash Unexecuted instantiation: sd-dns-resolver.c:empty_to_dash Unexecuted instantiation: network-internal.c:empty_to_dash |
71 | | |
72 | 0 | static inline bool empty_or_dash(const char *str) { |
73 | 0 | return !str || |
74 | 0 | str[0] == 0 || |
75 | 0 | (str[0] == '-' && str[1] == 0); |
76 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:empty_or_dash Unexecuted instantiation: dhcp-option.c:empty_or_dash Unexecuted instantiation: sd-dhcp-client-id.c:empty_or_dash Unexecuted instantiation: sd-dhcp-duid.c:empty_or_dash Unexecuted instantiation: sd-dhcp-lease.c:empty_or_dash Unexecuted instantiation: sd-dns-resolver.c:empty_or_dash Unexecuted instantiation: network-internal.c:empty_or_dash |
77 | | |
78 | 0 | static inline const char* empty_or_dash_to_null(const char *p) { |
79 | 0 | return empty_or_dash(p) ? NULL : p; |
80 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:empty_or_dash_to_null Unexecuted instantiation: dhcp-option.c:empty_or_dash_to_null Unexecuted instantiation: sd-dhcp-client-id.c:empty_or_dash_to_null Unexecuted instantiation: sd-dhcp-duid.c:empty_or_dash_to_null Unexecuted instantiation: sd-dhcp-lease.c:empty_or_dash_to_null Unexecuted instantiation: sd-dns-resolver.c:empty_or_dash_to_null Unexecuted instantiation: network-internal.c:empty_or_dash_to_null |
81 | | #define empty_or_dash_to_null(p) \ |
82 | | ({ \ |
83 | | const char *_p = (p); \ |
84 | | (typeof(p)) (empty_or_dash(_p) ? NULL : _p); \ |
85 | | }) |
86 | | |
87 | | char* first_word(const char *s, const char *word) _pure_; |
88 | | |
89 | | char* strextendn(char **x, const char *s, size_t l) _nonnull_if_nonzero_(2, 3); |
90 | | |
91 | 0 | #define strjoin(a, ...) strextend_with_separator_internal(NULL, NULL, a, __VA_ARGS__, NULL) |
92 | | |
93 | | #define strjoina(a, ...) \ |
94 | | ({ \ |
95 | | const char *_appendees_[] = { a, __VA_ARGS__ }; \ |
96 | | char *_d_, *_p_; \ |
97 | | size_t _len_ = 0; \ |
98 | | size_t _i_; \ |
99 | | for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \ |
100 | | _len_ += strlen(_appendees_[_i_]); \ |
101 | | _p_ = _d_ = newa(char, _len_ + 1); \ |
102 | | for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \ |
103 | | _p_ = stpcpy(_p_, _appendees_[_i_]); \ |
104 | | *_p_ = 0; \ |
105 | | _d_; \ |
106 | | }) |
107 | | |
108 | | char* strstrip(char *s); |
109 | | char* delete_chars(char *s, const char *bad); |
110 | | char* delete_trailing_chars(char *s, const char *bad); |
111 | | char* truncate_nl_full(char *s, size_t *ret_len); |
112 | 0 | static inline char* truncate_nl(char *s) { |
113 | 0 | return truncate_nl_full(s, NULL); |
114 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:truncate_nl Unexecuted instantiation: dhcp-option.c:truncate_nl Unexecuted instantiation: sd-dhcp-client-id.c:truncate_nl Unexecuted instantiation: sd-dhcp-duid.c:truncate_nl Unexecuted instantiation: sd-dhcp-lease.c:truncate_nl Unexecuted instantiation: sd-dns-resolver.c:truncate_nl Unexecuted instantiation: network-internal.c:truncate_nl |
115 | | |
116 | 0 | static inline char* skip_leading_chars(const char *s, const char *bad) { |
117 | 0 | if (!s) |
118 | 0 | return NULL; |
119 | 0 |
|
120 | 0 | if (!bad) |
121 | 0 | bad = WHITESPACE; |
122 | 0 |
|
123 | 0 | return (char*) s + strspn(s, bad); |
124 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:skip_leading_chars Unexecuted instantiation: dhcp-option.c:skip_leading_chars Unexecuted instantiation: sd-dhcp-client-id.c:skip_leading_chars Unexecuted instantiation: sd-dhcp-duid.c:skip_leading_chars Unexecuted instantiation: sd-dhcp-lease.c:skip_leading_chars Unexecuted instantiation: sd-dns-resolver.c:skip_leading_chars Unexecuted instantiation: network-internal.c:skip_leading_chars |
125 | | |
126 | | char ascii_tolower(char x) _const_; |
127 | | char* ascii_strlower(char *s); |
128 | | char* ascii_strlower_n(char *s, size_t n); |
129 | | |
130 | | char ascii_toupper(char x) _const_; |
131 | | char* ascii_strupper(char *s); |
132 | | |
133 | | int ascii_strcasecmp_n(const char *a, const char *b, size_t n); |
134 | | int ascii_strcasecmp_nn(const char *a, size_t n, const char *b, size_t m); |
135 | | |
136 | | bool chars_intersect(const char *a, const char *b) _pure_; |
137 | | |
138 | 1.37k | static inline bool _pure_ in_charset(const char *s, const char *charset) { |
139 | 1.37k | assert(s); |
140 | 1.37k | assert(charset); |
141 | 1.37k | return s[strspn(s, charset)] == '\0'; |
142 | 1.37k | } Unexecuted instantiation: fuzz-dhcp-client.c:in_charset Unexecuted instantiation: dhcp-option.c:in_charset Unexecuted instantiation: sd-dhcp-client-id.c:in_charset Unexecuted instantiation: sd-dhcp-duid.c:in_charset sd-dhcp-lease.c:in_charset Line | Count | Source | 138 | 954 | static inline bool _pure_ in_charset(const char *s, const char *charset) { | 139 | 954 | assert(s); | 140 | 954 | assert(charset); | 141 | 954 | return s[strspn(s, charset)] == '\0'; | 142 | 954 | } |
sd-dns-resolver.c:in_charset Line | Count | Source | 138 | 417 | static inline bool _pure_ in_charset(const char *s, const char *charset) { | 139 | 417 | assert(s); | 140 | 417 | assert(charset); | 141 | 417 | return s[strspn(s, charset)] == '\0'; | 142 | 417 | } |
Unexecuted instantiation: network-internal.c:in_charset |
143 | | |
144 | 0 | static inline bool char_is_cc(char p) { |
145 | 0 | /* char is unsigned on some architectures, e.g. aarch64. So, compiler may warn the condition |
146 | 0 | * p >= 0 is always true. See #19543. Hence, let's cast to unsigned before the comparison. Note |
147 | 0 | * that the cast in the right hand side is redundant, as according to the C standard, compilers |
148 | 0 | * automatically cast a signed value to unsigned when comparing with an unsigned variable. Just |
149 | 0 | * for safety and readability. */ |
150 | 0 | return (uint8_t) p < (uint8_t) ' ' || p == 127; |
151 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:char_is_cc Unexecuted instantiation: dhcp-option.c:char_is_cc Unexecuted instantiation: sd-dhcp-client-id.c:char_is_cc Unexecuted instantiation: sd-dhcp-duid.c:char_is_cc Unexecuted instantiation: sd-dhcp-lease.c:char_is_cc Unexecuted instantiation: sd-dns-resolver.c:char_is_cc Unexecuted instantiation: network-internal.c:char_is_cc |
152 | | bool string_has_cc(const char *p, const char *ok) _pure_; |
153 | | |
154 | | char* ellipsize_mem(const char *s, size_t old_length_bytes, size_t new_length_columns, unsigned percent); |
155 | 0 | static inline char* ellipsize(const char *s, size_t length, unsigned percent) { |
156 | 0 | return ellipsize_mem(s, strlen(s), length, percent); |
157 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:ellipsize Unexecuted instantiation: dhcp-option.c:ellipsize Unexecuted instantiation: sd-dhcp-client-id.c:ellipsize Unexecuted instantiation: sd-dhcp-duid.c:ellipsize Unexecuted instantiation: sd-dhcp-lease.c:ellipsize Unexecuted instantiation: sd-dns-resolver.c:ellipsize Unexecuted instantiation: network-internal.c:ellipsize |
158 | | |
159 | | char* cellescape(char *buf, size_t len, const char *s); |
160 | | |
161 | | /* This limit is arbitrary, enough to give some idea what the string contains */ |
162 | | #define CELLESCAPE_DEFAULT_LENGTH 64 |
163 | | |
164 | | char* strshorten(char *s, size_t l); |
165 | | |
166 | | int strgrowpad0(char **s, size_t l); |
167 | | |
168 | | char* strreplace(const char *text, const char *old_string, const char *new_string); |
169 | | |
170 | | char* strip_tab_ansi(char **ibuf, size_t *_isz, size_t highlight[2]); |
171 | | |
172 | | char* strextend_with_separator_internal(char **x, const char *separator, ...) _sentinel_; |
173 | | #define strextend_with_separator(x, separator, ...) strextend_with_separator_internal(x, separator, __VA_ARGS__, NULL) |
174 | | #define strextend(x, ...) strextend_with_separator_internal(x, NULL, __VA_ARGS__, NULL) |
175 | | |
176 | | int strextendf_with_separator(char **x, const char *separator, const char *format, ...) _printf_(3,4); |
177 | | #define strextendf(x, ...) strextendf_with_separator(x, NULL, __VA_ARGS__) |
178 | | |
179 | | #define strprepend_with_separator(x, separator, ...) \ |
180 | | ({ \ |
181 | | char **_p_ = ASSERT_PTR(x), *_s_; \ |
182 | | _s_ = strextend_with_separator_internal(NULL, (separator), __VA_ARGS__, empty_to_null(*_p_), NULL); \ |
183 | | if (_s_) { \ |
184 | | free(*_p_); \ |
185 | | *_p_ = _s_; \ |
186 | | } \ |
187 | | _s_; \ |
188 | | }) |
189 | | #define strprepend(x, ...) strprepend_with_separator(x, NULL, __VA_ARGS__) |
190 | | |
191 | | char* strrep(const char *s, unsigned n); |
192 | | |
193 | | #define strrepa(s, n) \ |
194 | | ({ \ |
195 | | const char *_sss_ = (s); \ |
196 | | size_t _nnn_ = (n), _len_ = strlen(_sss_); \ |
197 | | assert_se(MUL_ASSIGN_SAFE(&_len_, _nnn_)); \ |
198 | | char *_d_, *_p_; \ |
199 | | _p_ = _d_ = newa(char, _len_ + 1); \ |
200 | | for (size_t _i_ = 0; _i_ < _nnn_; _i_++) \ |
201 | | _p_ = stpcpy(_p_, _sss_); \ |
202 | | *_p_ = 0; \ |
203 | | _d_; \ |
204 | | }) |
205 | | |
206 | | int split_pair(const char *s, const char *sep, char **ret_first, char **ret_second); |
207 | | |
208 | | int free_and_strdup(char **p, const char *s); |
209 | | int free_and_strdup_warn(char **p, const char *s); |
210 | | int free_and_strndup(char **p, const char *s, size_t l) _nonnull_if_nonzero_(2, 3); |
211 | | |
212 | | int strdup_to_full(char **ret, const char *src); |
213 | 0 | static inline int strdup_to(char **ret, const char *src) { |
214 | 0 | int r = strdup_to_full(ASSERT_PTR(ret), src); |
215 | 0 | return r < 0 ? r : 0; /* Suppress return value of 1. */ |
216 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:strdup_to Unexecuted instantiation: dhcp-option.c:strdup_to Unexecuted instantiation: sd-dhcp-client-id.c:strdup_to Unexecuted instantiation: sd-dhcp-duid.c:strdup_to Unexecuted instantiation: sd-dhcp-lease.c:strdup_to Unexecuted instantiation: sd-dns-resolver.c:strdup_to Unexecuted instantiation: network-internal.c:strdup_to |
217 | | |
218 | | bool string_is_safe(const char *p) _pure_; |
219 | | bool string_is_safe_ascii(const char *p) _pure_; |
220 | | |
221 | | DISABLE_WARNING_STRINGOP_TRUNCATION; |
222 | 0 | static inline void strncpy_exact(char *buf, const char *src, size_t buf_len) { |
223 | 0 | strncpy(buf, src, buf_len); |
224 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:strncpy_exact Unexecuted instantiation: dhcp-option.c:strncpy_exact Unexecuted instantiation: sd-dhcp-client-id.c:strncpy_exact Unexecuted instantiation: sd-dhcp-duid.c:strncpy_exact Unexecuted instantiation: sd-dhcp-lease.c:strncpy_exact Unexecuted instantiation: sd-dns-resolver.c:strncpy_exact Unexecuted instantiation: network-internal.c:strncpy_exact |
225 | | REENABLE_WARNING; |
226 | | |
227 | | /* Like startswith_no_case(), but operates on arbitrary memory blocks. |
228 | | * It works only for ASCII strings. |
229 | | */ |
230 | 0 | static inline void* memory_startswith_no_case(const void *p, size_t sz, const char *token) { |
231 | 0 | assert(token); |
232 | 0 |
|
233 | 0 | size_t n = strlen(token); |
234 | 0 | if (sz < n) |
235 | 0 | return NULL; |
236 | 0 |
|
237 | 0 | assert(p); |
238 | 0 |
|
239 | 0 | for (size_t i = 0; i < n; i++) |
240 | 0 | if (ascii_tolower(((char *)p)[i]) != ascii_tolower(token[i])) |
241 | 0 | return NULL; |
242 | 0 |
|
243 | 0 | return (uint8_t*) p + n; |
244 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:memory_startswith_no_case Unexecuted instantiation: dhcp-option.c:memory_startswith_no_case Unexecuted instantiation: sd-dhcp-client-id.c:memory_startswith_no_case Unexecuted instantiation: sd-dhcp-duid.c:memory_startswith_no_case Unexecuted instantiation: sd-dhcp-lease.c:memory_startswith_no_case Unexecuted instantiation: sd-dns-resolver.c:memory_startswith_no_case Unexecuted instantiation: network-internal.c:memory_startswith_no_case |
245 | | |
246 | | char* str_realloc(char *p); |
247 | | char* string_erase(char *x); |
248 | | |
249 | | int string_truncate_lines(const char *s, size_t n_lines, char **ret); |
250 | | int string_extract_line(const char *s, size_t i, char **ret); |
251 | | |
252 | | int string_contains_word_strv(const char *string, const char *separators, char * const *words, const char **ret_word); |
253 | 0 | static inline int string_contains_word(const char *string, const char *separators, const char *word) { |
254 | 0 | return string_contains_word_strv(string, separators, STRV_MAKE(word), NULL); |
255 | 0 | } Unexecuted instantiation: fuzz-dhcp-client.c:string_contains_word Unexecuted instantiation: dhcp-option.c:string_contains_word Unexecuted instantiation: sd-dhcp-client-id.c:string_contains_word Unexecuted instantiation: sd-dhcp-duid.c:string_contains_word Unexecuted instantiation: sd-dhcp-lease.c:string_contains_word Unexecuted instantiation: sd-dns-resolver.c:string_contains_word Unexecuted instantiation: network-internal.c:string_contains_word |
256 | | |
257 | | bool streq_skip_trailing_chars(const char *s1, const char *s2, const char *ok); |
258 | | |
259 | | char* string_replace_char(char *str, char old_char, char new_char); |
260 | | |
261 | | typedef enum MakeCStringMode { |
262 | | MAKE_CSTRING_REFUSE_TRAILING_NUL, |
263 | | MAKE_CSTRING_ALLOW_TRAILING_NUL, |
264 | | MAKE_CSTRING_REQUIRE_TRAILING_NUL, |
265 | | _MAKE_CSTRING_MODE_MAX, |
266 | | _MAKE_CSTRING_MODE_INVALID = -1, |
267 | | } MakeCStringMode; |
268 | | |
269 | | int make_cstring(const char *s, size_t n, MakeCStringMode mode, char **ret); |
270 | | |
271 | | size_t strspn_from_end(const char *str, const char *accept) _pure_; |
272 | | |
273 | | char* strdupspn(const char *a, const char *accept); |
274 | | char* strdupcspn(const char *a, const char *reject); |
275 | | |
276 | | /* These are like strdupa()/strndupa(), but honour ALLOCA_MAX */ |
277 | | #define strdupa_safe(s) \ |
278 | | ({ \ |
279 | | const char *_t = (s); \ |
280 | | (char*) memdupa_suffix0(_t, strlen(_t)); \ |
281 | | }) |
282 | | |
283 | | #define strndupa_safe(s, n) \ |
284 | | ({ \ |
285 | | const char *_t = (s); \ |
286 | | (char*) memdupa_suffix0(_t, strnlen(_t, n)); \ |
287 | | }) |
288 | | |
289 | | char* find_line_startswith(const char *haystack, const char *needle); |
290 | | char* find_line(const char *haystack, const char *needle); |
291 | | char* find_line_after(const char *haystack, const char *needle); |
292 | | |
293 | | bool version_is_valid(const char *s) _pure_; |
294 | | bool version_is_valid_versionspec(const char *s) _pure_; |
295 | | |
296 | | ssize_t strlevenshtein(const char *x, const char *y); |
297 | | |
298 | | char* strrstr(const char *haystack, const char *needle) _pure_; |
299 | | |
300 | | size_t str_common_prefix(const char *a, const char *b) _pure_; |