c2ccf7f32baed763a7a3d9432788764003288e98
[uwplayer.git] / ucx / cx / string.h
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  */
36
37 #ifndef UCX_STRING_H
38 #define UCX_STRING_H
39
40 #include "common.h"
41 #include "allocator.h"
42
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 };
56
57 /**
58  * A mutable string.
59  */
60 typedef struct cx_mutstr_s cxmutstr;
61
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 };
75
76 /**
77  * An immutable string.
78  */
79 typedef struct cx_string_s cxstring;
80
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 };
126
127 /**
128  * A string tokenizing context.
129  */
130 typedef struct cx_strtok_ctx_s CxStrtokCtx;
131
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}
140
141 #ifdef __cplusplus
142 extern "C" {
143 #endif
144
145
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);
163
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 );
185
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);
203
204
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 );
226
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);
239
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);
253
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 );
271
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 );
287
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 );
308
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__)
324
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 );
345
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 );
371
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 );
392
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 );
418
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 );
436
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 );
454
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 );
472
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 );
490
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 );
512
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 );
534
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 );
554
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 );
582
583
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 );
603
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 );
631
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 );
645
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 );
659
660 /**
661  * Compares two strings.
662  *
663  * This function has a compatible signature for the use as a CxListComparator.
664  *
665  * @param s1 the first string
666  * @param s2 the second string
667  * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
668  * than \p s2, zero if both strings equal
669  */
670 __attribute__((__warn_unused_result__, __nonnull__))
671 int cx_strcmp_p(
672         void const *s1,
673         void const *s2
674 );
675
676 /**
677  * Compares two strings ignoring case.
678  *
679  * This function has a compatible signature for the use as a CxListComparator.
680  *
681  * @param s1 the first string
682  * @param s2 the second string
683  * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
684  * than \p s2, zero if both strings equal ignoring case
685  */
686 __attribute__((__warn_unused_result__, __nonnull__))
687 int cx_strcasecmp_p(
688         void const *s1,
689         void const *s2
690 );
691
692
693 /**
694  * Creates a duplicate of the specified string.
695  *
696  * The new string will contain a copy allocated by \p allocator.
697  *
698  * \note The returned string is guaranteed to be zero-terminated.
699  *
700  * @param allocator the allocator to use
701  * @param string the string to duplicate
702  * @return a duplicate of the string
703  * @see cx_strdup()
704  */
705 __attribute__((__warn_unused_result__, __nonnull__))
706 cxmutstr cx_strdup_a(
707         CxAllocator *allocator,
708         cxstring string
709 );
710
711 /**
712  * Creates a duplicate of the specified string.
713  *
714  * The new string will contain a copy allocated by standard
715  * \c malloc(). So developers \em must pass the return value to cx_strfree().
716  *
717  * \note The returned string is guaranteed to be zero-terminated.
718  *
719  * @param string the string to duplicate
720  * @return a duplicate of the string
721  * @see cx_strdup_a()
722  */
723 #define cx_strdup(string) cx_strdup_a(cxDefaultAllocator, string)
724
725 /**
726  * Omits leading and trailing spaces.
727  *
728  * \note the returned string references the same memory, thus you
729  * must \em not free the returned memory.
730  *
731  * @param string the string that shall be trimmed
732  * @return the trimmed string
733  */
734 __attribute__((__warn_unused_result__))
735 cxstring cx_strtrim(cxstring string);
736
737 /**
738  * Omits leading and trailing spaces.
739  *
740  * \note the returned string references the same memory, thus you
741  * must \em not free the returned memory.
742  *
743  * @param string the string that shall be trimmed
744  * @return the trimmed string
745  */
746 __attribute__((__warn_unused_result__))
747 cxmutstr cx_strtrim_m(cxmutstr string);
748
749 /**
750  * Checks, if a string has a specific prefix.
751  *
752  * @param string the string to check
753  * @param prefix the prefix the string should have
754  * @return \c true, if and only if the string has the specified prefix,
755  * \c false otherwise
756  */
757 __attribute__((__warn_unused_result__))
758 bool cx_strprefix(
759         cxstring string,
760         cxstring prefix
761 );
762
763 /**
764  * Checks, if a string has a specific suffix.
765  *
766  * @param string the string to check
767  * @param suffix the suffix the string should have
768  * @return \c true, if and only if the string has the specified suffix,
769  * \c false otherwise
770  */
771 __attribute__((__warn_unused_result__))
772 bool cx_strsuffix(
773         cxstring string,
774         cxstring suffix
775 );
776
777 /**
778  * Checks, if a string has a specific prefix, ignoring the case.
779  *
780  * @param string the string to check
781  * @param prefix the prefix the string should have
782  * @return \c true, if and only if the string has the specified prefix,
783  * \c false otherwise
784  */
785 __attribute__((__warn_unused_result__))
786 bool cx_strcaseprefix(
787         cxstring string,
788         cxstring prefix
789 );
790
791 /**
792  * Checks, if a string has a specific suffix, ignoring the case.
793  *
794  * @param string the string to check
795  * @param suffix the suffix the string should have
796  * @return \c true, if and only if the string has the specified suffix,
797  * \c false otherwise
798  */
799 __attribute__((__warn_unused_result__))
800 bool cx_strcasesuffix(
801         cxstring string,
802         cxstring suffix
803 );
804
805 /**
806  * Converts the string to lower case.
807  *
808  * The change is made in-place. If you want a copy, use cx_strdup(), first.
809  *
810  * @param string the string to modify
811  * @see cx_strdup()
812  */
813 void cx_strlower(cxmutstr string);
814
815 /**
816  * Converts the string to upper case.
817  *
818  * The change is made in-place. If you want a copy, use cx_strdup(), first.
819  *
820  * @param string the string to modify
821  * @see cx_strdup()
822  */
823 void cx_strupper(cxmutstr string);
824
825 /**
826  * Replaces a pattern in a string with another string.
827  *
828  * The pattern is taken literally and is no regular expression.
829  * Replaces at most \p replmax occurrences.
830  *
831  * The returned string will be allocated by \p allocator and is guaranteed
832  * to be zero-terminated.
833  *
834  * If allocation fails, or the input string is empty,
835  * the returned string will be empty.
836  *
837  * @param allocator the allocator to use
838  * @param str the string where replacements should be applied
839  * @param pattern the pattern to search for
840  * @param replacement the replacement string
841  * @param replmax maximum number of replacements
842  * @return the resulting string after applying the replacements
843  */
844 __attribute__((__warn_unused_result__, __nonnull__))
845 cxmutstr cx_strreplacen_a(
846         CxAllocator *allocator,
847         cxstring str,
848         cxstring pattern,
849         cxstring replacement,
850         size_t replmax
851 );
852
853 /**
854  * Replaces a pattern in a string with another string.
855  *
856  * The pattern is taken literally and is no regular expression.
857  * Replaces at most \p replmax occurrences.
858  *
859  * The returned string will be allocated by \c malloc() and is guaranteed
860  * to be zero-terminated.
861  *
862  * If allocation fails, or the input string is empty,
863  * the returned string will be empty.
864  *
865  * @param str the string where replacements should be applied
866  * @param pattern the pattern to search for
867  * @param replacement the replacement string
868  * @param replmax maximum number of replacements
869  * @return the resulting string after applying the replacements
870  */
871 #define cx_strreplacen(str, pattern, replacement, replmax) \
872 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, replmax)
873
874 /**
875  * Replaces a pattern in a string with another string.
876  *
877  * The pattern is taken literally and is no regular expression.
878  *
879  * The returned string will be allocated by \p allocator and is guaranteed
880  * to be zero-terminated.
881  *
882  * If allocation fails, or the input string is empty,
883  * the returned string will be empty.
884  *
885  * @param allocator the allocator to use
886  * @param str the string where replacements should be applied
887  * @param pattern the pattern to search for
888  * @param replacement the replacement string
889  * @return the resulting string after applying the replacements
890  */
891 #define cx_strreplace_a(allocator, str, pattern, replacement) \
892 cx_strreplacen_a(allocator, str, pattern, replacement, SIZE_MAX)
893
894 /**
895  * Replaces a pattern in a string with another string.
896  *
897  * The pattern is taken literally and is no regular expression.
898  * Replaces at most \p replmax occurrences.
899  *
900  * The returned string will be allocated by \c malloc() and is guaranteed
901  * to be zero-terminated.
902  *
903  * If allocation fails, or the input string is empty,
904  * the returned string will be empty.
905  *
906  * @param str the string where replacements should be applied
907  * @param pattern the pattern to search for
908  * @param replacement the replacement string
909  * @return the resulting string after applying the replacements
910  */
911 #define cx_strreplace(str, pattern, replacement) \
912 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, SIZE_MAX)
913
914 /**
915  * Creates a string tokenization context.
916  *
917  * @param str the string to tokenize
918  * @param delim the delimiter (must not be empty)
919  * @param limit the maximum number of tokens that shall be returned
920  * @return a new string tokenization context
921  */
922 __attribute__((__warn_unused_result__))
923 CxStrtokCtx cx_strtok(
924         cxstring str,
925         cxstring delim,
926         size_t limit
927 );
928
929 /**
930 * Creates a string tokenization context for a mutable string.
931 *
932 * @param str the string to tokenize
933 * @param delim the delimiter (must not be empty)
934 * @param limit the maximum number of tokens that shall be returned
935 * @return a new string tokenization context
936 */
937 __attribute__((__warn_unused_result__))
938 CxStrtokCtx cx_strtok_m(
939         cxmutstr str,
940         cxstring delim,
941         size_t limit
942 );
943
944 /**
945  * Returns the next token.
946  *
947  * The token will point to the source string.
948  *
949  * @param ctx the tokenization context
950  * @param token a pointer to memory where the next token shall be stored
951  * @return true if successful, false if the limit or the end of the string
952  * has been reached
953  */
954 __attribute__((__warn_unused_result__, __nonnull__))
955 bool cx_strtok_next(
956         CxStrtokCtx *ctx,
957         cxstring *token
958 );
959
960 /**
961  * Returns the next token of a mutable string.
962  *
963  * The token will point to the source string.
964  * If the context was not initialized over a mutable string, modifying
965  * the data of the returned token is undefined behavior.
966  *
967  * @param ctx the tokenization context
968  * @param token a pointer to memory where the next token shall be stored
969  * @return true if successful, false if the limit or the end of the string
970  * has been reached
971  */
972 __attribute__((__warn_unused_result__, __nonnull__))
973 bool cx_strtok_next_m(
974         CxStrtokCtx *ctx,
975         cxmutstr *token
976 );
977
978 /**
979  * Defines an array of more delimiters for the specified tokenization context.
980  *
981  * @param ctx the tokenization context
982  * @param delim array of more delimiters
983  * @param count number of elements in the array
984  */
985 __attribute__((__nonnull__))
986 void cx_strtok_delim(
987         CxStrtokCtx *ctx,
988         cxstring const *delim,
989         size_t count
990 );
991
992
993 #ifdef __cplusplus
994 } // extern "C"
995 #endif
996
997 #endif //UCX_STRING_H