| 10:80f9d007cb52 | 11:0aa8cbd7912e |
|---|---|
| 40 #include "allocator.h" | 40 #include "allocator.h" |
| 41 | 41 |
| 42 /** | 42 /** |
| 43 * The maximum length of the "needle" in cx_strstr() that can use SBO. | 43 * The maximum length of the "needle" in cx_strstr() that can use SBO. |
| 44 */ | 44 */ |
| 45 extern unsigned const cx_strstr_sbo_size; | 45 extern const unsigned cx_strstr_sbo_size; |
| 46 | 46 |
| 47 /** | 47 /** |
| 48 * The UCX string structure. | 48 * The UCX string structure. |
| 49 */ | 49 */ |
| 50 struct cx_mutstr_s { | 50 struct cx_mutstr_s { |
| 70 /** | 70 /** |
| 71 * A pointer to the immutable string. | 71 * A pointer to the immutable string. |
| 72 * \note The string is not necessarily \c NULL terminated. | 72 * \note The string is not necessarily \c NULL terminated. |
| 73 * Always use the length. | 73 * Always use the length. |
| 74 */ | 74 */ |
| 75 char const *ptr; | 75 const char *ptr; |
| 76 /** The length of the string */ | 76 /** The length of the string */ |
| 77 size_t length; | 77 size_t length; |
| 78 }; | 78 }; |
| 79 | 79 |
| 80 /** | 80 /** |
| 95 */ | 95 */ |
| 96 cxstring delim; | 96 cxstring delim; |
| 97 /** | 97 /** |
| 98 * Optional array of more delimiters. | 98 * Optional array of more delimiters. |
| 99 */ | 99 */ |
| 100 cxstring const *delim_more; | 100 const cxstring *delim_more; |
| 101 /** | 101 /** |
| 102 * Length of the array containing more delimiters. | 102 * Length of the array containing more delimiters. |
| 103 */ | 103 */ |
| 104 size_t delim_more_count; | 104 size_t delim_more_count; |
| 105 /** | 105 /** |
| 170 * @param cstring the string to wrap, must be zero-terminated | 170 * @param cstring the string to wrap, must be zero-terminated |
| 171 * @return the wrapped string | 171 * @return the wrapped string |
| 172 * | 172 * |
| 173 * @see cx_mutstrn() | 173 * @see cx_mutstrn() |
| 174 */ | 174 */ |
| 175 __attribute__((__warn_unused_result__, __nonnull__)) | 175 cx_attr_nonnull |
| 176 cx_attr_nodiscard | |
| 177 cx_attr_cstr_arg(1) | |
| 176 cxmutstr cx_mutstr(char *cstring); | 178 cxmutstr cx_mutstr(char *cstring); |
| 177 | 179 |
| 178 /** | 180 /** |
| 179 * Wraps a string that does not need to be zero-terminated. | 181 * Wraps a string that does not need to be zero-terminated. |
| 180 * | 182 * |
| 189 * @param length the length of the string | 191 * @param length the length of the string |
| 190 * @return the wrapped string | 192 * @return the wrapped string |
| 191 * | 193 * |
| 192 * @see cx_mutstr() | 194 * @see cx_mutstr() |
| 193 */ | 195 */ |
| 194 __attribute__((__warn_unused_result__)) | 196 cx_attr_nodiscard |
| 197 cx_attr_access_rw(1, 2) | |
| 195 cxmutstr cx_mutstrn( | 198 cxmutstr cx_mutstrn( |
| 196 char *cstring, | 199 char *cstring, |
| 197 size_t length | 200 size_t length |
| 198 ); | 201 ); |
| 199 | 202 |
| 210 * @param cstring the string to wrap, must be zero-terminated | 213 * @param cstring the string to wrap, must be zero-terminated |
| 211 * @return the wrapped string | 214 * @return the wrapped string |
| 212 * | 215 * |
| 213 * @see cx_strn() | 216 * @see cx_strn() |
| 214 */ | 217 */ |
| 215 __attribute__((__warn_unused_result__, __nonnull__)) | 218 cx_attr_nonnull |
| 216 cxstring cx_str(char const *cstring); | 219 cx_attr_nodiscard |
| 220 cx_attr_cstr_arg(1) | |
| 221 cxstring cx_str(const char *cstring); | |
| 217 | 222 |
| 218 | 223 |
| 219 /** | 224 /** |
| 220 * Wraps a string that does not need to be zero-terminated. | 225 * Wraps a string that does not need to be zero-terminated. |
| 221 * | 226 * |
| 230 * @param length the length of the string | 235 * @param length the length of the string |
| 231 * @return the wrapped string | 236 * @return the wrapped string |
| 232 * | 237 * |
| 233 * @see cx_str() | 238 * @see cx_str() |
| 234 */ | 239 */ |
| 235 __attribute__((__warn_unused_result__)) | 240 cx_attr_nodiscard |
| 241 cx_attr_access_r(1, 2) | |
| 236 cxstring cx_strn( | 242 cxstring cx_strn( |
| 237 char const *cstring, | 243 const char *cstring, |
| 238 size_t length | 244 size_t length |
| 239 ); | 245 ); |
| 246 | |
| 247 #ifdef __cplusplus | |
| 248 } // extern "C" | |
| 249 cx_attr_nodiscard | |
| 250 static inline cxstring cx_strcast(cxmutstr str) { | |
| 251 return cx_strn(str.ptr, str.length); | |
| 252 } | |
| 253 cx_attr_nodiscard | |
| 254 static inline cxstring cx_strcast(cxstring str) { | |
| 255 return str; | |
| 256 } | |
| 257 extern "C" { | |
| 258 #else | |
| 259 /** | |
| 260 * Internal function, do not use. | |
| 261 * @param str | |
| 262 * @return | |
| 263 * @see cx_strcast() | |
| 264 */ | |
| 265 cx_attr_nodiscard | |
| 266 static inline cxstring cx_strcast_m(cxmutstr str) { | |
| 267 return (cxstring) {str.ptr, str.length}; | |
| 268 } | |
| 269 /** | |
| 270 * Internal function, do not use. | |
| 271 * @param str | |
| 272 * @return | |
| 273 * @see cx_strcast() | |
| 274 */ | |
| 275 cx_attr_nodiscard | |
| 276 static inline cxstring cx_strcast_c(cxstring str) { | |
| 277 return str; | |
| 278 } | |
| 240 | 279 |
| 241 /** | 280 /** |
| 242 * Casts a mutable string to an immutable string. | 281 * Casts a mutable string to an immutable string. |
| 243 * | 282 * |
| 244 * \note This is not seriously a cast. Instead you get a copy | 283 * Does nothing for already immutable strings. |
| 284 * | |
| 285 * \note This is not seriously a cast. Instead, you get a copy | |
| 245 * of the struct with the desired pointer type. Both structs still | 286 * of the struct with the desired pointer type. Both structs still |
| 246 * point to the same location, though! | 287 * point to the same location, though! |
| 247 * | 288 * |
| 248 * @param str the mutable string to cast | 289 * @param str the mutable string to cast |
| 249 * @return an immutable copy of the string pointer | 290 * @return an immutable copy of the string pointer |
| 250 */ | 291 */ |
| 251 __attribute__((__warn_unused_result__)) | 292 #define cx_strcast(str) _Generic((str), \ |
| 252 cxstring cx_strcast(cxmutstr str); | 293 cxmutstr: cx_strcast_m, \ |
| 294 cxstring: cx_strcast_c) \ | |
| 295 (str) | |
| 296 #endif | |
| 253 | 297 |
| 254 /** | 298 /** |
| 255 * Passes the pointer in this string to \c free(). | 299 * Passes the pointer in this string to \c free(). |
| 256 * | 300 * |
| 257 * The pointer in the struct is set to \c NULL and the length is set to zero. | 301 * The pointer in the struct is set to \c NULL and the length is set to zero. |
| 258 * | 302 * |
| 259 * \note There is no implementation for cxstring, because it is unlikely that | 303 * \note There is no implementation for cxstring, because it is unlikely that |
| 260 * you ever have a \c char \c const* you are really supposed to free. If you | 304 * you ever have a <code>const char*</code> you are really supposed to free. |
| 261 * encounter such situation, you should double-check your code. | 305 * If you encounter such situation, you should double-check your code. |
| 262 * | 306 * |
| 263 * @param str the string to free | 307 * @param str the string to free |
| 264 */ | 308 */ |
| 265 __attribute__((__nonnull__)) | |
| 266 void cx_strfree(cxmutstr *str); | 309 void cx_strfree(cxmutstr *str); |
| 267 | 310 |
| 268 /** | 311 /** |
| 269 * Passes the pointer in this string to the allocators free function. | 312 * Passes the pointer in this string to the allocators free function. |
| 270 * | 313 * |
| 271 * The pointer in the struct is set to \c NULL and the length is set to zero. | 314 * The pointer in the struct is set to \c NULL and the length is set to zero. |
| 272 * | 315 * |
| 273 * \note There is no implementation for cxstring, because it is unlikely that | 316 * \note There is no implementation for cxstring, because it is unlikely that |
| 274 * you ever have a \c char \c const* you are really supposed to free. If you | 317 * you ever have a <code>const char*</code> you are really supposed to free. |
| 275 * encounter such situation, you should double-check your code. | 318 * If you encounter such situation, you should double-check your code. |
| 276 * | 319 * |
| 277 * @param alloc the allocator | 320 * @param alloc the allocator |
| 278 * @param str the string to free | 321 * @param str the string to free |
| 279 */ | 322 */ |
| 280 __attribute__((__nonnull__)) | 323 cx_attr_nonnull_arg(1) |
| 281 void cx_strfree_a( | 324 void cx_strfree_a( |
| 282 CxAllocator const *alloc, | 325 const CxAllocator *alloc, |
| 283 cxmutstr *str | 326 cxmutstr *str |
| 284 ); | 327 ); |
| 285 | 328 |
| 286 /** | 329 /** |
| 287 * Returns the accumulated length of all specified strings. | 330 * Returns the accumulated length of all specified strings. |
| 331 * | |
| 332 * If this sum overflows, errno is set to EOVERFLOW. | |
| 288 * | 333 * |
| 289 * \attention if the count argument is larger than the number of the | 334 * \attention if the count argument is larger than the number of the |
| 290 * specified strings, the behavior is undefined. | 335 * specified strings, the behavior is undefined. |
| 291 * | 336 * |
| 292 * @param count the total number of specified strings | 337 * @param count the total number of specified strings |
| 293 * @param ... all strings | 338 * @param ... all strings |
| 294 * @return the accumulated length of all strings | 339 * @return the accumulated length of all strings |
| 295 */ | 340 */ |
| 296 __attribute__((__warn_unused_result__)) | 341 cx_attr_nodiscard |
| 297 size_t cx_strlen( | 342 size_t cx_strlen( |
| 298 size_t count, | 343 size_t count, |
| 299 ... | 344 ... |
| 300 ); | 345 ); |
| 301 | 346 |
| 306 * So developers \em must pass the return value to cx_strfree_a() eventually. | 351 * So developers \em must pass the return value to cx_strfree_a() eventually. |
| 307 * | 352 * |
| 308 * If \p str already contains a string, the memory will be reallocated and | 353 * If \p str already contains a string, the memory will be reallocated and |
| 309 * the other strings are appended. Otherwise, new memory is allocated. | 354 * the other strings are appended. Otherwise, new memory is allocated. |
| 310 * | 355 * |
| 311 * \note It is guaranteed that there is only one allocation. | 356 * If memory allocation fails, the pointer in the returned string will |
| 357 * be \c NULL. Depending on the allocator, \c errno might be set. | |
| 358 * | |
| 359 * \note It is guaranteed that there is only one allocation for the | |
| 360 * resulting string. | |
| 312 * It is also guaranteed that the returned string is zero-terminated. | 361 * It is also guaranteed that the returned string is zero-terminated. |
| 313 * | 362 * |
| 314 * @param alloc the allocator to use | 363 * @param alloc the allocator to use |
| 315 * @param str the string the other strings shall be concatenated to | 364 * @param str the string the other strings shall be concatenated to |
| 316 * @param count the number of the other following strings to concatenate | 365 * @param count the number of the other following strings to concatenate |
| 317 * @param ... all other strings | 366 * @param ... all other strings |
| 318 * @return the concatenated string | 367 * @return the concatenated string |
| 319 */ | 368 */ |
| 320 __attribute__((__warn_unused_result__, __nonnull__)) | 369 cx_attr_nodiscard |
| 370 cx_attr_nonnull | |
| 321 cxmutstr cx_strcat_ma( | 371 cxmutstr cx_strcat_ma( |
| 322 CxAllocator const *alloc, | 372 const CxAllocator *alloc, |
| 323 cxmutstr str, | 373 cxmutstr str, |
| 324 size_t count, | 374 size_t count, |
| 325 ... | 375 ... |
| 326 ); | 376 ); |
| 327 | 377 |
| 329 * Concatenates strings and returns a new string. | 379 * Concatenates strings and returns a new string. |
| 330 * | 380 * |
| 331 * The resulting string will be allocated by the specified allocator. | 381 * The resulting string will be allocated by the specified allocator. |
| 332 * So developers \em must pass the return value to cx_strfree_a() eventually. | 382 * So developers \em must pass the return value to cx_strfree_a() eventually. |
| 333 * | 383 * |
| 334 * \note It is guaranteed that there is only one allocation. | 384 * If memory allocation fails, the pointer in the returned string will |
| 385 * be \c NULL. Depending on the allocator, \c errno might be set. | |
| 386 * | |
| 387 * \note It is guaranteed that there is only one allocation for the | |
| 388 * resulting string. | |
| 335 * It is also guaranteed that the returned string is zero-terminated. | 389 * It is also guaranteed that the returned string is zero-terminated. |
| 336 * | 390 * |
| 337 * @param alloc the allocator to use | 391 * @param alloc the allocator to use |
| 338 * @param count the number of the other following strings to concatenate | 392 * @param count the number of the other following strings to concatenate |
| 339 * @param ... all other strings | 393 * @param ... all other strings |
| 346 * Concatenates strings and returns a new string. | 400 * Concatenates strings and returns a new string. |
| 347 * | 401 * |
| 348 * The resulting string will be allocated by standard \c malloc(). | 402 * The resulting string will be allocated by standard \c malloc(). |
| 349 * So developers \em must pass the return value to cx_strfree() eventually. | 403 * So developers \em must pass the return value to cx_strfree() eventually. |
| 350 * | 404 * |
| 351 * \note It is guaranteed that there is only one allocation. | 405 * If memory allocation fails, the pointer in the returned string will |
| 406 * be \c NULL and \c errno might be set. | |
| 407 * | |
| 408 * \note It is guaranteed that there is only one allocation for the | |
| 409 * resulting string. | |
| 352 * It is also guaranteed that the returned string is zero-terminated. | 410 * It is also guaranteed that the returned string is zero-terminated. |
| 353 * | 411 * |
| 354 * @param count the number of the other following strings to concatenate | 412 * @param count the number of the other following strings to concatenate |
| 355 * @param ... all other strings | 413 * @param ... all other strings |
| 356 * @return the concatenated string | 414 * @return the concatenated string |
| 365 * So developers \em must pass the return value to cx_strfree() eventually. | 423 * So developers \em must pass the return value to cx_strfree() eventually. |
| 366 * | 424 * |
| 367 * If \p str already contains a string, the memory will be reallocated and | 425 * If \p str already contains a string, the memory will be reallocated and |
| 368 * the other strings are appended. Otherwise, new memory is allocated. | 426 * the other strings are appended. Otherwise, new memory is allocated. |
| 369 * | 427 * |
| 370 * \note It is guaranteed that there is only one allocation. | 428 * If memory allocation fails, the pointer in the returned string will |
| 429 * be \c NULL and \c errno might be set. | |
| 430 * | |
| 431 * \note It is guaranteed that there is only one allocation for the | |
| 432 * resulting string. | |
| 371 * It is also guaranteed that the returned string is zero-terminated. | 433 * It is also guaranteed that the returned string is zero-terminated. |
| 372 * | 434 * |
| 373 * @param str the string the other strings shall be concatenated to | 435 * @param str the string the other strings shall be concatenated to |
| 374 * @param count the number of the other following strings to concatenate | 436 * @param count the number of the other following strings to concatenate |
| 375 * @param ... all other strings | 437 * @param ... all other strings |
| 391 * | 453 * |
| 392 * @see cx_strsubsl() | 454 * @see cx_strsubsl() |
| 393 * @see cx_strsubs_m() | 455 * @see cx_strsubs_m() |
| 394 * @see cx_strsubsl_m() | 456 * @see cx_strsubsl_m() |
| 395 */ | 457 */ |
| 396 __attribute__((__warn_unused_result__)) | 458 cx_attr_nodiscard |
| 397 cxstring cx_strsubs( | 459 cxstring cx_strsubs( |
| 398 cxstring string, | 460 cxstring string, |
| 399 size_t start | 461 size_t start |
| 400 ); | 462 ); |
| 401 | 463 |
| 416 * | 478 * |
| 417 * @see cx_strsubs() | 479 * @see cx_strsubs() |
| 418 * @see cx_strsubs_m() | 480 * @see cx_strsubs_m() |
| 419 * @see cx_strsubsl_m() | 481 * @see cx_strsubsl_m() |
| 420 */ | 482 */ |
| 421 __attribute__((__warn_unused_result__)) | 483 cx_attr_nodiscard |
| 422 cxstring cx_strsubsl( | 484 cxstring cx_strsubsl( |
| 423 cxstring string, | 485 cxstring string, |
| 424 size_t start, | 486 size_t start, |
| 425 size_t length | 487 size_t length |
| 426 ); | 488 ); |
| 438 * | 500 * |
| 439 * @see cx_strsubsl_m() | 501 * @see cx_strsubsl_m() |
| 440 * @see cx_strsubs() | 502 * @see cx_strsubs() |
| 441 * @see cx_strsubsl() | 503 * @see cx_strsubsl() |
| 442 */ | 504 */ |
| 443 __attribute__((__warn_unused_result__)) | 505 cx_attr_nodiscard |
| 444 cxmutstr cx_strsubs_m( | 506 cxmutstr cx_strsubs_m( |
| 445 cxmutstr string, | 507 cxmutstr string, |
| 446 size_t start | 508 size_t start |
| 447 ); | 509 ); |
| 448 | 510 |
| 463 * | 525 * |
| 464 * @see cx_strsubs_m() | 526 * @see cx_strsubs_m() |
| 465 * @see cx_strsubs() | 527 * @see cx_strsubs() |
| 466 * @see cx_strsubsl() | 528 * @see cx_strsubsl() |
| 467 */ | 529 */ |
| 468 __attribute__((__warn_unused_result__)) | 530 cx_attr_nodiscard |
| 469 cxmutstr cx_strsubsl_m( | 531 cxmutstr cx_strsubsl_m( |
| 470 cxmutstr string, | 532 cxmutstr string, |
| 471 size_t start, | 533 size_t start, |
| 472 size_t length | 534 size_t length |
| 473 ); | 535 ); |
| 482 * @param chr the character to locate | 544 * @param chr the character to locate |
| 483 * @return a substring starting at the first location of \p chr | 545 * @return a substring starting at the first location of \p chr |
| 484 * | 546 * |
| 485 * @see cx_strchr_m() | 547 * @see cx_strchr_m() |
| 486 */ | 548 */ |
| 487 __attribute__((__warn_unused_result__)) | 549 cx_attr_nodiscard |
| 488 cxstring cx_strchr( | 550 cxstring cx_strchr( |
| 489 cxstring string, | 551 cxstring string, |
| 490 int chr | 552 int chr |
| 491 ); | 553 ); |
| 492 | 554 |
| 500 * @param chr the character to locate | 562 * @param chr the character to locate |
| 501 * @return a substring starting at the first location of \p chr | 563 * @return a substring starting at the first location of \p chr |
| 502 * | 564 * |
| 503 * @see cx_strchr() | 565 * @see cx_strchr() |
| 504 */ | 566 */ |
| 505 __attribute__((__warn_unused_result__)) | 567 cx_attr_nodiscard |
| 506 cxmutstr cx_strchr_m( | 568 cxmutstr cx_strchr_m( |
| 507 cxmutstr string, | 569 cxmutstr string, |
| 508 int chr | 570 int chr |
| 509 ); | 571 ); |
| 510 | 572 |
| 518 * @param chr the character to locate | 580 * @param chr the character to locate |
| 519 * @return a substring starting at the last location of \p chr | 581 * @return a substring starting at the last location of \p chr |
| 520 * | 582 * |
| 521 * @see cx_strrchr_m() | 583 * @see cx_strrchr_m() |
| 522 */ | 584 */ |
| 523 __attribute__((__warn_unused_result__)) | 585 cx_attr_nodiscard |
| 524 cxstring cx_strrchr( | 586 cxstring cx_strrchr( |
| 525 cxstring string, | 587 cxstring string, |
| 526 int chr | 588 int chr |
| 527 ); | 589 ); |
| 528 | 590 |
| 536 * @param chr the character to locate | 598 * @param chr the character to locate |
| 537 * @return a substring starting at the last location of \p chr | 599 * @return a substring starting at the last location of \p chr |
| 538 * | 600 * |
| 539 * @see cx_strrchr() | 601 * @see cx_strrchr() |
| 540 */ | 602 */ |
| 541 __attribute__((__warn_unused_result__)) | 603 cx_attr_nodiscard |
| 542 cxmutstr cx_strrchr_m( | 604 cxmutstr cx_strrchr_m( |
| 543 cxmutstr string, | 605 cxmutstr string, |
| 544 int chr | 606 int chr |
| 545 ); | 607 ); |
| 546 | 608 |
| 558 * @return a substring starting at the first occurrence of | 620 * @return a substring starting at the first occurrence of |
| 559 * \p needle, or an empty string, if the sequence is not | 621 * \p needle, or an empty string, if the sequence is not |
| 560 * contained | 622 * contained |
| 561 * @see cx_strstr_m() | 623 * @see cx_strstr_m() |
| 562 */ | 624 */ |
| 563 __attribute__((__warn_unused_result__)) | 625 cx_attr_nodiscard |
| 564 cxstring cx_strstr( | 626 cxstring cx_strstr( |
| 565 cxstring haystack, | 627 cxstring haystack, |
| 566 cxstring needle | 628 cxstring needle |
| 567 ); | 629 ); |
| 568 | 630 |
| 580 * @return a substring starting at the first occurrence of | 642 * @return a substring starting at the first occurrence of |
| 581 * \p needle, or an empty string, if the sequence is not | 643 * \p needle, or an empty string, if the sequence is not |
| 582 * contained | 644 * contained |
| 583 * @see cx_strstr() | 645 * @see cx_strstr() |
| 584 */ | 646 */ |
| 585 __attribute__((__warn_unused_result__)) | 647 cx_attr_nodiscard |
| 586 cxmutstr cx_strstr_m( | 648 cxmutstr cx_strstr_m( |
| 587 cxmutstr haystack, | 649 cxmutstr haystack, |
| 588 cxstring needle | 650 cxstring needle |
| 589 ); | 651 ); |
| 590 | 652 |
| 598 * @param delim the delimiter | 660 * @param delim the delimiter |
| 599 * @param limit the maximum number of split items | 661 * @param limit the maximum number of split items |
| 600 * @param output a pre-allocated array of at least \p limit length | 662 * @param output a pre-allocated array of at least \p limit length |
| 601 * @return the actual number of split items | 663 * @return the actual number of split items |
| 602 */ | 664 */ |
| 603 __attribute__((__warn_unused_result__, __nonnull__)) | 665 cx_attr_nodiscard |
| 666 cx_attr_nonnull | |
| 667 cx_attr_access_w(4, 3) | |
| 604 size_t cx_strsplit( | 668 size_t cx_strsplit( |
| 605 cxstring string, | 669 cxstring string, |
| 606 cxstring delim, | 670 cxstring delim, |
| 607 size_t limit, | 671 size_t limit, |
| 608 cxstring *output | 672 cxstring *output |
| 625 * @param limit the maximum number of split items | 689 * @param limit the maximum number of split items |
| 626 * @param output a pointer where the address of the allocated array shall be | 690 * @param output a pointer where the address of the allocated array shall be |
| 627 * written to | 691 * written to |
| 628 * @return the actual number of split items | 692 * @return the actual number of split items |
| 629 */ | 693 */ |
| 630 __attribute__((__warn_unused_result__, __nonnull__)) | 694 cx_attr_nodiscard |
| 695 cx_attr_nonnull | |
| 696 cx_attr_access_w(5) | |
| 631 size_t cx_strsplit_a( | 697 size_t cx_strsplit_a( |
| 632 CxAllocator const *allocator, | 698 const CxAllocator *allocator, |
| 633 cxstring string, | 699 cxstring string, |
| 634 cxstring delim, | 700 cxstring delim, |
| 635 size_t limit, | 701 size_t limit, |
| 636 cxstring **output | 702 cxstring **output |
| 637 ); | 703 ); |
| 647 * @param delim the delimiter | 713 * @param delim the delimiter |
| 648 * @param limit the maximum number of split items | 714 * @param limit the maximum number of split items |
| 649 * @param output a pre-allocated array of at least \p limit length | 715 * @param output a pre-allocated array of at least \p limit length |
| 650 * @return the actual number of split items | 716 * @return the actual number of split items |
| 651 */ | 717 */ |
| 652 __attribute__((__warn_unused_result__, __nonnull__)) | 718 cx_attr_nodiscard |
| 719 cx_attr_nonnull | |
| 720 cx_attr_access_w(4, 3) | |
| 653 size_t cx_strsplit_m( | 721 size_t cx_strsplit_m( |
| 654 cxmutstr string, | 722 cxmutstr string, |
| 655 cxstring delim, | 723 cxstring delim, |
| 656 size_t limit, | 724 size_t limit, |
| 657 cxmutstr *output | 725 cxmutstr *output |
| 674 * @param limit the maximum number of split items | 742 * @param limit the maximum number of split items |
| 675 * @param output a pointer where the address of the allocated array shall be | 743 * @param output a pointer where the address of the allocated array shall be |
| 676 * written to | 744 * written to |
| 677 * @return the actual number of split items | 745 * @return the actual number of split items |
| 678 */ | 746 */ |
| 679 __attribute__((__warn_unused_result__, __nonnull__)) | 747 cx_attr_nodiscard |
| 748 cx_attr_nonnull | |
| 749 cx_attr_access_w(5) | |
| 680 size_t cx_strsplit_ma( | 750 size_t cx_strsplit_ma( |
| 681 CxAllocator const *allocator, | 751 const CxAllocator *allocator, |
| 682 cxmutstr string, | 752 cxmutstr string, |
| 683 cxstring delim, | 753 cxstring delim, |
| 684 size_t limit, | 754 size_t limit, |
| 685 cxmutstr **output | 755 cxmutstr **output |
| 686 ); | 756 ); |
| 691 * @param s1 the first string | 761 * @param s1 the first string |
| 692 * @param s2 the second string | 762 * @param s2 the second string |
| 693 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger | 763 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger |
| 694 * than \p s2, zero if both strings equal | 764 * than \p s2, zero if both strings equal |
| 695 */ | 765 */ |
| 696 __attribute__((__warn_unused_result__)) | 766 cx_attr_nodiscard |
| 697 int cx_strcmp( | 767 int cx_strcmp( |
| 698 cxstring s1, | 768 cxstring s1, |
| 699 cxstring s2 | 769 cxstring s2 |
| 700 ); | 770 ); |
| 701 | 771 |
| 705 * @param s1 the first string | 775 * @param s1 the first string |
| 706 * @param s2 the second string | 776 * @param s2 the second string |
| 707 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger | 777 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger |
| 708 * than \p s2, zero if both strings equal ignoring case | 778 * than \p s2, zero if both strings equal ignoring case |
| 709 */ | 779 */ |
| 710 __attribute__((__warn_unused_result__)) | 780 cx_attr_nodiscard |
| 711 int cx_strcasecmp( | 781 int cx_strcasecmp( |
| 712 cxstring s1, | 782 cxstring s1, |
| 713 cxstring s2 | 783 cxstring s2 |
| 714 ); | 784 ); |
| 715 | 785 |
| 721 * @param s1 the first string | 791 * @param s1 the first string |
| 722 * @param s2 the second string | 792 * @param s2 the second string |
| 723 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger | 793 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger |
| 724 * than \p s2, zero if both strings equal | 794 * than \p s2, zero if both strings equal |
| 725 */ | 795 */ |
| 726 __attribute__((__warn_unused_result__, __nonnull__)) | 796 cx_attr_nodiscard |
| 797 cx_attr_nonnull | |
| 727 int cx_strcmp_p( | 798 int cx_strcmp_p( |
| 728 void const *s1, | 799 const void *s1, |
| 729 void const *s2 | 800 const void *s2 |
| 730 ); | 801 ); |
| 731 | 802 |
| 732 /** | 803 /** |
| 733 * Compares two strings ignoring case. | 804 * Compares two strings ignoring case. |
| 734 * | 805 * |
| 737 * @param s1 the first string | 808 * @param s1 the first string |
| 738 * @param s2 the second string | 809 * @param s2 the second string |
| 739 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger | 810 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger |
| 740 * than \p s2, zero if both strings equal ignoring case | 811 * than \p s2, zero if both strings equal ignoring case |
| 741 */ | 812 */ |
| 742 __attribute__((__warn_unused_result__, __nonnull__)) | 813 cx_attr_nodiscard |
| 814 cx_attr_nonnull | |
| 743 int cx_strcasecmp_p( | 815 int cx_strcasecmp_p( |
| 744 void const *s1, | 816 const void *s1, |
| 745 void const *s2 | 817 const void *s2 |
| 746 ); | 818 ); |
| 747 | 819 |
| 748 | 820 |
| 749 /** | 821 /** |
| 750 * Creates a duplicate of the specified string. | 822 * Creates a duplicate of the specified string. |
| 756 * @param allocator the allocator to use | 828 * @param allocator the allocator to use |
| 757 * @param string the string to duplicate | 829 * @param string the string to duplicate |
| 758 * @return a duplicate of the string | 830 * @return a duplicate of the string |
| 759 * @see cx_strdup() | 831 * @see cx_strdup() |
| 760 */ | 832 */ |
| 761 __attribute__((__warn_unused_result__, __nonnull__)) | 833 cx_attr_nodiscard |
| 834 cx_attr_nonnull | |
| 762 cxmutstr cx_strdup_a( | 835 cxmutstr cx_strdup_a( |
| 763 CxAllocator const *allocator, | 836 const CxAllocator *allocator, |
| 764 cxstring string | 837 cxstring string |
| 765 ); | 838 ); |
| 766 | 839 |
| 767 /** | 840 /** |
| 768 * Creates a duplicate of the specified string. | 841 * Creates a duplicate of the specified string. |
| 814 * must \em not free the returned memory. | 887 * must \em not free the returned memory. |
| 815 * | 888 * |
| 816 * @param string the string that shall be trimmed | 889 * @param string the string that shall be trimmed |
| 817 * @return the trimmed string | 890 * @return the trimmed string |
| 818 */ | 891 */ |
| 819 __attribute__((__warn_unused_result__)) | 892 cx_attr_nodiscard |
| 820 cxstring cx_strtrim(cxstring string); | 893 cxstring cx_strtrim(cxstring string); |
| 821 | 894 |
| 822 /** | 895 /** |
| 823 * Omits leading and trailing spaces. | 896 * Omits leading and trailing spaces. |
| 824 * | 897 * |
| 826 * must \em not free the returned memory. | 899 * must \em not free the returned memory. |
| 827 * | 900 * |
| 828 * @param string the string that shall be trimmed | 901 * @param string the string that shall be trimmed |
| 829 * @return the trimmed string | 902 * @return the trimmed string |
| 830 */ | 903 */ |
| 831 __attribute__((__warn_unused_result__)) | 904 cx_attr_nodiscard |
| 832 cxmutstr cx_strtrim_m(cxmutstr string); | 905 cxmutstr cx_strtrim_m(cxmutstr string); |
| 833 | 906 |
| 834 /** | 907 /** |
| 835 * Checks, if a string has a specific prefix. | 908 * Checks, if a string has a specific prefix. |
| 836 * | 909 * |
| 837 * @param string the string to check | 910 * @param string the string to check |
| 838 * @param prefix the prefix the string should have | 911 * @param prefix the prefix the string should have |
| 839 * @return \c true, if and only if the string has the specified prefix, | 912 * @return \c true, if and only if the string has the specified prefix, |
| 840 * \c false otherwise | 913 * \c false otherwise |
| 841 */ | 914 */ |
| 842 __attribute__((__warn_unused_result__)) | 915 cx_attr_nodiscard |
| 843 bool cx_strprefix( | 916 bool cx_strprefix( |
| 844 cxstring string, | 917 cxstring string, |
| 845 cxstring prefix | 918 cxstring prefix |
| 846 ); | 919 ); |
| 847 | 920 |
| 851 * @param string the string to check | 924 * @param string the string to check |
| 852 * @param suffix the suffix the string should have | 925 * @param suffix the suffix the string should have |
| 853 * @return \c true, if and only if the string has the specified suffix, | 926 * @return \c true, if and only if the string has the specified suffix, |
| 854 * \c false otherwise | 927 * \c false otherwise |
| 855 */ | 928 */ |
| 856 __attribute__((__warn_unused_result__)) | 929 cx_attr_nodiscard |
| 857 bool cx_strsuffix( | 930 bool cx_strsuffix( |
| 858 cxstring string, | 931 cxstring string, |
| 859 cxstring suffix | 932 cxstring suffix |
| 860 ); | 933 ); |
| 861 | 934 |
| 865 * @param string the string to check | 938 * @param string the string to check |
| 866 * @param prefix the prefix the string should have | 939 * @param prefix the prefix the string should have |
| 867 * @return \c true, if and only if the string has the specified prefix, | 940 * @return \c true, if and only if the string has the specified prefix, |
| 868 * \c false otherwise | 941 * \c false otherwise |
| 869 */ | 942 */ |
| 870 __attribute__((__warn_unused_result__)) | 943 cx_attr_nodiscard |
| 871 bool cx_strcaseprefix( | 944 bool cx_strcaseprefix( |
| 872 cxstring string, | 945 cxstring string, |
| 873 cxstring prefix | 946 cxstring prefix |
| 874 ); | 947 ); |
| 875 | 948 |
| 879 * @param string the string to check | 952 * @param string the string to check |
| 880 * @param suffix the suffix the string should have | 953 * @param suffix the suffix the string should have |
| 881 * @return \c true, if and only if the string has the specified suffix, | 954 * @return \c true, if and only if the string has the specified suffix, |
| 882 * \c false otherwise | 955 * \c false otherwise |
| 883 */ | 956 */ |
| 884 __attribute__((__warn_unused_result__)) | 957 cx_attr_nodiscard |
| 885 bool cx_strcasesuffix( | 958 bool cx_strcasesuffix( |
| 886 cxstring string, | 959 cxstring string, |
| 887 cxstring suffix | 960 cxstring suffix |
| 888 ); | 961 ); |
| 889 | 962 |
| 924 * @param pattern the pattern to search for | 997 * @param pattern the pattern to search for |
| 925 * @param replacement the replacement string | 998 * @param replacement the replacement string |
| 926 * @param replmax maximum number of replacements | 999 * @param replmax maximum number of replacements |
| 927 * @return the resulting string after applying the replacements | 1000 * @return the resulting string after applying the replacements |
| 928 */ | 1001 */ |
| 929 __attribute__((__warn_unused_result__, __nonnull__)) | 1002 cx_attr_nodiscard |
| 1003 cx_attr_nonnull | |
| 930 cxmutstr cx_strreplacen_a( | 1004 cxmutstr cx_strreplacen_a( |
| 931 CxAllocator const *allocator, | 1005 const CxAllocator *allocator, |
| 932 cxstring str, | 1006 cxstring str, |
| 933 cxstring pattern, | 1007 cxstring pattern, |
| 934 cxstring replacement, | 1008 cxstring replacement, |
| 935 size_t replmax | 1009 size_t replmax |
| 936 ); | 1010 ); |
| 1002 * @param str the string to tokenize | 1076 * @param str the string to tokenize |
| 1003 * @param delim the delimiter (must not be empty) | 1077 * @param delim the delimiter (must not be empty) |
| 1004 * @param limit the maximum number of tokens that shall be returned | 1078 * @param limit the maximum number of tokens that shall be returned |
| 1005 * @return a new string tokenization context | 1079 * @return a new string tokenization context |
| 1006 */ | 1080 */ |
| 1007 __attribute__((__warn_unused_result__)) | 1081 cx_attr_nodiscard |
| 1008 CxStrtokCtx cx_strtok( | 1082 CxStrtokCtx cx_strtok( |
| 1009 cxstring str, | 1083 cxstring str, |
| 1010 cxstring delim, | 1084 cxstring delim, |
| 1011 size_t limit | 1085 size_t limit |
| 1012 ); | 1086 ); |
| 1017 * @param str the string to tokenize | 1091 * @param str the string to tokenize |
| 1018 * @param delim the delimiter (must not be empty) | 1092 * @param delim the delimiter (must not be empty) |
| 1019 * @param limit the maximum number of tokens that shall be returned | 1093 * @param limit the maximum number of tokens that shall be returned |
| 1020 * @return a new string tokenization context | 1094 * @return a new string tokenization context |
| 1021 */ | 1095 */ |
| 1022 __attribute__((__warn_unused_result__)) | 1096 cx_attr_nodiscard |
| 1023 CxStrtokCtx cx_strtok_m( | 1097 CxStrtokCtx cx_strtok_m( |
| 1024 cxmutstr str, | 1098 cxmutstr str, |
| 1025 cxstring delim, | 1099 cxstring delim, |
| 1026 size_t limit | 1100 size_t limit |
| 1027 ); | 1101 ); |
| 1034 * @param ctx the tokenization context | 1108 * @param ctx the tokenization context |
| 1035 * @param token a pointer to memory where the next token shall be stored | 1109 * @param token a pointer to memory where the next token shall be stored |
| 1036 * @return true if successful, false if the limit or the end of the string | 1110 * @return true if successful, false if the limit or the end of the string |
| 1037 * has been reached | 1111 * has been reached |
| 1038 */ | 1112 */ |
| 1039 __attribute__((__warn_unused_result__, __nonnull__)) | 1113 cx_attr_nonnull |
| 1114 cx_attr_nodiscard | |
| 1115 cx_attr_access_w(2) | |
| 1040 bool cx_strtok_next( | 1116 bool cx_strtok_next( |
| 1041 CxStrtokCtx *ctx, | 1117 CxStrtokCtx *ctx, |
| 1042 cxstring *token | 1118 cxstring *token |
| 1043 ); | 1119 ); |
| 1044 | 1120 |
| 1052 * @param ctx the tokenization context | 1128 * @param ctx the tokenization context |
| 1053 * @param token a pointer to memory where the next token shall be stored | 1129 * @param token a pointer to memory where the next token shall be stored |
| 1054 * @return true if successful, false if the limit or the end of the string | 1130 * @return true if successful, false if the limit or the end of the string |
| 1055 * has been reached | 1131 * has been reached |
| 1056 */ | 1132 */ |
| 1057 __attribute__((__warn_unused_result__, __nonnull__)) | 1133 cx_attr_nonnull |
| 1134 cx_attr_nodiscard | |
| 1135 cx_attr_access_w(2) | |
| 1058 bool cx_strtok_next_m( | 1136 bool cx_strtok_next_m( |
| 1059 CxStrtokCtx *ctx, | 1137 CxStrtokCtx *ctx, |
| 1060 cxmutstr *token | 1138 cxmutstr *token |
| 1061 ); | 1139 ); |
| 1062 | 1140 |
| 1065 * | 1143 * |
| 1066 * @param ctx the tokenization context | 1144 * @param ctx the tokenization context |
| 1067 * @param delim array of more delimiters | 1145 * @param delim array of more delimiters |
| 1068 * @param count number of elements in the array | 1146 * @param count number of elements in the array |
| 1069 */ | 1147 */ |
| 1070 __attribute__((__nonnull__)) | 1148 cx_attr_nonnull |
| 1149 cx_attr_access_r(2, 3) | |
| 1071 void cx_strtok_delim( | 1150 void cx_strtok_delim( |
| 1072 CxStrtokCtx *ctx, | 1151 CxStrtokCtx *ctx, |
| 1073 cxstring const *delim, | 1152 const cxstring *delim, |
| 1074 size_t count | 1153 size_t count |
| 1075 ); | 1154 ); |
| 1076 | 1155 |
| 1156 /* ------------------------------------------------------------------------- * | |
| 1157 * string to number conversion functions * | |
| 1158 * ------------------------------------------------------------------------- */ | |
| 1159 | |
| 1160 /** | |
| 1161 * \copydoc cx_strtouz_lc() | |
| 1162 */ | |
| 1163 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1164 int cx_strtos_lc(cxstring str, short *output, int base, const char *groupsep); | |
| 1165 /** | |
| 1166 * \copydoc cx_strtouz_lc() | |
| 1167 */ | |
| 1168 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1169 int cx_strtoi_lc(cxstring str, int *output, int base, const char *groupsep); | |
| 1170 /** | |
| 1171 * \copydoc cx_strtouz_lc() | |
| 1172 */ | |
| 1173 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1174 int cx_strtol_lc(cxstring str, long *output, int base, const char *groupsep); | |
| 1175 /** | |
| 1176 * \copydoc cx_strtouz_lc() | |
| 1177 */ | |
| 1178 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1179 int cx_strtoll_lc(cxstring str, long long *output, int base, const char *groupsep); | |
| 1180 /** | |
| 1181 * \copydoc cx_strtouz_lc() | |
| 1182 */ | |
| 1183 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1184 int cx_strtoi8_lc(cxstring str, int8_t *output, int base, const char *groupsep); | |
| 1185 /** | |
| 1186 * \copydoc cx_strtouz_lc() | |
| 1187 */ | |
| 1188 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1189 int cx_strtoi16_lc(cxstring str, int16_t *output, int base, const char *groupsep); | |
| 1190 /** | |
| 1191 * \copydoc cx_strtouz_lc() | |
| 1192 */ | |
| 1193 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1194 int cx_strtoi32_lc(cxstring str, int32_t *output, int base, const char *groupsep); | |
| 1195 /** | |
| 1196 * \copydoc cx_strtouz_lc() | |
| 1197 */ | |
| 1198 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1199 int cx_strtoi64_lc(cxstring str, int64_t *output, int base, const char *groupsep); | |
| 1200 /** | |
| 1201 * \copydoc cx_strtouz_lc() | |
| 1202 */ | |
| 1203 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1204 int cx_strtoz_lc(cxstring str, ssize_t *output, int base, const char *groupsep); | |
| 1205 /** | |
| 1206 * \copydoc cx_strtouz_lc() | |
| 1207 */ | |
| 1208 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1209 int cx_strtous_lc(cxstring str, unsigned short *output, int base, const char *groupsep); | |
| 1210 /** | |
| 1211 * \copydoc cx_strtouz_lc() | |
| 1212 */ | |
| 1213 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1214 int cx_strtou_lc(cxstring str, unsigned int *output, int base, const char *groupsep); | |
| 1215 /** | |
| 1216 * \copydoc cx_strtouz_lc() | |
| 1217 */ | |
| 1218 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1219 int cx_strtoul_lc(cxstring str, unsigned long *output, int base, const char *groupsep); | |
| 1220 /** | |
| 1221 * \copydoc cx_strtouz_lc() | |
| 1222 */ | |
| 1223 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1224 int cx_strtoull_lc(cxstring str, unsigned long long *output, int base, const char *groupsep); | |
| 1225 /** | |
| 1226 * \copydoc cx_strtouz_lc() | |
| 1227 */ | |
| 1228 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1229 int cx_strtou8_lc(cxstring str, uint8_t *output, int base, const char *groupsep); | |
| 1230 /** | |
| 1231 * \copydoc cx_strtouz_lc() | |
| 1232 */ | |
| 1233 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1234 int cx_strtou16_lc(cxstring str, uint16_t *output, int base, const char *groupsep); | |
| 1235 /** | |
| 1236 * \copydoc cx_strtouz_lc() | |
| 1237 */ | |
| 1238 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1239 int cx_strtou32_lc(cxstring str, uint32_t *output, int base, const char *groupsep); | |
| 1240 /** | |
| 1241 * \copydoc cx_strtouz_lc() | |
| 1242 */ | |
| 1243 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1244 int cx_strtou64_lc(cxstring str, uint64_t *output, int base, const char *groupsep); | |
| 1245 | |
| 1246 /** | |
| 1247 * Converts a string to a number. | |
| 1248 * | |
| 1249 * The function returns non-zero when conversion is not possible. | |
| 1250 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. | |
| 1251 * It sets errno to ERANGE when the target datatype is too small. | |
| 1252 * | |
| 1253 * @param str the string to convert | |
| 1254 * @param output a pointer to the integer variable where the result shall be stored | |
| 1255 * @param base 2, 8, 10, or 16 | |
| 1256 * @param groupsep each character in this string is treated as group separator and ignored during conversion | |
| 1257 * @return zero on success, non-zero if conversion was not possible | |
| 1258 */ | |
| 1259 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1260 int cx_strtouz_lc(cxstring str, size_t *output, int base, const char *groupsep); | |
| 1261 | |
| 1262 /** | |
| 1263 * Converts a string to a single precision floating point number. | |
| 1264 * | |
| 1265 * The function returns non-zero when conversion is not possible. | |
| 1266 * In that case the function sets errno to EINVAL when the reason is an invalid character. | |
| 1267 * It sets errno to ERANGE when the necessary representation would exceed the limits defined in libc's float.h. | |
| 1268 * | |
| 1269 * The decimal separator is assumed to be a dot character. | |
| 1270 * The comma character is treated as group separator and ignored during parsing. | |
| 1271 * If you want to choose a different format, use cx_strtof_lc(). | |
| 1272 * | |
| 1273 * @param str the string to convert | |
| 1274 * @param output a pointer to the float variable where the result shall be stored | |
| 1275 * @param decsep the decimal separator | |
| 1276 * @param groupsep each character in this string is treated as group separator and ignored during conversion | |
| 1277 * @return zero on success, non-zero if conversion was not possible | |
| 1278 */ | |
| 1279 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1280 int cx_strtof_lc(cxstring str, float *output, char decsep, const char *groupsep); | |
| 1281 | |
| 1282 /** | |
| 1283 * Converts a string to a double precision floating point number. | |
| 1284 * | |
| 1285 * The function returns non-zero when conversion is not possible. | |
| 1286 * In that case the function sets errno to EINVAL when the reason is an invalid character. | |
| 1287 * It sets errno to ERANGE when the necessary representation would exceed the limits defined in libc's float.h. | |
| 1288 * | |
| 1289 * The decimal separator is assumed to be a dot character. | |
| 1290 * The comma character is treated as group separator and ignored during parsing. | |
| 1291 * If you want to choose a different format, use cx_strtof_lc(). | |
| 1292 * | |
| 1293 * @param str the string to convert | |
| 1294 * @param output a pointer to the float variable where the result shall be stored | |
| 1295 * @param decsep the decimal separator | |
| 1296 * @param groupsep each character in this string is treated as group separator and ignored during conversion | |
| 1297 * @return zero on success, non-zero if conversion was not possible | |
| 1298 */ | |
| 1299 cx_attr_access_w(2) cx_attr_nonnull_arg(2) | |
| 1300 int cx_strtod_lc(cxstring str, double *output, char decsep, const char *groupsep); | |
| 1301 | |
| 1302 #ifndef CX_STR_IMPLEMENTATION | |
| 1303 /** | |
| 1304 * \copydoc cx_strtouz_lc() | |
| 1305 */ | |
| 1306 #define cx_strtos_lc(str, output, base, groupsep) cx_strtos_lc(cx_strcast(str), output, base, groupsep) | |
| 1307 /** | |
| 1308 * \copydoc cx_strtouz_lc() | |
| 1309 */ | |
| 1310 #define cx_strtoi_lc(str, output, base, groupsep) cx_strtoi_lc(cx_strcast(str), output, base, groupsep) | |
| 1311 /** | |
| 1312 * \copydoc cx_strtouz_lc() | |
| 1313 */ | |
| 1314 #define cx_strtol_lc(str, output, base, groupsep) cx_strtol_lc(cx_strcast(str), output, base, groupsep) | |
| 1315 /** | |
| 1316 * \copydoc cx_strtouz_lc() | |
| 1317 */ | |
| 1318 #define cx_strtoll_lc(str, output, base, groupsep) cx_strtoll_lc(cx_strcast(str), output, base, groupsep) | |
| 1319 /** | |
| 1320 * \copydoc cx_strtouz_lc() | |
| 1321 */ | |
| 1322 #define cx_strtoi8_lc(str, output, base, groupsep) cx_strtoi8_lc(cx_strcast(str), output, base, groupsep) | |
| 1323 /** | |
| 1324 * \copydoc cx_strtouz_lc() | |
| 1325 */ | |
| 1326 #define cx_strtoi16_lc(str, output, base, groupsep) cx_strtoi16_lc(cx_strcast(str), output, base, groupsep) | |
| 1327 /** | |
| 1328 * \copydoc cx_strtouz_lc() | |
| 1329 */ | |
| 1330 #define cx_strtoi32_lc(str, output, base, groupsep) cx_strtoi32_lc(cx_strcast(str), output, base, groupsep) | |
| 1331 /** | |
| 1332 * \copydoc cx_strtouz_lc() | |
| 1333 */ | |
| 1334 #define cx_strtoi64_lc(str, output, base, groupsep) cx_strtoi64_lc(cx_strcast(str), output, base, groupsep) | |
| 1335 /** | |
| 1336 * \copydoc cx_strtouz_lc() | |
| 1337 */ | |
| 1338 #define cx_strtoz_lc(str, output, base, groupsep) cx_strtoz_lc(cx_strcast(str), output, base, groupsep) | |
| 1339 /** | |
| 1340 * \copydoc cx_strtouz_lc() | |
| 1341 */ | |
| 1342 #define cx_strtous_lc(str, output, base, groupsep) cx_strtous_lc(cx_strcast(str), output, base, groupsep) | |
| 1343 /** | |
| 1344 * \copydoc cx_strtouz_lc() | |
| 1345 */ | |
| 1346 #define cx_strtou_lc(str, output, base, groupsep) cx_strtou_lc(cx_strcast(str), output, base, groupsep) | |
| 1347 /** | |
| 1348 * \copydoc cx_strtouz_lc() | |
| 1349 */ | |
| 1350 #define cx_strtoul_lc(str, output, base, groupsep) cx_strtoul_lc(cx_strcast(str), output, base, groupsep) | |
| 1351 /** | |
| 1352 * \copydoc cx_strtouz_lc() | |
| 1353 */ | |
| 1354 #define cx_strtoull_lc(str, output, base, groupsep) cx_strtoull_lc(cx_strcast(str), output, base, groupsep) | |
| 1355 /** | |
| 1356 * \copydoc cx_strtouz_lc() | |
| 1357 */ | |
| 1358 #define cx_strtou8_lc(str, output, base, groupsep) cx_strtou8_lc(cx_strcast(str), output, base, groupsep) | |
| 1359 /** | |
| 1360 * \copydoc cx_strtouz_lc() | |
| 1361 */ | |
| 1362 #define cx_strtou16_lc(str, output, base, groupsep) cx_strtou16_lc(cx_strcast(str), output, base, groupsep) | |
| 1363 /** | |
| 1364 * \copydoc cx_strtouz_lc() | |
| 1365 */ | |
| 1366 #define cx_strtou32_lc(str, output, base, groupsep) cx_strtou32_lc(cx_strcast(str), output, base, groupsep) | |
| 1367 /** | |
| 1368 * \copydoc cx_strtouz_lc() | |
| 1369 */ | |
| 1370 #define cx_strtou64_lc(str, output, base, groupsep) cx_strtou64_lc(cx_strcast(str), output, base, groupsep) | |
| 1371 /** | |
| 1372 * Converts a string to a number. | |
| 1373 * | |
| 1374 * The function returns non-zero when conversion is not possible. | |
| 1375 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. | |
| 1376 * It sets errno to ERANGE when the target datatype is too small. | |
| 1377 * | |
| 1378 * @param str the string to convert | |
| 1379 * @param output a pointer to the integer variable where the result shall be stored | |
| 1380 * @param base 2, 8, 10, or 16 | |
| 1381 * @param groupsep each character in this string is treated as group separator and ignored during conversion | |
| 1382 * @return zero on success, non-zero if conversion was not possible | |
| 1383 */ | |
| 1384 #define cx_strtouz_lc(str, output, base, groupsep) cx_strtouz_lc(cx_strcast(str), output, base, groupsep) | |
| 1385 | |
| 1386 /** | |
| 1387 * \copydoc cx_strtouz() | |
| 1388 */ | |
| 1389 #define cx_strtos(str, output, base) cx_strtos_lc(str, output, base, ",") | |
| 1390 /** | |
| 1391 * \copydoc cx_strtouz() | |
| 1392 */ | |
| 1393 #define cx_strtoi(str, output, base) cx_strtoi_lc(str, output, base, ",") | |
| 1394 /** | |
| 1395 * \copydoc cx_strtouz() | |
| 1396 */ | |
| 1397 #define cx_strtol(str, output, base) cx_strtol_lc(str, output, base, ",") | |
| 1398 /** | |
| 1399 * \copydoc cx_strtouz() | |
| 1400 */ | |
| 1401 #define cx_strtoll(str, output, base) cx_strtoll_lc(str, output, base, ",") | |
| 1402 /** | |
| 1403 * \copydoc cx_strtouz() | |
| 1404 */ | |
| 1405 #define cx_strtoi8(str, output, base) cx_strtoi8_lc(str, output, base, ",") | |
| 1406 /** | |
| 1407 * \copydoc cx_strtouz() | |
| 1408 */ | |
| 1409 #define cx_strtoi16(str, output, base) cx_strtoi16_lc(str, output, base, ",") | |
| 1410 /** | |
| 1411 * \copydoc cx_strtouz() | |
| 1412 */ | |
| 1413 #define cx_strtoi32(str, output, base) cx_strtoi32_lc(str, output, base, ",") | |
| 1414 /** | |
| 1415 * \copydoc cx_strtouz() | |
| 1416 */ | |
| 1417 #define cx_strtoi64(str, output, base) cx_strtoi64_lc(str, output, base, ",") | |
| 1418 /** | |
| 1419 * \copydoc cx_strtouz() | |
| 1420 */ | |
| 1421 #define cx_strtoz(str, output, base) cx_strtoz_lc(str, output, base, ",") | |
| 1422 /** | |
| 1423 * \copydoc cx_strtouz() | |
| 1424 */ | |
| 1425 #define cx_strtous(str, output, base) cx_strtous_lc(str, output, base, ",") | |
| 1426 /** | |
| 1427 * \copydoc cx_strtouz() | |
| 1428 */ | |
| 1429 #define cx_strtou(str, output, base) cx_strtou_lc(str, output, base, ",") | |
| 1430 /** | |
| 1431 * \copydoc cx_strtouz() | |
| 1432 */ | |
| 1433 #define cx_strtoul(str, output, base) cx_strtoul_lc(str, output, base, ",") | |
| 1434 /** | |
| 1435 * \copydoc cx_strtouz() | |
| 1436 */ | |
| 1437 #define cx_strtoull(str, output, base) cx_strtoull_lc(str, output, base, ",") | |
| 1438 /** | |
| 1439 * \copydoc cx_strtouz() | |
| 1440 */ | |
| 1441 #define cx_strtou8(str, output, base) cx_strtou8_lc(str, output, base, ",") | |
| 1442 /** | |
| 1443 * \copydoc cx_strtouz() | |
| 1444 */ | |
| 1445 #define cx_strtou16(str, output, base) cx_strtou16_lc(str, output, base, ",") | |
| 1446 /** | |
| 1447 * \copydoc cx_strtouz() | |
| 1448 */ | |
| 1449 #define cx_strtou32(str, output, base) cx_strtou32_lc(str, output, base, ",") | |
| 1450 /** | |
| 1451 * \copydoc cx_strtouz() | |
| 1452 */ | |
| 1453 #define cx_strtou64(str, output, base) cx_strtou64_lc(str, output, base, ",") | |
| 1454 /** | |
| 1455 * Converts a string to a number. | |
| 1456 * | |
| 1457 * The function returns non-zero when conversion is not possible. | |
| 1458 * In that case the function sets errno to EINVAL when the reason is an invalid character or an unsupported base. | |
| 1459 * It sets errno to ERANGE when the target datatype is too small. | |
| 1460 * | |
| 1461 * The comma character is treated as group separator and ignored during parsing. | |
| 1462 * If you want to choose the set of group separators, use the \c _lc variant of this function (e.g. cx_strtouz_lc()). | |
| 1463 * | |
| 1464 * @param str the string to convert | |
| 1465 * @param output a pointer to the integer variable where the result shall be stored | |
| 1466 * @param base 2, 8, 10, or 16 | |
| 1467 * @return zero on success, non-zero if conversion was not possible | |
| 1468 */ | |
| 1469 #define cx_strtouz(str, output, base) cx_strtouz_lc(str, output, base, ",") | |
| 1470 | |
| 1471 /** | |
| 1472 * Converts a string to a single precision floating point number. | |
| 1473 * | |
| 1474 * The function returns non-zero when conversion is not possible. | |
| 1475 * In that case the function sets errno to EINVAL when the reason is an invalid character. | |
| 1476 * It sets errno to ERANGE when the necessary representation would exceed the limits defined in libc's float.h. | |
| 1477 * | |
| 1478 * The decimal separator is assumed to be a dot character. | |
| 1479 * The comma character is treated as group separator and ignored during parsing. | |
| 1480 * If you want to choose a different format, use cx_strtof_lc(). | |
| 1481 * | |
| 1482 * @param str the string to convert | |
| 1483 * @param output a pointer to the float variable where the result shall be stored | |
| 1484 * @param decsep the decimal separator | |
| 1485 * @param groupsep each character in this string is treated as group separator and ignored during conversion | |
| 1486 * @return zero on success, non-zero if conversion was not possible | |
| 1487 */ | |
| 1488 #define cx_strtof_lc(str, output, decsep, groupsep) cx_strtof_lc(cx_strcast(str), output, decsep, groupsep) | |
| 1489 /** | |
| 1490 * Converts a string to a double precision floating point number. | |
| 1491 * | |
| 1492 * The function returns non-zero when conversion is not possible. | |
| 1493 * In that case the function sets errno to EINVAL when the reason is an invalid character. | |
| 1494 * It sets errno to ERANGE when the necessary representation would exceed the limits defined in libc's float.h. | |
| 1495 * | |
| 1496 * The decimal separator is assumed to be a dot character. | |
| 1497 * The comma character is treated as group separator and ignored during parsing. | |
| 1498 * If you want to choose a different format, use cx_strtof_lc(). | |
| 1499 * | |
| 1500 * @param str the string to convert | |
| 1501 * @param output a pointer to the float variable where the result shall be stored | |
| 1502 * @param decsep the decimal separator | |
| 1503 * @param groupsep each character in this string is treated as group separator and ignored during conversion | |
| 1504 * @return zero on success, non-zero if conversion was not possible | |
| 1505 */ | |
| 1506 #define cx_strtod_lc(str, output, decsep, groupsep) cx_strtod_lc(cx_strcast(str), output, decsep, groupsep) | |
| 1507 | |
| 1508 /** | |
| 1509 * Converts a string to a single precision floating point number. | |
| 1510 * | |
| 1511 * The function returns non-zero when conversion is not possible. | |
| 1512 * In that case the function sets errno to EINVAL when the reason is an invalid character. | |
| 1513 * It sets errno to ERANGE when the necessary representation would exceed the limits defined in libc's float.h. | |
| 1514 * | |
| 1515 * The decimal separator is assumed to be a dot character. | |
| 1516 * The comma character is treated as group separator and ignored during parsing. | |
| 1517 * If you want to choose a different format, use cx_strtof_lc(). | |
| 1518 * | |
| 1519 * @param str the string to convert | |
| 1520 * @param output a pointer to the float variable where the result shall be stored | |
| 1521 * @return zero on success, non-zero if conversion was not possible | |
| 1522 */ | |
| 1523 #define cx_strtof(str, output) cx_strtof_lc(str, output, '.', ",") | |
| 1524 /** | |
| 1525 * Converts a string to a double precision floating point number. | |
| 1526 * | |
| 1527 * The function returns non-zero when conversion is not possible. | |
| 1528 * In that case the function sets errno to EINVAL when the reason is an invalid character. | |
| 1529 * It sets errno to ERANGE when the necessary representation would exceed the limits defined in libc's float.h. | |
| 1530 * | |
| 1531 * The decimal separator is assumed to be a dot character. | |
| 1532 * The comma character is treated as group separator and ignored during parsing. | |
| 1533 * If you want to choose a different format, use cx_strtof_lc(). | |
| 1534 * | |
| 1535 * @param str the string to convert | |
| 1536 * @param output a pointer to the float variable where the result shall be stored | |
| 1537 * @return zero on success, non-zero if conversion was not possible | |
| 1538 */ | |
| 1539 #define cx_strtod(str, output) cx_strtod_lc(str, output, '.', ",") | |
| 1540 | |
| 1541 #endif | |
| 1077 | 1542 |
| 1078 #ifdef __cplusplus | 1543 #ifdef __cplusplus |
| 1079 } // extern "C" | 1544 } // extern "C" |
| 1080 #endif | 1545 #endif |
| 1081 | 1546 |