ucx/cx/string.h

branch
dav-2
changeset 886
da79af4baec8
parent 855
6740836b7a1e
child 889
42cdbf9bbd49
equal deleted inserted replaced
885:591377a27fa3 886:da79af4baec8
36 #ifndef UCX_STRING_H 36 #ifndef UCX_STRING_H
37 #define UCX_STRING_H 37 #define UCX_STRING_H
38 38
39 #include "common.h" 39 #include "common.h"
40 #include "allocator.h" 40 #include "allocator.h"
41
42 /** Expands a UCX string as printf arguments. */
43 #define CX_SFMT(s) (int) (s).length, (s).ptr
44
45 /** Format specifier for a UCX string */
46 #define CX_PRIstr ".*s"
41 47
42 /** 48 /**
43 * The maximum length of the "needle" in cx_strstr() that can use SBO. 49 * The maximum length of the "needle" in cx_strstr() that can use SBO.
44 */ 50 */
45 cx_attr_export 51 cx_attr_export
159 /** 165 /**
160 * Wraps a mutable string that must be zero-terminated. 166 * Wraps a mutable string that must be zero-terminated.
161 * 167 *
162 * The length is implicitly inferred by using a call to @c strlen(). 168 * The length is implicitly inferred by using a call to @c strlen().
163 * 169 *
170 * When @c NULL is passed, the length will be set to zero.
171 *
164 * @note the wrapped string will share the specified pointer to the string. 172 * @note the wrapped string will share the specified pointer to the string.
165 * If you do want a copy, use cx_strdup() on the return value of this function. 173 * If you do want a copy, use cx_strdup() on the return value of this function.
166 * 174 *
167 * If you need to wrap a constant string, use cx_str(). 175 * If you need to wrap a constant string, use cx_str().
168 * 176 *
169 * @param cstring the string to wrap, must be zero-terminated 177 * @param cstring the string to wrap, must be zero-terminated
170 * @return the wrapped string 178 * @return the wrapped string
171 * 179 *
172 * @see cx_mutstrn() 180 * @see cx_mutstrn()
173 */ 181 */
174 cx_attr_nonnull
175 cx_attr_nodiscard 182 cx_attr_nodiscard
176 cx_attr_cstr_arg(1) 183 cx_attr_cstr_arg(1)
177 cx_attr_export 184 cx_attr_export
178 cxmutstr cx_mutstr(char *cstring); 185 cxmutstr cx_mutstr(char *cstring);
179 186
204 /** 211 /**
205 * Wraps a string that must be zero-terminated. 212 * Wraps a string that must be zero-terminated.
206 * 213 *
207 * The length is implicitly inferred by using a call to @c strlen(). 214 * The length is implicitly inferred by using a call to @c strlen().
208 * 215 *
216 * When @c NULL is passed, the length will be set to zero.
217 *
209 * @note the wrapped string will share the specified pointer to the string. 218 * @note the wrapped string will share the specified pointer to the string.
210 * If you do want a copy, use cx_strdup() on the return value of this function. 219 * If you do want a copy, use cx_strdup() on the return value of this function.
211 * 220 *
212 * If you need to wrap a non-constant string, use cx_mutstr(). 221 * If you need to wrap a non-constant string, use cx_mutstr().
213 * 222 *
214 * @param cstring the string to wrap, must be zero-terminated 223 * @param cstring the string to wrap, must be zero-terminated
215 * @return the wrapped string 224 * @return the wrapped string
216 * 225 *
217 * @see cx_strn() 226 * @see cx_strn()
218 */ 227 */
219 cx_attr_nonnull
220 cx_attr_nodiscard 228 cx_attr_nodiscard
221 cx_attr_cstr_arg(1) 229 cx_attr_cstr_arg(1)
222 cx_attr_export 230 cx_attr_export
223 cxstring cx_str(const char *cstring); 231 cxstring cx_str(const char *cstring);
224 232
254 return cx_strn(str.ptr, str.length); 262 return cx_strn(str.ptr, str.length);
255 } 263 }
256 cx_attr_nodiscard 264 cx_attr_nodiscard
257 static inline cxstring cx_strcast(cxstring str) { 265 static inline cxstring cx_strcast(cxstring str) {
258 return str; 266 return str;
267 }
268 cx_attr_nodiscard
269 static inline cxstring cx_strcast(const char *str) {
270 return cx_str(str);
259 } 271 }
260 extern "C" { 272 extern "C" {
261 #else 273 #else
262 /** 274 /**
263 * Internal function, do not use. 275 * Internal function, do not use.
276 * @see cx_strcast() 288 * @see cx_strcast()
277 */ 289 */
278 cx_attr_nodiscard 290 cx_attr_nodiscard
279 static inline cxstring cx_strcast_c(cxstring str) { 291 static inline cxstring cx_strcast_c(cxstring str) {
280 return str; 292 return str;
293 }
294
295 /**
296 * Internal function, do not use.
297 * @param str
298 * @return
299 * @see cx_strcast()
300 */
301 cx_attr_nodiscard
302 static inline cxstring cx_strcast_z(const char *str) {
303 return cx_str(str);
281 } 304 }
282 305
283 /** 306 /**
284 * Casts a mutable string to an immutable string. 307 * Casts a mutable string to an immutable string.
285 * 308 *
292 * @param str (@c cxstring or @c cxmutstr) the string to cast 315 * @param str (@c cxstring or @c cxmutstr) the string to cast
293 * @return (@c cxstring) an immutable copy of the string pointer 316 * @return (@c cxstring) an immutable copy of the string pointer
294 */ 317 */
295 #define cx_strcast(str) _Generic((str), \ 318 #define cx_strcast(str) _Generic((str), \
296 cxmutstr: cx_strcast_m, \ 319 cxmutstr: cx_strcast_m, \
297 cxstring: cx_strcast_c) \ 320 cxstring: cx_strcast_c, \
298 (str) 321 const char*: cx_strcast_z, \
322 char *: cx_strcast_z) (str)
299 #endif 323 #endif
300 324
301 /** 325 /**
302 * Passes the pointer in this string to @c free(). 326 * Passes the pointer in this string to the cxDefaultAllocator's @c free() function.
303 * 327 *
304 * The pointer in the struct is set to @c NULL and the length is set to zero 328 * The pointer in the struct is set to @c NULL and the length is set to zero
305 * which means that this function protects you against double-free. 329 * which means that this function protects you against double-free.
306 * 330 *
307 * @note There is no implementation for cxstring, because it is unlikely that 331 * @note There is no implementation for cxstring, because it is unlikely that
330 cx_attr_export 354 cx_attr_export
331 void cx_strfree_a( 355 void cx_strfree_a(
332 const CxAllocator *alloc, 356 const CxAllocator *alloc,
333 cxmutstr *str 357 cxmutstr *str
334 ); 358 );
359
360 /**
361 * Copies a string.
362 *
363 * The memory in the @p dest structure is either allocated or re-allocated to fit the entire
364 * source string, including a zero-terminator.
365 *
366 * The string in @p dest is guaranteed to be zero-terminated, regardless of whether @p src is.
367 *
368 * @param alloc the allocator
369 * @param dest a pointer to the structure where to copy the contents to
370 * @param src the source string
371 *
372 * @retval zero success
373 * @retval non-zero if re-allocation failed
374 */
375 cx_attr_nonnull_arg(1)
376 cx_attr_export
377 int cx_strcpy_a(
378 const CxAllocator *alloc,
379 cxmutstr *dest,
380 cxstring src
381 );
382
383
384 /**
385 * Copies a string.
386 *
387 * The memory in the @p dest structure is either allocated or re-allocated to fit the entire
388 * source string, including a zero-terminator.
389 *
390 * The string in @p dest is guaranteed to be zero-terminated, regardless of whether @p src is.
391 *
392 * @param dest (@c cxmutstr*) a pointer to the structure where to copy the contents to
393 * @param src (@c cxstring) the source string
394 *
395 * @retval zero success
396 * @retval non-zero if re-allocation failed
397 */
398 #define cx_strcpy(dest, src) cx_strcpy_a(cxDefaultAllocator, dest, src)
335 399
336 /** 400 /**
337 * Returns the accumulated length of all specified strings. 401 * Returns the accumulated length of all specified strings.
338 * 402 *
339 * If this sum overflows, errno is set to EOVERFLOW. 403 * If this sum overflows, errno is set to EOVERFLOW.
406 cx_strcat_ma(alloc, cx_mutstrn(NULL, 0), count, __VA_ARGS__) 470 cx_strcat_ma(alloc, cx_mutstrn(NULL, 0), count, __VA_ARGS__)
407 471
408 /** 472 /**
409 * Concatenates strings and returns a new string. 473 * Concatenates strings and returns a new string.
410 * 474 *
411 * The resulting string will be allocated by standard @c malloc(). 475 * The resulting string will be allocated by the cxDefaultAllocator.
412 * So developers @em must pass the return value to cx_strfree() eventually. 476 * So developers @em must pass the return value to cx_strfree() eventually.
413 * 477 *
414 * If memory allocation fails, the pointer in the returned string will 478 * If memory allocation fails, the pointer in the returned string will
415 * be @c NULL and @c errno might be set. 479 * be @c NULL and @c errno might be set.
416 * 480 *
426 cx_strcat_ma(cxDefaultAllocator, cx_mutstrn(NULL, 0), count, __VA_ARGS__) 490 cx_strcat_ma(cxDefaultAllocator, cx_mutstrn(NULL, 0), count, __VA_ARGS__)
427 491
428 /** 492 /**
429 * Concatenates strings. 493 * Concatenates strings.
430 * 494 *
431 * The resulting string will be allocated by standard @c malloc(). 495 * The resulting string will be allocated by the cxDefaultAllocator.
432 * So developers @em must pass the return value to cx_strfree() eventually. 496 * So developers @em must pass the return value to cx_strfree() eventually.
433 * 497 *
434 * If @p str already contains a string, the memory will be reallocated and 498 * If @p str already contains a string, the memory will be reallocated and
435 * the other strings are appended. Otherwise, new memory is allocated. 499 * the other strings are appended. Otherwise, new memory is allocated.
436 * 500 *
882 cx_strdup_a_((allocator), cx_strcast(string)) 946 cx_strdup_a_((allocator), cx_strcast(string))
883 947
884 /** 948 /**
885 * Creates a duplicate of the specified string. 949 * Creates a duplicate of the specified string.
886 * 950 *
887 * The new string will contain a copy allocated by standard 951 * The new string will contain a copy allocated by the cxDefaultAllocator.
888 * @c malloc(). So developers @em must pass the return value to cx_strfree(). 952 * So developers @em must pass the return value to cx_strfree().
889 * 953 *
890 * @note The returned string is guaranteed to be zero-terminated. 954 * @note The returned string is guaranteed to be zero-terminated.
891 * 955 *
892 * @param string the string to duplicate 956 * @param string the string to duplicate
893 * @return (@c cxmutstr) a duplicate of the string 957 * @return (@c cxmutstr) a duplicate of the string
1014 /** 1078 /**
1015 * Replaces a string with another string. 1079 * Replaces a string with another string.
1016 * 1080 *
1017 * Replaces at most @p replmax occurrences. 1081 * Replaces at most @p replmax occurrences.
1018 * 1082 *
1019 * The returned string will be allocated by @c malloc() and is guaranteed 1083 * The returned string will be allocated by the cxDefaultAllocator and is guaranteed
1020 * to be zero-terminated. 1084 * to be zero-terminated.
1021 * 1085 *
1022 * If allocation fails, or the input string is empty, 1086 * If allocation fails, or the input string is empty,
1023 * the returned string will be empty. 1087 * the returned string will be empty.
1024 * 1088 *
1050 cx_strreplacen_a(allocator, str, search, replacement, SIZE_MAX) 1114 cx_strreplacen_a(allocator, str, search, replacement, SIZE_MAX)
1051 1115
1052 /** 1116 /**
1053 * Replaces a string with another string. 1117 * Replaces a string with another string.
1054 * 1118 *
1055 * The returned string will be allocated by @c malloc() and is guaranteed 1119 * The returned string will be allocated by the cxDefaultAllocator and is guaranteed
1056 * to be zero-terminated. 1120 * to be zero-terminated.
1057 * 1121 *
1058 * If allocation fails, or the input string is empty, 1122 * If allocation fails, or the input string is empty,
1059 * the returned string will be empty. 1123 * the returned string will be empty.
1060 * 1124 *

mercurial