Thu, 28 Dec 2023 19:17:45 +0100
fix accidental generation of cxListIterator() symbol
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 * \copyright 2-Clause BSD License
34 */
36 #ifndef UCX_STRING_H
37 #define UCX_STRING_H
39 #include "common.h"
40 #include "allocator.h"
42 /**
43 * The UCX string structure.
44 */
45 struct cx_mutstr_s {
46 /**
47 * A pointer to the string.
48 * \note The string is not necessarily \c NULL terminated.
49 * Always use the length.
50 */
51 char *ptr;
52 /** The length of the string */
53 size_t length;
54 };
56 /**
57 * A mutable string.
58 */
59 typedef struct cx_mutstr_s cxmutstr;
61 /**
62 * The UCX string structure for immutable (constant) strings.
63 */
64 struct cx_string_s {
65 /**
66 * A pointer to the immutable string.
67 * \note The string is not necessarily \c NULL terminated.
68 * Always use the length.
69 */
70 char const *ptr;
71 /** The length of the string */
72 size_t length;
73 };
75 /**
76 * An immutable string.
77 */
78 typedef struct cx_string_s cxstring;
80 /**
81 * Context for string tokenizing.
82 */
83 struct cx_strtok_ctx_s {
84 /**
85 * The string to tokenize.
86 */
87 cxstring str;
88 /**
89 * The primary delimiter.
90 */
91 cxstring delim;
92 /**
93 * Optional array of more delimiters.
94 */
95 cxstring const *delim_more;
96 /**
97 * Length of the array containing more delimiters.
98 */
99 size_t delim_more_count;
100 /**
101 * Position of the currently active token in the source string.
102 */
103 size_t pos;
104 /**
105 * Position of next delimiter in the source string.
106 *
107 * If the tokenizer has not yet returned a token, the content of this field
108 * is undefined. If the tokenizer reached the end of the string, this field
109 * contains the length of the source string.
110 */
111 size_t delim_pos;
112 /**
113 * The position of the next token in the source string.
114 */
115 size_t next_pos;
116 /**
117 * The number of already found tokens.
118 */
119 size_t found;
120 /**
121 * The maximum number of tokens that shall be returned.
122 */
123 size_t limit;
124 };
126 /**
127 * A string tokenizing context.
128 */
129 typedef struct cx_strtok_ctx_s CxStrtokCtx;
131 #ifdef __cplusplus
132 extern "C" {
134 /**
135 * A literal initializer for an UCX string structure.
136 *
137 * @param literal the string literal
138 */
139 #define CX_STR(literal) cxstring{literal, sizeof(literal) - 1}
141 #else // __cplusplus
143 /**
144 * A literal initializer for an UCX string structure.
145 *
146 * The argument MUST be a string (const char*) \em literal.
147 *
148 * @param literal the string literal
149 */
150 #define CX_STR(literal) (cxstring){literal, sizeof(literal) - 1}
152 #endif
155 /**
156 * Wraps a mutable string that must be zero-terminated.
157 *
158 * The length is implicitly inferred by using a call to \c strlen().
159 *
160 * \note the wrapped string will share the specified pointer to the string.
161 * If you do want a copy, use cx_strdup() on the return value of this function.
162 *
163 * If you need to wrap a constant string, use cx_str().
164 *
165 * @param cstring the string to wrap, must be zero-terminated
166 * @return the wrapped string
167 *
168 * @see cx_mutstrn()
169 */
170 __attribute__((__warn_unused_result__, __nonnull__))
171 cxmutstr cx_mutstr(char *cstring);
173 /**
174 * Wraps a string that does not need to be zero-terminated.
175 *
176 * The argument may be \c NULL if the length is zero.
177 *
178 * \note the wrapped string will share the specified pointer to the string.
179 * If you do want a copy, use cx_strdup() on the return value of this function.
180 *
181 * If you need to wrap a constant string, use cx_strn().
182 *
183 * @param cstring the string to wrap (or \c NULL, only if the length is zero)
184 * @param length the length of the string
185 * @return the wrapped string
186 *
187 * @see cx_mutstr()
188 */
189 __attribute__((__warn_unused_result__))
190 cxmutstr cx_mutstrn(
191 char *cstring,
192 size_t length
193 );
195 /**
196 * Wraps a string that must be zero-terminated.
197 *
198 * The length is implicitly inferred by using a call to \c strlen().
199 *
200 * \note the wrapped string will share the specified pointer to the string.
201 * If you do want a copy, use cx_strdup() on the return value of this function.
202 *
203 * If you need to wrap a non-constant string, use cx_mutstr().
204 *
205 * @param cstring the string to wrap, must be zero-terminated
206 * @return the wrapped string
207 *
208 * @see cx_strn()
209 */
210 __attribute__((__warn_unused_result__, __nonnull__))
211 cxstring cx_str(char const *cstring);
214 /**
215 * Wraps a string that does not need to be zero-terminated.
216 *
217 * The argument may be \c NULL if the length is zero.
218 *
219 * \note the wrapped string will share the specified pointer to the string.
220 * If you do want a copy, use cx_strdup() on the return value of this function.
221 *
222 * If you need to wrap a non-constant string, use cx_mutstrn().
223 *
224 * @param cstring the string to wrap (or \c NULL, only if the length is zero)
225 * @param length the length of the string
226 * @return the wrapped string
227 *
228 * @see cx_str()
229 */
230 __attribute__((__warn_unused_result__))
231 cxstring cx_strn(
232 char const *cstring,
233 size_t length
234 );
236 /**
237 * Casts a mutable string to an immutable string.
238 *
239 * \note This is not seriously a cast. Instead you get a copy
240 * of the struct with the desired pointer type. Both structs still
241 * point to the same location, though!
242 *
243 * @param str the mutable string to cast
244 * @return an immutable copy of the string pointer
245 */
246 __attribute__((__warn_unused_result__))
247 cxstring cx_strcast(cxmutstr str);
249 /**
250 * Passes the pointer in this string to \c free().
251 *
252 * The pointer in the struct is set to \c NULL and the length is set to zero.
253 *
254 * \note There is no implementation for cxstring, because it is unlikely that
255 * you ever have a \c char \c const* you are really supposed to free. If you
256 * encounter such situation, you should double-check your code.
257 *
258 * @param str the string to free
259 */
260 __attribute__((__nonnull__))
261 void cx_strfree(cxmutstr *str);
263 /**
264 * Passes the pointer in this string to the allocators free function.
265 *
266 * The pointer in the struct is set to \c NULL and the length is set to zero.
267 *
268 * \note There is no implementation for cxstring, because it is unlikely that
269 * you ever have a \c char \c const* you are really supposed to free. If you
270 * encounter such situation, you should double-check your code.
271 *
272 * @param alloc the allocator
273 * @param str the string to free
274 */
275 __attribute__((__nonnull__))
276 void cx_strfree_a(
277 CxAllocator const *alloc,
278 cxmutstr *str
279 );
281 /**
282 * Returns the accumulated length of all specified strings.
283 *
284 * \attention if the count argument is larger than the number of the
285 * specified strings, the behavior is undefined.
286 *
287 * @param count the total number of specified strings
288 * @param ... all strings
289 * @return the accumulated length of all strings
290 */
291 __attribute__((__warn_unused_result__))
292 size_t cx_strlen(
293 size_t count,
294 ...
295 );
297 /**
298 * Concatenates strings.
299 *
300 * The resulting string will be allocated by the specified allocator.
301 * So developers \em must pass the return value to cx_strfree_a() eventually.
302 *
303 * If \p str already contains a string, the memory will be reallocated and
304 * the other strings are appended. Otherwise, new memory is allocated.
305 *
306 * \note It is guaranteed that there is only one allocation.
307 * It is also guaranteed that the returned string is zero-terminated.
308 *
309 * @param alloc the allocator to use
310 * @param str the string the other strings shall be concatenated to
311 * @param count the number of the other following strings to concatenate
312 * @param ... all other strings
313 * @return the concatenated string
314 */
315 __attribute__((__warn_unused_result__, __nonnull__))
316 cxmutstr cx_strcat_ma(
317 CxAllocator const *alloc,
318 cxmutstr str,
319 size_t count,
320 ...
321 );
323 /**
324 * Concatenates strings and returns a new string.
325 *
326 * The resulting string will be allocated by the specified allocator.
327 * So developers \em must pass the return value to cx_strfree_a() eventually.
328 *
329 * \note It is guaranteed that there is only one allocation.
330 * It is also guaranteed that the returned string is zero-terminated.
331 *
332 * @param alloc the allocator to use
333 * @param count the number of the other following strings to concatenate
334 * @param ... all other strings
335 * @return the concatenated string
336 */
337 #define cx_strcat_a(alloc, count, ...) \
338 cx_strcat_ma(alloc, cx_mutstrn(NULL, 0), count, __VA_ARGS__)
340 /**
341 * Concatenates strings and returns a new string.
342 *
343 * The resulting string will be allocated by standard \c malloc().
344 * So developers \em must pass the return value to cx_strfree() eventually.
345 *
346 * \note It is guaranteed that there is only one allocation.
347 * It is also guaranteed that the returned string is zero-terminated.
348 *
349 * @param count the number of the other following strings to concatenate
350 * @param ... all other strings
351 * @return the concatenated string
352 */
353 #define cx_strcat(count, ...) \
354 cx_strcat_ma(cxDefaultAllocator, cx_mutstrn(NULL, 0), count, __VA_ARGS__)
356 /**
357 * Concatenates strings.
358 *
359 * The resulting string will be allocated by standard \c malloc().
360 * So developers \em must pass the return value to cx_strfree() eventually.
361 *
362 * If \p str already contains a string, the memory will be reallocated and
363 * the other strings are appended. Otherwise, new memory is allocated.
364 *
365 * \note It is guaranteed that there is only one allocation.
366 * It is also guaranteed that the returned string is zero-terminated.
367 *
368 * @param str the string the other strings shall be concatenated to
369 * @param count the number of the other following strings to concatenate
370 * @param ... all other strings
371 * @return the concatenated string
372 */
373 #define cx_strcat_m(str, count, ...) \
374 cx_strcat_ma(cxDefaultAllocator, str, count, __VA_ARGS__)
376 /**
377 * Returns a substring starting at the specified location.
378 *
379 * \attention the new string references the same memory area as the
380 * input string and is usually \em not zero-terminated.
381 * Use cx_strdup() to get a copy.
382 *
383 * @param string input string
384 * @param start start location of the substring
385 * @return a substring of \p string starting at \p start
386 *
387 * @see cx_strsubsl()
388 * @see cx_strsubs_m()
389 * @see cx_strsubsl_m()
390 */
391 __attribute__((__warn_unused_result__))
392 cxstring cx_strsubs(
393 cxstring string,
394 size_t start
395 );
397 /**
398 * Returns a substring starting at the specified location.
399 *
400 * The returned string will be limited to \p length bytes or the number
401 * of bytes available in \p string, whichever is smaller.
402 *
403 * \attention the new string references the same memory area as the
404 * input string and is usually \em not zero-terminated.
405 * Use cx_strdup() to get a copy.
406 *
407 * @param string input string
408 * @param start start location of the substring
409 * @param length the maximum length of the returned string
410 * @return a substring of \p string starting at \p start
411 *
412 * @see cx_strsubs()
413 * @see cx_strsubs_m()
414 * @see cx_strsubsl_m()
415 */
416 __attribute__((__warn_unused_result__))
417 cxstring cx_strsubsl(
418 cxstring string,
419 size_t start,
420 size_t length
421 );
423 /**
424 * Returns a substring starting at the specified location.
425 *
426 * \attention the new string references the same memory area as the
427 * input string and is usually \em not zero-terminated.
428 * Use cx_strdup() to get a copy.
429 *
430 * @param string input string
431 * @param start start location of the substring
432 * @return a substring of \p string starting at \p start
433 *
434 * @see cx_strsubsl_m()
435 * @see cx_strsubs()
436 * @see cx_strsubsl()
437 */
438 __attribute__((__warn_unused_result__))
439 cxmutstr cx_strsubs_m(
440 cxmutstr string,
441 size_t start
442 );
444 /**
445 * Returns a substring starting at the specified location.
446 *
447 * The returned string will be limited to \p length bytes or the number
448 * of bytes available in \p string, whichever is smaller.
449 *
450 * \attention the new string references the same memory area as the
451 * input string and is usually \em not zero-terminated.
452 * Use cx_strdup() to get a copy.
453 *
454 * @param string input string
455 * @param start start location of the substring
456 * @param length the maximum length of the returned string
457 * @return a substring of \p string starting at \p start
458 *
459 * @see cx_strsubs_m()
460 * @see cx_strsubs()
461 * @see cx_strsubsl()
462 */
463 __attribute__((__warn_unused_result__))
464 cxmutstr cx_strsubsl_m(
465 cxmutstr string,
466 size_t start,
467 size_t length
468 );
470 /**
471 * Returns a substring starting at the location of the first occurrence of the
472 * specified character.
473 *
474 * If the string does not contain the character, an empty string is returned.
475 *
476 * @param string the string where to locate the character
477 * @param chr the character to locate
478 * @return a substring starting at the first location of \p chr
479 *
480 * @see cx_strchr_m()
481 */
482 __attribute__((__warn_unused_result__))
483 cxstring cx_strchr(
484 cxstring string,
485 int chr
486 );
488 /**
489 * Returns a substring starting at the location of the first occurrence of the
490 * specified character.
491 *
492 * If the string does not contain the character, an empty string is returned.
493 *
494 * @param string the string where to locate the character
495 * @param chr the character to locate
496 * @return a substring starting at the first location of \p chr
497 *
498 * @see cx_strchr()
499 */
500 __attribute__((__warn_unused_result__))
501 cxmutstr cx_strchr_m(
502 cxmutstr string,
503 int chr
504 );
506 /**
507 * Returns a substring starting at the location of the last occurrence of the
508 * specified character.
509 *
510 * If the string does not contain the character, an empty string is returned.
511 *
512 * @param string the string where to locate the character
513 * @param chr the character to locate
514 * @return a substring starting at the last location of \p chr
515 *
516 * @see cx_strrchr_m()
517 */
518 __attribute__((__warn_unused_result__))
519 cxstring cx_strrchr(
520 cxstring string,
521 int chr
522 );
524 /**
525 * Returns a substring starting at the location of the last occurrence of the
526 * specified character.
527 *
528 * If the string does not contain the character, an empty string is returned.
529 *
530 * @param string the string where to locate the character
531 * @param chr the character to locate
532 * @return a substring starting at the last location of \p chr
533 *
534 * @see cx_strrchr()
535 */
536 __attribute__((__warn_unused_result__))
537 cxmutstr cx_strrchr_m(
538 cxmutstr string,
539 int chr
540 );
542 /**
543 * Returns a substring starting at the location of the first occurrence of the
544 * specified string.
545 *
546 * If \p haystack does not contain \p needle, an empty string is returned.
547 *
548 * If \p needle is an empty string, the complete \p haystack is
549 * returned.
550 *
551 * @param haystack the string to be scanned
552 * @param needle string containing the sequence of characters to match
553 * @return a substring starting at the first occurrence of
554 * \p needle, or an empty string, if the sequence is not
555 * contained
556 * @see cx_strstr_m()
557 */
558 __attribute__((__warn_unused_result__))
559 cxstring cx_strstr(
560 cxstring haystack,
561 cxstring needle
562 );
564 /**
565 * Returns a substring starting at the location of the first occurrence of the
566 * specified string.
567 *
568 * If \p haystack does not contain \p needle, an empty string is returned.
569 *
570 * If \p needle is an empty string, the complete \p haystack is
571 * returned.
572 *
573 * @param haystack the string to be scanned
574 * @param needle string containing the sequence of characters to match
575 * @return a substring starting at the first occurrence of
576 * \p needle, or an empty string, if the sequence is not
577 * contained
578 * @see cx_strstr()
579 */
580 __attribute__((__warn_unused_result__))
581 cxmutstr cx_strstr_m(
582 cxmutstr haystack,
583 cxstring needle
584 );
586 /**
587 * Splits a given string using a delimiter string.
588 *
589 * \note The resulting array contains strings that point to the source
590 * \p string. Use cx_strdup() to get copies.
591 *
592 * @param string the string to split
593 * @param delim the delimiter
594 * @param limit the maximum number of split items
595 * @param output a pre-allocated array of at least \p limit length
596 * @return the actual number of split items
597 */
598 __attribute__((__warn_unused_result__, __nonnull__))
599 size_t cx_strsplit(
600 cxstring string,
601 cxstring delim,
602 size_t limit,
603 cxstring *output
604 );
606 /**
607 * Splits a given string using a delimiter string.
608 *
609 * The array pointed to by \p output will be allocated by \p allocator.
610 *
611 * \note The resulting array contains strings that point to the source
612 * \p string. Use cx_strdup() to get copies.
613 *
614 * \attention If allocation fails, the \c NULL pointer will be written to
615 * \p output and the number returned will be zero.
616 *
617 * @param allocator the allocator to use for allocating the resulting array
618 * @param string the string to split
619 * @param delim the delimiter
620 * @param limit the maximum number of split items
621 * @param output a pointer where the address of the allocated array shall be
622 * written to
623 * @return the actual number of split items
624 */
625 __attribute__((__warn_unused_result__, __nonnull__))
626 size_t cx_strsplit_a(
627 CxAllocator const *allocator,
628 cxstring string,
629 cxstring delim,
630 size_t limit,
631 cxstring **output
632 );
635 /**
636 * Splits a given string using a delimiter string.
637 *
638 * \note The resulting array contains strings that point to the source
639 * \p string. Use cx_strdup() to get copies.
640 *
641 * @param string the string to split
642 * @param delim the delimiter
643 * @param limit the maximum number of split items
644 * @param output a pre-allocated array of at least \p limit length
645 * @return the actual number of split items
646 */
647 __attribute__((__warn_unused_result__, __nonnull__))
648 size_t cx_strsplit_m(
649 cxmutstr string,
650 cxstring delim,
651 size_t limit,
652 cxmutstr *output
653 );
655 /**
656 * Splits a given string using a delimiter string.
657 *
658 * The array pointed to by \p output will be allocated by \p allocator.
659 *
660 * \note The resulting array contains strings that point to the source
661 * \p string. Use cx_strdup() to get copies.
662 *
663 * \attention If allocation fails, the \c NULL pointer will be written to
664 * \p output and the number returned will be zero.
665 *
666 * @param allocator the allocator to use for allocating the resulting array
667 * @param string the string to split
668 * @param delim the delimiter
669 * @param limit the maximum number of split items
670 * @param output a pointer where the address of the allocated array shall be
671 * written to
672 * @return the actual number of split items
673 */
674 __attribute__((__warn_unused_result__, __nonnull__))
675 size_t cx_strsplit_ma(
676 CxAllocator const *allocator,
677 cxmutstr string,
678 cxstring delim,
679 size_t limit,
680 cxmutstr **output
681 );
683 /**
684 * Compares two strings.
685 *
686 * @param s1 the first string
687 * @param s2 the second string
688 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
689 * than \p s2, zero if both strings equal
690 */
691 __attribute__((__warn_unused_result__))
692 int cx_strcmp(
693 cxstring s1,
694 cxstring s2
695 );
697 /**
698 * Compares two strings ignoring case.
699 *
700 * @param s1 the first string
701 * @param s2 the second string
702 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
703 * than \p s2, zero if both strings equal ignoring case
704 */
705 __attribute__((__warn_unused_result__))
706 int cx_strcasecmp(
707 cxstring s1,
708 cxstring s2
709 );
711 /**
712 * Compares two strings.
713 *
714 * This function has a compatible signature for the use as a cx_compare_func.
715 *
716 * @param s1 the first string
717 * @param s2 the second string
718 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
719 * than \p s2, zero if both strings equal
720 */
721 __attribute__((__warn_unused_result__, __nonnull__))
722 int cx_strcmp_p(
723 void const *s1,
724 void const *s2
725 );
727 /**
728 * Compares two strings ignoring case.
729 *
730 * This function has a compatible signature for the use as a cx_compare_func.
731 *
732 * @param s1 the first string
733 * @param s2 the second string
734 * @return negative if \p s1 is smaller than \p s2, positive if \p s1 is larger
735 * than \p s2, zero if both strings equal ignoring case
736 */
737 __attribute__((__warn_unused_result__, __nonnull__))
738 int cx_strcasecmp_p(
739 void const *s1,
740 void const *s2
741 );
744 /**
745 * Creates a duplicate of the specified string.
746 *
747 * The new string will contain a copy allocated by \p allocator.
748 *
749 * \note The returned string is guaranteed to be zero-terminated.
750 *
751 * @param allocator the allocator to use
752 * @param string the string to duplicate
753 * @return a duplicate of the string
754 * @see cx_strdup()
755 */
756 __attribute__((__warn_unused_result__, __nonnull__))
757 cxmutstr cx_strdup_a(
758 CxAllocator const *allocator,
759 cxstring string
760 );
762 /**
763 * Creates a duplicate of the specified string.
764 *
765 * The new string will contain a copy allocated by standard
766 * \c malloc(). So developers \em must pass the return value to cx_strfree().
767 *
768 * \note The returned string is guaranteed to be zero-terminated.
769 *
770 * @param string the string to duplicate
771 * @return a duplicate of the string
772 * @see cx_strdup_a()
773 */
774 #define cx_strdup(string) cx_strdup_a(cxDefaultAllocator, string)
777 /**
778 * Creates a duplicate of the specified string.
779 *
780 * The new string will contain a copy allocated by \p allocator.
781 *
782 * \note The returned string is guaranteed to be zero-terminated.
783 *
784 * @param allocator the allocator to use
785 * @param string the string to duplicate
786 * @return a duplicate of the string
787 * @see cx_strdup_m()
788 */
789 #define cx_strdup_ma(allocator, string) cx_strdup_a(allocator, cx_strcast(string))
791 /**
792 * Creates a duplicate of the specified string.
793 *
794 * The new string will contain a copy allocated by standard
795 * \c malloc(). So developers \em must pass the return value to cx_strfree().
796 *
797 * \note The returned string is guaranteed to be zero-terminated.
798 *
799 * @param string the string to duplicate
800 * @return a duplicate of the string
801 * @see cx_strdup_ma()
802 */
803 #define cx_strdup_m(string) cx_strdup_a(cxDefaultAllocator, cx_strcast(string))
805 /**
806 * Omits leading and trailing spaces.
807 *
808 * \note the returned string references the same memory, thus you
809 * must \em not free the returned memory.
810 *
811 * @param string the string that shall be trimmed
812 * @return the trimmed string
813 */
814 __attribute__((__warn_unused_result__))
815 cxstring cx_strtrim(cxstring string);
817 /**
818 * Omits leading and trailing spaces.
819 *
820 * \note the returned string references the same memory, thus you
821 * must \em not free the returned memory.
822 *
823 * @param string the string that shall be trimmed
824 * @return the trimmed string
825 */
826 __attribute__((__warn_unused_result__))
827 cxmutstr cx_strtrim_m(cxmutstr string);
829 /**
830 * Checks, if a string has a specific prefix.
831 *
832 * @param string the string to check
833 * @param prefix the prefix the string should have
834 * @return \c true, if and only if the string has the specified prefix,
835 * \c false otherwise
836 */
837 __attribute__((__warn_unused_result__))
838 bool cx_strprefix(
839 cxstring string,
840 cxstring prefix
841 );
843 /**
844 * Checks, if a string has a specific suffix.
845 *
846 * @param string the string to check
847 * @param suffix the suffix the string should have
848 * @return \c true, if and only if the string has the specified suffix,
849 * \c false otherwise
850 */
851 __attribute__((__warn_unused_result__))
852 bool cx_strsuffix(
853 cxstring string,
854 cxstring suffix
855 );
857 /**
858 * Checks, if a string has a specific prefix, ignoring the case.
859 *
860 * @param string the string to check
861 * @param prefix the prefix the string should have
862 * @return \c true, if and only if the string has the specified prefix,
863 * \c false otherwise
864 */
865 __attribute__((__warn_unused_result__))
866 bool cx_strcaseprefix(
867 cxstring string,
868 cxstring prefix
869 );
871 /**
872 * Checks, if a string has a specific suffix, ignoring the case.
873 *
874 * @param string the string to check
875 * @param suffix the suffix the string should have
876 * @return \c true, if and only if the string has the specified suffix,
877 * \c false otherwise
878 */
879 __attribute__((__warn_unused_result__))
880 bool cx_strcasesuffix(
881 cxstring string,
882 cxstring suffix
883 );
885 /**
886 * Converts the string to lower case.
887 *
888 * The change is made in-place. If you want a copy, use cx_strdup(), first.
889 *
890 * @param string the string to modify
891 * @see cx_strdup()
892 */
893 void cx_strlower(cxmutstr string);
895 /**
896 * Converts the string to upper case.
897 *
898 * The change is made in-place. If you want a copy, use cx_strdup(), first.
899 *
900 * @param string the string to modify
901 * @see cx_strdup()
902 */
903 void cx_strupper(cxmutstr string);
905 /**
906 * Replaces a pattern in a string with another string.
907 *
908 * The pattern is taken literally and is no regular expression.
909 * Replaces at most \p replmax occurrences.
910 *
911 * The returned string will be allocated by \p allocator and is guaranteed
912 * to be zero-terminated.
913 *
914 * If allocation fails, or the input string is empty,
915 * the returned string will be empty.
916 *
917 * @param allocator the allocator to use
918 * @param str the string where replacements should be applied
919 * @param pattern the pattern to search for
920 * @param replacement the replacement string
921 * @param replmax maximum number of replacements
922 * @return the resulting string after applying the replacements
923 */
924 __attribute__((__warn_unused_result__, __nonnull__))
925 cxmutstr cx_strreplacen_a(
926 CxAllocator const *allocator,
927 cxstring str,
928 cxstring pattern,
929 cxstring replacement,
930 size_t replmax
931 );
933 /**
934 * Replaces a pattern in a string with another string.
935 *
936 * The pattern is taken literally and is no regular expression.
937 * Replaces at most \p replmax occurrences.
938 *
939 * The returned string will be allocated by \c malloc() and is guaranteed
940 * to be zero-terminated.
941 *
942 * If allocation fails, or the input string is empty,
943 * the returned string will be empty.
944 *
945 * @param str the string where replacements should be applied
946 * @param pattern the pattern to search for
947 * @param replacement the replacement string
948 * @param replmax maximum number of replacements
949 * @return the resulting string after applying the replacements
950 */
951 #define cx_strreplacen(str, pattern, replacement, replmax) \
952 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, replmax)
954 /**
955 * Replaces a pattern in a string with another string.
956 *
957 * The pattern is taken literally and is no regular expression.
958 *
959 * The returned string will be allocated by \p allocator and is guaranteed
960 * to be zero-terminated.
961 *
962 * If allocation fails, or the input string is empty,
963 * the returned string will be empty.
964 *
965 * @param allocator the allocator to use
966 * @param str the string where replacements should be applied
967 * @param pattern the pattern to search for
968 * @param replacement the replacement string
969 * @return the resulting string after applying the replacements
970 */
971 #define cx_strreplace_a(allocator, str, pattern, replacement) \
972 cx_strreplacen_a(allocator, str, pattern, replacement, SIZE_MAX)
974 /**
975 * Replaces a pattern in a string with another string.
976 *
977 * The pattern is taken literally and is no regular expression.
978 * Replaces at most \p replmax occurrences.
979 *
980 * The returned string will be allocated by \c malloc() and is guaranteed
981 * to be zero-terminated.
982 *
983 * If allocation fails, or the input string is empty,
984 * the returned string will be empty.
985 *
986 * @param str the string where replacements should be applied
987 * @param pattern the pattern to search for
988 * @param replacement the replacement string
989 * @return the resulting string after applying the replacements
990 */
991 #define cx_strreplace(str, pattern, replacement) \
992 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, SIZE_MAX)
994 /**
995 * Creates a string tokenization context.
996 *
997 * @param str the string to tokenize
998 * @param delim the delimiter (must not be empty)
999 * @param limit the maximum number of tokens that shall be returned
1000 * @return a new string tokenization context
1001 */
1002 __attribute__((__warn_unused_result__))
1003 CxStrtokCtx cx_strtok(
1004 cxstring str,
1005 cxstring delim,
1006 size_t limit
1007 );
1009 /**
1010 * Creates a string tokenization context for a mutable string.
1011 *
1012 * @param str the string to tokenize
1013 * @param delim the delimiter (must not be empty)
1014 * @param limit the maximum number of tokens that shall be returned
1015 * @return a new string tokenization context
1016 */
1017 __attribute__((__warn_unused_result__))
1018 CxStrtokCtx cx_strtok_m(
1019 cxmutstr str,
1020 cxstring delim,
1021 size_t limit
1022 );
1024 /**
1025 * Returns the next token.
1026 *
1027 * The token will point to the source string.
1028 *
1029 * @param ctx the tokenization context
1030 * @param token a pointer to memory where the next token shall be stored
1031 * @return true if successful, false if the limit or the end of the string
1032 * has been reached
1033 */
1034 __attribute__((__warn_unused_result__, __nonnull__))
1035 bool cx_strtok_next(
1036 CxStrtokCtx *ctx,
1037 cxstring *token
1038 );
1040 /**
1041 * Returns the next token of a mutable string.
1042 *
1043 * The token will point to the source string.
1044 * If the context was not initialized over a mutable string, modifying
1045 * the data of the returned token is undefined behavior.
1046 *
1047 * @param ctx the tokenization context
1048 * @param token a pointer to memory where the next token shall be stored
1049 * @return true if successful, false if the limit or the end of the string
1050 * has been reached
1051 */
1052 __attribute__((__warn_unused_result__, __nonnull__))
1053 bool cx_strtok_next_m(
1054 CxStrtokCtx *ctx,
1055 cxmutstr *token
1056 );
1058 /**
1059 * Defines an array of more delimiters for the specified tokenization context.
1060 *
1061 * @param ctx the tokenization context
1062 * @param delim array of more delimiters
1063 * @param count number of elements in the array
1064 */
1065 __attribute__((__nonnull__))
1066 void cx_strtok_delim(
1067 CxStrtokCtx *ctx,
1068 cxstring const *delim,
1069 size_t count
1070 );
1073 #ifdef __cplusplus
1074 } // extern "C"
1075 #endif
1077 #endif //UCX_STRING_H