]> Pileus Git - ~andy/fetchmail/blobdiff - trio/triostr.c
Let distcheck call configure --with-ssl.
[~andy/fetchmail] / trio / triostr.c
index 199429e4510686f53e251caa4d6f46c3d1851d84..ce5cc74ef769f8c94b4302fe8257edf47692b554 100644 (file)
@@ -1,6 +1,6 @@
 /*************************************************************************
  *
- * $Id: triostr.c,v 1.19 2003/03/01 15:34:02 breese Exp $
+ * $Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $
  *
  * Copyright (C) 2001 Bjorn Reese and Daniel Stenberg.
  *
  * Include files
  */
 
+#if defined(HAVE_CONFIG_H)
+# include <config.h>
+#endif
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
-#include <math.h>
 #include "triodef.h"
 #include "triostr.h"
+#if defined(TRIO_FUNC_TO_LONG_DOUBLE)
+# define USE_MATH
+#endif
+#if defined(USE_MATH)
+# include <math.h>
+#endif
 
 /*************************************************************************
  * Definitions
  */
 
-#if !defined(TRIO_STRING_PUBLIC)
-# define TRIO_STRING_PUBLIC TRIO_PUBLIC
+#if !defined(TRIO_PUBLIC_STRING)
+# define TRIO_PUBLIC_STRING TRIO_PUBLIC
 #endif
-#if !defined(TRIO_STRING_PRIVATE)
-# define TRIO_STRING_PRIVATE TRIO_PRIVATE
+#if !defined(TRIO_PRIVATE_STRING)
+# define TRIO_PRIVATE_STRING TRIO_PRIVATE
 #endif
 
 #if !defined(NULL)
 # define BOOLEAN_T int
 #endif
 
-#if defined(TRIO_COMPILER_SUPPORTS_C99)
-# define USE_STRTOD
-# define USE_STRTOF
-#elif defined(TRIO_COMPILER_MSVC)
-# define USE_STRTOD
+#if defined(USE_MATH)
+# if defined(PREDEF_STANDARD_C99)
+#  if defined(TRIO_COMPILER_DECC)
+#   if (TRIO_COMPILER_DECC - 0 > 80000000)
+/*
+ * The OSF/1 runtime that comes with the DECC compiler does not support
+ * hexfloats conversion.
+ */
+#    define USE_STRTOD
+#    define USE_STRTOF
+#   endif
+#  else
+#   define USE_STRTOD
+#   define USE_STRTOF
+#  endif
+# else
+#  if defined(TRIO_COMPILER_VISUALC)
+#   define USE_STRTOD
+#  endif
+#endif
 #endif
 
 #if defined(TRIO_PLATFORM_UNIX)
-# define USE_STRCASECMP
-# define USE_STRNCASECMP
+# if defined(PREDEF_STANDARD_UNIX95)
+#  define USE_STRCASECMP
+#  define USE_STRNCASECMP
+# endif
 # if defined(TRIO_PLATFORM_SUNOS)
 #  define USE_SYS_ERRLIST
 # else
 #  define strcasecmp(x,y) stricmp(x,y)
 #  define strncasecmp(x,y,n) strnicmp(x,y,n)
 # endif
-#elif defined(TRIO_PLATFORM_WIN32)
+#endif
+
+#if defined(TRIO_PLATFORM_WIN32)
 # define USE_STRCASECMP
-# define strcasecmp(x,y) strcmpi(x,y)
+# if defined(TRIO_PLATFORM_WINCE)
+#  define strcasecmp(x,y) _stricmp(x,y)
+# else
+#  define strcasecmp(x,y) strcmpi(x,y)
+# endif
+#endif
+
+#if !defined(HAVE_CONFIG_H)
+# if !(defined(TRIO_PLATFORM_SUNOS))
+#  define HAVE_TOLOWER
+#  define HAVE_TOUPPER
+# endif
 #endif
 
-#if !(defined(TRIO_PLATFORM_SUNOS))
-# define USE_TOLOWER
-# define USE_TOUPPER
+#if defined(USE_MATH) && !defined(TRIO_NO_POWL)
+# if !defined(HAVE_POWL)
+#  if defined(PREDEF_STANDARD_C99) \
+   || defined(PREDEF_STANDARD_UNIX03)
+#   define HAVE_POWL
+#  else
+#   if defined(TRIO_COMPILER_VISUALC)
+#    if defined(powl)
+#     define HAVE_POWL
+#    endif
+#   endif
+#  endif
+# endif
+#endif
+
+#if defined(HAVE_POWL)
+# define trio_powl(x,y) powl((x),(y))
+#else
+# define trio_powl(x,y) pow((double)(x),(double)(y))
+#endif
+
+#if defined(TRIO_FUNC_TO_UPPER) \
+ || (defined(TRIO_FUNC_EQUAL) && !defined(USE_STRCASECMP)) \
+ || (defined(TRIO_FUNC_EQUAL_MAX) && !defined(USE_STRNCASECMP)) \
+ || defined(TRIO_FUNC_MATCH) \
+ || defined(TRIO_FUNC_TO_LONG_DOUBLE) \
+ || defined(TRIO_FUNC_UPPER)
+# define TRIO_FUNC_INTERNAL_TO_UPPER
 #endif
 
 /*************************************************************************
@@ -96,8 +159,8 @@ struct _trio_string_t
  * Constants
  */
 
-#if !defined(TRIO_MINIMAL)
-static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.19 2003/03/01 15:34:02 breese Exp $";
+#if !defined(TRIO_EMBED_STRING)
+static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.36 2010/01/26 13:02:02 breese Exp $";
 #endif
 
 /*************************************************************************
@@ -111,13 +174,155 @@ static TRIO_CONST char rcsid[] = "@(#)$Id: triostr.c,v 1.19 2003/03/01 15:34:02
     @{
 */
 
