2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
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.
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.
30 * \brief Strings that know their length.
32 * \author Olaf Wintermann
34 * \copyright 2-Clause BSD License
41 #include "allocator.h"
44 * The UCX string structure.
48 * A pointer to the string.
49 * \note The string is not necessarily \c NULL terminated.
50 * Always use the length.
53 /** The length of the string */
60 typedef struct cx_mutstr_s cxmutstr;
63 * The UCX string structure for immutable (constant) strings.
67 * A pointer to the immutable string.
68 * \note The string is not necessarily \c NULL terminated.
69 * Always use the length.
72 /** The length of the string */
77 * An immutable string.
79 typedef struct cx_string_s cxstring;
82 * Context for string tokenizing.
84 struct cx_strtok_ctx_s {
86 * The string to tokenize.
90 * The primary delimiter.
94 * Optional array of more delimiters.
96 cxstring const *delim_more;
98 * Length of the array containing more delimiters.
100 size_t delim_more_count;
102 * Position of the currently active token in the source string.
106 * Position of next delimiter in the source string.
108 * If the tokenizer has not yet returned a token, the content of this field
109 * is undefined. If the tokenizer reached the end of the string, this field
110 * contains the length of the source string.
114 * The position of the next token in the source string.
118 * The number of already found tokens.
122 * The maximum number of tokens that shall be returned.
128 * A string tokenizing context.
130 typedef struct cx_strtok_ctx_s CxStrtokCtx;
136 * A literal initializer for an UCX string structure.
138 * @param literal the string literal
140 #define CX_STR(literal) cxstring{literal, sizeof(literal) - 1}
145 * A literal initializer for an UCX string structure.
147 * The argument MUST be a string (const char*) \em literal.
149 * @param literal the string literal
151 #define CX_STR(literal) (cxstring){literal, sizeof(literal) - 1}
157 * Wraps a mutable string that must be zero-terminated.
159 * The length is implicitly inferred by using a call to \c strlen().
161 * \note the wrapped string will share the specified pointer to the string.
162 * If you do want a copy, use cx_strdup() on the return value of this function.
164 * If you need to wrap a constant string, use cx_str().
166 * @param cstring the string to wrap, must be zero-terminated
167 * @return the wrapped string
171 __attribute__((__warn_unused_result__, __nonnull__))
172 cxmutstr cx_mutstr(char *cstring);
175 * Wraps a string that does not need to be zero-terminated.
177 * The argument may be \c NULL if the length is zero.
179 * \note the wrapped string will share the specified pointer to the string.
180 * If you do want a copy, use cx_strdup() on the return value of this function.
182 * If you need to wrap a constant string, use cx_strn().
184 * @param cstring the string to wrap (or \c NULL, only if the length is zero)
185 * @param length the length of the string
186 * @return the wrapped string
190 __attribute__((__warn_unused_result__))
197 * Wraps a string that must be zero-terminated.
199 * The length is implicitly inferred by using a call to \c strlen().
201 * \note the wrapped string will share the specified pointer to the string.
202 * If you do want a copy, use cx_strdup() on the return value of this function.
204 * If you need to wrap a non-constant string, use cx_mutstr().
206 * @param cstring the string to wrap, must be zero-terminated
207 * @return the wrapped string
211 __attribute__((__warn_unused_result__, __nonnull__))
212 cxstring cx_str(char const *cstring);
216 * Wraps a string that does not need to be zero-terminated.
218 * The argument may be \c NULL if the length is zero.
220 * \note the wrapped string will share the specified pointer to the string.
221 * If you do want a copy, use cx_strdup() on the return value of this function.
223 * If you need to wrap a non-constant string, use cx_mutstrn().
225 * @param cstring the string to wrap (or \c NULL, only if the length is zero)
226 * @param length the length of the string
227 * @return the wrapped string
231 __attribute__((__warn_unused_result__))
238 * Casts a mutable string to an immutable string.
240 * \note This is not seriously a cast. Instead you get a copy
241 * of the struct with the desired pointer type. Both structs still
242 * point to the same location, though!
244 * @param str the mutable string to cast
245 * @return an immutable copy of the string pointer
247 __attribute__((__warn_unused_result__))
248 cxstring cx_strcast(cxmutstr str);
251 * Passes the pointer in this string to \c free().
253 * The pointer in the struct is set to \c NULL and the length is set to zero.
255 * \note There is no implementation for cxstring, because it is unlikely that
256 * you ever have a \c char \c const* you are really supposed to free. If you
257 * encounter such situation, you should double-check your code.
259 * @param str the string to free
261 __attribute__((__nonnull__))
262 void cx_strfree(cxmutstr *str);
265 * Passes the pointer in this string to the allocators free function.
267 * The pointer in the struct is set to \c NULL and the length is set to zero.
269 * \note There is no implementation for cxstring, because it is unlikely that
270 * you ever have a \c char \c const* you are really supposed to free. If you
271 * encounter such situation, you should double-check your code.
273 * @param alloc the allocator
274 * @param str the string to free
276 __attribute__((__nonnull__))
278 CxAllocator const *alloc,
283 * Returns the accumulated length of all specified strings.
285 * \attention if the count argument is larger than the number of the
286 * specified strings, the behavior is undefined.
288 * @param count the total number of specified strings
289 * @param ... all strings
290 * @return the accumulated length of all strings
292 __attribute__((__warn_unused_result__))
299 * Concatenates strings.
301 * The resulting string will be allocated by the specified allocator.
302 * So developers \em must pass the return value to cx_strfree_a() eventually.
304 * If \p str already contains a string, the memory will be reallocated and
305 * the other strings are appended. Otherwise, new memory is allocated.
307 * \note It is guaranteed that there is only one allocation.
308 * It is also guaranteed that the returned string is zero-terminated.
310 * @param alloc the allocator to use
311 * @param str the string the other strings shall be concatenated to
312 * @param count the number of the other following strings to concatenate
313 * @param ... all other strings
314 * @return the concatenated string
316 __attribute__((__warn_unused_result__, __nonnull__))
317 cxmutstr cx_strcat_ma(
318 CxAllocator const *alloc,
325 * Concatenates strings and returns a new string.
327 * The resulting string will be allocated by the specified allocator.
328 * So developers \em must pass the return value to cx_strfree_a() eventually.
330 * \note It is guaranteed that there is only one allocation.
331 * It is also guaranteed that the returned string is zero-terminated.
333 * @param alloc the allocator to use
334 * @param count the number of the other following strings to concatenate
335 * @param ... all other strings
336 * @return the concatenated string
338 #define cx_strcat_a(alloc, count, ...) \
339 cx_strcat_ma(alloc, cx_mutstrn(NULL, 0), count, __VA_ARGS__)
342 * Concatenates strings and returns a new string.
344 * The resulting string will be allocated by standard \c malloc().
345 * So developers \em must pass the return value to cx_strfree() eventually.
347 * \note It is guaranteed that there is only one allocation.
348 * It is also guaranteed that the returned string is zero-terminated.
350 * @param count the number of the other following strings to concatenate
351 * @param ... all other strings
352 * @return the concatenated string
354 #define cx_strcat(count, ...) \
355 cx_strcat_ma(cxDefaultAllocator, cx_mutstrn(NULL, 0), count, __VA_ARGS__)
358 * Concatenates strings.
360 * The resulting string will be allocated by standard \c malloc().
361 * So developers \em must pass the return value to cx_strfree() eventually.
363 * If \p str already contains a string, the memory will be reallocated and
364 * the other strings are appended. Otherwise, new memory is allocated.
366 * \note It is guaranteed that there is only one allocation.
367 * It is also guaranteed that the returned string is zero-terminated.
369 * @param str the string the other strings shall be concatenated to
370 * @param count the number of the other following strings to concatenate
371 * @param ... all other strings
372 * @return the concatenated string
374 #define cx_strcat_m(str, count, ...) \
375 cx_strcat_ma(cxDefaultAllocator, str, count, __VA_ARGS__)
378 * Returns a substring starting at the specified location.
380 * \attention the new string references the same memory area as the
381 * input string and is usually \em not zero-terminated.
382 * Use cx_strdup() to get a copy.
384 * @param string input string
385 * @param start start location of the substring
386 * @return a substring of \p string starting at \p start
389 * @see cx_strsubs_m()
390 * @see cx_strsubsl_m()
392 __attribute__((__warn_unused_result__))
399 * Returns a substring starting at the specified location.
401 * The returned string will be limited to \p length bytes or the number
402 * of bytes available in \p string, whichever is smaller.
404 * \attention the new string references the same memory area as the
405 * input string and is usually \em not zero-terminated.
406 * Use cx_strdup() to get a copy.
408 * @param string input string
409 * @param start start location of the substring
410 * @param length the maximum length of the returned string
411 * @return a substring of \p string starting at \p start
414 * @see cx_strsubs_m()
415 * @see cx_strsubsl_m()
417 __attribute__((__warn_unused_result__))
418 cxstring cx_strsubsl(
425 * Returns a substring starting at the specified location.
427 * \attention the new string references the same memory area as the
428 * input string and is usually \em not zero-terminated.
429 * Use cx_strdup() to get a copy.
431 * @param string input string
432 * @param start start location of the substring
433 * @return a substring of \p string starting at \p start
435 * @see cx_strsubsl_m()
439 __attribute__((__warn_unused_result__))
440 cxmutstr cx_strsubs_m(
446 * Returns a substring starting at the specified location.
448 * The returned string will be limited to \p length bytes or the number
449 * of bytes available in \p string, whichever is smaller.
451 * \attention the new string references the same memory area as the
452 * input string and is usually \em not zero-terminated.
453 * Use cx_strdup() to get a copy.
455 * @param string input string
456 * @param start start location of the substring
457 * @param length the maximum length of the returned string
458 * @return a substring of \p string starting at \p start
460 * @see cx_strsubs_m()
464 __attribute__((__warn_unused_result__))
465 cxmutstr cx_strsubsl_m(
472 * Returns a substring starting at the location of the first occurrence of the
473 * specified character.
475 * If the string does not contain the character, an empty string is returned.
477 * @param string the string where to locate the character
478 * @param chr the character to locate
479 * @return a substring starting at the first location of \p chr
483 __attribute__((__warn_unused_result__))
490 * Returns a substring starting at the location of the first occurrence of the
491 * specified character.
493 * If the string does not contain the character, an empty string is returned.
495 * @param string the string where to locate the character
496 * @param chr the character to locate
497 * @return a substring starting at the first location of \p chr
501 __attribute__((__warn_unused_result__))
502 cxmutstr cx_strchr_m(
508 * Returns a substring starting at the location of the last occurrence of the
509 * specified character.
511 * If the string does not contain the character, an empty string is returned.
513 * @param string the string where to locate the character
514 * @param chr the character to locate
515 * @return a substring starting at the last location of \p chr
517 * @see cx_strrchr_m()
519 __attribute__((__warn_unused_result__))
526 * Returns a substring starting at the location of the last occurrence of the
527 * specified character.
529 * If the string does not contain the character, an empty string is returned.
531 * @param string the string where to locate the character
532 * @param chr the character to locate
533 * @return a substring starting at the last location of \p chr
537 __attribute__((__warn_unused_result__))
538 cxmutstr cx_strrchr_m(
544 * Returns a substring starting at the location of the first occurrence of the
547 * If \p haystack does not contain \p needle, an empty string is returned.
549 * If \p needle is an empty string, the complete \p haystack is
552 * @param haystack the string to be scanned
553 * @param needle string containing the sequence of characters to match
554 * @return a substring starting at the first occurrence of
555 * \p needle, or an empty string, if the sequence is not
559 __attribute__((__warn_unused_result__))
566 * Returns a substring starting at the location of the first occurrence of the
569 * If \p haystack does not contain \p needle, an empty string is returned.
571 * If \p needle is an empty string, the complete \p haystack is
574 * @param haystack the string to be scanned
575 * @param needle string containing the sequence of characters to match
576 * @return a substring starting at the first occurrence of
577 * \p needle, or an empty string, if the sequence is not
581 __attribute__((__warn_unused_result__))
582 cxmutstr cx_strstr_m(
588 * Splits a given string using a delimiter string.
590 * \note The resulting array contains strings that point to the source
591 * \p string. Use cx_strdup() to get copies.
593 * @param string the string to split
594 * @param delim the delimiter
595 * @param limit the maximum number of split items
596 * @param output a pre-allocated array of at least \p limit length
597 * @return the actual number of split items
599 __attribute__((__warn_unused_result__, __nonnull__))
608 * Splits a given string using a delimiter string.
610 * The array pointed to by \p output will be allocated by \p allocator.
612 * \note The resulting array contains strings that point to the source
613 * \p string. Use cx_strdup() to get copies.
615 * \attention If allocation fails, the \c NULL pointer will be written to
616 * \p output and the number returned will be zero.
618 * @param allocator the allocator to use for allocating the resulting array
619 * @param string the string to split
620 * @param delim the delimiter
621 * @param limit the maximum number of split items
622 * @param output a pointer where the address of the allocated array shall be
624 * @return the actual number of split items
626 __attribute__((__warn_unused_result__, __nonnull__))
627 size_t cx_strsplit_a(
628 CxAllocator const *allocator,
637 * Splits a given string using a delimiter string.
639 * \note The resulting array contains strings that point to the source
640 * \p string. Use cx_strdup() to get copies.
642 * @param string the string to split
643 * @param delim the delimiter
644 * @param limit the maximum number of split items
645 * @param output a pre-allocated array of at least \p limit length
646 * @return the actual number of split items
648 __attribute__((__warn_unused_result__, __nonnull__))
649 size_t cx_strsplit_m(
657 * Splits a given string using a delimiter string.
659 * The array pointed to by \p output will be allocated by \p allocator.
661 * \note The resulting array contains strings that point to the source
662 * \p string. Use cx_strdup() to get copies.
664 * \attention If allocation fails, the \c NULL pointer will be written to
665 * \p output and the number returned will be zero.
667 * @param allocator the allocator to use for allocating the resulting array
668 * @param string the string to split
669 * @param delim the delimiter
670 * @param limit the maximum number of split items
671 * @param output a pointer where the address of the allocated array shall be
673 * @return the actual number of split items
675 __attribute__((__warn_unused_result__, __nonnull__))
676 size_t cx_strsplit_ma(
677 CxAllocator const *allocator,
685 * Compares two strings.
687 * @param s1 the first string
688 * @param s2 the second string
689 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
690 * than \p s2, zero if both strings equal
692 __attribute__((__warn_unused_result__))
699 * Compares two strings ignoring case.
701 * @param s1 the first string
702 * @param s2 the second string
703 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
704 * than \p s2, zero if both strings equal ignoring case
706 __attribute__((__warn_unused_result__))
713 * Compares two strings.
715 * This function has a compatible signature for the use as a cx_compare_func.
717 * @param s1 the first string
718 * @param s2 the second string
719 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
720 * than \p s2, zero if both strings equal
722 __attribute__((__warn_unused_result__, __nonnull__))
729 * Compares two strings ignoring case.
731 * This function has a compatible signature for the use as a cx_compare_func.
733 * @param s1 the first string
734 * @param s2 the second string
735 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
736 * than \p s2, zero if both strings equal ignoring case
738 __attribute__((__warn_unused_result__, __nonnull__))
746 * Creates a duplicate of the specified string.
748 * The new string will contain a copy allocated by \p allocator.
750 * \note The returned string is guaranteed to be zero-terminated.
752 * @param allocator the allocator to use
753 * @param string the string to duplicate
754 * @return a duplicate of the string
757 __attribute__((__warn_unused_result__, __nonnull__))
758 cxmutstr cx_strdup_a(
759 CxAllocator const *allocator,
764 * Creates a duplicate of the specified string.
766 * The new string will contain a copy allocated by standard
767 * \c malloc(). So developers \em must pass the return value to cx_strfree().
769 * \note The returned string is guaranteed to be zero-terminated.
771 * @param string the string to duplicate
772 * @return a duplicate of the string
775 #define cx_strdup(string) cx_strdup_a(cxDefaultAllocator, string)
779 * Creates a duplicate of the specified string.
781 * The new string will contain a copy allocated by \p allocator.
783 * \note The returned string is guaranteed to be zero-terminated.
785 * @param allocator the allocator to use
786 * @param string the string to duplicate
787 * @return a duplicate of the string
790 #define cx_strdup_ma(allocator, string) cx_strdup_a(allocator, cx_strcast(string))
793 * Creates a duplicate of the specified string.
795 * The new string will contain a copy allocated by standard
796 * \c malloc(). So developers \em must pass the return value to cx_strfree().
798 * \note The returned string is guaranteed to be zero-terminated.
800 * @param string the string to duplicate
801 * @return a duplicate of the string
802 * @see cx_strdup_ma()
804 #define cx_strdup_m(string) cx_strdup_a(cxDefaultAllocator, cx_strcast(string))
807 * Omits leading and trailing spaces.
809 * \note the returned string references the same memory, thus you
810 * must \em not free the returned memory.
812 * @param string the string that shall be trimmed
813 * @return the trimmed string
815 __attribute__((__warn_unused_result__))
816 cxstring cx_strtrim(cxstring string);
819 * Omits leading and trailing spaces.
821 * \note the returned string references the same memory, thus you
822 * must \em not free the returned memory.
824 * @param string the string that shall be trimmed
825 * @return the trimmed string
827 __attribute__((__warn_unused_result__))
828 cxmutstr cx_strtrim_m(cxmutstr string);
831 * Checks, if a string has a specific prefix.
833 * @param string the string to check
834 * @param prefix the prefix the string should have
835 * @return \c true, if and only if the string has the specified prefix,
838 __attribute__((__warn_unused_result__))
845 * Checks, if a string has a specific suffix.
847 * @param string the string to check
848 * @param suffix the suffix the string should have
849 * @return \c true, if and only if the string has the specified suffix,
852 __attribute__((__warn_unused_result__))
859 * Checks, if a string has a specific prefix, ignoring the case.
861 * @param string the string to check
862 * @param prefix the prefix the string should have
863 * @return \c true, if and only if the string has the specified prefix,
866 __attribute__((__warn_unused_result__))
867 bool cx_strcaseprefix(
873 * Checks, if a string has a specific suffix, ignoring the case.
875 * @param string the string to check
876 * @param suffix the suffix the string should have
877 * @return \c true, if and only if the string has the specified suffix,
880 __attribute__((__warn_unused_result__))
881 bool cx_strcasesuffix(
887 * Converts the string to lower case.
889 * The change is made in-place. If you want a copy, use cx_strdup(), first.
891 * @param string the string to modify
894 void cx_strlower(cxmutstr string);
897 * Converts the string to upper case.
899 * The change is made in-place. If you want a copy, use cx_strdup(), first.
901 * @param string the string to modify
904 void cx_strupper(cxmutstr string);
907 * Replaces a pattern in a string with another string.
909 * The pattern is taken literally and is no regular expression.
910 * Replaces at most \p replmax occurrences.
912 * The returned string will be allocated by \p allocator and is guaranteed
913 * to be zero-terminated.
915 * If allocation fails, or the input string is empty,
916 * the returned string will be empty.
918 * @param allocator the allocator to use
919 * @param str the string where replacements should be applied
920 * @param pattern the pattern to search for
921 * @param replacement the replacement string
922 * @param replmax maximum number of replacements
923 * @return the resulting string after applying the replacements
925 __attribute__((__warn_unused_result__, __nonnull__))
926 cxmutstr cx_strreplacen_a(
927 CxAllocator const *allocator,
930 cxstring replacement,
935 * Replaces a pattern in a string with another string.
937 * The pattern is taken literally and is no regular expression.
938 * Replaces at most \p replmax occurrences.
940 * The returned string will be allocated by \c malloc() and is guaranteed
941 * to be zero-terminated.
943 * If allocation fails, or the input string is empty,
944 * the returned string will be empty.
946 * @param str the string where replacements should be applied
947 * @param pattern the pattern to search for
948 * @param replacement the replacement string
949 * @param replmax maximum number of replacements
950 * @return the resulting string after applying the replacements
952 #define cx_strreplacen(str, pattern, replacement, replmax) \
953 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, replmax)
956 * Replaces a pattern in a string with another string.
958 * The pattern is taken literally and is no regular expression.
960 * The returned string will be allocated by \p allocator and is guaranteed
961 * to be zero-terminated.
963 * If allocation fails, or the input string is empty,
964 * the returned string will be empty.
966 * @param allocator the allocator to use
967 * @param str the string where replacements should be applied
968 * @param pattern the pattern to search for
969 * @param replacement the replacement string
970 * @return the resulting string after applying the replacements
972 #define cx_strreplace_a(allocator, str, pattern, replacement) \
973 cx_strreplacen_a(allocator, str, pattern, replacement, SIZE_MAX)
976 * Replaces a pattern in a string with another string.
978 * The pattern is taken literally and is no regular expression.
979 * Replaces at most \p replmax occurrences.
981 * The returned string will be allocated by \c malloc() and is guaranteed
982 * to be zero-terminated.
984 * If allocation fails, or the input string is empty,
985 * the returned string will be empty.
987 * @param str the string where replacements should be applied
988 * @param pattern the pattern to search for
989 * @param replacement the replacement string
990 * @return the resulting string after applying the replacements
992 #define cx_strreplace(str, pattern, replacement) \
993 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, SIZE_MAX)
996 * Creates a string tokenization context.
998 * @param str the string to tokenize
999 * @param delim the delimiter (must not be empty)
1000 * @param limit the maximum number of tokens that shall be returned
1001 * @return a new string tokenization context
1003 __attribute__((__warn_unused_result__))
1004 CxStrtokCtx cx_strtok(
1011 * Creates a string tokenization context for a mutable string.
1013 * @param str the string to tokenize
1014 * @param delim the delimiter (must not be empty)
1015 * @param limit the maximum number of tokens that shall be returned
1016 * @return a new string tokenization context
1018 __attribute__((__warn_unused_result__))
1019 CxStrtokCtx cx_strtok_m(
1026 * Returns the next token.
1028 * The token will point to the source string.
1030 * @param ctx the tokenization context
1031 * @param token a pointer to memory where the next token shall be stored
1032 * @return true if successful, false if the limit or the end of the string
1035 __attribute__((__warn_unused_result__, __nonnull__))
1036 bool cx_strtok_next(
1042 * Returns the next token of a mutable string.
1044 * The token will point to the source string.
1045 * If the context was not initialized over a mutable string, modifying
1046 * the data of the returned token is undefined behavior.
1048 * @param ctx the tokenization context
1049 * @param token a pointer to memory where the next token shall be stored
1050 * @return true if successful, false if the limit or the end of the string
1053 __attribute__((__warn_unused_result__, __nonnull__))
1054 bool cx_strtok_next_m(
1060 * Defines an array of more delimiters for the specified tokenization context.
1062 * @param ctx the tokenization context
1063 * @param delim array of more delimiters
1064 * @param count number of elements in the array
1066 __attribute__((__nonnull__))
1067 void cx_strtok_delim(
1069 cxstring const *delim,
1078 #endif //UCX_STRING_H