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 */
|