1 /* SPDX-License-Identifier: LGPL-2.1+ */
5 This file is part of systemd.
7 Copyright 2010 Lennart Poettering
9 systemd is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 2.1 of the License, or
12 (at your option) any later version.
14 systemd is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 Lesser General Public License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with systemd; If not, see <http://www.gnu.org/licenses/>.
30 /* What is interpreted as whitespace? */
31 #define WHITESPACE " \t\n\r"
32 #define NEWLINE "\n\r"
35 #define GLOB_CHARS "*?["
36 #define DIGITS "0123456789"
37 #define LOWERCASE_LETTERS "abcdefghijklmnopqrstuvwxyz"
38 #define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
39 #define LETTERS LOWERCASE_LETTERS UPPERCASE_LETTERS
40 #define ALPHANUMERICAL LETTERS DIGITS
41 #define HEXDIGITS DIGITS "abcdefABCDEF"
43 #define streq(a,b) (strcmp((a),(b)) == 0)
44 #define strneq(a, b, n) (strncmp((a), (b), (n)) == 0)
45 #define strcaseeq(a,b) (strcasecmp((a),(b)) == 0)
46 #define strncaseeq(a, b, n) (strncasecmp((a), (b), (n)) == 0)
48 int strcmp_ptr(const char *a, const char *b) _pure_;
50 static inline bool streq_ptr(const char *a, const char *b) {
51 return strcmp_ptr(a, b) == 0;
54 static inline const char* strempty(const char *s) {
58 static inline const char* strnull(const char *s) {
62 static inline const char *strna(const char *s) {
66 static inline bool isempty(const char *p) {
70 static inline const char *empty_to_null(const char *p) {
71 return isempty(p) ? NULL : p;
74 #if 0 /// UNNEEDED by elogind
75 static inline const char *strdash_if_empty(const char *str) {
76 return isempty(str) ? "-" : str;
80 static inline char *startswith(const char *s, const char *prefix) {
84 if (strncmp(s, prefix, l) == 0)
90 #if 0 /// UNNEEDED by elogind
91 static inline char *startswith_no_case(const char *s, const char *prefix) {
95 if (strncasecmp(s, prefix, l) == 0)
102 char *endswith(const char *s, const char *postfix) _pure_;
103 char *endswith_no_case(const char *s, const char *postfix) _pure_;
105 char *first_word(const char *s, const char *word) _pure_;
107 const char* split(const char **state, size_t *l, const char *separator, bool quoted);
109 #define FOREACH_WORD(word, length, s, state) \
110 _FOREACH_WORD(word, length, s, WHITESPACE, false, state)
112 #define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \
113 _FOREACH_WORD(word, length, s, separator, false, state)
115 #define _FOREACH_WORD(word, length, s, separator, quoted, state) \
116 for ((state) = (s), (word) = split(&(state), &(length), (separator), (quoted)); (word); (word) = split(&(state), &(length), (separator), (quoted)))
118 char *strappend(const char *s, const char *suffix);
119 char *strnappend(const char *s, const char *suffix, size_t length);
121 char *strjoin_real(const char *x, ...) _sentinel_;
122 #define strjoin(a, ...) strjoin_real((a), __VA_ARGS__, NULL)
124 #define strjoina(a, ...) \
126 const char *_appendees_[] = { a, __VA_ARGS__ }; \
130 for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \
131 _len_ += strlen(_appendees_[_i_]); \
132 _p_ = _d_ = alloca(_len_ + 1); \
133 for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \
134 _p_ = stpcpy(_p_, _appendees_[_i_]); \
139 char *strstrip(char *s);
140 #if 0 /// UNNEEDED by elogind
141 char *delete_chars(char *s, const char *bad);
143 char *delete_trailing_chars(char *s, const char *bad);
144 char *truncate_nl(char *s);
146 #if 0 /// UNNEEDED by elogind
147 static inline char *skip_leading_chars(const char *s, const char *bad) {
155 return (char*) s + strspn(s, bad);
158 char ascii_tolower(char x);
159 char *ascii_strlower(char *s);
160 char *ascii_strlower_n(char *s, size_t n);
162 char ascii_toupper(char x);
163 char *ascii_strupper(char *s);
165 int ascii_strcasecmp_n(const char *a, const char *b, size_t n);
166 int ascii_strcasecmp_nn(const char *a, size_t n, const char *b, size_t m);
168 bool chars_intersect(const char *a, const char *b) _pure_;
171 static inline bool _pure_ in_charset(const char *s, const char* charset) {
174 return s[strspn(s, charset)] == '\0';
177 bool string_has_cc(const char *p, const char *ok) _pure_;
179 char *ellipsize_mem(const char *s, size_t old_length_bytes, size_t new_length_columns, unsigned percent);
180 char *ellipsize(const char *s, size_t length, unsigned percent);
182 bool nulstr_contains(const char *nulstr, const char *needle);
184 char* strshorten(char *s, size_t l);
186 char *strreplace(const char *text, const char *old_string, const char *new_string);
188 char *strip_tab_ansi(char **p, size_t *l);
190 char *strextend_with_separator(char **x, const char *separator, ...) _sentinel_;
192 #define strextend(x, ...) strextend_with_separator(x, NULL, __VA_ARGS__)
194 char *strrep(const char *s, unsigned n);
196 int split_pair(const char *s, const char *sep, char **l, char **r);
198 int free_and_strdup(char **p, const char *s);
200 /* Normal memmem() requires haystack to be nonnull, which is annoying for zero-length buffers */
201 static inline void *memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
204 return (void*) haystack;
206 if (haystacklen < needlelen)
212 return memmem(haystack, haystacklen, needle, needlelen);
215 #if !HAVE_EXPLICIT_BZERO
216 void explicit_bzero(void *p, size_t l);
219 char *string_erase(char *x);
221 char *string_free_erase(char *s);
222 DEFINE_TRIVIAL_CLEANUP_FUNC(char *, string_free_erase);
223 #define _cleanup_string_free_erase_ _cleanup_(string_free_erasep)
225 bool string_is_safe(const char *p) _pure_;
227 static inline size_t strlen_ptr(const char *s) {