blob: 123bbebee24a843f30167b7b331cb26bc5254deb [file] [log] [blame]
Bjorn Reese026d29f2002-01-19 15:40:18 +00001/*************************************************************************
2 *
3 * $Id$
4 *
5 * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
12 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
13 * MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE AUTHORS AND
14 * CONTRIBUTORS ACCEPT NO RESPONSIBILITY IN ANY CONCEIVABLE MANNER.
15 *
16 ************************************************************************/
17
Bjorn Reese026d29f2002-01-19 15:40:18 +000018/*************************************************************************
19 * Include files
20 */
21
22#include <assert.h>
23#include <stdlib.h>
24#include <string.h>
25#include <ctype.h>
26#include <math.h>
Daniel Veillardb7c29c32002-09-25 22:44:43 +000027#include "triodef.h"
Bjorn Reese026d29f2002-01-19 15:40:18 +000028#include "triostr.h"
29
30/*************************************************************************
31 * Definitions
32 */
33
Daniel Veillardb7c29c32002-09-25 22:44:43 +000034#if !defined(TRIO_STRING_PUBLIC)
35# define TRIO_STRING_PUBLIC TRIO_PUBLIC
36#endif
37#if !defined(TRIO_STRING_PRIVATE)
38# define TRIO_STRING_PRIVATE TRIO_PRIVATE
39#endif
40
41#if !defined(NULL)
Bjorn Reese026d29f2002-01-19 15:40:18 +000042# define NULL 0
43#endif
Daniel Veillardb7c29c32002-09-25 22:44:43 +000044#if !defined(NIL)
45# define NIL ((char)0)
46#endif
47#if !defined(FALSE)
Bjorn Reese026d29f2002-01-19 15:40:18 +000048# define FALSE (1 == 0)
49# define TRUE (! FALSE)
50#endif
Daniel Veillardb7c29c32002-09-25 22:44:43 +000051#if !defined(BOOLEAN_T)
52# define BOOLEAN_T int
53#endif
Bjorn Reese026d29f2002-01-19 15:40:18 +000054
Jacob (Jouk) Jansen4d041a22013-12-17 15:32:57 +080055#ifdef __VMS
56# define USE_STRTOD
57#elif defined(TRIO_COMPILER_SUPPORTS_C99)
Bjorn Reese026d29f2002-01-19 15:40:18 +000058# define USE_STRTOD
59# define USE_STRTOF
60#elif defined(TRIO_COMPILER_MSVC)
61# define USE_STRTOD
62#endif
63
64#if defined(TRIO_PLATFORM_UNIX)
65# define USE_STRCASECMP
66# define USE_STRNCASECMP
Daniel Veillarda48ed3d2003-04-03 15:28:28 +000067# if defined(TRIO_PLATFORM_SUNOS)
68# define USE_SYS_ERRLIST
69# else
70# define USE_STRERROR
71# endif
Bjorn Reese026d29f2002-01-19 15:40:18 +000072# if defined(TRIO_PLATFORM_QNX)
73# define strcasecmp(x,y) stricmp(x,y)
74# define strncasecmp(x,y,n) strnicmp(x,y,n)
75# endif
76#elif defined(TRIO_PLATFORM_WIN32)
77# define USE_STRCASECMP
Daniel Veillard59d3ed82007-04-17 12:44:58 +000078# if defined(_WIN32_WCE)
79# define strcasecmp(x,y) _stricmp(x,y)
80# else
81# define strcasecmp(x,y) strcmpi(x,y)
82# endif
Patrick Monneratca9fc432013-12-12 15:11:40 +080083#elif defined(TRIO_PLATFORM_OS400)
84# define USE_STRCASECMP
85# define USE_STRNCASECMP
86# include <strings.h>
Bjorn Reese026d29f2002-01-19 15:40:18 +000087#endif
88
Daniel Veillarda48ed3d2003-04-03 15:28:28 +000089#if !(defined(TRIO_PLATFORM_SUNOS))
90# define USE_TOLOWER
91# define USE_TOUPPER
92#endif
93
Bjorn Reese026d29f2002-01-19 15:40:18 +000094/*************************************************************************
95 * Structures
96 */
97
98struct _trio_string_t
99{
100 char *content;
101 size_t length;
102 size_t allocated;
103};
104
105/*************************************************************************
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000106 * Constants
107 */
108
109#if !defined(TRIO_MINIMAL)
110static TRIO_CONST char rcsid[] = "@(#)$Id$";
111#endif
112
113/*************************************************************************
Bjorn Reese026d29f2002-01-19 15:40:18 +0000114 * Static String Functions
115 */
116
117#if defined(TRIO_DOCUMENTATION)
118# include "doc/doc_static.h"
119#endif
120/** @addtogroup StaticStrings
121 @{
122*/
123
124/**
125 Create new string.
126
127 @param size Size of new string.
128 @return Pointer to string, or NULL if allocation failed.
129*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000130TRIO_STRING_PUBLIC char *
131trio_create
132TRIO_ARGS1((size),
133 size_t size)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000134{
135 return (char *)TRIO_MALLOC(size);
136}
137
138
139/**
140 Destroy string.
141
142 @param string String to be freed.
143*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000144TRIO_STRING_PUBLIC void
145trio_destroy
146TRIO_ARGS1((string),
147 char *string)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000148{
149 if (string)
150 {
151 TRIO_FREE(string);
152 }
153}
154
155
156/**
157 Count the number of characters in a string.
158
159 @param string String to measure.
160 @return Number of characters in @string.
161*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000162TRIO_STRING_PUBLIC size_t
163trio_length
164TRIO_ARGS1((string),
165 TRIO_CONST char *string)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000166{
167 return strlen(string);
168}
169
170
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000171#if !defined(TRIO_MINIMAL)
172/**
173 Append @p source at the end of @p target.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800174
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000175 @param target Target string.
176 @param source Source string.
177 @return Boolean value indicating success or failure.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800178
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000179 @pre @p target must point to a memory chunk with sufficient room to
180 contain the @p target string and @p source string.
181 @pre No boundary checking is performed, so insufficient memory will
182 result in a buffer overrun.
183 @post @p target will be zero terminated.
184*/
185TRIO_STRING_PUBLIC int
186trio_append
187TRIO_ARGS2((target, source),
188 char *target,
189 TRIO_CONST char *source)
190{
191 assert(target);
192 assert(source);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800193
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000194 return (strcat(target, source) != NULL);
195}
196#endif /* !defined(TRIO_MINIMAL) */
197
198#if !defined(TRIO_MINIMAL)
199/**
200 Append at most @p max characters from @p source to @p target.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800201
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000202 @param target Target string.
203 @param max Maximum number of characters to append.
204 @param source Source string.
205 @return Boolean value indicating success or failure.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800206
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000207 @pre @p target must point to a memory chuck with sufficient room to
208 contain the @p target string and the @p source string (at most @p max
209 characters).
210 @pre No boundary checking is performed, so insufficient memory will
211 result in a buffer overrun.
212 @post @p target will be zero terminated.
213*/
214TRIO_STRING_PUBLIC int
215trio_append_max
216TRIO_ARGS3((target, max, source),
217 char *target,
218 size_t max,
219 TRIO_CONST char *source)
220{
221 size_t length;
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800222
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000223 assert(target);
224 assert(source);
225
226 length = trio_length(target);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800227
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000228 if (max > length)
229 {
230 strncat(target, source, max - length - 1);
231 }
232 return TRUE;
233}
234#endif /* !defined(TRIO_MINIMAL) */
235
236
237#if !defined(TRIO_MINIMAL)
238/**
239 Determine if a string contains a substring.
240
241 @param string String to be searched.
242 @param substring String to be found.
243 @return Boolean value indicating success or failure.
244*/
245TRIO_STRING_PUBLIC int
246trio_contains
247TRIO_ARGS2((string, substring),
248 TRIO_CONST char *string,
249 TRIO_CONST char *substring)
250{
251 assert(string);
252 assert(substring);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800253
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000254 return (0 != strstr(string, substring));
255}
256#endif /* !defined(TRIO_MINIMAL) */
257
258
259#if !defined(TRIO_MINIMAL)
260/**
261 Copy @p source to @p target.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800262
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000263 @param target Target string.
264 @param source Source string.
265 @return Boolean value indicating success or failure.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800266
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000267 @pre @p target must point to a memory chunk with sufficient room to
268 contain the @p source string.
269 @pre No boundary checking is performed, so insufficient memory will
270 result in a buffer overrun.
271 @post @p target will be zero terminated.
272*/
273TRIO_STRING_PUBLIC int
274trio_copy
275TRIO_ARGS2((target, source),
276 char *target,
277 TRIO_CONST char *source)
278{
279 assert(target);
280 assert(source);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800281
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000282 (void)strcpy(target, source);
283 return TRUE;
284}
285#endif /* !defined(TRIO_MINIMAL) */
286
287
288/**
289 Copy at most @p max characters from @p source to @p target.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800290
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000291 @param target Target string.
292 @param max Maximum number of characters to append.
293 @param source Source string.
294 @return Boolean value indicating success or failure.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800295
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000296 @pre @p target must point to a memory chunk with sufficient room to
297 contain the @p source string (at most @p max characters).
298 @pre No boundary checking is performed, so insufficient memory will
299 result in a buffer overrun.
300 @post @p target will be zero terminated.
301*/
302TRIO_STRING_PUBLIC int
303trio_copy_max
304TRIO_ARGS3((target, max, source),
305 char *target,
306 size_t max,
307 TRIO_CONST char *source)
308{
309 assert(target);
310 assert(source);
311 assert(max > 0); /* Includes != 0 */
312
313 (void)strncpy(target, source, max - 1);
314 target[max - 1] = (char)0;
315 return TRUE;
316}
317
318
Bjorn Reese026d29f2002-01-19 15:40:18 +0000319/*
320 * TrioDuplicateMax
321 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000322TRIO_STRING_PRIVATE char *
323TrioDuplicateMax
324TRIO_ARGS2((source, size),
325 TRIO_CONST char *source,
326 size_t size)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000327{
328 char *target;
329
330 assert(source);
331
332 /* Make room for string plus a terminating zero */
333 size++;
334 target = trio_create(size);
335 if (target)
336 {
337 trio_copy_max(target, size, source);
338 }
339 return target;
340}
341
342
343/**
Bjorn Reese026d29f2002-01-19 15:40:18 +0000344 Duplicate @p source.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800345
Bjorn Reese026d29f2002-01-19 15:40:18 +0000346 @param source Source string.
347 @return A copy of the @p source string.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800348
Bjorn Reese026d29f2002-01-19 15:40:18 +0000349 @post @p target will be zero terminated.
350*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000351TRIO_STRING_PUBLIC char *
352trio_duplicate
353TRIO_ARGS1((source),
354 TRIO_CONST char *source)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000355{
356 return TrioDuplicateMax(source, trio_length(source));
357}
358
359
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000360#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000361/**
362 Duplicate at most @p max characters of @p source.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800363
Bjorn Reese026d29f2002-01-19 15:40:18 +0000364 @param source Source string.
365 @param max Maximum number of characters to duplicate.
366 @return A copy of the @p source string.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800367
Bjorn Reese026d29f2002-01-19 15:40:18 +0000368 @post @p target will be zero terminated.
369*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000370TRIO_STRING_PUBLIC char *
371trio_duplicate_max TRIO_ARGS2((source, max),
372 TRIO_CONST char *source,
373 size_t max)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000374{
375 size_t length;
376
377 assert(source);
378 assert(max > 0);
379
380 length = trio_length(source);
381 if (length > max)
382 {
383 length = max;
384 }
385 return TrioDuplicateMax(source, length);
386}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000387#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000388
389
390/**
391 Compare if two strings are equal.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800392
Bjorn Reese026d29f2002-01-19 15:40:18 +0000393 @param first First string.
394 @param second Second string.
395 @return Boolean indicating whether the two strings are equal or not.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800396
Bjorn Reese026d29f2002-01-19 15:40:18 +0000397 Case-insensitive comparison.
398*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000399TRIO_STRING_PUBLIC int
400trio_equal
401TRIO_ARGS2((first, second),
402 TRIO_CONST char *first,
403 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000404{
405 assert(first);
406 assert(second);
407
408 if ((first != NULL) && (second != NULL))
409 {
410#if defined(USE_STRCASECMP)
411 return (0 == strcasecmp(first, second));
412#else
413 while ((*first != NIL) && (*second != NIL))
414 {
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000415 if (trio_to_upper(*first) != trio_to_upper(*second))
Bjorn Reese026d29f2002-01-19 15:40:18 +0000416 {
417 break;
418 }
419 first++;
420 second++;
421 }
422 return ((*first == NIL) && (*second == NIL));
423#endif
424 }
425 return FALSE;
426}
427
428
429/**
430 Compare if two strings are equal.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800431
Bjorn Reese026d29f2002-01-19 15:40:18 +0000432 @param first First string.
433 @param second Second string.
434 @return Boolean indicating whether the two strings are equal or not.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800435
Bjorn Reese026d29f2002-01-19 15:40:18 +0000436 Case-sensitive comparison.
437*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000438TRIO_STRING_PUBLIC int
439trio_equal_case
440TRIO_ARGS2((first, second),
441 TRIO_CONST char *first,
442 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000443{
444 assert(first);
445 assert(second);
446
447 if ((first != NULL) && (second != NULL))
448 {
449 return (0 == strcmp(first, second));
450 }
451 return FALSE;
452}
453
454
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000455#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000456/**
457 Compare if two strings up until the first @p max characters are equal.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800458
Bjorn Reese026d29f2002-01-19 15:40:18 +0000459 @param first First string.
460 @param max Maximum number of characters to compare.
461 @param second Second string.
462 @return Boolean indicating whether the two strings are equal or not.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800463
Bjorn Reese026d29f2002-01-19 15:40:18 +0000464 Case-sensitive comparison.
465*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000466TRIO_STRING_PUBLIC int
467trio_equal_case_max
468TRIO_ARGS3((first, max, second),
469 TRIO_CONST char *first,
470 size_t max,
471 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000472{
473 assert(first);
474 assert(second);
475
476 if ((first != NULL) && (second != NULL))
477 {
478 return (0 == strncmp(first, second, max));
479 }
480 return FALSE;
481}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000482#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000483
484
485/**
486 Compare if two strings are equal.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800487
Bjorn Reese026d29f2002-01-19 15:40:18 +0000488 @param first First string.
489 @param second Second string.
490 @return Boolean indicating whether the two strings are equal or not.
491
492 Collating characters are considered equal.
493*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000494TRIO_STRING_PUBLIC int
495trio_equal_locale
496TRIO_ARGS2((first, second),
497 TRIO_CONST char *first,
498 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000499{
500 assert(first);
501 assert(second);
502
503#if defined(LC_COLLATE)
504 return (strcoll(first, second) == 0);
505#else
506 return trio_equal(first, second);
507#endif
508}
509
510
511/**
512 Compare if two strings up until the first @p max characters are equal.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800513
Bjorn Reese026d29f2002-01-19 15:40:18 +0000514 @param first First string.
515 @param max Maximum number of characters to compare.
516 @param second Second string.
517 @return Boolean indicating whether the two strings are equal or not.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800518
Bjorn Reese026d29f2002-01-19 15:40:18 +0000519 Case-insensitive comparison.
520*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000521TRIO_STRING_PUBLIC int
522trio_equal_max
523TRIO_ARGS3((first, max, second),
524 TRIO_CONST char *first,
525 size_t max,
526 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000527{
528 assert(first);
529 assert(second);
530
531 if ((first != NULL) && (second != NULL))
532 {
533#if defined(USE_STRNCASECMP)
534 return (0 == strncasecmp(first, second, max));
535#else
536 /* Not adequately tested yet */
537 size_t cnt = 0;
538 while ((*first != NIL) && (*second != NIL) && (cnt <= max))
539 {
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000540 if (trio_to_upper(*first) != trio_to_upper(*second))
Bjorn Reese026d29f2002-01-19 15:40:18 +0000541 {
542 break;
543 }
544 first++;
545 second++;
546 cnt++;
547 }
548 return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
549#endif
550 }
551 return FALSE;
552}
553
554
555/**
556 Provide a textual description of an error code (errno).
557
558 @param error_number Error number.
559 @return Textual description of @p error_number.
560*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000561TRIO_STRING_PUBLIC TRIO_CONST char *
562trio_error
563TRIO_ARGS1((error_number),
564 int error_number)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000565{
566#if defined(USE_STRERROR)
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800567
Bjorn Reese026d29f2002-01-19 15:40:18 +0000568 return strerror(error_number);
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000569
570#elif defined(USE_SYS_ERRLIST)
571
572 extern char *sys_errlist[];
573 extern int sys_nerr;
574
575 return ((error_number < 0) || (error_number >= sys_nerr))
576 ? "unknown"
577 : sys_errlist[error_number];
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800578
Bjorn Reese026d29f2002-01-19 15:40:18 +0000579#else
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800580
Bjorn Reese026d29f2002-01-19 15:40:18 +0000581 return "unknown";
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800582
Bjorn Reese026d29f2002-01-19 15:40:18 +0000583#endif
584}
585
586
Daniel Veillard59d3ed82007-04-17 12:44:58 +0000587#if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000588/**
589 Format the date/time according to @p format.
590
591 @param target Target string.
592 @param max Maximum number of characters to format.
593 @param format Formatting string.
594 @param datetime Date/time structure.
595 @return Number of formatted characters.
596
597 The formatting string accepts the same specifiers as the standard C
598 function strftime.
599*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000600TRIO_STRING_PUBLIC size_t
601trio_format_date_max
602TRIO_ARGS4((target, max, format, datetime),
603 char *target,
604 size_t max,
605 TRIO_CONST char *format,
606 TRIO_CONST struct tm *datetime)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000607{
608 assert(target);
609 assert(format);
610 assert(datetime);
611 assert(max > 0);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800612
Bjorn Reese026d29f2002-01-19 15:40:18 +0000613 return strftime(target, max, format, datetime);
614}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000615#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000616
617
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000618#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000619/**
620 Calculate a hash value for a string.
621
622 @param string String to be calculated on.
623 @param type Hash function.
624 @return Calculated hash value.
625
626 @p type can be one of the following
627 @li @c TRIO_HASH_PLAIN Plain hash function.
628*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000629TRIO_STRING_PUBLIC unsigned long
630trio_hash
631TRIO_ARGS2((string, type),
632 TRIO_CONST char *string,
633 int type)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000634{
635 unsigned long value = 0L;
636 char ch;
637
638 assert(string);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800639
Bjorn Reese026d29f2002-01-19 15:40:18 +0000640 switch (type)
641 {
642 case TRIO_HASH_PLAIN:
643 while ( (ch = *string++) != NIL )
644 {
645 value *= 31;
646 value += (unsigned long)ch;
647 }
648 break;
649 default:
650 assert(FALSE);
651 break;
652 }
653 return value;
654}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000655#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000656
657
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000658#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000659/**
660 Find first occurrence of a character in a string.
661
662 @param string String to be searched.
663 @param character Character to be found.
664 @param A pointer to the found character, or NULL if character was not found.
665 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000666TRIO_STRING_PUBLIC char *
667trio_index
668TRIO_ARGS2((string, character),
669 TRIO_CONST char *string,
670 int character)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000671{
672 assert(string);
673
674 return strchr(string, character);
675}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000676#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000677
678
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000679#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000680/**
681 Find last occurrence of a character in a string.
682
683 @param string String to be searched.
684 @param character Character to be found.
685 @param A pointer to the found character, or NULL if character was not found.
686 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000687TRIO_STRING_PUBLIC char *
688trio_index_last
689TRIO_ARGS2((string, character),
690 TRIO_CONST char *string,
691 int character)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000692{
693 assert(string);
694
695 return strchr(string, character);
696}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000697#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000698
699
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000700#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000701/**
702 Convert the alphabetic letters in the string to lower-case.
703
704 @param target String to be converted.
705 @return Number of processed characters (converted or not).
706*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000707TRIO_STRING_PUBLIC int
708trio_lower
709TRIO_ARGS1((target),
710 char *target)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000711{
712 assert(target);
713
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000714 return trio_span_function(target, target, trio_to_lower);
Bjorn Reese026d29f2002-01-19 15:40:18 +0000715}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000716#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000717
718
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000719#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000720/**
721 Compare two strings using wildcards.
722
723 @param string String to be searched.
724 @param pattern Pattern, including wildcards, to search for.
725 @return Boolean value indicating success or failure.
726
727 Case-insensitive comparison.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800728
Bjorn Reese026d29f2002-01-19 15:40:18 +0000729 The following wildcards can be used
730 @li @c * Match any number of characters.
731 @li @c ? Match a single character.
732*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000733TRIO_STRING_PUBLIC int
734trio_match
735TRIO_ARGS2((string, pattern),
736 TRIO_CONST char *string,
737 TRIO_CONST char *pattern)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000738{
739 assert(string);
740 assert(pattern);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800741
Bjorn Reese026d29f2002-01-19 15:40:18 +0000742 for (; ('*' != *pattern); ++pattern, ++string)
743 {
744 if (NIL == *string)
745 {
746 return (NIL == *pattern);
747 }
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000748 if ((trio_to_upper((int)*string) != trio_to_upper((int)*pattern))
Bjorn Reese026d29f2002-01-19 15:40:18 +0000749 && ('?' != *pattern))
750 {
751 return FALSE;
752 }
753 }
754 /* two-line patch to prevent *too* much recursiveness: */
755 while ('*' == pattern[1])
756 pattern++;
757
758 do
759 {
760 if ( trio_match(string, &pattern[1]) )
761 {
762 return TRUE;
763 }
764 }
765 while (*string++);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800766
Bjorn Reese026d29f2002-01-19 15:40:18 +0000767 return FALSE;
768}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000769#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000770
771
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000772#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000773/**
774 Compare two strings using wildcards.
775
776 @param string String to be searched.
777 @param pattern Pattern, including wildcards, to search for.
778 @return Boolean value indicating success or failure.
779
780 Case-sensitive comparison.
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800781
Bjorn Reese026d29f2002-01-19 15:40:18 +0000782 The following wildcards can be used
783 @li @c * Match any number of characters.
784 @li @c ? Match a single character.
785*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000786TRIO_STRING_PUBLIC int
787trio_match_case
788TRIO_ARGS2((string, pattern),
789 TRIO_CONST char *string,
790 TRIO_CONST char *pattern)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000791{
792 assert(string);
793 assert(pattern);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800794
Bjorn Reese026d29f2002-01-19 15:40:18 +0000795 for (; ('*' != *pattern); ++pattern, ++string)
796 {
797 if (NIL == *string)
798 {
799 return (NIL == *pattern);
800 }
801 if ((*string != *pattern)
802 && ('?' != *pattern))
803 {
804 return FALSE;
805 }
806 }
807 /* two-line patch to prevent *too* much recursiveness: */
808 while ('*' == pattern[1])
809 pattern++;
810
811 do
812 {
813 if ( trio_match_case(string, &pattern[1]) )
814 {
815 return TRUE;
816 }
817 }
818 while (*string++);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800819
Bjorn Reese026d29f2002-01-19 15:40:18 +0000820 return FALSE;
821}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000822#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000823
824
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000825#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000826/**
827 Execute a function on each character in string.
828
829 @param target Target string.
830 @param source Source string.
831 @param Function Function to be executed.
832 @return Number of processed characters.
833*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000834TRIO_STRING_PUBLIC size_t
835trio_span_function
836TRIO_ARGS3((target, source, Function),
837 char *target,
838 TRIO_CONST char *source,
839 int (*Function) TRIO_PROTO((int)))
Bjorn Reese026d29f2002-01-19 15:40:18 +0000840{
841 size_t count = 0;
842
843 assert(target);
844 assert(source);
845 assert(Function);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800846
Bjorn Reese026d29f2002-01-19 15:40:18 +0000847 while (*source != NIL)
848 {
849 *target++ = Function(*source++);
850 count++;
851 }
852 return count;
853}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000854#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000855
856
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000857#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000858/**
859 Search for a substring in a string.
860
861 @param string String to be searched.
862 @param substring String to be found.
863 @return Pointer to first occurrence of @p substring in @p string, or NULL
864 if no match was found.
865*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000866TRIO_STRING_PUBLIC char *
867trio_substring
868TRIO_ARGS2((string, substring),
869 TRIO_CONST char *string,
870 TRIO_CONST char *substring)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000871{
872 assert(string);
873 assert(substring);
874
875 return strstr(string, substring);
876}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000877#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000878
879
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000880#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000881/**
882 Search for a substring in the first @p max characters of a string.
883
884 @param string String to be searched.
885 @param max Maximum characters to be searched.
886 @param substring String to be found.
887 @return Pointer to first occurrence of @p substring in @p string, or NULL
888 if no match was found.
889*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000890TRIO_STRING_PUBLIC char *
891trio_substring_max
892TRIO_ARGS3((string, max, substring),
893 TRIO_CONST char *string,
894 size_t max,
895 TRIO_CONST char *substring)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000896{
897 size_t count;
898 size_t size;
899 char *result = NULL;
900
901 assert(string);
902 assert(substring);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800903
Bjorn Reese026d29f2002-01-19 15:40:18 +0000904 size = trio_length(substring);
905 if (size <= max)
906 {
907 for (count = 0; count <= max - size; count++)
908 {
909 if (trio_equal_max(substring, size, &string[count]))
910 {
911 result = (char *)&string[count];
912 break;
913 }
914 }
915 }
916 return result;
917}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000918#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000919
920
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000921#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000922/**
923 Tokenize string.
924
925 @param string String to be tokenized.
926 @param tokens String containing list of delimiting characters.
927 @return Start of new token.
928
929 @warning @p string will be destroyed.
930*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000931TRIO_STRING_PUBLIC char *
932trio_tokenize
933TRIO_ARGS2((string, delimiters),
934 char *string,
935 TRIO_CONST char *delimiters)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000936{
937 assert(delimiters);
Daniel Veillardf8e3db02012-09-11 13:26:36 +0800938
Bjorn Reese026d29f2002-01-19 15:40:18 +0000939 return strtok(string, delimiters);
940}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000941#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000942
943
944/**
945 Convert string to floating-point number.
946
947 @param source String to be converted.
948 @param endp Pointer to end of the converted string.
949 @return A floating-point number.
950
951 The following Extended Backus-Naur form is used
952 @verbatim
953 double ::= [ <sign> ]
954 ( <number> |
955 <number> <decimal_point> <number> |
956 <decimal_point> <number> )
957 [ <exponential> [ <sign> ] <number> ]
958 number ::= 1*( <digit> )
959 digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
960 exponential ::= ( 'e' | 'E' )
961 sign ::= ( '-' | '+' )
962 decimal_point ::= '.'
963 @endverbatim
964*/
965/* FIXME: Add EBNF for hex-floats */
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000966TRIO_STRING_PUBLIC trio_long_double_t
967trio_to_long_double
968TRIO_ARGS2((source, endp),
969 TRIO_CONST char *source,
970 char **endp)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000971{
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000972#if defined(USE_STRTOLD)
973 return strtold(source, endp);
Bjorn Reese026d29f2002-01-19 15:40:18 +0000974#else
Bjorn Reese026d29f2002-01-19 15:40:18 +0000975 int isNegative = FALSE;
976 int isExponentNegative = FALSE;
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000977 trio_long_double_t integer = 0.0;
978 trio_long_double_t fraction = 0.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +0000979 unsigned long exponent = 0;
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000980 trio_long_double_t base;
981 trio_long_double_t fracdiv = 1.0;
982 trio_long_double_t value = 0.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +0000983
984 /* First try hex-floats */
985 if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
986 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000987 base = 16.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +0000988 source += 2;
989 while (isxdigit((int)*source))
990 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000991 integer *= base;
Bjorn Reese026d29f2002-01-19 15:40:18 +0000992 integer += (isdigit((int)*source)
993 ? (*source - '0')
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000994 : 10 + (trio_to_upper((int)*source) - 'A'));
Bjorn Reese026d29f2002-01-19 15:40:18 +0000995 source++;
996 }
997 if (*source == '.')
998 {
999 source++;
1000 while (isxdigit((int)*source))
1001 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001002 fracdiv /= base;
1003 fraction += fracdiv * (isdigit((int)*source)
1004 ? (*source - '0')
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001005 : 10 + (trio_to_upper((int)*source) - 'A'));
Bjorn Reese026d29f2002-01-19 15:40:18 +00001006 source++;
1007 }
1008 if ((*source == 'p') || (*source == 'P'))
1009 {
1010 source++;
1011 if ((*source == '+') || (*source == '-'))
1012 {
1013 isExponentNegative = (*source == '-');
1014 source++;
1015 }
1016 while (isdigit((int)*source))
1017 {
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001018 exponent *= 10;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001019 exponent += (*source - '0');
1020 source++;
1021 }
1022 }
1023 }
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001024 /* For later use with exponent */
1025 base = 2.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001026 }
1027 else /* Then try normal decimal floats */
1028 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001029 base = 10.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001030 isNegative = (*source == '-');
1031 /* Skip sign */
1032 if ((*source == '+') || (*source == '-'))
1033 source++;
1034
1035 /* Integer part */
1036 while (isdigit((int)*source))
1037 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001038 integer *= base;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001039 integer += (*source - '0');
1040 source++;
1041 }
1042
1043 if (*source == '.')
1044 {
1045 source++; /* skip decimal point */
1046 while (isdigit((int)*source))
1047 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001048 fracdiv /= base;
1049 fraction += (*source - '0') * fracdiv;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001050 source++;
1051 }
1052 }
1053 if ((*source == 'e')
1054 || (*source == 'E')
1055#if TRIO_MICROSOFT
1056 || (*source == 'd')
1057 || (*source == 'D')
1058#endif
1059 )
1060 {
1061 source++; /* Skip exponential indicator */
1062 isExponentNegative = (*source == '-');
1063 if ((*source == '+') || (*source == '-'))
1064 source++;
1065 while (isdigit((int)*source))
1066 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001067 exponent *= (int)base;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001068 exponent += (*source - '0');
1069 source++;
1070 }
1071 }
1072 }
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001073
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001074 value = integer + fraction;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001075 if (exponent != 0)
1076 {
1077 if (isExponentNegative)
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001078 value /= pow(base, (double)exponent);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001079 else
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001080 value *= pow(base, (double)exponent);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001081 }
1082 if (isNegative)
1083 value = -value;
1084
1085 if (endp)
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001086 *endp = (char *)source;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001087 return value;
1088#endif
1089}
1090
1091
1092/**
1093 Convert string to floating-point number.
1094
1095 @param source String to be converted.
1096 @param endp Pointer to end of the converted string.
1097 @return A floating-point number.
1098
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001099 See @ref trio_to_long_double.
Bjorn Reese026d29f2002-01-19 15:40:18 +00001100*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001101TRIO_STRING_PUBLIC double
1102trio_to_double
1103TRIO_ARGS2((source, endp),
1104 TRIO_CONST char *source,
1105 char **endp)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001106{
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001107#if defined(USE_STRTOD)
1108 return strtod(source, endp);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001109#else
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001110 return (double)trio_to_long_double(source, endp);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001111#endif
1112}
1113
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001114#if !defined(TRIO_MINIMAL)
1115/**
1116 Convert string to floating-point number.
1117
1118 @param source String to be converted.
1119 @param endp Pointer to end of the converted string.
1120 @return A floating-point number.
1121
1122 See @ref trio_to_long_double.
1123*/
1124TRIO_STRING_PUBLIC float
1125trio_to_float
1126TRIO_ARGS2((source, endp),
1127 TRIO_CONST char *source,
1128 char **endp)
1129{
1130#if defined(USE_STRTOF)
1131 return strtof(source, endp);
1132#else
1133 return (float)trio_to_long_double(source, endp);
1134#endif
1135}
1136#endif /* !defined(TRIO_MINIMAL) */
1137
Bjorn Reese026d29f2002-01-19 15:40:18 +00001138
1139/**
1140 Convert string to signed integer.
1141
1142 @param string String to be converted.
1143 @param endp Pointer to end of converted string.
1144 @param base Radix number of number.
1145*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001146TRIO_STRING_PUBLIC long
1147trio_to_long
1148TRIO_ARGS3((string, endp, base),
1149 TRIO_CONST char *string,
1150 char **endp,
1151 int base)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001152{
1153 assert(string);
1154 assert((base >= 2) && (base <= 36));
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001155
Bjorn Reese026d29f2002-01-19 15:40:18 +00001156 return strtol(string, endp, base);
1157}
1158
1159
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001160#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001161/**
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001162 Convert one alphabetic letter to lower-case.
1163
1164 @param source The letter to be converted.
1165 @return The converted letter.
1166*/
1167TRIO_STRING_PUBLIC int
1168trio_to_lower
1169TRIO_ARGS1((source),
1170 int source)
1171{
1172#if defined(USE_TOLOWER)
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001173
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001174 return tolower(source);
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001175
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001176#else
1177
1178 /* Does not handle locales or non-contiguous alphabetic characters */
1179 return ((source >= (int)'A') && (source <= (int)'Z'))
1180 ? source - 'A' + 'a'
1181 : source;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001182
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001183#endif
1184}
1185#endif /* !defined(TRIO_MINIMAL) */
1186
1187#if !defined(TRIO_MINIMAL)
1188/**
Bjorn Reese026d29f2002-01-19 15:40:18 +00001189 Convert string to unsigned integer.
1190
1191 @param string String to be converted.
1192 @param endp Pointer to end of converted string.
1193 @param base Radix number of number.
1194*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001195TRIO_STRING_PUBLIC unsigned long
1196trio_to_unsigned_long
1197TRIO_ARGS3((string, endp, base),
1198 TRIO_CONST char *string,
1199 char **endp,
1200 int base)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001201{
1202 assert(string);
1203 assert((base >= 2) && (base <= 36));
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001204
Bjorn Reese026d29f2002-01-19 15:40:18 +00001205 return strtoul(string, endp, base);
1206}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001207#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001208
1209
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001210/**
1211 Convert one alphabetic letter to upper-case.
1212
1213 @param source The letter to be converted.
1214 @return The converted letter.
1215*/
1216TRIO_STRING_PUBLIC int
1217trio_to_upper
1218TRIO_ARGS1((source),
1219 int source)
1220{
1221#if defined(USE_TOUPPER)
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001222
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001223 return toupper(source);
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001224
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001225#else
1226
1227 /* Does not handle locales or non-contiguous alphabetic characters */
1228 return ((source >= (int)'a') && (source <= (int)'z'))
1229 ? source - 'a' + 'A'
1230 : source;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001231
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001232#endif
1233}
1234
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001235#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001236/**
1237 Convert the alphabetic letters in the string to upper-case.
1238
1239 @param target The string to be converted.
1240 @return The number of processed characters (converted or not).
1241*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001242TRIO_STRING_PUBLIC int
1243trio_upper
1244TRIO_ARGS1((target),
1245 char *target)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001246{
1247 assert(target);
1248
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001249 return trio_span_function(target, target, trio_to_upper);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001250}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001251#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001252
1253
1254/** @} End of StaticStrings */
1255
1256
1257/*************************************************************************
1258 * Dynamic String Functions
1259 */
1260
1261#if defined(TRIO_DOCUMENTATION)
1262# include "doc/doc_dynamic.h"
1263#endif
1264/** @addtogroup DynamicStrings
1265 @{
1266*/
1267
1268/*
1269 * TrioStringAlloc
1270 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001271TRIO_STRING_PRIVATE trio_string_t *
1272TrioStringAlloc(TRIO_NOARGS)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001273{
1274 trio_string_t *self;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001275
Bjorn Reese026d29f2002-01-19 15:40:18 +00001276 self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
1277 if (self)
1278 {
1279 self->content = NULL;
1280 self->length = 0;
1281 self->allocated = 0;
1282 }
1283 return self;
1284}
1285
1286
1287/*
1288 * TrioStringGrow
1289 *
1290 * The size of the string will be increased by 'delta' characters. If
1291 * 'delta' is zero, the size will be doubled.
1292 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001293TRIO_STRING_PRIVATE BOOLEAN_T
1294TrioStringGrow
1295TRIO_ARGS2((self, delta),
1296 trio_string_t *self,
1297 size_t delta)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001298{
1299 BOOLEAN_T status = FALSE;
1300 char *new_content;
1301 size_t new_size;
1302
1303 new_size = (delta == 0)
1304 ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
1305 : self->allocated + delta;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001306
Bjorn Reese026d29f2002-01-19 15:40:18 +00001307 new_content = (char *)TRIO_REALLOC(self->content, new_size);
1308 if (new_content)
1309 {
1310 self->content = new_content;
1311 self->allocated = new_size;
1312 status = TRUE;
1313 }
1314 return status;
1315}
1316
1317
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001318#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001319/*
1320 * TrioStringGrowTo
1321 *
1322 * The size of the string will be increased to 'length' plus one characters.
1323 * If 'length' is less than the original size, the original size will be
1324 * used (that is, the size of the string is never decreased).
1325 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001326TRIO_STRING_PRIVATE BOOLEAN_T
1327TrioStringGrowTo
1328TRIO_ARGS2((self, length),
1329 trio_string_t *self,
1330 size_t length)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001331{
1332 length++; /* Room for terminating zero */
1333 return (self->allocated < length)
1334 ? TrioStringGrow(self, length - self->allocated)
1335 : TRUE;
1336}
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001337#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001338
1339
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001340#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001341/**
1342 Create a new dynamic string.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001343
Bjorn Reese026d29f2002-01-19 15:40:18 +00001344 @param initial_size Initial size of the buffer.
1345 @return Newly allocated dynamic string, or NULL if memory allocation failed.
1346*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001347TRIO_STRING_PUBLIC trio_string_t *
1348trio_string_create
1349TRIO_ARGS1((initial_size),
1350 int initial_size)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001351{
1352 trio_string_t *self;
1353
1354 self = TrioStringAlloc();
1355 if (self)
1356 {
1357 if (TrioStringGrow(self,
1358 (size_t)((initial_size > 0) ? initial_size : 1)))
1359 {
1360 self->content[0] = (char)0;
1361 self->allocated = initial_size;
1362 }
1363 else
1364 {
1365 trio_string_destroy(self);
1366 self = NULL;
1367 }
1368 }
1369 return self;
1370}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001371#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001372
1373
1374/**
1375 Deallocate the dynamic string and its contents.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001376
Bjorn Reese026d29f2002-01-19 15:40:18 +00001377 @param self Dynamic string
1378*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001379TRIO_STRING_PUBLIC void
1380trio_string_destroy
1381TRIO_ARGS1((self),
1382 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001383{
1384 assert(self);
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001385
Bjorn Reese026d29f2002-01-19 15:40:18 +00001386 if (self)
1387 {
1388 trio_destroy(self->content);
1389 TRIO_FREE(self);
1390 }
1391}
1392
1393
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001394#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001395/**
1396 Get a pointer to the content.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001397
Bjorn Reese026d29f2002-01-19 15:40:18 +00001398 @param self Dynamic string.
1399 @param offset Offset into content.
1400 @return Pointer to the content.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001401
Bjorn Reese026d29f2002-01-19 15:40:18 +00001402 @p Offset can be zero, positive, or negative. If @p offset is zero,
1403 then the start of the content will be returned. If @p offset is positive,
1404 then a pointer to @p offset number of characters from the beginning of the
1405 content is returned. If @p offset is negative, then a pointer to @p offset
1406 number of characters from the ending of the string, starting at the
1407 terminating zero, is returned.
1408*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001409TRIO_STRING_PUBLIC char *
1410trio_string_get
1411TRIO_ARGS2((self, offset),
1412 trio_string_t *self,
1413 int offset)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001414{
1415 char *result = NULL;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001416
Bjorn Reese026d29f2002-01-19 15:40:18 +00001417 assert(self);
1418
1419 if (self->content != NULL)
1420 {
1421 if (self->length == 0)
1422 {
1423 (void)trio_string_length(self);
1424 }
1425 if (offset >= 0)
1426 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001427 if (offset > (int)self->length)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001428 {
1429 offset = self->length;
1430 }
1431 }
1432 else
1433 {
1434 offset += self->length + 1;
1435 if (offset < 0)
1436 {
1437 offset = 0;
1438 }
1439 }
1440 result = &(self->content[offset]);
1441 }
1442 return result;
1443}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001444#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001445
1446
1447/**
1448 Extract the content.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001449
Bjorn Reese026d29f2002-01-19 15:40:18 +00001450 @param self Dynamic String
1451 @return Content of dynamic string.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001452
Bjorn Reese026d29f2002-01-19 15:40:18 +00001453 The content is removed from the dynamic string. This enables destruction
1454 of the dynamic string without deallocation of the content.
1455*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001456TRIO_STRING_PUBLIC char *
1457trio_string_extract
1458TRIO_ARGS1((self),
1459 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001460{
1461 char *result;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001462
Bjorn Reese026d29f2002-01-19 15:40:18 +00001463 assert(self);
1464
1465 result = self->content;
1466 /* FIXME: Allocate new empty buffer? */
1467 self->content = NULL;
1468 self->length = self->allocated = 0;
1469 return result;
1470}
1471
1472
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001473#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001474/**
1475 Set the content of the dynamic string.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001476
Bjorn Reese026d29f2002-01-19 15:40:18 +00001477 @param self Dynamic String
1478 @param buffer The new content.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001479
Bjorn Reese026d29f2002-01-19 15:40:18 +00001480 Sets the content of the dynamic string to a copy @p buffer.
1481 An existing content will be deallocated first, if necessary.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001482
Bjorn Reese026d29f2002-01-19 15:40:18 +00001483 @remark
1484 This function will make a copy of @p buffer.
1485 You are responsible for deallocating @p buffer yourself.
1486*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001487TRIO_STRING_PUBLIC void
1488trio_xstring_set
1489TRIO_ARGS2((self, buffer),
1490 trio_string_t *self,
1491 char *buffer)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001492{
1493 assert(self);
1494
1495 trio_destroy(self->content);
1496 self->content = trio_duplicate(buffer);
1497}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001498#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001499
1500
1501/*
1502 * trio_string_size
1503 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001504TRIO_STRING_PUBLIC int
1505trio_string_size
1506TRIO_ARGS1((self),
1507 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001508{
1509 assert(self);
1510
1511 return self->allocated;
1512}
1513
1514
1515/*
1516 * trio_string_terminate
1517 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001518TRIO_STRING_PUBLIC void
1519trio_string_terminate
1520TRIO_ARGS1((self),
1521 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001522{
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001523 trio_xstring_append_char(self, 0);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001524}
1525
1526
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001527#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001528/**
1529 Append the second string to the first.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001530
Bjorn Reese026d29f2002-01-19 15:40:18 +00001531 @param self Dynamic string to be modified.
1532 @param other Dynamic string to copy from.
1533 @return Boolean value indicating success or failure.
1534*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001535TRIO_STRING_PUBLIC int
1536trio_string_append
1537TRIO_ARGS2((self, other),
1538 trio_string_t *self,
1539 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001540{
1541 size_t length;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001542
Bjorn Reese026d29f2002-01-19 15:40:18 +00001543 assert(self);
1544 assert(other);
1545
1546 length = self->length + other->length;
1547 if (!TrioStringGrowTo(self, length))
1548 goto error;
1549 trio_copy(&self->content[self->length], other->content);
1550 self->length = length;
1551 return TRUE;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001552
Bjorn Reese026d29f2002-01-19 15:40:18 +00001553 error:
1554 return FALSE;
1555}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001556#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001557
1558
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001559#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001560/*
1561 * trio_xstring_append
1562 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001563TRIO_STRING_PUBLIC int
1564trio_xstring_append
1565TRIO_ARGS2((self, other),
1566 trio_string_t *self,
1567 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001568{
1569 size_t length;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001570
Bjorn Reese026d29f2002-01-19 15:40:18 +00001571 assert(self);
1572 assert(other);
1573
1574 length = self->length + trio_length(other);
1575 if (!TrioStringGrowTo(self, length))
1576 goto error;
1577 trio_copy(&self->content[self->length], other);
1578 self->length = length;
1579 return TRUE;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001580
Bjorn Reese026d29f2002-01-19 15:40:18 +00001581 error:
1582 return FALSE;
1583}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001584#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001585
1586
1587/*
1588 * trio_xstring_append_char
1589 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001590TRIO_STRING_PUBLIC int
1591trio_xstring_append_char
1592TRIO_ARGS2((self, character),
1593 trio_string_t *self,
1594 char character)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001595{
1596 assert(self);
1597
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001598 if ((int)self->length >= trio_string_size(self))
Bjorn Reese026d29f2002-01-19 15:40:18 +00001599 {
1600 if (!TrioStringGrow(self, 0))
1601 goto error;
1602 }
1603 self->content[self->length] = character;
1604 self->length++;
1605 return TRUE;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001606
Bjorn Reese026d29f2002-01-19 15:40:18 +00001607 error:
1608 return FALSE;
1609}
1610
1611
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001612#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001613/**
1614 Search for the first occurrence of second parameter in the first.
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001615
Bjorn Reese026d29f2002-01-19 15:40:18 +00001616 @param self Dynamic string to be modified.
1617 @param other Dynamic string to copy from.
1618 @return Boolean value indicating success or failure.
1619*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001620TRIO_STRING_PUBLIC int
1621trio_string_contains
1622TRIO_ARGS2((self, other),
1623 trio_string_t *self,
1624 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001625{
1626 assert(self);
1627 assert(other);
1628
1629 return trio_contains(self->content, other->content);
1630}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001631#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001632
1633
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001634#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001635/*
1636 * trio_xstring_contains
1637 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001638TRIO_STRING_PUBLIC int
1639trio_xstring_contains
1640TRIO_ARGS2((self, other),
1641 trio_string_t *self,
1642 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001643{
1644 assert(self);
1645 assert(other);
1646
1647 return trio_contains(self->content, other);
1648}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001649#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001650
1651
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001652#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001653/*
1654 * trio_string_copy
1655 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001656TRIO_STRING_PUBLIC int
1657trio_string_copy
1658TRIO_ARGS2((self, other),
1659 trio_string_t *self,
1660 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001661{
1662 assert(self);
1663 assert(other);
1664
1665 self->length = 0;
1666 return trio_string_append(self, other);
1667}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001668#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001669
1670
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001671#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001672/*
1673 * trio_xstring_copy
1674 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001675TRIO_STRING_PUBLIC int
1676trio_xstring_copy
1677TRIO_ARGS2((self, other),
1678 trio_string_t *self,
1679 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001680{
1681 assert(self);
1682 assert(other);
1683
1684 self->length = 0;
1685 return trio_xstring_append(self, other);
1686}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001687#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001688
1689
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001690#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001691/*
1692 * trio_string_duplicate
1693 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001694TRIO_STRING_PUBLIC trio_string_t *
1695trio_string_duplicate
1696TRIO_ARGS1((other),
1697 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001698{
1699 trio_string_t *self;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001700
Bjorn Reese026d29f2002-01-19 15:40:18 +00001701 assert(other);
1702
1703 self = TrioStringAlloc();
1704 if (self)
1705 {
1706 self->content = TrioDuplicateMax(other->content, other->length);
1707 if (self->content)
1708 {
1709 self->length = other->length;
1710 self->allocated = self->length + 1;
1711 }
1712 else
1713 {
1714 self->length = self->allocated = 0;
1715 }
1716 }
1717 return self;
1718}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001719#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001720
1721
1722/*
1723 * trio_xstring_duplicate
1724 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001725TRIO_STRING_PUBLIC trio_string_t *
1726trio_xstring_duplicate
1727TRIO_ARGS1((other),
1728 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001729{
1730 trio_string_t *self;
Daniel Veillardf8e3db02012-09-11 13:26:36 +08001731
Bjorn Reese026d29f2002-01-19 15:40:18 +00001732 assert(other);
1733
1734 self = TrioStringAlloc();
1735 if (self)
1736 {
1737 self->content = TrioDuplicateMax(other, trio_length(other));
1738 if (self->content)
1739 {
1740 self->length = trio_length(self->content);
1741 self->allocated = self->length + 1;
1742 }
1743 else
1744 {
1745 self->length = self->allocated = 0;
1746 }
1747 }
1748 return self;
1749}
1750
1751
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001752#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001753/*
1754 * trio_string_equal
1755 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001756TRIO_STRING_PUBLIC int
1757trio_string_equal
1758TRIO_ARGS2((self, other),
1759 trio_string_t *self,
1760 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001761{
1762 assert(self);
1763 assert(other);
1764
1765 return trio_equal(self->content, other->content);
1766}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001767#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001768
1769
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001770#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001771/*
1772 * trio_xstring_equal
1773 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001774TRIO_STRING_PUBLIC int
1775trio_xstring_equal
1776TRIO_ARGS2((self, other),
1777 trio_string_t *self,
1778 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001779{
1780 assert(self);
1781 assert(other);
1782
1783 return trio_equal(self->content, other);
1784}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001785#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001786
1787
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001788#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001789/*
1790 * trio_string_equal_max
1791 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001792TRIO_STRING_PUBLIC int
1793trio_string_equal_max
1794TRIO_ARGS3((self, max, other),
1795 trio_string_t *self,
1796 size_t max,
1797 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001798{
1799 assert(self);
1800 assert(other);
1801
1802 return trio_equal_max(self->content, max, other->content);
1803}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001804#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001805
1806
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001807#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001808/*
1809 * trio_xstring_equal_max
1810 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001811TRIO_STRING_PUBLIC int
1812trio_xstring_equal_max
1813TRIO_ARGS3((self, max, other),
1814 trio_string_t *self,
1815 size_t max,
1816 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001817{
1818 assert(self);
1819 assert(other);
1820
1821 return trio_equal_max(self->content, max, other);
1822}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001823#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001824
1825
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001826#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001827/*
1828 * trio_string_equal_case
1829 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001830TRIO_STRING_PUBLIC int
1831trio_string_equal_case
1832TRIO_ARGS2((self, other),
1833 trio_string_t *self,
1834 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001835{
1836 assert(self);
1837 assert(other);
1838
1839 return trio_equal_case(self->content, other->content);
1840}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001841#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001842
1843
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001844#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001845/*
1846 * trio_xstring_equal_case
1847 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001848TRIO_STRING_PUBLIC int
1849trio_xstring_equal_case
1850TRIO_ARGS2((self, other),
1851 trio_string_t *self,
1852 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001853{
1854 assert(self);
1855 assert(other);
1856
1857 return trio_equal_case(self->content, other);
1858}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001859#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001860
1861
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001862#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001863/*
1864 * trio_string_equal_case_max
1865 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001866TRIO_STRING_PUBLIC int
1867trio_string_equal_case_max
1868TRIO_ARGS3((self, max, other),
1869 trio_string_t *self,
1870 size_t max,
1871 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001872{
1873 assert(self);
1874 assert(other);
1875
1876 return trio_equal_case_max(self->content, max, other->content);
1877}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001878#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001879
1880
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001881#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001882/*
1883 * trio_xstring_equal_case_max
1884 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001885TRIO_STRING_PUBLIC int
1886trio_xstring_equal_case_max
1887TRIO_ARGS3((self, max, other),
1888 trio_string_t *self,
1889 size_t max,
1890 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001891{
1892 assert(self);
1893 assert(other);
1894
1895 return trio_equal_case_max(self->content, max, other);
1896}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001897#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001898
1899
Daniel Veillard59d3ed82007-04-17 12:44:58 +00001900#if !defined(TRIO_MINIMAL) && !defined(_WIN32_WCE)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001901/*
1902 * trio_string_format_data_max
1903 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001904TRIO_STRING_PUBLIC size_t
1905trio_string_format_date_max
1906TRIO_ARGS4((self, max, format, datetime),
1907 trio_string_t *self,
1908 size_t max,
1909 TRIO_CONST char *format,
1910 TRIO_CONST struct tm *datetime)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001911{
1912 assert(self);
1913
1914 return trio_format_date_max(self->content, max, format, datetime);
1915}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001916#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001917
1918
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001919#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001920/*
1921 * trio_string_index
1922 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001923TRIO_STRING_PUBLIC char *
1924trio_string_index
1925TRIO_ARGS2((self, character),
1926 trio_string_t *self,
1927 int character)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001928{
1929 assert(self);
1930
1931 return trio_index(self->content, character);
1932}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001933#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001934
1935
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001936#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001937/*
1938 * trio_string_index_last
1939 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001940TRIO_STRING_PUBLIC char *
1941trio_string_index_last
1942TRIO_ARGS2((self, character),
1943 trio_string_t *self,
1944 int character)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001945{
1946 assert(self);
1947
1948 return trio_index_last(self->content, character);
1949}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001950#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001951
1952
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001953#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001954/*
1955 * trio_string_length
1956 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001957TRIO_STRING_PUBLIC int
1958trio_string_length
1959TRIO_ARGS1((self),
1960 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001961{
1962 assert(self);
1963
1964 if (self->length == 0)
1965 {
1966 self->length = trio_length(self->content);
1967 }
1968 return self->length;
1969}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001970#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001971
1972
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001973#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001974/*
1975 * trio_string_lower
1976 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001977TRIO_STRING_PUBLIC int
1978trio_string_lower
1979TRIO_ARGS1((self),
1980 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001981{
1982 assert(self);
1983
1984 return trio_lower(self->content);
1985}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001986#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001987
1988
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001989#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001990/*
1991 * trio_string_match
1992 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001993TRIO_STRING_PUBLIC int
1994trio_string_match
1995TRIO_ARGS2((self, other),
1996 trio_string_t *self,
1997 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001998{
1999 assert(self);
2000 assert(other);
2001
2002 return trio_match(self->content, other->content);
2003}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002004#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002005
2006
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002007#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002008/*
2009 * trio_xstring_match
2010 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002011TRIO_STRING_PUBLIC int
2012trio_xstring_match
2013TRIO_ARGS2((self, other),
2014 trio_string_t *self,
2015 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002016{
2017 assert(self);
2018 assert(other);
2019
2020 return trio_match(self->content, other);
2021}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002022#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002023
2024
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002025#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002026/*
2027 * trio_string_match_case
2028 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002029TRIO_STRING_PUBLIC int
2030trio_string_match_case
2031TRIO_ARGS2((self, other),
2032 trio_string_t *self,
2033 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002034{
2035 assert(self);
2036 assert(other);
2037
2038 return trio_match_case(self->content, other->content);
2039}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002040#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002041
2042
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002043#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002044/*
2045 * trio_xstring_match_case
2046 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002047TRIO_STRING_PUBLIC int
2048trio_xstring_match_case
2049TRIO_ARGS2((self, other),
2050 trio_string_t *self,
2051 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002052{
2053 assert(self);
2054 assert(other);
2055
2056 return trio_match_case(self->content, other);
2057}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002058#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002059
2060
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002061#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002062/*
2063 * trio_string_substring
2064 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002065TRIO_STRING_PUBLIC char *
2066trio_string_substring
2067TRIO_ARGS2((self, other),
2068 trio_string_t *self,
2069 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002070{
2071 assert(self);
2072 assert(other);
2073
2074 return trio_substring(self->content, other->content);
2075}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002076#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002077
2078
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002079#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002080/*
2081 * trio_xstring_substring
2082 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002083TRIO_STRING_PUBLIC char *
2084trio_xstring_substring
2085TRIO_ARGS2((self, other),
2086 trio_string_t *self,
2087 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002088{
2089 assert(self);
2090 assert(other);
2091
2092 return trio_substring(self->content, other);
2093}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002094#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002095
2096
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002097#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002098/*
2099 * trio_string_upper
2100 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002101TRIO_STRING_PUBLIC int
2102trio_string_upper
2103TRIO_ARGS1((self),
2104 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002105{
2106 assert(self);
2107
2108 return trio_upper(self->content);
2109}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002110#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002111
2112/** @} End of DynamicStrings */