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 *
TrioStringAlloc(TRIO_NOARGS)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 */
2113