Tue, 13 Sep 2022 20:11:26 +0200
disallow NULL for cx_str() and cx_mutstr()
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 * A literal initializer for an UCX string structure.
83 *
84 * The argument MUST be a string (const char*) \em literal.
85 *
86 * @param literal the string literal
87 */
88 #define CX_STR(literal) {literal, sizeof(literal) - 1}
90 #ifdef __cplusplus
91 extern "C" {
92 #endif
95 /**
96 * Wraps a mutable string that must be zero-terminated.
97 *
98 * The length is implicitly inferred by using a call to \c strlen().
99 *
100 * \note the wrapped string will share the specified pointer to the string.
101 * If you do want a copy, use cx_strdup() on the return value of this function.
102 *
103 * If you need to wrap a constant string, use cx_str().
104 *
105 * @param cstring the string to wrap, must be zero-terminated
106 * @return the wrapped string
107 *
108 * @see cx_mutstrn()
109 */
110 __attribute__((__warn_unused_result__, __nonnull__))
111 cxmutstr cx_mutstr(char *cstring);
113 /**
114 * Wraps a string that does not need to be zero-terminated.
115 *
116 * The argument may be \c NULL if the length is zero.
117 *
118 * \note the wrapped string will share the specified pointer to the string.
119 * If you do want a copy, use cx_strdup() on the return value of this function.
120 *
121 * If you need to wrap a constant string, use cx_strn().
122 *
123 * @param cstring the string to wrap (or \c NULL, only if the length is zero)
124 * @param length the length of the string
125 * @return the wrapped string
126 *
127 * @see cx_mutstr()
128 */
129 __attribute__((__warn_unused_result__))
130 cxmutstr cx_mutstrn(
131 char *cstring,
132 size_t length
133 );
135 /**
136 * Wraps a string that must be zero-terminated.
137 *
138 * The length is implicitly inferred by using a call to \c strlen().
139 *
140 * \note the wrapped string will share the specified pointer to the string.
141 * If you do want a copy, use cx_strdup() on the return value of this function.
142 *
143 * If you need to wrap a non-constant string, use cx_mutstr().
144 *
145 * @param cstring the string to wrap, must be zero-terminated
146 * @return the wrapped string
147 *
148 * @see cx_strn()
149 */
150 __attribute__((__warn_unused_result__, __nonnull__))
151 cxstring cx_str(char const *cstring);
154 /**
155 * Wraps a string that does not need to be zero-terminated.
156 *
157 * The argument may be \c NULL if the length is zero.
158 *
159 * \note the wrapped string will share the specified pointer to the string.
160 * If you do want a copy, use cx_strdup() on the return value of this function.
161 *
162 * If you need to wrap a non-constant string, use cx_mutstrn().
163 *
164 * @param cstring the string to wrap (or \c NULL, only if the length is zero)
165 * @param length the length of the string
166 * @return the wrapped string
167 *
168 * @see cx_str()
169 */
170 __attribute__((__warn_unused_result__))
171 cxstring cx_strn(
172 char const *cstring,
173 size_t length
174 );
176 /**
177 * Casts a mutable string to an immutable string.
178 *
179 * \note This is not seriously a cast. Instead you get a copy
180 * of the struct with the desired pointer type. Both structs still
181 * point to the same location, though!
182 *
183 * @param str the mutable string to cast
184 * @return an immutable copy of the string pointer
185 */
186 __attribute__((__warn_unused_result__))
187 cxstring cx_strcast(cxmutstr str);
189 /**
190 * Passes the pointer in this string to \c free().
191 *
192 * The pointer in the struct is set to \c NULL and the length is set to zero.
193 *
194 * \note There is no implementation for cxstring, because it is unlikely that
195 * you ever have a \c char \c const* you are really supposed to free. If you
196 * encounter such situation, you should double-check your code.
197 *
198 * @param str the string to free
199 */
200 __attribute__((__nonnull__))
201 void cx_strfree(cxmutstr *str);
203 /**
204 * Passes the pointer in this string to the allocators free function.
205 *
206 * The pointer in the struct is set to \c NULL and the length is set to zero.
207 *
208 * \note There is no implementation for cxstring, because it is unlikely that
209 * you ever have a \c char \c const* you are really supposed to free. If you
210 * encounter such situation, you should double-check your code.
211 *
212 * @param alloc the allocator
213 * @param str the string to free
214 */
215 __attribute__((__nonnull__))
216 void cx_strfree_a(
217 CxAllocator *alloc,
218 cxmutstr *str
219 );
221 /**
222 * Returns the accumulated length of all specified strings.
223 *
224 * \attention if the count argument is larger than the number of the
225 * specified strings, the behavior is undefined.
226 *
227 * @param count the total number of specified strings
228 * @param ... all strings
229 * @return the accumulated length of all strings
230 */
231 __attribute__((__warn_unused_result__))
232 size_t cx_strlen(
233 size_t count,
234 ...
235 );
237 /**
238 * Concatenates two or more strings.
239 *
240 * The resulting string will be allocated by the specified allocator.
241 * So developers \em must pass the return value to cx_strfree() eventually.
242 *
243 * \note It is guaranteed that there is only one allocation.
244 *
245 * @param alloc the allocator to use
246 * @param count the total number of strings to concatenate
247 * @param ... all strings
248 * @return the concatenated string
249 */
250 __attribute__((__warn_unused_result__, __nonnull__))
251 cxmutstr cx_strcat_a(
252 CxAllocator *alloc,
253 size_t count,
254 ...
255 );
257 /**
258 * Concatenates two or more strings.
259 *
260 * The resulting string will be allocated by standard \c malloc().
261 * So developers \em must pass the return value to cx_strfree() eventually.
262 *
263 * @param count the total number of strings to concatenate
264 * @param ... all strings
265 * @return the concatenated string
266 */
267 #define cx_strcat(count, ...) \
268 cx_strcat_a(cxDefaultAllocator, count, __VA_ARGS__)
270 /**
271 * Returns a substring starting at the specified location.
272 *
273 * \attention the new string references the same memory area as the
274 * input string and is usually \em not zero-terminated.
275 * Use cx_strdup() to get a copy.
276 *
277 * @param string input string
278 * @param start start location of the substring
279 * @return a substring of \p string starting at \p start
280 *
281 * @see cx_strsubsl()
282 * @see cx_strsubs_m()
283 * @see cx_strsubsl_m()
284 */
285 __attribute__((__warn_unused_result__))
286 cxstring cx_strsubs(
287 cxstring string,
288 size_t start
289 );
291 /**
292 * Returns a substring starting at the specified location.
293 *
294 * The returned string will be limited to \p length bytes or the number
295 * of bytes available in \p string, whichever is smaller.
296 *
297 * \attention the new string references the same memory area as the
298 * input string and is usually \em not zero-terminated.
299 * Use cx_strdup() to get a copy.
300 *
301 * @param string input string
302 * @param start start location of the substring
303 * @param length the maximum length of the returned string
304 * @return a substring of \p string starting at \p start
305 *
306 * @see cx_strsubs()
307 * @see cx_strsubs_m()
308 * @see cx_strsubsl_m()
309 */
310 __attribute__((__warn_unused_result__))
311 cxstring cx_strsubsl(
312 cxstring string,
313 size_t start,
314 size_t length
315 );
317 /**
318 * Returns a substring starting at the specified location.
319 *
320 * \attention the new string references the same memory area as the
321 * input string and is usually \em not zero-terminated.
322 * Use cx_strdup() to get a copy.
323 *
324 * @param string input string
325 * @param start start location of the substring
326 * @return a substring of \p string starting at \p start
327 *
328 * @see cx_strsubsl_m()
329 * @see cx_strsubs()
330 * @see cx_strsubsl()
331 */
332 __attribute__((__warn_unused_result__))
333 cxmutstr cx_strsubs_m(
334 cxmutstr string,
335 size_t start
336 );
338 /**
339 * Returns a substring starting at the specified location.
340 *
341 * The returned string will be limited to \p length bytes or the number
342 * of bytes available in \p string, whichever is smaller.
343 *
344 * \attention the new string references the same memory area as the
345 * input string and is usually \em not zero-terminated.
346 * Use cx_strdup() to get a copy.
347 *
348 * @param string input string
349 * @param start start location of the substring
350 * @param length the maximum length of the returned string
351 * @return a substring of \p string starting at \p start
352 *
353 * @see cx_strsubs_m()
354 * @see cx_strsubs()
355 * @see cx_strsubsl()
356 */
357 __attribute__((__warn_unused_result__))
358 cxmutstr cx_strsubsl_m(
359 cxmutstr string,
360 size_t start,
361 size_t length
362 );
364 /**
365 * Returns a substring starting at the location of the first occurrence of the
366 * specified character.
367 *
368 * If the string does not contain the character, an empty string is returned.
369 *
370 * @param string the string where to locate the character
371 * @param chr the character to locate
372 * @return a substring starting at the first location of \p chr
373 *
374 * @see cx_strchr_m()
375 */
376 __attribute__((__warn_unused_result__))
377 cxstring cx_strchr(
378 cxstring string,
379 int chr
380 );
382 /**
383 * Returns a substring starting at the location of the first occurrence of the
384 * specified character.
385 *
386 * If the string does not contain the character, an empty string is returned.
387 *
388 * @param string the string where to locate the character
389 * @param chr the character to locate
390 * @return a substring starting at the first location of \p chr
391 *
392 * @see cx_strchr()
393 */
394 __attribute__((__warn_unused_result__))
395 cxmutstr cx_strchr_m(
396 cxmutstr string,
397 int chr
398 );
400 /**
401 * Returns a substring starting at the location of the last occurrence of the
402 * specified character.
403 *
404 * If the string does not contain the character, an empty string is returned.
405 *
406 * @param string the string where to locate the character
407 * @param chr the character to locate
408 * @return a substring starting at the last location of \p chr
409 *
410 * @see cx_strrchr_m()
411 */
412 __attribute__((__warn_unused_result__))
413 cxstring cx_strrchr(
414 cxstring string,
415 int chr
416 );
418 /**
419 * Returns a substring starting at the location of the last occurrence of the
420 * specified character.
421 *
422 * If the string does not contain the character, an empty string is returned.
423 *
424 * @param string the string where to locate the character
425 * @param chr the character to locate
426 * @return a substring starting at the last location of \p chr
427 *
428 * @see cx_strrchr()
429 */
430 __attribute__((__warn_unused_result__))
431 cxmutstr cx_strrchr_m(
432 cxmutstr string,
433 int chr
434 );
436 /**
437 * Returns a substring starting at the location of the first occurrence of the
438 * specified string.
439 *
440 * If \p haystack does not contain \p needle, an empty string is returned.
441 *
442 * If \p needle is an empty string, the complete \p haystack is
443 * returned.
444 *
445 * @param haystack the string to be scanned
446 * @param needle string containing the sequence of characters to match
447 * @return a substring starting at the first occurrence of
448 * \p needle, or an empty string, if the sequence is not
449 * contained
450 * @see cx_strstr_m()
451 */
452 __attribute__((__warn_unused_result__))
453 cxstring cx_strstr(
454 cxstring haystack,
455 cxstring needle
456 );
458 /**
459 * Returns a substring starting at the location of the first occurrence of the
460 * specified string.
461 *
462 * If \p haystack does not contain \p needle, an empty string is returned.
463 *
464 * If \p needle is an empty string, the complete \p haystack is
465 * returned.
466 *
467 * @param haystack the string to be scanned
468 * @param needle string containing the sequence of characters to match
469 * @return a substring starting at the first occurrence of
470 * \p needle, or an empty string, if the sequence is not
471 * contained
472 * @see cx_strstr()
473 */
474 __attribute__((__warn_unused_result__))
475 cxmutstr cx_strstr_m(
476 cxmutstr haystack,
477 cxstring needle
478 );
480 /**
481 * Splits a given string using a delimiter string.
482 *
483 * \note The resulting array contains strings that point to the source
484 * \p string. Use cx_strdup() to get copies.
485 *
486 * @param string the string to split
487 * @param delim the delimiter
488 * @param limit the maximum number of split items
489 * @param output a pre-allocated array of at least \p limit length
490 * @return the actual number of split items
491 */
492 __attribute__((__warn_unused_result__, __nonnull__))
493 size_t cx_strsplit(
494 cxstring string,
495 cxstring delim,
496 size_t limit,
497 cxstring *output
498 );
500 /**
501 * Splits a given string using a delimiter string.
502 *
503 * The array pointed to by \p output will be allocated by \p allocator.
504 *
505 * \note The resulting array contains strings that point to the source
506 * \p string. Use cx_strdup() to get copies.
507 *
508 * \attention If allocation fails, the \c NULL pointer will be written to
509 * \p output and the number returned will be zero.
510 *
511 * @param allocator the allocator to use for allocating the resulting array
512 * @param string the string to split
513 * @param delim the delimiter
514 * @param limit the maximum number of split items
515 * @param output a pointer where the address of the allocated array shall be
516 * written to
517 * @return the actual number of split items
518 */
519 __attribute__((__warn_unused_result__, __nonnull__))
520 size_t cx_strsplit_a(
521 CxAllocator *allocator,
522 cxstring string,
523 cxstring delim,
524 size_t limit,
525 cxstring **output
526 );
529 /**
530 * Splits a given string using a delimiter string.
531 *
532 * \note The resulting array contains strings that point to the source
533 * \p string. Use cx_strdup() to get copies.
534 *
535 * @param string the string to split
536 * @param delim the delimiter
537 * @param limit the maximum number of split items
538 * @param output a pre-allocated array of at least \p limit length
539 * @return the actual number of split items
540 */
541 __attribute__((__warn_unused_result__, __nonnull__))
542 size_t cx_strsplit_m(
543 cxmutstr string,
544 cxstring delim,
545 size_t limit,
546 cxmutstr *output
547 );
549 /**
550 * Splits a given string using a delimiter string.
551 *
552 * The array pointed to by \p output will be allocated by \p allocator.
553 *
554 * \note The resulting array contains strings that point to the source
555 * \p string. Use cx_strdup() to get copies.
556 *
557 * \attention If allocation fails, the \c NULL pointer will be written to
558 * \p output and the number returned will be zero.
559 *
560 * @param allocator the allocator to use for allocating the resulting array
561 * @param string the string to split
562 * @param delim the delimiter
563 * @param limit the maximum number of split items
564 * @param output a pointer where the address of the allocated array shall be
565 * written to
566 * @return the actual number of split items
567 */
568 __attribute__((__warn_unused_result__, __nonnull__))
569 size_t cx_strsplit_ma(
570 CxAllocator *allocator,
571 cxmutstr string,
572 cxstring delim,
573 size_t limit,
574 cxmutstr **output
575 );
577 /**
578 * Compares two strings.
579 *
580 * @param s1 the first string
581 * @param s2 the second string
582 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
583 * than \p s2, zero if both strings equal
584 */
585 __attribute__((__warn_unused_result__))
586 int cx_strcmp(
587 cxstring s1,
588 cxstring s2
589 );
591 /**
592 * Compares two strings ignoring case.
593 *
594 * @param s1 the first string
595 * @param s2 the second string
596 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
597 * than \p s2, zero if both strings equal ignoring case
598 */
599 __attribute__((__warn_unused_result__))
600 int cx_strcasecmp(
601 cxstring s1,
602 cxstring s2
603 );
606 /**
607 * Creates a duplicate of the specified string.
608 *
609 * The new string will contain a copy allocated by \p allocator.
610 *
611 * \note The returned string is guaranteed to be zero-terminated and can safely
612 * be passed to other APIs.
613 *
614 * @param allocator the allocator to use
615 * @param string the string to duplicate
616 * @return a duplicate of the string
617 * @see cx_strdup()
618 */
619 __attribute__((__warn_unused_result__, __nonnull__))
620 cxmutstr cx_strdup_a(
621 CxAllocator *allocator,
622 cxstring string
623 );
625 /**
626 * Creates a duplicate of the specified string.
627 *
628 * The new string will contain a copy allocated by standard
629 * \c malloc(). So developers \em must pass the return value to cx_strfree().
630 *
631 * \note The returned string is guaranteed to be zero-terminated and can safely
632 * be passed to other APIs.
633 *
634 * @param string the string to duplicate
635 * @return a duplicate of the string
636 * @see cx_strdup_a()
637 */
638 #define cx_strdup(string) cx_strdup_a(cxDefaultAllocator, string)
640 /**
641 * Omits leading and trailing spaces.
642 *
643 * \note the returned string references the same memory, thus you
644 * must \em not free the returned memory.
645 *
646 * @param string the string that shall be trimmed
647 * @return the trimmed string
648 */
649 __attribute__((__warn_unused_result__))
650 cxstring cx_strtrim(cxstring string);
652 /**
653 * Omits leading and trailing spaces.
654 *
655 * \note the returned string references the same memory, thus you
656 * must \em not free the returned memory.
657 *
658 * @param string the string that shall be trimmed
659 * @return the trimmed string
660 */
661 __attribute__((__warn_unused_result__))
662 cxmutstr cx_strtrim_m(cxmutstr string);
664 /**
665 * Checks, if a string has a specific prefix.
666 *
667 * @param string the string to check
668 * @param prefix the prefix the string should have
669 * @return \c true, if and only if the string has the specified prefix,
670 * \c false otherwise
671 */
672 __attribute__((__warn_unused_result__))
673 bool cx_strprefix(
674 cxstring string,
675 cxstring prefix
676 );
678 /**
679 * Checks, if a string has a specific suffix.
680 *
681 * @param string the string to check
682 * @param suffix the suffix the string should have
683 * @return \c true, if and only if the string has the specified suffix,
684 * \c false otherwise
685 */
686 __attribute__((__warn_unused_result__))
687 bool cx_strsuffix(
688 cxstring string,
689 cxstring suffix
690 );
692 /**
693 * Checks, if a string has a specific prefix, ignoring the case.
694 *
695 * @param string the string to check
696 * @param prefix the prefix the string should have
697 * @return \c true, if and only if the string has the specified prefix,
698 * \c false otherwise
699 */
700 __attribute__((__warn_unused_result__))
701 bool cx_strcaseprefix(
702 cxstring string,
703 cxstring prefix
704 );
706 /**
707 * Checks, if a string has a specific suffix, ignoring the case.
708 *
709 * @param string the string to check
710 * @param suffix the suffix the string should have
711 * @return \c true, if and only if the string has the specified suffix,
712 * \c false otherwise
713 */
714 __attribute__((__warn_unused_result__))
715 bool cx_strcasesuffix(
716 cxstring string,
717 cxstring suffix
718 );
720 /**
721 * Converts the string to lower case.
722 *
723 * The change is made in-place. If you want a copy, use cx_strdup(), first.
724 *
725 * @param string the string to modify
726 * @see cx_strdup()
727 */
728 void cx_strlower(cxmutstr string);
730 /**
731 * Converts the string to upper case.
732 *
733 * The change is made in-place. If you want a copy, use cx_strdup(), first.
734 *
735 * @param string the string to modify
736 * @see cx_strdup()
737 */
738 void cx_strupper(cxmutstr string);
740 /**
741 * Replaces a pattern in a string with another string.
742 *
743 * The pattern is taken literally and is no regular expression.
744 * Replaces at most \p replmax occurrences.
745 *
746 * The returned string will be allocated by \p allocator.
747 *
748 * If allocation fails, or the input string is empty,
749 * the returned string will be empty.
750 *
751 * @param allocator the allocator to use
752 * @param str the string where replacements should be applied
753 * @param pattern the pattern to search for
754 * @param replacement the replacement string
755 * @param replmax maximum number of replacements
756 * @return the resulting string after applying the replacements
757 */
758 __attribute__((__warn_unused_result__, __nonnull__))
759 cxmutstr cx_strreplacen_a(
760 CxAllocator *allocator,
761 cxstring str,
762 cxstring pattern,
763 cxstring replacement,
764 size_t replmax
765 );
767 /**
768 * Replaces a pattern in a string with another string.
769 *
770 * The pattern is taken literally and is no regular expression.
771 * Replaces at most \p replmax occurrences.
772 *
773 * The returned string will be allocated by \c malloc() and \em must be passed
774 * to cx_strfree() eventually.
775 *
776 * If allocation fails, or the input string is empty,
777 * the returned string will be empty.
778 *
779 * @param str the string where replacements should be applied
780 * @param pattern the pattern to search for
781 * @param replacement the replacement string
782 * @param replmax maximum number of replacements
783 * @return the resulting string after applying the replacements
784 */
785 #define cx_strreplacen(str, pattern, replacement, replmax) \
786 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, replmax)
788 /**
789 * Replaces a pattern in a string with another string.
790 *
791 * The pattern is taken literally and is no regular expression.
792 *
793 * The returned string will be allocated by \p allocator.
794 *
795 * If allocation fails, or the input string is empty,
796 * the returned string will be empty.
797 *
798 * @param allocator the allocator to use
799 * @param str the string where replacements should be applied
800 * @param pattern the pattern to search for
801 * @param replacement the replacement string
802 * @return the resulting string after applying the replacements
803 */
804 #define cx_strreplace_a(allocator, str, pattern, replacement) \
805 cx_strreplacen_a(allocator, str, pattern, replacement, SIZE_MAX)
807 /**
808 * Replaces a pattern in a string with another string.
809 *
810 * The pattern is taken literally and is no regular expression.
811 * Replaces at most \p replmax occurrences.
812 *
813 * The returned string will be allocated by \c malloc() and \em must be passed
814 * to cx_strfree() eventually.
815 *
816 * If allocation fails, or the input string is empty,
817 * the returned string will be empty.
818 *
819 * @param str the string where replacements should be applied
820 * @param pattern the pattern to search for
821 * @param replacement the replacement string
822 * @return the resulting string after applying the replacements
823 */
824 #define cx_strreplace(str, pattern, replacement) \
825 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, SIZE_MAX)
827 #ifdef __cplusplus
828 } // extern "C"
829 #endif
831 #endif //UCX_STRING_H