]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/basic/string-util.h
shared: replace a few invocations of strcasecmp() for DNS labels with ascii_strcasecm...
[thirdparty/systemd.git] / src / basic / string-util.h
CommitLineData
07630cea
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3#pragma once
4
5/***
6 This file is part of systemd.
7
8 Copyright 2010 Lennart Poettering
9
10 systemd is free software; you can redistribute it and/or modify it
11 under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14
15 systemd is distributed in the hope that it will be useful, but
16 WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 Lesser General Public License for more details.
19
20 You should have received a copy of the GNU Lesser General Public License
21 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22***/
23
11c3a366 24#include <alloca.h>
07630cea 25#include <stdbool.h>
11c3a366 26#include <stddef.h>
07630cea
LP
27#include <string.h>
28
29#include "macro.h"
30
b11d6a7b
LP
31/* What is interpreted as whitespace? */
32#define WHITESPACE " \t\n\r"
33#define NEWLINE "\n\r"
34#define QUOTES "\"\'"
35#define COMMENTS "#;"
36#define GLOB_CHARS "*?["
37#define DIGITS "0123456789"
38#define LOWERCASE_LETTERS "abcdefghijklmnopqrstuvwxyz"
39#define UPPERCASE_LETTERS "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
40#define LETTERS LOWERCASE_LETTERS UPPERCASE_LETTERS
41#define ALPHANUMERICAL LETTERS DIGITS
42
07630cea
LP
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)
47
48int strcmp_ptr(const char *a, const char *b) _pure_;
49
50static inline bool streq_ptr(const char *a, const char *b) {
51 return strcmp_ptr(a, b) == 0;
52}
53
54static inline const char* strempty(const char *s) {
55 return s ? s : "";
56}
57
58static inline const char* strnull(const char *s) {
59 return s ? s : "(null)";
60}
61
62static inline const char *strna(const char *s) {
63 return s ? s : "n/a";
64}
65
66static inline bool isempty(const char *p) {
67 return !p || !p[0];
68}
69
70static inline char *startswith(const char *s, const char *prefix) {
71 size_t l;
72
73 l = strlen(prefix);
74 if (strncmp(s, prefix, l) == 0)
75 return (char*) s + l;
76
77 return NULL;
78}
79
80static inline char *startswith_no_case(const char *s, const char *prefix) {
81 size_t l;
82
83 l = strlen(prefix);
84 if (strncasecmp(s, prefix, l) == 0)
85 return (char*) s + l;
86
87 return NULL;
88}
89
90char *endswith(const char *s, const char *postfix) _pure_;
91char *endswith_no_case(const char *s, const char *postfix) _pure_;
92
93char *first_word(const char *s, const char *word) _pure_;
94
95const char* split(const char **state, size_t *l, const char *separator, bool quoted);
96
97#define FOREACH_WORD(word, length, s, state) \
98 _FOREACH_WORD(word, length, s, WHITESPACE, false, state)
99
100#define FOREACH_WORD_SEPARATOR(word, length, s, separator, state) \
101 _FOREACH_WORD(word, length, s, separator, false, state)
102
103#define FOREACH_WORD_QUOTED(word, length, s, state) \
104 _FOREACH_WORD(word, length, s, WHITESPACE, true, state)
105
106#define _FOREACH_WORD(word, length, s, separator, quoted, state) \
107 for ((state) = (s), (word) = split(&(state), &(length), (separator), (quoted)); (word); (word) = split(&(state), &(length), (separator), (quoted)))
108
109char *strappend(const char *s, const char *suffix);
110char *strnappend(const char *s, const char *suffix, size_t length);
111
112char *strjoin(const char *x, ...) _sentinel_;
113
114#define strjoina(a, ...) \
115 ({ \
116 const char *_appendees_[] = { a, __VA_ARGS__ }; \
117 char *_d_, *_p_; \
118 int _len_ = 0; \
119 unsigned _i_; \
120 for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \
121 _len_ += strlen(_appendees_[_i_]); \
122 _p_ = _d_ = alloca(_len_ + 1); \
123 for (_i_ = 0; _i_ < ELEMENTSOF(_appendees_) && _appendees_[_i_]; _i_++) \
124 _p_ = stpcpy(_p_, _appendees_[_i_]); \
125 *_p_ = 0; \
126 _d_; \
127 })
128
129char *strstrip(char *s);
130char *delete_chars(char *s, const char *bad);
131char *truncate_nl(char *s);
132
b577e3d5
LP
133char ascii_tolower(char x);
134char *ascii_strlower(char *s);
135char *ascii_strlower_n(char *s, size_t n);
07630cea 136
522d85ae
LP
137int ascii_strcasecmp_n(const char *a, const char *b, size_t n);
138
07630cea
LP
139bool chars_intersect(const char *a, const char *b) _pure_;
140
141static inline bool _pure_ in_charset(const char *s, const char* charset) {
142 assert(s);
143 assert(charset);
144 return s[strspn(s, charset)] == '\0';
145}
146
147bool string_has_cc(const char *p, const char *ok) _pure_;
148
149char *ellipsize_mem(const char *s, size_t old_length_bytes, size_t new_length_columns, unsigned percent);
150char *ellipsize(const char *s, size_t length, unsigned percent);
151
152bool nulstr_contains(const char*nulstr, const char *needle);
153
154char* strshorten(char *s, size_t l);
155
156char *strreplace(const char *text, const char *old_string, const char *new_string);
157
158char *strip_tab_ansi(char **p, size_t *l);
159
160char *strextend(char **x, ...) _sentinel_;
161
162char *strrep(const char *s, unsigned n);
163
164int split_pair(const char *s, const char *sep, char **l, char **r);
165
166int free_and_strdup(char **p, const char *s);
167
168/* Normal memmem() requires haystack to be nonnull, which is annoying for zero-length buffers */
169static inline void *memmem_safe(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) {
170
171 if (needlelen <= 0)
172 return (void*) haystack;
173
174 if (haystacklen < needlelen)
175 return NULL;
176
177 assert(haystack);
178 assert(needle);
179
180 return memmem(haystack, haystacklen, needle, needlelen);
181}
182
9fe4ea21
LP
183void* memory_erase(void *p, size_t l);
184char *string_erase(char *x);
07630cea
LP
185
186char *string_free_erase(char *s);
187DEFINE_TRIVIAL_CLEANUP_FUNC(char *, string_free_erase);
188#define _cleanup_string_free_erase_ _cleanup_(string_free_erasep)
f3e2e81d
LP
189
190bool string_is_safe(const char *p) _pure_;