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