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