Mercurial > hg > dmlib
comparison src/dmstring.c @ 2027:750a7e125546
Add in several string helper functions from th-libs.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 27 Nov 2018 11:31:10 +0200 |
parents | 47fe47f01fea |
children | eeddaf411083 |
comparison
equal
deleted
inserted
replaced
2026:b137d324e13f | 2027:750a7e125546 |
---|---|
40 | 40 |
41 return result; | 41 return result; |
42 } | 42 } |
43 | 43 |
44 | 44 |
45 /* Compare two strings ignoring case [strcasecmp, strncasecmp] | |
46 */ | |
47 int dm_strcasecmp(const char *haystack, const char *needle) | |
48 { | |
49 const char *s1 = haystack, *s2 = needle; | |
50 assert(haystack != NULL); | |
51 assert(needle != NULL); | |
52 | |
53 if (haystack == needle) | |
54 return 0; | |
55 | |
56 while (*s1 && *s2) | |
57 { | |
58 int k = tolower(*s1) - tolower(*s2); | |
59 if (k != 0) | |
60 return k; | |
61 s1++; | |
62 s2++; | |
63 } | |
64 | |
65 return 0; | |
66 } | |
67 | |
68 | |
69 int dm_strncasecmp(const char *haystack, const char *needle, size_t n) | |
70 { | |
71 const char *s1 = haystack, *s2 = needle; | |
72 assert(haystack != NULL); | |
73 assert(needle != NULL); | |
74 | |
75 if (haystack == needle) | |
76 return 0; | |
77 | |
78 while (n > 0 && *s1 && *s2) | |
79 { | |
80 int k = tolower(*s1) - tolower(*s2); | |
81 if (k != 0) | |
82 return k; | |
83 s1++; | |
84 s2++; | |
85 n--; | |
86 } | |
87 | |
88 return 0; | |
89 } | |
90 | |
91 | |
45 /* Check if end of the given string str matches needle | 92 /* Check if end of the given string str matches needle |
46 * case-insensitively, return pointer to start of the match, | 93 * case-insensitively, return pointer to start of the match, |
47 * if found, NULL otherwise. | 94 * if found, NULL otherwise. |
48 */ | 95 */ |
49 char *dm_strrcasecmp(char *str, const char *needle) | 96 char *dm_strrcasecmp(char *str, const char *needle) |
56 nlen = strlen(needle); | 103 nlen = strlen(needle); |
57 | 104 |
58 if (slen < nlen) | 105 if (slen < nlen) |
59 return NULL; | 106 return NULL; |
60 | 107 |
61 if (strcasecmp(str - nlen - 1, needle) == 0) | 108 if (dm_strcasecmp(str - nlen - 1, needle) == 0) |
62 return str - nlen - 1; | 109 return str - nlen - 1; |
63 else | 110 else |
64 return NULL; | 111 return NULL; |
65 } | 112 } |
66 | 113 |
81 } | 128 } |
82 | 129 |
83 | 130 |
84 /* Implementation of strndup() with NULL check | 131 /* Implementation of strndup() with NULL check |
85 */ | 132 */ |
86 char *dm_strndup(const char *s, const size_t n) | 133 char *dm_strndup(const char *str, const size_t n) |
87 { | 134 { |
88 char *res; | 135 char *res; |
89 if (s == NULL) | 136 if (str == NULL) |
90 return NULL; | 137 return NULL; |
91 | 138 |
92 size_t len = strlen(s); | 139 size_t len = strlen(str); |
93 if (len > n) | 140 if (len > n) |
94 len = n; | 141 len = n; |
95 | 142 |
96 if ((res = dmMalloc(len + 1)) == NULL) | 143 if ((res = dmMalloc(len + 1)) == NULL) |
97 return NULL; | 144 return NULL; |
98 | 145 |
99 memcpy(res, s, len); | 146 memcpy(res, str, len); |
100 res[len] = 0; | 147 res[len] = 0; |
101 | 148 |
102 return res; | 149 return res; |
150 } | |
151 | |
152 | |
153 /* Like strdup, but trims whitespace from the string according to specified flags. | |
154 * See DM_TRIM_* in dmlib.h. If the resulting string would be empty (length 0), | |
155 * NULL is returned. | |
156 */ | |
157 static char * dm_strdup_trim_do(const char *src, size_t len, const int flags) | |
158 { | |
159 char *res; | |
160 size_t start, end; | |
161 | |
162 if (len == 0) | |
163 return NULL; | |
164 | |
165 // Trim start: find first non-whitespace character | |
166 if (flags & DM_TRIM_START) | |
167 for (start = 0; start < len && isspace(src[start]); start++); | |
168 else | |
169 start = 0; | |
170 | |
171 // Trim end: find last non-whitespace character | |
172 if (flags & DM_TRIM_END) | |
173 for (end = len - 1; end > start && isspace(src[end]); end--); | |
174 else | |
175 end = len; | |
176 | |
177 // Allocate memory for result | |
178 if (src[end] == 0 || isspace(src[end])) | |
179 return NULL; | |
180 | |
181 len = end - start + 1; | |
182 if ((res = dmMalloc(len + 1)) == NULL) | |
183 return NULL; | |
184 | |
185 memcpy(res, src + start, len); | |
186 res[len] = 0; | |
187 return res; | |
188 } | |
189 | |
190 | |
191 char *dm_strdup_trim(const char *src, const int flags) | |
192 { | |
193 if (src == NULL) | |
194 return NULL; | |
195 | |
196 return dm_strdup_trim_do(src, strlen(src), flags); | |
197 } | |
198 | |
199 | |
200 char *dm_strndup_trim(const char *src, const size_t n, const int flags) | |
201 { | |
202 size_t len; | |
203 if (src == NULL || n == 0) | |
204 return NULL; | |
205 | |
206 for (len = 0; len < n && src[len]; len++); | |
207 | |
208 return dm_strdup_trim_do(src, len, flags); | |
103 } | 209 } |
104 | 210 |
105 | 211 |
106 /* Simulate a sprintf() that allocates memory | 212 /* Simulate a sprintf() that allocates memory |
107 */ | 213 */ |