Branch data Line data Source code
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 : 14406 : static inline bool strends(const char *str, const char *postfix) 44 : : { 45 : 14406 : if (strlen(str) < strlen(postfix)) 46 : 5520 : return false; 47 : : 48 : 8886 : 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 : : #include <ccan/str/str_debug.h> 103 : : 104 : : /* These checks force things out of line, hence they are under DEBUG. */ 105 : : #ifdef CCAN_STR_DEBUG 106 : : #include <ccan/build_assert/build_assert.h> 107 : : 108 : : /* You can use a char if char is unsigned. */ 109 : : #if HAVE_BUILTIN_TYPES_COMPATIBLE_P && HAVE_TYPEOF 110 : : #define str_check_arg_(i) \ 111 : : ((i) + BUILD_ASSERT_OR_ZERO(!__builtin_types_compatible_p(typeof(i), \ 112 : : char) \ 113 : : || (char)255 > 0)) 114 : : #else 115 : : #define str_check_arg_(i) (i) 116 : : #endif 117 : : 118 : : #if HAVE_TYPEOF 119 : : /* With GNU magic, we can make const-respecting standard string functions. */ 120 : : #undef strstr 121 : : #undef strchr 122 : : #undef strrchr 123 : : 124 : : /* + 0 is needed to decay array into pointer. */ 125 : : #define strstr(haystack, needle) \ 126 : : ((typeof((haystack) + 0))str_strstr((haystack), (needle))) 127 : : #define strchr(haystack, c) \ 128 : : ((typeof((haystack) + 0))str_strchr((haystack), (c))) 129 : : #define strrchr(haystack, c) \ 130 : : ((typeof((haystack) + 0))str_strrchr((haystack), (c))) 131 : : #endif 132 : : #endif /* CCAN_STR_DEBUG */ 133 : : 134 : : #endif /* CCAN_STR_H */