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