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