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