blob: 2082e961d6fcfd7f4c597248366f213f5b74f4e0 [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
55#if defined(TRIO_COMPILER_SUPPORTS_C99)
56# define USE_STRTOD
57# define USE_STRTOF
58#elif defined(TRIO_COMPILER_MSVC)
59# define USE_STRTOD
60#endif
61
62#if defined(TRIO_PLATFORM_UNIX)
63# define USE_STRCASECMP
64# define USE_STRNCASECMP
Daniel Veillarda48ed3d2003-04-03 15:28:28 +000065# if defined(TRIO_PLATFORM_SUNOS)
66# define USE_SYS_ERRLIST
67# else
68# define USE_STRERROR
69# endif
Bjorn Reese026d29f2002-01-19 15:40:18 +000070# if defined(TRIO_PLATFORM_QNX)
71# define strcasecmp(x,y) stricmp(x,y)
72# define strncasecmp(x,y,n) strnicmp(x,y,n)
73# endif
74#elif defined(TRIO_PLATFORM_WIN32)
75# define USE_STRCASECMP
76# define strcasecmp(x,y) strcmpi(x,y)
77#endif
78
Daniel Veillarda48ed3d2003-04-03 15:28:28 +000079#if !(defined(TRIO_PLATFORM_SUNOS))
80# define USE_TOLOWER
81# define USE_TOUPPER
82#endif
83
Bjorn Reese026d29f2002-01-19 15:40:18 +000084/*************************************************************************
85 * Structures
86 */
87
88struct _trio_string_t
89{
90 char *content;
91 size_t length;
92 size_t allocated;
93};
94
95/*************************************************************************
Daniel Veillardb7c29c32002-09-25 22:44:43 +000096 * Constants
97 */
98
99#if !defined(TRIO_MINIMAL)
100static TRIO_CONST char rcsid[] = "@(#)$Id$";
101#endif
102
103/*************************************************************************
Bjorn Reese026d29f2002-01-19 15:40:18 +0000104 * Static String Functions
105 */
106
107#if defined(TRIO_DOCUMENTATION)
108# include "doc/doc_static.h"
109#endif
110/** @addtogroup StaticStrings
111 @{
112*/
113
114/**
115 Create new string.
116
117 @param size Size of new string.
118 @return Pointer to string, or NULL if allocation failed.
119*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000120TRIO_STRING_PUBLIC char *
121trio_create
122TRIO_ARGS1((size),
123 size_t size)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000124{
125 return (char *)TRIO_MALLOC(size);
126}
127
128
129/**
130 Destroy string.
131
132 @param string String to be freed.
133*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000134TRIO_STRING_PUBLIC void
135trio_destroy
136TRIO_ARGS1((string),
137 char *string)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000138{
139 if (string)
140 {
141 TRIO_FREE(string);
142 }
143}
144
145
146/**
147 Count the number of characters in a string.
148
149 @param string String to measure.
150 @return Number of characters in @string.
151*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000152TRIO_STRING_PUBLIC size_t
153trio_length
154TRIO_ARGS1((string),
155 TRIO_CONST char *string)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000156{
157 return strlen(string);
158}
159
160
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000161#if !defined(TRIO_MINIMAL)
162/**
163 Append @p source at the end of @p target.
164
165 @param target Target string.
166 @param source Source string.
167 @return Boolean value indicating success or failure.
168
169 @pre @p target must point to a memory chunk with sufficient room to
170 contain the @p target string and @p source string.
171 @pre No boundary checking is performed, so insufficient memory will
172 result in a buffer overrun.
173 @post @p target will be zero terminated.
174*/
175TRIO_STRING_PUBLIC int
176trio_append
177TRIO_ARGS2((target, source),
178 char *target,
179 TRIO_CONST char *source)
180{
181 assert(target);
182 assert(source);
183
184 return (strcat(target, source) != NULL);
185}
186#endif /* !defined(TRIO_MINIMAL) */
187
188#if !defined(TRIO_MINIMAL)
189/**
190 Append at most @p max characters from @p source to @p target.
191
192 @param target Target string.
193 @param max Maximum number of characters to append.
194 @param source Source string.
195 @return Boolean value indicating success or failure.
196
197 @pre @p target must point to a memory chuck with sufficient room to
198 contain the @p target string and the @p source string (at most @p max
199 characters).
200 @pre No boundary checking is performed, so insufficient memory will
201 result in a buffer overrun.
202 @post @p target will be zero terminated.
203*/
204TRIO_STRING_PUBLIC int
205trio_append_max
206TRIO_ARGS3((target, max, source),
207 char *target,
208 size_t max,
209 TRIO_CONST char *source)
210{
211 size_t length;
212
213 assert(target);
214 assert(source);
215
216 length = trio_length(target);
217
218 if (max > length)
219 {
220 strncat(target, source, max - length - 1);
221 }
222 return TRUE;
223}
224#endif /* !defined(TRIO_MINIMAL) */
225
226
227#if !defined(TRIO_MINIMAL)
228/**
229 Determine if a string contains a substring.
230
231 @param string String to be searched.
232 @param substring String to be found.
233 @return Boolean value indicating success or failure.
234*/
235TRIO_STRING_PUBLIC int
236trio_contains
237TRIO_ARGS2((string, substring),
238 TRIO_CONST char *string,
239 TRIO_CONST char *substring)
240{
241 assert(string);
242 assert(substring);
243
244 return (0 != strstr(string, substring));
245}
246#endif /* !defined(TRIO_MINIMAL) */
247
248
249#if !defined(TRIO_MINIMAL)
250/**
251 Copy @p source to @p target.
252
253 @param target Target string.
254 @param source Source string.
255 @return Boolean value indicating success or failure.
256
257 @pre @p target must point to a memory chunk with sufficient room to
258 contain the @p source string.
259 @pre No boundary checking is performed, so insufficient memory will
260 result in a buffer overrun.
261 @post @p target will be zero terminated.
262*/
263TRIO_STRING_PUBLIC int
264trio_copy
265TRIO_ARGS2((target, source),
266 char *target,
267 TRIO_CONST char *source)
268{
269 assert(target);
270 assert(source);
271
272 (void)strcpy(target, source);
273 return TRUE;
274}
275#endif /* !defined(TRIO_MINIMAL) */
276
277
278/**
279 Copy at most @p max characters from @p source to @p target.
280
281 @param target Target string.
282 @param max Maximum number of characters to append.
283 @param source Source string.
284 @return Boolean value indicating success or failure.
285
286 @pre @p target must point to a memory chunk with sufficient room to
287 contain the @p source string (at most @p max characters).
288 @pre No boundary checking is performed, so insufficient memory will
289 result in a buffer overrun.
290 @post @p target will be zero terminated.
291*/
292TRIO_STRING_PUBLIC int
293trio_copy_max
294TRIO_ARGS3((target, max, source),
295 char *target,
296 size_t max,
297 TRIO_CONST char *source)
298{
299 assert(target);
300 assert(source);
301 assert(max > 0); /* Includes != 0 */
302
303 (void)strncpy(target, source, max - 1);
304 target[max - 1] = (char)0;
305 return TRUE;
306}
307
308
Bjorn Reese026d29f2002-01-19 15:40:18 +0000309/*
310 * TrioDuplicateMax
311 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000312TRIO_STRING_PRIVATE char *
313TrioDuplicateMax
314TRIO_ARGS2((source, size),
315 TRIO_CONST char *source,
316 size_t size)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000317{
318 char *target;
319
320 assert(source);
321
322 /* Make room for string plus a terminating zero */
323 size++;
324 target = trio_create(size);
325 if (target)
326 {
327 trio_copy_max(target, size, source);
328 }
329 return target;
330}
331
332
333/**
Bjorn Reese026d29f2002-01-19 15:40:18 +0000334 Duplicate @p source.
335
336 @param source Source string.
337 @return A copy of the @p source string.
338
339 @post @p target will be zero terminated.
340*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000341TRIO_STRING_PUBLIC char *
342trio_duplicate
343TRIO_ARGS1((source),
344 TRIO_CONST char *source)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000345{
346 return TrioDuplicateMax(source, trio_length(source));
347}
348
349
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000350#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000351/**
352 Duplicate at most @p max characters of @p source.
353
354 @param source Source string.
355 @param max Maximum number of characters to duplicate.
356 @return A copy of the @p source string.
357
358 @post @p target will be zero terminated.
359*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000360TRIO_STRING_PUBLIC char *
361trio_duplicate_max TRIO_ARGS2((source, max),
362 TRIO_CONST char *source,
363 size_t max)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000364{
365 size_t length;
366
367 assert(source);
368 assert(max > 0);
369
370 length = trio_length(source);
371 if (length > max)
372 {
373 length = max;
374 }
375 return TrioDuplicateMax(source, length);
376}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000377#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000378
379
380/**
381 Compare if two strings are equal.
382
383 @param first First string.
384 @param second Second string.
385 @return Boolean indicating whether the two strings are equal or not.
386
387 Case-insensitive comparison.
388*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000389TRIO_STRING_PUBLIC int
390trio_equal
391TRIO_ARGS2((first, second),
392 TRIO_CONST char *first,
393 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000394{
395 assert(first);
396 assert(second);
397
398 if ((first != NULL) && (second != NULL))
399 {
400#if defined(USE_STRCASECMP)
401 return (0 == strcasecmp(first, second));
402#else
403 while ((*first != NIL) && (*second != NIL))
404 {
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000405 if (trio_to_upper(*first) != trio_to_upper(*second))
Bjorn Reese026d29f2002-01-19 15:40:18 +0000406 {
407 break;
408 }
409 first++;
410 second++;
411 }
412 return ((*first == NIL) && (*second == NIL));
413#endif
414 }
415 return FALSE;
416}
417
418
419/**
420 Compare if two strings are equal.
421
422 @param first First string.
423 @param second Second string.
424 @return Boolean indicating whether the two strings are equal or not.
425
426 Case-sensitive comparison.
427*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000428TRIO_STRING_PUBLIC int
429trio_equal_case
430TRIO_ARGS2((first, second),
431 TRIO_CONST char *first,
432 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000433{
434 assert(first);
435 assert(second);
436
437 if ((first != NULL) && (second != NULL))
438 {
439 return (0 == strcmp(first, second));
440 }
441 return FALSE;
442}
443
444
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000445#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000446/**
447 Compare if two strings up until the first @p max characters are equal.
448
449 @param first First string.
450 @param max Maximum number of characters to compare.
451 @param second Second string.
452 @return Boolean indicating whether the two strings are equal or not.
453
454 Case-sensitive comparison.
455*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000456TRIO_STRING_PUBLIC int
457trio_equal_case_max
458TRIO_ARGS3((first, max, second),
459 TRIO_CONST char *first,
460 size_t max,
461 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000462{
463 assert(first);
464 assert(second);
465
466 if ((first != NULL) && (second != NULL))
467 {
468 return (0 == strncmp(first, second, max));
469 }
470 return FALSE;
471}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000472#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000473
474
475/**
476 Compare if two strings are equal.
477
478 @param first First string.
479 @param second Second string.
480 @return Boolean indicating whether the two strings are equal or not.
481
482 Collating characters are considered equal.
483*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000484TRIO_STRING_PUBLIC int
485trio_equal_locale
486TRIO_ARGS2((first, second),
487 TRIO_CONST char *first,
488 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000489{
490 assert(first);
491 assert(second);
492
493#if defined(LC_COLLATE)
494 return (strcoll(first, second) == 0);
495#else
496 return trio_equal(first, second);
497#endif
498}
499
500
501/**
502 Compare if two strings up until the first @p max characters are equal.
503
504 @param first First string.
505 @param max Maximum number of characters to compare.
506 @param second Second string.
507 @return Boolean indicating whether the two strings are equal or not.
508
509 Case-insensitive comparison.
510*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000511TRIO_STRING_PUBLIC int
512trio_equal_max
513TRIO_ARGS3((first, max, second),
514 TRIO_CONST char *first,
515 size_t max,
516 TRIO_CONST char *second)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000517{
518 assert(first);
519 assert(second);
520
521 if ((first != NULL) && (second != NULL))
522 {
523#if defined(USE_STRNCASECMP)
524 return (0 == strncasecmp(first, second, max));
525#else
526 /* Not adequately tested yet */
527 size_t cnt = 0;
528 while ((*first != NIL) && (*second != NIL) && (cnt <= max))
529 {
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000530 if (trio_to_upper(*first) != trio_to_upper(*second))
Bjorn Reese026d29f2002-01-19 15:40:18 +0000531 {
532 break;
533 }
534 first++;
535 second++;
536 cnt++;
537 }
538 return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
539#endif
540 }
541 return FALSE;
542}
543
544
545/**
546 Provide a textual description of an error code (errno).
547
548 @param error_number Error number.
549 @return Textual description of @p error_number.
550*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000551TRIO_STRING_PUBLIC TRIO_CONST char *
552trio_error
553TRIO_ARGS1((error_number),
554 int error_number)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000555{
556#if defined(USE_STRERROR)
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000557
Bjorn Reese026d29f2002-01-19 15:40:18 +0000558 return strerror(error_number);
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000559
560#elif defined(USE_SYS_ERRLIST)
561
562 extern char *sys_errlist[];
563 extern int sys_nerr;
564
565 return ((error_number < 0) || (error_number >= sys_nerr))
566 ? "unknown"
567 : sys_errlist[error_number];
568
Bjorn Reese026d29f2002-01-19 15:40:18 +0000569#else
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000570
Bjorn Reese026d29f2002-01-19 15:40:18 +0000571 return "unknown";
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000572
Bjorn Reese026d29f2002-01-19 15:40:18 +0000573#endif
574}
575
576
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000577#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000578/**
579 Format the date/time according to @p format.
580
581 @param target Target string.
582 @param max Maximum number of characters to format.
583 @param format Formatting string.
584 @param datetime Date/time structure.
585 @return Number of formatted characters.
586
587 The formatting string accepts the same specifiers as the standard C
588 function strftime.
589*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000590TRIO_STRING_PUBLIC size_t
591trio_format_date_max
592TRIO_ARGS4((target, max, format, datetime),
593 char *target,
594 size_t max,
595 TRIO_CONST char *format,
596 TRIO_CONST struct tm *datetime)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000597{
598 assert(target);
599 assert(format);
600 assert(datetime);
601 assert(max > 0);
602
603 return strftime(target, max, format, datetime);
604}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000605#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000606
607
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000608#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000609/**
610 Calculate a hash value for a string.
611
612 @param string String to be calculated on.
613 @param type Hash function.
614 @return Calculated hash value.
615
616 @p type can be one of the following
617 @li @c TRIO_HASH_PLAIN Plain hash function.
618*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000619TRIO_STRING_PUBLIC unsigned long
620trio_hash
621TRIO_ARGS2((string, type),
622 TRIO_CONST char *string,
623 int type)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000624{
625 unsigned long value = 0L;
626 char ch;
627
628 assert(string);
629
630 switch (type)
631 {
632 case TRIO_HASH_PLAIN:
633 while ( (ch = *string++) != NIL )
634 {
635 value *= 31;
636 value += (unsigned long)ch;
637 }
638 break;
639 default:
640 assert(FALSE);
641 break;
642 }
643 return value;
644}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000645#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000646
647
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000648#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000649/**
650 Find first occurrence of a character in a string.
651
652 @param string String to be searched.
653 @param character Character to be found.
654 @param A pointer to the found character, or NULL if character was not found.
655 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000656TRIO_STRING_PUBLIC char *
657trio_index
658TRIO_ARGS2((string, character),
659 TRIO_CONST char *string,
660 int character)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000661{
662 assert(string);
663
664 return strchr(string, character);
665}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000666#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000667
668
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000669#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000670/**
671 Find last occurrence of a character in a string.
672
673 @param string String to be searched.
674 @param character Character to be found.
675 @param A pointer to the found character, or NULL if character was not found.
676 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000677TRIO_STRING_PUBLIC char *
678trio_index_last
679TRIO_ARGS2((string, character),
680 TRIO_CONST char *string,
681 int character)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000682{
683 assert(string);
684
685 return strchr(string, character);
686}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000687#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000688
689
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000690#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000691/**
692 Convert the alphabetic letters in the string to lower-case.
693
694 @param target String to be converted.
695 @return Number of processed characters (converted or not).
696*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000697TRIO_STRING_PUBLIC int
698trio_lower
699TRIO_ARGS1((target),
700 char *target)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000701{
702 assert(target);
703
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000704 return trio_span_function(target, target, trio_to_lower);
Bjorn Reese026d29f2002-01-19 15:40:18 +0000705}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000706#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000707
708
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000709#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000710/**
711 Compare two strings using wildcards.
712
713 @param string String to be searched.
714 @param pattern Pattern, including wildcards, to search for.
715 @return Boolean value indicating success or failure.
716
717 Case-insensitive comparison.
718
719 The following wildcards can be used
720 @li @c * Match any number of characters.
721 @li @c ? Match a single character.
722*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000723TRIO_STRING_PUBLIC int
724trio_match
725TRIO_ARGS2((string, pattern),
726 TRIO_CONST char *string,
727 TRIO_CONST char *pattern)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000728{
729 assert(string);
730 assert(pattern);
731
732 for (; ('*' != *pattern); ++pattern, ++string)
733 {
734 if (NIL == *string)
735 {
736 return (NIL == *pattern);
737 }
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000738 if ((trio_to_upper((int)*string) != trio_to_upper((int)*pattern))
Bjorn Reese026d29f2002-01-19 15:40:18 +0000739 && ('?' != *pattern))
740 {
741 return FALSE;
742 }
743 }
744 /* two-line patch to prevent *too* much recursiveness: */
745 while ('*' == pattern[1])
746 pattern++;
747
748 do
749 {
750 if ( trio_match(string, &pattern[1]) )
751 {
752 return TRUE;
753 }
754 }
755 while (*string++);
756
757 return FALSE;
758}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000759#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000760
761
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000762#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000763/**
764 Compare two strings using wildcards.
765
766 @param string String to be searched.
767 @param pattern Pattern, including wildcards, to search for.
768 @return Boolean value indicating success or failure.
769
770 Case-sensitive comparison.
771
772 The following wildcards can be used
773 @li @c * Match any number of characters.
774 @li @c ? Match a single character.
775*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000776TRIO_STRING_PUBLIC int
777trio_match_case
778TRIO_ARGS2((string, pattern),
779 TRIO_CONST char *string,
780 TRIO_CONST char *pattern)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000781{
782 assert(string);
783 assert(pattern);
784
785 for (; ('*' != *pattern); ++pattern, ++string)
786 {
787 if (NIL == *string)
788 {
789 return (NIL == *pattern);
790 }
791 if ((*string != *pattern)
792 && ('?' != *pattern))
793 {
794 return FALSE;
795 }
796 }
797 /* two-line patch to prevent *too* much recursiveness: */
798 while ('*' == pattern[1])
799 pattern++;
800
801 do
802 {
803 if ( trio_match_case(string, &pattern[1]) )
804 {
805 return TRUE;
806 }
807 }
808 while (*string++);
809
810 return FALSE;
811}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000812#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000813
814
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000815#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000816/**
817 Execute a function on each character in string.
818
819 @param target Target string.
820 @param source Source string.
821 @param Function Function to be executed.
822 @return Number of processed characters.
823*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000824TRIO_STRING_PUBLIC size_t
825trio_span_function
826TRIO_ARGS3((target, source, Function),
827 char *target,
828 TRIO_CONST char *source,
829 int (*Function) TRIO_PROTO((int)))
Bjorn Reese026d29f2002-01-19 15:40:18 +0000830{
831 size_t count = 0;
832
833 assert(target);
834 assert(source);
835 assert(Function);
836
837 while (*source != NIL)
838 {
839 *target++ = Function(*source++);
840 count++;
841 }
842 return count;
843}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000844#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000845
846
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000847#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000848/**
849 Search for a substring in a string.
850
851 @param string String to be searched.
852 @param substring String to be found.
853 @return Pointer to first occurrence of @p substring in @p string, or NULL
854 if no match was found.
855*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000856TRIO_STRING_PUBLIC char *
857trio_substring
858TRIO_ARGS2((string, substring),
859 TRIO_CONST char *string,
860 TRIO_CONST char *substring)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000861{
862 assert(string);
863 assert(substring);
864
865 return strstr(string, substring);
866}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000867#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000868
869
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000870#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000871/**
872 Search for a substring in the first @p max characters of a string.
873
874 @param string String to be searched.
875 @param max Maximum characters to be searched.
876 @param substring String to be found.
877 @return Pointer to first occurrence of @p substring in @p string, or NULL
878 if no match was found.
879*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000880TRIO_STRING_PUBLIC char *
881trio_substring_max
882TRIO_ARGS3((string, max, substring),
883 TRIO_CONST char *string,
884 size_t max,
885 TRIO_CONST char *substring)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000886{
887 size_t count;
888 size_t size;
889 char *result = NULL;
890
891 assert(string);
892 assert(substring);
893
894 size = trio_length(substring);
895 if (size <= max)
896 {
897 for (count = 0; count <= max - size; count++)
898 {
899 if (trio_equal_max(substring, size, &string[count]))
900 {
901 result = (char *)&string[count];
902 break;
903 }
904 }
905 }
906 return result;
907}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000908#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000909
910
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000911#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000912/**
913 Tokenize string.
914
915 @param string String to be tokenized.
916 @param tokens String containing list of delimiting characters.
917 @return Start of new token.
918
919 @warning @p string will be destroyed.
920*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000921TRIO_STRING_PUBLIC char *
922trio_tokenize
923TRIO_ARGS2((string, delimiters),
924 char *string,
925 TRIO_CONST char *delimiters)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000926{
927 assert(delimiters);
928
929 return strtok(string, delimiters);
930}
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000931#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +0000932
933
934/**
935 Convert string to floating-point number.
936
937 @param source String to be converted.
938 @param endp Pointer to end of the converted string.
939 @return A floating-point number.
940
941 The following Extended Backus-Naur form is used
942 @verbatim
943 double ::= [ <sign> ]
944 ( <number> |
945 <number> <decimal_point> <number> |
946 <decimal_point> <number> )
947 [ <exponential> [ <sign> ] <number> ]
948 number ::= 1*( <digit> )
949 digit ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
950 exponential ::= ( 'e' | 'E' )
951 sign ::= ( '-' | '+' )
952 decimal_point ::= '.'
953 @endverbatim
954*/
955/* FIXME: Add EBNF for hex-floats */
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000956TRIO_STRING_PUBLIC trio_long_double_t
957trio_to_long_double
958TRIO_ARGS2((source, endp),
959 TRIO_CONST char *source,
960 char **endp)
Bjorn Reese026d29f2002-01-19 15:40:18 +0000961{
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000962#if defined(USE_STRTOLD)
963 return strtold(source, endp);
Bjorn Reese026d29f2002-01-19 15:40:18 +0000964#else
Bjorn Reese026d29f2002-01-19 15:40:18 +0000965 int isNegative = FALSE;
966 int isExponentNegative = FALSE;
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000967 trio_long_double_t integer = 0.0;
968 trio_long_double_t fraction = 0.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +0000969 unsigned long exponent = 0;
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000970 trio_long_double_t base;
971 trio_long_double_t fracdiv = 1.0;
972 trio_long_double_t value = 0.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +0000973
974 /* First try hex-floats */
975 if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
976 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000977 base = 16.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +0000978 source += 2;
979 while (isxdigit((int)*source))
980 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000981 integer *= base;
Bjorn Reese026d29f2002-01-19 15:40:18 +0000982 integer += (isdigit((int)*source)
983 ? (*source - '0')
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000984 : 10 + (trio_to_upper((int)*source) - 'A'));
Bjorn Reese026d29f2002-01-19 15:40:18 +0000985 source++;
986 }
987 if (*source == '.')
988 {
989 source++;
990 while (isxdigit((int)*source))
991 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +0000992 fracdiv /= base;
993 fraction += fracdiv * (isdigit((int)*source)
994 ? (*source - '0')
Daniel Veillarda48ed3d2003-04-03 15:28:28 +0000995 : 10 + (trio_to_upper((int)*source) - 'A'));
Bjorn Reese026d29f2002-01-19 15:40:18 +0000996 source++;
997 }
998 if ((*source == 'p') || (*source == 'P'))
999 {
1000 source++;
1001 if ((*source == '+') || (*source == '-'))
1002 {
1003 isExponentNegative = (*source == '-');
1004 source++;
1005 }
1006 while (isdigit((int)*source))
1007 {
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001008 exponent *= 10;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001009 exponent += (*source - '0');
1010 source++;
1011 }
1012 }
1013 }
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001014 /* For later use with exponent */
1015 base = 2.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001016 }
1017 else /* Then try normal decimal floats */
1018 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001019 base = 10.0;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001020 isNegative = (*source == '-');
1021 /* Skip sign */
1022 if ((*source == '+') || (*source == '-'))
1023 source++;
1024
1025 /* Integer part */
1026 while (isdigit((int)*source))
1027 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001028 integer *= base;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001029 integer += (*source - '0');
1030 source++;
1031 }
1032
1033 if (*source == '.')
1034 {
1035 source++; /* skip decimal point */
1036 while (isdigit((int)*source))
1037 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001038 fracdiv /= base;
1039 fraction += (*source - '0') * fracdiv;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001040 source++;
1041 }
1042 }
1043 if ((*source == 'e')
1044 || (*source == 'E')
1045#if TRIO_MICROSOFT
1046 || (*source == 'd')
1047 || (*source == 'D')
1048#endif
1049 )
1050 {
1051 source++; /* Skip exponential indicator */
1052 isExponentNegative = (*source == '-');
1053 if ((*source == '+') || (*source == '-'))
1054 source++;
1055 while (isdigit((int)*source))
1056 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001057 exponent *= (int)base;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001058 exponent += (*source - '0');
1059 source++;
1060 }
1061 }
1062 }
1063
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001064 value = integer + fraction;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001065 if (exponent != 0)
1066 {
1067 if (isExponentNegative)
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001068 value /= pow(base, (double)exponent);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001069 else
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001070 value *= pow(base, (double)exponent);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001071 }
1072 if (isNegative)
1073 value = -value;
1074
1075 if (endp)
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001076 *endp = (char *)source;
Bjorn Reese026d29f2002-01-19 15:40:18 +00001077 return value;
1078#endif
1079}
1080
1081
1082/**
1083 Convert string to floating-point number.
1084
1085 @param source String to be converted.
1086 @param endp Pointer to end of the converted string.
1087 @return A floating-point number.
1088
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001089 See @ref trio_to_long_double.
Bjorn Reese026d29f2002-01-19 15:40:18 +00001090*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001091TRIO_STRING_PUBLIC double
1092trio_to_double
1093TRIO_ARGS2((source, endp),
1094 TRIO_CONST char *source,
1095 char **endp)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001096{
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001097#if defined(USE_STRTOD)
1098 return strtod(source, endp);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001099#else
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001100 return (double)trio_to_long_double(source, endp);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001101#endif
1102}
1103
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001104#if !defined(TRIO_MINIMAL)
1105/**
1106 Convert string to floating-point number.
1107
1108 @param source String to be converted.
1109 @param endp Pointer to end of the converted string.
1110 @return A floating-point number.
1111
1112 See @ref trio_to_long_double.
1113*/
1114TRIO_STRING_PUBLIC float
1115trio_to_float
1116TRIO_ARGS2((source, endp),
1117 TRIO_CONST char *source,
1118 char **endp)
1119{
1120#if defined(USE_STRTOF)
1121 return strtof(source, endp);
1122#else
1123 return (float)trio_to_long_double(source, endp);
1124#endif
1125}
1126#endif /* !defined(TRIO_MINIMAL) */
1127
Bjorn Reese026d29f2002-01-19 15:40:18 +00001128
1129/**
1130 Convert string to signed integer.
1131
1132 @param string String to be converted.
1133 @param endp Pointer to end of converted string.
1134 @param base Radix number of number.
1135*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001136TRIO_STRING_PUBLIC long
1137trio_to_long
1138TRIO_ARGS3((string, endp, base),
1139 TRIO_CONST char *string,
1140 char **endp,
1141 int base)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001142{
1143 assert(string);
1144 assert((base >= 2) && (base <= 36));
1145
1146 return strtol(string, endp, base);
1147}
1148
1149
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001150#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001151/**
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001152 Convert one alphabetic letter to lower-case.
1153
1154 @param source The letter to be converted.
1155 @return The converted letter.
1156*/
1157TRIO_STRING_PUBLIC int
1158trio_to_lower
1159TRIO_ARGS1((source),
1160 int source)
1161{
1162#if defined(USE_TOLOWER)
1163
1164 return tolower(source);
1165
1166#else
1167
1168 /* Does not handle locales or non-contiguous alphabetic characters */
1169 return ((source >= (int)'A') && (source <= (int)'Z'))
1170 ? source - 'A' + 'a'
1171 : source;
1172
1173#endif
1174}
1175#endif /* !defined(TRIO_MINIMAL) */
1176
1177#if !defined(TRIO_MINIMAL)
1178/**
Bjorn Reese026d29f2002-01-19 15:40:18 +00001179 Convert string to unsigned integer.
1180
1181 @param string String to be converted.
1182 @param endp Pointer to end of converted string.
1183 @param base Radix number of number.
1184*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001185TRIO_STRING_PUBLIC unsigned long
1186trio_to_unsigned_long
1187TRIO_ARGS3((string, endp, base),
1188 TRIO_CONST char *string,
1189 char **endp,
1190 int base)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001191{
1192 assert(string);
1193 assert((base >= 2) && (base <= 36));
1194
1195 return strtoul(string, endp, base);
1196}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001197#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001198
1199
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001200/**
1201 Convert one alphabetic letter to upper-case.
1202
1203 @param source The letter to be converted.
1204 @return The converted letter.
1205*/
1206TRIO_STRING_PUBLIC int
1207trio_to_upper
1208TRIO_ARGS1((source),
1209 int source)
1210{
1211#if defined(USE_TOUPPER)
1212
1213 return toupper(source);
1214
1215#else
1216
1217 /* Does not handle locales or non-contiguous alphabetic characters */
1218 return ((source >= (int)'a') && (source <= (int)'z'))
1219 ? source - 'a' + 'A'
1220 : source;
1221
1222#endif
1223}
1224
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001225#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001226/**
1227 Convert the alphabetic letters in the string to upper-case.
1228
1229 @param target The string to be converted.
1230 @return The number of processed characters (converted or not).
1231*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001232TRIO_STRING_PUBLIC int
1233trio_upper
1234TRIO_ARGS1((target),
1235 char *target)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001236{
1237 assert(target);
1238
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001239 return trio_span_function(target, target, trio_to_upper);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001240}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001241#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001242
1243
1244/** @} End of StaticStrings */
1245
1246
1247/*************************************************************************
1248 * Dynamic String Functions
1249 */
1250
1251#if defined(TRIO_DOCUMENTATION)
1252# include "doc/doc_dynamic.h"
1253#endif
1254/** @addtogroup DynamicStrings
1255 @{
1256*/
1257
1258/*
1259 * TrioStringAlloc
1260 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001261TRIO_STRING_PRIVATE trio_string_t *
1262TrioStringAlloc(TRIO_NOARGS)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001263{
1264 trio_string_t *self;
1265
1266 self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
1267 if (self)
1268 {
1269 self->content = NULL;
1270 self->length = 0;
1271 self->allocated = 0;
1272 }
1273 return self;
1274}
1275
1276
1277/*
1278 * TrioStringGrow
1279 *
1280 * The size of the string will be increased by 'delta' characters. If
1281 * 'delta' is zero, the size will be doubled.
1282 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001283TRIO_STRING_PRIVATE BOOLEAN_T
1284TrioStringGrow
1285TRIO_ARGS2((self, delta),
1286 trio_string_t *self,
1287 size_t delta)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001288{
1289 BOOLEAN_T status = FALSE;
1290 char *new_content;
1291 size_t new_size;
1292
1293 new_size = (delta == 0)
1294 ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
1295 : self->allocated + delta;
1296
1297 new_content = (char *)TRIO_REALLOC(self->content, new_size);
1298 if (new_content)
1299 {
1300 self->content = new_content;
1301 self->allocated = new_size;
1302 status = TRUE;
1303 }
1304 return status;
1305}
1306
1307
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001308#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001309/*
1310 * TrioStringGrowTo
1311 *
1312 * The size of the string will be increased to 'length' plus one characters.
1313 * If 'length' is less than the original size, the original size will be
1314 * used (that is, the size of the string is never decreased).
1315 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001316TRIO_STRING_PRIVATE BOOLEAN_T
1317TrioStringGrowTo
1318TRIO_ARGS2((self, length),
1319 trio_string_t *self,
1320 size_t length)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001321{
1322 length++; /* Room for terminating zero */
1323 return (self->allocated < length)
1324 ? TrioStringGrow(self, length - self->allocated)
1325 : TRUE;
1326}
Daniel Veillarda48ed3d2003-04-03 15:28:28 +00001327#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001328
1329
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001330#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001331/**
1332 Create a new dynamic string.
1333
1334 @param initial_size Initial size of the buffer.
1335 @return Newly allocated dynamic string, or NULL if memory allocation failed.
1336*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001337TRIO_STRING_PUBLIC trio_string_t *
1338trio_string_create
1339TRIO_ARGS1((initial_size),
1340 int initial_size)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001341{
1342 trio_string_t *self;
1343
1344 self = TrioStringAlloc();
1345 if (self)
1346 {
1347 if (TrioStringGrow(self,
1348 (size_t)((initial_size > 0) ? initial_size : 1)))
1349 {
1350 self->content[0] = (char)0;
1351 self->allocated = initial_size;
1352 }
1353 else
1354 {
1355 trio_string_destroy(self);
1356 self = NULL;
1357 }
1358 }
1359 return self;
1360}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001361#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001362
1363
1364/**
1365 Deallocate the dynamic string and its contents.
1366
1367 @param self Dynamic string
1368*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001369TRIO_STRING_PUBLIC void
1370trio_string_destroy
1371TRIO_ARGS1((self),
1372 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001373{
1374 assert(self);
1375
1376 if (self)
1377 {
1378 trio_destroy(self->content);
1379 TRIO_FREE(self);
1380 }
1381}
1382
1383
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001384#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001385/**
1386 Get a pointer to the content.
1387
1388 @param self Dynamic string.
1389 @param offset Offset into content.
1390 @return Pointer to the content.
1391
1392 @p Offset can be zero, positive, or negative. If @p offset is zero,
1393 then the start of the content will be returned. If @p offset is positive,
1394 then a pointer to @p offset number of characters from the beginning of the
1395 content is returned. If @p offset is negative, then a pointer to @p offset
1396 number of characters from the ending of the string, starting at the
1397 terminating zero, is returned.
1398*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001399TRIO_STRING_PUBLIC char *
1400trio_string_get
1401TRIO_ARGS2((self, offset),
1402 trio_string_t *self,
1403 int offset)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001404{
1405 char *result = NULL;
1406
1407 assert(self);
1408
1409 if (self->content != NULL)
1410 {
1411 if (self->length == 0)
1412 {
1413 (void)trio_string_length(self);
1414 }
1415 if (offset >= 0)
1416 {
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001417 if (offset > (int)self->length)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001418 {
1419 offset = self->length;
1420 }
1421 }
1422 else
1423 {
1424 offset += self->length + 1;
1425 if (offset < 0)
1426 {
1427 offset = 0;
1428 }
1429 }
1430 result = &(self->content[offset]);
1431 }
1432 return result;
1433}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001434#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001435
1436
1437/**
1438 Extract the content.
1439
1440 @param self Dynamic String
1441 @return Content of dynamic string.
1442
1443 The content is removed from the dynamic string. This enables destruction
1444 of the dynamic string without deallocation of the content.
1445*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001446TRIO_STRING_PUBLIC char *
1447trio_string_extract
1448TRIO_ARGS1((self),
1449 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001450{
1451 char *result;
1452
1453 assert(self);
1454
1455 result = self->content;
1456 /* FIXME: Allocate new empty buffer? */
1457 self->content = NULL;
1458 self->length = self->allocated = 0;
1459 return result;
1460}
1461
1462
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001463#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001464/**
1465 Set the content of the dynamic string.
1466
1467 @param self Dynamic String
1468 @param buffer The new content.
1469
1470 Sets the content of the dynamic string to a copy @p buffer.
1471 An existing content will be deallocated first, if necessary.
1472
1473 @remark
1474 This function will make a copy of @p buffer.
1475 You are responsible for deallocating @p buffer yourself.
1476*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001477TRIO_STRING_PUBLIC void
1478trio_xstring_set
1479TRIO_ARGS2((self, buffer),
1480 trio_string_t *self,
1481 char *buffer)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001482{
1483 assert(self);
1484
1485 trio_destroy(self->content);
1486 self->content = trio_duplicate(buffer);
1487}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001488#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001489
1490
1491/*
1492 * trio_string_size
1493 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001494TRIO_STRING_PUBLIC int
1495trio_string_size
1496TRIO_ARGS1((self),
1497 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001498{
1499 assert(self);
1500
1501 return self->allocated;
1502}
1503
1504
1505/*
1506 * trio_string_terminate
1507 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001508TRIO_STRING_PUBLIC void
1509trio_string_terminate
1510TRIO_ARGS1((self),
1511 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001512{
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001513 trio_xstring_append_char(self, 0);
Bjorn Reese026d29f2002-01-19 15:40:18 +00001514}
1515
1516
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001517#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001518/**
1519 Append the second string to the first.
1520
1521 @param self Dynamic string to be modified.
1522 @param other Dynamic string to copy from.
1523 @return Boolean value indicating success or failure.
1524*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001525TRIO_STRING_PUBLIC int
1526trio_string_append
1527TRIO_ARGS2((self, other),
1528 trio_string_t *self,
1529 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001530{
1531 size_t length;
1532
1533 assert(self);
1534 assert(other);
1535
1536 length = self->length + other->length;
1537 if (!TrioStringGrowTo(self, length))
1538 goto error;
1539 trio_copy(&self->content[self->length], other->content);
1540 self->length = length;
1541 return TRUE;
1542
1543 error:
1544 return FALSE;
1545}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001546#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001547
1548
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001549#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001550/*
1551 * trio_xstring_append
1552 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001553TRIO_STRING_PUBLIC int
1554trio_xstring_append
1555TRIO_ARGS2((self, other),
1556 trio_string_t *self,
1557 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001558{
1559 size_t length;
1560
1561 assert(self);
1562 assert(other);
1563
1564 length = self->length + trio_length(other);
1565 if (!TrioStringGrowTo(self, length))
1566 goto error;
1567 trio_copy(&self->content[self->length], other);
1568 self->length = length;
1569 return TRUE;
1570
1571 error:
1572 return FALSE;
1573}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001574#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001575
1576
1577/*
1578 * trio_xstring_append_char
1579 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001580TRIO_STRING_PUBLIC int
1581trio_xstring_append_char
1582TRIO_ARGS2((self, character),
1583 trio_string_t *self,
1584 char character)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001585{
1586 assert(self);
1587
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001588 if ((int)self->length >= trio_string_size(self))
Bjorn Reese026d29f2002-01-19 15:40:18 +00001589 {
1590 if (!TrioStringGrow(self, 0))
1591 goto error;
1592 }
1593 self->content[self->length] = character;
1594 self->length++;
1595 return TRUE;
1596
1597 error:
1598 return FALSE;
1599}
1600
1601
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001602#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001603/**
1604 Search for the first occurrence of second parameter in the first.
1605
1606 @param self Dynamic string to be modified.
1607 @param other Dynamic string to copy from.
1608 @return Boolean value indicating success or failure.
1609*/
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001610TRIO_STRING_PUBLIC int
1611trio_string_contains
1612TRIO_ARGS2((self, other),
1613 trio_string_t *self,
1614 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001615{
1616 assert(self);
1617 assert(other);
1618
1619 return trio_contains(self->content, other->content);
1620}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001621#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001622
1623
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001624#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001625/*
1626 * trio_xstring_contains
1627 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001628TRIO_STRING_PUBLIC int
1629trio_xstring_contains
1630TRIO_ARGS2((self, other),
1631 trio_string_t *self,
1632 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001633{
1634 assert(self);
1635 assert(other);
1636
1637 return trio_contains(self->content, other);
1638}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001639#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001640
1641
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001642#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001643/*
1644 * trio_string_copy
1645 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001646TRIO_STRING_PUBLIC int
1647trio_string_copy
1648TRIO_ARGS2((self, other),
1649 trio_string_t *self,
1650 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001651{
1652 assert(self);
1653 assert(other);
1654
1655 self->length = 0;
1656 return trio_string_append(self, other);
1657}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001658#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001659
1660
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001661#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001662/*
1663 * trio_xstring_copy
1664 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001665TRIO_STRING_PUBLIC int
1666trio_xstring_copy
1667TRIO_ARGS2((self, other),
1668 trio_string_t *self,
1669 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001670{
1671 assert(self);
1672 assert(other);
1673
1674 self->length = 0;
1675 return trio_xstring_append(self, other);
1676}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001677#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001678
1679
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001680#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001681/*
1682 * trio_string_duplicate
1683 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001684TRIO_STRING_PUBLIC trio_string_t *
1685trio_string_duplicate
1686TRIO_ARGS1((other),
1687 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001688{
1689 trio_string_t *self;
1690
1691 assert(other);
1692
1693 self = TrioStringAlloc();
1694 if (self)
1695 {
1696 self->content = TrioDuplicateMax(other->content, other->length);
1697 if (self->content)
1698 {
1699 self->length = other->length;
1700 self->allocated = self->length + 1;
1701 }
1702 else
1703 {
1704 self->length = self->allocated = 0;
1705 }
1706 }
1707 return self;
1708}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001709#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001710
1711
1712/*
1713 * trio_xstring_duplicate
1714 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001715TRIO_STRING_PUBLIC trio_string_t *
1716trio_xstring_duplicate
1717TRIO_ARGS1((other),
1718 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001719{
1720 trio_string_t *self;
1721
1722 assert(other);
1723
1724 self = TrioStringAlloc();
1725 if (self)
1726 {
1727 self->content = TrioDuplicateMax(other, trio_length(other));
1728 if (self->content)
1729 {
1730 self->length = trio_length(self->content);
1731 self->allocated = self->length + 1;
1732 }
1733 else
1734 {
1735 self->length = self->allocated = 0;
1736 }
1737 }
1738 return self;
1739}
1740
1741
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001742#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001743/*
1744 * trio_string_equal
1745 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001746TRIO_STRING_PUBLIC int
1747trio_string_equal
1748TRIO_ARGS2((self, other),
1749 trio_string_t *self,
1750 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001751{
1752 assert(self);
1753 assert(other);
1754
1755 return trio_equal(self->content, other->content);
1756}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001757#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001758
1759
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001760#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001761/*
1762 * trio_xstring_equal
1763 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001764TRIO_STRING_PUBLIC int
1765trio_xstring_equal
1766TRIO_ARGS2((self, other),
1767 trio_string_t *self,
1768 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001769{
1770 assert(self);
1771 assert(other);
1772
1773 return trio_equal(self->content, other);
1774}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001775#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001776
1777
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001778#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001779/*
1780 * trio_string_equal_max
1781 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001782TRIO_STRING_PUBLIC int
1783trio_string_equal_max
1784TRIO_ARGS3((self, max, other),
1785 trio_string_t *self,
1786 size_t max,
1787 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001788{
1789 assert(self);
1790 assert(other);
1791
1792 return trio_equal_max(self->content, max, other->content);
1793}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001794#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001795
1796
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001797#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001798/*
1799 * trio_xstring_equal_max
1800 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001801TRIO_STRING_PUBLIC int
1802trio_xstring_equal_max
1803TRIO_ARGS3((self, max, other),
1804 trio_string_t *self,
1805 size_t max,
1806 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001807{
1808 assert(self);
1809 assert(other);
1810
1811 return trio_equal_max(self->content, max, other);
1812}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001813#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001814
1815
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001816#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001817/*
1818 * trio_string_equal_case
1819 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001820TRIO_STRING_PUBLIC int
1821trio_string_equal_case
1822TRIO_ARGS2((self, other),
1823 trio_string_t *self,
1824 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001825{
1826 assert(self);
1827 assert(other);
1828
1829 return trio_equal_case(self->content, other->content);
1830}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001831#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001832
1833
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001834#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001835/*
1836 * trio_xstring_equal_case
1837 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001838TRIO_STRING_PUBLIC int
1839trio_xstring_equal_case
1840TRIO_ARGS2((self, other),
1841 trio_string_t *self,
1842 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001843{
1844 assert(self);
1845 assert(other);
1846
1847 return trio_equal_case(self->content, other);
1848}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001849#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001850
1851
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001852#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001853/*
1854 * trio_string_equal_case_max
1855 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001856TRIO_STRING_PUBLIC int
1857trio_string_equal_case_max
1858TRIO_ARGS3((self, max, other),
1859 trio_string_t *self,
1860 size_t max,
1861 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001862{
1863 assert(self);
1864 assert(other);
1865
1866 return trio_equal_case_max(self->content, max, other->content);
1867}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001868#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001869
1870
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001871#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001872/*
1873 * trio_xstring_equal_case_max
1874 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001875TRIO_STRING_PUBLIC int
1876trio_xstring_equal_case_max
1877TRIO_ARGS3((self, max, other),
1878 trio_string_t *self,
1879 size_t max,
1880 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001881{
1882 assert(self);
1883 assert(other);
1884
1885 return trio_equal_case_max(self->content, max, other);
1886}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001887#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001888
1889
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001890#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001891/*
1892 * trio_string_format_data_max
1893 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001894TRIO_STRING_PUBLIC size_t
1895trio_string_format_date_max
1896TRIO_ARGS4((self, max, format, datetime),
1897 trio_string_t *self,
1898 size_t max,
1899 TRIO_CONST char *format,
1900 TRIO_CONST struct tm *datetime)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001901{
1902 assert(self);
1903
1904 return trio_format_date_max(self->content, max, format, datetime);
1905}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001906#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001907
1908
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001909#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001910/*
1911 * trio_string_index
1912 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001913TRIO_STRING_PUBLIC char *
1914trio_string_index
1915TRIO_ARGS2((self, character),
1916 trio_string_t *self,
1917 int character)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001918{
1919 assert(self);
1920
1921 return trio_index(self->content, character);
1922}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001923#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001924
1925
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001926#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001927/*
1928 * trio_string_index_last
1929 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001930TRIO_STRING_PUBLIC char *
1931trio_string_index_last
1932TRIO_ARGS2((self, character),
1933 trio_string_t *self,
1934 int character)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001935{
1936 assert(self);
1937
1938 return trio_index_last(self->content, character);
1939}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001940#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001941
1942
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001943#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001944/*
1945 * trio_string_length
1946 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001947TRIO_STRING_PUBLIC int
1948trio_string_length
1949TRIO_ARGS1((self),
1950 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001951{
1952 assert(self);
1953
1954 if (self->length == 0)
1955 {
1956 self->length = trio_length(self->content);
1957 }
1958 return self->length;
1959}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001960#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001961
1962
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001963#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001964/*
1965 * trio_string_lower
1966 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001967TRIO_STRING_PUBLIC int
1968trio_string_lower
1969TRIO_ARGS1((self),
1970 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001971{
1972 assert(self);
1973
1974 return trio_lower(self->content);
1975}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001976#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001977
1978
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001979#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001980/*
1981 * trio_string_match
1982 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001983TRIO_STRING_PUBLIC int
1984trio_string_match
1985TRIO_ARGS2((self, other),
1986 trio_string_t *self,
1987 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001988{
1989 assert(self);
1990 assert(other);
1991
1992 return trio_match(self->content, other->content);
1993}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001994#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00001995
1996
Daniel Veillardb7c29c32002-09-25 22:44:43 +00001997#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00001998/*
1999 * trio_xstring_match
2000 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002001TRIO_STRING_PUBLIC int
2002trio_xstring_match
2003TRIO_ARGS2((self, other),
2004 trio_string_t *self,
2005 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002006{
2007 assert(self);
2008 assert(other);
2009
2010 return trio_match(self->content, other);
2011}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002012#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002013
2014
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002015#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002016/*
2017 * trio_string_match_case
2018 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002019TRIO_STRING_PUBLIC int
2020trio_string_match_case
2021TRIO_ARGS2((self, other),
2022 trio_string_t *self,
2023 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002024{
2025 assert(self);
2026 assert(other);
2027
2028 return trio_match_case(self->content, other->content);
2029}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002030#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002031
2032
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002033#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002034/*
2035 * trio_xstring_match_case
2036 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002037TRIO_STRING_PUBLIC int
2038trio_xstring_match_case
2039TRIO_ARGS2((self, other),
2040 trio_string_t *self,
2041 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002042{
2043 assert(self);
2044 assert(other);
2045
2046 return trio_match_case(self->content, other);
2047}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002048#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002049
2050
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002051#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002052/*
2053 * trio_string_substring
2054 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002055TRIO_STRING_PUBLIC char *
2056trio_string_substring
2057TRIO_ARGS2((self, other),
2058 trio_string_t *self,
2059 trio_string_t *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002060{
2061 assert(self);
2062 assert(other);
2063
2064 return trio_substring(self->content, other->content);
2065}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002066#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002067
2068
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002069#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002070/*
2071 * trio_xstring_substring
2072 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002073TRIO_STRING_PUBLIC char *
2074trio_xstring_substring
2075TRIO_ARGS2((self, other),
2076 trio_string_t *self,
2077 TRIO_CONST char *other)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002078{
2079 assert(self);
2080 assert(other);
2081
2082 return trio_substring(self->content, other);
2083}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002084#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002085
2086
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002087#if !defined(TRIO_MINIMAL)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002088/*
2089 * trio_string_upper
2090 */
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002091TRIO_STRING_PUBLIC int
2092trio_string_upper
2093TRIO_ARGS1((self),
2094 trio_string_t *self)
Bjorn Reese026d29f2002-01-19 15:40:18 +00002095{
2096 assert(self);
2097
2098 return trio_upper(self->content);
2099}
Daniel Veillardb7c29c32002-09-25 22:44:43 +00002100#endif /* !defined(TRIO_MINIMAL) */
Bjorn Reese026d29f2002-01-19 15:40:18 +00002101
2102/** @} End of DynamicStrings */