diff -r 591377a27fa3 -r da79af4baec8 ucx/cx/string.h --- a/ucx/cx/string.h Tue Sep 09 16:01:30 2025 +0200 +++ b/ucx/cx/string.h Tue Sep 09 20:56:47 2025 +0200 @@ -39,6 +39,12 @@ #include "common.h" #include "allocator.h" +/** Expands a UCX string as printf arguments. */ +#define CX_SFMT(s) (int) (s).length, (s).ptr + +/** Format specifier for a UCX string */ +#define CX_PRIstr ".*s" + /** * The maximum length of the "needle" in cx_strstr() that can use SBO. */ @@ -161,6 +167,8 @@ * * The length is implicitly inferred by using a call to @c strlen(). * + * When @c NULL is passed, the length will be set to zero. + * * @note the wrapped string will share the specified pointer to the string. * If you do want a copy, use cx_strdup() on the return value of this function. * @@ -171,7 +179,6 @@ * * @see cx_mutstrn() */ -cx_attr_nonnull cx_attr_nodiscard cx_attr_cstr_arg(1) cx_attr_export @@ -206,6 +213,8 @@ * * The length is implicitly inferred by using a call to @c strlen(). * + * When @c NULL is passed, the length will be set to zero. + * * @note the wrapped string will share the specified pointer to the string. * If you do want a copy, use cx_strdup() on the return value of this function. * @@ -216,7 +225,6 @@ * * @see cx_strn() */ -cx_attr_nonnull cx_attr_nodiscard cx_attr_cstr_arg(1) cx_attr_export @@ -257,6 +265,10 @@ static inline cxstring cx_strcast(cxstring str) { return str; } +cx_attr_nodiscard +static inline cxstring cx_strcast(const char *str) { + return cx_str(str); +} extern "C" { #else /** @@ -281,6 +293,17 @@ } /** + * Internal function, do not use. + * @param str + * @return + * @see cx_strcast() + */ +cx_attr_nodiscard +static inline cxstring cx_strcast_z(const char *str) { + return cx_str(str); +} + +/** * Casts a mutable string to an immutable string. * * Does nothing for already immutable strings. @@ -294,12 +317,13 @@ */ #define cx_strcast(str) _Generic((str), \ cxmutstr: cx_strcast_m, \ - cxstring: cx_strcast_c) \ - (str) + cxstring: cx_strcast_c, \ + const char*: cx_strcast_z, \ + char *: cx_strcast_z) (str) #endif /** - * Passes the pointer in this string to @c free(). + * Passes the pointer in this string to the cxDefaultAllocator's @c free() function. * * The pointer in the struct is set to @c NULL and the length is set to zero * which means that this function protects you against double-free. @@ -334,6 +358,46 @@ ); /** + * Copies a string. + * + * The memory in the @p dest structure is either allocated or re-allocated to fit the entire + * source string, including a zero-terminator. + * + * The string in @p dest is guaranteed to be zero-terminated, regardless of whether @p src is. + * + * @param alloc the allocator + * @param dest a pointer to the structure where to copy the contents to + * @param src the source string + * + * @retval zero success + * @retval non-zero if re-allocation failed + */ +cx_attr_nonnull_arg(1) +cx_attr_export +int cx_strcpy_a( + const CxAllocator *alloc, + cxmutstr *dest, + cxstring src +); + + +/** + * Copies a string. + * + * The memory in the @p dest structure is either allocated or re-allocated to fit the entire + * source string, including a zero-terminator. + * + * The string in @p dest is guaranteed to be zero-terminated, regardless of whether @p src is. + * + * @param dest (@c cxmutstr*) a pointer to the structure where to copy the contents to + * @param src (@c cxstring) the source string + * + * @retval zero success + * @retval non-zero if re-allocation failed + */ +#define cx_strcpy(dest, src) cx_strcpy_a(cxDefaultAllocator, dest, src) + +/** * Returns the accumulated length of all specified strings. * * If this sum overflows, errno is set to EOVERFLOW. @@ -408,7 +472,7 @@ /** * Concatenates strings and returns a new string. * - * The resulting string will be allocated by standard @c malloc(). + * The resulting string will be allocated by the cxDefaultAllocator. * So developers @em must pass the return value to cx_strfree() eventually. * * If memory allocation fails, the pointer in the returned string will @@ -428,7 +492,7 @@ /** * Concatenates strings. * - * The resulting string will be allocated by standard @c malloc(). + * The resulting string will be allocated by the cxDefaultAllocator. * So developers @em must pass the return value to cx_strfree() eventually. * * If @p str already contains a string, the memory will be reallocated and @@ -884,8 +948,8 @@ /** * Creates a duplicate of the specified string. * - * The new string will contain a copy allocated by standard - * @c malloc(). So developers @em must pass the return value to cx_strfree(). + * The new string will contain a copy allocated by the cxDefaultAllocator. + * So developers @em must pass the return value to cx_strfree(). * * @note The returned string is guaranteed to be zero-terminated. * @@ -1016,7 +1080,7 @@ * * Replaces at most @p replmax occurrences. * - * The returned string will be allocated by @c malloc() and is guaranteed + * The returned string will be allocated by the cxDefaultAllocator and is guaranteed * to be zero-terminated. * * If allocation fails, or the input string is empty, @@ -1052,7 +1116,7 @@ /** * Replaces a string with another string. * - * The returned string will be allocated by @c malloc() and is guaranteed + * The returned string will be allocated by the cxDefaultAllocator and is guaranteed * to be zero-terminated. * * If allocation fails, or the input string is empty,