Thu, 02 Feb 2023 20:25:34 +0100
add strtok API - fixes #220
1 /*
2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3 *
4 * Copyright 2021 Mike Becker, Olaf Wintermann All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 *
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28 /**
29 * \file string.h
30 * \brief Strings that know their length.
31 * \author Mike Becker
32 * \author Olaf Wintermann
33 * \version 3.0
34 * \copyright 2-Clause BSD License
35 */
37 #ifndef UCX_STRING_H
38 #define UCX_STRING_H
40 #include "common.h"
41 #include "allocator.h"
43 /**
44 * The UCX string structure.
45 */
46 struct cx_mutstr_s {
47 /**
48 * A pointer to the string.
49 * \note The string is not necessarily \c NULL terminated.
50 * Always use the length.
51 */
52 char *ptr;
53 /** The length of the string */
54 size_t length;
55 };
57 /**
58 * A mutable string.
59 */
60 typedef struct cx_mutstr_s cxmutstr;
62 /**
63 * The UCX string structure for immutable (constant) strings.
64 */
65 struct cx_string_s {
66 /**
67 * A pointer to the immutable string.
68 * \note The string is not necessarily \c NULL terminated.
69 * Always use the length.
70 */
71 char const *ptr;
72 /** The length of the string */
73 size_t length;
74 };
76 /**
77 * An immutable string.
78 */
79 typedef struct cx_string_s cxstring;
81 /**
82 * Context for string tokenizing.
83 */
84 struct cx_strtok_ctx_s {
85 /**
86 * The string to tokenize.
87 */
88 cxstring str;
89 /**
90 * The primary delimiter.
91 */
92 cxstring delim;
93 /**
94 * Optional array of more delimiters.
95 */
96 cxstring const *delim_more;
97 /**
98 * Length of the array containing more delimiters.
99 */
100 size_t delim_more_count;
101 /**
102 * Position of the currently active token in the source string.
103 */
104 size_t pos;
105 /**
106 * Position of next delimiter in the source string.
107 *
108 * If the tokenizer has not yet returned a token, the content of this field
109 * is undefined. If the tokenizer reached the end of the string, this field
110 * contains the length of the source string.
111 */
112 size_t delim_pos;
113 /**
114 * The position of the next token in the source string.
115 */
116 size_t next_pos;
117 /**
118 * The number of already found tokens.
119 */
120 size_t found;
121 /**
122 * The maximum number of tokens that shall be returned.
123 */
124 size_t limit;
125 };
127 /**
128 * A string tokenizing context.
129 */
130 typedef struct cx_strtok_ctx_s CxStrtokCtx;
132 /**
133 * A literal initializer for an UCX string structure.
134 *
135 * The argument MUST be a string (const char*) \em literal.
136 *
137 * @param literal the string literal
138 */
139 #define CX_STR(literal) {literal, sizeof(literal) - 1}
141 #ifdef __cplusplus
142 extern "C" {
143 #endif
146 /**
147 * Wraps a mutable string that must be zero-terminated.
148 *
149 * The length is implicitly inferred by using a call to \c strlen().
150 *
151 * \note the wrapped string will share the specified pointer to the string.
152 * If you do want a copy, use cx_strdup() on the return value of this function.
153 *
154 * If you need to wrap a constant string, use cx_str().
155 *
156 * @param cstring the string to wrap, must be zero-terminated
157 * @return the wrapped string
158 *
159 * @see cx_mutstrn()
160 */
161 __attribute__((__warn_unused_result__, __nonnull__))
162 cxmutstr cx_mutstr(char *cstring);
164 /**
165 * Wraps a string that does not need to be zero-terminated.
166 *
167 * The argument may be \c NULL if the length is zero.
168 *
169 * \note the wrapped string will share the specified pointer to the string.
170 * If you do want a copy, use cx_strdup() on the return value of this function.
171 *
172 * If you need to wrap a constant string, use cx_strn().
173 *
174 * @param cstring the string to wrap (or \c NULL, only if the length is zero)
175 * @param length the length of the string
176 * @return the wrapped string
177 *
178 * @see cx_mutstr()
179 */
180 __attribute__((__warn_unused_result__))
181 cxmutstr cx_mutstrn(
182 char *cstring,
183 size_t length
184 );
186 /**
187 * Wraps a string that must be zero-terminated.
188 *
189 * The length is implicitly inferred by using a call to \c strlen().
190 *
191 * \note the wrapped string will share the specified pointer to the string.
192 * If you do want a copy, use cx_strdup() on the return value of this function.
193 *
194 * If you need to wrap a non-constant string, use cx_mutstr().
195 *
196 * @param cstring the string to wrap, must be zero-terminated
197 * @return the wrapped string
198 *
199 * @see cx_strn()
200 */
201 __attribute__((__warn_unused_result__, __nonnull__))
202 cxstring cx_str(char const *cstring);
205 /**
206 * Wraps a string that does not need to be zero-terminated.
207 *
208 * The argument may be \c NULL if the length is 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_mutstrn().
214 *
215 * @param cstring the string to wrap (or \c NULL, only if the length is zero)
216 * @param length the length of the string
217 * @return the wrapped string
218 *
219 * @see cx_str()
220 */
221 __attribute__((__warn_unused_result__))
222 cxstring cx_strn(
223 char const *cstring,
224 size_t length
225 );
227 /**
228 * Casts a mutable string to an immutable string.
229 *
230 * \note This is not seriously a cast. Instead you get a copy
231 * of the struct with the desired pointer type. Both structs still
232 * point to the same location, though!
233 *
234 * @param str the mutable string to cast
235 * @return an immutable copy of the string pointer
236 */
237 __attribute__((__warn_unused_result__))
238 cxstring cx_strcast(cxmutstr str);
240 /**
241 * Passes the pointer in this string to \c free().
242 *
243 * The pointer in the struct is set to \c NULL and the length is set to zero.
244 *
245 * \note There is no implementation for cxstring, because it is unlikely that
246 * you ever have a \c char \c const* you are really supposed to free. If you
247 * encounter such situation, you should double-check your code.
248 *
249 * @param str the string to free
250 */
251 __attribute__((__nonnull__))
252 void cx_strfree(cxmutstr *str);
254 /**
255 * Passes the pointer in this string to the allocators free function.
256 *
257 * The pointer in the struct is set to \c NULL and the length is set to zero.
258 *
259 * \note There is no implementation for cxstring, because it is unlikely that
260 * you ever have a \c char \c const* you are really supposed to free. If you
261 * encounter such situation, you should double-check your code.
262 *
263 * @param alloc the allocator
264 * @param str the string to free
265 */
266 __attribute__((__nonnull__))
267 void cx_strfree_a(
268 CxAllocator *alloc,
269 cxmutstr *str
270 );
272 /**
273 * Returns the accumulated length of all specified strings.
274 *
275 * \attention if the count argument is larger than the number of the
276 * specified strings, the behavior is undefined.
277 *
278 * @param count the total number of specified strings
279 * @param ... all strings
280 * @return the accumulated length of all strings
281 */
282 __attribute__((__warn_unused_result__))
283 size_t cx_strlen(
284 size_t count,
285 ...
286 );
288 /**
289 * Concatenates two or more strings.
290 *
291 * The resulting string will be allocated by the specified allocator.
292 * So developers \em must pass the return value to cx_strfree() eventually.
293 *
294 * \note It is guaranteed that there is only one allocation.
295 * It is also guaranteed that the returned string is zero-terminated.
296 *
297 * @param alloc the allocator to use
298 * @param count the total number of strings to concatenate
299 * @param ... all strings
300 * @return the concatenated string
301 */
302 __attribute__((__warn_unused_result__, __nonnull__))
303 cxmutstr cx_strcat_a(
304 CxAllocator *alloc,
305 size_t count,
306 ...
307 );
309 /**
310 * Concatenates two or more strings.
311 *
312 * The resulting string will be allocated by standard \c malloc().
313 * So developers \em must pass the return value to cx_strfree() eventually.
314 *
315 * \note It is guaranteed that there is only one allocation.
316 * It is also guaranteed that the returned string is zero-terminated.
317 *
318 * @param count the total number of strings to concatenate
319 * @param ... all strings
320 * @return the concatenated string
321 */
322 #define cx_strcat(count, ...) \
323 cx_strcat_a(cxDefaultAllocator, count, __VA_ARGS__)
325 /**
326 * Returns a substring starting at the specified location.
327 *
328 * \attention the new string references the same memory area as the
329 * input string and is usually \em not zero-terminated.
330 * Use cx_strdup() to get a copy.
331 *
332 * @param string input string
333 * @param start start location of the substring
334 * @return a substring of \p string starting at \p start
335 *
336 * @see cx_strsubsl()
337 * @see cx_strsubs_m()
338 * @see cx_strsubsl_m()
339 */
340 __attribute__((__warn_unused_result__))
341 cxstring cx_strsubs(
342 cxstring string,
343 size_t start
344 );
346 /**
347 * Returns a substring starting at the specified location.
348 *
349 * The returned string will be limited to \p length bytes or the number
350 * of bytes available in \p string, whichever is smaller.
351 *
352 * \attention the new string references the same memory area as the
353 * input string and is usually \em not zero-terminated.
354 * Use cx_strdup() to get a copy.
355 *
356 * @param string input string
357 * @param start start location of the substring
358 * @param length the maximum length of the returned string
359 * @return a substring of \p string starting at \p start
360 *
361 * @see cx_strsubs()
362 * @see cx_strsubs_m()
363 * @see cx_strsubsl_m()
364 */
365 __attribute__((__warn_unused_result__))
366 cxstring cx_strsubsl(
367 cxstring string,
368 size_t start,
369 size_t length
370 );
372 /**
373 * Returns a substring starting at the specified location.
374 *
375 * \attention the new string references the same memory area as the
376 * input string and is usually \em not zero-terminated.
377 * Use cx_strdup() to get a copy.
378 *
379 * @param string input string
380 * @param start start location of the substring
381 * @return a substring of \p string starting at \p start
382 *
383 * @see cx_strsubsl_m()
384 * @see cx_strsubs()
385 * @see cx_strsubsl()
386 */
387 __attribute__((__warn_unused_result__))
388 cxmutstr cx_strsubs_m(
389 cxmutstr string,
390 size_t start
391 );
393 /**
394 * Returns a substring starting at the specified location.
395 *
396 * The returned string will be limited to \p length bytes or the number
397 * of bytes available in \p string, whichever is smaller.
398 *
399 * \attention the new string references the same memory area as the
400 * input string and is usually \em not zero-terminated.
401 * Use cx_strdup() to get a copy.
402 *
403 * @param string input string
404 * @param start start location of the substring
405 * @param length the maximum length of the returned string
406 * @return a substring of \p string starting at \p start
407 *
408 * @see cx_strsubs_m()
409 * @see cx_strsubs()
410 * @see cx_strsubsl()
411 */
412 __attribute__((__warn_unused_result__))
413 cxmutstr cx_strsubsl_m(
414 cxmutstr string,
415 size_t start,
416 size_t length
417 );
419 /**
420 * Returns a substring starting at the location of the first occurrence of the
421 * specified character.
422 *
423 * If the string does not contain the character, an empty string is returned.
424 *
425 * @param string the string where to locate the character
426 * @param chr the character to locate
427 * @return a substring starting at the first location of \p chr
428 *
429 * @see cx_strchr_m()
430 */
431 __attribute__((__warn_unused_result__))
432 cxstring cx_strchr(
433 cxstring string,
434 int chr
435 );
437 /**
438 * Returns a substring starting at the location of the first occurrence of the
439 * specified character.
440 *
441 * If the string does not contain the character, an empty string is returned.
442 *
443 * @param string the string where to locate the character
444 * @param chr the character to locate
445 * @return a substring starting at the first location of \p chr
446 *
447 * @see cx_strchr()
448 */
449 __attribute__((__warn_unused_result__))
450 cxmutstr cx_strchr_m(
451 cxmutstr string,
452 int chr
453 );
455 /**
456 * Returns a substring starting at the location of the last occurrence of the
457 * specified character.
458 *
459 * If the string does not contain the character, an empty string is returned.
460 *
461 * @param string the string where to locate the character
462 * @param chr the character to locate
463 * @return a substring starting at the last location of \p chr
464 *
465 * @see cx_strrchr_m()
466 */
467 __attribute__((__warn_unused_result__))
468 cxstring cx_strrchr(
469 cxstring string,
470 int chr
471 );
473 /**
474 * Returns a substring starting at the location of the last occurrence of the
475 * specified character.
476 *
477 * If the string does not contain the character, an empty string is returned.
478 *
479 * @param string the string where to locate the character
480 * @param chr the character to locate
481 * @return a substring starting at the last location of \p chr
482 *
483 * @see cx_strrchr()
484 */
485 __attribute__((__warn_unused_result__))
486 cxmutstr cx_strrchr_m(
487 cxmutstr string,
488 int chr
489 );
491 /**
492 * Returns a substring starting at the location of the first occurrence of the
493 * specified string.
494 *
495 * If \p haystack does not contain \p needle, an empty string is returned.
496 *
497 * If \p needle is an empty string, the complete \p haystack is
498 * returned.
499 *
500 * @param haystack the string to be scanned
501 * @param needle string containing the sequence of characters to match
502 * @return a substring starting at the first occurrence of
503 * \p needle, or an empty string, if the sequence is not
504 * contained
505 * @see cx_strstr_m()
506 */
507 __attribute__((__warn_unused_result__))
508 cxstring cx_strstr(
509 cxstring haystack,
510 cxstring needle
511 );
513 /**
514 * Returns a substring starting at the location of the first occurrence of the
515 * specified string.
516 *
517 * If \p haystack does not contain \p needle, an empty string is returned.
518 *
519 * If \p needle is an empty string, the complete \p haystack is
520 * returned.
521 *
522 * @param haystack the string to be scanned
523 * @param needle string containing the sequence of characters to match
524 * @return a substring starting at the first occurrence of
525 * \p needle, or an empty string, if the sequence is not
526 * contained
527 * @see cx_strstr()
528 */
529 __attribute__((__warn_unused_result__))
530 cxmutstr cx_strstr_m(
531 cxmutstr haystack,
532 cxstring needle
533 );
535 /**
536 * Splits a given string using a delimiter string.
537 *
538 * \note The resulting array contains strings that point to the source
539 * \p string. Use cx_strdup() to get copies.
540 *
541 * @param string the string to split
542 * @param delim the delimiter
543 * @param limit the maximum number of split items
544 * @param output a pre-allocated array of at least \p limit length
545 * @return the actual number of split items
546 */
547 __attribute__((__warn_unused_result__, __nonnull__))
548 size_t cx_strsplit(
549 cxstring string,
550 cxstring delim,
551 size_t limit,
552 cxstring *output
553 );
555 /**
556 * Splits a given string using a delimiter string.
557 *
558 * The array pointed to by \p output will be allocated by \p allocator.
559 *
560 * \note The resulting array contains strings that point to the source
561 * \p string. Use cx_strdup() to get copies.
562 *
563 * \attention If allocation fails, the \c NULL pointer will be written to
564 * \p output and the number returned will be zero.
565 *
566 * @param allocator the allocator to use for allocating the resulting array
567 * @param string the string to split
568 * @param delim the delimiter
569 * @param limit the maximum number of split items
570 * @param output a pointer where the address of the allocated array shall be
571 * written to
572 * @return the actual number of split items
573 */
574 __attribute__((__warn_unused_result__, __nonnull__))
575 size_t cx_strsplit_a(
576 CxAllocator *allocator,
577 cxstring string,
578 cxstring delim,
579 size_t limit,
580 cxstring **output
581 );
584 /**
585 * Splits a given string using a delimiter string.
586 *
587 * \note The resulting array contains strings that point to the source
588 * \p string. Use cx_strdup() to get copies.
589 *
590 * @param string the string to split
591 * @param delim the delimiter
592 * @param limit the maximum number of split items
593 * @param output a pre-allocated array of at least \p limit length
594 * @return the actual number of split items
595 */
596 __attribute__((__warn_unused_result__, __nonnull__))
597 size_t cx_strsplit_m(
598 cxmutstr string,
599 cxstring delim,
600 size_t limit,
601 cxmutstr *output
602 );
604 /**
605 * Splits a given string using a delimiter string.
606 *
607 * The array pointed to by \p output will be allocated by \p allocator.
608 *
609 * \note The resulting array contains strings that point to the source
610 * \p string. Use cx_strdup() to get copies.
611 *
612 * \attention If allocation fails, the \c NULL pointer will be written to
613 * \p output and the number returned will be zero.
614 *
615 * @param allocator the allocator to use for allocating the resulting array
616 * @param string the string to split
617 * @param delim the delimiter
618 * @param limit the maximum number of split items
619 * @param output a pointer where the address of the allocated array shall be
620 * written to
621 * @return the actual number of split items
622 */
623 __attribute__((__warn_unused_result__, __nonnull__))
624 size_t cx_strsplit_ma(
625 CxAllocator *allocator,
626 cxmutstr string,
627 cxstring delim,
628 size_t limit,
629 cxmutstr **output
630 );
632 /**
633 * Compares two strings.
634 *
635 * @param s1 the first string
636 * @param s2 the second string
637 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
638 * than \p s2, zero if both strings equal
639 */
640 __attribute__((__warn_unused_result__))
641 int cx_strcmp(
642 cxstring s1,
643 cxstring s2
644 );
646 /**
647 * Compares two strings ignoring case.
648 *
649 * @param s1 the first string
650 * @param s2 the second string
651 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
652 * than \p s2, zero if both strings equal ignoring case
653 */
654 __attribute__((__warn_unused_result__))
655 int cx_strcasecmp(
656 cxstring s1,
657 cxstring s2
658 );
661 /**
662 * Creates a duplicate of the specified string.
663 *
664 * The new string will contain a copy allocated by \p allocator.
665 *
666 * \note The returned string is guaranteed to be zero-terminated.
667 *
668 * @param allocator the allocator to use
669 * @param string the string to duplicate
670 * @return a duplicate of the string
671 * @see cx_strdup()
672 */
673 __attribute__((__warn_unused_result__, __nonnull__))
674 cxmutstr cx_strdup_a(
675 CxAllocator *allocator,
676 cxstring string
677 );
679 /**
680 * Creates a duplicate of the specified string.
681 *
682 * The new string will contain a copy allocated by standard
683 * \c malloc(). So developers \em must pass the return value to cx_strfree().
684 *
685 * \note The returned string is guaranteed to be zero-terminated.
686 *
687 * @param string the string to duplicate
688 * @return a duplicate of the string
689 * @see cx_strdup_a()
690 */
691 #define cx_strdup(string) cx_strdup_a(cxDefaultAllocator, string)
693 /**
694 * Omits leading and trailing spaces.
695 *
696 * \note the returned string references the same memory, thus you
697 * must \em not free the returned memory.
698 *
699 * @param string the string that shall be trimmed
700 * @return the trimmed string
701 */
702 __attribute__((__warn_unused_result__))
703 cxstring cx_strtrim(cxstring string);
705 /**
706 * Omits leading and trailing spaces.
707 *
708 * \note the returned string references the same memory, thus you
709 * must \em not free the returned memory.
710 *
711 * @param string the string that shall be trimmed
712 * @return the trimmed string
713 */
714 __attribute__((__warn_unused_result__))
715 cxmutstr cx_strtrim_m(cxmutstr string);
717 /**
718 * Checks, if a string has a specific prefix.
719 *
720 * @param string the string to check
721 * @param prefix the prefix the string should have
722 * @return \c true, if and only if the string has the specified prefix,
723 * \c false otherwise
724 */
725 __attribute__((__warn_unused_result__))
726 bool cx_strprefix(
727 cxstring string,
728 cxstring prefix
729 );
731 /**
732 * Checks, if a string has a specific suffix.
733 *
734 * @param string the string to check
735 * @param suffix the suffix the string should have
736 * @return \c true, if and only if the string has the specified suffix,
737 * \c false otherwise
738 */
739 __attribute__((__warn_unused_result__))
740 bool cx_strsuffix(
741 cxstring string,
742 cxstring suffix
743 );
745 /**
746 * Checks, if a string has a specific prefix, ignoring the case.
747 *
748 * @param string the string to check
749 * @param prefix the prefix the string should have
750 * @return \c true, if and only if the string has the specified prefix,
751 * \c false otherwise
752 */
753 __attribute__((__warn_unused_result__))
754 bool cx_strcaseprefix(
755 cxstring string,
756 cxstring prefix
757 );
759 /**
760 * Checks, if a string has a specific suffix, ignoring the case.
761 *
762 * @param string the string to check
763 * @param suffix the suffix the string should have
764 * @return \c true, if and only if the string has the specified suffix,
765 * \c false otherwise
766 */
767 __attribute__((__warn_unused_result__))
768 bool cx_strcasesuffix(
769 cxstring string,
770 cxstring suffix
771 );
773 /**
774 * Converts the string to lower case.
775 *
776 * The change is made in-place. If you want a copy, use cx_strdup(), first.
777 *
778 * @param string the string to modify
779 * @see cx_strdup()
780 */
781 void cx_strlower(cxmutstr string);
783 /**
784 * Converts the string to upper case.
785 *
786 * The change is made in-place. If you want a copy, use cx_strdup(), first.
787 *
788 * @param string the string to modify
789 * @see cx_strdup()
790 */
791 void cx_strupper(cxmutstr string);
793 /**
794 * Replaces a pattern in a string with another string.
795 *
796 * The pattern is taken literally and is no regular expression.
797 * Replaces at most \p replmax occurrences.
798 *
799 * The returned string will be allocated by \p allocator and is guaranteed
800 * to be zero-terminated.
801 *
802 * If allocation fails, or the input string is empty,
803 * the returned string will be empty.
804 *
805 * @param allocator the allocator to use
806 * @param str the string where replacements should be applied
807 * @param pattern the pattern to search for
808 * @param replacement the replacement string
809 * @param replmax maximum number of replacements
810 * @return the resulting string after applying the replacements
811 */
812 __attribute__((__warn_unused_result__, __nonnull__))
813 cxmutstr cx_strreplacen_a(
814 CxAllocator *allocator,
815 cxstring str,
816 cxstring pattern,
817 cxstring replacement,
818 size_t replmax
819 );
821 /**
822 * Replaces a pattern in a string with another string.
823 *
824 * The pattern is taken literally and is no regular expression.
825 * Replaces at most \p replmax occurrences.
826 *
827 * The returned string will be allocated by \c malloc() and is guaranteed
828 * to be zero-terminated.
829 *
830 * If allocation fails, or the input string is empty,
831 * the returned string will be empty.
832 *
833 * @param str the string where replacements should be applied
834 * @param pattern the pattern to search for
835 * @param replacement the replacement string
836 * @param replmax maximum number of replacements
837 * @return the resulting string after applying the replacements
838 */
839 #define cx_strreplacen(str, pattern, replacement, replmax) \
840 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, replmax)
842 /**
843 * Replaces a pattern in a string with another string.
844 *
845 * The pattern is taken literally and is no regular expression.
846 *
847 * The returned string will be allocated by \p allocator and is guaranteed
848 * to be zero-terminated.
849 *
850 * If allocation fails, or the input string is empty,
851 * the returned string will be empty.
852 *
853 * @param allocator the allocator to use
854 * @param str the string where replacements should be applied
855 * @param pattern the pattern to search for
856 * @param replacement the replacement string
857 * @return the resulting string after applying the replacements
858 */
859 #define cx_strreplace_a(allocator, str, pattern, replacement) \
860 cx_strreplacen_a(allocator, str, pattern, replacement, SIZE_MAX)
862 /**
863 * Replaces a pattern in a string with another string.
864 *
865 * The pattern is taken literally and is no regular expression.
866 * Replaces at most \p replmax occurrences.
867 *
868 * The returned string will be allocated by \c malloc() and is guaranteed
869 * to be zero-terminated.
870 *
871 * If allocation fails, or the input string is empty,
872 * the returned string will be empty.
873 *
874 * @param str the string where replacements should be applied
875 * @param pattern the pattern to search for
876 * @param replacement the replacement string
877 * @return the resulting string after applying the replacements
878 */
879 #define cx_strreplace(str, pattern, replacement) \
880 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, SIZE_MAX)
882 /**
883 * Creates a string tokenization context.
884 *
885 * @param str the string to tokenize
886 * @param delim the delimiter (must not be empty)
887 * @param limit the maximum number of tokens that shall be returned
888 * @return a new string tokenization context
889 */
890 __attribute__((__warn_unused_result__))
891 CxStrtokCtx cx_strtok(
892 cxstring str,
893 cxstring delim,
894 size_t limit
895 );
897 /**
898 * Creates a string tokenization context for a mutable string.
899 *
900 * @param str the string to tokenize
901 * @param delim the delimiter (must not be empty)
902 * @param limit the maximum number of tokens that shall be returned
903 * @return a new string tokenization context
904 */
905 __attribute__((__warn_unused_result__))
906 CxStrtokCtx cx_strtok_m(
907 cxmutstr str,
908 cxstring delim,
909 size_t limit
910 );
912 /**
913 * Returns the next token.
914 *
915 * The token will point to the source string.
916 *
917 * @param ctx the tokenization context
918 * @param token a pointer to memory where the next token shall be stored
919 * @return true if successful, false if the limit or the end of the string
920 * has been reached
921 */
922 __attribute__((__warn_unused_result__, __nonnull__))
923 bool cx_strtok_next(
924 CxStrtokCtx *ctx,
925 cxstring *token
926 );
928 /**
929 * Returns the next token of a mutable string.
930 *
931 * The token will point to the source string.
932 * If the context was not initialized over a mutable string, modifying
933 * the data of the returned token is undefined behavior.
934 *
935 * @param ctx the tokenization context
936 * @param token a pointer to memory where the next token shall be stored
937 * @return true if successful, false if the limit or the end of the string
938 * has been reached
939 */
940 __attribute__((__warn_unused_result__, __nonnull__))
941 bool cx_strtok_next_m(
942 CxStrtokCtx *ctx,
943 cxmutstr *token
944 );
946 /**
947 * Defines an array of more delimiters for the specified tokenization context.
948 *
949 * @param ctx the tokenization context
950 * @param delim array of more delimiters
951 * @param count number of elements in the array
952 */
953 __attribute__((__nonnull__))
954 void cx_strtok_delim(
955 CxStrtokCtx *ctx,
956 cxstring const *delim,
957 size_t count
958 );
961 #ifdef __cplusplus
962 } // extern "C"
963 #endif
965 #endif //UCX_STRING_H