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