Mercurial > hg > nnchat
annotate th_string.c @ 322:b9c15c57dc8f
Clean up message functions, add new printMsgQ() helper function for messages that should not
go into the log file. Add skeleton help function, accessible via F1 key. And other cleanups.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Sat, 11 Jun 2011 09:48:26 +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 |