Mercurial > hg > th-libs
comparison th_string.c @ 14:e5e6370217ef
Various cleanups, additions and removals.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 30 Oct 2010 17:47:41 +0300 |
parents | a25f5d22483e |
children | 1f7d8693fda8 |
comparison
equal
deleted
inserted
replaced
13:adcbcac66125 | 14:e5e6370217ef |
---|---|
7 */ | 7 */ |
8 #ifdef HAVE_CONFIG_H | 8 #ifdef HAVE_CONFIG_H |
9 #include "config.h" | 9 #include "config.h" |
10 #endif | 10 #endif |
11 #include "th_string.h" | 11 #include "th_string.h" |
12 | |
13 #define LPREV (pNode->pPrev) | |
14 #define LNEXT (pNode->pNext) | |
15 | |
16 | 12 |
17 /* strdup with a NULL check | 13 /* strdup with a NULL check |
18 */ | 14 */ |
19 char *th_strdup(const char *s) | 15 char *th_strdup(const char *s) |
20 { | 16 { |
28 strcpy(res, s); | 24 strcpy(res, s); |
29 return res; | 25 return res; |
30 } | 26 } |
31 | 27 |
32 | 28 |
33 /* Allocate memory for a string with given length | 29 char *th_strncpy(char * dst, const char * src, const size_t n) |
34 */ | |
35 char *th_stralloc(const size_t l) | |
36 { | |
37 assert(l > 0); | |
38 return th_malloc(sizeof(char) * l); | |
39 } | |
40 | |
41 | |
42 char *th_strrealloc(char * s, const size_t l) | |
43 { | |
44 assert(l > 0); | |
45 return th_realloc(s, sizeof(char) * l); | |
46 } | |
47 | |
48 | |
49 char *th_strncpy(char * dst, const char * src, size_t n) | |
50 { | 30 { |
51 const char *s = src; | 31 const char *s = src; |
52 char *d = dst; | 32 char *d = dst; |
53 size_t i; | 33 size_t i; |
54 assert(src != NULL); | 34 assert(src != NULL); |
55 assert(dst != NULL); | 35 assert(dst != NULL); |
56 | 36 |
57 /* Copy to the destination */ | 37 /* Copy to the destination */ |
58 i = n; | 38 i = n; |
59 while (*s && (i > 0)) { | 39 while (*s && i > 0) { |
60 *(d++) = *(s++); | 40 *(d++) = *(s++); |
61 i--; | 41 i--; |
62 } | 42 } |
63 | 43 |
64 /* Fill rest of space with zeros */ | 44 /* Fill rest of space with zeros */ |
72 | 52 |
73 return dst; | 53 return dst; |
74 } | 54 } |
75 | 55 |
76 | 56 |
77 int th_strncmp(char * str1, char * str2, size_t n) | 57 /* Simulate a sprintf() that allocates memory |
78 { | 58 */ |
79 char *s1, *s2; | 59 char * th_strdup_vprintf(const char *fmt, va_list args) |
60 { | |
61 int size = 100; | |
62 char *buf, *nbuf = NULL; | |
63 | |
64 if ((buf = th_malloc(size)) == NULL) | |
65 return NULL; | |
66 | |
67 while (1) { | |
68 int n = vsnprintf(buf, size, fmt, args); | |
69 if (n > -1 && n < size) | |
70 return buf; | |
71 if (n > -1) | |
72 size = n + 1; | |
73 else | |
74 size *= 2; | |
75 | |
76 if ((nbuf = th_realloc(nbuf, size)) == NULL) { | |
77 th_free(buf); | |
78 return NULL; | |
79 } | |
80 | |
81 buf = nbuf; | |
82 } | |
83 } | |
84 | |
85 | |
86 char * th_strdup_printf(const char *fmt, ...) | |
87 { | |
88 char *res; | |
89 va_list ap; | |
90 | |
91 va_start(ap, fmt); | |
92 res = th_strdup_vprintf(fmt, ap); | |
93 va_end(ap); | |
94 | |
95 return res; | |
96 } | |
97 | |
98 | |
99 /* Compare two strings ignoring case [strcasecmp, strncasecmp] | |
100 */ | |
101 int th_strcasecmp(const char * str1, const char * str2) | |
102 { | |
103 const char *s1 = str1, *s2 = str2; | |
80 assert(str1 != NULL); | 104 assert(str1 != NULL); |
81 assert(str2 != NULL); | 105 assert(str2 != NULL); |
82 | 106 |
83 /* Check the string pointers */ | |
84 if (str1 == str2) | 107 if (str1 == str2) |
85 return 0; | 108 return 0; |
86 | 109 |
87 /* Go through the string */ | 110 while (*s1 && *s2 && th_tolower(*s1) == th_tolower(*s2)) { |
88 s1 = str1; | 111 s1++; |
89 s2 = str2; | 112 s2++; |
90 while ((n > 0) && *s1 && *s2 && (*s1 == *s2)) { | 113 } |
114 | |
115 return (th_tolower(*s1) - th_tolower(*s2)); | |
116 } | |
117 | |
118 | |
119 int th_strncasecmp(const char * str1, const char * str2, size_t n) | |
120 { | |
121 const char *s1 = str1, *s2 = str2; | |
122 assert(str1 != NULL); | |
123 assert(str2 != NULL); | |
124 | |
125 if (str1 == str2) | |
126 return 0; | |
127 | |
128 while (n > 0 && *s1 && *s2 && th_tolower(*s1) == th_tolower(*s2)) { | |
91 s1++; | 129 s1++; |
92 s2++; | 130 s2++; |
93 n--; | 131 n--; |
94 } | 132 } |
95 | 133 |
96 if (n > 0) | 134 return n > 0 ? (th_tolower(*s1) - th_tolower(*s2)) : 0; |
97 return ((*s1) - (*s2)); | |
98 else | |
99 return 0; | |
100 } | |
101 | |
102 | |
103 /* Compare two strings ignoring case [strcasecmp, strncasecmp] | |
104 */ | |
105 int th_strcasecmp(char * str1, char * str2) | |
106 { | |
107 char *s1 = str1, *s2 = str2; | |
108 assert(str1 != NULL); | |
109 assert(str2 != NULL); | |
110 | |
111 /* Check the string pointers */ | |
112 if (str1 == str2) | |
113 return 0; | |
114 | |
115 /* Go through the string */ | |
116 while (*s1 && *s2 && (th_tolower(*s1) == th_tolower(*s2))) { | |
117 s1++; | |
118 s2++; | |
119 } | |
120 | |
121 return (th_tolower(*s1) - th_tolower(*s2)); | |
122 } | |
123 | |
124 | |
125 int th_strncasecmp(char * str1, char * str2, size_t n) | |
126 { | |
127 char *s1 = str1, *s2 = str2; | |
128 assert(str1 != NULL); | |
129 assert(str2 != NULL); | |
130 | |
131 /* Check the string pointers */ | |
132 if (str1 == str2) | |
133 return 0; | |
134 | |
135 /* Go through the string */ | |
136 while ((n > 0) && *s1 && *s2 && (th_tolower(*s1) == th_tolower(*s2))) { | |
137 s1++; | |
138 s2++; | |
139 n--; | |
140 } | |
141 | |
142 if (n > 0) | |
143 return (th_tolower(*s1) - th_tolower(*s2)); | |
144 else | |
145 return 0; | |
146 } | 135 } |
147 | 136 |
148 | 137 |
149 /* Remove all occurences of control characters, in-place. | 138 /* Remove all occurences of control characters, in-place. |
150 * Resulting string is always shorter or same length than original. | 139 * Resulting string is always shorter or same length than original. |
166 } | 155 } |
167 | 156 |
168 | 157 |
169 /* Copy a given string over in *result. | 158 /* Copy a given string over in *result. |
170 */ | 159 */ |
171 int th_pstrcpy(char ** result, char * str) | 160 int th_pstrcpy(char ** result, const char * str) |
172 { | 161 { |
173 assert(result != NULL); | 162 assert(result != NULL); |
174 | 163 |
175 /* Check the string pointers */ | |
176 if (str == NULL) | 164 if (str == NULL) |
177 return -1; | 165 return -1; |
178 | 166 |
179 /* Allocate memory for destination */ | |
180 th_free(*result); | 167 th_free(*result); |
181 *result = th_stralloc(strlen(str) + 1); | 168 if ((*result = th_malloc(strlen(str) + 1)) == NULL) |
182 if (!*result) | |
183 return -2; | 169 return -2; |
184 | 170 |
185 /* Copy to the destination */ | |
186 strcpy(*result, str); | 171 strcpy(*result, str); |
187 | |
188 return 0; | 172 return 0; |
189 } | 173 } |
190 | 174 |
191 | 175 |
192 /* Concatenates a given string into string pointed by *result. | 176 /* Concatenates a given string into string pointed by *result. |
193 */ | 177 */ |
194 int th_pstrcat(char ** result, char * str) | 178 int th_pstrcat(char ** result, const char * str) |
195 { | 179 { |
196 assert(result != NULL); | 180 assert(result != NULL); |
197 | 181 |
198 /* Check the string pointers */ | |
199 if (str == NULL) | 182 if (str == NULL) |
200 return -1; | 183 return -1; |
201 | 184 |
202 if (*result != NULL) { | 185 if (*result != NULL) { |
203 *result = th_strrealloc(*result, strlen(*result) + strlen(str) + 1); | 186 *result = th_realloc(*result, strlen(*result) + strlen(str) + 1); |
204 if (*result == NULL) | 187 if (*result == NULL) |
205 return -1; | 188 return -1; |
206 | 189 |
207 strcat(*result, str); | 190 strcat(*result, str); |
208 } else { | 191 } else { |
209 *result = th_stralloc(strlen(str) + 1); | 192 *result = th_malloc(strlen(str) + 1); |
210 if (*result == NULL) | 193 if (*result == NULL) |
211 return -1; | 194 return -1; |
212 | 195 |
213 strcpy(*result, str); | 196 strcpy(*result, str); |
214 } | 197 } |
219 | 202 |
220 /* Find next non-whitespace character in string. | 203 /* Find next non-whitespace character in string. |
221 * Updates iPos into the position of such character and | 204 * Updates iPos into the position of such character and |
222 * returns pointer to the string. | 205 * returns pointer to the string. |
223 */ | 206 */ |
224 char *th_findnext(char * str, size_t * iPos) | 207 const char *th_findnext(const char * str, size_t * pos) |
225 { | 208 { |
226 assert(str != NULL); | 209 assert(str != NULL); |
227 | 210 |
228 /* Terminating NULL-character is not whitespace! */ | 211 /* Terminating NULL-character is not whitespace! */ |
229 while (th_isspace(str[*iPos])) | 212 while (th_isspace(str[*pos])) |
230 (*iPos)++; | 213 (*pos)++; |
231 return &str[*iPos]; | 214 return &str[*pos]; |
232 } | 215 } |
233 | 216 |
234 | 217 |
235 /* Find next chSep-character from string | 218 /* Find next sep-character from string |
236 */ | 219 */ |
237 char *th_findsep(char * str, size_t * iPos, char chSep) | 220 const char *th_findsep(const char * str, size_t * pos, char sep) |
238 { | 221 { |
239 assert(str != NULL); | 222 assert(str != NULL); |
240 | 223 |
241 /* Terminating NULL-character is not digit! */ | 224 while (str[*pos] && str[*pos] != sep) |
242 while (str[*iPos] && (str[*iPos] != chSep)) | 225 (*pos)++; |
243 (*iPos)++; | 226 |
244 return &str[*iPos]; | 227 return &str[*pos]; |
245 } | 228 } |
246 | 229 |
247 | 230 |
248 /* Find next chSep- or whitespace from string | 231 /* Find next sep- or whitespace from string |
249 */ | 232 */ |
250 char *th_findseporspace(char * str, size_t * iPos, char chSep) | 233 const char *th_findseporspace(const char * str, size_t * pos, char sep) |
251 { | 234 { |
252 assert(str != NULL); | 235 assert(str != NULL); |
253 | 236 |
254 /* Terminating NULL-character is not digit! */ | 237 while (!th_isspace(str[*pos]) && str[*pos] != sep) |
255 while (!th_isspace(str[*iPos]) && (str[*iPos] != chSep)) | 238 (*pos)++; |
256 (*iPos)++; | 239 |
257 return &str[*iPos]; | 240 return &str[*pos]; |
258 } | 241 } |
259 | 242 |
260 | 243 |
261 /* Compare a string to a pattern. Case-SENSITIVE version. | 244 /* Compare a string to a pattern. Case-SENSITIVE version. |
262 * The matching pattern can consist of any normal characters plus | 245 * The matching pattern can consist of any normal characters plus |
263 * wildcards ? and *. "?" matches any character and "*" matches | 246 * wildcards ? and *. "?" matches any character and "*" matches |
264 * any number of characters. | 247 * any number of characters. |
265 */ | 248 */ |
266 BOOL th_strmatch(char * str, char * pattern) | 249 BOOL th_strmatch(const char * str, const char * pattern) |
267 { | 250 { |
268 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; | 251 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; |
269 char *tmpPattern = NULL; | 252 const char *tmpPattern = NULL; |
270 | 253 |
271 /* Check given pattern and string */ | 254 /* Check given pattern and string */ |
272 if (str == NULL || pattern == NULL) | 255 if (str == NULL || pattern == NULL) |
273 return FALSE; | 256 return FALSE; |
274 | 257 |
350 } | 333 } |
351 | 334 |
352 | 335 |
353 /* Compare a string to a pattern. Case-INSENSITIVE version. | 336 /* Compare a string to a pattern. Case-INSENSITIVE version. |
354 */ | 337 */ |
355 BOOL th_strcasematch(char * str, char * pattern) | 338 BOOL th_strcasematch(const char * str, const char * pattern) |
356 { | 339 { |
357 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; | 340 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; |
358 char *tmpPattern = NULL; | 341 const char *tmpPattern = NULL; |
359 | 342 |
360 /* Check given pattern and string */ | 343 /* Check given pattern and string */ |
361 if (str == NULL || pattern == NULL) | 344 if (str == NULL || pattern == NULL) |
362 return FALSE; | 345 return FALSE; |
363 | 346 |
433 } while (didMatch && !isEnd); | 416 } while (didMatch && !isEnd); |
434 | 417 |
435 return didMatch; | 418 return didMatch; |
436 } | 419 } |
437 | 420 |
421 | |
422 int th_get_hex_triplet(const char *str) | |
423 { | |
424 const char *p = str; | |
425 int len, val = 0; | |
426 | |
427 for (len = 0; *p && len < 6; p++, len++) { | |
428 if (*p >= '0' && *p <= '9') { | |
429 val *= 16; val += (*p - '0'); | |
430 } else if (*p >= 'A' && *p <= 'F') { | |
431 val *= 16; val += (*p - 'A') + 10; | |
432 } else if (*p >= 'a' && *p <= 'f') { | |
433 val *= 16; val += (*p - 'a') + 10; | |
434 } else | |
435 return -1; | |
436 } | |
437 | |
438 return (len == 6) ? val : -1; | |
439 } | |
440 | |
441 |