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