GCC Code Coverage Report


Directory: ./
File: cx/string.h
Date: 2025-11-30 14:18:36
Exec Total Coverage
Lines: 3 3 100.0%
Functions: 0 0 -%
Branches: 0 0 -%

Line Branch Exec Source
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 7403 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 9863 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 2 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