ucx/cx/string.h

branch
newapi
changeset 178
7c3ff86ee9d4
parent 174
0358f1d9c506
child 253
087cc9216f28
equal deleted inserted replaced
177:e79a60b3a7cb 178:7c3ff86ee9d4
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

mercurial