Mercurial > hg > nnchat
annotate th_string.c @ 317:0089d94201b6
Bump version.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 11 Jun 2011 06:32:11 +0300 |
parents | f1049f487987 |
children | fae4651d37bc |
rev | line source |
---|---|
0 | 1 /* |
2 * Miscellaneous string-handling related utility-functions | |
3 * Programmed and designed by Matti 'ccr' Hamalainen | |
4 * (C) Copyright 2002-2008 Tecnic Software productions (TNSP) | |
5 * | |
6 * Please read file 'COPYING' for information on license and distribution. | |
7 */ | |
8 #ifdef HAVE_CONFIG_H | |
2 | 9 #include "config.h" |
0 | 10 #endif |
11 #include "th_string.h" | |
12 | |
79 | 13 /* strdup with a NULL check |
14 */ | |
15 char *th_strdup(const char *s) | |
16 { | |
81 | 17 char *res; |
18 if (s == NULL) | |
19 return NULL; | |
20 | |
21 if ((res = th_malloc(strlen(s) + 1)) == NULL) | |
22 return NULL; | |
23 | |
24 strcpy(res, s); | |
25 return res; | |
79 | 26 } |
27 | |
28 | |
124 | 29 char *th_strncpy(char * dst, const char * src, const size_t n) |
0 | 30 { |
81 | 31 const char *s = src; |
32 char *d = dst; | |
33 size_t i; | |
34 assert(src != NULL); | |
35 assert(dst != NULL); | |
0 | 36 |
81 | 37 /* Copy to the destination */ |
38 i = n; | |
124 | 39 while (*s && i > 0) { |
81 | 40 *(d++) = *(s++); |
41 i--; | |
42 } | |
0 | 43 |
81 | 44 /* Fill rest of space with zeros */ |
45 while (i > 0) { | |
46 *(d++) = 0; | |
47 i--; | |
48 } | |
0 | 49 |
81 | 50 /* Ensure that last is always zero */ |
51 dst[n - 1] = 0; | |
0 | 52 |
81 | 53 return dst; |
0 | 54 } |
55 | |
56 | |
126 | 57 /* Simulate a sprintf() that allocates memory |
124 | 58 */ |
59 char * th_strdup_vprintf(const char *fmt, va_list args) | |
60 { | |
127 | 61 int size = 100; |
126 | 62 char *buf, *nbuf = NULL; |
124 | 63 |
126 | 64 if ((buf = th_malloc(size)) == NULL) |
65 return NULL; | |
66 | |
67 while (1) { | |
127 | 68 int n = vsnprintf(buf, size, fmt, args); |
126 | 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; | |
124 | 79 } |
126 | 80 |
81 buf = nbuf; | |
124 | 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 } | |
126 | 97 |
124 | 98 |
282
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
99 void th_pstr_vprintf(char **buf, const char *fmt, va_list ap) |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
100 { |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
101 char *tmp = th_strdup_vprintf(fmt, ap); |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
102 th_free(*buf); |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
103 *buf = tmp; |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
104 } |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
105 |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
106 |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
107 void th_pstr_printf(char **buf, const char *fmt, ...) |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
108 { |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
109 char *tmp; |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
110 va_list ap; |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
111 |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
112 va_start(ap, fmt); |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
113 tmp = th_strdup_vprintf(fmt, ap); |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
114 va_end(ap); |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
115 |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
116 th_free(*buf); |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
117 *buf = tmp; |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
118 } |
3dc86d8eb0a9
Added helper functions for easier string manipulation.
Matti Hamalainen <ccr@tnsp.org>
parents:
244
diff
changeset
|
119 |
124 | 120 /* Compare two strings ignoring case [strcasecmp, strncasecmp] |
121 */ | |
122 int th_strcasecmp(const char * str1, const char * str2) | |
123 { | |
124 const char *s1 = str1, *s2 = str2; | |
81 | 125 assert(str1 != NULL); |
126 assert(str2 != NULL); | |
0 | 127 |
81 | 128 if (str1 == str2) |
129 return 0; | |
0 | 130 |
124 | 131 while (*s1 && *s2 && th_tolower(*s1) == th_tolower(*s2)) { |
81 | 132 s1++; |
133 s2++; | |
134 } | |
0 | 135 |
81 | 136 return (th_tolower(*s1) - th_tolower(*s2)); |
0 | 137 } |
138 | |
139 | |
124 | 140 int th_strncasecmp(const char * str1, const char * str2, size_t n) |
0 | 141 { |
124 | 142 const char *s1 = str1, *s2 = str2; |
81 | 143 assert(str1 != NULL); |
144 assert(str2 != NULL); | |
0 | 145 |
81 | 146 if (str1 == str2) |
147 return 0; | |
0 | 148 |
124 | 149 while (n > 0 && *s1 && *s2 && th_tolower(*s1) == th_tolower(*s2)) { |
81 | 150 s1++; |
151 s2++; | |
152 n--; | |
153 } | |
0 | 154 |
124 | 155 return n > 0 ? (th_tolower(*s1) - th_tolower(*s2)) : 0; |
0 | 156 } |
157 | |
158 | |
159 /* Remove all occurences of control characters, in-place. | |
160 * Resulting string is always shorter or same length than original. | |
161 */ | |
11 | 162 void th_strip_ctrlchars(char * str) |
0 | 163 { |
81 | 164 char *i, *j; |
165 assert(str != NULL); | |
0 | 166 |
81 | 167 i = str; |
168 j = str; | |
169 while (*i) { | |
170 if (!th_iscntrl(*i)) | |
171 *(j++) = *i; | |
172 i++; | |
173 } | |
0 | 174 |
81 | 175 *j = 0; |
0 | 176 } |
177 | |
178 | |
11 | 179 /* Copy a given string over in *result. |
0 | 180 */ |
124 | 181 int th_pstrcpy(char ** result, const char * str) |
0 | 182 { |
81 | 183 assert(result != NULL); |
0 | 184 |
81 | 185 if (str == NULL) |
186 return -1; | |
0 | 187 |
81 | 188 th_free(*result); |
124 | 189 if ((*result = th_malloc(strlen(str) + 1)) == NULL) |
81 | 190 return -2; |
0 | 191 |
81 | 192 strcpy(*result, str); |
193 return 0; | |
0 | 194 } |
195 | |
196 | |
11 | 197 /* Concatenates a given string into string pointed by *result. |
0 | 198 */ |
124 | 199 int th_pstrcat(char ** result, const char * str) |
0 | 200 { |
81 | 201 assert(result != NULL); |
0 | 202 |
81 | 203 if (str == NULL) |
204 return -1; | |
0 | 205 |
81 | 206 if (*result != NULL) { |
124 | 207 *result = th_realloc(*result, strlen(*result) + strlen(str) + 1); |
81 | 208 if (*result == NULL) |
209 return -1; | |
0 | 210 |
81 | 211 strcat(*result, str); |
212 } else { | |
124 | 213 *result = th_malloc(strlen(str) + 1); |
81 | 214 if (*result == NULL) |
215 return -1; | |
0 | 216 |
81 | 217 strcpy(*result, str); |
218 } | |
0 | 219 |
81 | 220 return 0; |
0 | 221 } |
222 | |
223 | |
224 /* Find next non-whitespace character in string. | |
225 * Updates iPos into the position of such character and | |
226 * returns pointer to the string. | |
227 */ | |
124 | 228 const char *th_findnext(const char * str, size_t * pos) |
0 | 229 { |
81 | 230 assert(str != NULL); |
0 | 231 |
81 | 232 /* Terminating NULL-character is not whitespace! */ |
124 | 233 while (th_isspace(str[*pos])) |
234 (*pos)++; | |
235 return &str[*pos]; | |
0 | 236 } |
237 | |
238 | |
124 | 239 /* Find next sep-character from string |
0 | 240 */ |
124 | 241 const char *th_findsep(const char * str, size_t * pos, char sep) |
0 | 242 { |
81 | 243 assert(str != NULL); |
0 | 244 |
124 | 245 while (str[*pos] && str[*pos] != sep) |
246 (*pos)++; | |
247 | |
248 return &str[*pos]; | |
0 | 249 } |
250 | |
251 | |
124 | 252 /* Find next sep- or whitespace from string |
0 | 253 */ |
124 | 254 const char *th_findseporspace(const char * str, size_t * pos, char sep) |
0 | 255 { |
81 | 256 assert(str != NULL); |
0 | 257 |
124 | 258 while (!th_isspace(str[*pos]) && str[*pos] != sep) |
259 (*pos)++; | |
260 | |
261 return &str[*pos]; | |
0 | 262 } |
263 | |
264 | |
265 /* Compare a string to a pattern. Case-SENSITIVE version. | |
266 * The matching pattern can consist of any normal characters plus | |
267 * wildcards ? and *. "?" matches any character and "*" matches | |
268 * any number of characters. | |
269 */ | |
124 | 270 BOOL th_strmatch(const char * str, const char * pattern) |
0 | 271 { |
81 | 272 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; |
124 | 273 const char *tmpPattern = NULL; |
0 | 274 |
81 | 275 /* Check given pattern and string */ |
276 if (str == NULL || pattern == NULL) | |
277 return FALSE; | |
0 | 278 |
81 | 279 /* Start comparision */ |
280 do { | |
281 didMatch = FALSE; | |
282 switch (*pattern) { | |
283 case '?': | |
284 /* Any single character matches */ | |
285 if (*str) { | |
286 didMatch = TRUE; | |
287 pattern++; | |
288 str++; | |
289 } | |
290 break; | |
0 | 291 |
81 | 292 case '*': |
293 didMatch = TRUE; | |
294 pattern++; | |
295 if (!*pattern) | |
296 isEnd = TRUE; | |
297 isAnyMode = TRUE; | |
298 tmpPattern = pattern; | |
299 break; | |
0 | 300 |
81 | 301 case 0: |
302 if (isAnyMode) { | |
303 if (*str) | |
304 str++; | |
305 else | |
306 isEnd = TRUE; | |
307 } else { | |
308 if (*str) { | |
309 if (tmpPattern) { | |
310 isAnyMode = TRUE; | |
311 pattern = tmpPattern; | |
312 } else | |
313 didMatch = FALSE; | |
314 } else | |
315 isEnd = TRUE; | |
316 } | |
317 break; | |
318 default: | |
319 if (isAnyMode) { | |
320 if (*pattern == *str) { | |
321 isAnyMode = FALSE; | |
322 didMatch = TRUE; | |
323 } else { | |
324 if (*str) { | |
325 didMatch = TRUE; | |
326 str++; | |
327 } | |
328 } | |
329 } else { | |
330 if (*pattern == *str) { | |
331 didMatch = TRUE; | |
332 if (*pattern) | |
333 pattern++; | |
334 if (*str) | |
335 str++; | |
336 } else { | |
337 if (tmpPattern) { | |
338 didMatch = TRUE; | |
339 isAnyMode = TRUE; | |
340 pattern = tmpPattern; | |
341 } | |
342 } | |
343 } | |
0 | 344 |
81 | 345 if (!*str && !*pattern) |
346 isEnd = TRUE; | |
347 break; | |
0 | 348 |
81 | 349 } /* switch */ |
0 | 350 |
81 | 351 } while (didMatch && !isEnd); |
0 | 352 |
81 | 353 return didMatch; |
0 | 354 } |
355 | |
356 | |
357 /* Compare a string to a pattern. Case-INSENSITIVE version. | |
358 */ | |
124 | 359 BOOL th_strcasematch(const char * str, const char * pattern) |
0 | 360 { |
81 | 361 BOOL didMatch = TRUE, isAnyMode = FALSE, isEnd = FALSE; |
124 | 362 const char *tmpPattern = NULL; |
0 | 363 |
81 | 364 /* Check given pattern and string */ |
365 if (str == NULL || pattern == NULL) | |
366 return FALSE; | |
0 | 367 |
81 | 368 /* Start comparision */ |
369 do { | |
370 switch (*pattern) { | |
371 case '?': | |
372 /* Any single character matches */ | |
373 if (*str) { | |
374 pattern++; | |
375 str++; | |
376 } else | |
377 didMatch = FALSE; | |
378 break; | |
0 | 379 |
81 | 380 case '*': |
381 pattern++; | |
382 if (!*pattern || *pattern == '?') | |
383 isEnd = TRUE; | |
384 isAnyMode = TRUE; | |
385 tmpPattern = pattern; | |
386 break; | |
0 | 387 |
81 | 388 case 0: |
389 if (isAnyMode) { | |
390 if (*str) | |
391 str++; | |
392 else | |
393 isEnd = TRUE; | |
394 } else { | |
395 if (*str) { | |
396 if (tmpPattern) { | |
397 isAnyMode = TRUE; | |
398 pattern = tmpPattern; | |
399 } else | |
400 didMatch = FALSE; | |
401 } else | |
402 isEnd = TRUE; | |
403 } | |
404 break; | |
0 | 405 |
81 | 406 default: |
407 if (isAnyMode) { | |
408 if (th_tolower(*pattern) == th_tolower(*str)) { | |
409 isAnyMode = FALSE; | |
410 } else { | |
411 if (*str) | |
412 str++; | |
413 else | |
414 didMatch = FALSE; | |
415 } | |
416 } else { | |
417 if (th_tolower(*pattern) == th_tolower(*str)) { | |
418 if (*pattern) | |
419 pattern++; | |
420 if (*str) | |
421 str++; | |
422 } else { | |
423 if (tmpPattern) { | |
424 isAnyMode = TRUE; | |
425 pattern = tmpPattern; | |
426 } else | |
427 didMatch = FALSE; | |
428 } | |
429 } | |
0 | 430 |
81 | 431 if (!*str && !*pattern) |
432 isEnd = TRUE; | |
433 break; | |
0 | 434 |
81 | 435 } /* switch */ |
0 | 436 |
81 | 437 } while (didMatch && !isEnd); |
0 | 438 |
81 | 439 return didMatch; |
0 | 440 } |
441 | |
131
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
442 |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
443 int th_get_hex_triplet(const char *str) |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
444 { |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
445 const char *p = str; |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
446 int len, val = 0; |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
447 |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
448 for (len = 0; *p && len < 6; p++, len++) { |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
449 if (*p >= '0' && *p <= '9') { |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
450 val *= 16; val += (*p - '0'); |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
451 } else if (*p >= 'A' && *p <= 'F') { |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
452 val *= 16; val += (*p - 'A') + 10; |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
453 } else if (*p >= 'a' && *p <= 'f') { |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
454 val *= 16; val += (*p - 'a') + 10; |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
455 } else |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
456 return -1; |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
457 } |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
458 |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
459 return (len == 6) ? val : -1; |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
460 } |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
461 |
3896861974ac
Added th_get_hex_triplet().
Matti Hamalainen <ccr@tnsp.org>
parents:
127
diff
changeset
|
462 |
243 | 463 static BOOL th_growbuf(char **buf, size_t *bufsize, size_t *len, size_t grow) |
241
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
464 { |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
465 assert(buf != NULL); |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
466 assert(bufsize != NULL); |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
467 assert(len != NULL); |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
468 |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
469 if (*buf == NULL) |
287
eb74097b73f5
Make th_vputch() and th_vputs() return a boolean value for success and failure respectively. Also fix a grave bug in th_growbuf().
Matti Hamalainen <ccr@tnsp.org>
parents:
282
diff
changeset
|
470 *bufsize = *len = 0; |
241
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
471 |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
472 if (*buf == NULL || *len + grow >= *bufsize) { |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
473 *bufsize += grow + TH_BUFGROW; |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
474 *buf = (char *) th_realloc(*buf, *bufsize); |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
475 if (*buf == NULL) |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
476 return FALSE; |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
477 } |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
478 return TRUE; |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
479 } |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
480 |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
481 |
287
eb74097b73f5
Make th_vputch() and th_vputs() return a boolean value for success and failure respectively. Also fix a grave bug in th_growbuf().
Matti Hamalainen <ccr@tnsp.org>
parents:
282
diff
changeset
|
482 BOOL th_vputch(char **buf, size_t *bufsize, size_t *len, const char ch) |
241
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
483 { |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
484 if (!th_growbuf(buf, bufsize, len, 1)) |
287
eb74097b73f5
Make th_vputch() and th_vputs() return a boolean value for success and failure respectively. Also fix a grave bug in th_growbuf().
Matti Hamalainen <ccr@tnsp.org>
parents:
282
diff
changeset
|
485 return FALSE; |
241
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
486 |
244
517c7b22b3c9
Buffer pointer handling was wrong in th_vaddch(), fixed.
Matti Hamalainen <ccr@tnsp.org>
parents:
243
diff
changeset
|
487 (*buf)[*len] = ch; |
241
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
488 (*len)++; |
287
eb74097b73f5
Make th_vputch() and th_vputs() return a boolean value for success and failure respectively. Also fix a grave bug in th_growbuf().
Matti Hamalainen <ccr@tnsp.org>
parents:
282
diff
changeset
|
489 |
eb74097b73f5
Make th_vputch() and th_vputs() return a boolean value for success and failure respectively. Also fix a grave bug in th_growbuf().
Matti Hamalainen <ccr@tnsp.org>
parents:
282
diff
changeset
|
490 return TRUE; |
241
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
491 } |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
492 |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
493 |
287
eb74097b73f5
Make th_vputch() and th_vputs() return a boolean value for success and failure respectively. Also fix a grave bug in th_growbuf().
Matti Hamalainen <ccr@tnsp.org>
parents:
282
diff
changeset
|
494 BOOL th_vputs(char **buf, size_t *bufsize, size_t *len, const char *str) |
241
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
495 { |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
496 size_t slen; |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
497 if (str == NULL) |
287
eb74097b73f5
Make th_vputch() and th_vputs() return a boolean value for success and failure respectively. Also fix a grave bug in th_growbuf().
Matti Hamalainen <ccr@tnsp.org>
parents:
282
diff
changeset
|
498 return FALSE; |
241
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
499 |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
500 slen = strlen(str); |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
501 if (!th_growbuf(buf, bufsize, len, slen)) |
287
eb74097b73f5
Make th_vputch() and th_vputs() return a boolean value for success and failure respectively. Also fix a grave bug in th_growbuf().
Matti Hamalainen <ccr@tnsp.org>
parents:
282
diff
changeset
|
502 return FALSE; |
241
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
503 |
290
f1049f487987
Use strcpy() instead of strcat().
Matti Hamalainen <ccr@tnsp.org>
parents:
287
diff
changeset
|
504 strcpy(*buf + *len, str); |
241
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
505 (*len) += slen; |
287
eb74097b73f5
Make th_vputch() and th_vputs() return a boolean value for success and failure respectively. Also fix a grave bug in th_growbuf().
Matti Hamalainen <ccr@tnsp.org>
parents:
282
diff
changeset
|
506 |
eb74097b73f5
Make th_vputch() and th_vputs() return a boolean value for success and failure respectively. Also fix a grave bug in th_growbuf().
Matti Hamalainen <ccr@tnsp.org>
parents:
282
diff
changeset
|
507 return TRUE; |
241
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
508 } |
a1ee6c76ca1c
Functions for growing a string buffer when needed.
Matti Hamalainen <ccr@tnsp.org>
parents:
131
diff
changeset
|
509 |