+/*
+ * internal_duplicate_max
+ */
+#if defined(TRIO_FUNC_DUPLICATE) \
+ || defined(TRIO_FUNC_DUPLICATE_MAX) \
+ || defined(TRIO_FUNC_STRING_DUPLICATE) \
+ || defined(TRIO_FUNC_XSTRING_DUPLICATE)
+
+TRIO_PRIVATE_STRING char *
+internal_duplicate_max
+TRIO_ARGS2((source, size),
+          TRIO_CONST char *source,
+          size_t size)
+{
+  char *target;
+
+  assert(source);
+
+  /* Make room for string plus a terminating zero */
+  size++;
+  target = trio_create(size);
+  if (target)
+    {
+      trio_copy_max(target, size, source);
+    }
+  return target;
+}
+
+#endif
+
+/*
+ * internal_string_alloc
+ */
+#if defined(TRIO_FUNC_STRING_CREATE) \
+ || defined(TRIO_FUNC_STRING_DUPLICATE) \
+ || defined(TRIO_FUNC_XSTRING_DUPLICATE)
+
+TRIO_PRIVATE_STRING trio_string_t *
+internal_string_alloc(TRIO_NOARGS)
+{
+  trio_string_t *self;
+
+  self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
+  if (self)
+    {
+      self->content = NULL;
+      self->length = 0;
+      self->allocated = 0;
+    }
+  return self;
+}
+
+#endif
+
+/*
+ * internal_string_grow
+ *
+ * The size of the string will be increased by 'delta' characters. If
+ * 'delta' is zero, the size will be doubled.
+ */
+#if defined(TRIO_FUNC_STRING_CREATE) \
+ || defined(TRIO_FUNC_STRING_APPEND) \
+ || defined(TRIO_FUNC_XSTRING_APPEND) \
+ || defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
+
+TRIO_PRIVATE_STRING BOOLEAN_T
+internal_string_grow
+TRIO_ARGS2((self, delta),
+          trio_string_t *self,
+          size_t delta)
+{
+  BOOLEAN_T status = FALSE;
+  char *new_content;
+  size_t new_size;
+
+  new_size = (delta == 0)
+    ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
+    : self->allocated + delta;
+
+  new_content = (char *)TRIO_REALLOC(self->content, new_size);
+  if (new_content)
+    {
+      self->content = new_content;
+      self->allocated = new_size;
+      status = TRUE;
+    }
+  return status;
+}
+
+#endif
+
+/*
+ * internal_string_grow_to
+ *
+ * The size of the string will be increased to 'length' plus one characters.
+ * If 'length' is less than the original size, the original size will be
+ * used (that is, the size of the string is never decreased).
+ */
+#if defined(TRIO_FUNC_STRING_APPEND) \
+ || defined(TRIO_FUNC_XSTRING_APPEND) \
+ || defined(TRIO_FUNC_XSTRING_APPEND_MAX)
+
+TRIO_PRIVATE_STRING BOOLEAN_T
+internal_string_grow_to
+TRIO_ARGS2((self, length),
+          trio_string_t *self,
+          size_t length)
+{
+  length++; /* Room for terminating zero */
+  return (self->allocated < length)
+    ? internal_string_grow(self, length - self->allocated)
+    : TRUE;
+}
+
+#endif
+
+#if defined(TRIO_FUNC_INTERNAL_TO_UPPER)
+
+TRIO_PRIVATE_STRING TRIO_INLINE int
+internal_to_upper
+TRIO_ARGS1((source),
+          int source)
+{
+# if defined(HAVE_TOUPPER)
+
+  return toupper(source);
+
+# else
+
+  /* Does not handle locales or non-contiguous alphabetic characters */
+  return ((source >= (int)'a') && (source <= (int)'z'))
+    ? source - 'a' + 'A'
+    : source;
+
+# endif
+}
+
+#endif
+
+
 /**
    Create new string.
 
    @param size Size of new string.
    @return Pointer to string, or NULL if allocation failed.
 */
-TRIO_STRING_PUBLIC char *
+#if defined(TRIO_FUNC_CREATE)
+
+TRIO_PUBLIC_STRING char *
 trio_create
 TRIO_ARGS1((size),
           size_t size)
@@ -125,13 +330,16 @@ TRIO_ARGS1((size),
   return (char *)TRIO_MALLOC(size);
 }
 
+#endif
 
 /**
    Destroy string.
 
    @param string String to be freed.
 */
-TRIO_STRING_PUBLIC void
+#if defined(TRIO_FUNC_DESTROY)
+
+TRIO_PUBLIC_STRING void
 trio_destroy
 TRIO_ARGS1((string),
           char *string)
@@ -142,14 +350,17 @@ TRIO_ARGS1((string),
     }
 }
 
+#endif
 
 /**
    Count the number of characters in a string.
 
    @param string String to measure.
-   @return Number of characters in @string.
+   @return Number of characters in @string.
 */
-TRIO_STRING_PUBLIC size_t
+#if defined(TRIO_FUNC_LENGTH)
+
+TRIO_PUBLIC_STRING size_t
 trio_length
 TRIO_ARGS1((string),
           TRIO_CONST char *string)
@@ -157,22 +368,51 @@ TRIO_ARGS1((string),
   return strlen(string);
 }
 
+#endif
+
+/**
+   Count at most @p max characters in a string.
+
+   @param string String to measure.
+   @param max Maximum number of characters to count.
+   @return The maximum value of @p max and number of characters in @p string.
+*/
+#if defined(TRIO_FUNC_LENGTH_MAX)
+
+TRIO_PUBLIC_STRING size_t
+trio_length_max
+TRIO_ARGS2((string, max),
+          TRIO_CONST char *string,
+          size_t max)
+{
+  size_t i;
+
+  for (i = 0; i < max; ++i)
+    {
+      if (string[i] == 0)
+       break;
+    }
+  return i;
+}
+
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Append @p source at the end of @p target.
-   
+
    @param target Target string.
    @param source Source string.
    @return Boolean value indicating success or failure.
-   
+
    @pre @p target must point to a memory chunk with sufficient room to
    contain the @p target string and @p source string.
    @pre No boundary checking is performed, so insufficient memory will
    result in a buffer overrun.
    @post @p target will be zero terminated.
 */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_APPEND)
