add single instance mode
[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 #ifdef __cplusplus
133 extern "C" {
134
135 /**
136  * A literal initializer for an UCX string structure.
137  *
138  * @param literal the string literal
139  */
140 #define CX_STR(literal) cxstring{literal, sizeof(literal) - 1}
141
142 #else // __cplusplus
143
144 /**
145  * A literal initializer for an UCX string structure.
146  *
147  * The argument MUST be a string (const char*) \em literal.
148  *
149  * @param literal the string literal
150  */
151 #define CX_STR(literal) (cxstring){literal, sizeof(literal) - 1}
152
153 #endif
154
155
156 /**
157  * Wraps a mutable string that must be zero-terminated.
158  *
159  * The length is implicitly inferred by using a call to \c strlen().
160  *
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.
163  *
164  * If you need to wrap a constant string, use cx_str().
165  *
166  * @param cstring the string to wrap, must be zero-terminated
167  * @return the wrapped string
168  *
169  * @see cx_mutstrn()
170  */
171 __attribute__((__warn_unused_result__, __nonnull__))
172 cxmutstr cx_mutstr(char *cstring);
173
174 /**
175  * Wraps a string that does not need to be zero-terminated.
176  *
177  * The argument may be \c NULL if the length is zero.
178  *
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.
181  *
182  * If you need to wrap a constant string, use cx_strn().
183  *
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
187  *
188  * @see cx_mutstr()
189  */
190 __attribute__((__warn_unused_result__))
191 cxmutstr cx_mutstrn(
192         char *cstring,
193         size_t length
194 );
195
196 /**
197  * Wraps a string that must be zero-terminated.
198  *
199  * The length is implicitly inferred by using a call to \c strlen().
200  *
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.
203  *
204  * If you need to wrap a non-constant string, use cx_mutstr().
205  *
206  * @param cstring the string to wrap, must be zero-terminated
207  * @return the wrapped string
208  *
209  * @see cx_strn()
210  */
211 __attribute__((__warn_unused_result__, __nonnull__))
212 cxstring cx_str(char const *cstring);
213
214
215 /**
216  * Wraps a string that does not need to be zero-terminated.
217  *
218  * The argument may be \c NULL if the length is zero.
219  *
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.
222  *
223  * If you need to wrap a non-constant string, use cx_mutstrn().
224  *
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
228  *
229  * @see cx_str()
230  */
231 __attribute__((__warn_unused_result__))
232 cxstring cx_strn(
233         char const *cstring,
234         size_t length
235 );
236
237 /**
238 * Casts a mutable string to an immutable string.
239 *
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!
243 *
244 * @param str the mutable string to cast
245 * @return an immutable copy of the string pointer
246 */
247 __attribute__((__warn_unused_result__))
248 cxstring cx_strcast(cxmutstr str);
249
250 /**
251  * Passes the pointer in this string to \c free().
252  *
253  * The pointer in the struct is set to \c NULL and the length is set to zero.
254  *
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.
258  *
259  * @param str the string to free
260  */
261 __attribute__((__nonnull__))
262 void cx_strfree(cxmutstr *str);
263
264 /**
265  * Passes the pointer in this string to the allocators free function.
266  *
267  * The pointer in the struct is set to \c NULL and the length is set to zero.
268  *
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.
272  *
273  * @param alloc the allocator
274  * @param str the string to free
275  */
276 __attribute__((__nonnull__))
277 void cx_strfree_a(
278         CxAllocator const *alloc,
279         cxmutstr *str
280 );
281
282 /**
283  * Returns the accumulated length of all specified strings.
284  *
285  * \attention if the count argument is larger than the number of the
286  * specified strings, the behavior is undefined.
287  *
288  * @param count    the total number of specified strings
289  * @param ...      all strings
290  * @return the accumulated length of all strings
291  */
292 __attribute__((__warn_unused_result__))
293 size_t cx_strlen(
294         size_t count,
295         ...
296 );
297
298 /**
299  * Concatenates strings.
300  *
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.
303  *
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.
306  *
307  * \note It is guaranteed that there is only one allocation.
308  * It is also guaranteed that the returned string is zero-terminated.
309  *
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
315  */
316 __attribute__((__warn_unused_result__, __nonnull__))
317 cxmutstr cx_strcat_ma(
318         CxAllocator const *alloc,
319         cxmutstr str,
320         size_t count,
321         ...
322 );
323
324 /**
325  * Concatenates strings and returns a new string.
326  *
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.
329  *
330  * \note It is guaranteed that there is only one allocation.
331  * It is also guaranteed that the returned string is zero-terminated.
332  *
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
337  */
338 #define cx_strcat_a(alloc, count, ...) \
339 cx_strcat_ma(alloc, cx_mutstrn(NULL, 0), count, __VA_ARGS__)
340
341 /**
342  * Concatenates strings and returns a new string.
343  *
344  * The resulting string will be allocated by standard \c malloc().
345  * So developers \em must pass the return value to cx_strfree() eventually.
346  *
347  * \note It is guaranteed that there is only one allocation.
348  * It is also guaranteed that the returned string is zero-terminated.
349  *
350  * @param count   the number of the other following strings to concatenate
351  * @param ...     all other strings
352  * @return the concatenated string
353  */
354 #define cx_strcat(count, ...) \
355 cx_strcat_ma(cxDefaultAllocator, cx_mutstrn(NULL, 0), count, __VA_ARGS__)
356
357 /**
358  * Concatenates strings.
359  *
360  * The resulting string will be allocated by standard \c malloc().
361  * So developers \em must pass the return value to cx_strfree() eventually.
362  *
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.
365  *
366  * \note It is guaranteed that there is only one allocation.
367  * It is also guaranteed that the returned string is zero-terminated.
368  *
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
373  */
374 #define cx_strcat_m(str, count, ...) \
375 cx_strcat_ma(cxDefaultAllocator, str, count, __VA_ARGS__)
376
377 /**
378  * Returns a substring starting at the specified location.
379  *
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.
383  *
384  * @param string input string
385  * @param start  start location of the substring
386  * @return a substring of \p string starting at \p start
387  *
388  * @see cx_strsubsl()
389  * @see cx_strsubs_m()
390  * @see cx_strsubsl_m()
391  */
392 __attribute__((__warn_unused_result__))
393 cxstring cx_strsubs(
394         cxstring string,
395         size_t start
396 );
397
398 /**
399  * Returns a substring starting at the specified location.
400  *
401  * The returned string will be limited to \p length bytes or the number
402  * of bytes available in \p string, whichever is smaller.
403  *
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.
407  *
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
412  *
413  * @see cx_strsubs()
414  * @see cx_strsubs_m()
415  * @see cx_strsubsl_m()
416  */
417 __attribute__((__warn_unused_result__))
418 cxstring cx_strsubsl(
419         cxstring string,
420         size_t start,
421         size_t length
422 );
423
424 /**
425  * Returns a substring starting at the specified location.
426  *
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.
430  *
431  * @param string input string
432  * @param start  start location of the substring
433  * @return a substring of \p string starting at \p start
434  *
435  * @see cx_strsubsl_m()
436  * @see cx_strsubs()
437  * @see cx_strsubsl()
438  */
439 __attribute__((__warn_unused_result__))
440 cxmutstr cx_strsubs_m(
441         cxmutstr string,
442         size_t start
443 );
444
445 /**
446  * Returns a substring starting at the specified location.
447  *
448  * The returned string will be limited to \p length bytes or the number
449  * of bytes available in \p string, whichever is smaller.
450  *
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.
454  *
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
459  *
460  * @see cx_strsubs_m()
461  * @see cx_strsubs()
462  * @see cx_strsubsl()
463  */
464 __attribute__((__warn_unused_result__))
465 cxmutstr cx_strsubsl_m(
466         cxmutstr string,
467         size_t start,
468         size_t length
469 );
470
471 /**
472  * Returns a substring starting at the location of the first occurrence of the
473  * specified character.
474  *
475  * If the string does not contain the character, an empty string is returned.
476  *
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
480  *
481  * @see cx_strchr_m()
482  */
483 __attribute__((__warn_unused_result__))
484 cxstring cx_strchr(
485         cxstring string,
486         int chr
487 );
488
489 /**
490  * Returns a substring starting at the location of the first occurrence of the
491  * specified character.
492  *
493  * If the string does not contain the character, an empty string is returned.
494  *
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
498  *
499  * @see cx_strchr()
500  */
501 __attribute__((__warn_unused_result__))
502 cxmutstr cx_strchr_m(
503         cxmutstr string,
504         int chr
505 );
506
507 /**
508  * Returns a substring starting at the location of the last occurrence of the
509  * specified character.
510  *
511  * If the string does not contain the character, an empty string is returned.
512  *
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
516  *
517  * @see cx_strrchr_m()
518  */
519 __attribute__((__warn_unused_result__))
520 cxstring cx_strrchr(
521         cxstring string,
522         int chr
523 );
524
525 /**
526  * Returns a substring starting at the location of the last occurrence of the
527  * specified character.
528  *
529  * If the string does not contain the character, an empty string is returned.
530  *
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
534  *
535  * @see cx_strrchr()
536  */
537 __attribute__((__warn_unused_result__))
538 cxmutstr cx_strrchr_m(
539         cxmutstr string,
540         int chr
541 );
542
543 /**
544  * Returns a substring starting at the location of the first occurrence of the
545  * specified string.
546  *
547  * If \p haystack does not contain \p needle, an empty string is returned.
548  *
549  * If \p needle is an empty string, the complete \p haystack is
550  * returned.
551  *
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
556  *               contained
557  * @see cx_strstr_m()
558  */
559 __attribute__((__warn_unused_result__))
560 cxstring cx_strstr(
561         cxstring haystack,
562         cxstring needle
563 );
564
565 /**
566  * Returns a substring starting at the location of the first occurrence of the
567  * specified string.
568  *
569  * If \p haystack does not contain \p needle, an empty string is returned.
570  *
571  * If \p needle is an empty string, the complete \p haystack is
572  * returned.
573  *
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
578  *               contained
579  * @see cx_strstr()
580  */
581 __attribute__((__warn_unused_result__))
582 cxmutstr cx_strstr_m(
583         cxmutstr haystack,
584         cxstring needle
585 );
586
587 /**
588  * Splits a given string using a delimiter string.
589  *
590  * \note The resulting array contains strings that point to the source
591  * \p string. Use cx_strdup() to get copies.
592  *
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
598  */
599 __attribute__((__warn_unused_result__, __nonnull__))
600 size_t cx_strsplit(
601         cxstring string,
602         cxstring delim,
603         size_t limit,
604         cxstring *output
605 );
606
607 /**
608  * Splits a given string using a delimiter string.
609  *
610  * The array pointed to by \p output will be allocated by \p allocator.
611  *
612  * \note The resulting array contains strings that point to the source
613  * \p string. Use cx_strdup() to get copies.
614  *
615  * \attention If allocation fails, the \c NULL pointer will be written to
616  * \p output and the number returned will be zero.
617  *
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
623  * written to
624  * @return the actual number of split items
625  */
626 __attribute__((__warn_unused_result__, __nonnull__))
627 size_t cx_strsplit_a(
628         CxAllocator const *allocator,
629         cxstring string,
630         cxstring delim,
631         size_t limit,
632         cxstring **output
633 );
634
635
636 /**
637  * Splits a given string using a delimiter string.
638  *
639  * \note The resulting array contains strings that point to the source
640  * \p string. Use cx_strdup() to get copies.
641  *
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
647  */
648 __attribute__((__warn_unused_result__, __nonnull__))
649 size_t cx_strsplit_m(
650         cxmutstr string,
651         cxstring delim,
652         size_t limit,
653         cxmutstr *output
654 );
655
656 /**
657  * Splits a given string using a delimiter string.
658  *
659  * The array pointed to by \p output will be allocated by \p allocator.
660  *
661  * \note The resulting array contains strings that point to the source
662  * \p string. Use cx_strdup() to get copies.
663  *
664  * \attention If allocation fails, the \c NULL pointer will be written to
665  * \p output and the number returned will be zero.
666  *
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
672  * written to
673  * @return the actual number of split items
674  */
675 __attribute__((__warn_unused_result__, __nonnull__))
676 size_t cx_strsplit_ma(
677         CxAllocator const *allocator,
678         cxmutstr string,
679         cxstring delim,
680         size_t limit,
681         cxmutstr **output
682 );
683
684 /**
685  * Compares two strings.
686  *
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
691  */
692 __attribute__((__warn_unused_result__))
693 int cx_strcmp(
694         cxstring s1,
695         cxstring s2
696 );
697
698 /**
699  * Compares two strings ignoring case.
700  *
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
705  */
706 __attribute__((__warn_unused_result__))
707 int cx_strcasecmp(
708         cxstring s1,
709         cxstring s2
710 );
711
712 /**
713  * Compares two strings.
714  *
715  * This function has a compatible signature for the use as a cx_compare_func.
716  *
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
721  */
722 __attribute__((__warn_unused_result__, __nonnull__))
723 int cx_strcmp_p(
724         void const *s1,
725         void const *s2
726 );
727
728 /**
729  * Compares two strings ignoring case.
730  *
731  * This function has a compatible signature for the use as a cx_compare_func.
732  *
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
737  */
738 __attribute__((__warn_unused_result__, __nonnull__))
739 int cx_strcasecmp_p(
740         void const *s1,
741         void const *s2
742 );
743
744
745 /**
746  * Creates a duplicate of the specified string.
747  *
748  * The new string will contain a copy allocated by \p allocator.
749  *
750  * \note The returned string is guaranteed to be zero-terminated.
751  *
752  * @param allocator the allocator to use
753  * @param string the string to duplicate
754  * @return a duplicate of the string
755  * @see cx_strdup()
756  */
757 __attribute__((__warn_unused_result__, __nonnull__))
758 cxmutstr cx_strdup_a(
759         CxAllocator const *allocator,
760         cxstring string
761 );
762
763 /**
764  * Creates a duplicate of the specified string.
765  *
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().
768  *
769  * \note The returned string is guaranteed to be zero-terminated.
770  *
771  * @param string the string to duplicate
772  * @return a duplicate of the string
773  * @see cx_strdup_a()
774  */
775 #define cx_strdup(string) cx_strdup_a(cxDefaultAllocator, string)
776
777
778 /**
779  * Creates a duplicate of the specified string.
780  *
781  * The new string will contain a copy allocated by \p allocator.
782  *
783  * \note The returned string is guaranteed to be zero-terminated.
784  *
785  * @param allocator the allocator to use
786  * @param string the string to duplicate
787  * @return a duplicate of the string
788  * @see cx_strdup_m()
789  */
790 #define cx_strdup_ma(allocator, string) cx_strdup_a(allocator, cx_strcast(string))
791
792 /**
793  * Creates a duplicate of the specified string.
794  *
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().
797  *
798  * \note The returned string is guaranteed to be zero-terminated.
799  *
800  * @param string the string to duplicate
801  * @return a duplicate of the string
802  * @see cx_strdup_ma()
803  */
804 #define cx_strdup_m(string) cx_strdup_a(cxDefaultAllocator, cx_strcast(string))
805
806 /**
807  * Omits leading and trailing spaces.
808  *
809  * \note the returned string references the same memory, thus you
810  * must \em not free the returned memory.
811  *
812  * @param string the string that shall be trimmed
813  * @return the trimmed string
814  */
815 __attribute__((__warn_unused_result__))
816 cxstring cx_strtrim(cxstring string);
817
818 /**
819  * Omits leading and trailing spaces.
820  *
821  * \note the returned string references the same memory, thus you
822  * must \em not free the returned memory.
823  *
824  * @param string the string that shall be trimmed
825  * @return the trimmed string
826  */
827 __attribute__((__warn_unused_result__))
828 cxmutstr cx_strtrim_m(cxmutstr string);
829
830 /**
831  * Checks, if a string has a specific prefix.
832  *
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,
836  * \c false otherwise
837  */
838 __attribute__((__warn_unused_result__))
839 bool cx_strprefix(
840         cxstring string,
841         cxstring prefix
842 );
843
844 /**
845  * Checks, if a string has a specific suffix.
846  *
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,
850  * \c false otherwise
851  */
852 __attribute__((__warn_unused_result__))
853 bool cx_strsuffix(
854         cxstring string,
855         cxstring suffix
856 );
857
858 /**
859  * Checks, if a string has a specific prefix, ignoring the case.
860  *
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,
864  * \c false otherwise
865  */
866 __attribute__((__warn_unused_result__))
867 bool cx_strcaseprefix(
868         cxstring string,
869         cxstring prefix
870 );
871
872 /**
873  * Checks, if a string has a specific suffix, ignoring the case.
874  *
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,
878  * \c false otherwise
879  */
880 __attribute__((__warn_unused_result__))
881 bool cx_strcasesuffix(
882         cxstring string,
883         cxstring suffix
884 );
885
886 /**
887  * Converts the string to lower case.
888  *
889  * The change is made in-place. If you want a copy, use cx_strdup(), first.
890  *
891  * @param string the string to modify
892  * @see cx_strdup()
893  */
894 void cx_strlower(cxmutstr string);
895
896 /**
897  * Converts the string to upper case.
898  *
899  * The change is made in-place. If you want a copy, use cx_strdup(), first.
900  *
901  * @param string the string to modify
902  * @see cx_strdup()
903  */
904 void cx_strupper(cxmutstr string);
905
906 /**
907  * Replaces a pattern in a string with another string.
908  *
909  * The pattern is taken literally and is no regular expression.
910  * Replaces at most \p replmax occurrences.
911  *
912  * The returned string will be allocated by \p allocator and is guaranteed
913  * to be zero-terminated.
914  *
915  * If allocation fails, or the input string is empty,
916  * the returned string will be empty.
917  *
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
924  */
925 __attribute__((__warn_unused_result__, __nonnull__))
926 cxmutstr cx_strreplacen_a(
927         CxAllocator const *allocator,
928         cxstring str,
929         cxstring pattern,
930         cxstring replacement,
931         size_t replmax
932 );
933
934 /**
935  * Replaces a pattern in a string with another string.
936  *
937  * The pattern is taken literally and is no regular expression.
938  * Replaces at most \p replmax occurrences.
939  *
940  * The returned string will be allocated by \c malloc() and is guaranteed
941  * to be zero-terminated.
942  *
943  * If allocation fails, or the input string is empty,
944  * the returned string will be empty.
945  *
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
951  */
952 #define cx_strreplacen(str, pattern, replacement, replmax) \
953 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, replmax)
954
955 /**
956  * Replaces a pattern in a string with another string.
957  *
958  * The pattern is taken literally and is no regular expression.
959  *
960  * The returned string will be allocated by \p allocator and is guaranteed
961  * to be zero-terminated.
962  *
963  * If allocation fails, or the input string is empty,
964  * the returned string will be empty.
965  *
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
971  */
972 #define cx_strreplace_a(allocator, str, pattern, replacement) \
973 cx_strreplacen_a(allocator, str, pattern, replacement, SIZE_MAX)
974
975 /**
976  * Replaces a pattern in a string with another string.
977  *
978  * The pattern is taken literally and is no regular expression.
979  * Replaces at most \p replmax occurrences.
980  *
981  * The returned string will be allocated by \c malloc() and is guaranteed
982  * to be zero-terminated.
983  *
984  * If allocation fails, or the input string is empty,
985  * the returned string will be empty.
986  *
987  * @param 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
991  */
992 #define cx_strreplace(str, pattern, replacement) \
993 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, SIZE_MAX)
994
995 /**
996  * Creates a string tokenization context.
997  *
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
1002  */
1003 __attribute__((__warn_unused_result__))
1004 CxStrtokCtx cx_strtok(
1005         cxstring str,
1006         cxstring delim,
1007         size_t limit
1008 );
1009
1010 /**
1011 * Creates a string tokenization context for a mutable string.
1012 *
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
1017 */
1018 __attribute__((__warn_unused_result__))
1019 CxStrtokCtx cx_strtok_m(
1020         cxmutstr str,
1021         cxstring delim,
1022         size_t limit
1023 );
1024
1025 /**
1026  * Returns the next token.
1027  *
1028  * The token will point to the source string.
1029  *
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
1033  * has been reached
1034  */
1035 __attribute__((__warn_unused_result__, __nonnull__))
1036 bool cx_strtok_next(
1037         CxStrtokCtx *ctx,
1038         cxstring *token
1039 );
1040
1041 /**
1042  * Returns the next token of a mutable string.
1043  *
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.
1047  *
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
1051  * has been reached
1052  */
1053 __attribute__((__warn_unused_result__, __nonnull__))
1054 bool cx_strtok_next_m(
1055         CxStrtokCtx *ctx,
1056         cxmutstr *token
1057 );
1058
1059 /**
1060  * Defines an array of more delimiters for the specified tokenization context.
1061  *
1062  * @param ctx the tokenization context
1063  * @param delim array of more delimiters
1064  * @param count number of elements in the array
1065  */
1066 __attribute__((__nonnull__))
1067 void cx_strtok_delim(
1068         CxStrtokCtx *ctx,
1069         cxstring const *delim,
1070         size_t count
1071 );
1072
1073
1074 #ifdef __cplusplus
1075 } // extern "C"
1076 #endif
1077
1078 #endif //UCX_STRING_H