]> git.ozlabs.org Git - ccan/blob - ccan/str/str.h
tdb2: reduce transaction before writing to recovery area.
[ccan] / ccan / str / str.h
1 #ifndef CCAN_STR_H
2 #define CCAN_STR_H
3 #include "config.h"
4 #include <string.h>
5 #include <stdbool.h>
6 #include <ctype.h>
7
8 /**
9  * streq - Are two strings equal?
10  * @a: first string
11  * @b: first string
12  *
13  * This macro is arguably more readable than "!strcmp(a, b)".
14  *
15  * Example:
16  *      if (streq(somestring, ""))
17  *              printf("String is empty!\n");
18  */
19 #define streq(a,b) (strcmp((a),(b)) == 0)
20
21 /**
22  * strstarts - Does this string start with this prefix?
23  * @str: string to test
24  * @prefix: prefix to look for at start of str
25  *
26  * Example:
27  *      if (strstarts(somestring, "foo"))
28  *              printf("String %s begins with 'foo'!\n", somestring);
29  */
30 #define strstarts(str,prefix) (strncmp((str),(prefix),strlen(prefix)) == 0)
31
32 /**
33  * strends - Does this string end with this postfix?
34  * @str: string to test
35  * @postfix: postfix to look for at end of str
36  *
37  * Example:
38  *      if (strends(somestring, "foo"))
39  *              printf("String %s end with 'foo'!\n", somestring);
40  */
41 static inline bool strends(const char *str, const char *postfix)
42 {
43         if (strlen(str) < strlen(postfix))
44                 return false;
45
46         return streq(str + strlen(str) - strlen(postfix), postfix);
47 }
48
49 /**
50  * stringify - Turn expression into a string literal
51  * @expr: any C expression
52  *
53  * Example:
54  *      #define PRINT_COND_IF_FALSE(cond) \
55  *              ((cond) || printf("%s is false!", stringify(cond)))
56  */
57 #define stringify(expr)         stringify_1(expr)
58 /* Double-indirection required to stringify expansions */
59 #define stringify_1(expr)       #expr
60
61 /**
62  * strcount - Count number of (non-overlapping) occurrences of a substring.
63  * @haystack: a C string
64  * @needle: a substring
65  *
66  * Example:
67  *      int i;
68  *      i = strcount("aaa aaa", "a");  // i = 6;
69  *      i = strcount("aaa aaa", "ab"); // i = 0;
70  *      i = strcount("aaa aaa", "aa"); // i = 2;
71  */
72 size_t strcount(const char *haystack, const char *needle);
73
74 /**
75  * cisalnum - isalnum() which takes a char (and doesn't accept EOF)
76  * @c: a character
77  *
78  * Surprisingly, the standard ctype.h isalnum() takes an int, which
79  * must have the value of EOF (-1) or an unsigned char.  This variant
80  * takes a real char, and doesn't accept EOF.
81  */
82 static inline bool cisalnum(char c)
83 {
84         return isalnum((unsigned char)c);
85 }
86 static inline bool cisalpha(char c)
87 {
88         return isalpha((unsigned char)c);
89 }
90 static inline bool cisascii(char c)
91 {
92         return isascii((unsigned char)c);
93 }
94 #if HAVE_ISBLANK
95 static inline bool cisblank(char c)
96 {
97         return isblank((unsigned char)c);
98 }
99 #endif
100 static inline bool ciscntrl(char c)
101 {
102         return iscntrl((unsigned char)c);
103 }
104 static inline bool cisdigit(char c)
105 {
106         return isdigit((unsigned char)c);
107 }
108 static inline bool cisgraph(char c)
109 {
110         return isgraph((unsigned char)c);
111 }
112 static inline bool cislower(char c)
113 {
114         return islower((unsigned char)c);
115 }
116 static inline bool cisprint(char c)
117 {
118         return isprint((unsigned char)c);
119 }
120 static inline bool cispunct(char c)
121 {
122         return ispunct((unsigned char)c);
123 }
124 static inline bool cisspace(char c)
125 {
126         return isspace((unsigned char)c);
127 }
128 static inline bool cisupper(char c)
129 {
130         return isupper((unsigned char)c);
131 }
132 static inline bool cisxdigit(char c)
133 {
134         return isxdigit((unsigned char)c);
135 }
136
137 #include <ccan/str/str_debug.h>
138
139 /* These checks force things out of line, hence they are under DEBUG. */
140 #ifdef CCAN_STR_DEBUG
141 #include <ccan/build_assert/build_assert.h>
142
143 /* These are commonly misused: they take -1 or an *unsigned* char value. */
144 #undef isalnum
145 #undef isalpha
146 #undef isascii
147 #undef isblank
148 #undef iscntrl
149 #undef isdigit
150 #undef isgraph
151 #undef islower
152 #undef isprint
153 #undef ispunct
154 #undef isspace
155 #undef isupper
156 #undef isxdigit
157
158 /* You can use a char if char is unsigned. */
159 #if HAVE_BUILTIN_TYPES_COMPATIBLE_P && HAVE_TYPEOF
160 #define str_check_arg_(i)                                               \
161         ((i) + BUILD_ASSERT_OR_ZERO(!__builtin_types_compatible_p(typeof(i), \
162                                                                   char) \
163                                     || (char)255 > 0))
164 #else
165 #define str_check_arg_(i) (i)
166 #endif
167
168 #define isalnum(i) str_isalnum(str_check_arg_(i))
169 #define isalpha(i) str_isalpha(str_check_arg_(i))
170 #define isascii(i) str_isascii(str_check_arg_(i))
171 #if HAVE_ISBLANK
172 #define isblank(i) str_isblank(str_check_arg_(i))
173 #endif
174 #define iscntrl(i) str_iscntrl(str_check_arg_(i))
175 #define isdigit(i) str_isdigit(str_check_arg_(i))
176 #define isgraph(i) str_isgraph(str_check_arg_(i))
177 #define islower(i) str_islower(str_check_arg_(i))
178 #define isprint(i) str_isprint(str_check_arg_(i))
179 #define ispunct(i) str_ispunct(str_check_arg_(i))
180 #define isspace(i) str_isspace(str_check_arg_(i))
181 #define isupper(i) str_isupper(str_check_arg_(i))
182 #define isxdigit(i) str_isxdigit(str_check_arg_(i))
183
184 #if HAVE_TYPEOF
185 /* With GNU magic, we can make const-respecting standard string functions. */
186 #undef strstr
187 #undef strchr
188 #undef strrchr
189
190 /* + 0 is needed to decay array into pointer. */
191 #define strstr(haystack, needle)                                        \
192         ((typeof((haystack) + 0))str_strstr((haystack), (needle)))
193 #define strchr(haystack, c)                                     \
194         ((typeof((haystack) + 0))str_strchr((haystack), (c)))
195 #define strrchr(haystack, c)                                    \
196         ((typeof((haystack) + 0))str_strrchr((haystack), (c)))
197 #endif
198 #endif /* CCAN_STR_DEBUG */
199
200 #endif /* CCAN_STR_H */