]> Pileus Git - ~andy/fetchmail/blob - trio/triostr.c
Update trio to CVS checkout of 2009-07-02.
[~andy/fetchmail] / trio / triostr.c
1 /*************************************************************************
2  *
3  * $Id: triostr.c,v 1.34 2008/11/09 12:17:39 breese Exp $
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
18 /*************************************************************************
19  * Include files
20  */
21
22 #if defined(HAVE_CONFIG_H)
23 # include <config.h>
24 #endif
25 #include <assert.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <ctype.h>
29 #include "triodef.h"
30 #include "triostr.h"
31 #if defined(TRIO_FUNC_TO_LONG_DOUBLE)
32 # define USE_MATH
33 #endif
34 #if defined(USE_MATH)
35 # include <math.h>
36 #endif
37
38 /*************************************************************************
39  * Definitions
40  */
41
42 #if !defined(TRIO_PUBLIC_STRING)
43 # define TRIO_PUBLIC_STRING TRIO_PUBLIC
44 #endif
45 #if !defined(TRIO_PRIVATE_STRING)
46 # define TRIO_PRIVATE_STRING TRIO_PRIVATE
47 #endif
48
49 #if !defined(NULL)
50 # define NULL 0
51 #endif
52 #if !defined(NIL)
53 # define NIL ((char)0)
54 #endif
55 #if !defined(FALSE)
56 # define FALSE (1 == 0)
57 # define TRUE (! FALSE)
58 #endif
59 #if !defined(BOOLEAN_T)
60 # define BOOLEAN_T int
61 #endif
62
63 #if defined(USE_MATH)
64 # if defined(PREDEF_STANDARD_C99)
65 #  if defined(TRIO_COMPILER_DECC)
66 #   if (TRIO_COMPILER_DECC - 0 > 80000000)
67 /*
68  * The OSF/1 runtime that comes with the DECC compiler does not support
69  * hexfloats conversion.
70  */
71 #    define USE_STRTOD
72 #    define USE_STRTOF
73 #   endif
74 #  else
75 #   define USE_STRTOD
76 #   define USE_STRTOF
77 #  endif
78 # else
79 #  if defined(TRIO_COMPILER_VISUALC)
80 #   define USE_STRTOD
81 #  endif
82 #endif
83 #endif
84
85 #if defined(TRIO_PLATFORM_UNIX)
86 # if defined(PREDEF_STANDARD_UNIX95)
87 #  define USE_STRCASECMP
88 #  define USE_STRNCASECMP
89 # endif
90 # if defined(TRIO_PLATFORM_SUNOS)
91 #  define USE_SYS_ERRLIST
92 # else
93 #  define USE_STRERROR
94 # endif
95 # if defined(TRIO_PLATFORM_QNX)
96 #  define strcasecmp(x,y) stricmp(x,y)
97 #  define strncasecmp(x,y,n) strnicmp(x,y,n)
98 # endif
99 #endif
100
101 #if defined(TRIO_PLATFORM_WIN32)
102 # define USE_STRCASECMP
103 # if defined(TRIO_PLATFORM_WINCE)
104 #  define strcasecmp(x,y) _stricmp(x,y)
105 # else
106 #  define strcasecmp(x,y) strcmpi(x,y)
107 # endif
108 #endif
109
110 #if !defined(HAVE_CONFIG_H)
111 # if !(defined(TRIO_PLATFORM_SUNOS))
112 #  define HAVE_TOLOWER
113 #  define HAVE_TOUPPER
114 # endif
115 #endif
116
117 #if defined(USE_MATH)
118 # if !defined(HAVE_POWL)
119 #  if defined(PREDEF_STANDARD_C99) \
120    || defined(PREDEF_STANDARD_UNIX03)
121 #   define HAVE_POWL
122 #  else
123 #   if defined(TRIO_COMPILER_VISUALC)
124 #    if defined(powl)
125 #     define HAVE_POWL
126 #    endif
127 #   endif
128 #  endif
129 # endif
130 #endif
131
132 #if defined(HAVE_POWL)
133 # define trio_powl(x,y) powl((x),(y))
134 #else
135 # define trio_powl(x,y) pow((double)(x),(double)(y))
136 #endif
137
138 #if defined(TRIO_FUNC_TO_UPPER) \
139  || (defined(TRIO_FUNC_EQUAL) && !defined(USE_STRCASECMP)) \
140  || (defined(TRIO_FUNC_EQUAL_MAX) && !defined(USE_STRNCASECMP)) \
141  || defined(TRIO_FUNC_MATCH) \
142  || defined(TRIO_FUNC_TO_LONG_DOUBLE) \
143  || defined(TRIO_FUNC_UPPER)
144 # define TRIO_FUNC_INTERNAL_TO_UPPER
145 #endif
146
147 /*************************************************************************
148  * Structures
149  */
150
151 struct _trio_string_t
152 {
153   char *content;
154   size_t length;
155   size_t allocated;
156 };
157
158 /*************************************************************************
159  * Constants
160  */
161
162 #if !defined(TRIO_EMBED_STRING)
163 static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.34 2008/11/09 12:17:39 breese Exp $";
164 #endif
165
166 /*************************************************************************
167  * Static String Functions
168  */
169
170 #if defined(TRIO_DOCUMENTATION)
171 # include "doc/doc_static.h"
172 #endif
173 /** @addtogroup StaticStrings
174     @{
175 */
176
177 /*
178  * internal_duplicate_max
179  */
180 #if defined(TRIO_FUNC_DUPLICATE) \
181  || defined(TRIO_FUNC_DUPLICATE_MAX) \
182  || defined(TRIO_FUNC_STRING_DUPLICATE) \
183  || defined(TRIO_FUNC_XSTRING_DUPLICATE)
184
185 TRIO_PRIVATE_STRING char *
186 internal_duplicate_max
187 TRIO_ARGS2((source, size),
188            TRIO_CONST char *source,
189            size_t size)
190 {
191   char *target;
192
193   assert(source);
194
195   /* Make room for string plus a terminating zero */
196   size++;
197   target = trio_create(size);
198   if (target)
199     {
200       trio_copy_max(target, size, source);
201     }
202   return target;
203 }
204
205 #endif
206
207 /*
208  * internal_string_alloc
209  */
210 #if defined(TRIO_FUNC_STRING_CREATE) \
211  || defined(TRIO_FUNC_STRING_DUPLICATE) \
212  || defined(TRIO_FUNC_XSTRING_DUPLICATE)
213
214 TRIO_PRIVATE_STRING trio_string_t *
215 internal_string_alloc(TRIO_NOARGS)
216 {
217   trio_string_t *self;
218   
219   self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
220   if (self)
221     {
222       self->content = NULL;
223       self->length = 0;
224       self->allocated = 0;
225     }
226   return self;
227 }
228
229 #endif
230
231 /*
232  * internal_string_grow
233  *
234  * The size of the string will be increased by 'delta' characters. If
235  * 'delta' is zero, the size will be doubled.
236  */
237 #if defined(TRIO_FUNC_STRING_CREATE) \
238  || defined(TRIO_FUNC_STRING_APPEND) \
239  || defined(TRIO_FUNC_XSTRING_APPEND) \
240  || defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
241
242 TRIO_PRIVATE_STRING BOOLEAN_T
243 internal_string_grow
244 TRIO_ARGS2((self, delta),
245            trio_string_t *self,
246            size_t delta)
247 {
248   BOOLEAN_T status = FALSE;
249   char *new_content;
250   size_t new_size;
251
252   new_size = (delta == 0)
253     ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
254     : self->allocated + delta;
255   
256   new_content = (char *)TRIO_REALLOC(self->content, new_size);
257   if (new_content)
258     {
259       self->content = new_content;
260       self->allocated = new_size;
261       status = TRUE;
262     }
263   return status;
264 }
265
266 #endif
267
268 /*
269  * internal_string_grow_to
270  *
271  * The size of the string will be increased to 'length' plus one characters.
272  * If 'length' is less than the original size, the original size will be
273  * used (that is, the size of the string is never decreased).
274  */
275 #if defined(TRIO_FUNC_STRING_APPEND) \
276  || defined(TRIO_FUNC_XSTRING_APPEND)
277
278 TRIO_PRIVATE_STRING BOOLEAN_T
279 internal_string_grow_to
280 TRIO_ARGS2((self, length),
281            trio_string_t *self,
282            size_t length)
283 {
284   length++; /* Room for terminating zero */
285   return (self->allocated < length)
286     ? internal_string_grow(self, length - self->allocated)
287     : TRUE;
288 }
289
290 #endif
291
292 #if defined(TRIO_FUNC_INTERNAL_TO_UPPER)
293
294 TRIO_PRIVATE_STRING TRIO_INLINE int
295 internal_to_upper
296 TRIO_ARGS1((source),
297            int source)
298 {
299 # if defined(HAVE_TOUPPER)
300   
301   return toupper(source);
302   
303 # else
304
305   /* Does not handle locales or non-contiguous alphabetic characters */
306   return ((source >= (int)'a') && (source <= (int)'z'))
307     ? source - 'a' + 'A'
308     : source;
309   
310 # endif
311 }
312
313 #endif
314
315
316 /**
317    Create new string.
318
319    @param size Size of new string.
320    @return Pointer to string, or NULL if allocation failed.
321 */
322 #if defined(TRIO_FUNC_CREATE)
323
324 TRIO_PUBLIC_STRING char *
325 trio_create
326 TRIO_ARGS1((size),
327            size_t size)
328 {
329   return (char *)TRIO_MALLOC(size);
330 }
331
332 #endif
333
334 /**
335    Destroy string.
336
337    @param string String to be freed.
338 */
339 #if defined(TRIO_FUNC_DESTROY)
340
341 TRIO_PUBLIC_STRING void
342 trio_destroy
343 TRIO_ARGS1((string),
344            char *string)
345 {
346   if (string)
347     {
348       TRIO_FREE(string);
349     }
350 }
351
352 #endif
353
354 /**
355    Count the number of characters in a string.
356
357    @param string String to measure.
358    @return Number of characters in @p string.
359 */
360 #if defined(TRIO_FUNC_LENGTH)
361
362 TRIO_PUBLIC_STRING size_t
363 trio_length
364 TRIO_ARGS1((string),
365            TRIO_CONST char *string)
366 {
367   return strlen(string);
368 }
369
370 #endif
371
372 /**
373    Count at most @p max characters in a string.
374
375    @param string String to measure.
376    @param max Maximum number of characters to count.
377    @return The maximum value of @p max and number of characters in @p string.
378 */
379 #if defined(TRIO_FUNC_LENGTH)
380
381 TRIO_PUBLIC_STRING size_t
382 trio_length_max
383 TRIO_ARGS2((string, max),
384            TRIO_CONST char *string,
385            size_t max)
386 {
387   size_t i;
388
389   for (i = 0; i < max; ++i)
390     {
391       if (string[i] == 0)
392         break;
393     }
394   return i;
395 }
396
397 #endif
398
399 /**
400    Append @p source at the end of @p target.
401    
402    @param target Target string.
403    @param source Source string.
404    @return Boolean value indicating success or failure.
405    
406    @pre @p target must point to a memory chunk with sufficient room to
407    contain the @p target string and @p source string.
408    @pre No boundary checking is performed, so insufficient memory will
409    result in a buffer overrun.
410    @post @p target will be zero terminated.
411 */
412 #if defined(TRIO_FUNC_APPEND)
413
414 TRIO_PUBLIC_STRING int
415 trio_append
416 TRIO_ARGS2((target, source),
417            char *target,
418            TRIO_CONST char *source)
419 {
420   assert(target);
421   assert(source);
422   
423   return (strcat(target, source) != NULL);
424 }
425
426 #endif
427
428 /**
429    Append at most @p max characters from @p source to @p target.
430    
431    @param target Target string.
432    @param max Maximum number of characters to append.
433    @param source Source string.
434    @return Boolean value indicating success or failure.
435    
436    @pre @p target must point to a memory chuck with sufficient room to
437    contain the @p target string and the @p source string (at most @p max
438    characters).
439    @pre No boundary checking is performed, so insufficient memory will
440    result in a buffer overrun.
441    @post @p target will be zero terminated.
442 */
443 #if defined(TRIO_FUNC_APPEND_MAX)
444
445 TRIO_PUBLIC_STRING int
446 trio_append_max
447 TRIO_ARGS3((target, max, source),
448            char *target,
449            size_t max,
450            TRIO_CONST char *source)
451 {
452   size_t length;
453   
454   assert(target);
455   assert(source);
456
457   length = trio_length(target);
458   
459   if (max > length)
460     {
461       strncat(target, source, max - length - 1);
462     }
463   return TRUE;
464 }
465
466 #endif
467
468 /**
469    Determine if a string contains a substring.
470
471    @param string String to be searched.
472    @param substring String to be found.
473    @return Boolean value indicating success or failure.
474 */
475 #if defined(TRIO_FUNC_CONTAINS)
476
477 TRIO_PUBLIC_STRING int
478 trio_contains
479 TRIO_ARGS2((string, substring),
480            TRIO_CONST char *string,
481            TRIO_CONST char *substring)
482 {
483   assert(string);
484   assert(substring);
485   
486   return (0 != strstr(string, substring));
487 }
488
489 #endif
490
491 /**
492    Copy @p source to @p target.
493    
494    @param target Target string.
495    @param source Source string.
496    @return Boolean value indicating success or failure.
497    
498    @pre @p target must point to a memory chunk with sufficient room to
499    contain the @p source string.
500    @pre No boundary checking is performed, so insufficient memory will
501    result in a buffer overrun.
502    @post @p target will be zero terminated.
503 */
504 #if defined(TRIO_FUNC_COPY)
505
506 TRIO_PUBLIC_STRING int
507 trio_copy
508 TRIO_ARGS2((target, source),
509            char *target,
510            TRIO_CONST char *source)
511 {
512   assert(target);
513   assert(source);
514      
515   (void)strcpy(target, source);
516   return TRUE;
517 }
518
519 #endif
520
521 /**
522    Copy at most @p max characters from @p source to @p target.
523    
524    @param target Target string.
525    @param max Maximum number of characters to append.
526    @param source Source string.
527    @return Boolean value indicating success or failure.
528    
529    @pre @p target must point to a memory chunk with sufficient room to
530    contain the @p source string (at most @p max characters).
531    @pre No boundary checking is performed, so insufficient memory will
532    result in a buffer overrun.
533    @post @p target will be zero terminated.
534 */
535 #if defined(TRIO_FUNC_COPY_MAX)
536
537 TRIO_PUBLIC_STRING int
538 trio_copy_max
539 TRIO_ARGS3((target, max, source),
540            char *target,
541            size_t max,
542            TRIO_CONST char *source)
543 {
544   assert(target);
545   assert(source);
546   assert(max > 0); /* Includes != 0 */
547
548   (void)strncpy(target, source, max - 1);
549   target[max - 1] = (char)0;
550   return TRUE;
551 }
552
553 #endif
554
555 /**
556    Duplicate @p source.
557    
558    @param source Source string.
559    @return A copy of the @p source string.
560    
561    @post @p target will be zero terminated.
562 */
563 #if defined(TRIO_FUNC_DUPLICATE)
564
565 TRIO_PUBLIC_STRING char *
566 trio_duplicate
567 TRIO_ARGS1((source),
568            TRIO_CONST char *source)
569 {
570   return internal_duplicate_max(source, trio_length(source));
571 }
572
573 #endif
574
575 /**
576    Duplicate at most @p max characters of @p source.
577    
578    @param source Source string.
579    @param max Maximum number of characters to duplicate.
580    @return A copy of the @p source string.
581    
582    @post @p target will be zero terminated.
583 */
584 #if defined(TRIO_FUNC_DUPLICATE_MAX)
585
586 TRIO_PUBLIC_STRING char *
587 trio_duplicate_max
588 TRIO_ARGS2((source, max),
589            TRIO_CONST char *source,
590            size_t max)
591 {
592   size_t length;
593
594   assert(source);
595   assert(max > 0);
596
597   length = trio_length(source);
598   if (length > max)
599     {
600       length = max;
601     }
602   return internal_duplicate_max(source, length);
603 }
604
605 #endif
606
607 /**
608    Compare if two strings are equal.
609    
610    @param first First string.
611    @param second Second string.
612    @return Boolean indicating whether the two strings are equal or not.
613    
614    Case-insensitive comparison.
615 */
616 #if defined(TRIO_FUNC_EQUAL)
617
618 TRIO_PUBLIC_STRING int
619 trio_equal
620 TRIO_ARGS2((first, second),
621            TRIO_CONST char *first,
622            TRIO_CONST char *second)
623 {
624   assert(first);
625   assert(second);
626
627   if ((first != NULL) && (second != NULL))
628     {
629 # if defined(USE_STRCASECMP)
630       return (0 == strcasecmp(first, second));
631 # else
632       while ((*first != NIL) && (*second != NIL))
633         {
634           if (internal_to_upper(*first) != internal_to_upper(*second))
635             {
636               break;
637             }
638           first++;
639           second++;
640         }
641       return ((*first == NIL) && (*second == NIL));
642 # endif
643     }
644   return FALSE;
645 }
646
647 #endif
648
649 /**
650    Compare if two strings are equal.
651    
652    @param first First string.
653    @param second Second string.
654    @return Boolean indicating whether the two strings are equal or not.
655    
656    Case-sensitive comparison.
657 */
658 #if defined(TRIO_FUNC_EQUAL_CASE)
659
660 TRIO_PUBLIC_STRING int
661 trio_equal_case
662 TRIO_ARGS2((first, second),
663            TRIO_CONST char *first,
664            TRIO_CONST char *second)
665 {
666   assert(first);
667   assert(second);
668
669   if ((first != NULL) && (second != NULL))
670     {
671       return (0 == strcmp(first, second));
672     }
673   return FALSE;
674 }
675
676 #endif
677
678 /**
679    Compare if two strings up until the first @p max characters are equal.
680    
681    @param first First string.
682    @param max Maximum number of characters to compare.
683    @param second Second string.
684    @return Boolean indicating whether the two strings are equal or not.
685    
686    Case-sensitive comparison.
687 */
688 #if defined(TRIO_FUNC_EQUAL_CASE_MAX)
689
690 TRIO_PUBLIC_STRING int
691 trio_equal_case_max
692 TRIO_ARGS3((first, max, second),
693            TRIO_CONST char *first,
694            size_t max,
695            TRIO_CONST char *second)
696 {
697   assert(first);
698   assert(second);
699
700   if ((first != NULL) && (second != NULL))
701     {
702       return (0 == strncmp(first, second, max));
703     }
704   return FALSE;
705 }
706
707 #endif
708
709 /**
710    Compare if two strings are equal.
711    
712    @param first First string.
713    @param second Second string.
714    @return Boolean indicating whether the two strings are equal or not.
715
716    Collating characters are considered equal.
717 */
718 #if defined(TRIO_FUNC_EQUAL_LOCALE)
719
720 TRIO_PUBLIC_STRING int
721 trio_equal_locale
722 TRIO_ARGS2((first, second),
723            TRIO_CONST char *first,
724            TRIO_CONST char *second)
725 {
726   assert(first);
727   assert(second);
728
729 # if defined(LC_COLLATE)
730   return (strcoll(first, second) == 0);
731 # else
732   return trio_equal(first, second);
733 # endif
734 }
735
736 #endif
737
738 /**
739    Compare if two strings up until the first @p max characters are equal.
740    
741    @param first First string.
742    @param max Maximum number of characters to compare.
743    @param second Second string.
744    @return Boolean indicating whether the two strings are equal or not.
745    
746    Case-insensitive comparison.
747 */
748 #if defined(TRIO_FUNC_EQUAL_MAX)
749
750 TRIO_PUBLIC_STRING int
751 trio_equal_max
752 TRIO_ARGS3((first, max, second),
753            TRIO_CONST char *first,
754            size_t max,
755            TRIO_CONST char *second)
756 {
757   assert(first);
758   assert(second);
759
760   if ((first != NULL) && (second != NULL))
761     {
762 # if defined(USE_STRNCASECMP)
763       return (0 == strncasecmp(first, second, max));
764 # else
765       /* Not adequately tested yet */
766       size_t cnt = 0;
767       while ((*first != NIL) && (*second != NIL) && (cnt <= max))
768         {
769           if (internal_to_upper(*first) != internal_to_upper(*second))
770             {
771               break;
772             }
773           first++;
774           second++;
775           cnt++;
776         }
777       return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
778 # endif
779     }
780   return FALSE;
781 }
782
783 #endif
784
785 /**
786    Provide a textual description of an error code (errno).
787
788    @param error_number Error number.
789    @return Textual description of @p error_number.
790 */
791 #if defined(TRIO_FUNC_ERROR)
792
793 TRIO_PUBLIC_STRING TRIO_CONST char *
794 trio_error
795 TRIO_ARGS1((error_number),
796            int error_number)
797 {
798 # if defined(USE_STRERROR)
799   
800   return strerror(error_number);
801
802 # else
803 #  if defined(USE_SYS_ERRLIST)
804
805   extern char *sys_errlist[];
806   extern int sys_nerr;
807
808   return ((error_number < 0) || (error_number >= sys_nerr))
809     ? "unknown"
810     : sys_errlist[error_number];
811  
812 #  else
813   
814   return "unknown";
815
816 #  endif
817 # endif
818 }
819
820 #endif
821
822 /**
823    Format the date/time according to @p format.
824
825    @param target Target string.
826    @param max Maximum number of characters to format.
827    @param format Formatting string.
828    @param datetime Date/time structure.
829    @return Number of formatted characters.
830
831    The formatting string accepts the same specifiers as the standard C
832    function strftime.
833 */
834 #if defined(TRIO_FUNC_FORMAT_DATE_MAX)
835
836 TRIO_PUBLIC_STRING size_t
837 trio_format_date_max
838 TRIO_ARGS4((target, max, format, datetime),
839            char *target,
840            size_t max,
841            TRIO_CONST char *format,
842            TRIO_CONST struct tm *datetime)
843 {
844   assert(target);
845   assert(format);
846   assert(datetime);
847   assert(max > 0);
848
849   return strftime(target, max, format, datetime);
850 }
851
852 #endif
853
854 /**
855    Calculate a hash value for a string.
856
857    @param string String to be calculated on.
858    @param type Hash function.
859    @return Calculated hash value.
860
861    @p type can be one of the following
862    @li @c TRIO_HASH_PLAIN Plain hash function.
863 */
864 #if defined(TRIO_FUNC_HASH)
865
866 TRIO_PUBLIC_STRING unsigned long
867 trio_hash
868 TRIO_ARGS2((string, type),
869            TRIO_CONST char *string,
870            int type)
871 {
872   unsigned long value = 0L;
873   char ch;
874
875   assert(string);
876   
877   switch (type)
878     {
879     case TRIO_HASH_PLAIN:
880       while ( (ch = *string++) != NIL )
881         {
882           value *= 31;
883           value += (unsigned long)ch;
884         }
885       break;
886     default:
887       assert(FALSE);
888       break;
889     }
890   return value;
891 }
892
893 #endif
894
895 /**
896    Find first occurrence of a character in a string.
897
898    @param string String to be searched.
899    @param character Character to be found.
900    @return A pointer to the found character, or NULL if character was not found.
901  */
902 #if defined(TRIO_FUNC_INDEX)
903
904 TRIO_PUBLIC_STRING char *
905 trio_index
906 TRIO_ARGS2((string, character),
907            TRIO_CONST char *string,
908            int character)
909 {
910   assert(string);
911
912   return strchr(string, character);
913 }
914
915 #endif
916
917 /**
918    Find last occurrence of a character in a string.
919
920    @param string String to be searched.
921    @param character Character to be found.
922    @return A pointer to the found character, or NULL if character was not found.
923  */
924 #if defined(TRIO_FUNC_INDEX_LAST)
925
926 TRIO_PUBLIC_STRING char *
927 trio_index_last
928 TRIO_ARGS2((string, character),
929            TRIO_CONST char *string,
930            int character)
931 {
932   assert(string);
933
934   return strchr(string, character);
935 }
936
937 #endif
938
939 /**
940    Convert the alphabetic letters in the string to lower-case.
941
942    @param target String to be converted.
943    @return Number of processed characters (converted or not).
944 */
945 #if defined(TRIO_FUNC_LOWER)
946
947 TRIO_PUBLIC_STRING int
948 trio_lower
949 TRIO_ARGS1((target),
950            char *target)
951 {
952   assert(target);
953
954   return trio_span_function(target, target, trio_to_lower);
955 }
956
957 #endif
958
959 /**
960    Compare two strings using wildcards.
961
962    @param string String to be searched.
963    @param pattern Pattern, including wildcards, to search for.
964    @return Boolean value indicating success or failure.
965
966    Case-insensitive comparison.
967    
968    The following wildcards can be used
969    @li @c * Match any number of characters.
970    @li @c ? Match a single character.
971 */
972 #if defined(TRIO_FUNC_MATCH)
973
974 TRIO_PUBLIC_STRING int
975 trio_match
976 TRIO_ARGS2((string, pattern),
977            TRIO_CONST char *string,
978            TRIO_CONST char *pattern)
979 {
980   assert(string);
981   assert(pattern);
982   
983   for (; ('*' != *pattern); ++pattern, ++string)
984     {
985       if (NIL == *string)
986         {
987           return (NIL == *pattern);
988         }
989       if ((internal_to_upper((int)*string) != internal_to_upper((int)*pattern))
990           && ('?' != *pattern))
991         {
992           return FALSE;
993         }
994     }
995   /* two-line patch to prevent *too* much recursiveness: */
996   while ('*' == pattern[1])
997     pattern++;
998
999   do
1000     {
1001       if ( trio_match(string, &pattern[1]) )
1002         {
1003           return TRUE;
1004         }
1005     }
1006   while (*string++);
1007   
1008   return FALSE;
1009 }
1010
1011 #endif
1012
1013 /**
1014    Compare two strings using wildcards.
1015
1016    @param string String to be searched.
1017    @param pattern Pattern, including wildcards, to search for.
1018    @return Boolean value indicating success or failure.
1019
1020    Case-sensitive comparison.
1021    
1022    The following wildcards can be used
1023    @li @c * Match any number of characters.
1024    @li @c ? Match a single character.
1025 */
1026 #if defined(TRIO_FUNC_MATCH_CASE)
1027
1028 TRIO_PUBLIC_STRING int
1029 trio_match_case
1030 TRIO_ARGS2((string, pattern),
1031            TRIO_CONST char *string,
1032            TRIO_CONST char *pattern)
1033 {
1034   assert(string);
1035   assert(pattern);
1036   
1037   for (; ('*' != *pattern); ++pattern, ++string)
1038     {
1039       if (NIL == *string)
1040         {
1041           return (NIL == *pattern);
1042         }
1043       if ((*string != *pattern)
1044           && ('?' != *pattern))
1045         {
1046           return FALSE;
1047         }
1048     }
1049   /* two-line patch to prevent *too* much recursiveness: */
1050   while ('*' == pattern[1])
1051     pattern++;
1052
1053   do
1054     {
1055       if ( trio_match_case(string, &pattern[1]) )
1056         {
1057           return TRUE;
1058         }
1059     }
1060   while (*string++);
1061   
1062   return FALSE;
1063 }
1064
1065 #endif
1066
1067 /**
1068    Execute a function on each character in string.
1069
1070    @param target Target string.
1071    @param source Source string.
1072    @param Function Function to be executed.
1073    @return Number of processed characters.
1074 */
1075 #if defined(TRIO_FUNC_SPAN_FUNCTION)
1076
1077 TRIO_PUBLIC_STRING size_t
1078 trio_span_function
1079 TRIO_ARGS3((target, source, Function),
1080            char *target,
1081            TRIO_CONST char *source,
1082            int (*Function) TRIO_PROTO((int)))
1083 {
1084   size_t count = 0;
1085
1086   assert(target);
1087   assert(source);
1088   assert(Function);
1089   
1090   while (*source != NIL)
1091     {
1092       *target++ = Function(*source++);
1093       count++;
1094     }
1095   return count;
1096 }
1097
1098 #endif
1099
1100 /**
1101    Search for a substring in a string.
1102
1103    @param string String to be searched.
1104    @param substring String to be found.
1105    @return Pointer to first occurrence of @p substring in @p string, or NULL
1106    if no match was found.
1107 */
1108 #if defined(TRIO_FUNC_SUBSTRING)
1109
1110 TRIO_PUBLIC_STRING char *
1111 trio_substring
1112 TRIO_ARGS2((string, substring),
1113            TRIO_CONST char *string,
1114            TRIO_CONST char *substring)
1115 {
1116   assert(string);
1117   assert(substring);
1118
1119   return strstr(string, substring);
1120 }
1121
1122 #endif
1123
1124 /**
1125    Search for a substring in the first @p max characters of a string.
1126
1127    @param string String to be searched.
1128    @param max Maximum characters to be searched.
1129    @param substring String to be found.
1130    @return Pointer to first occurrence of @p substring in @p string, or NULL
1131    if no match was found.
1132 */
1133 #if defined(TRIO_FUNC_SUBSTRING_MAX)
1134
1135 TRIO_PUBLIC_STRING char *
1136 trio_substring_max
1137 TRIO_ARGS3((string, max, substring),
1138            TRIO_CONST char *string,
1139            size_t max,
1140            TRIO_CONST char *substring)
1141 {
1142   size_t count;
1143   size_t size;
1144   char *result = NULL;
1145
1146   assert(string);
1147   assert(substring);
1148   
1149   size = trio_length(substring);
1150   if (size <= max)
1151     {
1152       for (count = 0; count <= max - size; count++)
1153         {
1154           if (trio_equal_max(substring, size, &string[count]))
1155             {
1156               result = (char *)&string[count];
1157               break;
1158             }
1159         }
1160     }
1161   return result;
1162 }
1163
1164 #endif
1165
1166 /**
1167    Tokenize string.
1168
1169    @param string String to be tokenized.
1170    @param delimiters String containing list of delimiting characters.
1171    @return Start of new token.
1172
1173    @warning @p string will be destroyed.
1174 */
1175 #if defined(TRIO_FUNC_TOKENIZE)
1176
1177 TRIO_PUBLIC_STRING char *
1178 trio_tokenize
1179 TRIO_ARGS2((string, delimiters),
1180            char *string,
1181            TRIO_CONST char *delimiters)
1182 {
1183   assert(delimiters);
1184   
1185   return strtok(string, delimiters);
1186 }
1187
1188 #endif
1189
1190 /**
1191    Convert string to floating-point number.
1192
1193    @param source String to be converted.
1194    @param endp Pointer to end of the converted string.
1195    @return A floating-point number.
1196
1197    The following Extended Backus-Naur form is used
1198    @verbatim
1199    double        ::= [ <sign> ]
1200                      ( <number> |
1201                        <number> <decimal_point> <number> |
1202                        <decimal_point> <number> )
1203                      [ <exponential> [ <sign> ] <number> ]
1204    number        ::= 1*( <digit> )
1205    digit         ::= ( '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' )
1206    exponential   ::= ( 'e' | 'E' )
1207    sign          ::= ( '-' | '+' )
1208    decimal_point ::= '.'
1209    @endverbatim
1210 */
1211 #if defined(TRIO_FUNC_TO_LONG_DOUBLE)
1212
1213 /* FIXME: Add EBNF for hex-floats */
1214 TRIO_PUBLIC_STRING trio_long_double_t
1215 trio_to_long_double
1216 TRIO_ARGS2((source, endp),
1217            TRIO_CONST char *source,
1218            char **endp)
1219 {
1220 # if defined(USE_STRTOLD)
1221   return strtold(source, endp);
1222 # else
1223   int isNegative = FALSE;
1224   int isExponentNegative = FALSE;
1225   trio_long_double_t integer = 0.0;
1226   trio_long_double_t fraction = 0.0;
1227   unsigned long exponent = 0;
1228   trio_long_double_t base;
1229   trio_long_double_t fracdiv = 1.0;
1230   trio_long_double_t value = 0.0;
1231
1232   /* First try hex-floats */
1233   if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
1234     {
1235       base = 16.0;
1236       source += 2;
1237       while (isxdigit((int)*source))
1238         {
1239           integer *= base;
1240           integer += (isdigit((int)*source)
1241                       ? (*source - '0')
1242                       : 10 + (internal_to_upper((int)*source) - 'A'));
1243           source++;
1244         }
1245       if (*source == '.')
1246         {
1247           source++;
1248           while (isxdigit((int)*source))
1249             {
1250               fracdiv /= base;
1251               fraction += fracdiv * (isdigit((int)*source)
1252                                      ? (*source - '0')
1253                                      : 10 + (internal_to_upper((int)*source) - 'A'));
1254               source++;
1255             }
1256           if ((*source == 'p') || (*source == 'P'))
1257             {
1258               source++;
1259               if ((*source == '+') || (*source == '-'))
1260                 {
1261                   isExponentNegative = (*source == '-');
1262                   source++;
1263                 }
1264               while (isdigit((int)*source))
1265                 {
1266                   exponent *= 10;
1267                   exponent += (*source - '0');
1268                   source++;
1269                 }
1270             }
1271         }
1272       /* For later use with exponent */
1273       base = 2.0;
1274     }
1275   else /* Then try normal decimal floats */
1276     {
1277       base = 10.0;
1278       isNegative = (*source == '-');
1279       /* Skip sign */
1280       if ((*source == '+') || (*source == '-'))
1281         source++;
1282
1283       /* Integer part */
1284       while (isdigit((int)*source))
1285         {
1286           integer *= base;
1287           integer += (*source - '0');
1288           source++;
1289         }
1290
1291       if (*source == '.')
1292         {
1293           source++; /* skip decimal point */
1294           while (isdigit((int)*source))
1295             {
1296               fracdiv /= base;
1297               fraction += (*source - '0') * fracdiv;
1298               source++;
1299             }
1300         }
1301       if ((*source == 'e')
1302           || (*source == 'E')
1303 #  if TRIO_MICROSOFT
1304           || (*source == 'd')
1305           || (*source == 'D')
1306 #  endif
1307           )
1308         {
1309           source++; /* Skip exponential indicator */
1310           isExponentNegative = (*source == '-');
1311           if ((*source == '+') || (*source == '-'))
1312             source++;
1313           while (isdigit((int)*source))
1314             {
1315               exponent *= (int)base;
1316               exponent += (*source - '0');
1317               source++;
1318             }
1319         }
1320     }
1321   
1322   value = integer + fraction;
1323   if (exponent != 0)
1324     {
1325       if (isExponentNegative)
1326         value /= trio_powl(base, (trio_long_double_t)exponent);
1327       else
1328         value *= trio_powl(base, (trio_long_double_t)exponent);
1329     }
1330   if (isNegative)
1331     value = -value;
1332
1333   if (endp)
1334     *endp = (char *)source;
1335   return value;
1336 # endif
1337 }
1338
1339 #endif
1340
1341 /**
1342    Convert string to floating-point number.
1343
1344    @param source String to be converted.
1345    @param endp Pointer to end of the converted string.
1346    @return A floating-point number.
1347
1348    See @ref trio_to_long_double.
1349 */
1350 #if defined(TRIO_FUNC_TO_DOUBLE)
1351
1352 TRIO_PUBLIC_STRING double
1353 trio_to_double
1354 TRIO_ARGS2((source, endp),
1355            TRIO_CONST char *source,
1356            char **endp)
1357 {
1358 #if defined(USE_STRTOD)
1359   return strtod(source, endp);
1360 #else
1361   return (double)trio_to_long_double(source, endp);
1362 #endif
1363 }
1364
1365 #endif
1366
1367 /**
1368    Convert string to floating-point number.
1369
1370    @param source String to be converted.
1371    @param endp Pointer to end of the converted string.
1372    @return A floating-point number.
1373
1374    See @ref trio_to_long_double.
1375 */
1376 #if defined(TRIO_FUNC_TO_FLOAT)
1377
1378 TRIO_PUBLIC_STRING float
1379 trio_to_float
1380 TRIO_ARGS2((source, endp),
1381            TRIO_CONST char *source,
1382            char **endp)
1383 {
1384 #  if defined(USE_STRTOF)
1385   return strtof(source, endp);
1386 #  else
1387   return (float)trio_to_long_double(source, endp);
1388 #  endif
1389 }
1390
1391 #endif
1392
1393 /**
1394    Convert string to signed integer.
1395
1396    @param string String to be converted.
1397    @param endp Pointer to end of converted string.
1398    @param base Radix number of number.
1399 */
1400 #if defined(TRIO_FUNC_TO_LONG)
1401
1402 TRIO_PUBLIC_STRING long
1403 trio_to_long
1404 TRIO_ARGS3((string, endp, base),
1405            TRIO_CONST char *string,
1406            char **endp,
1407            int base)
1408 {
1409   assert(string);
1410   assert((base >= 2) && (base <= 36));
1411   
1412   return strtol(string, endp, base);
1413 }
1414
1415 #endif
1416
1417 /**
1418    Convert one alphabetic letter to lower-case.
1419
1420    @param source The letter to be converted.
1421    @return The converted letter.
1422 */
1423 #if defined(TRIO_FUNC_TO_LOWER)
1424
1425 TRIO_PUBLIC_STRING int
1426 trio_to_lower
1427 TRIO_ARGS1((source),
1428            int source)
1429 {
1430 # if defined(HAVE_TOLOWER)
1431   
1432   return tolower(source);
1433   
1434 # else
1435
1436   /* Does not handle locales or non-contiguous alphabetic characters */
1437   return ((source >= (int)'A') && (source <= (int)'Z'))
1438     ? source - 'A' + 'a'
1439     : source;
1440   
1441 # endif
1442 }
1443
1444 #endif
1445
1446 /**
1447    Convert string to unsigned integer.
1448
1449    @param string String to be converted.
1450    @param endp Pointer to end of converted string.
1451    @param base Radix number of number.
1452 */
1453 #if defined(TRIO_FUNC_TO_UNSIGNED_LONG)
1454
1455 TRIO_PUBLIC_STRING unsigned long
1456 trio_to_unsigned_long
1457 TRIO_ARGS3((string, endp, base),
1458            TRIO_CONST char *string,
1459            char **endp,
1460            int base)
1461 {
1462   assert(string);
1463   assert((base >= 2) && (base <= 36));
1464   
1465   return strtoul(string, endp, base);
1466 }
1467
1468 #endif
1469
1470 /**
1471    Convert one alphabetic letter to upper-case.
1472
1473    @param source The letter to be converted.
1474    @return The converted letter.
1475 */
1476 #if defined(TRIO_FUNC_TO_UPPER)
1477
1478 TRIO_PUBLIC_STRING int
1479 trio_to_upper
1480 TRIO_ARGS1((source),
1481            int source)
1482 {
1483   return internal_to_upper(source);
1484 }
1485
1486 #endif
1487
1488 /**
1489    Convert the alphabetic letters in the string to upper-case.
1490
1491    @param target The string to be converted.
1492    @return The number of processed characters (converted or not).
1493 */
1494 #if defined(TRIO_FUNC_UPPER)
1495
1496 TRIO_PUBLIC_STRING int
1497 trio_upper
1498 TRIO_ARGS1((target),
1499            char *target)
1500 {
1501   assert(target);
1502
1503   return trio_span_function(target, target, internal_to_upper);
1504 }
1505
1506 #endif
1507
1508 /** @} End of StaticStrings */
1509
1510
1511 /*************************************************************************
1512  * Dynamic String Functions
1513  */
1514
1515 #if defined(TRIO_DOCUMENTATION)
1516 # include "doc/doc_dynamic.h"
1517 #endif
1518 /** @addtogroup DynamicStrings
1519     @{
1520 */
1521
1522 /**
1523    Create a new dynamic string.
1524    
1525    @param initial_size Initial size of the buffer.
1526    @return Newly allocated dynamic string, or NULL if memory allocation failed.
1527 */
1528 #if defined(TRIO_FUNC_STRING_CREATE)
1529
1530 TRIO_PUBLIC_STRING trio_string_t *
1531 trio_string_create
1532 TRIO_ARGS1((initial_size),
1533            int initial_size)
1534 {
1535   trio_string_t *self;
1536
1537   self = internal_string_alloc();
1538   if (self)
1539     {
1540       if (internal_string_grow(self,
1541                          (size_t)((initial_size > 0) ? initial_size : 1)))
1542         {
1543           self->content[0] = (char)0;
1544           self->allocated = initial_size;
1545         }
1546       else
1547         {
1548           trio_string_destroy(self);
1549           self = NULL;
1550         }
1551     }
1552   return self;
1553 }
1554
1555 #endif
1556
1557 /**
1558    Deallocate the dynamic string and its contents.
1559    
1560    @param self Dynamic string
1561 */
1562 #if defined(TRIO_FUNC_STRING_DESTROY)
1563
1564 TRIO_PUBLIC_STRING void
1565 trio_string_destroy
1566 TRIO_ARGS1((self),
1567            trio_string_t *self)
1568 {
1569   assert(self);
1570   
1571   if (self)
1572     {
1573       trio_destroy(self->content);
1574       TRIO_FREE(self);
1575     }
1576 }
1577
1578 #endif
1579
1580 /**
1581    Get a pointer to the content.
1582    
1583    @param self Dynamic string.
1584    @param offset Offset into content.
1585    @return Pointer to the content.
1586    
1587    @p Offset can be zero, positive, or negative. If @p offset is zero,
1588    then the start of the content will be returned. If @p offset is positive,
1589    then a pointer to @p offset number of characters from the beginning of the
1590    content is returned. If @p offset is negative, then a pointer to @p offset
1591    number of characters from the ending of the string, starting at the
1592    terminating zero, is returned.
1593 */
1594 #if defined(TRIO_FUNCT_STRING_GET)
1595
1596 TRIO_PUBLIC_STRING char *
1597 trio_string_get
1598 TRIO_ARGS2((self, offset),
1599            trio_string_t *self,
1600            int offset)
1601 {
1602   char *result = NULL;
1603   
1604   assert(self);
1605
1606   if (self->content != NULL)
1607     {
1608       if (self->length == 0)
1609         {
1610           (void)trio_string_length(self);
1611         }
1612       if (offset >= 0)
1613         {
1614           if (offset > (int)self->length)
1615             {
1616               offset = self->length;
1617             }
1618         }
1619       else
1620         {
1621           offset += self->length + 1;
1622           if (offset < 0)
1623             {
1624               offset = 0;
1625             }
1626         }
1627       result = &(self->content[offset]);
1628     }
1629   return result;
1630 }
1631
1632 #endif
1633
1634 /**
1635    Extract the content.
1636    
1637    @param self Dynamic String
1638    @return Content of dynamic string.
1639    
1640    The content is removed from the dynamic string. This enables destruction
1641    of the dynamic string without deallocation of the content.
1642 */
1643 #if defined(TRIO_FUNC_STRING_EXTRACT)
1644
1645 TRIO_PUBLIC_STRING char *
1646 trio_string_extract
1647 TRIO_ARGS1((self),
1648            trio_string_t *self)
1649 {
1650   char *result;
1651   
1652   assert(self);
1653
1654   result = self->content;
1655   /* FIXME: Allocate new empty buffer? */
1656   self->content = NULL;
1657   self->length = self->allocated = 0;
1658   return result;
1659 }
1660
1661 #endif
1662
1663 /**
1664    Set the content of the dynamic string.
1665    
1666    @param self Dynamic String
1667    @param buffer The new content.
1668    
1669    Sets the content of the dynamic string to a copy @p buffer.
1670    An existing content will be deallocated first, if necessary.
1671    
1672    @remark
1673    This function will make a copy of @p buffer.
1674    You are responsible for deallocating @p buffer yourself.
1675 */
1676 #if defined(TRIO_FUNC_XSTRING_SET)
1677
1678 TRIO_PUBLIC_STRING void
1679 trio_xstring_set
1680 TRIO_ARGS2((self, buffer),
1681            trio_string_t *self,
1682            char *buffer)
1683 {
1684   assert(self);
1685
1686   trio_destroy(self->content);
1687   self->content = trio_duplicate(buffer);
1688 }
1689
1690 #endif
1691
1692 /*
1693  * trio_string_size
1694  */
1695 #if defined(TRIO_FUNC_STRING_SIZE)
1696
1697 TRIO_PUBLIC_STRING int
1698 trio_string_size
1699 TRIO_ARGS1((self),
1700            trio_string_t *self)
1701 {
1702   assert(self);
1703
1704   return self->allocated;
1705 }
1706
1707 #endif
1708
1709 /*
1710  * trio_string_terminate
1711  */
1712 #if defined(TRIO_FUNC_STRING_TERMINATE)
1713
1714 TRIO_PUBLIC_STRING void
1715 trio_string_terminate
1716 TRIO_ARGS1((self),
1717            trio_string_t *self)
1718 {
1719   trio_xstring_append_char(self, 0);
1720 }
1721
1722 #endif
1723
1724 /**
1725    Append the second string to the first.
1726    
1727    @param self Dynamic string to be modified.
1728    @param other Dynamic string to copy from.
1729    @return Boolean value indicating success or failure.
1730 */
1731 #if defined(TRIO_FUNC_STRING_APPEND)
1732
1733 TRIO_PUBLIC_STRING int
1734 trio_string_append
1735 TRIO_ARGS2((self, other),
1736            trio_string_t *self,
1737            trio_string_t *other)
1738 {
1739   size_t length;
1740   
1741   assert(self);
1742   assert(other);
1743
1744   length = self->length + other->length;
1745   if (!internal_string_grow_to(self, length))
1746     goto error;
1747   trio_copy(&self->content[self->length], other->content);
1748   self->length = length;
1749   return TRUE;
1750   
1751  error:
1752   return FALSE;
1753 }
1754
1755 #endif
1756
1757
1758 /*
1759  * trio_xstring_append
1760  */
1761 #if defined(TRIO_FUNC_XSTRING_APPEND)
1762
1763 TRIO_PUBLIC_STRING int
1764 trio_xstring_append
1765 TRIO_ARGS2((self, other),
1766            trio_string_t *self,
1767            TRIO_CONST char *other)
1768 {
1769   size_t length;
1770   
1771   assert(self);
1772   assert(other);
1773
1774   length = self->length + trio_length(other);
1775   if (!internal_string_grow_to(self, length))
1776     goto error;
1777   trio_copy(&self->content[self->length], other);
1778   self->length = length;
1779   return TRUE;
1780   
1781  error:
1782   return FALSE;
1783 }
1784
1785 #endif
1786
1787 /*
1788  * trio_xstring_append_char
1789  */
1790 #if defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
1791
1792 TRIO_PUBLIC_STRING int
1793 trio_xstring_append_char
1794 TRIO_ARGS2((self, character),
1795            trio_string_t *self,
1796            char character)
1797 {
1798   assert(self);
1799
1800   if ((int)self->length >= trio_string_size(self))
1801     {
1802       if (!internal_string_grow(self, 0))
1803         goto error;
1804     }
1805   self->content[self->length] = character;
1806   self->length++;
1807   return TRUE;
1808   
1809  error:
1810   return FALSE;
1811 }
1812
1813 #endif
1814
1815 /**
1816    Search for the first occurrence of second parameter in the first.
1817    
1818    @param self Dynamic string to be modified.
1819    @param other Dynamic string to copy from.
1820    @return Boolean value indicating success or failure.
1821 */
1822 #if defined(TRIO_FUNC_STRING_CONTAINS)
1823
1824 TRIO_PUBLIC_STRING int
1825 trio_string_contains
1826 TRIO_ARGS2((self, other),
1827            trio_string_t *self,
1828            trio_string_t *other)
1829 {
1830   assert(self);
1831   assert(other);
1832
1833   return trio_contains(self->content, other->content);
1834 }
1835
1836 #endif
1837
1838 /*
1839  * trio_xstring_contains
1840  */
1841 #if defined(TRIO_FUNC_XSTRING_CONTAINS)
1842
1843 TRIO_PUBLIC_STRING int
1844 trio_xstring_contains
1845 TRIO_ARGS2((self, other),
1846            trio_string_t *self,
1847            TRIO_CONST char *other)
1848 {
1849   assert(self);
1850   assert(other);
1851
1852   return trio_contains(self->content, other);
1853 }
1854
1855 #endif
1856
1857 /*
1858  * trio_string_copy
1859  */
1860 #if defined(TRIO_FUNC_STRING_COPY)
1861
1862 TRIO_PUBLIC_STRING int
1863 trio_string_copy
1864 TRIO_ARGS2((self, other),
1865            trio_string_t *self,
1866            trio_string_t *other)
1867 {
1868   assert(self);
1869   assert(other);
1870
1871   self->length = 0;
1872   return trio_string_append(self, other);
1873 }
1874
1875 #endif
1876
1877
1878 /*
1879  * trio_xstring_copy
1880  */
1881 #if defined(TRIO_FUNC_XSTRING_COPY)
1882
1883 TRIO_PUBLIC_STRING int
1884 trio_xstring_copy
1885 TRIO_ARGS2((self, other),
1886            trio_string_t *self,
1887            TRIO_CONST char *other)
1888 {
1889   assert(self);
1890   assert(other);
1891
1892   self->length = 0;
1893   return trio_xstring_append(self, other);
1894 }
1895
1896 #endif
1897
1898 /*
1899  * trio_string_duplicate
1900  */
1901 #if defined(TRIO_FUNC_STRING_DUPLICATE)
1902
1903 TRIO_PUBLIC_STRING trio_string_t *
1904 trio_string_duplicate
1905 TRIO_ARGS1((other),
1906            trio_string_t *other)
1907 {
1908   trio_string_t *self;
1909   
1910   assert(other);
1911
1912   self = internal_string_alloc();
1913   if (self)
1914     {
1915       self->content = internal_duplicate_max(other->content, other->length);
1916       if (self->content)
1917         {
1918           self->length = other->length;
1919           self->allocated = self->length + 1;
1920         }
1921       else
1922         {
1923           self->length = self->allocated = 0;
1924         }
1925     }
1926   return self;
1927 }
1928
1929 #endif
1930
1931 /*
1932  * trio_xstring_duplicate
1933  */
1934 #if defined(TRIO_FUNC_XSTRING_DUPLICATE)
1935
1936 TRIO_PUBLIC_STRING trio_string_t *
1937 trio_xstring_duplicate
1938 TRIO_ARGS1((other),
1939            TRIO_CONST char *other)
1940 {
1941   trio_string_t *self;
1942   
1943   assert(other);
1944
1945   self = internal_string_alloc();
1946   if (self)
1947     {
1948       self->content = internal_duplicate_max(other, trio_length(other));
1949       if (self->content)
1950         {
1951           self->length = trio_length(self->content);
1952           self->allocated = self->length + 1;
1953         }
1954       else
1955         {
1956           self->length = self->allocated = 0;
1957         }
1958     }
1959   return self;
1960 }
1961
1962 #endif
1963
1964 /*
1965  * trio_string_equal
1966  */
1967 #if defined(TRIO_FUNC_STRING_EQUAL)
1968
1969 TRIO_PUBLIC_STRING int
1970 trio_string_equal
1971 TRIO_ARGS2((self, other),
1972            trio_string_t *self,
1973            trio_string_t *other)
1974 {
1975   assert(self);
1976   assert(other);
1977
1978   return trio_equal(self->content, other->content);
1979 }
1980
1981 #endif
1982
1983
1984 /*
1985  * trio_xstring_equal
1986  */
1987 #if defined(TRIO_FUNC_XSTRING_EQUAL)
1988
1989 TRIO_PUBLIC_STRING int
1990 trio_xstring_equal
1991 TRIO_ARGS2((self, other),
1992            trio_string_t *self,
1993            TRIO_CONST char *other)
1994 {
1995   assert(self);
1996   assert(other);
1997
1998   return trio_equal(self->content, other);
1999 }
2000
2001 #endif
2002
2003 /*
2004  * trio_string_equal_max
2005  */
2006 #if defined(TRIO_FUNC_STRING_EQUAL_MAX)
2007
2008 TRIO_PUBLIC_STRING int
2009 trio_string_equal_max
2010 TRIO_ARGS3((self, max, other),
2011            trio_string_t *self,
2012            size_t max,
2013            trio_string_t *other)
2014 {
2015   assert(self);
2016   assert(other);
2017
2018   return trio_equal_max(self->content, max, other->content);
2019 }
2020 #endif
2021
2022 /*
2023  * trio_xstring_equal_max
2024  */
2025 #if defined(TRIO_FUNC_XSTRING_EQUAL_MAX)
2026
2027 TRIO_PUBLIC_STRING int
2028 trio_xstring_equal_max
2029 TRIO_ARGS3((self, max, other),
2030            trio_string_t *self,
2031            size_t max,
2032            TRIO_CONST char *other)
2033 {
2034   assert(self);
2035   assert(other);
2036
2037   return trio_equal_max(self->content, max, other);
2038 }
2039
2040 #endif
2041
2042 /*
2043  * trio_string_equal_case
2044  */
2045 #if defined(TRIO_FUNC_STRING_EQUAL_CASE)
2046
2047 TRIO_PUBLIC_STRING int
2048 trio_string_equal_case
2049 TRIO_ARGS2((self, other),
2050            trio_string_t *self,
2051            trio_string_t *other)
2052 {
2053   assert(self);
2054   assert(other);
2055
2056   return trio_equal_case(self->content, other->content);
2057 }
2058
2059 #endif
2060
2061 /*
2062  * trio_xstring_equal_case
2063  */
2064 #if defined(TRIO_FUNC_XSTRING_EQUAL_CASE)
2065
2066 TRIO_PUBLIC_STRING int
2067 trio_xstring_equal_case
2068 TRIO_ARGS2((self, other),
2069            trio_string_t *self,
2070            TRIO_CONST char *other)
2071 {
2072   assert(self);
2073   assert(other);
2074
2075   return trio_equal_case(self->content, other);
2076 }
2077
2078 #endif
2079
2080 /*
2081  * trio_string_equal_case_max
2082  */
2083 #if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX)
2084
2085 TRIO_PUBLIC_STRING int
2086 trio_string_equal_case_max
2087 TRIO_ARGS3((self, max, other),
2088            trio_string_t *self,
2089            size_t max,
2090            trio_string_t *other)
2091 {
2092   assert(self);
2093   assert(other);
2094
2095   return trio_equal_case_max(self->content, max, other->content);
2096 }
2097
2098 #endif
2099
2100 /*
2101  * trio_xstring_equal_case_max
2102  */
2103 #if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX)
2104
2105 TRIO_PUBLIC_STRING int
2106 trio_xstring_equal_case_max
2107 TRIO_ARGS3((self, max, other),
2108            trio_string_t *self,
2109            size_t max,
2110            TRIO_CONST char *other)
2111 {
2112   assert(self);
2113   assert(other);
2114
2115   return trio_equal_case_max(self->content, max, other);
2116 }
2117
2118 #endif
2119
2120 /*
2121  * trio_string_format_data_max
2122  */
2123 #if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX)
2124
2125 TRIO_PUBLIC_STRING size_t
2126 trio_string_format_date_max
2127 TRIO_ARGS4((self, max, format, datetime),
2128            trio_string_t *self,
2129            size_t max,
2130            TRIO_CONST char *format,
2131            TRIO_CONST struct tm *datetime)
2132 {
2133   assert(self);
2134
2135   return trio_format_date_max(self->content, max, format, datetime);
2136 }
2137
2138 #endif
2139
2140 /*
2141  * trio_string_index
2142  */
2143 #if defined(TRIO_FUNC_STRING_INDEX)
2144
2145 TRIO_PUBLIC_STRING char *
2146 trio_string_index
2147 TRIO_ARGS2((self, character),
2148            trio_string_t *self,
2149            int character)
2150 {
2151   assert(self);
2152
2153   return trio_index(self->content, character);
2154 }
2155
2156 #endif
2157
2158 /*
2159  * trio_string_index_last
2160  */
2161 #if defined(TRIO_FUNC_STRING_INDEX_LAST)
2162
2163 TRIO_PUBLIC_STRING char *
2164 trio_string_index_last
2165 TRIO_ARGS2((self, character),
2166            trio_string_t *self,
2167            int character)
2168 {
2169   assert(self);
2170
2171   return trio_index_last(self->content, character);
2172 }
2173
2174 #endif
2175
2176 /*
2177  * trio_string_length
2178  */
2179 #if defined(TRIO_FUNC_STRING_LENGTH)
2180
2181 TRIO_PUBLIC_STRING int
2182 trio_string_length
2183 TRIO_ARGS1((self),
2184            trio_string_t *self)
2185 {
2186   assert(self);
2187
2188   if (self->length == 0)
2189     {
2190       self->length = trio_length(self->content);
2191     }
2192   return self->length;
2193 }
2194
2195 #endif
2196
2197 /*
2198  * trio_string_lower
2199  */
2200 #if defined(TRIO_FUNC_STRING_LOWER)
2201
2202 TRIO_PUBLIC_STRING int
2203 trio_string_lower
2204 TRIO_ARGS1((self),
2205            trio_string_t *self)
2206 {
2207   assert(self);
2208
2209   return trio_lower(self->content);
2210 }
2211
2212 #endif
2213
2214 /*
2215  * trio_string_match
2216  */
2217 #if defined(TRIO_FUNC_STRING_MATCH)
2218
2219 TRIO_PUBLIC_STRING int
2220 trio_string_match
2221 TRIO_ARGS2((self, other),
2222            trio_string_t *self,
2223            trio_string_t *other)
2224 {
2225   assert(self);
2226   assert(other);
2227
2228   return trio_match(self->content, other->content);
2229 }
2230
2231 #endif
2232
2233 /*
2234  * trio_xstring_match
2235  */
2236 #if defined(TRIO_FUNC_XSTRING_MATCH)
2237
2238 TRIO_PUBLIC_STRING int
2239 trio_xstring_match
2240 TRIO_ARGS2((self, other),
2241            trio_string_t *self,
2242            TRIO_CONST char *other)
2243 {
2244   assert(self);
2245   assert(other);
2246
2247   return trio_match(self->content, other);
2248 }
2249
2250 #endif
2251
2252 /*
2253  * trio_string_match_case
2254  */
2255 #if defined(TRIO_FUNC_STRING_MATCH_CASE)
2256
2257 TRIO_PUBLIC_STRING int
2258 trio_string_match_case
2259 TRIO_ARGS2((self, other),
2260            trio_string_t *self,
2261            trio_string_t *other)
2262 {
2263   assert(self);
2264   assert(other);
2265
2266   return trio_match_case(self->content, other->content);
2267 }
2268
2269 #endif
2270
2271 /*
2272  * trio_xstring_match_case
2273  */
2274 #if defined(TRIO_FUNC_XSTRING_MATCH_CASE)
2275
2276 TRIO_PUBLIC_STRING int
2277 trio_xstring_match_case
2278 TRIO_ARGS2((self, other),
2279            trio_string_t *self,
2280            TRIO_CONST char *other)
2281 {
2282   assert(self);
2283   assert(other);
2284
2285   return trio_match_case(self->content, other);
2286 }
2287
2288 #endif
2289
2290 /*
2291  * trio_string_substring
2292  */
2293 #if defined(TRIO_FUNC_STRING_SUBSTRING)
2294
2295 TRIO_PUBLIC_STRING char *
2296 trio_string_substring
2297 TRIO_ARGS2((self, other),
2298            trio_string_t *self,
2299            trio_string_t *other)
2300 {
2301   assert(self);
2302   assert(other);
2303
2304   return trio_substring(self->content, other->content);
2305 }
2306
2307 #endif
2308
2309 /*
2310  * trio_xstring_substring
2311  */
2312 #if defined(TRIO_FUNC_XSTRING_SUBSTRING)
2313
2314 TRIO_PUBLIC_STRING char *
2315 trio_xstring_substring
2316 TRIO_ARGS2((self, other),
2317            trio_string_t *self,
2318            TRIO_CONST char *other)
2319 {
2320   assert(self);
2321   assert(other);
2322
2323   return trio_substring(self->content, other);
2324 }
2325
2326 #endif
2327
2328 /*
2329  * trio_string_upper
2330  */
2331 #if defined(TRIO_FUNC_STRING_UPPER)
2332
2333 TRIO_PUBLIC_STRING int
2334 trio_string_upper
2335 TRIO_ARGS1((self),
2336            trio_string_t *self)
2337 {
2338   assert(self);
2339
2340   return trio_upper(self->content);
2341 }
2342
2343 #endif
2344
2345 /** @} End of DynamicStrings */