+
+TRIO_PUBLIC_STRING int
 trio_append
 TRIO_ARGS2((target, source),
           char *target,
@@ -180,20 +420,20 @@ TRIO_ARGS2((target, source),
 {
   assert(target);
   assert(source);
-  
+
   return (strcat(target, source) != NULL);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
-#if !defined(TRIO_MINIMAL)
+#endif
+
 /**
    Append at most @p max characters from @p source to @p target.
-   
+
    @param target Target string.
    @param max Maximum number of characters to append.
    @param source Source string.
    @return Boolean value indicating success or failure.
-   
+
    @pre @p target must point to a memory chuck with sufficient room to
    contain the @p target string and the @p source string (at most @p max
    characters).
@@ -201,7 +441,9 @@ TRIO_ARGS2((target, source),
    result in a buffer overrun.
    @post @p target will be zero terminated.
 */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_APPEND_MAX)
+
+TRIO_PUBLIC_STRING int
 trio_append_max
 TRIO_ARGS3((target, max, source),
           char *target,
@@ -209,22 +451,21 @@ TRIO_ARGS3((target, max, source),
           TRIO_CONST char *source)
 {
   size_t length;
-  
+
   assert(target);
   assert(source);
 
   length = trio_length(target);
-  
+
   if (max > length)
     {
       strncat(target, source, max - length - 1);
     }
   return TRUE;
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Determine if a string contains a substring.
 
@@ -232,7 +473,9 @@ TRIO_ARGS3((target, max, source),
    @param substring String to be found.
    @return Boolean value indicating success or failure.
 */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_CONTAINS)
+
+TRIO_PUBLIC_STRING int
 trio_contains
 TRIO_ARGS2((string, substring),
           TRIO_CONST char *string,
@@ -240,27 +483,28 @@ TRIO_ARGS2((string, substring),
 {
   assert(string);
   assert(substring);
-  
+
   return (0 != strstr(string, substring));
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Copy @p source to @p target.
-   
+
    @param target Target string.
    @param source Source string.
    @return Boolean value indicating success or failure.
-   
+
    @pre @p target must point to a memory chunk with sufficient room to
    contain the @p source string.
    @pre No boundary checking is performed, so insufficient memory will
    result in a buffer overrun.
    @post @p target will be zero terminated.
 */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_COPY)
+
+TRIO_PUBLIC_STRING int
 trio_copy
 TRIO_ARGS2((target, source),
           char *target,
@@ -268,28 +512,34 @@ TRIO_ARGS2((target, source),
 {
   assert(target);
   assert(source);
-     
+
   (void)strcpy(target, source);
   return TRUE;
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
 /**
-   Copy at most @p max characters from @p source to @p target.
-   
+   Copy at most @p max - 1 characters from @p source to @p target.
+
    @param target Target string.
-   @param max Maximum number of characters to append.
+   @param max Maximum number of characters to append (one of which is
+   a NUL terminator).  In other words @p source must point to at least
+   @p max - 1 bytes, but @p target must point to at least @p max
+   bytes.
    @param source Source string.
    @return Boolean value indicating success or failure.
-   
+
    @pre @p target must point to a memory chunk with sufficient room to
-   contain the @p source string (at most @p max characters).
+   contain the @p source string and a NUL terminator (at most @p max
+   bytes total).
    @pre No boundary checking is performed, so insufficient memory will
    result in a buffer overrun.
    @post @p target will be zero terminated.
 */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_COPY_MAX)
+
+TRIO_PUBLIC_STRING int
 trio_copy_max
 TRIO_ARGS3((target, max, source),
           char *target,
@@ -305,62 +555,44 @@ TRIO_ARGS3((target, max, source),
   return TRUE;
 }
 
-
-/*
- * TrioDuplicateMax
- */
-TRIO_STRING_PRIVATE char *
-TrioDuplicateMax
-TRIO_ARGS2((source, size),
-          TRIO_CONST char *source,
-          size_t size)
-{
-  char *target;
-
-  assert(source);
-
-  /* Make room for string plus a terminating zero */
-  size++;
-  target = trio_create(size);
-  if (target)
-    {
-      trio_copy_max(target, size, source);
-    }
-  return target;
-}
-
+#endif
 
 /**
    Duplicate @p source.
-   
+
    @param source Source string.
    @return A copy of the @p source string.
-   
+
    @post @p target will be zero terminated.
 */
-TRIO_STRING_PUBLIC char *
+#if defined(TRIO_FUNC_DUPLICATE)
+
+TRIO_PUBLIC_STRING char *
 trio_duplicate
 TRIO_ARGS1((source),
           TRIO_CONST char *source)
 {
-  return TrioDuplicateMax(source, trio_length(source));
+  return internal_duplicate_max(source, trio_length(source));
 }
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Duplicate at most @p max characters of @p source.
-   
+
    @param source Source string.
    @param max Maximum number of characters to duplicate.
    @return A copy of the @p source string.
-   
+
    @post @p target will be zero terminated.
 */
-TRIO_STRING_PUBLIC char *
-trio_duplicate_max TRIO_ARGS2((source, max),
-                             TRIO_CONST char *source,
-                             size_t max)
+#if defined(TRIO_FUNC_DUPLICATE_MAX)
+
+TRIO_PUBLIC_STRING char *
+trio_duplicate_max
+TRIO_ARGS2((source, max),
+          TRIO_CONST char *source,
+          size_t max)
 {
   size_t length;
 
@@ -372,21 +604,23 @@ trio_duplicate_max TRIO_ARGS2((source, max),
     {
       length = max;
     }
-  return TrioDuplicateMax(source, length);
+  return internal_duplicate_max(source, length);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
 /**
    Compare if two strings are equal.
-   
+
    @param first First string.
    @param second Second string.
    @return Boolean indicating whether the two strings are equal or not.
-   
+
    Case-insensitive comparison.
 */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_EQUAL)
+
+TRIO_PUBLIC_STRING int
 trio_equal
 TRIO_ARGS2((first, second),
           TRIO_CONST char *first,
@@ -397,12 +631,12 @@ TRIO_ARGS2((first, second),
 
   if ((first != NULL) && (second != NULL))
     {
-#if defined(USE_STRCASECMP)
+# if defined(USE_STRCASECMP)
       return (0 == strcasecmp(first, second));
-#else
+# else
       while ((*first != NIL) && (*second != NIL))
        {
-         if (trio_to_upper(*first) != trio_to_upper(*second))
+         if (internal_to_upper(*first) != internal_to_upper(*second))
            {
              break;
            }
@@ -410,22 +644,25 @@ TRIO_ARGS2((first, second),
          second++;
        }
       return ((*first == NIL) && (*second == NIL));
-#endif
+# endif
     }
   return FALSE;
 }
 
+#endif
 
 /**
    Compare if two strings are equal.
-   
+
    @param first First string.
    @param second Second string.
    @return Boolean indicating whether the two strings are equal or not.
-   
+
    Case-sensitive comparison.
 */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_EQUAL_CASE)
+
+TRIO_PUBLIC_STRING int
 trio_equal_case
 TRIO_ARGS2((first, second),
           TRIO_CONST char *first,
@@ -441,19 +678,21 @@ TRIO_ARGS2((first, second),
   return FALSE;
 }
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Compare if two strings up until the first @p max characters are equal.
-   
+
    @param first First string.
    @param max Maximum number of characters to compare.
    @param second Second string.
    @return Boolean indicating whether the two strings are equal or not.
-   
+
    Case-sensitive comparison.
 */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_EQUAL_CASE_MAX)
+
+TRIO_PUBLIC_STRING int
 trio_equal_case_max
 TRIO_ARGS3((first, max, second),
           TRIO_CONST char *first,
@@ -469,19 +708,21 @@ TRIO_ARGS3((first, max, second),
     }
   return FALSE;
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
 /**
    Compare if two strings are equal.
-   
+
    @param first First string.
    @param second Second string.
    @return Boolean indicating whether the two strings are equal or not.
 
    Collating characters are considered equal.
 */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_EQUAL_LOCALE)
+
+TRIO_PUBLIC_STRING int
 trio_equal_locale
 TRIO_ARGS2((first, second),
           TRIO_CONST char *first,
@@ -490,25 +731,28 @@ TRIO_ARGS2((first, second),
   assert(first);
   assert(second);
 
-#if defined(LC_COLLATE)
+# if defined(LC_COLLATE)
   return (strcoll(first, second) == 0);
-#else
+# else
   return trio_equal(first, second);
-#endif
+# endif
 }
 
+#endif
 
 /**
    Compare if two strings up until the first @p max characters are equal.
-   
+
    @param first First string.
    @param max Maximum number of characters to compare.
    @param second Second string.
    @return Boolean indicating whether the two strings are equal or not.
-   
+
    Case-insensitive comparison.
 */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_EQUAL_MAX)
+
+TRIO_PUBLIC_STRING int
 trio_equal_max
 TRIO_ARGS3((first, max, second),
           TRIO_CONST char *first,
@@ -520,14 +764,14 @@ TRIO_ARGS3((first, max, second),
 
   if ((first != NULL) && (second != NULL))
     {
-#if defined(USE_STRNCASECMP)
+# if defined(USE_STRNCASECMP)
       return (0 == strncasecmp(first, second, max));
-#else
+# else
       /* Not adequately tested yet */
       size_t cnt = 0;
       while ((*first != NIL) && (*second != NIL) && (cnt <= max))
        {
-         if (trio_to_upper(*first) != trio_to_upper(*second))
+         if (internal_to_upper(*first) != internal_to_upper(*second))
            {
              break;
            }
@@ -536,11 +780,12 @@ TRIO_ARGS3((first, max, second),
          cnt++;
        }
       return ((cnt == max) || ((*first == NIL) && (*second == NIL)));
-#endif
+# endif
     }
   return FALSE;
 }
 
+#endif
 
 /**
    Provide a textual description of an error code (errno).
@@ -548,16 +793,19 @@ TRIO_ARGS3((first, max, second),
    @param error_number Error number.
    @return Textual description of @p error_number.
 */
-TRIO_STRING_PUBLIC TRIO_CONST char *
+#if defined(TRIO_FUNC_ERROR)
+
+TRIO_PUBLIC_STRING TRIO_CONST char *
 trio_error
 TRIO_ARGS1((error_number),
           int error_number)
 {
-#if defined(USE_STRERROR)
-  
+# if defined(USE_STRERROR)
+
   return strerror(error_number);
 
-#elif defined(USE_SYS_ERRLIST)
+# else
+#  if defined(USE_SYS_ERRLIST)
 
   extern char *sys_errlist[];
   extern int sys_nerr;
@@ -565,16 +813,17 @@ TRIO_ARGS1((error_number),
   return ((error_number < 0) || (error_number >= sys_nerr))
     ? "unknown"
     : sys_errlist[error_number];
-#else
-  
+
+#  else
+
   return "unknown";
-  
-#endif
+
+#  endif
+# endif
 }
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Format the date/time according to @p format.
 
@@ -587,7 +836,9 @@ TRIO_ARGS1((error_number),
    The formatting string accepts the same specifiers as the standard C
    function strftime.
 */
-TRIO_STRING_PUBLIC size_t
+#if defined(TRIO_FUNC_FORMAT_DATE_MAX)
+
+TRIO_PUBLIC_STRING size_t
 trio_format_date_max
 TRIO_ARGS4((target, max, format, datetime),
           char *target,
@@ -599,13 +850,12 @@ TRIO_ARGS4((target, max, format, datetime),
   assert(format);
   assert(datetime);
   assert(max > 0);
-  
+
   return strftime(target, max, format, datetime);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Calculate a hash value for a string.
 
@@ -616,7 +866,9 @@ TRIO_ARGS4((target, max, format, datetime),
    @p type can be one of the following
    @li @c TRIO_HASH_PLAIN Plain hash function.
 */
-TRIO_STRING_PUBLIC unsigned long
+#if defined(TRIO_FUNC_HASH)
+
+TRIO_PUBLIC_STRING unsigned long
 trio_hash
 TRIO_ARGS2((string, type),
           TRIO_CONST char *string,
@@ -626,7 +878,7 @@ TRIO_ARGS2((string, type),
   char ch;
 
   assert(string);
-  
+
   switch (type)
     {
     case TRIO_HASH_PLAIN:
@@ -642,18 +894,19 @@ TRIO_ARGS2((string, type),
     }
   return value;
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Find first occurrence of a character in a string.
 
    @param string String to be searched.
    @param character Character to be found.
-   @param A pointer to the found character, or NULL if character was not found.
+   @return A pointer to the found character, or NULL if character was not found.
  */
-TRIO_STRING_PUBLIC char *
+#if defined(TRIO_FUNC_INDEX)
+
+TRIO_PUBLIC_STRING char *
 trio_index
 TRIO_ARGS2((string, character),
           TRIO_CONST char *string,
@@ -663,18 +916,19 @@ TRIO_ARGS2((string, character),
 
   return strchr(string, character);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Find last occurrence of a character in a string.
 
    @param string String to be searched.
    @param character Character to be found.
-   @param A pointer to the found character, or NULL if character was not found.
+   @return A pointer to the found character, or NULL if character was not found.
  */
-TRIO_STRING_PUBLIC char *
+#if defined(TRIO_FUNC_INDEX_LAST)
+
+TRIO_PUBLIC_STRING char *
 trio_index_last
 TRIO_ARGS2((string, character),
           TRIO_CONST char *string,
@@ -684,17 +938,18 @@ TRIO_ARGS2((string, character),
 
   return strchr(string, character);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Convert the alphabetic letters in the string to lower-case.
 
    @param target String to be converted.
    @return Number of processed characters (converted or not).
 */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_LOWER)
+
+TRIO_PUBLIC_STRING int
 trio_lower
 TRIO_ARGS1((target),
           char *target)
@@ -703,10 +958,9 @@ TRIO_ARGS1((target),
 
   return trio_span_function(target, target, trio_to_lower);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Compare two strings using wildcards.
 
@@ -715,12 +969,14 @@ TRIO_ARGS1((target),
    @return Boolean value indicating success or failure.
 
    Case-insensitive comparison.
-   
+
    The following wildcards can be used
    @li @c * Match any number of characters.
    @li @c ? Match a single character.
 */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_MATCH)
+
+TRIO_PUBLIC_STRING int
 trio_match
 TRIO_ARGS2((string, pattern),
           TRIO_CONST char *string,
@@ -728,14 +984,14 @@ TRIO_ARGS2((string, pattern),
 {
   assert(string);
   assert(pattern);
-  
+
   for (; ('*' != *pattern); ++pattern, ++string)
     {
       if (NIL == *string)
        {
          return (NIL == *pattern);
        }
-      if ((trio_to_upper((int)*string) != trio_to_upper((int)*pattern))
+      if ((internal_to_upper((int)*string) != internal_to_upper((int)*pattern))
          && ('?' != *pattern))
        {
          return FALSE;
@@ -753,13 +1009,12 @@ TRIO_ARGS2((string, pattern),
        }
     }
   while (*string++);
-  
+
   return FALSE;
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Compare two strings using wildcards.
 
@@ -768,12 +1023,14 @@ TRIO_ARGS2((string, pattern),
    @return Boolean value indicating success or failure.
 
    Case-sensitive comparison.
-   
+
    The following wildcards can be used
    @li @c * Match any number of characters.
    @li @c ? Match a single character.
 */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_MATCH_CASE)
+
+TRIO_PUBLIC_STRING int
 trio_match_case
 TRIO_ARGS2((string, pattern),
           TRIO_CONST char *string,
@@ -781,7 +1038,7 @@ TRIO_ARGS2((string, pattern),
 {
   assert(string);
   assert(pattern);
-  
+
   for (; ('*' != *pattern); ++pattern, ++string)
     {
       if (NIL == *string)
@@ -806,13 +1063,12 @@ TRIO_ARGS2((string, pattern),
        }
     }
   while (*string++);
-  
+
   return FALSE;
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Execute a function on each character in string.
 
@@ -821,7 +1077,9 @@ TRIO_ARGS2((string, pattern),
    @param Function Function to be executed.
    @return Number of processed characters.
 */
-TRIO_STRING_PUBLIC size_t
+#if defined(TRIO_FUNC_SPAN_FUNCTION)
+
+TRIO_PUBLIC_STRING size_t
 trio_span_function
 TRIO_ARGS3((target, source, Function),
           char *target,
@@ -833,7 +1091,7 @@ TRIO_ARGS3((target, source, Function),
   assert(target);
   assert(source);
   assert(Function);
-  
+
   while (*source != NIL)
     {
       *target++ = Function(*source++);
@@ -841,10 +1099,9 @@ TRIO_ARGS3((target, source, Function),
     }
   return count;
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Search for a substring in a string.
 
@@ -853,7 +1110,9 @@ TRIO_ARGS3((target, source, Function),
    @return Pointer to first occurrence of @p substring in @p string, or NULL
    if no match was found.
 */
-TRIO_STRING_PUBLIC char *
+#if defined(TRIO_FUNC_SUBSTRING)
+
+TRIO_PUBLIC_STRING char *
 trio_substring
 TRIO_ARGS2((string, substring),
           TRIO_CONST char *string,
@@ -864,10 +1123,9 @@ TRIO_ARGS2((string, substring),
 
   return strstr(string, substring);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Search for a substring in the first @p max characters of a string.
 
@@ -877,7 +1135,9 @@ TRIO_ARGS2((string, substring),
    @return Pointer to first occurrence of @p substring in @p string, or NULL
    if no match was found.
 */
-TRIO_STRING_PUBLIC char *
+#if defined(TRIO_FUNC_SUBSTRING_MAX)
+
+TRIO_PUBLIC_STRING char *
 trio_substring_max
 TRIO_ARGS3((string, max, substring),
           TRIO_CONST char *string,
@@ -890,7 +1150,7 @@ TRIO_ARGS3((string, max, substring),
 
   assert(string);
   assert(substring);
-  
+
   size = trio_length(substring);
   if (size <= max)
     {
@@ -905,31 +1165,32 @@ TRIO_ARGS3((string, max, substring),
     }
   return result;
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Tokenize string.
 
    @param string String to be tokenized.
-   @param tokens String containing list of delimiting characters.
+   @param delimiters String containing list of delimiting characters.
    @return Start of new token.
 
    @warning @p string will be destroyed.
 */
-TRIO_STRING_PUBLIC char *
+#if defined(TRIO_FUNC_TOKENIZE)
+
+TRIO_PUBLIC_STRING char *
 trio_tokenize
 TRIO_ARGS2((string, delimiters),
           char *string,
           TRIO_CONST char *delimiters)
 {
   assert(delimiters);
-  
+
   return strtok(string, delimiters);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
 /**
    Convert string to floating-point number.
@@ -952,16 +1213,18 @@ TRIO_ARGS2((string, delimiters),
    decimal_point ::= '.'
    @endverbatim
 */
+#if defined(TRIO_FUNC_TO_LONG_DOUBLE)
+
 /* FIXME: Add EBNF for hex-floats */
-TRIO_STRING_PUBLIC trio_long_double_t
+TRIO_PUBLIC_STRING trio_long_double_t
 trio_to_long_double
 TRIO_ARGS2((source, endp),
           TRIO_CONST char *source,
           char **endp)
 {
-#if defined(USE_STRTOLD)
+# if defined(USE_STRTOLD)
   return strtold(source, endp);
-#else
+# else
   int isNegative = FALSE;
   int isExponentNegative = FALSE;
   trio_long_double_t integer = 0.0;
@@ -981,7 +1244,7 @@ TRIO_ARGS2((source, endp),
          integer *= base;
          integer += (isdigit((int)*source)
                      ? (*source - '0')
-                     : 10 + (trio_to_upper((int)*source) - 'A'));
+                     : 10 + (internal_to_upper((int)*source) - 'A'));
          source++;
        }
       if (*source == '.')
@@ -992,7 +1255,7 @@ TRIO_ARGS2((source, endp),
              fracdiv /= base;
              fraction += fracdiv * (isdigit((int)*source)
                                     ? (*source - '0')
-                                    : 10 + (trio_to_upper((int)*source) - 'A'));
+                                    : 10 + (internal_to_upper((int)*source) - 'A'));
              source++;
            }
          if ((*source == 'p') || (*source == 'P'))
@@ -1042,10 +1305,10 @@ TRIO_ARGS2((source, endp),
        }
       if ((*source == 'e')
          || (*source == 'E')
-#if TRIO_MICROSOFT
+#  if TRIO_MICROSOFT
          || (*source == 'd')
          || (*source == 'D')
-#endif
+#  endif
          )
        {
          source++; /* Skip exponential indicator */
@@ -1060,14 +1323,14 @@ TRIO_ARGS2((source, endp),
            }
        }
     }
-  
+
   value = integer + fraction;
   if (exponent != 0)
     {
       if (isExponentNegative)
-       value /= pow(base, (double)exponent);
+       value /= trio_powl(base, (trio_long_double_t)exponent);
       else
-       value *= pow(base, (double)exponent);
+       value *= trio_powl(base, (trio_long_double_t)exponent);
     }
   if (isNegative)
     value = -value;
@@ -1075,9 +1338,10 @@ TRIO_ARGS2((source, endp),
   if (endp)
     *endp = (char *)source;
   return value;
-#endif
+# endif
 }
 
+#endif
 
 /**
    Convert string to floating-point number.
@@ -1088,7 +1352,9 @@ TRIO_ARGS2((source, endp),
 
    See @ref trio_to_long_double.
 */
-TRIO_STRING_PUBLIC double
+#if defined(TRIO_FUNC_TO_DOUBLE)
+
+TRIO_PUBLIC_STRING double
 trio_to_double
 TRIO_ARGS2((source, endp),
           TRIO_CONST char *source,
@@ -1101,7 +1367,8 @@ TRIO_ARGS2((source, endp),
 #endif
 }
 
-#if !defined(TRIO_MINIMAL)
+#endif
+
 /**
    Convert string to floating-point number.
 
@@ -1111,20 +1378,22 @@ TRIO_ARGS2((source, endp),
 
    See @ref trio_to_long_double.
 */
-TRIO_STRING_PUBLIC float
+#if defined(TRIO_FUNC_TO_FLOAT)
+
+TRIO_PUBLIC_STRING float
 trio_to_float
 TRIO_ARGS2((source, endp),
           TRIO_CONST char *source,
           char **endp)
 {
-#if defined(USE_STRTOF)
+#  if defined(USE_STRTOF)
   return strtof(source, endp);
-#else
+#  else
   return (float)trio_to_long_double(source, endp);
-#endif
+#  endif
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
 /**
    Convert string to signed integer.
@@ -1133,7 +1402,9 @@ TRIO_ARGS2((source, endp),
    @param endp Pointer to end of converted string.
    @param base Radix number of number.
 */
-TRIO_STRING_PUBLIC long
+#if defined(TRIO_FUNC_TO_LONG)
+
+TRIO_PUBLIC_STRING long
 trio_to_long
 TRIO_ARGS3((string, endp, base),
           TRIO_CONST char *string,
@@ -1142,39 +1413,41 @@ TRIO_ARGS3((string, endp, base),
 {
   assert(string);
   assert((base >= 2) && (base <= 36));
-  
+
   return strtol(string, endp, base);
 }
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Convert one alphabetic letter to lower-case.
 
    @param source The letter to be converted.
    @return The converted letter.
 */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_TO_LOWER)
+
+TRIO_PUBLIC_STRING int
 trio_to_lower
 TRIO_ARGS1((source),
           int source)
 {
-#if defined(USE_TOLOWER)
-  
+# if defined(HAVE_TOLOWER)
+
   return tolower(source);
-  
-#else
+
+# else
 
   /* Does not handle locales or non-contiguous alphabetic characters */
   return ((source >= (int)'A') && (source <= (int)'Z'))
     ? source - 'A' + 'a'
     : source;
-  
-#endif
+
+# endif
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
-#if !defined(TRIO_MINIMAL)
+#endif
+
 /**
    Convert string to unsigned integer.
 
@@ -1182,7 +1455,9 @@ TRIO_ARGS1((source),
    @param endp Pointer to end of converted string.
    @param base Radix number of number.
 */
-TRIO_STRING_PUBLIC unsigned long
+#if defined(TRIO_FUNC_TO_UNSIGNED_LONG)
+
+TRIO_PUBLIC_STRING unsigned long
 trio_to_unsigned_long
 TRIO_ARGS3((string, endp, base),
           TRIO_CONST char *string,
@@ -1191,11 +1466,11 @@ TRIO_ARGS3((string, endp, base),
 {
   assert(string);
   assert((base >= 2) && (base <= 36));
-  
+
   return strtoul(string, endp, base);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
 /**
    Convert one alphabetic letter to upper-case.
@@ -1203,43 +1478,37 @@ TRIO_ARGS3((string, endp, base),
    @param source The letter to be converted.
    @return The converted letter.
 */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_TO_UPPER)
+
+TRIO_PUBLIC_STRING int
 trio_to_upper
 TRIO_ARGS1((source),
           int source)
 {
-#if defined(USE_TOUPPER)
-  
-  return toupper(source);
-  
-#else
+  return internal_to_upper(source);
+}
 
-  /* Does not handle locales or non-contiguous alphabetic characters */
-  return ((source >= (int)'a') && (source <= (int)'z'))
-    ? source - 'a' + 'A'
-    : source;
-  
 #endif
-}
 
-#if !defined(TRIO_MINIMAL)
 /**
    Convert the alphabetic letters in the string to upper-case.
 
    @param target The string to be converted.
    @return The number of processed characters (converted or not).
 */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_UPPER)
+
+TRIO_PUBLIC_STRING int
 trio_upper
 TRIO_ARGS1((target),
           char *target)
 {
   assert(target);
 
-  return trio_span_function(target, target, trio_to_upper);
+  return trio_span_function(target, target, internal_to_upper);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
 /** @} End of StaticStrings */
 
@@ -1255,96 +1524,25 @@ TRIO_ARGS1((target),
     @{
 */
 
-/*
- * TrioStringAlloc
- */
-TRIO_STRING_PRIVATE trio_string_t *
-TrioStringAlloc(TRIO_NOARGS)
-{
-  trio_string_t *self;
-  
-  self = (trio_string_t *)TRIO_MALLOC(sizeof(trio_string_t));
-  if (self)
-    {
-      self->content = NULL;
-      self->length = 0;
-      self->allocated = 0;
-    }
-  return self;
-}
-
-
-/*
- * TrioStringGrow
- *
- * The size of the string will be increased by 'delta' characters. If
- * 'delta' is zero, the size will be doubled.
- */
-TRIO_STRING_PRIVATE BOOLEAN_T
-TrioStringGrow
-TRIO_ARGS2((self, delta),
-          trio_string_t *self,
-          size_t delta)
-{
-  BOOLEAN_T status = FALSE;
-  char *new_content;
-  size_t new_size;
-
-  new_size = (delta == 0)
-    ? ( (self->allocated == 0) ? 1 : self->allocated * 2 )
-    : self->allocated + delta;
-  
-  new_content = (char *)TRIO_REALLOC(self->content, new_size);
-  if (new_content)
-    {
-      self->content = new_content;
-      self->allocated = new_size;
-      status = TRUE;
-    }
-  return status;
-}
-
-
-#if !defined(TRIO_MINIMAL)
-/*
- * TrioStringGrowTo
- *
- * The size of the string will be increased to 'length' plus one characters.
- * If 'length' is less than the original size, the original size will be
- * used (that is, the size of the string is never decreased).
- */
-TRIO_STRING_PRIVATE BOOLEAN_T
-TrioStringGrowTo
-TRIO_ARGS2((self, length),
-          trio_string_t *self,
-          size_t length)
-{
-  length++; /* Room for terminating zero */
-  return (self->allocated < length)
-    ? TrioStringGrow(self, length - self->allocated)
-    : TRUE;
-}
-#endif /* !defined(TRIO_MINIMAL) */
-
-
-#if !defined(TRIO_MINIMAL)
 /**
    Create a new dynamic string.
-   
+
    @param initial_size Initial size of the buffer.
    @return Newly allocated dynamic string, or NULL if memory allocation failed.
 */
-TRIO_STRING_PUBLIC trio_string_t *
+#if defined(TRIO_FUNC_STRING_CREATE)
+
+TRIO_PUBLIC_STRING trio_string_t *
 trio_string_create
 TRIO_ARGS1((initial_size),
           int initial_size)
 {
   trio_string_t *self;
 
-  self = TrioStringAlloc();
+  self = internal_string_alloc();
   if (self)
     {
-      if (TrioStringGrow(self,
+      if (internal_string_grow(self,
                         (size_t)((initial_size > 0) ? initial_size : 1)))
        {
          self->content[0] = (char)0;
@@ -1358,21 +1556,23 @@ TRIO_ARGS1((initial_size),
     }
   return self;
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
 /**
    Deallocate the dynamic string and its contents.
-   
+
    @param self Dynamic string
 */
-TRIO_STRING_PUBLIC void
+#if defined(TRIO_FUNC_STRING_DESTROY)
+
+TRIO_PUBLIC_STRING void
 trio_string_destroy
 TRIO_ARGS1((self),
           trio_string_t *self)
 {
   assert(self);
-  
+
   if (self)
     {
       trio_destroy(self->content);
@@ -1380,15 +1580,15 @@ TRIO_ARGS1((self),
     }
 }
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Get a pointer to the content.
-   
+
    @param self Dynamic string.
    @param offset Offset into content.
    @return Pointer to the content.
-   
+
    @p Offset can be zero, positive, or negative. If @p offset is zero,
    then the start of the content will be returned. If @p offset is positive,
    then a pointer to @p offset number of characters from the beginning of the
@@ -1396,14 +1596,16 @@ TRIO_ARGS1((self),
    number of characters from the ending of the string, starting at the
    terminating zero, is returned.
 */
-TRIO_STRING_PUBLIC char *
+#if defined(TRIO_FUNC_STRING_GET)
+
+TRIO_PUBLIC_STRING char *
 trio_string_get
 TRIO_ARGS2((self, offset),
           trio_string_t *self,
           int offset)
 {
   char *result = NULL;
-  
+
   assert(self);
 
   if (self->content != NULL)
@@ -1431,25 +1633,27 @@ TRIO_ARGS2((self, offset),
     }
   return result;
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
 /**
    Extract the content.
-   
+
    @param self Dynamic String
    @return Content of dynamic string.
-   
+
    The content is removed from the dynamic string. This enables destruction
    of the dynamic string without deallocation of the content.
 */
-TRIO_STRING_PUBLIC char *
+#if defined(TRIO_FUNC_STRING_EXTRACT)
+
+TRIO_PUBLIC_STRING char *
 trio_string_extract
 TRIO_ARGS1((self),
           trio_string_t *self)
 {
   char *result;
-  
+
   assert(self);
 
   result = self->content;
@@ -1459,22 +1663,24 @@ TRIO_ARGS1((self),
   return result;
 }
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Set the content of the dynamic string.
-   
+
    @param self Dynamic String
    @param buffer The new content.
-   
+
    Sets the content of the dynamic string to a copy @p buffer.
    An existing content will be deallocated first, if necessary.
-   
+
    @remark
    This function will make a copy of @p buffer.
    You are responsible for deallocating @p buffer yourself.
 */
-TRIO_STRING_PUBLIC void
+#if defined(TRIO_FUNC_XSTRING_SET)
+
+TRIO_PUBLIC_STRING void
 trio_xstring_set
 TRIO_ARGS2((self, buffer),
           trio_string_t *self,
@@ -1485,13 +1691,15 @@ TRIO_ARGS2((self, buffer),
   trio_destroy(self->content);
   self->content = trio_duplicate(buffer);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
 /*
  * trio_string_size
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_STRING_SIZE)
+
+TRIO_PUBLIC_STRING int
 trio_string_size
 TRIO_ARGS1((self),
           trio_string_t *self)
@@ -1501,11 +1709,14 @@ TRIO_ARGS1((self),
   return self->allocated;
 }
 
+#endif
 
 /*
  * trio_string_terminate
  */
-TRIO_STRING_PUBLIC void
+#if defined(TRIO_FUNC_STRING_TERMINATE)
+
+TRIO_PUBLIC_STRING void
 trio_string_terminate
 TRIO_ARGS1((self),
           trio_string_t *self)
@@ -1513,71 +1724,77 @@ TRIO_ARGS1((self),
   trio_xstring_append_char(self, 0);
 }
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Append the second string to the first.
-   
+
    @param self Dynamic string to be modified.
    @param other Dynamic string to copy from.
    @return Boolean value indicating success or failure.
 */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_STRING_APPEND)
+
+TRIO_PUBLIC_STRING int
 trio_string_append
 TRIO_ARGS2((self, other),
           trio_string_t *self,
           trio_string_t *other)
 {
   size_t length;
-  
+
   assert(self);
   assert(other);
 
   length = self->length + other->length;
-  if (!TrioStringGrowTo(self, length))
+  if (!internal_string_grow_to(self, length))
     goto error;
   trio_copy(&self->content[self->length], other->content);
   self->length = length;
   return TRUE;
-  
+
  error:
   return FALSE;
 }
-#endif /* !defined(TRIO_MINIMAL) */
+
+#endif
 
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_xstring_append
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_XSTRING_APPEND)
+
+TRIO_PUBLIC_STRING int
 trio_xstring_append
 TRIO_ARGS2((self, other),
           trio_string_t *self,
           TRIO_CONST char *other)
 {
   size_t length;
-  
+
   assert(self);
   assert(other);
 
   length = self->length + trio_length(other);
-  if (!TrioStringGrowTo(self, length))
+  if (!internal_string_grow_to(self, length))
     goto error;
   trio_copy(&self->content[self->length], other);
   self->length = length;
   return TRUE;
-  
+
  error:
   return FALSE;
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
 /*
  * trio_xstring_append_char
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_XSTRING_APPEND_CHAR)
+
+TRIO_PUBLIC_STRING int
 trio_xstring_append_char
 TRIO_ARGS2((self, character),
           trio_string_t *self,
@@ -1587,27 +1804,64 @@ TRIO_ARGS2((self, character),
 
   if ((int)self->length >= trio_string_size(self))
     {
-      if (!TrioStringGrow(self, 0))
+      if (!internal_string_grow(self, 0))
        goto error;
     }
   self->content[self->length] = character;
   self->length++;
   return TRUE;
-  
+
+ error:
+  return FALSE;
+}
+
+#endif
+
+/*
+ * trio_xstring_append_max
+ */
+#if defined(TRIO_FUNC_XSTRING_APPEND_MAX)
+
+TRIO_PUBLIC_STRING int
+trio_xstring_append_max
+TRIO_ARGS3((self, other, max),
+          trio_string_t *self,
+          TRIO_CONST char *other,
+           size_t max)
+{
+  size_t length;
+
+  assert(self);
+  assert(other);
+
+  length = self->length + trio_length_max(other, max);
+  if (!internal_string_grow_to(self, length))
+    goto error;
+
+  /*
+   * Pass max + 1 since trio_copy_max copies one character less than
+   * this from the source to make room for a terminating zero.
+   */
+  trio_copy_max(&self->content[self->length], max + 1, other);
+  self->length = length;
+  return TRUE;
+
  error:
   return FALSE;
 }
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /**
    Search for the first occurrence of second parameter in the first.
-   
+
    @param self Dynamic string to be modified.
    @param other Dynamic string to copy from.
    @return Boolean value indicating success or failure.
 */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_STRING_CONTAINS)
+
+TRIO_PUBLIC_STRING int
 trio_string_contains
 TRIO_ARGS2((self, other),
           trio_string_t *self,
@@ -1618,14 +1872,15 @@ TRIO_ARGS2((self, other),
 
   return trio_contains(self->content, other->content);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_xstring_contains
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_XSTRING_CONTAINS)
+
+TRIO_PUBLIC_STRING int
 trio_xstring_contains
 TRIO_ARGS2((self, other),
           trio_string_t *self,
@@ -1636,14 +1891,15 @@ TRIO_ARGS2((self, other),
 
   return trio_contains(self->content, other);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_string_copy
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_STRING_COPY)
+
+TRIO_PUBLIC_STRING int
 trio_string_copy
 TRIO_ARGS2((self, other),
           trio_string_t *self,
@@ -1655,14 +1911,16 @@ TRIO_ARGS2((self, other),
   self->length = 0;
   return trio_string_append(self, other);
 }
-#endif /* !defined(TRIO_MINIMAL) */
+
+#endif
 
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_xstring_copy
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_XSTRING_COPY)
+
+TRIO_PUBLIC_STRING int
 trio_xstring_copy
 TRIO_ARGS2((self, other),
           trio_string_t *self,
@@ -1674,26 +1932,27 @@ TRIO_ARGS2((self, other),
   self->length = 0;
   return trio_xstring_append(self, other);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_string_duplicate
  */
-TRIO_STRING_PUBLIC trio_string_t *
+#if defined(TRIO_FUNC_STRING_DUPLICATE)
+
+TRIO_PUBLIC_STRING trio_string_t *
 trio_string_duplicate
 TRIO_ARGS1((other),
           trio_string_t *other)
 {
   trio_string_t *self;
-  
+
   assert(other);
 
-  self = TrioStringAlloc();
+  self = internal_string_alloc();
   if (self)
     {
-      self->content = TrioDuplicateMax(other->content, other->length);
+      self->content = internal_duplicate_max(other->content, other->length);
       if (self->content)
        {
          self->length = other->length;
@@ -1706,25 +1965,27 @@ TRIO_ARGS1((other),
     }
   return self;
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
 /*
  * trio_xstring_duplicate
  */
-TRIO_STRING_PUBLIC trio_string_t *
+#if defined(TRIO_FUNC_XSTRING_DUPLICATE)
+
+TRIO_PUBLIC_STRING trio_string_t *
 trio_xstring_duplicate
 TRIO_ARGS1((other),
           TRIO_CONST char *other)
 {
   trio_string_t *self;
-  
+
   assert(other);
 
-  self = TrioStringAlloc();
+  self = internal_string_alloc();
   if (self)
     {
-      self->content = TrioDuplicateMax(other, trio_length(other));
+      self->content = internal_duplicate_max(other, trio_length(other));
       if (self->content)
        {
          self->length = trio_length(self->content);
@@ -1738,12 +1999,14 @@ TRIO_ARGS1((other),
   return self;
 }
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_string_equal
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_STRING_EQUAL)
+
+TRIO_PUBLIC_STRING int
 trio_string_equal
 TRIO_ARGS2((self, other),
           trio_string_t *self,
@@ -1754,14 +2017,16 @@ TRIO_ARGS2((self, other),
 
   return trio_equal(self->content, other->content);
 }
-#endif /* !defined(TRIO_MINIMAL) */
+
+#endif
 
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_xstring_equal
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_XSTRING_EQUAL)
+
+TRIO_PUBLIC_STRING int
 trio_xstring_equal
 TRIO_ARGS2((self, other),
           trio_string_t *self,
@@ -1772,14 +2037,15 @@ TRIO_ARGS2((self, other),
 
   return trio_equal(self->content, other);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_string_equal_max
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_STRING_EQUAL_MAX)
+
+TRIO_PUBLIC_STRING int
 trio_string_equal_max
 TRIO_ARGS3((self, max, other),
           trio_string_t *self,
@@ -1791,14 +2057,14 @@ TRIO_ARGS3((self, max, other),
 
   return trio_equal_max(self->content, max, other->content);
 }
-#endif /* !defined(TRIO_MINIMAL) */
-
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_xstring_equal_max
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_XSTRING_EQUAL_MAX)
+
+TRIO_PUBLIC_STRING int
 trio_xstring_equal_max
 TRIO_ARGS3((self, max, other),
           trio_string_t *self,
@@ -1810,14 +2076,15 @@ TRIO_ARGS3((self, max, other),
 
   return trio_equal_max(self->content, max, other);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_string_equal_case
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_STRING_EQUAL_CASE)
+
+TRIO_PUBLIC_STRING int
 trio_string_equal_case
 TRIO_ARGS2((self, other),
           trio_string_t *self,
@@ -1828,14 +2095,15 @@ TRIO_ARGS2((self, other),
 
   return trio_equal_case(self->content, other->content);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_xstring_equal_case
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE)
+
+TRIO_PUBLIC_STRING int
 trio_xstring_equal_case
 TRIO_ARGS2((self, other),
           trio_string_t *self,
@@ -1846,14 +2114,15 @@ TRIO_ARGS2((self, other),
 
   return trio_equal_case(self->content, other);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_string_equal_case_max
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_STRING_EQUAL_CASE_MAX)
+
+TRIO_PUBLIC_STRING int
 trio_string_equal_case_max
 TRIO_ARGS3((self, max, other),
           trio_string_t *self,
@@ -1865,14 +2134,15 @@ TRIO_ARGS3((self, max, other),
 
   return trio_equal_case_max(self->content, max, other->content);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_xstring_equal_case_max
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_XSTRING_EQUAL_CASE_MAX)
+
+TRIO_PUBLIC_STRING int
 trio_xstring_equal_case_max
 TRIO_ARGS3((self, max, other),
           trio_string_t *self,
@@ -1884,14 +2154,15 @@ TRIO_ARGS3((self, max, other),
 
   return trio_equal_case_max(self->content, max, other);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_string_format_data_max
  */
-TRIO_STRING_PUBLIC size_t
+#if defined(TRIO_FUNC_STRING_FORMAT_DATE_MAX)
+
+TRIO_PUBLIC_STRING size_t
 trio_string_format_date_max
 TRIO_ARGS4((self, max, format, datetime),
           trio_string_t *self,
@@ -1903,14 +2174,15 @@ TRIO_ARGS4((self, max, format, datetime),
 
   return trio_format_date_max(self->content, max, format, datetime);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_string_index
  */
-TRIO_STRING_PUBLIC char *
+#if defined(TRIO_FUNC_STRING_INDEX)
+
+TRIO_PUBLIC_STRING char *
 trio_string_index
 TRIO_ARGS2((self, character),
           trio_string_t *self,
@@ -1920,14 +2192,15 @@ TRIO_ARGS2((self, character),
 
   return trio_index(self->content, character);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_string_index_last
  */
-TRIO_STRING_PUBLIC char *
+#if defined(TRIO_FUNC_STRING_INDEX_LAST)
+
+TRIO_PUBLIC_STRING char *
 trio_string_index_last
 TRIO_ARGS2((self, character),
           trio_string_t *self,
@@ -1937,14 +2210,15 @@ TRIO_ARGS2((self, character),
 
   return trio_index_last(self->content, character);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_string_length
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_STRING_LENGTH)
+
+TRIO_PUBLIC_STRING int
 trio_string_length
 TRIO_ARGS1((self),
           trio_string_t *self)
@@ -1957,14 +2231,15 @@ TRIO_ARGS1((self),
     }
   return self->length;
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_string_lower
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_STRING_LOWER)
+
+TRIO_PUBLIC_STRING int
 trio_string_lower
 TRIO_ARGS1((self),
           trio_string_t *self)
@@ -1973,14 +2248,15 @@ TRIO_ARGS1((self),
 
   return trio_lower(self->content);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_string_match
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_STRING_MATCH)
+
+TRIO_PUBLIC_STRING int
 trio_string_match
 TRIO_ARGS2((self, other),
           trio_string_t *self,
@@ -1991,14 +2267,15 @@ TRIO_ARGS2((self, other),
 
   return trio_match(self->content, other->content);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_xstring_match
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_XSTRING_MATCH)
+
+TRIO_PUBLIC_STRING int
 trio_xstring_match
 TRIO_ARGS2((self, other),
           trio_string_t *self,
@@ -2009,14 +2286,15 @@ TRIO_ARGS2((self, other),
 
   return trio_match(self->content, other);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_string_match_case
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_STRING_MATCH_CASE)
+
+TRIO_PUBLIC_STRING int
 trio_string_match_case
 TRIO_ARGS2((self, other),
           trio_string_t *self,
@@ -2027,14 +2305,15 @@ TRIO_ARGS2((self, other),
 
   return trio_match_case(self->content, other->content);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_xstring_match_case
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_XSTRING_MATCH_CASE)
+
+TRIO_PUBLIC_STRING int
 trio_xstring_match_case
 TRIO_ARGS2((self, other),
           trio_string_t *self,
@@ -2045,14 +2324,15 @@ TRIO_ARGS2((self, other),
 
   return trio_match_case(self->content, other);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_string_substring
  */
-TRIO_STRING_PUBLIC char *
+#if defined(TRIO_FUNC_STRING_SUBSTRING)
+
+TRIO_PUBLIC_STRING char *
 trio_string_substring
 TRIO_ARGS2((self, other),
           trio_string_t *self,
@@ -2063,14 +2343,15 @@ TRIO_ARGS2((self, other),
 
   return trio_substring(self->content, other->content);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_xstring_substring
  */
-TRIO_STRING_PUBLIC char *
+#if defined(TRIO_FUNC_XSTRING_SUBSTRING)
+
+TRIO_PUBLIC_STRING char *
 trio_xstring_substring
 TRIO_ARGS2((self, other),
           trio_string_t *self,
@@ -2081,14 +2362,15 @@ TRIO_ARGS2((self, other),
 
   return trio_substring(self->content, other);
 }
-#endif /* !defined(TRIO_MINIMAL) */
 
+#endif
 
-#if !defined(TRIO_MINIMAL)
 /*
  * trio_string_upper
  */
-TRIO_STRING_PUBLIC int
+#if defined(TRIO_FUNC_STRING_UPPER)
+
+TRIO_PUBLIC_STRING int
 trio_string_upper
 TRIO_ARGS1((self),
           trio_string_t *self)
@@ -2097,6 +2379,7 @@ TRIO_ARGS1((self),
 
   return trio_upper(self->content);
 }
-#endif /* !defined(TRIO_MINIMAL) */
+
+#endif
 
 /** @} End of DynamicStrings */