src/ucx/cx/string.h

changeset 490
d218607f5a7e
parent 415
d938228c382e
equal deleted inserted replaced
489:921f83a8943f 490:d218607f5a7e
77 * An immutable string. 77 * An immutable string.
78 */ 78 */
79 typedef struct cx_string_s cxstring; 79 typedef struct cx_string_s cxstring;
80 80
81 /** 81 /**
82 * A literal initializer for an UCX string structure. 82 * Context for string tokenizing.
83 * 83 */
84 * The argument MUST be a string (const char*) \em literal. 84 struct cx_strtok_ctx_s {
85 * 85 /**
86 * @param literal the string literal 86 * The string to tokenize.
87 */ 87 */
88 #define CX_STR(literal) {literal, sizeof(literal) - 1} 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;
89 131
90 #ifdef __cplusplus 132 #ifdef __cplusplus
91 extern "C" { 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
92 #endif 153 #endif
93 154
94 155
95 /** 156 /**
96 * Wraps a mutable string that must be zero-terminated. 157 * Wraps a mutable string that must be zero-terminated.
212 * @param alloc the allocator 273 * @param alloc the allocator
213 * @param str the string to free 274 * @param str the string to free
214 */ 275 */
215 __attribute__((__nonnull__)) 276 __attribute__((__nonnull__))
216 void cx_strfree_a( 277 void cx_strfree_a(
217 CxAllocator *alloc, 278 CxAllocator const *alloc,
218 cxmutstr *str 279 cxmutstr *str
219 ); 280 );
220 281
221 /** 282 /**
222 * Returns the accumulated length of all specified strings. 283 * Returns the accumulated length of all specified strings.
233 size_t count, 294 size_t count,
234 ... 295 ...
235 ); 296 );
236 297
237 /** 298 /**
238 * Concatenates two or more strings. 299 * Concatenates strings.
239 * 300 *
240 * The resulting string will be allocated by the specified allocator. 301 * The resulting string will be allocated by the specified allocator.
241 * So developers \em must pass the return value to cx_strfree() eventually. 302 * So developers \em must pass the return value to cx_strfree_a() eventually.
242 * 303 *
243 * \note It is guaranteed that there is only one allocation. 304 * If \p str already contains a string, the memory will be reallocated and
244 * It is also guaranteed that the returned string is zero-terminated. 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.
245 * 309 *
246 * @param alloc the allocator to use 310 * @param alloc the allocator to use
247 * @param count the total number of strings to concatenate 311 * @param str the string the other strings shall be concatenated to
248 * @param ... all strings 312 * @param count the number of the other following strings to concatenate
313 * @param ... all other strings
249 * @return the concatenated string 314 * @return the concatenated string
250 */ 315 */
251 __attribute__((__warn_unused_result__, __nonnull__)) 316 __attribute__((__warn_unused_result__, __nonnull__))
252 cxmutstr cx_strcat_a( 317 cxmutstr cx_strcat_ma(
253 CxAllocator *alloc, 318 CxAllocator const *alloc,
319 cxmutstr str,
254 size_t count, 320 size_t count,
255 ... 321 ...
256 ); 322 );
257 323
258 /** 324 /**
259 * Concatenates two or more strings. 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.
260 * 343 *
261 * The resulting string will be allocated by standard \c malloc(). 344 * The resulting string will be allocated by standard \c malloc().
262 * So developers \em must pass the return value to cx_strfree() eventually. 345 * So developers \em must pass the return value to cx_strfree() eventually.
263 * 346 *
264 * \note It is guaranteed that there is only one allocation. 347 * \note It is guaranteed that there is only one allocation.
265 * It is also guaranteed that the returned string is zero-terminated. 348 * It is also guaranteed that the returned string is zero-terminated.
266 * 349 *
267 * @param count the total number of strings to concatenate 350 * @param count the number of the other following strings to concatenate
268 * @param ... all strings 351 * @param ... all other strings
269 * @return the concatenated string 352 * @return the concatenated string
270 */ 353 */
271 #define cx_strcat(count, ...) \ 354 #define cx_strcat(count, ...) \
272 cx_strcat_a(cxDefaultAllocator, count, __VA_ARGS__) 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__)
273 376
274 /** 377 /**
275 * Returns a substring starting at the specified location. 378 * Returns a substring starting at the specified location.
276 * 379 *
277 * \attention the new string references the same memory area as the 380 * \attention the new string references the same memory area as the
520 * written to 623 * written to
521 * @return the actual number of split items 624 * @return the actual number of split items
522 */ 625 */
523 __attribute__((__warn_unused_result__, __nonnull__)) 626 __attribute__((__warn_unused_result__, __nonnull__))
524 size_t cx_strsplit_a( 627 size_t cx_strsplit_a(
525 CxAllocator *allocator, 628 CxAllocator const *allocator,
526 cxstring string, 629 cxstring string,
527 cxstring delim, 630 cxstring delim,
528 size_t limit, 631 size_t limit,
529 cxstring **output 632 cxstring **output
530 ); 633 );
569 * written to 672 * written to
570 * @return the actual number of split items 673 * @return the actual number of split items
571 */ 674 */
572 __attribute__((__warn_unused_result__, __nonnull__)) 675 __attribute__((__warn_unused_result__, __nonnull__))
573 size_t cx_strsplit_ma( 676 size_t cx_strsplit_ma(
574 CxAllocator *allocator, 677 CxAllocator const *allocator,
575 cxmutstr string, 678 cxmutstr string,
576 cxstring delim, 679 cxstring delim,
577 size_t limit, 680 size_t limit,
578 cxmutstr **output 681 cxmutstr **output
579 ); 682 );
604 int cx_strcasecmp( 707 int cx_strcasecmp(
605 cxstring s1, 708 cxstring s1,
606 cxstring s2 709 cxstring s2
607 ); 710 );
608 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
609 744
610 /** 745 /**
611 * Creates a duplicate of the specified string. 746 * Creates a duplicate of the specified string.
612 * 747 *
613 * The new string will contain a copy allocated by \p allocator. 748 * The new string will contain a copy allocated by \p allocator.
619 * @return a duplicate of the string 754 * @return a duplicate of the string
620 * @see cx_strdup() 755 * @see cx_strdup()
621 */ 756 */
622 __attribute__((__warn_unused_result__, __nonnull__)) 757 __attribute__((__warn_unused_result__, __nonnull__))
623 cxmutstr cx_strdup_a( 758 cxmutstr cx_strdup_a(
624 CxAllocator *allocator, 759 CxAllocator const *allocator,
625 cxstring string 760 cxstring string
626 ); 761 );
627 762
628 /** 763 /**
629 * Creates a duplicate of the specified string. 764 * Creates a duplicate of the specified string.
636 * @param string the string to duplicate 771 * @param string the string to duplicate
637 * @return a duplicate of the string 772 * @return a duplicate of the string
638 * @see cx_strdup_a() 773 * @see cx_strdup_a()
639 */ 774 */
640 #define cx_strdup(string) cx_strdup_a(cxDefaultAllocator, string) 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))
641 805
642 /** 806 /**
643 * Omits leading and trailing spaces. 807 * Omits leading and trailing spaces.
644 * 808 *
645 * \note the returned string references the same memory, thus you 809 * \note the returned string references the same memory, thus you
758 * @param replmax maximum number of replacements 922 * @param replmax maximum number of replacements
759 * @return the resulting string after applying the replacements 923 * @return the resulting string after applying the replacements
760 */ 924 */
761 __attribute__((__warn_unused_result__, __nonnull__)) 925 __attribute__((__warn_unused_result__, __nonnull__))
762 cxmutstr cx_strreplacen_a( 926 cxmutstr cx_strreplacen_a(
763 CxAllocator *allocator, 927 CxAllocator const *allocator,
764 cxstring str, 928 cxstring str,
765 cxstring pattern, 929 cxstring pattern,
766 cxstring replacement, 930 cxstring replacement,
767 size_t replmax 931 size_t replmax
768 ); 932 );
826 * @return the resulting string after applying the replacements 990 * @return the resulting string after applying the replacements
827 */ 991 */
828 #define cx_strreplace(str, pattern, replacement) \ 992 #define cx_strreplace(str, pattern, replacement) \
829 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, SIZE_MAX) 993 cx_strreplacen_a(cxDefaultAllocator, str, pattern, replacement, SIZE_MAX)
830 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
831 #ifdef __cplusplus 1074 #ifdef __cplusplus
832 } // extern "C" 1075 } // extern "C"
833 #endif 1076 #endif
834 1077
835 #endif //UCX_STRING_H 1078 #endif //UCX_STRING_H

mercurial