Wed, 16 Apr 2025 20:35:34 +0200
bring back CX_PRIstr and CX_SFMT macros - resolves #612
--- a/CHANGELOG Tue Apr 15 22:16:05 2025 +0200 +++ b/CHANGELOG Wed Apr 16 20:35:34 2025 +0200 @@ -6,6 +6,7 @@ * adds cxListContains() * adds cxBufferShrink() * adds cxTreeSize() + * adds CX_PRIstr and CX_SFMT macros for formatting UCX strings * changes grow strategy for the mempory pool to reduce reallocations * changes grow strategy for CxBuffer, which does now take the page size into account * fixes unnecessary allocations in cx_strcat() family of functions
--- a/docs/Writerside/topics/about.md Tue Apr 15 22:16:05 2025 +0200 +++ b/docs/Writerside/topics/about.md Wed Apr 16 20:35:34 2025 +0200 @@ -33,6 +33,7 @@ * adds cxListContains() * adds cxBufferShrink() * adds cxTreeSize() +* adds CX_PRIstr and CX_SFMT macros for formatting UCX strings * changes grow strategy for the mempory pool to reduce reallocations * changes grow strategy for CxBuffer, which does now take the page size into account * fixes unnecessary allocations in cx_strcat() family of functions
--- a/docs/Writerside/topics/string.h.md Tue Apr 15 22:16:05 2025 +0200 +++ b/docs/Writerside/topics/string.h.md Wed Apr 16 20:35:34 2025 +0200 @@ -42,6 +42,10 @@ void cx_strfree(cxmutstr *str); void cx_strfree_a(const CxAllocator *alloc, cxmutstr *str); + + +#define CX_SFMT(s) (int) (s).length, (s).ptr +#define CX_PRIstr ".*s" ``` The functions `cx_str()` and `cx_mutstr()` create a UCX string from a `const char*` or a `char*` @@ -57,6 +61,9 @@ It is safe to call these functions multiple times on a given string, as the pointer will be nulled and the length set to zero. It is also safe to call the functions with a `NULL`-pointer, just like any other `free()`-like function. +When you want to use a UCX string in a `printf`-like function, you can use the macro `CX_PRIstr` for the format specifier, +and the `CX_SFMT(s)` macro to expand the arguments. + > When you want to convert a string _literal_ into a UCX string, you can also use the `CX_STR(lit)` macro. > This macro uses the fact that `sizeof(lit)` for a string literal `lit` is always the string length plus one, > effectively saving an invocation of `strlen()`.
--- a/src/cx/string.h Tue Apr 15 22:16:05 2025 +0200 +++ b/src/cx/string.h Wed Apr 16 20:35:34 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. */
--- a/tests/test_string.c Tue Apr 15 22:16:05 2025 +0200 +++ b/tests/test_string.c Wed Apr 16 20:35:34 2025 +0200 @@ -1247,6 +1247,15 @@ } } +CX_TEST(test_strformat) { + cxstring str = CX_STR("Hello, World!"); + CX_TEST_DO { + char actual[64]; + snprintf(actual, 64, "Test %"CX_PRIstr " Success.", CX_SFMT(str)); + CX_TEST_ASSERT(0 == strncmp("Test Hello, World! Success.", actual, 64)); + } +} + CxTestSuite *cx_test_suite_string(void) { CxTestSuite *suite = cx_test_suite_new("string"); @@ -1276,6 +1285,7 @@ cx_test_register(suite, test_strtok_next_easy); cx_test_register(suite, test_strtok_next_unlimited); cx_test_register(suite, test_strtok_next_advanced); + cx_test_register(suite, test_strformat); return suite; }