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