UNIXworkcode

1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. 3 * 4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 /** 29 * \file string.h 30 * \brief Strings that know their length. 31 * \author Mike Becker 32 * \author Olaf Wintermann 33 * \copyright 2-Clause BSD License 34 */ 35 36 #ifndef UCX_STRING_H 37 #define UCX_STRING_H 38 39 #include "common.h" 40 #include "allocator.h" 41 42 /** 43 * The maximum length of the "needle" in cx_strstr() that can use SBO. 44 */ 45 extern unsigned const cx_strstr_sbo_size; 46 47 /** 48 * The UCX string structure. 49 */ 50 struct cx_mutstr_s { 51 /** 52 * A pointer to the string. 53 * \note The string is not necessarily \c NULL terminated. 54 * Always use the length. 55 */ 56 char *ptr; 57 /** The length of the string */ 58 size_t length; 59 }; 60 61 /** 62 * A mutable string. 63 */ 64 typedef struct cx_mutstr_s cxmutstr; 65 66 /** 67 * The UCX string structure for immutable (constant) strings. 68 */ 69 struct cx_string_s { 70 /** 71 * A pointer to the immutable string. 72 * \note The string is not necessarily \c NULL terminated. 73 * Always use the length. 74 */ 75 char const *ptr; 76 /** The length of the string */ 77 size_t length; 78 }; 79 80 /** 81 * An immutable string. 82 */ 83 typedef struct cx_string_s cxstring; 84 85 /** 86 * Context for string tokenizing. 87 */ 88 struct cx_strtok_ctx_s { 89 /** 90 * The string to tokenize. 91 */ 92 cxstring str; 93 /** 94 * The primary delimiter. 95 */ 96 cxstring delim; 97 /** 98 * Optional array of more delimiters. 99 */ 100 cxstring const *delim_more; 101 /** 102 * Length of the array containing more delimiters. 103 */ 104 size_t delim_more_count; 105 /** 106 * Position of the currently active token in the source string. 107 */ 108 size_t pos; 109 /** 110 * Position of next delimiter in the source string. 111 * 112 * If the tokenizer has not yet returned a token, the content of this field 113 * is undefined. If the tokenizer reached the end of the string, this field 114 * contains the length of the source string. 115 */ 116 size_t delim_pos; 117 /** 118 * The position of the next token in the source string. 119 */ 120 size_t next_pos; 121 /** 122 * The number of already found tokens. 123 */ 124 size_t found; 125 /** 126 * The maximum number of tokens that shall be returned. 127 */ 128 size_t limit; 129 }; 130 131 /** 132 * A string tokenizing context. 133 */ 134 typedef struct cx_strtok_ctx_s CxStrtokCtx; 135 136 #ifdef __cplusplus 137 extern "C" { 138 139 /** 140 * A literal initializer for an UCX string structure. 141 * 142 * @param literal the string literal 143 */ 144 #define CX_STR(literal) cxstring{literal, sizeof(literal) - 1} 145 146 #else // __cplusplus 147 148 /** 149 * A literal initializer for an UCX string structure. 150 * 151 * The argument MUST be a string (const char*) \em literal. 152 * 153 * @param literal the string literal 154 */ 155 #define CX_STR(literal) (cxstring){literal, sizeof(literal) - 1} 156 157 #endif 158 159 160 /** 161 * Wraps a mutable string that must be zero-terminated. 162 * 163 * The length is implicitly inferred by using a call to \c strlen(). 164 * 165 * \note the wrapped string will share the specified pointer to the string. 166 * If you do want a copy, use cx_strdup() on the return value of this function. 167 * 168 * If you need to wrap a constant string, use cx_str(). 169 * 170 * @param cstring the string to wrap, must be zero-terminated 171 * @return the wrapped string 172 * 173 * @see cx_mutstrn() 174 */ 175 __attribute__((__warn_unused_result__, __nonnull__)) 176 cxmutstr cx_mutstr(char *cstring); 177 178 /** 179 * Wraps a string that does not need to be zero-terminated. 180 * 181 * The argument may be \c NULL if the length is zero. 182 * 183 * \note the wrapped string will share the specified pointer to the string. 184 * If you do want a copy, use cx_strdup() on the return value of this function. 185 * 186 * If you need to wrap a constant string, use cx_strn(). 187 * 188 * @param cstring the string to wrap (or \c NULL, only if the length is zero) 189 * @param length the length of the string 190 * @return the wrapped string 191 * 192 * @see cx_mutstr() 193 */ 194 __attribute__((__warn_unused_result__)) 195 cxmutstr cx_mutstrn( 196 char *cstring, 197 size_t length 198 ); 199 200 /** 201 * Wraps a string that must be zero-terminated. 202 * 203 * The length is implicitly inferred by using a call to \c strlen(). 204 * 205 * \note the wrapped string will share the specified pointer to the string. 206 * If you do want a copy, use cx_strdup() on the return value of this function. 207 * 208 * If you need to wrap a non-constant string, use cx_mutstr(). 209 * 210 * @param cstring the string to wrap, must be zero-terminated 211 * @return the wrapped string 212 * 213 * @see cx_strn() 214 */ 215 __attribute__((__warn_unused_result__, __nonnull__)) 216 cxstring cx_str(char const *cstring); 217 218 219 /** 220 * Wraps a string that does not need to be zero-terminated. 221 * 222 * The argument may be \c NULL if the length is zero. 223 * 224 * \note the wrapped string will share the specified pointer to the string. 225 * If you do want a copy, use cx_strdup() on the return value of this function. 226 * 227 * If you need to wrap a non-constant string, use cx_mutstrn(). 228 * 229 * @param cstring the string to wrap (or \c NULL, only if the length is zero) 230 * @param length the length of the string 231 * @return the wrapped string 232 * 233 * @see cx_str() 234 */ 235 __attribute__((__warn_unused_result__)) 236 cxstring cx_strn( 237 char const *cstring, 238 size_t length 239 ); 240 241 /** 242 * Casts a mutable string to an immutable string. 243 * 244 * \note This is not seriously a cast. Instead you get a copy 245 * of the struct with the desired pointer type. Both structs still 246 * point to the same location, though! 247 * 248 * @param str the mutable string to cast 249 * @return an immutable copy of the string pointer 250 */ 251 __attribute__((__warn_unused_result__)) 252 cxstring cx_strcast(cxmutstr str); 253 254 /** 255 * Passes the pointer in this string to \c free(). 256 * 257 * The pointer in the struct is set to \c NULL and the length is set to zero. 258 * 259 * \note There is no implementation for cxstring, because it is unlikely that 260 * you ever have a \c char \c const* you are really supposed to free. If you 261 * encounter such situation, you should double-check your code. 262 * 263 * @param str the string to free 264 */ 265 __attribute__((__nonnull__)) 266 void cx_strfree(cxmutstr *str); 267 268 /** 269 * Passes the pointer in this string to the allocators free function. 270 * 271 * The pointer in the struct is set to \c NULL and the length is set to zero. 272 * 273 * \note There is no implementation for cxstring, because it is unlikely that 274 * you ever have a \c char \c const* you are really supposed to free. If you 275 * encounter such situation, you should double-check your code. 276 * 277 * @param alloc the allocator 278 * @param str the string to free 279 */ 280 __attribute__((__nonnull__)) 281 void cx_strfree_a( 282 CxAllocator const *alloc, 283 cxmutstr *str 284 ); 285 286 /** 287 * Returns the accumulated length of all specified strings. 288 * 289 * \attention if the count argument is larger than the number of the 290 * specified strings, the behavior is undefined. 291 * 292 * @param count the total number of specified strings 293 * @param ... all strings 294 * @return the accumulated length of all strings 295 */ 296 __attribute__((__warn_unused_result__)) 297 size_t cx_strlen( 298 size_t count, 299 ... 300 ); 301 302 /** 303 * Concatenates strings. 304 * 305 * The resulting string will be allocated by the specified allocator. 306 * So developers \em must pass the return value to cx_strfree_a() eventually. 307 * 308 * If \p str already contains a string, the memory will be reallocated and 309 * the other strings are appended. Otherwise, new memory is allocated. 310 * 311 * \note It is guaranteed that there is only one allocation. 312 * It is also guaranteed that the returned string is zero-terminated. 313 * 314 * @param alloc the allocator to use 315 * @param str the string the other strings shall be concatenated to 316 * @param count the number of the other following strings to concatenate 317 * @param ... all other strings 318 * @return the concatenated string 319 */ 320 __attribute__((__warn_unused_result__, __nonnull__)) 321 cxmutstr cx_strcat_ma( 322 CxAllocator const *alloc, 323 cxmutstr str, 324 size_t count, 325 ... 326 ); 327 328 /** 329 * Concatenates strings and returns a new string. 330 * 331 * The resulting string will be allocated by the specified allocator. 332 * So developers \em must pass the return value to cx_strfree_a() eventually. 333 * 334 * \note It is guaranteed that there is only one allocation. 335 * It is also guaranteed that the returned string is zero-terminated. 336 * 337 * @param alloc the allocator to use 338 * @param count the number of the other following strings to concatenate 339 * @param ... all other strings 340 * @return the concatenated string 341 */ 342 #define cx_strcat_a(alloc, count, ...) \ 343 cx_strcat_ma(alloc, cx_mutstrn(NULL, 0), count, __VA_ARGS__) 344 345 /** 346 * Concatenates strings and returns a new string. 347 * 348 * The resulting string will be allocated by standard \c malloc(). 349 * So developers \em must pass the return value to cx_strfree() eventually. 350 * 351 * \note It is guaranteed that there is only one allocation. 352 * It is also guaranteed that the returned string is zero-terminated. 353 * 354 * @param count the number of the other following strings to concatenate 355 * @param ... all other strings 356 * @return the concatenated string 357 */ 358 #define cx_strcat(count, ...) \ 359 cx_strcat_ma(cxDefaultAllocator, cx_mutstrn(NULL, 0), count, __VA_ARGS__) 360 361 /** 362 * Concatenates strings. 363 * 364 * The resulting string will be allocated by standard \c malloc(). 365 * So developers \em must pass the return value to cx_strfree() eventually. 366 * 367 * If \p str already contains a string, the memory will be reallocated and 368 * the other strings are appended. Otherwise, new memory is allocated. 369 * 370 * \note It is guaranteed that there is only one allocation. 371 * It is also guaranteed that the returned string is zero-terminated. 372 * 373 * @param str the string the other strings shall be concatenated to 374 * @param count the number of the other following strings to concatenate 375 * @param ... all other strings 376 * @return the concatenated string 377 */ 378 #define cx_strcat_m(str, count, ...) \ 379 cx_strcat_ma(cxDefaultAllocator, str, count, __VA_ARGS__) 380 381 /** 382 * Returns a substring starting at the specified location. 383 * 384 * \attention the new string references the same memory area as the 385 * input string and is usually \em not zero-terminated. 386 * Use cx_strdup() to get a copy. 387 * 388 * @param string input string 389 * @param start start location of the substring 390 * @return a substring of \p string starting at \p start 391 * 392 * @see cx_strsubsl() 393 * @see cx_strsubs_m() 394 * @see cx_strsubsl_m() 395 */ 396 __attribute__((__warn_unused_result__)) 397 cxstring cx_strsubs( 398 cxstring string, 399 size_t start 400 ); 401 402 /** 403 * Returns a substring starting at the specified location. 404 * 405 * The returned string will be limited to \p length bytes or the number 406 * of bytes available in \p string, whichever is smaller. 407 * 408 * \attention the new string references the same memory area as the 409 * input string and is usually \em not zero-terminated. 410 * Use cx_strdup() to get a copy. 411 * 412 * @param string input string 413 * @param start start location of the substring 414 * @param length the maximum length of the returned string 415 * @return a substring of \p string starting at \p start 416 * 417 * @see cx_strsubs() 418 * @see cx_strsubs_m() 419 * @see cx_strsubsl_m() 420 */ 421 __attribute__((__warn_unused_result__)) 422 cxstring cx_strsubsl( 423 cxstring string, 424 size_t start, 425 size_t length 426 ); 427 428 /** 429 * Returns a substring starting at the specified location. 430 * 431 * \attention the new string references the same memory area as the 432 * input string and is usually \em not zero-terminated. 433 * Use cx_strdup() to get a copy. 434 * 435 * @param string input string 436 * @param start start location of the substring 437 * @return a substring of \p string starting at \p start 438 * 439 * @see cx_strsubsl_m() 440 * @see cx_strsubs() 441 * @see cx_strsubsl() 442 */ 443 __attribute__((__warn_unused_result__)) 444 cxmutstr cx_strsubs_m( 445 cxmutstr string, 446 size_t start 447 ); 448 449 /** 450 * Returns a substring starting at the specified location. 451 * 452 * The returned string will be limited to \p length bytes or the number 453 * of bytes available in \p string, whichever is smaller. 454 * 455 * \attention the new string references the same memory area as the 456 * input string and is usually \em not zero-terminated. 457 * Use cx_strdup() to get a copy. 458 * 459 * @param string input string 460 * @param start start location of the substring 461 * @param length the maximum length of the returned string 462 * @return a substring of \p string starting at \p start 463 * 464 * @see cx_strsubs_m() 465 * @see cx_strsubs() 466 * @see cx_strsubsl() 467 */ 468 __attribute__((__warn_unused_result__)) 469 cxmutstr cx_strsubsl_m( 470 cxmutstr string, 471 size_t start, 472 size_t length 473 ); 474 475 /** 476 * Returns a substring starting at the location of the first occurrence of the 477 * specified character. 478 * 479 * If the string does not contain the character, an empty string is returned. 480 * 481 * @param string the string where to locate the character 482 * @param chr the character to locate 483 * @return a substring starting at the first location of \p chr 484 * 485 * @see cx_strchr_m() 486 */ 487 __attribute__((__warn_unused_result__)) 488 cxstring cx_strchr( 489 cxstring string, 490 int chr 491 ); 492 493 /** 494 * Returns a substring starting at the location of the first occurrence of the 495 * specified character. 496 * 497 * If the string does not contain the character, an empty string is returned. 498 * 499 * @param string the string where to locate the character 500 * @param chr the character to locate 501 * @return a substring starting at the first location of \p chr 502 * 503 * @see cx_strchr() 504 */ 505 __attribute__((__warn_unused_result__)) 506 cxmutstr cx_strchr_m( 507 cxmutstr string, 508 int chr 509 ); 510 511 /** 512 * Returns a substring starting at the location of the last occurrence of the 513 * specified character. 514 * 515 * If the string does not contain the character, an empty string is returned. 516 * 517 * @param string the string where to locate the character 518 * @param chr the character to locate 519 * @return a substring starting at the last location of \p chr 520 * 521 * @see cx_strrchr_m() 522 */ 523 __attribute__((__warn_unused_result__)) 524 cxstring cx_strrchr( 525 cxstring string, 526 int chr 527 ); 528 529 /** 530 * Returns a substring starting at the location of the last occurrence of the 531 * specified character. 532 * 533 * If the string does not contain the character, an empty string is returned. 534 * 535 * @param string the string where to locate the character 536 * @param chr the character to locate 537 * @return a substring starting at the last location of \p chr 538 * 539 * @see cx_strrchr() 540 */ 541 __attribute__((__warn_unused_result__)) 542 cxmutstr cx_strrchr_m( 543 cxmutstr string, 544 int chr 545 ); 546 547 /** 548 * Returns a substring starting at the location of the first occurrence of the 549 * specified string. 550 * 551 * If \p haystack does not contain \p needle, an empty string is returned. 552 * 553 * If \p needle is an empty string, the complete \p haystack is 554 * returned. 555 * 556 * @param haystack the string to be scanned 557 * @param needle string containing the sequence of characters to match 558 * @return a substring starting at the first occurrence of 559 * \p needle, or an empty string, if the sequence is not 560 * contained 561 * @see cx_strstr_m() 562 */ 563 __attribute__((__warn_unused_result__)) 564 cxstring cx_strstr( 565 cxstring haystack, 566 cxstring needle 567 ); 568 569 /** 570 * Returns a substring starting at the location of the first occurrence of the 571 * specified string. 572 * 573 * If \p haystack does not contain \p needle, an empty string is returned. 574 * 575 * If \p needle is an empty string, the complete \p haystack is 576 * returned. 577 * 578 * @param haystack the string to be scanned 579 * @param needle string containing the sequence of characters to match 580 * @return a substring starting at the first occurrence of 581 * \p needle, or an empty string, if the sequence is not 582 * contained 583 * @see cx_strstr() 584 */ 585 __attribute__((__warn_unused_result__)) 586 cxmutstr cx_strstr_m( 587 cxmutstr haystack, 588 cxstring needle 589 ); 590 591 /** 592 * Splits a given string using a delimiter string. 593 * 594 * \note The resulting array contains strings that point to the source 595 * \p string. Use cx_strdup() to get copies. 596 * 597 * @param string the string to split 598 * @param delim the delimiter 599 * @param limit the maximum number of split items 600 * @param output a pre-allocated array of at least \p limit length 601 * @return the actual number of split items 602 */ 603 __attribute__((__warn_unused_result__, __nonnull__)) 604 size_t cx_strsplit( 605 cxstring string, 606 cxstring delim, 607 size_t limit, 608 cxstring *output 609 ); 610 611 /** 612 * Splits a given string using a delimiter string. 613 * 614 * The array pointed to by \p output will be allocated by \p allocator. 615 * 616 * \note The resulting array contains strings that point to the source 617 * \p string. Use cx_strdup() to get copies. 618 * 619 * \attention If allocation fails, the \c NULL pointer will be written to 620 * \p output and the number returned will be zero. 621 * 622 * @param allocator the allocator to use for allocating the resulting array 623 * @param string the string to split 624 * @param delim the delimiter 625 * @param limit the maximum number of split items 626 * @param output a pointer where the address of the allocated array shall be 627 * written to 628 * @return the actual number of split items 629 */ 630 __attribute__((__warn_unused_result__, __nonnull__)) 631 size_t cx_strsplit_a( 632 CxAllocator const *allocator, 633 cxstring string, 634 cxstring delim, 635 size_t limit, 636 cxstring **output 637 ); 638 639 640 /** 641 * Splits a given string using a delimiter string. 642 * 643 * \note The resulting array contains strings that point to the source 644 * \p string. Use cx_strdup() to get copies. 645 * 646 * @param string the string to split 647 * @param delim the delimiter 648 * @param limit the maximum number of split items 649 * @param output a pre-allocated array of at least \p limit length 650 * @return the actual number of split items 651 */ 652 __attribute__((__warn_unused_result__, __nonnull__)) 653 size_t cx_strsplit_m( 654 cxmutstr string, 655 cxstring delim, 656 size_t limit, 657 cxmutstr *output 658 ); 659 660 /** 661 * Splits a given string using a delimiter string. 662 * 663 * The array pointed to by \p output will be allocated by \p allocator. 664 * 665 * \note The resulting array contains strings that point to the source 666 * \p string. Use cx_strdup() to get copies. 667 * 668 * \attention If allocation fails, the \c NULL pointer will be written to 669 * \p output and the number returned will be zero. 670 * 671 * @param allocator the allocator to use for allocating the resulting array 672 * @param string the string to split 673 * @param delim the delimiter 674 * @param limit the maximum number of split items 675 * @param output a pointer where the address of the allocated array shall be 676 * written to 677 * @return the actual number of split items 678 */ 679 __attribute__((__warn_unused_result__, __nonnull__)) 680 size_t cx_strsplit_ma( 681 CxAllocator const *allocator, 682 cxmutstr string, 683 cxstring delim, 684 size_t limit, 685 cxmutstr **output 686 ); 687 688 /** 689 * Compares two strings. 690 * 691 * @param s1 the first string 692 * @param s2 the second string 693 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger 694 * than \p s2, zero if both strings equal 695 */ 696 __attribute__((__warn_unused_result__)) 697 int cx_strcmp( 698 cxstring s1, 699 cxstring s2 700 ); 701 702 /** 703 * Compares two strings ignoring case. 704 * 705 * @param s1 the first string 706 * @param s2 the second string 707 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger 708 * than \p s2, zero if both strings equal ignoring case 709 */ 710 __attribute__((__warn_unused_result__)) 711 int cx_strcasecmp( 712 cxstring s1, 713 cxstring s2 714 ); 715 716 /** 717 * Compares two strings. 718 * 719 * This function has a compatible signature for the use as a cx_compare_func. 720 * 721 * @param s1 the first string 722 * @param s2 the second string 723 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger 724 * than \p s2, zero if both strings equal 725 */ 726 __attribute__((__warn_unused_result__, __nonnull__)) 727 int cx_strcmp_p( 728 void const *s1, 729 void const *s2 730 ); 731 732 /** 733 * Compares two strings ignoring case. 734 * 735 * This function has a compatible signature for the use as a cx_compare_func. 736 * 737 * @param s1 the first string 738 * @param s2 the second string 739 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger 740 * than \p s2, zero if both strings equal ignoring case 741 */ 742 __attribute__((__warn_unused_result__, __nonnull__)) 743 int cx_strcasecmp_p( 744 void const *s1, 745 void const *s2 746 ); 747 748 749 /** 750 * Creates a duplicate of the specified string. 751 * 752 * The new string will contain a copy allocated by \p allocator. 753 * 754 * \note The returned string is guaranteed to be zero-terminated. 755 * 756 * @param allocator the allocator to use 757 * @param string the string to duplicate 758 * @return a duplicate of the string 759 * @see cx_strdup() 760 */ 761 __attribute__((__warn_unused_result__, __nonnull__)) 762 cxmutstr cx_strdup_a( 763 CxAllocator const *allocator, 764 cxstring string 765 ); 766 767 /** 768 * Creates a duplicate of the specified string. 769 * 770 * The new string will contain a copy allocated by standard 771 * \c malloc(). So developers \em must pass the return value to cx_strfree(). 772 * 773 * \note The returned string is guaranteed to be zero-terminated. 774 * 775 * @param string the string to duplicate 776 * @return a duplicate of the string 777 * @see cx_strdup_a() 778 */ 779 #define cx_strdup(string) cx_strdup_a(cxDefaultAllocator, string) 780 781 782 /** 783 * Creates a duplicate of the specified string. 784 * 785 * The new string will contain a copy allocated by \p allocator. 786 * 787 * \note The returned string is guaranteed to be zero-terminated. 788 * 789 * @param allocator the allocator to use 790 * @param string the string to duplicate 791 * @return a duplicate of the string 792 * @see cx_strdup_m() 793 */ 794 #define cx_strdup_ma(allocator, string) cx_strdup_a(allocator, cx_strcast(string)) 795 796 /** 797 * Creates a duplicate of the specified string. 798 * 799 * The new string will contain a copy allocated by standard 800 * \c malloc(). So developers \em must pass the return value to cx_strfree(). 801 * 802 * \note The returned string is guaranteed to be zero-terminated. 803 * 804 * @param string the string to duplicate 805 * @return a duplicate of the string 806 * @see cx_strdup_ma() 807 */ 808 #define cx_strdup_m(string) cx_strdup_a(cxDefaultAllocator, cx_strcast(string)) 809 810 /** 811 * Omits leading and trailing spaces. 812 * 813 * \note the returned string references the same memory, thus you 814 * must \em not free the returned memory. 815 * 816 * @param string the string that shall be trimmed 817 * @return the trimmed string 818 */ 819 __attribute__((__warn_unused_result__)) 820 cxstring cx_strtrim(cxstring string); 821 822 /** 823 * Omits leading and trailing spaces. 824 * 825 * \note the returned string references the same memory, thus you 826 * must \em not free the returned memory. 827 * 828 * @param string the string that shall be trimmed 829 * @return the trimmed string 830 */ 831 __attribute__((__warn_unused_result__)) 832 cxmutstr cx_strtrim_m(cxmutstr string); 833 834 /** 835 * Checks, if a string has a specific prefix. 836 * 837 * @param string the string to check 838 * @param prefix the prefix the string should have 839 * @return \c true, if and only if the string has the specified prefix, 840 * \c false otherwise 841 */ 842 __attribute__((__warn_unused_result__)) 843 bool cx_strprefix( 844 cxstring string, 845 cxstring prefix 846 ); 847 848 /** 849 * Checks, if a string has a specific suffix. 850 * 851 * @param string the string to check 852 * @param suffix the suffix the string should have 853 * @return \c true, if and only if the string has the specified suffix, 854 * \c false otherwise 855 */ 856 __attribute__((__warn_unused_result__)) 857 bool cx_strsuffix( 858 cxstring string, 859 cxstring suffix 860 ); 861 862 /** 863 * Checks, if a string has a specific prefix, ignoring the case. 864 * 865 * @param string the string to check 866 * @param prefix the prefix the string should have 867 * @return \c true, if and only if the string has the specified prefix, 868 * \c false otherwise 869 */ 870 __attribute__((__warn_unused_result__)) 871 bool cx_strcaseprefix( 872 cxstring string, 873 cxstring prefix 874 ); 875 876 /** 877 * Checks, if a string has a specific suffix, ignoring the case. 878 * 879 * @param string the string to check 880 * @param suffix the suffix the string should have 881 * @return \c true, if and only if the string has the specified suffix, 882 * \c false otherwise 883 */ 884 __attribute__((__warn_unused_result__)) 885 bool cx_strcasesuffix( 886 cxstring string, 887 cxstring suffix 888 ); 889 890 /** 891 * Converts the string to lower case. 892 * 893 * The change is made in-place. If you want a copy, use cx_strdup(), first. 894 * 895 * @param string the string to modify 896 * @see cx_strdup() 897 */ 898 void cx_strlower(cxmutstr string); 899 900 /** 901 * Converts the string to upper case. 902 * 903 * The change is made in-place. If you want a copy, use cx_strdup(), first. 904 * 905 * @param string the string to modify 906 * @see cx_strdup() 907 */ 908 void cx_strupper(cxmutstr string); 909 910 /** 911 * Replaces a pattern in a string with another string. 912 * 913 * The pattern is taken literally and is no regular expression. 914 * Replaces at most \p replmax occurrences. 915 * 916 * The returned string will be allocated by \p allocator and is guaranteed 917 * to be zero-terminated. 918 * 919 * If allocation fails, or the input string is empty, 920 * the returned string will be empty. 921 * 922 * @param allocator the allocator to use 923 * @param str the string where replacements should be applied 924 * @param pattern the pattern to search for 925 * @param replacement the replacement string 926 * @param replmax maximum number of replacements 927 * @return the resulting string after applying the replacements 928 */ 929 __attribute__((__warn_unused_result__, __nonnull__)) 930 cxmutstr cx_strreplacen_a( 931 CxAllocator const *allocator, 932 cxstring str, 933 cxstring pattern, 934 cxstring replacement, 935 size_t replmax 936 ); 937 938 /** 939 * Replaces a pattern in a string with another string. 940 * 941 * The pattern is taken literally and is no regular expression. 942 * Replaces at most \p replmax occurrences. 943 * 944 * The returned string will be allocated by \c malloc() and is guaranteed 945 * to be zero-terminated. 946 * 947 * If allocation fails, or the input string is empty, 948 * the returned string will be empty. 949 * 950 * @param str the string where replacements should be applied 951 * @param pattern the pattern to search for 952 * @param replacement the replacement string 953 * @param replmax maximum number of replacements 954 * @return the resulting string after applying the replacements 955 */ 956 #define cx_strreplacen(str, pattern, replacement, replmax) \ 957 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, replmax) 958 959 /** 960 * Replaces a pattern in a string with another string. 961 * 962 * The pattern is taken literally and is no regular expression. 963 * 964 * The returned string will be allocated by \p allocator and is guaranteed 965 * to be zero-terminated. 966 * 967 * If allocation fails, or the input string is empty, 968 * the returned string will be empty. 969 * 970 * @param allocator the allocator to use 971 * @param str the string where replacements should be applied 972 * @param pattern the pattern to search for 973 * @param replacement the replacement string 974 * @return the resulting string after applying the replacements 975 */ 976 #define cx_strreplace_a(allocator, str, pattern, replacement) \ 977 cx_strreplacen_a(allocator, str, pattern, replacement, SIZE_MAX) 978 979 /** 980 * Replaces a pattern in a string with another string. 981 * 982 * The pattern is taken literally and is no regular expression. 983 * Replaces at most \p replmax occurrences. 984 * 985 * The returned string will be allocated by \c malloc() and is guaranteed 986 * to be zero-terminated. 987 * 988 * If allocation fails, or the input string is empty, 989 * the returned string will be empty. 990 * 991 * @param str the string where replacements should be applied 992 * @param pattern the pattern to search for 993 * @param replacement the replacement string 994 * @return the resulting string after applying the replacements 995 */ 996 #define cx_strreplace(str, pattern, replacement) \ 997 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, SIZE_MAX) 998 999 /** 1000 * Creates a string tokenization context. 1001 * 1002 * @param str the string to tokenize 1003 * @param delim the delimiter (must not be empty) 1004 * @param limit the maximum number of tokens that shall be returned 1005 * @return a new string tokenization context 1006 */ 1007 __attribute__((__warn_unused_result__)) 1008 CxStrtokCtx cx_strtok( 1009 cxstring str, 1010 cxstring delim, 1011 size_t limit 1012 ); 1013 1014 /** 1015 * Creates a string tokenization context for a mutable string. 1016 * 1017 * @param str the string to tokenize 1018 * @param delim the delimiter (must not be empty) 1019 * @param limit the maximum number of tokens that shall be returned 1020 * @return a new string tokenization context 1021 */ 1022 __attribute__((__warn_unused_result__)) 1023 CxStrtokCtx cx_strtok_m( 1024 cxmutstr str, 1025 cxstring delim, 1026 size_t limit 1027 ); 1028 1029 /** 1030 * Returns the next token. 1031 * 1032 * The token will point to the source string. 1033 * 1034 * @param ctx the tokenization context 1035 * @param token a pointer to memory where the next token shall be stored 1036 * @return true if successful, false if the limit or the end of the string 1037 * has been reached 1038 */ 1039 __attribute__((__warn_unused_result__, __nonnull__)) 1040 bool cx_strtok_next( 1041 CxStrtokCtx *ctx, 1042 cxstring *token 1043 ); 1044 1045 /** 1046 * Returns the next token of a mutable string. 1047 * 1048 * The token will point to the source string. 1049 * If the context was not initialized over a mutable string, modifying 1050 * the data of the returned token is undefined behavior. 1051 * 1052 * @param ctx the tokenization context 1053 * @param token a pointer to memory where the next token shall be stored 1054 * @return true if successful, false if the limit or the end of the string 1055 * has been reached 1056 */ 1057 __attribute__((__warn_unused_result__, __nonnull__)) 1058 bool cx_strtok_next_m( 1059 CxStrtokCtx *ctx, 1060 cxmutstr *token 1061 ); 1062 1063 /** 1064 * Defines an array of more delimiters for the specified tokenization context. 1065 * 1066 * @param ctx the tokenization context 1067 * @param delim array of more delimiters 1068 * @param count number of elements in the array 1069 */ 1070 __attribute__((__nonnull__)) 1071 void cx_strtok_delim( 1072 CxStrtokCtx *ctx, 1073 cxstring const *delim, 1074 size_t count 1075 ); 1076 1077 1078 #ifdef __cplusplus 1079 } // extern "C" 1080 #endif 1081 1082 #endif //UCX_STRING_H 1083