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