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