(root)/
libxml2-2.12.3/
triostr.c
       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   * MERCHANTABILITY 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 */