1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
6 #include "alloc-util.h"
8 #include "string-util-fundamental.h" /* IWYU pragma: export */
10 static inline char* strstr_ptr(const char *haystack
, const char *needle
) {
11 if (!haystack
|| !needle
)
13 return strstr(haystack
, needle
);
16 static inline char* strstrafter(const char *haystack
, const char *needle
) {
19 /* Returns NULL if not found, or pointer to first character after needle if found */
21 p
= strstr_ptr(haystack
, needle
);
25 return p
+ strlen(needle
);
28 static inline const char* strnull(const char *s
) {
32 static inline const char* strna(const char *s
) {
36 static inline const char* true_false(bool b
) {
37 return b
? "true" : "false";
40 static inline const char* plus_minus(bool b
) {
44 static inline const char* one_zero(bool b
) {
48 static inline const char* enable_disable(bool b
) {
49 return b
? "enable" : "disable";
52 static inline const char* enabled_disabled(bool b
) {
53 return b
? "enabled" : "disabled";
56 /* This macro's return pointer will have the "const" qualifier set or unset the same way as the input
58 #define empty_to_null(p) \
60 const char *_p = (p); \
61 (typeof(p)) (isempty(_p) ? NULL : _p); \
64 static inline const char* empty_to_na(const char *p
) {
65 return isempty(p
) ? "n/a" : p
;
68 static inline const char* empty_to_dash(const char *str
) {
69 return isempty(str
) ? "-" : str
;
72 static inline bool empty_or_dash(const char *str
) {
75 (str
[0] == '-' && str
[1] == 0);
78 static inline const char* empty_or_dash_to_null(const char *p
) {
79 return empty_or_dash(p
) ? NULL
: p
;
81 #define empty_or_dash_to_null(p) \
83 const char *_p = (p); \
84 (typeof(p)) (empty_or_dash(_p) ? NULL : _p); \
87 char* first_word(const char *s
, const char *word
) _pure_
;
89 char* strextendn(char **x
, const char *s
, size_t l
) _nonnull_if_nonzero_(2, 3);
91 #define strjoin(a, ...) strextend_with_separator_internal(NULL, NULL, a, __VA_ARGS__, NULL)
93 #define strjoina(a, ...) \
95 const char *_appendees_[] = { a, __VA_ARGS__ }; \
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_]); \
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 static inline char* truncate_nl(char *s
) {
113 return truncate_nl_full(s
, NULL
);
116 static inline char* skip_leading_chars(const char *s
, const char *bad
) {
123 return (char*) s
+ strspn(s
, bad
);
126 char ascii_tolower(char x
) _const_
;
127 char* ascii_strlower(char *s
);
128 char* ascii_strlower_n(char *s
, size_t n
);
130 char ascii_toupper(char x
) _const_
;
131 char* ascii_strupper(char *s
);
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
);
136 bool chars_intersect(const char *a
, const char *b
) _pure_
;
138 static inline bool _pure_
in_charset(const char *s
, const char *charset
) {
141 return s
[strspn(s
, charset
)] == '\0';
144 static inline bool char_is_cc(char p
) {
145 /* char is unsigned on some architectures, e.g. aarch64. So, compiler may warn the condition
146 * p >= 0 is always true. See #19543. Hence, let's cast to unsigned before the comparison. Note
147 * that the cast in the right hand side is redundant, as according to the C standard, compilers
148 * automatically cast a signed value to unsigned when comparing with an unsigned variable. Just
149 * for safety and readability. */
150 return (uint8_t) p
< (uint8_t) ' ' || p
== 127;
152 bool string_has_cc(const char *p
, const char *ok
) _pure_
;
154 char* ellipsize_mem(const char *s
, size_t old_length_bytes
, size_t new_length_columns
, unsigned percent
);
155 static inline char* ellipsize(const char *s
, size_t length
, unsigned percent
) {
156 return ellipsize_mem(s
, strlen(s
), length
, percent
);
159 char* cellescape(char *buf
, size_t len
, const char *s
);
161 /* This limit is arbitrary, enough to give some idea what the string contains */
162 #define CELLESCAPE_DEFAULT_LENGTH 64
164 char* strshorten(char *s
, size_t l
);
166 int strgrowpad0(char **s
, size_t l
);
168 char* strreplace(const char *text
, const char *old_string
, const char *new_string
);
170 char* strip_tab_ansi(char **ibuf
, size_t *_isz
, size_t highlight
[2]);
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)
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__)
179 #define strprepend_with_separator(x, separator, ...) \
181 char **_p_ = ASSERT_PTR(x), *_s_; \
182 _s_ = strextend_with_separator_internal(NULL, (separator), __VA_ARGS__, empty_to_null(*_p_), NULL); \
189 #define strprepend(x, ...) strprepend_with_separator(x, NULL, __VA_ARGS__)
191 char* strrep(const char *s
, unsigned n
);
193 #define strrepa(s, n) \
195 const char *_sss_ = (s); \
196 size_t _nnn_ = (n), _len_ = strlen(_sss_); \
197 assert_se(MUL_ASSIGN_SAFE(&_len_, _nnn_)); \
199 _p_ = _d_ = newa(char, _len_ + 1); \
200 for (size_t _i_ = 0; _i_ < _nnn_; _i_++) \
201 _p_ = stpcpy(_p_, _sss_); \
206 int split_pair(const char *s
, const char *sep
, char **ret_first
, char **ret_second
);
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);
212 int strdup_to_full(char **ret
, const char *src
);
213 static inline int strdup_to(char **ret
, const char *src
) {
214 int r
= strdup_to_full(ASSERT_PTR(ret
), src
);
215 return r
< 0 ? r
: 0; /* Suppress return value of 1. */
218 bool string_is_safe(const char *p
) _pure_
;
219 bool string_is_safe_ascii(const char *p
) _pure_
;
221 DISABLE_WARNING_STRINGOP_TRUNCATION
;
222 static inline void strncpy_exact(char *buf
, const char *src
, size_t buf_len
) {
223 strncpy(buf
, src
, buf_len
);
227 /* Like startswith_no_case(), but operates on arbitrary memory blocks.
228 * It works only for ASCII strings.
230 static inline void* memory_startswith_no_case(const void *p
, size_t sz
, const char *token
) {
233 size_t n
= strlen(token
);
239 for (size_t i
= 0; i
< n
; i
++)
240 if (ascii_tolower(((char *)p
)[i
]) != ascii_tolower(token
[i
]))
243 return (uint8_t*) p
+ n
;
246 char* str_realloc(char *p
);
247 char* string_erase(char *x
);
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
);
252 int string_contains_word_strv(const char *string
, const char *separators
, char * const *words
, const char **ret_word
);
253 static inline int string_contains_word(const char *string
, const char *separators
, const char *word
) {
254 return string_contains_word_strv(string
, separators
, STRV_MAKE(word
), NULL
);
257 bool streq_skip_trailing_chars(const char *s1
, const char *s2
, const char *ok
);
259 char* string_replace_char(char *str
, char old_char
, char new_char
);
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,
269 int make_cstring(const char *s
, size_t n
, MakeCStringMode mode
, char **ret
);
271 size_t strspn_from_end(const char *str
, const char *accept
) _pure_
;
273 char* strdupspn(const char *a
, const char *accept
);
274 char* strdupcspn(const char *a
, const char *reject
);
276 /* These are like strdupa()/strndupa(), but honour ALLOCA_MAX */
277 #define strdupa_safe(s) \
279 const char *_t = (s); \
280 (char*) memdupa_suffix0(_t, strlen(_t)); \
283 #define strndupa_safe(s, n) \
285 const char *_t = (s); \
286 (char*) memdupa_suffix0(_t, strnlen(_t, n)); \
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
);
293 bool version_is_valid(const char *s
) _pure_
;
294 bool version_is_valid_versionspec(const char *s
) _pure_
;
296 ssize_t
strlevenshtein(const char *x
, const char *y
);
298 char* strrstr(const char *haystack
, const char *needle
) _pure_
;
300 size_t str_common_prefix(const char *a
, const char *b
) _pure_
;