diff -r b7e2e1d7ed22 -r 85859399a0cc tests/test_printf.c --- a/tests/test_printf.c Tue Jan 16 23:12:43 2024 +0100 +++ b/tests/test_printf.c Tue Jan 16 23:13:01 2024 +0100 @@ -294,6 +294,107 @@ free(expected); } +CX_TEST(test_sprintf_no_realloc) { + char *buf = malloc(16); + CxTestingAllocator talloc; + cx_testing_allocator_init(&talloc); + CxAllocator *alloc = &talloc.base; + CX_TEST_DO { + char *oldbuf = buf; + size_t len = cx_sprintf_a(alloc, &buf, 16, "Test %d %s", 47, "string"); + CX_TEST_ASSERT(oldbuf == buf); + CX_TEST_ASSERT(len == 14); + CX_TEST_ASSERT(0 == memcmp(buf, "Test 47 string", 15)); + CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); + } + cx_testing_allocator_destroy(&talloc); + free(buf); +} + +CX_TEST(test_sprintf_realloc) { + CxTestingAllocator talloc; + cx_testing_allocator_init(&talloc); + CxAllocator *alloc = &talloc.base; + char *buf = cxMalloc(alloc, 8); + CX_TEST_DO { + size_t len = cx_sprintf_a(alloc, &buf, 8, "Test %d %s", 47, "foobar"); + CX_TEST_ASSERT(len == 14); + CX_TEST_ASSERT(0 == memcmp(buf, "Test 47 foobar", 15)); + cxFree(alloc, buf); + CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); + } + cx_testing_allocator_destroy(&talloc); +} + +CX_TEST(test_sprintf_realloc_to_fit_terminator) { + CxTestingAllocator talloc; + cx_testing_allocator_init(&talloc); + CxAllocator *alloc = &talloc.base; + // make it so that only the zero-terminator does not fit + char *buf = cxMalloc(alloc, 14); + CX_TEST_DO { + size_t len = cx_sprintf_a(alloc, &buf, 14, "Test %d %s", 13, "string"); + CX_TEST_ASSERT(len == 14); + CX_TEST_ASSERT(0 == memcmp(buf, "Test 13 string", 15)); + cxFree(alloc, buf); + CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); + } + cx_testing_allocator_destroy(&talloc); +} + +CX_TEST(test_sprintf_s_no_alloc) { + char buf[16]; + CxTestingAllocator talloc; + cx_testing_allocator_init(&talloc); + CxAllocator *alloc = &talloc.base; + CX_TEST_DO { + char *str; + size_t len = cx_sprintf_sa(alloc, buf, 16, &str, "Test %d %s", 47, "string"); + CX_TEST_ASSERT(str == buf); + CX_TEST_ASSERT(len == 14); + CX_TEST_ASSERT(0 == memcmp(buf, "Test 47 string", 15)); + CX_TEST_ASSERT(0 == memcmp(str, "Test 47 string", 15)); + CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); + } + cx_testing_allocator_destroy(&talloc); +} + +CX_TEST(test_sprintf_s_alloc) { + char buf[16]; + memcpy(buf, "0123456789abcdef", 16); + CxTestingAllocator talloc; + cx_testing_allocator_init(&talloc); + CxAllocator *alloc = &talloc.base; + CX_TEST_DO { + char *str; + size_t len = cx_sprintf_sa(alloc, buf, 16, &str, "Hello %d %s", 4711, "larger string"); + CX_TEST_ASSERT(str != buf); + CX_TEST_ASSERT(len == 24); + CX_TEST_ASSERT(0 == memcmp(str, "Hello 4711 larger string", 25)); + cxFree(alloc, str); + CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); + } + cx_testing_allocator_destroy(&talloc); +} + +CX_TEST(test_sprintf_s_alloc_to_fit_terminator) { + char buf[16]; + memcpy(buf, "0123456789abcdef", 16); + CxTestingAllocator talloc; + cx_testing_allocator_init(&talloc); + CxAllocator *alloc = &talloc.base; + CX_TEST_DO { + char *str; + size_t len = cx_sprintf_sa(alloc, buf, 16, &str, "Hello %d %s", 112, "string"); + CX_TEST_ASSERT(str != buf); + CX_TEST_ASSERT(len == 16); + CX_TEST_ASSERT(0 == memcmp(str, "Hello 112 string", 17)); // include terminator + cxFree(alloc, str); + CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc)); + } + cx_testing_allocator_destroy(&talloc); +} + CxTestSuite *cx_test_suite_printf(void) { CxTestSuite *suite = cx_test_suite_new("printf"); @@ -303,6 +404,12 @@ cx_test_register(suite, test_fprintf); cx_test_register(suite, test_asprintf); cx_test_register(suite, test_asprintf_large_string); + cx_test_register(suite, test_sprintf_no_realloc); + cx_test_register(suite, test_sprintf_realloc); + cx_test_register(suite, test_sprintf_realloc_to_fit_terminator); + cx_test_register(suite, test_sprintf_s_no_alloc); + cx_test_register(suite, test_sprintf_s_alloc); + cx_test_register(suite, test_sprintf_s_alloc_to_fit_terminator); return suite; }