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