Mercurial > hg > nnchat
comparison th_string.c @ 378:afbc3bfd3e03
Sync th-libs.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 03 Oct 2011 00:31:46 +0300 |
parents | 9ad157feb99a |
children |
comparison
equal
deleted
inserted
replaced
377:9ad157feb99a | 378:afbc3bfd3e03 |
---|---|
15 char *th_strdup(const char *s) | 15 char *th_strdup(const char *s) |
16 { | 16 { |
17 char *res; | 17 char *res; |
18 if (s == NULL) | 18 if (s == NULL) |
19 return NULL; | 19 return NULL; |
20 | 20 |
21 if ((res = th_malloc(strlen(s) + 1)) == NULL) | 21 if ((res = th_malloc(strlen(s) + 1)) == NULL) |
22 return NULL; | 22 return NULL; |
23 | 23 |
24 strcpy(res, s); | 24 strcpy(res, s); |
25 return res; | 25 return res; |
26 } | 26 } |
27 | 27 |
28 | 28 |
29 char *th_strncpy(char * dst, const char * src, const size_t n) | 29 char *th_strncpy(char *dst, const char *src, const size_t n) |
30 { | 30 { |
31 const char *s = src; | 31 const char *s = src; |
32 char *d = dst; | 32 char *d = dst; |
33 size_t i; | 33 size_t i; |
34 assert(src != NULL); | 34 assert(src != NULL); |
56 } | 56 } |
57 | 57 |
58 | 58 |
59 /* Simulate a sprintf() that allocates memory | 59 /* Simulate a sprintf() that allocates memory |
60 */ | 60 */ |
61 char * th_strdup_vprintf(const char *fmt, va_list args) | 61 char *th_strdup_vprintf(const char *fmt, va_list args) |
62 { | 62 { |
63 int size = 64; | 63 int size = 64; |
64 char *buf, *nbuf = NULL; | 64 char *buf, *nbuf = NULL; |
65 | 65 |
66 if ((buf = th_malloc(size)) == NULL) | 66 if ((buf = th_malloc(size)) == NULL) |
67 return NULL; | 67 return NULL; |
68 | 68 |
69 while (1) | 69 while (1) |
70 { | 70 { |
71 int n; | 71 int n; |
72 va_list ap; | 72 va_list ap; |
73 va_copy(ap, args); | 73 va_copy(ap, args); |
84 if ((nbuf = th_realloc(nbuf, size)) == NULL) | 84 if ((nbuf = th_realloc(nbuf, size)) == NULL) |
85 { | 85 { |
86 th_free(buf); | 86 th_free(buf); |
87 return NULL; | 87 return NULL; |
88 } | 88 } |
89 | 89 |
90 buf = nbuf; | 90 buf = nbuf; |
91 } | 91 } |
92 } | 92 } |
93 | 93 |
94 | 94 |
95 char * th_strdup_printf(const char *fmt, ...) | 95 char *th_strdup_printf(const char *fmt, ...) |
96 { | 96 { |
97 char *res; | 97 char *res; |
98 va_list ap; | 98 va_list ap; |
99 | 99 |
100 va_start(ap, fmt); | 100 va_start(ap, fmt); |
126 *buf = tmp; | 126 *buf = tmp; |
127 } | 127 } |
128 | 128 |
129 /* Compare two strings ignoring case [strcasecmp, strncasecmp] | 129 /* Compare two strings ignoring case [strcasecmp, strncasecmp] |
130 */ | 130 */ |
131 int th_strcasecmp(const char * str1, const char * str2) | 131 int th_strcasecmp(const char *str1, const char *str2) |
132 { | 132 { |
133 const char *s1 = str1, *s2 = str2; | 133 const char *s1 = str1, *s2 = str2; |
134 assert(str1 != NULL); | 134 assert(str1 != NULL); |
135 assert(str2 != NULL); | 135 assert(str2 != NULL); |
136 | 136 |
145 | 145 |
146 return (th_tolower(*s1) - th_tolower(*s2)); | 146 return (th_tolower(*s1) - th_tolower(*s2)); |
147 } | 147 } |
148 | 148 |
149 | 149 |
150 int th_strncasecmp(const char * str1, const char * str2, size_t n) | 150 int th_strncasecmp(const char *str1, const char *str2, size_t n) |
151 { | 151 { |
152 const char *s1 = str1, *s2 = str2; | 152 const char *s1 = str1, *s2 = str2; |
153 assert(str1 != NULL); | 153 assert(str1 != NULL); |
154 assert(str2 != NULL); | 154 assert(str2 != NULL); |
155 | 155 |
168 | 168 |
169 | 169 |
170 /* Remove all occurences of control characters, in-place. | 170 /* Remove all occurences of control characters, in-place. |
171 * Resulting string is always shorter or same length than original. | 171 * Resulting string is always shorter or same length than original. |
172 */ | 172 */ |
173 void th_strip_ctrlchars(char * str) | 173 void th_strip_ctrlchars(char *str) |
174 { | 174 { |
175 char *i, *j; | 175 char *i, *j; |
176 assert(str != NULL); | 176 assert(str != NULL); |
177 | 177 |
178 i = str; | 178 i = str; |
188 } | 188 } |
189 | 189 |
190 | 190 |
191 /* Copy a given string over in *result. | 191 /* Copy a given string over in *result. |
192 */ | 192 */ |
193 int th_pstrcpy(char ** result, const char * str) | 193 int th_pstrcpy(char **result, const char *str) |
194 { | 194 { |
195 assert(result != NULL); | 195 assert(result != NULL); |
196 | 196 |
197 if (str == NULL) | 197 if (str == NULL) |
198 return -1; | 198 return -1; |
206 } | 206 } |
207 | 207 |
208 | 208 |
209 /* Concatenates a given string into string pointed by *result. | 209 /* Concatenates a given string into string pointed by *result. |
210 */ | 210 */ |
211 int th_pstrcat(char ** result, const char * str) | 211 int th_pstrcat(char **result, const char *str) |
212 { | 212 { |
213 assert(result != NULL); | 213 assert(result != NULL); |
214 | 214 |
215 if (str == NULL) | 215 if (str == NULL) |
216 return -1; | 216 return -1; |
238 | 238 |
239 /* Find next non-whitespace character in string. | 239 /* Find next non-whitespace character in string. |
240 * Updates iPos into the position of such character and | 240 * Updates iPos into the position of such character and |
241 * returns pointer to the string. | 241 * returns pointer to the string. |
242 */ | 242 */ |
243 const char *th_findnext(const char * str, size_t * pos) | 243 const char *th_findnext(const char *str, size_t *pos) |
244 { | 244 { |
245 assert(str != NULL); | 245 assert(str != NULL); |
246 | 246 |
247 /* Terminating NULL-character is not whitespace! */ | 247 /* Terminating NULL-character is not whitespace! */ |
248 while (th_isspace(str[*pos])) | 248 while (th_isspace(str[*pos])) |
252 } | 252 } |
253 | 253 |
254 | 254 |
255 /* Find next sep-character from string | 255 /* Find next sep-character from string |
256 */ | 256 */ |
257 const char *th_findsep(const char * str, size_t * pos, char sep) | 257 const char *th_findsep(const char *str, size_t *pos, char sep) |
258 { | 258 { |
259 assert(str != NULL); | 259 assert(str != NULL); |
260 | 260 |
261 while (str[*pos] && str[*pos] != sep) | 261 while (str[*pos] && str[*pos] != sep) |
262 (*pos)++; | 262 (*pos)++; |
265 } | 265 } |
266 | 266 |
267 | 267 |
268 /* Find next sep- or whitespace from string | 268 /* Find next sep- or whitespace from string |
269 */ | 269 */ |
270 const char *th_findseporspace(const char * str, size_t * pos, char sep) | 270 const char *th_findseporspace(const char *str, size_t *pos, char sep) |
271 { | 271 { |
272 assert(str != NULL); | 272 assert(str != NULL); |
273 | 273 |
274 while (!th_isspace(str[*pos]) && str[*pos] != sep) | 274 while (!th_isspace(str[*pos]) && str[*pos] != sep) |
275 (*pos)++; | 275 (*pos)++; |
281 /* Compare a string to a pattern. Case-SENSITIVE version. | 281 /* Compare a string to a pattern. Case-SENSITIVE version. |
282 * The matching pattern can consist of any normal characters plus | 282 * The matching pattern can consist of any normal characters plus |
283 * wildcards ? and *. "?" matches any character and "*" matches | 283 * wildcards ? and *. "?" matches any character and "*" matches |
284 * any number of characters. | 284 * any number of characters. |
285 */ | 285 */ |
286 BOOL th_strmatch(const char * str, const char * pattern) | 286 BOOL th_strmatch(const char *str, const char *pattern) |
287 { | 287 { |
288 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; | 288 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; |
289 const char *tmpPattern = NULL; | 289 const char *tmpPattern = NULL; |
290 | 290 |
291 /* Check given pattern and string */ | 291 /* Check given pattern and string */ |
292 if (str == NULL || pattern == NULL) | 292 if (str == NULL || pattern == NULL) |
293 return FALSE; | 293 return FALSE; |
294 | 294 |
295 /* Start comparision */ | 295 /* Start comparision */ |
296 do { | 296 do |
297 { | |
297 didMatch = FALSE; | 298 didMatch = FALSE; |
298 switch (*pattern) | 299 switch (*pattern) |
299 { | 300 { |
300 case '?': | 301 case '?': |
301 /* Any single character matches */ | 302 /* Any single character matches */ |
333 isAnyMode = TRUE; | 334 isAnyMode = TRUE; |
334 pattern = tmpPattern; | 335 pattern = tmpPattern; |
335 } | 336 } |
336 else | 337 else |
337 didMatch = FALSE; | 338 didMatch = FALSE; |
338 } else | 339 } |
340 else | |
339 isEnd = TRUE; | 341 isEnd = TRUE; |
340 } | 342 } |
341 break; | 343 break; |
342 default: | 344 default: |
343 if (isAnyMode) | 345 if (isAnyMode) |
379 | 381 |
380 if (!*str && !*pattern) | 382 if (!*str && !*pattern) |
381 isEnd = TRUE; | 383 isEnd = TRUE; |
382 break; | 384 break; |
383 | 385 |
384 } /* switch */ | 386 } /* switch */ |
385 | 387 |
386 } while (didMatch && !isEnd); | 388 } |
389 while (didMatch && !isEnd); | |
387 | 390 |
388 return didMatch; | 391 return didMatch; |
389 } | 392 } |
390 | 393 |
391 | 394 |
392 /* Compare a string to a pattern. Case-INSENSITIVE version. | 395 /* Compare a string to a pattern. Case-INSENSITIVE version. |
393 */ | 396 */ |
394 BOOL th_strcasematch(const char * str, const char * pattern) | 397 BOOL th_strcasematch(const char *str, const char *pattern) |
395 { | 398 { |
396 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; | 399 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; |
397 const char *tmpPattern = NULL; | 400 const char *tmpPattern = NULL; |
398 | 401 |
399 /* Check given pattern and string */ | 402 /* Check given pattern and string */ |
400 if (str == NULL || pattern == NULL) | 403 if (str == NULL || pattern == NULL) |
401 return FALSE; | 404 return FALSE; |
402 | 405 |
403 /* Start comparision */ | 406 /* Start comparision */ |
404 do { | 407 do |
405 switch (*pattern) { | 408 { |
409 switch (*pattern) | |
410 { | |
406 case '?': | 411 case '?': |
407 /* Any single character matches */ | 412 /* Any single character matches */ |
408 if (*str) | 413 if (*str) |
409 { | 414 { |
410 pattern++; | 415 pattern++; |
411 str++; | 416 str++; |
412 } else | 417 } |
418 else | |
413 didMatch = FALSE; | 419 didMatch = FALSE; |
414 break; | 420 break; |
415 | 421 |
416 case '*': | 422 case '*': |
417 pattern++; | 423 pattern++; |
438 isAnyMode = TRUE; | 444 isAnyMode = TRUE; |
439 pattern = tmpPattern; | 445 pattern = tmpPattern; |
440 } | 446 } |
441 else | 447 else |
442 didMatch = FALSE; | 448 didMatch = FALSE; |
443 } else | 449 } |
450 else | |
444 isEnd = TRUE; | 451 isEnd = TRUE; |
445 } | 452 } |
446 break; | 453 break; |
447 | 454 |
448 default: | 455 default: |
484 if (!*str && !*pattern) | 491 if (!*str && !*pattern) |
485 isEnd = TRUE; | 492 isEnd = TRUE; |
486 | 493 |
487 break; | 494 break; |
488 | 495 |
489 } /* switch */ | 496 } /* switch */ |
490 | 497 |
491 } while (didMatch && !isEnd); | 498 } |
499 while (didMatch && !isEnd); | |
492 | 500 |
493 return didMatch; | 501 return didMatch; |
494 } | 502 } |
495 | 503 |
496 | 504 |
497 int th_get_hex_triplet(const char *str) | 505 int th_get_hex_triplet(const char *str) |
498 { | 506 { |
499 const char *p = str; | 507 const char *p = str; |
500 int len, val = 0; | 508 int len, val = 0; |
501 | 509 |
502 for (len = 0; *p && len < 6; p++, len++) | 510 for (len = 0; *p && len < 6; p++, len++) |
503 { | 511 { |
504 if (*p >= '0' && *p <= '9') | 512 if (*p >= '0' && *p <= '9') |
505 { | 513 { |
506 val *= 16; | 514 val *= 16; |
517 val += (*p - 'a') + 10; | 525 val += (*p - 'a') + 10; |
518 } | 526 } |
519 else | 527 else |
520 return -1; | 528 return -1; |
521 } | 529 } |
522 | 530 |
523 return (len == 6) ? val : -1; | 531 return (len == 6) ? val : -1; |
524 } | 532 } |
525 | 533 |
526 | 534 |
527 BOOL th_growbuf(char **buf, size_t *bufsize, size_t *len, size_t grow) | 535 BOOL th_growbuf(char **buf, size_t *bufsize, size_t *len, size_t grow) |
528 { | 536 { |
529 if (*buf == NULL) | 537 if (*buf == NULL) |
530 *bufsize = *len = 0; | 538 *bufsize = *len = 0; |
531 | 539 |
532 if (*buf == NULL || *len + grow >= *bufsize) | 540 if (*buf == NULL || *len + grow >= *bufsize) |
533 { | 541 { |
534 *bufsize += grow + TH_BUFGROW; | 542 *bufsize += grow + TH_BUFGROW; |
535 *buf = (char *) th_realloc(*buf, *bufsize); | 543 *buf = (char *) th_realloc(*buf, *bufsize); |
536 if (*buf == NULL) | 544 if (*buf == NULL) |
542 | 550 |
543 BOOL th_vputch(char **buf, size_t *bufsize, size_t *len, const char ch) | 551 BOOL th_vputch(char **buf, size_t *bufsize, size_t *len, const char ch) |
544 { | 552 { |
545 if (!th_growbuf(buf, bufsize, len, 1)) | 553 if (!th_growbuf(buf, bufsize, len, 1)) |
546 return FALSE; | 554 return FALSE; |
547 | 555 |
548 (*buf)[*len] = ch; | 556 (*buf)[*len] = ch; |
549 (*len)++; | 557 (*len)++; |
550 | 558 |
551 return TRUE; | 559 return TRUE; |
552 } | 560 } |
555 BOOL th_vputs(char **buf, size_t *bufsize, size_t *len, const char *str) | 563 BOOL th_vputs(char **buf, size_t *bufsize, size_t *len, const char *str) |
556 { | 564 { |
557 size_t slen; | 565 size_t slen; |
558 if (str == NULL) | 566 if (str == NULL) |
559 return FALSE; | 567 return FALSE; |
560 | 568 |
561 slen = strlen(str); | 569 slen = strlen(str); |
562 if (!th_growbuf(buf, bufsize, len, slen)) | 570 if (!th_growbuf(buf, bufsize, len, slen)) |
563 return FALSE; | 571 return FALSE; |
564 | 572 |
565 strcpy(*buf + *len, str); | 573 strcpy(*buf + *len, str); |
566 (*len) += slen; | 574 (*len) += slen; |
567 | 575 |
568 return TRUE; | 576 return TRUE; |
569 } | 577 } |
570 |