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