comparison th_string.c @ 81:69aed051f84d

Synced th-libs.
author Matti Hamalainen <ccr@tnsp.org>
date Mon, 20 Apr 2009 22:02:37 +0300
parents e36df57c5b0f
children fe4d5f3b486c
comparison
equal deleted inserted replaced
80:335b5a74c22e 81:69aed051f84d
16 16
17 /* strdup with a NULL check 17 /* strdup with a NULL check
18 */ 18 */
19 char *th_strdup(const char *s) 19 char *th_strdup(const char *s)
20 { 20 {
21 char *res; 21 char *res;
22 if (s == NULL) 22 if (s == NULL)
23 return NULL; 23 return NULL;
24 24
25 if ((res = th_malloc(strlen(s) + 1)) == NULL) 25 if ((res = th_malloc(strlen(s) + 1)) == NULL)
26 return NULL; 26 return NULL;
27 27
28 strcpy(res, s); 28 strcpy(res, s);
29 return res; 29 return res;
30 } 30 }
31 31
32 32
33 /* Allocate memory for a string with given length 33 /* Allocate memory for a string with given length
34 */ 34 */
35 char *th_stralloc(const size_t l) 35 char *th_stralloc(const size_t l)
36 { 36 {
37 assert(l > 0); 37 assert(l > 0);
38 return th_malloc(sizeof(char) * l); 38 return th_malloc(sizeof(char) * l);
39 } 39 }
40 40
41 41
42 char *th_strrealloc(char * s, const size_t l) 42 char *th_strrealloc(char * s, const size_t l)
43 { 43 {
44 assert(l > 0); 44 assert(l > 0);
45 return th_realloc(s, sizeof(char) * l); 45 return th_realloc(s, sizeof(char) * l);
46 } 46 }
47 47
48 48
49 char *th_strncpy(char * dst, const char * src, size_t n) 49 char *th_strncpy(char * dst, const char * src, size_t n)
50 { 50 {
51 const char *s = src; 51 const char *s = src;
52 char *d = dst; 52 char *d = dst;
53 size_t i; 53 size_t i;
54 assert(src != NULL); 54 assert(src != NULL);
55 assert(dst != NULL); 55 assert(dst != NULL);
56 56
57 /* Copy to the destination */ 57 /* Copy to the destination */
58 i = n; 58 i = n;
59 while (*s && (i > 0)) { 59 while (*s && (i > 0)) {
60 *(d++) = *(s++); 60 *(d++) = *(s++);
61 i--; 61 i--;
62 } 62 }
63 63
64 /* Fill rest of space with zeros */ 64 /* Fill rest of space with zeros */
65 while (i > 0) { 65 while (i > 0) {
66 *(d++) = 0; 66 *(d++) = 0;
67 i--; 67 i--;
68 } 68 }
69 69
70 /* Ensure that last is always zero */ 70 /* Ensure that last is always zero */
71 dst[n - 1] = 0; 71 dst[n - 1] = 0;
72 72
73 return dst; 73 return dst;
74 } 74 }
75 75
76 76
77 int th_strncmp(char * str1, char * str2, size_t n) 77 int th_strncmp(char * str1, char * str2, size_t n)
78 { 78 {
79 char *s1, *s2; 79 char *s1, *s2;
80 assert(str1 != NULL); 80 assert(str1 != NULL);
81 assert(str2 != NULL); 81 assert(str2 != NULL);
82 82
83 /* Check the string pointers */ 83 /* Check the string pointers */
84 if (str1 == str2) 84 if (str1 == str2)
85 return 0; 85 return 0;
86 86
87 /* Go through the string */ 87 /* Go through the string */
88 s1 = str1; 88 s1 = str1;
89 s2 = str2; 89 s2 = str2;
90 while ((n > 0) && *s1 && *s2 && (*s1 == *s2)) { 90 while ((n > 0) && *s1 && *s2 && (*s1 == *s2)) {
91 s1++; 91 s1++;
92 s2++; 92 s2++;
93 n--; 93 n--;
94 } 94 }
95 95
96 if (n > 0) 96 if (n > 0)
97 return ((*s1) - (*s2)); 97 return ((*s1) - (*s2));
98 else 98 else
99 return 0; 99 return 0;
100 } 100 }
101 101
102 102
103 /* Compare two strings ignoring case [strcasecmp, strncasecmp] 103 /* Compare two strings ignoring case [strcasecmp, strncasecmp]
104 */ 104 */
105 int th_strcasecmp(char * str1, char * str2) 105 int th_strcasecmp(char * str1, char * str2)
106 { 106 {
107 char *s1 = str1, *s2 = str2; 107 char *s1 = str1, *s2 = str2;
108 assert(str1 != NULL); 108 assert(str1 != NULL);
109 assert(str2 != NULL); 109 assert(str2 != NULL);
110 110
111 /* Check the string pointers */ 111 /* Check the string pointers */
112 if (str1 == str2) 112 if (str1 == str2)
113 return 0; 113 return 0;
114 114
115 /* Go through the string */ 115 /* Go through the string */
116 while (*s1 && *s2 && (th_tolower(*s1) == th_tolower(*s2))) { 116 while (*s1 && *s2 && (th_tolower(*s1) == th_tolower(*s2))) {
117 s1++; 117 s1++;
118 s2++; 118 s2++;
119 } 119 }
120 120
121 return (th_tolower(*s1) - th_tolower(*s2)); 121 return (th_tolower(*s1) - th_tolower(*s2));
122 } 122 }
123 123
124 124
125 int th_strncasecmp(char * str1, char * str2, size_t n) 125 int th_strncasecmp(char * str1, char * str2, size_t n)
126 { 126 {
127 char *s1 = str1, *s2 = str2; 127 char *s1 = str1, *s2 = str2;
128 assert(str1 != NULL); 128 assert(str1 != NULL);
129 assert(str2 != NULL); 129 assert(str2 != NULL);
130 130
131 /* Check the string pointers */ 131 /* Check the string pointers */
132 if (str1 == str2) 132 if (str1 == str2)
133 return 0; 133 return 0;
134 134
135 /* Go through the string */ 135 /* Go through the string */
136 while ((n > 0) && *s1 && *s2 && (th_tolower(*s1) == th_tolower(*s2))) { 136 while ((n > 0) && *s1 && *s2 && (th_tolower(*s1) == th_tolower(*s2))) {
137 s1++; 137 s1++;
138 s2++; 138 s2++;
139 n--; 139 n--;
140 } 140 }
141 141
142 if (n > 0) 142 if (n > 0)
143 return (th_tolower(*s1) - th_tolower(*s2)); 143 return (th_tolower(*s1) - th_tolower(*s2));
144 else 144 else
145 return 0; 145 return 0;
146 } 146 }
147 147
148 148
149 /* Remove all occurences of control characters, in-place. 149 /* Remove all occurences of control characters, in-place.
150 * Resulting string is always shorter or same length than original. 150 * Resulting string is always shorter or same length than original.
151 */ 151 */
152 void th_strip_ctrlchars(char * str) 152 void th_strip_ctrlchars(char * str)
153 { 153 {
154 char *i, *j; 154 char *i, *j;
155 assert(str != NULL); 155 assert(str != NULL);
156 156
157 i = str; 157 i = str;
158 j = str; 158 j = str;
159 while (*i) { 159 while (*i) {
160 if (!th_iscntrl(*i)) 160 if (!th_iscntrl(*i))
161 *(j++) = *i; 161 *(j++) = *i;
162 i++; 162 i++;
163 } 163 }
164 164
165 *j = 0; 165 *j = 0;
166 } 166 }
167 167
168 168
169 /* Copy a given string over in *result. 169 /* Copy a given string over in *result.
170 */ 170 */
171 int th_pstrcpy(char ** result, char * str) 171 int th_pstrcpy(char ** result, char * str)
172 { 172 {
173 assert(result != NULL); 173 assert(result != NULL);
174 174
175 /* Check the string pointers */ 175 /* Check the string pointers */
176 if (str == NULL) 176 if (str == NULL)
177 return -1; 177 return -1;
178 178
179 /* Allocate memory for destination */ 179 /* Allocate memory for destination */
180 th_free(*result); 180 th_free(*result);
181 *result = th_stralloc(strlen(str) + 1); 181 *result = th_stralloc(strlen(str) + 1);
182 if (!*result) 182 if (!*result)
183 return -2; 183 return -2;
184 184
185 /* Copy to the destination */ 185 /* Copy to the destination */
186 strcpy(*result, str); 186 strcpy(*result, str);
187 187
188 return 0; 188 return 0;
189 } 189 }
190 190
191 191
192 /* Concatenates a given string into string pointed by *result. 192 /* Concatenates a given string into string pointed by *result.
193 */ 193 */
194 int th_pstrcat(char ** result, char * str) 194 int th_pstrcat(char ** result, char * str)
195 { 195 {
196 assert(result != NULL); 196 assert(result != NULL);
197 197
198 /* Check the string pointers */ 198 /* Check the string pointers */
199 if (str == NULL) 199 if (str == NULL)
200 return -1; 200 return -1;
201 201
202 if (*result != NULL) { 202 if (*result != NULL) {
203 *result = th_strrealloc(*result, strlen(*result) + strlen(str) + 1); 203 *result = th_strrealloc(*result, strlen(*result) + strlen(str) + 1);
204 if (*result == NULL) 204 if (*result == NULL)
205 return -1; 205 return -1;
206 206
207 strcat(*result, str); 207 strcat(*result, str);
208 } else { 208 } else {
209 *result = th_stralloc(strlen(str) + 1); 209 *result = th_stralloc(strlen(str) + 1);
210 if (*result == NULL) 210 if (*result == NULL)
211 return -1; 211 return -1;
212 212
213 strcpy(*result, str); 213 strcpy(*result, str);
214 } 214 }
215 215
216 return 0; 216 return 0;
217 } 217 }
218 218
219 219
220 /* Find next non-whitespace character in string. 220 /* Find next non-whitespace character in string.
221 * Updates iPos into the position of such character and 221 * Updates iPos into the position of such character and
222 * returns pointer to the string. 222 * returns pointer to the string.
223 */ 223 */
224 char *th_findnext(char * str, size_t * iPos) 224 char *th_findnext(char * str, size_t * iPos)
225 { 225 {
226 assert(str != NULL); 226 assert(str != NULL);
227 227
228 /* Terminating NULL-character is not whitespace! */ 228 /* Terminating NULL-character is not whitespace! */
229 while (th_isspace(str[*iPos])) 229 while (th_isspace(str[*iPos]))
230 (*iPos)++; 230 (*iPos)++;
231 return &str[*iPos]; 231 return &str[*iPos];
232 } 232 }
233 233
234 234
235 /* Find next chSep-character from string 235 /* Find next chSep-character from string
236 */ 236 */
237 char *th_findsep(char * str, size_t * iPos, char chSep) 237 char *th_findsep(char * str, size_t * iPos, char chSep)
238 { 238 {
239 assert(str != NULL); 239 assert(str != NULL);
240 240
241 /* Terminating NULL-character is not digit! */ 241 /* Terminating NULL-character is not digit! */
242 while (str[*iPos] && (str[*iPos] != chSep)) 242 while (str[*iPos] && (str[*iPos] != chSep))
243 (*iPos)++; 243 (*iPos)++;
244 return &str[*iPos]; 244 return &str[*iPos];
245 } 245 }
246 246
247 247
248 /* Find next chSep- or whitespace from string 248 /* Find next chSep- or whitespace from string
249 */ 249 */
250 char *th_findseporspace(char * str, size_t * iPos, char chSep) 250 char *th_findseporspace(char * str, size_t * iPos, char chSep)
251 { 251 {
252 assert(str != NULL); 252 assert(str != NULL);
253 253
254 /* Terminating NULL-character is not digit! */ 254 /* Terminating NULL-character is not digit! */
255 while (!th_isspace(str[*iPos]) && (str[*iPos] != chSep)) 255 while (!th_isspace(str[*iPos]) && (str[*iPos] != chSep))
256 (*iPos)++; 256 (*iPos)++;
257 return &str[*iPos]; 257 return &str[*iPos];
258 } 258 }
259 259
260 260
261 /* Compare a string to a pattern. Case-SENSITIVE version. 261 /* Compare a string to a pattern. Case-SENSITIVE version.
262 * The matching pattern can consist of any normal characters plus 262 * The matching pattern can consist of any normal characters plus
263 * wildcards ? and *. "?" matches any character and "*" matches 263 * wildcards ? and *. "?" matches any character and "*" matches
264 * any number of characters. 264 * any number of characters.
265 */ 265 */
266 BOOL th_strmatch(char * str, char * pattern) 266 BOOL th_strmatch(char * str, char * pattern)
267 { 267 {
268 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; 268 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE;
269 char *tmpPattern = NULL; 269 char *tmpPattern = NULL;
270 270
271 /* Check given pattern and string */ 271 /* Check given pattern and string */
272 if (str == NULL || pattern == NULL) 272 if (str == NULL || pattern == NULL)
273 return FALSE; 273 return FALSE;
274 274
275 /* Start comparision */ 275 /* Start comparision */
276 do { 276 do {
277 didMatch = FALSE; 277 didMatch = FALSE;
278 switch (*pattern) { 278 switch (*pattern) {
279 case '?': 279 case '?':
280 /* Any single character matches */ 280 /* Any single character matches */
281 if (*str) { 281 if (*str) {
282 didMatch = TRUE; 282 didMatch = TRUE;
283 pattern++; 283 pattern++;
284 str++; 284 str++;
285 } 285 }
286 break; 286 break;
287 287
288 case '*': 288 case '*':
289 didMatch = TRUE; 289 didMatch = TRUE;
290 pattern++; 290 pattern++;
291 if (!*pattern) 291 if (!*pattern)
292 isEnd = TRUE; 292 isEnd = TRUE;
293 isAnyMode = TRUE; 293 isAnyMode = TRUE;
294 tmpPattern = pattern; 294 tmpPattern = pattern;
295 break; 295 break;
296 296
297 case 0: 297 case 0:
298 if (isAnyMode) { 298 if (isAnyMode) {
299 if (*str) 299 if (*str)
300 str++; 300 str++;
301 else 301 else
302 isEnd = TRUE; 302 isEnd = TRUE;
303 } else { 303 } else {
304 if (*str) { 304 if (*str) {
305 if (tmpPattern) { 305 if (tmpPattern) {
306 isAnyMode = TRUE; 306 isAnyMode = TRUE;
307 pattern = tmpPattern; 307 pattern = tmpPattern;
308 } else 308 } else
309 didMatch = FALSE; 309 didMatch = FALSE;
310 } else 310 } else
311 isEnd = TRUE; 311 isEnd = TRUE;
312 } 312 }
313 break; 313 break;
314 default: 314 default:
315 if (isAnyMode) { 315 if (isAnyMode) {
316 if (*pattern == *str) { 316 if (*pattern == *str) {
317 isAnyMode = FALSE; 317 isAnyMode = FALSE;
318 didMatch = TRUE; 318 didMatch = TRUE;
319 } else { 319 } else {
320 if (*str) { 320 if (*str) {
321 didMatch = TRUE; 321 didMatch = TRUE;
322 str++; 322 str++;
323 } 323 }
324 } 324 }
325 } else { 325 } else {
326 if (*pattern == *str) { 326 if (*pattern == *str) {
327 didMatch = TRUE; 327 didMatch = TRUE;
328 if (*pattern) 328 if (*pattern)
329 pattern++; 329 pattern++;
330 if (*str) 330 if (*str)
331 str++; 331 str++;
332 } else { 332 } else {
333 if (tmpPattern) { 333 if (tmpPattern) {
334 didMatch = TRUE; 334 didMatch = TRUE;
335 isAnyMode = TRUE; 335 isAnyMode = TRUE;
336 pattern = tmpPattern; 336 pattern = tmpPattern;
337 } 337 }
338 } 338 }
339 } 339 }
340 340
341 if (!*str && !*pattern) 341 if (!*str && !*pattern)
342 isEnd = TRUE; 342 isEnd = TRUE;
343 break; 343 break;
344 344
345 } /* switch */ 345 } /* switch */
346 346
347 } while (didMatch && !isEnd); 347 } while (didMatch && !isEnd);
348 348
349 return didMatch; 349 return didMatch;
350 } 350 }
351 351
352 352
353 /* Compare a string to a pattern. Case-INSENSITIVE version. 353 /* Compare a string to a pattern. Case-INSENSITIVE version.
354 */ 354 */
355 BOOL th_strcasematch(char * str, char * pattern) 355 BOOL th_strcasematch(char * str, char * pattern)
356 { 356 {
357 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; 357 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE;
358 char *tmpPattern = NULL; 358 char *tmpPattern = NULL;
359 359
360 /* Check given pattern and string */ 360 /* Check given pattern and string */
361 if (str == NULL || pattern == NULL) 361 if (str == NULL || pattern == NULL)
362 return FALSE; 362 return FALSE;
363 363
364 /* Start comparision */ 364 /* Start comparision */
365 do { 365 do {
366 switch (*pattern) { 366 switch (*pattern) {
367 case '?': 367 case '?':
368 /* Any single character matches */ 368 /* Any single character matches */
369 if (*str) { 369 if (*str) {
370 pattern++; 370 pattern++;
371 str++; 371 str++;
372 } else 372 } else
373 didMatch = FALSE; 373 didMatch = FALSE;
374 break; 374 break;
375 375
376 case '*': 376 case '*':
377 pattern++; 377 pattern++;
378 if (!*pattern || *pattern == '?') 378 if (!*pattern || *pattern == '?')
379 isEnd = TRUE; 379 isEnd = TRUE;
380 isAnyMode = TRUE; 380 isAnyMode = TRUE;
381 tmpPattern = pattern; 381 tmpPattern = pattern;
382 break; 382 break;
383 383
384 case 0: 384 case 0:
385 if (isAnyMode) { 385 if (isAnyMode) {
386 if (*str) 386 if (*str)
387 str++; 387 str++;
388 else 388 else
389 isEnd = TRUE; 389 isEnd = TRUE;
390 } else { 390 } else {
391 if (*str) { 391 if (*str) {
392 if (tmpPattern) { 392 if (tmpPattern) {
393 isAnyMode = TRUE; 393 isAnyMode = TRUE;
394 pattern = tmpPattern; 394 pattern = tmpPattern;
395 } else 395 } else
396 didMatch = FALSE; 396 didMatch = FALSE;
397 } else 397 } else
398 isEnd = TRUE; 398 isEnd = TRUE;
399 } 399 }
400 break; 400 break;
401 401
402 default: 402 default:
403 if (isAnyMode) { 403 if (isAnyMode) {
404 if (th_tolower(*pattern) == th_tolower(*str)) { 404 if (th_tolower(*pattern) == th_tolower(*str)) {
405 isAnyMode = FALSE; 405 isAnyMode = FALSE;
406 } else { 406 } else {
407 if (*str) 407 if (*str)
408 str++; 408 str++;
409 else 409 else
410 didMatch = FALSE; 410 didMatch = FALSE;
411 } 411 }
412 } else { 412 } else {
413 if (th_tolower(*pattern) == th_tolower(*str)) { 413 if (th_tolower(*pattern) == th_tolower(*str)) {
414 if (*pattern) 414 if (*pattern)
415 pattern++; 415 pattern++;
416 if (*str) 416 if (*str)
417 str++; 417 str++;
418 } else { 418 } else {
419 if (tmpPattern) { 419 if (tmpPattern) {
420 isAnyMode = TRUE; 420 isAnyMode = TRUE;
421 pattern = tmpPattern; 421 pattern = tmpPattern;
422 } else 422 } else
423 didMatch = FALSE; 423 didMatch = FALSE;
424 } 424 }
425 } 425 }
426 426
427 if (!*str && !*pattern) 427 if (!*str && !*pattern)
428 isEnd = TRUE; 428 isEnd = TRUE;
429 break; 429 break;
430 430
431 } /* switch */ 431 } /* switch */
432 432
433 } while (didMatch && !isEnd); 433 } while (didMatch && !isEnd);
434 434
435 return didMatch; 435 return didMatch;
436 } 436 }
437 437