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 /** Expands a UCX string as printf arguments. */ 43 #define CX_SFMT(s) (int) (s).length, (s).ptr 44 45 /** Format specifier for a UCX string */ 46 #define CX_PRIstr ".*s" 47 48 /** 49 * The maximum length of the "needle" in cx_strstr() that can use SBO. 50 */ 51 CX_EXPORT extern const unsigned cx_strstr_sbo_size; 52 53 /** 54 * The UCX string structure. 55 */ 56 struct cx_mutstr_s { 57 /** 58 * A pointer to the string. 59 * @note The string is not necessarily @c NULL terminated. 60 */ 61 char *ptr; 62 /** The length of the string */ 63 size_t length; 64 }; 65 66 /** 67 * A mutable string. 68 */ 69 typedef struct cx_mutstr_s cxmutstr; 70 71 /** 72 * The UCX string structure for immutable (constant) strings. 73 */ 74 struct cx_string_s { 75 /** 76 * A pointer to the immutable string. 77 * @note The string is not necessarily @c NULL terminated. 78 */ 79 const char *ptr; 80 /** The length of the string */ 81 size_t length; 82 }; 83 84 /** 85 * An immutable string. 86 */ 87 typedef struct cx_string_s cxstring; 88 89 /** 90 * Context for string tokenizing. 91 */ 92 struct cx_strtok_ctx_s { 93 /** 94 * The string to tokenize. 95 */ 96 cxstring str; 97 /** 98 * The primary delimiter. 99 */ 100 cxstring delim; 101 /** 102 * Optional array of more delimiters. 103 */ 104 const cxstring *delim_more; 105 /** 106 * Length of the array containing more delimiters. 107 */ 108 size_t delim_more_count; 109 /** 110 * Position of the currently active token in the source string. 111 */ 112 size_t pos; 113 /** 114 * Position of the next delimiter in the source string. 115 * 116 * If the tokenizer has not yet returned a token, the content of this field 117 * is undefined. If the tokenizer reaches the end of the string, this field 118 * contains the length of the source string. 119 */ 120 size_t delim_pos; 121 /** 122 * The position of the next token in the source string. 123 */ 124 size_t next_pos; 125 /** 126 * The number of already found tokens. 127 */ 128 size_t found; 129 /** 130 * The maximum number of tokens that shall be returned. 131 */ 132 size_t limit; 133 }; 134 135 /** 136 * A string tokenizing context. 137 */ 138 typedef struct cx_strtok_ctx_s CxStrtokCtx; 139 140 #ifdef __cplusplus 141 extern "C" { 142 143 /** 144 * A literal initializer for an UCX string structure. 145 * 146 * @param literal the string literal 147 */ 148 #define CX_STR(literal) cxstring{literal, sizeof(literal) - 1} 149 150 #else // __cplusplus 151 152 /** 153 * A literal initializer for an UCX string structure. 154 * 155 * The argument MUST be a string (const char*) @em literal. 156 * 157 * @param literal the string literal 158 */ 159 #define CX_STR(literal) ((cxstring){literal, sizeof(literal) - 1}) 160 161 #endif 162 163 164 /** 165 * Wraps a mutable string that must be zero-terminated. 166 * 167 * The length is implicitly inferred by using a call to @c strlen(). 168 * 169 * When @c NULL is passed, the length will be set to zero. 170 * 171 * @note the wrapped string will share the specified pointer to the string. 172 * If you do want a copy, use cx_strdup() on the return value of this function. 173 * 174 * If you need to wrap a constant string, use cx_str(). 175 * 176 * @param cstring the string to wrap (must be zero-terminated) 177 * @return the wrapped string 178 * 179 * @see cx_mutstrn() 180 */ 181 cx_attr_nodiscard cx_attr_cstr_arg(1) 182 CX_EXPORT cxmutstr cx_mutstr(char *cstring); 183 184 /** 185 * Wraps a string that does not need to be zero-terminated. 186 * 187 * The argument may be @c NULL if the length is zero. 188 * 189 * @note the wrapped string will share the specified pointer to the string. 190 * If you do want a copy, use cx_strdup() on the return value of this function. 191 * 192 * If you need to wrap a constant string, use cx_strn(). 193 * 194 * @param cstring the string to wrap (or @c NULL, only if the length is zero) 195 * @param length the length of the string 196 * @return the wrapped string 197 * 198 * @see cx_mutstr() 199 */ 200 cx_attr_nodiscard cx_attr_access_rw(1, 2) 201 CX_EXPORT cxmutstr cx_mutstrn(char *cstring, size_t length); 202 203 /** 204 * Wraps a string that must be zero-terminated. 205 * 206 * The length is implicitly inferred by using a call to @c strlen(). 207 * 208 * When @c NULL is passed, the length will be set to zero. 209 * 210 * @note the wrapped string will share the specified pointer to the string. 211 * If you do want a copy, use cx_strdup() on the return value of this function. 212 * 213 * If you need to wrap a non-constant string, use cx_mutstr(). 214 * 215 * @param cstring the string to wrap (must be zero-terminated) 216 * @return the wrapped string 217 * 218 * @see cx_strn() 219 */ 220 cx_attr_nodiscard cx_attr_cstr_arg(1) 221 CX_EXPORT cxstring cx_str(const char *cstring); 222 223 224 /** 225 * Wraps a string that does not need to be zero-terminated. 226 * 227 * The argument may be @c NULL if the length is zero. 228 * 229 * @note the wrapped string will share the specified pointer to the string. 230 * If you do want a copy, use cx_strdup() on the return value of this function. 231 * 232 * If you need to wrap a non-constant string, use cx_mutstrn(). 233 * 234 * @param cstring the string to wrap (or @c NULL, only if the length is zero) 235 * @param length the length of the string 236 * @return the wrapped string 237 * 238 * @see cx_str() 239 */ 240 cx_attr_nodiscard cx_attr_access_r(1, 2) 241 CX_EXPORT cxstring cx_strn(const char *cstring, size_t length); 242 243 #ifdef __cplusplus 244 } // extern "C" 245 cx_attr_nodiscard 246 CX_CPPDECL cxstring cx_strcast(cxmutstr str) { 247 return cx_strn(str.ptr, str.length); 248 } 249 cx_attr_nodiscard 250 CX_CPPDECL cxstring cx_strcast(cxstring str) { 251 return str; 252 } 253 cx_attr_nodiscard 254 CX_CPPDECL cxstring cx_strcast(const char *str) { 255 return cx_str(str); 256 } 257 cx_attr_nodiscard 258 CX_CPPDECL cxstring cx_strcast(const unsigned char *str) { 259 return cx_str(reinterpret_cast<const char*>(str)); 260 } 261 extern "C" { 262 #else 263 /** 264 * Internal function, do not use. 265 * @param str 266 * @return 267 * @see cx_strcast() 268 */ 269 cx_attr_nodiscard 270 CX_INLINE cxstring cx_strcast_m(cxmutstr str) { 271 return (cxstring) {str.ptr, str.length}; 272 } 273 /** 274 * Internal function, do not use. 275 * @param str 276 * @return 277 * @see cx_strcast() 278 */ 279 cx_attr_nodiscard 280 CX_INLINE cxstring cx_strcast_c(cxstring str) { 281 return str; 282 } 283 284 /** 285 * Internal function, do not use. 286 * @param str 287 * @return 288 * @see cx_strcast() 289 */ 290 cx_attr_nodiscard 291 CX_INLINE cxstring cx_strcast_u(const unsigned char *str) { 292 return cx_str((const char*)str); 293 } 294 295 /** 296 * Internal function, do not use. 297 * @param str 298 * @return 299 * @see cx_strcast() 300 */ 301 cx_attr_nodiscard 302 CX_INLINE cxstring cx_strcast_z(const char *str) { 303 return cx_str(str); 304 } 305 306 /** 307 * Wraps any string into an UCX string. 308 * 309 * @param str (any supported string type) the string to cast 310 * @return (@c cxstring) the string wrapped as UCX string 311 */ 312 #define cx_strcast(str) _Generic((str), \ 313 cxmutstr: cx_strcast_m, \ 314 cxstring: cx_strcast_c, \ 315 const unsigned char*: cx_strcast_u, \ 316 unsigned char *: cx_strcast_u, \ 317 const char*: cx_strcast_z, \ 318 char *: cx_strcast_z) (str) 319 #endif 320 321 /** 322 * Passes the pointer in this string to the cxDefaultAllocator's @c free() function. 323 * 324 * The pointer in the struct is set to @c NULL, and the length is set to zero, 325 * which means that this function protects you against double-free. 326 * 327 * @note There is no implementation for cxstring, because it is unlikely that 328 * you ever have a <code>const char*</code> you are really supposed to free. 329 * If you encounter such a situation, you should double-check your code. 330 * 331 * @param str the string to free 332 */ 333 CX_EXPORT void cx_strfree(cxmutstr *str); 334 335 /** 336 * Passes the pointer in this string to the allocator's free function. 337 * 338 * The pointer in the struct is set to @c NULL, and the length is set to zero, 339 * which means that this function protects you against double-free. 340 * 341 * @note There is no implementation for cxstring, because it is unlikely that 342 * you ever have a <code>const char*</code> you are really supposed to free. 343 * If you encounter such a situation, you should double-check your code. 344 * 345 * @param alloc the allocator 346 * @param str the string to free 347 */ 348 cx_attr_nonnull_arg(1) 349 CX_EXPORT void cx_strfree_a(const CxAllocator *alloc, cxmutstr *str); 350 351 /** 352 * Copies a string. 353 * 354 * The memory in the @p dest structure is either allocated or re-allocated to fit the entire 355 * source string, including a zero-terminator. 356 * 357 * The string in @p dest is guaranteed to be zero-terminated, regardless of whether @p src is. 358 * 359 * @param alloc the allocator 360 * @param dest a pointer to the structure where to copy the contents to 361 * @param src the source string 362 * 363 * @retval zero success 364 * @retval non-zero if re-allocation failed 365 */ 366 cx_attr_nonnull_arg(1) 367 CX_EXPORT int cx_strcpy_a(const CxAllocator *alloc, cxmutstr *dest, cxstring src); 368 369 370 /** 371 * Copies a string. 372 * 373 * The memory in the @p dest structure is either allocated or re-allocated to fit the entire 374 * source string, including a zero-terminator. 375 * 376 * The string in @p dest is guaranteed to be zero-terminated, regardless of whether @p src is. 377 * 378 * @param dest (@c cxmutstr*) a pointer to the structure where to copy the contents to 379 * @param src (@c cxstring) the source string 380 * 381 * @retval zero success 382 * @retval non-zero if re-allocation failed 383 */ 384 #define cx_strcpy(dest, src) cx_strcpy_a(cxDefaultAllocator, dest, src) 385 386 /** 387 * Returns the accumulated length of all specified strings. 388 * 389 * If this sum overflows, errno is set to EOVERFLOW. 390 * 391 * @attention if the count argument is larger than the number of the 392 * specified strings, the behavior is undefined. 393 * 394 * @param count the total number of specified strings 395 * @param ... all strings 396 * @return the accumulated length of all strings 397 */ 398 cx_attr_nodiscard 399 CX_EXPORT size_t cx_strlen(size_t count, ...); 400 401 /** 402 * Concatenates strings. 403 * 404 * The resulting string will be allocated by the specified allocator. 405 * So developers @em must pass the return value to cx_strfree_a() eventually. 406 * 407 * If @p str already contains a string, the memory will be reallocated and 408 * the other strings are appended. Otherwise, new memory is allocated. 409 * 410 * If memory allocation fails, the pointer in the returned string will 411 * be @c NULL. Depending on the allocator, @c errno might be set. 412 * 413 * @note It is guaranteed that there is only one allocation for the 414 * resulting string. 415 * It is also guaranteed that the returned string is zero-terminated. 416 * 417 * @param alloc the allocator to use 418 * @param str the string the other strings shall be concatenated to 419 * @param count the number of the other following strings to concatenate 420 * @param ... all other UCX strings 421 * @return the concatenated string 422 */ 423 cx_attr_nodiscard cx_attr_nonnull 424 CX_EXPORT cxmutstr cx_strcat_ma(const CxAllocator *alloc, 425 cxmutstr str, size_t count, ...); 426 427 /** 428 * Concatenates strings and returns a new string. 429 * 430 * The resulting string will be allocated by the specified allocator. 431 * So developers @em must pass the return value to cx_strfree_a() eventually. 432 * 433 * If memory allocation fails, the pointer in the returned string will 434 * be @c NULL. Depending on the allocator, @c errno might be set. 435 * 436 * @note It is guaranteed that there is only one allocation for the 437 * resulting string. 438 * It is also guaranteed that the returned string is zero-terminated. 439 * 440 * @param alloc (@c CxAllocator*) the allocator to use 441 * @param count (@c size_t) the number of the other following strings to concatenate 442 * @param ... all other UCX strings 443 * @return (@c cxmutstr) the concatenated string 444 */ 445 #define cx_strcat_a(alloc, count, ...) \ 446 cx_strcat_ma(alloc, cx_mutstrn(NULL, 0), count, __VA_ARGS__) 447 448 /** 449 * Concatenates strings and returns a new string. 450 * 451 * The resulting string will be allocated by the cxDefaultAllocator. 452 * So developers @em must pass the return value to cx_strfree() eventually. 453 * 454 * If memory allocation fails, the pointer in the returned string will 455 * be @c NULL and @c errno might be set. 456 * 457 * @note It is guaranteed that there is only one allocation for the 458 * resulting string. 459 * It is also guaranteed that the returned string is zero-terminated. 460 * 461 * @param count (@c size_t) the number of the other following strings to concatenate 462 * @param ... all other UCX strings 463 * @return (@c cxmutstr) the concatenated string 464 */ 465 #define cx_strcat(count, ...) \ 466 cx_strcat_ma(cxDefaultAllocator, cx_mutstrn(NULL, 0), count, __VA_ARGS__) 467 468 /** 469 * Concatenates strings. 470 * 471 * The resulting string will be allocated by the cxDefaultAllocator. 472 * So developers @em must pass the return value to cx_strfree() eventually. 473 * 474 * If @p str already contains a string, the memory will be reallocated and 475 * the other strings are appended. Otherwise, new memory is allocated. 476 * 477 * If memory allocation fails, the pointer in the returned string will 478 * be @c NULL and @c errno might be set. 479 * 480 * @note It is guaranteed that there is only one allocation for the 481 * resulting string. 482 * It is also guaranteed that the returned string is zero-terminated. 483 * 484 * @param str (@c cxmutstr) the string the other strings shall be concatenated to 485 * @param count (@c size_t) the number of the other following strings to concatenate 486 * @param ... all other strings 487 * @return (@c cxmutstr) the concatenated string 488 */ 489 #define cx_strcat_m(str, count, ...) \ 490 cx_strcat_ma(cxDefaultAllocator, str, count, __VA_ARGS__) 491 492 /** 493 * Returns a substring starting at the specified location. 494 * 495 * @attention the new string references the same memory area as the 496 * input string and is usually @em not zero-terminated. 497 * Use cx_strdup() to get a copy. 498 * 499 * @param string input string 500 * @param start start location of the substring 501 * @return a substring of @p string starting at @p start 502 * 503 * @see cx_strsubsl() 504 * @see cx_strsubs_m() 505 * @see cx_strsubsl_m() 506 */ 507 cx_attr_nodiscard 508 CX_EXPORT cxstring cx_strsubs(cxstring string, size_t start); 509 510 /** 511 * Returns a substring starting at the specified location. 512 * 513 * The returned string will be limited to @p length bytes or the number 514 * of bytes available in @p string, whichever is smaller. 515 * 516 * @attention the new string references the same memory area as the 517 * input string and is usually @em not zero-terminated. 518 * Use cx_strdup() to get a copy. 519 * 520 * @param string input string 521 * @param start start location of the substring 522 * @param length the maximum length of the returned string 523 * @return a substring of @p string starting at @p start 524 * 525 * @see cx_strsubs() 526 * @see cx_strsubs_m() 527 * @see cx_strsubsl_m() 528 */ 529 cx_attr_nodiscard 530 CX_EXPORT cxstring cx_strsubsl(cxstring string, size_t start, size_t length); 531 532 /** 533 * Returns a substring starting at the specified location. 534 * 535 * @attention the new string references the same memory area as the 536 * input string and is usually @em not zero-terminated. 537 * Use cx_strdup() to get a copy. 538 * 539 * @param string input string 540 * @param start start location of the substring 541 * @return a substring of @p string starting at @p start 542 * 543 * @see cx_strsubsl_m() 544 * @see cx_strsubs() 545 * @see cx_strsubsl() 546 */ 547 cx_attr_nodiscard 548 CX_EXPORT cxmutstr cx_strsubs_m(cxmutstr string, size_t start); 549 550 /** 551 * Returns a substring starting at the specified location. 552 * 553 * The returned string will be limited to @p length bytes or the number 554 * of bytes available in @p string, whichever is smaller. 555 * 556 * @attention the new string references the same memory area as the 557 * input string and is usually @em not zero-terminated. 558 * Use cx_strdup() to get a copy. 559 * 560 * @param string input string 561 * @param start start location of the substring 562 * @param length the maximum length of the returned string 563 * @return a substring of @p string starting at @p start 564 * 565 * @see cx_strsubs_m() 566 * @see cx_strsubs() 567 * @see cx_strsubsl() 568 */ 569 cx_attr_nodiscard 570 CX_EXPORT cxmutstr cx_strsubsl_m(cxmutstr string, size_t start, size_t length); 571 572 /** 573 * Returns a substring starting at the location of the first occurrence of the 574 * specified character. 575 * 576 * If the string does not contain the character, an empty string is returned. 577 * 578 * @param string the string where to locate the character 579 * @param chr the character to locate 580 * @return a substring starting at the first location of @p chr 581 * 582 * @see cx_strchr_m() 583 */ 584 cx_attr_nodiscard 585 CX_EXPORT cxstring cx_strchr(cxstring string, int chr); 586 587 /** 588 * Returns a substring starting at the location of the first occurrence of the 589 * specified character. 590 * 591 * If the string does not contain the character, an empty string is returned. 592 * 593 * @param string the string where to locate the character 594 * @param chr the character to locate 595 * @return a substring starting at the first location of @p chr 596 * 597 * @see cx_strchr() 598 */ 599 cx_attr_nodiscard 600 CX_EXPORT cxmutstr cx_strchr_m(cxmutstr string, int chr); 601 602 /** 603 * Returns a substring starting at the location of the last occurrence of the 604 * specified character. 605 * 606 * If the string does not contain the character, an empty string is returned. 607 * 608 * @param string the string where to locate the character 609 * @param chr the character to locate 610 * @return a substring starting at the last location of @p chr 611 * 612 * @see cx_strrchr_m() 613 */ 614 cx_attr_nodiscard 615 CX_EXPORT cxstring cx_strrchr(cxstring string, int chr); 616 617 /** 618 * Returns a substring starting at the location of the last occurrence of the 619 * specified character. 620 * 621 * If the string does not contain the character, an empty string is returned. 622 * 623 * @param string the string where to locate the character 624 * @param chr the character to locate 625 * @return a substring starting at the last location of @p chr 626 * 627 * @see cx_strrchr() 628 */ 629 cx_attr_nodiscard 630 CX_EXPORT cxmutstr cx_strrchr_m(cxmutstr string, int chr); 631 632 /** 633 * Returns a substring starting at the location of the first occurrence of the 634 * specified string. 635 * 636 * If @p haystack does not contain @p needle, an empty string is returned. 637 * 638 * If @p needle is an empty string, the complete @p haystack is 639 * returned. 640 * 641 * @param haystack the string to be scanned 642 * @param needle string containing the sequence of characters to match 643 * @return a substring starting at the first occurrence of 644 * @p needle, or an empty string, if the sequence is not 645 * contained 646 * @see cx_strstr_m() 647 */ 648 cx_attr_nodiscard 649 CX_EXPORT cxstring cx_strstr(cxstring haystack, cxstring needle); 650 651 /** 652 * Returns a substring starting at the location of the first occurrence of the 653 * specified string. 654 * 655 * If @p haystack does not contain @p needle, an empty string is returned. 656 * 657 * If @p needle is an empty string, the complete @p haystack is 658 * returned. 659 * 660 * @param haystack the string to be scanned 661 * @param needle string containing the sequence of characters to match 662 * @return a substring starting at the first occurrence of 663 * @p needle, or an empty string, if the sequence is not 664 * contained 665 * @see cx_strstr() 666 */ 667 cx_attr_nodiscard 668 CX_EXPORT cxmutstr cx_strstr_m(cxmutstr haystack, cxstring needle); 669 670 /** 671 * Splits a given string using a delimiter string. 672 * 673 * @note The resulting array contains strings that point to the source 674 * @p string. Use cx_strdup() to get copies. 675 * 676 * @param string the string to split 677 * @param delim the delimiter 678 * @param limit the maximum number of split items 679 * @param output a preallocated array of at least @p limit length 680 * @return the actual number of split items 681 */ 682 cx_attr_nodiscard cx_attr_nonnull cx_attr_access_w(4, 3) 683 CX_EXPORT size_t cx_strsplit(cxstring string, cxstring delim, 684 size_t limit, cxstring *output); 685 686 /** 687 * Splits a given string using a delimiter string. 688 * 689 * The array pointed to by @p output will be allocated by @p allocator. 690 * 691 * @note The resulting array contains strings that point to the source 692 * @p string. Use cx_strdup() to get copies. 693 * 694 * @attention If allocation fails, the @c NULL pointer will be written to 695 * @p output and the number returned will be zero. 696 * 697 * @param allocator the allocator to use for allocating the resulting array 698 * @param string the string to split 699 * @param delim the delimiter 700 * @param limit the maximum number of split items 701 * @param output a pointer where the address of the allocated array shall be 702 * written to 703 * @return the actual number of split items 704 */ 705 cx_attr_nodiscard cx_attr_nonnull cx_attr_access_w(5) 706 CX_EXPORT size_t cx_strsplit_a(const CxAllocator *allocator, 707 cxstring string, cxstring delim, 708 size_t limit, cxstring **output); 709 710 711 /** 712 * Splits a given string using a delimiter string. 713 * 714 * @note The resulting array contains strings that point to the source 715 * @p string. Use cx_strdup() to get copies. 716 * 717 * @param string the string to split 718 * @param delim the delimiter 719 * @param limit the maximum number of split items 720 * @param output a preallocated array of at least @p limit length 721 * @return the actual number of split items 722 */ 723 cx_attr_nodiscard cx_attr_nonnull cx_attr_access_w(4, 3) 724 CX_EXPORT size_t cx_strsplit_m(cxmutstr string, cxstring delim, 725 size_t limit, cxmutstr *output); 726 727 /** 728 * Splits a given string using a delimiter string. 729 * 730 * The array pointed to by @p output will be allocated by @p allocator. 731 * 732 * @note The resulting array contains strings that point to the source 733 * @p string. Use cx_strdup() to get copies. 734 * 735 * @attention If allocation fails, the @c NULL pointer will be written to 736 * @p output and the number returned will be zero. 737 * 738 * @param allocator the allocator to use for allocating the resulting array 739 * @param string the string to split 740 * @param delim the delimiter 741 * @param limit the maximum number of split items 742 * @param output a pointer where the address of the allocated array shall be 743 * written to 744 * @return the actual number of split items 745 */ 746 cx_attr_nodiscard cx_attr_nonnull cx_attr_access_w(5) 747 CX_EXPORT size_t cx_strsplit_ma(const CxAllocator *allocator, 748 cxmutstr string, cxstring delim, size_t limit, 749 cxmutstr **output); 750 751 /** 752 * Compares two strings. 753 * 754 * @param s1 the first string 755 * @param s2 the second string 756 * @return negative if @p s1 is smaller than @p s2, positive if @p s1 is larger 757 * than @p s2, zero if both strings equal 758 */ 759 cx_attr_nodiscard 760 CX_EXPORT int cx_strcmp_(cxstring s1, cxstring s2); 761 762 /** 763 * Compares two strings. 764 * 765 * @param s1 the first string 766 * @param s2 the second string 767 * @return negative if @p s1 is smaller than @p s2, positive if @p s1 is larger 768 * than @p s2, zero if both strings equal 769 */ 770 #define cx_strcmp(s1, s2) cx_strcmp_(cx_strcast(s1), cx_strcast(s2)) 771 772 /** 773 * Compares two strings ignoring case. 774 * 775 * @param s1 the first string 776 * @param s2 the second string 777 * @return negative if @p s1 is smaller than @p s2, positive if @p s1 is larger 778 * than @p s2, zero if both strings equal ignoring case 779 */ 780 cx_attr_nodiscard 781 CX_EXPORT int cx_strcasecmp_(cxstring s1, cxstring s2); 782 783 /** 784 * Compares two strings ignoring case. 785 * 786 * @param s1 the first string 787 * @param s2 the second string 788 * @return negative if @p s1 is smaller than @p s2, positive if @p s1 is larger 789 * than @p s2, zero if both strings equal ignoring case 790 */ 791 #define cx_strcasecmp(s1, s2) cx_strcasecmp_(cx_strcast(s1), cx_strcast(s2)) 792 793 /** 794 * Compares two strings. 795 * 796 * This function has a compatible signature for the use as a cx_compare_func. 797 * 798 * @attention This function can @em only compare UCX strings. It is unsafe to 799 * pass normal C-strings to this function. 800 * 801 * @param s1 the first string 802 * @param s2 the second string 803 * @return negative if @p s1 is smaller than @p s2, positive if @p s1 is larger 804 * than @p s2, zero if both strings equal 805 */ 806 cx_attr_nodiscard cx_attr_nonnull 807 CX_EXPORT int cx_strcmp_p(const void *s1, const void *s2); 808 809 /** 810 * Compares two strings ignoring case. 811 * 812 * This function has a compatible signature for the use as a cx_compare_func. 813 * 814 * @param s1 the first string 815 * @param s2 the second string 816 * @return negative if @p s1 is smaller than @p s2, positive if @p s1 is larger 817 * than @p s2, zero if both strings equal ignoring case 818 */ 819 cx_attr_nodiscard cx_attr_nonnull 820 CX_EXPORT int cx_strcasecmp_p(const void *s1, const void *s2); 821 822 823 /** 824 * Creates a duplicate of the specified string. 825 * 826 * The new string will contain a copy allocated by @p allocator. 827 * 828 * @note The returned string is guaranteed to be zero-terminated. 829 * 830 * @param allocator the allocator to use 831 * @param string the string to duplicate 832 * @return a duplicate of the string 833 * @see cx_strdup() 834 */ 835 cx_attr_nodiscard cx_attr_nonnull 836 CX_EXPORT cxmutstr cx_strdup_a_(const CxAllocator *allocator, cxstring string); 837 838 /** 839 * Creates a duplicate of the specified string. 840 * 841 * The new string will contain a copy allocated by @p allocator. 842 * 843 * @note The returned string is guaranteed to be zero-terminated. 844 * 845 * @param allocator (@c CxAllocator*) the allocator to use 846 * @param string the string to duplicate 847 * @return (@c cxmutstr) a duplicate of the string 848 * @see cx_strdup() 849 * @see cx_strfree_a() 850 */ 851 #define cx_strdup_a(allocator, string) cx_strdup_a_((allocator), cx_strcast(string)) 852 853 /** 854 * Creates a duplicate of the specified string. 855 * 856 * The new string will contain a copy allocated by the cxDefaultAllocator. 857 * So developers @em must pass the return value to cx_strfree(). 858 * 859 * @note The returned string is guaranteed to be zero-terminated. 860 * 861 * @param string the string to duplicate 862 * @return (@c cxmutstr) a duplicate of the string 863 * @see cx_strdup_a() 864 * @see cx_strfree() 865 */ 866 #define cx_strdup(string) cx_strdup_a(cxDefaultAllocator, string) 867 868 /** 869 * Omits leading and trailing spaces. 870 * 871 * @note the returned string references the same memory, thus you 872 * must @em not free the returned memory. 873 * 874 * @param string the string that shall be trimmed 875 * @return the trimmed string 876 */ 877 cx_attr_nodiscard 878 CX_EXPORT cxstring cx_strtrim(cxstring string); 879 880 /** 881 * Omits leading and trailing spaces. 882 * 883 * @note the returned string references the same memory, thus you 884 * must @em not free the returned memory. 885 * 886 * @param string the string that shall be trimmed 887 * @return the trimmed string 888 */ 889 cx_attr_nodiscard 890 CX_EXPORT cxmutstr cx_strtrim_m(cxmutstr string); 891 892 /** 893 * Checks if a string has a specific prefix. 894 * 895 * @param string the string to check 896 * @param prefix the prefix the string should have 897 * @return @c true, if and only if the string has the specified prefix, 898 * @c false otherwise 899 */ 900 cx_attr_nodiscard 901 CX_EXPORT bool cx_strprefix_(cxstring string, cxstring prefix); 902 903 /** 904 * Checks if a string has a specific prefix. 905 * 906 * @param string the string to check 907 * @param prefix the prefix the string should have 908 * @return @c true, if and only if the string has the specified prefix, 909 * @c false otherwise 910 */ 911 #define cx_strprefix(string, prefix) cx_strprefix_(cx_strcast(string), cx_strcast(prefix)) 912 913 /** 914 * Checks if a string has a specific suffix. 915 * 916 * @param string the string to check 917 * @param suffix the suffix the string should have 918 * @return @c true, if and only if the string has the specified suffix, 919 * @c false otherwise 920 */ 921 cx_attr_nodiscard 922 CX_EXPORT bool cx_strsuffix_(cxstring string, cxstring suffix); 923 924 /** 925 * Checks if a string has a specific suffix. 926 * 927 * @param string the string to check 928 * @param suffix the suffix the string should have 929 * @return @c true, if and only if the string has the specified suffix, 930 * @c false otherwise 931 */ 932 #define cx_strsuffix(string, suffix) cx_strsuffix_(cx_strcast(string), cx_strcast(suffix)) 933 934 /** 935 * Checks if a string has a specific prefix, ignoring the case. 936 * 937 * @param string the string to check 938 * @param prefix the prefix the string should have 939 * @return @c true, if and only if the string has the specified prefix, 940 * @c false otherwise 941 */ 942 cx_attr_nodiscard 943 CX_EXPORT bool cx_strcaseprefix_(cxstring string, cxstring prefix); 944 945 /** 946 * Checks if a string has a specific prefix, ignoring the case. 947 * 948 * @param string the string to check 949 * @param prefix the prefix the string should have 950 * @return @c true, if and only if the string has the specified prefix, 951 * @c false otherwise 952 */ 953 #define cx_strcaseprefix(string, prefix) cx_strcaseprefix_(cx_strcast(string), cx_strcast(prefix)) 954 955 /** 956 * Checks, if a string has a specific suffix, ignoring the case. 957 * 958 * @param string the string to check 959 * @param suffix the suffix the string should have 960 * @return @c true, if and only if the string has the specified suffix, 961 * @c false otherwise 962 */ 963 cx_attr_nodiscard 964 CX_EXPORT bool cx_strcasesuffix_(cxstring string, cxstring suffix); 965 966 /** 967 * Checks, if a string has a specific suffix, ignoring the case. 968 * 969 * @param string the string to check 970 * @param suffix the suffix the string should have 971 * @return @c true, if and only if the string has the specified suffix, 972 * @c false otherwise 973 */ 974 #define cx_strcasesuffix(string, suffix) cx_strcasesuffix_(cx_strcast(string), cx_strcast(suffix)) 975 976 /** 977 * Replaces a string with another string. 978 * 979 * The function replaces at most @p replmax occurrences. 980 * 981 * The returned string will be allocated by @p allocator 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 allocator the allocator to use 988 * @param str the string where replacements should be applied 989 * @param search the string to search for 990 * @param replacement the replacement string 991 * @param replmax maximum number of replacements 992 * @return the resulting string after applying the replacements 993 */ 994 cx_attr_nodiscard cx_attr_nonnull 995 CX_EXPORT cxmutstr cx_strreplacen_a(const CxAllocator *allocator, 996 cxstring str, cxstring search, cxstring replacement, size_t replmax); 997 998 /** 999 * Replaces a string with another string. 1000 * 1001 * The function replaces at most @p replmax occurrences. 1002 * 1003 * The returned string will be allocated by the cxDefaultAllocator and is guaranteed 1004 * to be zero-terminated. 1005 * 1006 * If allocation fails, or the input string is empty, 1007 * the returned string will be empty. 1008 * 1009 * @param str (@c cxstring) the string where replacements should be applied 1010 * @param search (@c cxstring) the string to search for 1011 * @param replacement (@c cxstring) the replacement string 1012 * @param replmax (@c size_t) maximum number of replacements 1013 * @return (@c cxmutstr) the resulting string after applying the replacements 1014 */ 1015 #define cx_strreplacen(str, search, replacement, replmax) \ 1016 cx_strreplacen_a(cxDefaultAllocator, str, search, replacement, replmax) 1017 1018 /** 1019 * Replaces a string with another string. 1020 * 1021 * The returned string will be allocated by @p allocator and is guaranteed 1022 * to be zero-terminated. 1023 * 1024 * If allocation fails, or the input string is empty, 1025 * the returned string will be empty. 1026 * 1027 * @param allocator (@c CxAllocator*) the allocator to use 1028 * @param str (@c cxstring) the string where replacements should be applied 1029 * @param search (@c cxstring) the string to search for 1030 * @param replacement (@c cxstring) the replacement string 1031 * @return (@c cxmutstr) the resulting string after applying the replacements 1032 */ 1033 #define cx_strreplace_a(allocator, str, search, replacement) \ 1034 cx_strreplacen_a(allocator, str, search, replacement, SIZE_MAX) 1035 1036 /** 1037 * Replaces a string with another string. 1038 * 1039 * The returned string will be allocated by the cxDefaultAllocator and is guaranteed 1040 * to be zero-terminated. 1041 * 1042 * If allocation fails, or the input string is empty, 1043 * the returned string will be empty. 1044 * 1045 * @param str (@c cxstring) the string where replacements should be applied 1046 * @param search (@c cxstring) the string to search for 1047 * @param replacement (@c cxstring) the replacement string 1048 * @return (@c cxmutstr) the resulting string after applying the replacements 1049 */ 1050 #define cx_strreplace(str, search, replacement) \ 1051 cx_strreplacen_a(cxDefaultAllocator, str, search, replacement, SIZE_MAX) 1052 1053 /** 1054 * Creates a string tokenization context. 1055 * 1056 * @param str the string to tokenize 1057 * @param delim the delimiter (must not be empty) 1058 * @param limit the maximum number of tokens that shall be returned 1059 * @return a new string tokenization context 1060 */ 1061 cx_attr_nodiscard 1062 CX_EXPORT CxStrtokCtx cx_strtok_(cxstring str, cxstring delim, size_t limit); 1063 1064 /** 1065 * Creates a string tokenization context. 1066 * 1067 * @param str the string to tokenize 1068 * @param delim the delimiter string (must not be empty) 1069 * @param limit (@c size_t) the maximum number of tokens that shall be returned 1070 * @return (@c CxStrtokCtx) a new string tokenization context 1071 */ 1072 #define cx_strtok(str, delim, limit) \ 1073 cx_strtok_(cx_strcast(str), cx_strcast(delim), (limit)) 1074 1075 /** 1076 * Returns the next token. 1077 * 1078 * The token will point to the source string. 1079 * 1080 * @param ctx the tokenization context 1081 * @param token a pointer to memory where the next token shall be stored 1082 * @return true if successful, false if the limit or the end of the string 1083 * has been reached 1084 */ 1085 cx_attr_nonnull cx_attr_nodiscard cx_attr_access_w(2) 1086 CX_EXPORT bool cx_strtok_next(CxStrtokCtx *ctx, cxstring *token); 1087 1088 /** 1089 * Returns the next token of a mutable string. 1090 * 1091 * The token will point to the source string. 1092 * 1093 * @attention 1094 * If the context was not initialized over a mutable string, modifying 1095 * the data of the returned token is undefined behavior. 1096 * 1097 * @param ctx the tokenization context 1098 * @param token a pointer to memory where the next token shall be stored 1099 * @return true if successful, false if the limit or the end of the string 1100 * has been reached 1101 */ 1102 cx_attr_nonnull cx_attr_nodiscard cx_attr_access_w(2) 1103 CX_EXPORT bool cx_strtok_next_m(CxStrtokCtx *ctx, cxmutstr *token); 1104 1105 /** 1106 * Defines an array of more delimiters for the specified tokenization context. 1107 * 1108 * @param ctx the tokenization context 1109 * @param delim array of more delimiters 1110 * @param count number of elements in the array 1111 */ 1112 cx_attr_nonnull cx_attr_access_r(2, 3) 1113 CX_EXPORT void cx_strtok_delim(CxStrtokCtx *ctx, const cxstring *delim, size_t count); 1114 1115 /* ------------------------------------------------------------------------- * 1116 * string to number conversion functions * 1117 * ------------------------------------------------------------------------- */ 1118 1119 /** 1120 * Converts a string to a number. 1121 * 1122 * The function returns non-zero when conversion is not possible. 1123 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1124 * It sets errno to ERANGE when the target datatype is too small. 1125 * 1126 * @param str the string to convert 1127 * @param output a pointer to the integer variable where the result shall be stored 1128 * @param base 2, 8, 10, or 16 1129 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1130 * @retval zero success 1131 * @retval non-zero conversion was not possible 1132 */ 1133 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1134 CX_EXPORT int cx_strtos_lc_(cxstring str, short *output, int base, const char *groupsep); 1135 1136 /** 1137 * Converts a string to a number. 1138 * 1139 * The function returns non-zero when conversion is not possible. 1140 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1141 * It sets errno to ERANGE when the target datatype is too small. 1142 * 1143 * @param str the string to convert 1144 * @param output a pointer to the integer variable where the result shall be stored 1145 * @param base 2, 8, 10, or 16 1146 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1147 * @retval zero success 1148 * @retval non-zero conversion was not possible 1149 */ 1150 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1151 CX_EXPORT int cx_strtoi_lc_(cxstring str, int *output, int base, const char *groupsep); 1152 1153 /** 1154 * Converts a string to a number. 1155 * 1156 * The function returns non-zero when conversion is not possible. 1157 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1158 * It sets errno to ERANGE when the target datatype is too small. 1159 * 1160 * @param str the string to convert 1161 * @param output a pointer to the integer variable where the result shall be stored 1162 * @param base 2, 8, 10, or 16 1163 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1164 * @retval zero success 1165 * @retval non-zero conversion was not possible 1166 */ 1167 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1168 CX_EXPORT int cx_strtol_lc_(cxstring str, long *output, int base, const char *groupsep); 1169 1170 /** 1171 * Converts a string to a number. 1172 * 1173 * The function returns non-zero when conversion is not possible. 1174 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1175 * It sets errno to ERANGE when the target datatype is too small. 1176 * 1177 * @param str the string to convert 1178 * @param output a pointer to the integer variable where the result shall be stored 1179 * @param base 2, 8, 10, or 16 1180 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1181 * @retval zero success 1182 * @retval non-zero conversion was not possible 1183 */ 1184 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1185 CX_EXPORT int cx_strtoll_lc_(cxstring str, long long *output, int base, const char *groupsep); 1186 1187 /** 1188 * Converts a string to a number. 1189 * 1190 * The function returns non-zero when conversion is not possible. 1191 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1192 * It sets errno to ERANGE when the target datatype is too small. 1193 * 1194 * @param str the string to convert 1195 * @param output a pointer to the integer variable where the result shall be stored 1196 * @param base 2, 8, 10, or 16 1197 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1198 * @retval zero success 1199 * @retval non-zero conversion was not possible 1200 */ 1201 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1202 CX_EXPORT int cx_strtoi8_lc_(cxstring str, int8_t *output, int base, const char *groupsep); 1203 1204 /** 1205 * Converts a string to a number. 1206 * 1207 * The function returns non-zero when conversion is not possible. 1208 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1209 * It sets errno to ERANGE when the target datatype is too small. 1210 * 1211 * @param str the string to convert 1212 * @param output a pointer to the integer variable where the result shall be stored 1213 * @param base 2, 8, 10, or 16 1214 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1215 * @retval zero success 1216 * @retval non-zero conversion was not possible 1217 */ 1218 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1219 CX_EXPORT int cx_strtoi16_lc_(cxstring str, int16_t *output, int base, const char *groupsep); 1220 1221 /** 1222 * Converts a string to a number. 1223 * 1224 * The function returns non-zero when conversion is not possible. 1225 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1226 * It sets errno to ERANGE when the target datatype is too small. 1227 * 1228 * @param str the string to convert 1229 * @param output a pointer to the integer variable where the result shall be stored 1230 * @param base 2, 8, 10, or 16 1231 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1232 * @retval zero success 1233 * @retval non-zero conversion was not possible 1234 */ 1235 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1236 CX_EXPORT int cx_strtoi32_lc_(cxstring str, int32_t *output, int base, const char *groupsep); 1237 1238 /** 1239 * Converts a string to a number. 1240 * 1241 * The function returns non-zero when conversion is not possible. 1242 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1243 * It sets errno to ERANGE when the target datatype is too small. 1244 * 1245 * @param str the string to convert 1246 * @param output a pointer to the integer variable where the result shall be stored 1247 * @param base 2, 8, 10, or 16 1248 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1249 * @retval zero success 1250 * @retval non-zero conversion was not possible 1251 */ 1252 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1253 CX_EXPORT int cx_strtoi64_lc_(cxstring str, int64_t *output, int base, const char *groupsep); 1254 1255 /** 1256 * Converts a string to a number. 1257 * 1258 * The function returns non-zero when conversion is not possible. 1259 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1260 * It sets errno to ERANGE when the target datatype is too small. 1261 * 1262 * @param str the string to convert 1263 * @param output a pointer to the integer variable where the result shall be stored 1264 * @param base 2, 8, 10, or 16 1265 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1266 * @retval zero success 1267 * @retval non-zero conversion was not possible 1268 */ 1269 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1270 CX_EXPORT int cx_strtous_lc_(cxstring str, unsigned short *output, int base, const char *groupsep); 1271 1272 /** 1273 * Converts a string to a number. 1274 * 1275 * The function returns non-zero when conversion is not possible. 1276 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1277 * It sets errno to ERANGE when the target datatype is too small. 1278 * 1279 * @param str the string to convert 1280 * @param output a pointer to the integer variable where the result shall be stored 1281 * @param base 2, 8, 10, or 16 1282 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1283 * @retval zero success 1284 * @retval non-zero conversion was not possible 1285 */ 1286 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1287 CX_EXPORT int cx_strtou_lc_(cxstring str, unsigned int *output, int base, const char *groupsep); 1288 1289 /** 1290 * Converts a string to a number. 1291 * 1292 * The function returns non-zero when conversion is not possible. 1293 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1294 * It sets errno to ERANGE when the target datatype is too small. 1295 * 1296 * @param str the string to convert 1297 * @param output a pointer to the integer variable where the result shall be stored 1298 * @param base 2, 8, 10, or 16 1299 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1300 * @retval zero success 1301 * @retval non-zero conversion was not possible 1302 */ 1303 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1304 CX_EXPORT int cx_strtoul_lc_(cxstring str, unsigned long *output, int base, const char *groupsep); 1305 1306 /** 1307 * Converts a string to a number. 1308 * 1309 * The function returns non-zero when conversion is not possible. 1310 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1311 * It sets errno to ERANGE when the target datatype is too small. 1312 * 1313 * @param str the string to convert 1314 * @param output a pointer to the integer variable where the result shall be stored 1315 * @param base 2, 8, 10, or 16 1316 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1317 * @retval zero success 1318 * @retval non-zero conversion was not possible 1319 */ 1320 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1321 CX_EXPORT int cx_strtoull_lc_(cxstring str, unsigned long long *output, int base, const char *groupsep); 1322 1323 /** 1324 * Converts a string to a number. 1325 * 1326 * The function returns non-zero when conversion is not possible. 1327 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1328 * It sets errno to ERANGE when the target datatype is too small. 1329 * 1330 * @param str the string to convert 1331 * @param output a pointer to the integer variable where the result shall be stored 1332 * @param base 2, 8, 10, or 16 1333 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1334 * @retval zero success 1335 * @retval non-zero conversion was not possible 1336 */ 1337 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1338 CX_EXPORT int cx_strtou8_lc_(cxstring str, uint8_t *output, int base, const char *groupsep); 1339 1340 /** 1341 * Converts a string to a number. 1342 * 1343 * The function returns non-zero when conversion is not possible. 1344 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1345 * It sets errno to ERANGE when the target datatype is too small. 1346 * 1347 * @param str the string to convert 1348 * @param output a pointer to the integer variable where the result shall be stored 1349 * @param base 2, 8, 10, or 16 1350 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1351 * @retval zero success 1352 * @retval non-zero conversion was not possible 1353 */ 1354 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1355 CX_EXPORT int cx_strtou16_lc_(cxstring str, uint16_t *output, int base, const char *groupsep); 1356 1357 /** 1358 * Converts a string to a number. 1359 * 1360 * The function returns non-zero when conversion is not possible. 1361 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1362 * It sets errno to ERANGE when the target datatype is too small. 1363 * 1364 * @param str the string to convert 1365 * @param output a pointer to the integer variable where the result shall be stored 1366 * @param base 2, 8, 10, or 16 1367 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1368 * @retval zero success 1369 * @retval non-zero conversion was not possible 1370 */ 1371 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1372 CX_EXPORT int cx_strtou32_lc_(cxstring str, uint32_t *output, int base, const char *groupsep); 1373 1374 /** 1375 * Converts a string to a number. 1376 * 1377 * The function returns non-zero when conversion is not possible. 1378 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1379 * It sets errno to ERANGE when the target datatype is too small. 1380 * 1381 * @param str the string to convert 1382 * @param output a pointer to the integer variable where the result shall be stored 1383 * @param base 2, 8, 10, or 16 1384 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1385 * @retval zero success 1386 * @retval non-zero conversion was not possible 1387 */ 1388 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1389 CX_EXPORT int cx_strtou64_lc_(cxstring str, uint64_t *output, int base, const char *groupsep); 1390 1391 /** 1392 * Converts a string to a number. 1393 * 1394 * The function returns non-zero when conversion is not possible. 1395 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1396 * It sets errno to ERANGE when the target datatype is too small. 1397 * 1398 * @param str the string to convert 1399 * @param output a pointer to the integer variable where the result shall be stored 1400 * @param base 2, 8, 10, or 16 1401 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1402 * @retval zero success 1403 * @retval non-zero conversion was not possible 1404 */ 1405 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1406 CX_EXPORT int cx_strtoz_lc_(cxstring str, size_t *output, int base, const char *groupsep); 1407 1408 /** 1409 * Converts a string to a single precision floating-point number. 1410 * 1411 * The function returns non-zero when conversion is not possible. 1412 * In that case the function sets errno to EINVAL when the reason is an invalid character. 1413 * It sets errno to ERANGE when the necessary representation would exceed the limits defined in libc's float.h. 1414 * 1415 * @param str the string to convert 1416 * @param output a pointer to the float variable where the result shall be stored 1417 * @param decsep the decimal separator 1418 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1419 * @retval zero success 1420 * @retval non-zero conversion was not possible 1421 */ 1422 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1423 CX_EXPORT int cx_strtof_lc_(cxstring str, float *output, char decsep, const char *groupsep); 1424 1425 /** 1426 * Converts a string to a double precision floating-point number. 1427 * 1428 * The function returns non-zero when conversion is not possible. 1429 * In that case the function sets errno to EINVAL when the reason is an invalid character. 1430 * It sets errno to ERANGE when the necessary representation would exceed the limits defined in libc's float.h. 1431 * 1432 * @param str the string to convert 1433 * @param output a pointer to the float variable where the result shall be stored 1434 * @param decsep the decimal separator 1435 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 1436 * @retval zero success 1437 * @retval non-zero conversion was not possible 1438 */ 1439 cx_attr_access_w(2) cx_attr_nonnull_arg(2) 1440 CX_EXPORT int cx_strtod_lc_(cxstring str, double *output, char decsep, const char *groupsep); 1441 1442 /** 1443 * Converts a string to a number. 1444 * 1445 * The function returns non-zero when conversion is not possible. 1446 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1447 * It sets errno to ERANGE when the target datatype is too small. 1448 * 1449 * @param str the string to convert 1450 * @param output a pointer to the integer variable where the result shall be stored 1451 * @param base 2, 8, 10, or 16 1452 * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion 1453 * @retval zero success 1454 * @retval non-zero conversion was not possible 1455 */ 1456 #define cx_strtos_lc(str, output, base, groupsep) cx_strtos_lc_(cx_strcast(str), output, base, groupsep) 1457 1458 /** 1459 * Converts a string to a number. 1460 * 1461 * The function returns non-zero when conversion is not possible. 1462 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1463 * It sets errno to ERANGE when the target datatype is too small. 1464 * 1465 * @param str the string to convert 1466 * @param output a pointer to the integer variable where the result shall be stored 1467 * @param base 2, 8, 10, or 16 1468 * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion 1469 * @retval zero success 1470 * @retval non-zero conversion was not possible 1471 */ 1472 #define cx_strtoi_lc(str, output, base, groupsep) cx_strtoi_lc_(cx_strcast(str), output, base, groupsep) 1473 1474 /** 1475 * Converts a string to a number. 1476 * 1477 * The function returns non-zero when conversion is not possible. 1478 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1479 * It sets errno to ERANGE when the target datatype is too small. 1480 * 1481 * @param str the string to convert 1482 * @param output a pointer to the integer variable where the result shall be stored 1483 * @param base 2, 8, 10, or 16 1484 * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion 1485 * @retval zero success 1486 * @retval non-zero conversion was not possible 1487 */ 1488 #define cx_strtol_lc(str, output, base, groupsep) cx_strtol_lc_(cx_strcast(str), output, base, groupsep) 1489 1490 /** 1491 * Converts a string to a number. 1492 * 1493 * The function returns non-zero when conversion is not possible. 1494 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1495 * It sets errno to ERANGE when the target datatype is too small. 1496 * 1497 * @param str the string to convert 1498 * @param output a pointer to the integer variable where the result shall be stored 1499 * @param base 2, 8, 10, or 16 1500 * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion 1501 * @retval zero success 1502 * @retval non-zero conversion was not possible 1503 */ 1504 #define cx_strtoll_lc(str, output, base, groupsep) cx_strtoll_lc_(cx_strcast(str), output, base, groupsep) 1505 1506 /** 1507 * Converts a string to a number. 1508 * 1509 * The function returns non-zero when conversion is not possible. 1510 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1511 * It sets errno to ERANGE when the target datatype is too small. 1512 * 1513 * @param str the string to convert 1514 * @param output a pointer to the integer variable where the result shall be stored 1515 * @param base 2, 8, 10, or 16 1516 * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion 1517 * @retval zero success 1518 * @retval non-zero conversion was not possible 1519 */ 1520 #define cx_strtoi8_lc(str, output, base, groupsep) cx_strtoi8_lc_(cx_strcast(str), output, base, groupsep) 1521 1522 /** 1523 * Converts a string to a number. 1524 * 1525 * The function returns non-zero when conversion is not possible. 1526 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1527 * It sets errno to ERANGE when the target datatype is too small. 1528 * 1529 * @param str the string to convert 1530 * @param output a pointer to the integer variable where the result shall be stored 1531 * @param base 2, 8, 10, or 16 1532 * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion 1533 * @retval zero success 1534 * @retval non-zero conversion was not possible 1535 */ 1536 #define cx_strtoi16_lc(str, output, base, groupsep) cx_strtoi16_lc_(cx_strcast(str), output, base, groupsep) 1537 1538 /** 1539 * Converts a string to a number. 1540 * 1541 * The function returns non-zero when conversion is not possible. 1542 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1543 * It sets errno to ERANGE when the target datatype is too small. 1544 * 1545 * @param str the string to convert 1546 * @param output a pointer to the integer variable where the result shall be stored 1547 * @param base 2, 8, 10, or 16 1548 * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion 1549 * @retval zero success 1550 * @retval non-zero conversion was not possible 1551 */ 1552 #define cx_strtoi32_lc(str, output, base, groupsep) cx_strtoi32_lc_(cx_strcast(str), output, base, groupsep) 1553 1554 /** 1555 * Converts a string to a number. 1556 * 1557 * The function returns non-zero when conversion is not possible. 1558 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1559 * It sets errno to ERANGE when the target datatype is too small. 1560 * 1561 * @param str the string to convert 1562 * @param output a pointer to the integer variable where the result shall be stored 1563 * @param base 2, 8, 10, or 16 1564 * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion 1565 * @retval zero success 1566 * @retval non-zero conversion was not possible 1567 */ 1568 #define cx_strtoi64_lc(str, output, base, groupsep) cx_strtoi64_lc_(cx_strcast(str), output, base, groupsep) 1569 1570 /** 1571 * Converts a string to a number. 1572 * 1573 * The function returns non-zero when conversion is not possible. 1574 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1575 * It sets errno to ERANGE when the target datatype is too small. 1576 * 1577 * @param str the string to convert 1578 * @param output a pointer to the integer variable where the result shall be stored 1579 * @param base 2, 8, 10, or 16 1580 * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion 1581 * @retval zero success 1582 * @retval non-zero conversion was not possible 1583 */ 1584 #define cx_strtous_lc(str, output, base, groupsep) cx_strtous_lc_(cx_strcast(str), output, base, groupsep) 1585 1586 /** 1587 * Converts a string to a number. 1588 * 1589 * The function returns non-zero when conversion is not possible. 1590 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1591 * It sets errno to ERANGE when the target datatype is too small. 1592 * 1593 * @param str the string to convert 1594 * @param output a pointer to the integer variable where the result shall be stored 1595 * @param base 2, 8, 10, or 16 1596 * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion 1597 * @retval zero success 1598 * @retval non-zero conversion was not possible 1599 */ 1600 #define cx_strtou_lc(str, output, base, groupsep) cx_strtou_lc_(cx_strcast(str), output, base, groupsep) 1601 1602 /** 1603 * Converts a string to a number. 1604 * 1605 * The function returns non-zero when conversion is not possible. 1606 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1607 * It sets errno to ERANGE when the target datatype is too small. 1608 * 1609 * @param str the string to convert 1610 * @param output a pointer to the integer variable where the result shall be stored 1611 * @param base 2, 8, 10, or 16 1612 * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion 1613 * @retval zero success 1614 * @retval non-zero conversion was not possible 1615 */ 1616 #define cx_strtoul_lc(str, output, base, groupsep) cx_strtoul_lc_(cx_strcast(str), output, base, groupsep) 1617 1618 /** 1619 * Converts a string to a number. 1620 * 1621 * The function returns non-zero when conversion is not possible. 1622 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1623 * It sets errno to ERANGE when the target datatype is too small. 1624 * 1625 * @param str the string to convert 1626 * @param output a pointer to the integer variable where the result shall be stored 1627 * @param base 2, 8, 10, or 16 1628 * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion 1629 * @retval zero success 1630 * @retval non-zero conversion was not possible 1631 */ 1632 #define cx_strtoull_lc(str, output, base, groupsep) cx_strtoull_lc_(cx_strcast(str), output, base, groupsep) 1633 1634 /** 1635 * Converts a string to a number. 1636 * 1637 * The function returns non-zero when conversion is not possible. 1638 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1639 * It sets errno to ERANGE when the target datatype is too small. 1640 * 1641 * @param str the string to convert 1642 * @param output a pointer to the integer variable where the result shall be stored 1643 * @param base 2, 8, 10, or 16 1644 * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion 1645 * @retval zero success 1646 * @retval non-zero conversion was not possible 1647 */ 1648 #define cx_strtou8_lc(str, output, base, groupsep) cx_strtou8_lc_(cx_strcast(str), output, base, groupsep) 1649 1650 /** 1651 * Converts a string to a number. 1652 * 1653 * The function returns non-zero when conversion is not possible. 1654 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1655 * It sets errno to ERANGE when the target datatype is too small. 1656 * 1657 * @param str the string to convert 1658 * @param output a pointer to the integer variable where the result shall be stored 1659 * @param base 2, 8, 10, or 16 1660 * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion 1661 * @retval zero success 1662 * @retval non-zero conversion was not possible 1663 */ 1664 #define cx_strtou16_lc(str, output, base, groupsep) cx_strtou16_lc_(cx_strcast(str), output, base, groupsep) 1665 1666 /** 1667 * Converts a string to a number. 1668 * 1669 * The function returns non-zero when conversion is not possible. 1670 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1671 * It sets errno to ERANGE when the target datatype is too small. 1672 * 1673 * @param str the string to convert 1674 * @param output a pointer to the integer variable where the result shall be stored 1675 * @param base 2, 8, 10, or 16 1676 * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion 1677 * @retval zero success 1678 * @retval non-zero conversion was not possible 1679 */ 1680 #define cx_strtou32_lc(str, output, base, groupsep) cx_strtou32_lc_(cx_strcast(str), output, base, groupsep) 1681 1682 /** 1683 * Converts a string to a number. 1684 * 1685 * The function returns non-zero when conversion is not possible. 1686 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1687 * It sets errno to ERANGE when the target datatype is too small. 1688 * 1689 * @param str the string to convert 1690 * @param output a pointer to the integer variable where the result shall be stored 1691 * @param base 2, 8, 10, or 16 1692 * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion 1693 * @retval zero success 1694 * @retval non-zero conversion was not possible 1695 */ 1696 #define cx_strtou64_lc(str, output, base, groupsep) cx_strtou64_lc_(cx_strcast(str), output, base, groupsep) 1697 1698 /** 1699 * Converts a string to a number. 1700 * 1701 * The function returns non-zero when conversion is not possible. 1702 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1703 * It sets errno to ERANGE when the target datatype is too small. 1704 * 1705 * @param str the string to convert 1706 * @param output a pointer to the integer variable where the result shall be stored 1707 * @param base 2, 8, 10, or 16 1708 * @param groupsep (@c const @c char*) each character in this string is treated as a group separator and ignored during conversion 1709 * @retval zero success 1710 * @retval non-zero conversion was not possible 1711 */ 1712 #define cx_strtoz_lc(str, output, base, groupsep) cx_strtoz_lc_(cx_strcast(str), output, base, groupsep) 1713 1714 /** 1715 * Converts a string to a number. 1716 * 1717 * The function returns non-zero when conversion is not possible. 1718 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1719 * It sets errno to ERANGE when the target datatype is too small. 1720 * 1721 * The comma character is treated as a group separator and ignored during parsing. 1722 * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()). 1723 * 1724 * @param str the string to convert 1725 * @param output a pointer to the integer variable where the result shall be stored 1726 * @param base 2, 8, 10, or 16 1727 * @retval zero success 1728 * @retval non-zero conversion was not possible 1729 */ 1730 #define cx_strtos(str, output, base) cx_strtos_lc_(cx_strcast(str), output, base, ",") 1731 1732 /** 1733 * Converts a string to a number. 1734 * 1735 * The function returns non-zero when conversion is not possible. 1736 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1737 * It sets errno to ERANGE when the target datatype is too small. 1738 * 1739 * The comma character is treated as a group separator and ignored during parsing. 1740 * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()). 1741 * 1742 * @param str the string to convert 1743 * @param output a pointer to the integer variable where the result shall be stored 1744 * @param base 2, 8, 10, or 16 1745 * @retval zero success 1746 * @retval non-zero conversion was not possible 1747 */ 1748 #define cx_strtoi(str, output, base) cx_strtoi_lc_(cx_strcast(str), output, base, ",") 1749 1750 /** 1751 * Converts a string to a number. 1752 * 1753 * The function returns non-zero when conversion is not possible. 1754 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1755 * It sets errno to ERANGE when the target datatype is too small. 1756 * 1757 * The comma character is treated as a group separator and ignored during parsing. 1758 * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()). 1759 * 1760 * @param str the string to convert 1761 * @param output a pointer to the integer variable where the result shall be stored 1762 * @param base 2, 8, 10, or 16 1763 * @retval zero success 1764 * @retval non-zero conversion was not possible 1765 */ 1766 #define cx_strtol(str, output, base) cx_strtol_lc_(cx_strcast(str), output, base, ",") 1767 1768 /** 1769 * Converts a string to a number. 1770 * 1771 * The function returns non-zero when conversion is not possible. 1772 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1773 * It sets errno to ERANGE when the target datatype is too small. 1774 * 1775 * The comma character is treated as a group separator and ignored during parsing. 1776 * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()). 1777 * 1778 * @param str the string to convert 1779 * @param output a pointer to the integer variable where the result shall be stored 1780 * @param base 2, 8, 10, or 16 1781 * @retval zero success 1782 * @retval non-zero conversion was not possible 1783 */ 1784 #define cx_strtoll(str, output, base) cx_strtoll_lc_(cx_strcast(str), output, base, ",") 1785 1786 /** 1787 * Converts a string to a number. 1788 * 1789 * The function returns non-zero when conversion is not possible. 1790 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1791 * It sets errno to ERANGE when the target datatype is too small. 1792 * 1793 * The comma character is treated as a group separator and ignored during parsing. 1794 * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()). 1795 * 1796 * @param str the string to convert 1797 * @param output a pointer to the integer variable where the result shall be stored 1798 * @param base 2, 8, 10, or 16 1799 * @retval zero success 1800 * @retval non-zero conversion was not possible 1801 */ 1802 #define cx_strtoi8(str, output, base) cx_strtoi8_lc_(cx_strcast(str), output, base, ",") 1803 1804 /** 1805 * Converts a string to a number. 1806 * 1807 * The function returns non-zero when conversion is not possible. 1808 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1809 * It sets errno to ERANGE when the target datatype is too small. 1810 * 1811 * The comma character is treated as a group separator and ignored during parsing. 1812 * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()). 1813 * 1814 * @param str the string to convert 1815 * @param output a pointer to the integer variable where the result shall be stored 1816 * @param base 2, 8, 10, or 16 1817 * @retval zero success 1818 * @retval non-zero conversion was not possible 1819 */ 1820 #define cx_strtoi16(str, output, base) cx_strtoi16_lc_(cx_strcast(str), output, base, ",") 1821 1822 /** 1823 * Converts a string to a number. 1824 * 1825 * The function returns non-zero when conversion is not possible. 1826 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1827 * It sets errno to ERANGE when the target datatype is too small. 1828 * 1829 * The comma character is treated as a group separator and ignored during parsing. 1830 * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()). 1831 * 1832 * @param str the string to convert 1833 * @param output a pointer to the integer variable where the result shall be stored 1834 * @param base 2, 8, 10, or 16 1835 * @retval zero success 1836 * @retval non-zero conversion was not possible 1837 */ 1838 #define cx_strtoi32(str, output, base) cx_strtoi32_lc_(cx_strcast(str), output, base, ",") 1839 1840 /** 1841 * Converts a string to a number. 1842 * 1843 * The function returns non-zero when conversion is not possible. 1844 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1845 * It sets errno to ERANGE when the target datatype is too small. 1846 * 1847 * The comma character is treated as a group separator and ignored during parsing. 1848 * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()). 1849 * 1850 * @param str the string to convert 1851 * @param output a pointer to the integer variable where the result shall be stored 1852 * @param base 2, 8, 10, or 16 1853 * @retval zero success 1854 * @retval non-zero conversion was not possible 1855 */ 1856 #define cx_strtoi64(str, output, base) cx_strtoi64_lc_(cx_strcast(str), output, base, ",") 1857 1858 /** 1859 * Converts a string to a number. 1860 * 1861 * The function returns non-zero when conversion is not possible. 1862 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1863 * It sets errno to ERANGE when the target datatype is too small. 1864 * 1865 * The comma character is treated as a group separator and ignored during parsing. 1866 * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()). 1867 * 1868 * @param str the string to convert 1869 * @param output a pointer to the integer variable where the result shall be stored 1870 * @param base 2, 8, 10, or 16 1871 * @retval zero success 1872 * @retval non-zero conversion was not possible 1873 */ 1874 #define cx_strtoz(str, output, base) cx_strtoz_lc_(cx_strcast(str), output, base, ",") 1875 1876 /** 1877 * Converts a string to a number. 1878 * 1879 * The function returns non-zero when conversion is not possible. 1880 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1881 * It sets errno to ERANGE when the target datatype is too small. 1882 * 1883 * The comma character is treated as a group separator and ignored during parsing. 1884 * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()). 1885 * 1886 * @param str the string to convert 1887 * @param output a pointer to the integer variable where the result shall be stored 1888 * @param base 2, 8, 10, or 16 1889 * @retval zero success 1890 * @retval non-zero conversion was not possible 1891 */ 1892 #define cx_strtous(str, output, base) cx_strtous_lc_(cx_strcast(str), output, base, ",") 1893 1894 /** 1895 * Converts a string to a number. 1896 * 1897 * The function returns non-zero when conversion is not possible. 1898 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1899 * It sets errno to ERANGE when the target datatype is too small. 1900 * 1901 * The comma character is treated as a group separator and ignored during parsing. 1902 * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()). 1903 * 1904 * @param str the string to convert 1905 * @param output a pointer to the integer variable where the result shall be stored 1906 * @param base 2, 8, 10, or 16 1907 * @retval zero success 1908 * @retval non-zero conversion was not possible 1909 */ 1910 #define cx_strtou(str, output, base) cx_strtou_lc_(cx_strcast(str), output, base, ",") 1911 1912 /** 1913 * Converts a string to a number. 1914 * 1915 * The function returns non-zero when conversion is not possible. 1916 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1917 * It sets errno to ERANGE when the target datatype is too small. 1918 * 1919 * The comma character is treated as a group separator and ignored during parsing. 1920 * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()). 1921 * 1922 * @param str the string to convert 1923 * @param output a pointer to the integer variable where the result shall be stored 1924 * @param base 2, 8, 10, or 16 1925 * @retval zero success 1926 * @retval non-zero conversion was not possible 1927 */ 1928 #define cx_strtoul(str, output, base) cx_strtoul_lc_(cx_strcast(str), output, base, ",") 1929 1930 /** 1931 * Converts a string to a number. 1932 * 1933 * The function returns non-zero when conversion is not possible. 1934 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1935 * It sets errno to ERANGE when the target datatype is too small. 1936 * 1937 * The comma character is treated as a group separator and ignored during parsing. 1938 * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()). 1939 * 1940 * @param str the string to convert 1941 * @param output a pointer to the integer variable where the result shall be stored 1942 * @param base 2, 8, 10, or 16 1943 * @retval zero success 1944 * @retval non-zero conversion was not possible 1945 */ 1946 #define cx_strtoull(str, output, base) cx_strtoull_lc_(cx_strcast(str), output, base, ",") 1947 1948 /** 1949 * Converts a string to a number. 1950 * 1951 * The function returns non-zero when conversion is not possible. 1952 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1953 * It sets errno to ERANGE when the target datatype is too small. 1954 * 1955 * The comma character is treated as a group separator and ignored during parsing. 1956 * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()). 1957 * 1958 * @param str the string to convert 1959 * @param output a pointer to the integer variable where the result shall be stored 1960 * @param base 2, 8, 10, or 16 1961 * @retval zero success 1962 * @retval non-zero conversion was not possible 1963 */ 1964 #define cx_strtou8(str, output, base) cx_strtou8_lc_(cx_strcast(str), output, base, ",") 1965 1966 /** 1967 * Converts a string to a number. 1968 * 1969 * The function returns non-zero when conversion is not possible. 1970 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1971 * It sets errno to ERANGE when the target datatype is too small. 1972 * 1973 * The comma character is treated as a group separator and ignored during parsing. 1974 * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()). 1975 * 1976 * @param str the string to convert 1977 * @param output a pointer to the integer variable where the result shall be stored 1978 * @param base 2, 8, 10, or 16 1979 * @retval zero success 1980 * @retval non-zero conversion was not possible 1981 */ 1982 #define cx_strtou16(str, output, base) cx_strtou16_lc_(cx_strcast(str), output, base, ",") 1983 1984 /** 1985 * Converts a string to a number. 1986 * 1987 * The function returns non-zero when conversion is not possible. 1988 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 1989 * It sets errno to ERANGE when the target datatype is too small. 1990 * 1991 * The comma character is treated as a group separator and ignored during parsing. 1992 * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()). 1993 * 1994 * @param str the string to convert 1995 * @param output a pointer to the integer variable where the result shall be stored 1996 * @param base 2, 8, 10, or 16 1997 * @retval zero success 1998 * @retval non-zero conversion was not possible 1999 */ 2000 #define cx_strtou32(str, output, base) cx_strtou32_lc_(cx_strcast(str), output, base, ",") 2001 2002 /** 2003 * Converts a string to a number. 2004 * 2005 * The function returns non-zero when conversion is not possible. 2006 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. 2007 * It sets errno to ERANGE when the target datatype is too small. 2008 * 2009 * The comma character is treated as a group separator and ignored during parsing. 2010 * If you want to choose the set of group separators, use the @c _lc variant of this function (e.g. cx_strtoz_lc()). 2011 * 2012 * @param str the string to convert 2013 * @param output a pointer to the integer variable where the result shall be stored 2014 * @param base 2, 8, 10, or 16 2015 * @retval zero success 2016 * @retval non-zero conversion was not possible 2017 */ 2018 #define cx_strtou64(str, output, base) cx_strtou64_lc_(cx_strcast(str), output, base, ",") 2019 2020 /** 2021 * Converts a string to a single precision floating-point number. 2022 * 2023 * The function returns non-zero when conversion is not possible. 2024 * In that case the function sets errno to EINVAL when the reason is an invalid character. 2025 * It sets errno to ERANGE when the necessary representation would exceed the limits defined in libc's float.h. 2026 * 2027 * @param str the string to convert 2028 * @param output a pointer to the float variable where the result shall be stored 2029 * @param decsep the decimal separator 2030 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 2031 * @retval zero success 2032 * @retval non-zero conversion was not possible 2033 */ 2034 #define cx_strtof_lc(str, output, decsep, groupsep) cx_strtof_lc_(cx_strcast(str), output, decsep, groupsep) 2035 2036 /** 2037 * Converts a string to a double precision floating-point number. 2038 * 2039 * The function returns non-zero when conversion is not possible. 2040 * In that case the function sets errno to EINVAL when the reason is an invalid character. 2041 * 2042 * @param str the string to convert 2043 * @param output a pointer to the double variable where the result shall be stored 2044 * @param decsep the decimal separator 2045 * @param groupsep each character in this string is treated as a group separator and ignored during conversion 2046 * @retval zero success 2047 * @retval non-zero conversion was not possible 2048 */ 2049 #define cx_strtod_lc(str, output, decsep, groupsep) cx_strtod_lc_(cx_strcast(str), output, decsep, groupsep) 2050 2051 /** 2052 * Converts a string to a single precision floating-point number. 2053 * 2054 * The function returns non-zero when conversion is not possible. 2055 * In that case the function sets errno to EINVAL when the reason is an invalid character. 2056 * It sets errno to ERANGE when the necessary representation would exceed the limits defined in libc's float.h. 2057 * 2058 * The decimal separator is assumed to be a dot character. 2059 * The comma character is treated as a group separator and ignored during parsing. 2060 * If you want to choose a different format, use cx_strtof_lc(). 2061 * 2062 * @param str the string to convert 2063 * @param output a pointer to the float variable where the result shall be stored 2064 * @retval zero success 2065 * @retval non-zero conversion was not possible 2066 */ 2067 #define cx_strtof(str, output) cx_strtof_lc_(cx_strcast(str), output, '.', ",") 2068 2069 /** 2070 * Converts a string to a double precision floating-point number. 2071 * 2072 * The function returns non-zero when conversion is not possible. 2073 * In that case the function sets errno to EINVAL when the reason is an invalid character. 2074 * 2075 * The decimal separator is assumed to be a dot character. 2076 * The comma character is treated as a group separator and ignored during parsing. 2077 * If you want to choose a different format, use cx_strtof_lc(). 2078 * 2079 * @param str the string to convert 2080 * @param output a pointer to the double variable where the result shall be stored 2081 * @retval zero success 2082 * @retval non-zero conversion was not possible 2083 */ 2084 #define cx_strtod(str, output) cx_strtod_lc_(cx_strcast(str), output, '.', ",") 2085 2086 #ifdef __cplusplus 2087 } // extern "C" 2088 #endif 2089 2090 #endif //UCX_STRING_H 2091