]> Pileus Git - ~andy/fetchmail/blob - trio/triostr.c
Import Trio 1.10 into fetchmail's trunk.
[~andy/fetchmail] / trio / triostr.c
1 /*************************************************************************
2  *
3  * $Id: triostr.c,v 1.19 2003/03/01 15:34:02 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 #include <assert.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <math.h>
27 #include "triodef.h"
28 #include "triostr.h"
29
30 /*************************************************************************
31  * Definitions
32  */
33
34 #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)
42 # define NULL 0
43 #endif
44 #if !defined(NIL)
45 # define NIL ((char)0)
46 #endif
47 #if !defined(FALSE)
48 # define FALSE (1 == 0)
49 # define TRUE (! FALSE)
50 #endif
51 #if !defined(BOOLEAN_T)
52 # define BOOLEAN_T int
53 #endif
54
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
65 # if defined(TRIO_PLATFORM_SUNOS)
66 #  define USE_SYS_ERRLIST
67 # else
68 #  define USE_STRERROR
69 # endif
70 # 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
79 #if !(defined(TRIO_PLATFORM_SUNOS))
80 # define USE_TOLOWER
81 # define USE_TOUPPER
82 #endif
83
84 /*************************************************************************
85  * Structures
86  */
87
88 struct _trio_string_t
89 {
90   char *content;
91   size_t length;
92   size_t allocated;
93 };
94
95 /*************************************************************************
96  * Constants
97  */
98
99 #if !defined(TRIO_MINIMAL)
100 static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.19 2003/03/01 15:34:02 breese Exp $";
101 #endif
102
103 /*************************************************************************
104  * 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 */
120 TRIO_STRING_PUBLIC char *
121 trio_create
122 TRIO_ARGS1((size),
123            size_t size)
124 {
125   return (char *)TRIO_MALLOC(size);
126 }
127
128
129 /**
130    Destroy string.
131
132    @param string String to be freed.
133 */
134 TRIO_STRING_PUBLIC void
135 trio_destroy
136 TRIO_ARGS1((string),
137            char *string)
138 {
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 */
152 TRIO_STRING_PUBLIC size_t
153 trio_length
154 TRIO_ARGS1((string),
155            TRIO_CONST char *string)
156 {
157   return strlen(string);
158 }
159
160
161 #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 */
175 TRIO_STRING_PUBLIC int
176 trio_append
177 TRIO_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 */
204 TRIO_STRING_PUBLIC int
205 trio_append_max
206 TRIO_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 */
235 TRIO_STRING_PUBLIC int
236 trio_contains
237 TRIO_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 */
263 TRIO_STRING_PUBLIC int
264 trio_copy
265 TRIO_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 */
292 TRIO_STRING_PUBLIC int
293 trio_copy_max
294 TRIO_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
309 /*
310  * TrioDuplicateMax
311  */
312 TRIO_STRING_PRIVATE char *
313 TrioDuplicateMax
314 TRIO_ARGS2((source, size),
315            TRIO_CONST char *source,
316            size_t size)
317 {
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 /**
334    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 */
341 TRIO_STRING_PUBLIC char *
342 trio_duplicate
343 TRIO_ARGS1((source),
344            TRIO_CONST char *source)
345 {
346   return TrioDuplicateMax(source, trio_length(source));
347 }
348
349
350 #if !defined(TRIO_MINIMAL)
351 /**
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 */
360 TRIO_STRING_PUBLIC char *
361 trio_duplicate_max TRIO_ARGS2((source, max),
362                               TRIO_CONST char *source,
363                               size_t max)
364 {
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 }
377 #endif /* !defined(TRIO_MINIMAL) */
378
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 */
389 TRIO_STRING_PUBLIC int
390 trio_equal
391 TRIO_ARGS2((first, second),
392            TRIO_CONST char *first,
393            TRIO_CONST char *second)
394 {
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         {
405           if (trio_to_upper(*first) != trio_to_upper(*second))
406             {
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 */
428 TRIO_STRING_PUBLIC int
429 trio_equal_case
430 TRIO_ARGS2((first, second),
431            TRIO_CONST char *first,
432            TRIO_CONST char *second)
433 {
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
445 #if !defined(TRIO_MINIMAL)
446 /**
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 */
456 TRIO_STRING_PUBLIC int
457 trio_equal_case_max
458 TRIO_ARGS3((first, max, second),
459            TRIO_CONST char *first,
460            size_t max,
461            TRIO_CONST char *second)
462 {
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 }
472 #endif /* !defined(TRIO_MINIMAL) */
473
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 */
484 TRIO_STRING_PUBLIC int
485 trio_equal_locale
486 TRIO_ARGS2((first, second),
487            TRIO_CONST char *first,
488            TRIO_CONST char *second)
489 {
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 */
511 TRIO_STRING_PUBLIC int
512 trio_equal_max
513 TRIO_ARGS3((first, max, second),
514            TRIO_CONST char *first,
515            size_t max,
516            TRIO_CONST char *second)
517 {
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         {
530           if (trio_to_upper(*first) != trio_to_upper(*second))
531             {
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 */
551 TRIO_STRING_PUBLIC TRIO_CONST char *
552 trio_error
553 TRIO_ARGS1((error_number),
554            int error_number)
555 {
556 #if defined(USE_STRERROR)
557   
558   return strerror(error_number);
559
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  
569 #else
570   
571   return "unknown";
572   
573 #endif
574 }
575
576
577 #if !defined(TRIO_MINIMAL)
578 /**
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 */
590 TRIO_STRING_PUBLIC size_t
591 trio_format_date_max
592 TRIO_ARGS4((target, max, format, datetime),
593            char *target,
594            size_t max,
595            TRIO_CONST char *format,
596            TRIO_CONST struct tm *datetime)
597 {
598   assert(target);
599   assert(format);
600   assert(datetime);
601   assert(max > 0);
602   
603   return strftime(target, max, format, datetime);
604 }
605 #endif /* !defined(TRIO_MINIMAL) */
606
607
608 #if !defined(TRIO_MINIMAL)
609 /**
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 */
619 TRIO_STRING_PUBLIC unsigned long
620 trio_hash
621 TRIO_ARGS2((string, type),
622            TRIO_CONST char *string,
623            int type)
624 {
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 }
645 #endif /* !defined(TRIO_MINIMAL) */
646
647
648 #if !defined(TRIO_MINIMAL)
649 /**
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  */
656 TRIO_STRING_PUBLIC char *
657 trio_index
658 TRIO_ARGS2((string, character),
659            TRIO_CONST char *string,
660            int character)
661 {
662   assert(string);
663
664   return strchr(string, character);
665 }
666 #endif /* !defined(TRIO_MINIMAL) */
667
668
669 #if !defined(TRIO_MINIMAL)
670 /**
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  */
677 TRIO_STRING_PUBLIC char *
678 trio_index_last
679 TRIO_ARGS2((string, character),
680            TRIO_CONST char *string,
681            int character)
682 {
683   assert(string);
684
685   return strchr(string, character);
686 }
687 #endif /* !defined(TRIO_MINIMAL) */
688
689
690 #if !defined(TRIO_MINIMAL)
691 /**
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 */
697 TRIO_STRING_PUBLIC int
698 trio_lower
699 TRIO_ARGS1((target),
700            char *target)
701 {
702   assert(target);
703
704   return trio_span_function(target, target, trio_to_lower);
705 }
706 #endif /* !defined(TRIO_MINIMAL) */
707
708
709 #if !defined(TRIO_MINIMAL)
710 /**
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 */
723 TRIO_STRING_PUBLIC int
724 trio_match
725 TRIO_ARGS2((string, pattern),
726            TRIO_CONST char *string,
727            TRIO_CONST char *pattern)
728 {
729   assert(string);
730   assert(pattern);
731   
732   for (; ('*' != *pattern); ++pattern, ++string)
733     {
734       if (NIL == *string)
735         {
736           return (NIL == *pattern);
737         }
738       if ((trio_to_upper((int)*string) != trio_to_upper((int)*pattern))
739           && ('?' != *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 }
759 #endif /* !defined(TRIO_MINIMAL) */
760
761
762 #if !defined(TRIO_MINIMAL)
763 /**
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 */
776 TRIO_STRING_PUBLIC int
777 trio_match_case
778 TRIO_ARGS2((string, pattern),
779            TRIO_CONST char *string,
780            TRIO_CONST char *pattern)
781 {
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 }
812 #endif /* !defined(TRIO_MINIMAL) */
813
814
815 #if !defined(TRIO_MINIMAL)
816 /**
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 */
824 TRIO_STRING_PUBLIC size_t
825 trio_span_function
826 TRIO_ARGS3((target, source, Function),
827            char *target,
828            TRIO_CONST char *source,
829            int (*Function) TRIO_PROTO((int)))
830 {
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 }
844 #endif /* !defined(TRIO_MINIMAL) */
845
846
847 #if !defined(TRIO_MINIMAL)
848 /**
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 */
856 TRIO_STRING_PUBLIC char *
857 trio_substring
858 TRIO_ARGS2((string, substring),
859            TRIO_CONST char *string,
860            TRIO_CONST char *substring)
861 {
862   assert(string);
863   assert(substring);
864
865   return strstr(string, substring);
866 }
867 #endif /* !defined(TRIO_MINIMAL) */
868
869
870 #if !defined(TRIO_MINIMAL)
871 /**
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 */
880 TRIO_STRING_PUBLIC char *
881 trio_substring_max
882 TRIO_ARGS3((string, max, substring),
883            TRIO_CONST char *string,
884            size_t max,
885            TRIO_CONST char *substring)
886 {
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 }
908 #endif /* !defined(TRIO_MINIMAL) */
909
910
911 #if !defined(TRIO_MINIMAL)
912 /**
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 */
921 TRIO_STRING_PUBLIC char *
922 trio_tokenize
923 TRIO_ARGS2((string, delimiters),
924            char *string,
925            TRIO_CONST char *delimiters)
926 {
927   assert(delimiters);
928   
929   return strtok(string, delimiters);
930 }
931 #endif /* !defined(TRIO_MINIMAL) */
932
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 */
956 TRIO_STRING_PUBLIC trio_long_double_t
957 trio_to_long_double
958 TRIO_ARGS2((source, endp),
959            TRIO_CONST char *source,
960            char **endp)
961 {
962 #if defined(USE_STRTOLD)
963   return strtold(source, endp);
964 #else
965   int isNegative = FALSE;
966   int isExponentNegative = FALSE;
967   trio_long_double_t integer = 0.0;
968   trio_long_double_t fraction = 0.0;
969   unsigned long exponent = 0;
970   trio_long_double_t base;
971   trio_long_double_t fracdiv = 1.0;
972   trio_long_double_t value = 0.0;
973
974   /* First try hex-floats */
975   if ((source[0] == '0') && ((source[1] == 'x') || (source[1] == 'X')))
976     {
977       base = 16.0;
978       source += 2;
979       while (isxdigit((int)*source))
980         {
981           integer *= base;
982           integer += (isdigit((int)*source)
983                       ? (*source - '0')
984                       : 10 + (trio_to_upper((int)*source) - 'A'));
985           source++;
986         }
987       if (*source == '.')
988         {
989           source++;
990           while (isxdigit((int)*source))
991             {
992               fracdiv /= base;
993               fraction += fracdiv * (isdigit((int)*source)
994                                      ? (*source - '0')
995                                      : 10 + (trio_to_upper((int)*source) - 'A'));
996               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                 {
1008                   exponent *= 10;
1009                   exponent += (*source - '0');
1010                   source++;
1011                 }
1012             }
1013         }
1014       /* For later use with exponent */
1015       base = 2.0;
1016     }
1017   else /* Then try normal decimal floats */
1018     {
1019       base = 10.0;
1020       isNegative = (*source == '-');
1021       /* Skip sign */
1022       if ((*source == '+') || (*source == '-'))
1023         source++;
1024
1025       /* Integer part */
1026       while (isdigit((int)*source))
1027         {
1028           integer *= base;
1029           integer += (*source - '0');
1030           source++;
1031         }
1032
1033       if (*source == '.')
1034         {
1035           source++; /* skip decimal point */
1036           while (isdigit((int)*source))
1037             {
1038               fracdiv /= base;
1039               fraction += (*source - '0') * fracdiv;
1040               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             {
1057               exponent *= (int)base;
1058               exponent += (*source - '0');
1059               source++;
1060             }
1061         }
1062     }
1063   
1064   value = integer + fraction;
1065   if (exponent != 0)
1066     {
1067       if (isExponentNegative)
1068         value /= pow(base, (double)exponent);
1069       else
1070         value *= pow(base, (double)exponent);
1071     }
1072   if (isNegative)
1073     value = -value;
1074
1075   if (endp)
1076     *endp = (char *)source;
1077   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
1089    See @ref trio_to_long_double.
1090 */
1091 TRIO_STRING_PUBLIC double
1092 trio_to_double
1093 TRIO_ARGS2((source, endp),
1094            TRIO_CONST char *source,
1095            char **endp)
1096 {
1097 #if defined(USE_STRTOD)
1098   return strtod(source, endp);
1099 #else
1100   return (double)trio_to_long_double(source, endp);
1101 #endif
1102 }
1103
1104 #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 */
1114 TRIO_STRING_PUBLIC float
1115 trio_to_float
1116 TRIO_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
1128
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 */
1136 TRIO_STRING_PUBLIC long
1137 trio_to_long
1138 TRIO_ARGS3((string, endp, base),
1139            TRIO_CONST char *string,
1140            char **endp,
1141            int base)
1142 {
1143   assert(string);
1144   assert((base >= 2) && (base <= 36));
1145   
1146   return strtol(string, endp, base);
1147 }
1148
1149
1150 #if !defined(TRIO_MINIMAL)
1151 /**
1152    Convert one alphabetic letter to lower-case.
1153
1154    @param source The letter to be converted.
1155    @return The converted letter.
1156 */
1157 TRIO_STRING_PUBLIC int
1158 trio_to_lower
1159 TRIO_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 /**
1179    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 */
1185 TRIO_STRING_PUBLIC unsigned long
1186 trio_to_unsigned_long
1187 TRIO_ARGS3((string, endp, base),
1188            TRIO_CONST char *string,
1189            char **endp,
1190            int base)
1191 {
1192   assert(string);
1193   assert((base >= 2) && (base <= 36));
1194   
1195   return strtoul(string, endp, base);
1196 }
1197 #endif /* !defined(TRIO_MINIMAL) */
1198
1199
1200 /**
1201    Convert one alphabetic letter to upper-case.
1202
1203    @param source The letter to be converted.
1204    @return The converted letter.
1205 */
1206 TRIO_STRING_PUBLIC int
1207 trio_to_upper
1208 TRIO_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
1225 #if !defined(TRIO_MINIMAL)
1226 /**
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 */
1232 TRIO_STRING_PUBLIC int
1233 trio_upper
1234 TRIO_ARGS1((target),
1235            char *target)
1236 {
1237   assert(target);
1238
1239   return trio_span_function(target, target, trio_to_upper);
1240 }
1241 #endif /* !defined(TRIO_MINIMAL) */
1242
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  */
1261 TRIO_STRING_PRIVATE trio_string_t *
1262 TrioStringAlloc(TRIO_NOARGS)
1263 {
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  */
1283 TRIO_STRING_PRIVATE BOOLEAN_T
1284 TrioStringGrow
1285 TRIO_ARGS2((self, delta),
1286            trio_string_t *self,
1287            size_t delta)
1288 {
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
1308 #if !defined(TRIO_MINIMAL)
1309 /*
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  */
1316 TRIO_STRING_PRIVATE BOOLEAN_T
1317 TrioStringGrowTo
1318 TRIO_ARGS2((self, length),
1319            trio_string_t *self,
1320            size_t length)
1321 {
1322   length++; /* Room for terminating zero */
1323   return (self->allocated < length)
1324     ? TrioStringGrow(self, length - self->allocated)
1325     : TRUE;
1326 }
1327 #endif /* !defined(TRIO_MINIMAL) */
1328
1329
1330 #if !defined(TRIO_MINIMAL)
1331 /**
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 */
1337 TRIO_STRING_PUBLIC trio_string_t *
1338 trio_string_create
1339 TRIO_ARGS1((initial_size),
1340            int initial_size)
1341 {
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 }
1361 #endif /* !defined(TRIO_MINIMAL) */
1362
1363
1364 /**
1365    Deallocate the dynamic string and its contents.
1366    
1367    @param self Dynamic string
1368 */
1369 TRIO_STRING_PUBLIC void
1370 trio_string_destroy
1371 TRIO_ARGS1((self),
1372            trio_string_t *self)
1373 {
1374   assert(self);
1375   
1376   if (self)
1377     {
1378       trio_destroy(self->content);
1379       TRIO_FREE(self);
1380     }
1381 }
1382
1383
1384 #if !defined(TRIO_MINIMAL)
1385 /**
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 */
1399 TRIO_STRING_PUBLIC char *
1400 trio_string_get
1401 TRIO_ARGS2((self, offset),
1402            trio_string_t *self,
1403            int offset)
1404 {
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         {
1417           if (offset > (int)self->length)
1418             {
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 }
1434 #endif /* !defined(TRIO_MINIMAL) */
1435
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 */
1446 TRIO_STRING_PUBLIC char *
1447 trio_string_extract
1448 TRIO_ARGS1((self),
1449            trio_string_t *self)
1450 {
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
1463 #if !defined(TRIO_MINIMAL)
1464 /**
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 */
1477 TRIO_STRING_PUBLIC void
1478 trio_xstring_set
1479 TRIO_ARGS2((self, buffer),
1480            trio_string_t *self,
1481            char *buffer)
1482 {
1483   assert(self);
1484
1485   trio_destroy(self->content);
1486   self->content = trio_duplicate(buffer);
1487 }
1488 #endif /* !defined(TRIO_MINIMAL) */
1489
1490
1491 /*
1492  * trio_string_size
1493  */
1494 TRIO_STRING_PUBLIC int
1495 trio_string_size
1496 TRIO_ARGS1((self),
1497            trio_string_t *self)
1498 {
1499   assert(self);
1500
1501   return self->allocated;
1502 }
1503
1504
1505 /*
1506  * trio_string_terminate
1507  */
1508 TRIO_STRING_PUBLIC void
1509 trio_string_terminate
1510 TRIO_ARGS1((self),
1511            trio_string_t *self)
1512 {
1513   trio_xstring_append_char(self, 0);
1514 }
1515
1516
1517 #if !defined(TRIO_MINIMAL)
1518 /**
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 */
1525 TRIO_STRING_PUBLIC int
1526 trio_string_append
1527 TRIO_ARGS2((self, other),
1528            trio_string_t *self,
1529            trio_string_t *other)
1530 {
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 }
1546 #endif /* !defined(TRIO_MINIMAL) */
1547
1548
1549 #if !defined(TRIO_MINIMAL)
1550 /*
1551  * trio_xstring_append
1552  */
1553 TRIO_STRING_PUBLIC int
1554 trio_xstring_append
1555 TRIO_ARGS2((self, other),
1556            trio_string_t *self,
1557            TRIO_CONST char *other)
1558 {
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 }
1574 #endif /* !defined(TRIO_MINIMAL) */
1575
1576
1577 /*
1578  * trio_xstring_append_char
1579  */
1580 TRIO_STRING_PUBLIC int
1581 trio_xstring_append_char
1582 TRIO_ARGS2((self, character),
1583            trio_string_t *self,
1584            char character)
1585 {
1586   assert(self);
1587
1588   if ((int)self->length >= trio_string_size(self))
1589     {
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
1602 #if !defined(TRIO_MINIMAL)
1603 /**
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 */
1610 TRIO_STRING_PUBLIC int
1611 trio_string_contains
1612 TRIO_ARGS2((self, other),
1613            trio_string_t *self,
1614            trio_string_t *other)
1615 {
1616   assert(self);
1617   assert(other);
1618
1619   return trio_contains(self->content, other->content);
1620 }
1621 #endif /* !defined(TRIO_MINIMAL) */
1622
1623
1624 #if !defined(TRIO_MINIMAL)
1625 /*
1626  * trio_xstring_contains
1627  */
1628 TRIO_STRING_PUBLIC int
1629 trio_xstring_contains
1630 TRIO_ARGS2((self, other),
1631            trio_string_t *self,
1632            TRIO_CONST char *other)
1633 {
1634   assert(self);
1635   assert(other);
1636
1637   return trio_contains(self->content, other);
1638 }
1639 #endif /* !defined(TRIO_MINIMAL) */
1640
1641
1642 #if !defined(TRIO_MINIMAL)
1643 /*
1644  * trio_string_copy
1645  */
1646 TRIO_STRING_PUBLIC int
1647 trio_string_copy
1648 TRIO_ARGS2((self, other),
1649            trio_string_t *self,
1650            trio_string_t *other)
1651 {
1652   assert(self);
1653   assert(other);
1654
1655   self->length = 0;
1656   return trio_string_append(self, other);
1657 }
1658 #endif /* !defined(TRIO_MINIMAL) */
1659
1660
1661 #if !defined(TRIO_MINIMAL)
1662 /*
1663  * trio_xstring_copy
1664  */
1665 TRIO_STRING_PUBLIC int
1666 trio_xstring_copy
1667 TRIO_ARGS2((self, other),
1668            trio_string_t *self,
1669            TRIO_CONST char *other)
1670 {
1671   assert(self);
1672   assert(other);
1673
1674   self->length = 0;
1675   return trio_xstring_append(self, other);
1676 }
1677 #endif /* !defined(TRIO_MINIMAL) */
1678
1679
1680 #if !defined(TRIO_MINIMAL)
1681 /*
1682  * trio_string_duplicate
1683  */
1684 TRIO_STRING_PUBLIC trio_string_t *
1685 trio_string_duplicate
1686 TRIO_ARGS1((other),
1687            trio_string_t *other)
1688 {
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 }
1709 #endif /* !defined(TRIO_MINIMAL) */
1710
1711
1712 /*
1713  * trio_xstring_duplicate
1714  */
1715 TRIO_STRING_PUBLIC trio_string_t *
1716 trio_xstring_duplicate
1717 TRIO_ARGS1((other),
1718            TRIO_CONST char *other)
1719 {
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
1742 #if !defined(TRIO_MINIMAL)
1743 /*
1744  * trio_string_equal
1745  */
1746 TRIO_STRING_PUBLIC int
1747 trio_string_equal
1748 TRIO_ARGS2((self, other),
1749            trio_string_t *self,
1750            trio_string_t *other)
1751 {
1752   assert(self);
1753   assert(other);
1754
1755   return trio_equal(self->content, other->content);
1756 }
1757 #endif /* !defined(TRIO_MINIMAL) */
1758
1759
1760 #if !defined(TRIO_MINIMAL)
1761 /*
1762  * trio_xstring_equal
1763  */
1764 TRIO_STRING_PUBLIC int
1765 trio_xstring_equal
1766 TRIO_ARGS2((self, other),
1767            trio_string_t *self,
1768            TRIO_CONST char *other)
1769 {
1770   assert(self);
1771   assert(other);
1772
1773   return trio_equal(self->content, other);
1774 }
1775 #endif /* !defined(TRIO_MINIMAL) */
1776
1777
1778 #if !defined(TRIO_MINIMAL)
1779 /*
1780  * trio_string_equal_max
1781  */
1782 TRIO_STRING_PUBLIC int
1783 trio_string_equal_max
1784 TRIO_ARGS3((self, max, other),
1785            trio_string_t *self,
1786            size_t max,
1787            trio_string_t *other)
1788 {
1789   assert(self);
1790   assert(other);
1791
1792   return trio_equal_max(self->content, max, other->content);
1793 }
1794 #endif /* !defined(TRIO_MINIMAL) */
1795
1796
1797 #if !defined(TRIO_MINIMAL)
1798 /*
1799  * trio_xstring_equal_max
1800  */
1801 TRIO_STRING_PUBLIC int
1802 trio_xstring_equal_max
1803 TRIO_ARGS3((self, max, other),
1804            trio_string_t *self,
1805            size_t max,
1806            TRIO_CONST char *other)
1807 {
1808   assert(self);
1809   assert(other);
1810
1811   return trio_equal_max(self->content, max, other);
1812 }
1813 #endif /* !defined(TRIO_MINIMAL) */
1814
1815
1816 #if !defined(TRIO_MINIMAL)
1817 /*
1818  * trio_string_equal_case
1819  */
1820 TRIO_STRING_PUBLIC int
1821 trio_string_equal_case
1822 TRIO_ARGS2((self, other),
1823            trio_string_t *self,
1824            trio_string_t *other)
1825 {
1826   assert(self);
1827   assert(other);
1828
1829   return trio_equal_case(self->content, other->content);
1830 }
1831 #endif /* !defined(TRIO_MINIMAL) */
1832
1833
1834 #if !defined(TRIO_MINIMAL)
1835 /*
1836  * trio_xstring_equal_case
1837  */
1838 TRIO_STRING_PUBLIC int
1839 trio_xstring_equal_case
1840 TRIO_ARGS2((self, other),
1841            trio_string_t *self,
1842            TRIO_CONST char *other)
1843 {
1844   assert(self);
1845   assert(other);
1846
1847   return trio_equal_case(self->content, other);
1848 }
1849 #endif /* !defined(TRIO_MINIMAL) */
1850
1851
1852 #if !defined(TRIO_MINIMAL)
1853 /*
1854  * trio_string_equal_case_max
1855  */
1856 TRIO_STRING_PUBLIC int
1857 trio_string_equal_case_max
1858 TRIO_ARGS3((self, max, other),
1859            trio_string_t *self,
1860            size_t max,
1861            trio_string_t *other)
1862 {
1863   assert(self);
1864   assert(other);
1865
1866   return trio_equal_case_max(self->content, max, other->content);
1867 }
1868 #endif /* !defined(TRIO_MINIMAL) */
1869
1870
1871 #if !defined(TRIO_MINIMAL)
1872 /*
1873  * trio_xstring_equal_case_max
1874  */
1875 TRIO_STRING_PUBLIC int
1876 trio_xstring_equal_case_max
1877 TRIO_ARGS3((self, max, other),
1878            trio_string_t *self,
1879            size_t max,
1880            TRIO_CONST char *other)
1881 {
1882   assert(self);
1883   assert(other);
1884
1885   return trio_equal_case_max(self->content, max, other);
1886 }
1887 #endif /* !defined(TRIO_MINIMAL) */
1888
1889
1890 #if !defined(TRIO_MINIMAL)
1891 /*
1892  * trio_string_format_data_max
1893  */
1894 TRIO_STRING_PUBLIC size_t
1895 trio_string_format_date_max
1896 TRIO_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)
1901 {
1902   assert(self);
1903
1904   return trio_format_date_max(self->content, max, format, datetime);
1905 }
1906 #endif /* !defined(TRIO_MINIMAL) */
1907
1908
1909 #if !defined(TRIO_MINIMAL)
1910 /*
1911  * trio_string_index
1912  */
1913 TRIO_STRING_PUBLIC char *
1914 trio_string_index
1915 TRIO_ARGS2((self, character),
1916            trio_string_t *self,
1917            int character)
1918 {
1919   assert(self);
1920
1921   return trio_index(self->content, character);
1922 }
1923 #endif /* !defined(TRIO_MINIMAL) */
1924
1925
1926 #if !defined(TRIO_MINIMAL)
1927 /*
1928  * trio_string_index_last
1929  */
1930 TRIO_STRING_PUBLIC char *
1931 trio_string_index_last
1932 TRIO_ARGS2((self, character),
1933            trio_string_t *self,
1934            int character)
1935 {
1936   assert(self);
1937
1938   return trio_index_last(self->content, character);
1939 }
1940 #endif /* !defined(TRIO_MINIMAL) */
1941
1942
1943 #if !defined(TRIO_MINIMAL)
1944 /*
1945  * trio_string_length
1946  */
1947 TRIO_STRING_PUBLIC int
1948 trio_string_length
1949 TRIO_ARGS1((self),
1950            trio_string_t *self)
1951 {
1952   assert(self);
1953
1954   if (self->length == 0)
1955     {
1956       self->length = trio_length(self->content);
1957     }
1958   return self->length;
1959 }
1960 #endif /* !defined(TRIO_MINIMAL) */
1961
1962
1963 #if !defined(TRIO_MINIMAL)
1964 /*
1965  * trio_string_lower
1966  */
1967 TRIO_STRING_PUBLIC int
1968 trio_string_lower
1969 TRIO_ARGS1((self),
1970            trio_string_t *self)
1971 {
1972   assert(self);
1973
1974   return trio_lower(self->content);
1975 }
1976 #endif /* !defined(TRIO_MINIMAL) */
1977
1978
1979 #if !defined(TRIO_MINIMAL)
1980 /*
1981  * trio_string_match
1982  */
1983 TRIO_STRING_PUBLIC int
1984 trio_string_match
1985 TRIO_ARGS2((self, other),
1986            trio_string_t *self,
1987            trio_string_t *other)
1988 {
1989   assert(self);
1990   assert(other);
1991
1992   return trio_match(self->content, other->content);
1993 }
1994 #endif /* !defined(TRIO_MINIMAL) */
1995
1996
1997 #if !defined(TRIO_MINIMAL)
1998 /*
1999  * trio_xstring_match
2000  */
2001 TRIO_STRING_PUBLIC int
2002 trio_xstring_match
2003 TRIO_ARGS2((self, other),
2004            trio_string_t *self,
2005            TRIO_CONST char *other)
2006 {
2007   assert(self);
2008   assert(other);
2009
2010   return trio_match(self->content, other);
2011 }
2012 #endif /* !defined(TRIO_MINIMAL) */
2013
2014
2015 #if !defined(TRIO_MINIMAL)
2016 /*
2017  * trio_string_match_case
2018  */
2019 TRIO_STRING_PUBLIC int
2020 trio_string_match_case
2021 TRIO_ARGS2((self, other),
2022            trio_string_t *self,
2023            trio_string_t *other)
2024 {
2025   assert(self);
2026   assert(other);
2027
2028   return trio_match_case(self->content, other->content);
2029 }
2030 #endif /* !defined(TRIO_MINIMAL) */
2031
2032
2033 #if !defined(TRIO_MINIMAL)
2034 /*
2035  * trio_xstring_match_case
2036  */
2037 TRIO_STRING_PUBLIC int
2038 trio_xstring_match_case
2039 TRIO_ARGS2((self, other),
2040            trio_string_t *self,
2041            TRIO_CONST char *other)
2042 {
2043   assert(self);
2044   assert(other);
2045
2046   return trio_match_case(self->content, other);
2047 }
2048 #endif /* !defined(TRIO_MINIMAL) */
2049
2050
2051 #if !defined(TRIO_MINIMAL)
2052 /*
2053  * trio_string_substring
2054  */
2055 TRIO_STRING_PUBLIC char *
2056 trio_string_substring
2057 TRIO_ARGS2((self, other),
2058            trio_string_t *self,
2059            trio_string_t *other)
2060 {
2061   assert(self);
2062   assert(other);
2063
2064   return trio_substring(self->content, other->content);
2065 }
2066 #endif /* !defined(TRIO_MINIMAL) */
2067
2068
2069 #if !defined(TRIO_MINIMAL)
2070 /*
2071  * trio_xstring_substring
2072  */
2073 TRIO_STRING_PUBLIC char *
2074 trio_xstring_substring
2075 TRIO_ARGS2((self, other),
2076            trio_string_t *self,
2077            TRIO_CONST char *other)
2078 {
2079   assert(self);
2080   assert(other);
2081
2082   return trio_substring(self->content, other);
2083 }
2084 #endif /* !defined(TRIO_MINIMAL) */
2085
2086
2087 #if !defined(TRIO_MINIMAL)
2088 /*
2089  * trio_string_upper
2090  */
2091 TRIO_STRING_PUBLIC int
2092 trio_string_upper
2093 TRIO_ARGS1((self),
2094            trio_string_t *self)
2095 {
2096   assert(self);
2097
2098   return trio_upper(self->content);
2099 }
2100 #endif /* !defined(TRIO_MINIMAL) */
2101
2102 /** @} End of DynamicStrings */