tests/test_printf.c

Sun, 14 Jan 2024 13:13:12 +0100

author
Mike Becker <universe@uap-core.de>
date
Sun, 14 Jan 2024 13:13:12 +0100
changeset 805
26500fc24058
parent 780
9965df621652
child 810
85859399a0cc
permissions
-rw-r--r--

add constant for reading out printf sbo size - relates to #343

universe@780 1 /*
universe@780 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
universe@780 3 *
universe@780 4 * Copyright 2023 Mike Becker, Olaf Wintermann All rights reserved.
universe@780 5 *
universe@780 6 * Redistribution and use in source and binary forms, with or without
universe@780 7 * modification, are permitted provided that the following conditions are met:
universe@780 8 *
universe@780 9 * 1. Redistributions of source code must retain the above copyright
universe@780 10 * notice, this list of conditions and the following disclaimer.
universe@780 11 *
universe@780 12 * 2. Redistributions in binary form must reproduce the above copyright
universe@780 13 * notice, this list of conditions and the following disclaimer in the
universe@780 14 * documentation and/or other materials provided with the distribution.
universe@780 15 *
universe@780 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
universe@780 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
universe@780 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
universe@780 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
universe@780 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
universe@780 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
universe@780 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
universe@780 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
universe@780 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
universe@780 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
universe@780 26 * POSSIBILITY OF SUCH DAMAGE.
universe@780 27 */
universe@780 28
universe@780 29 #include "cx/test.h"
universe@780 30 #include "util_allocator.h"
universe@780 31
universe@780 32 #include "cx/printf.h"
universe@780 33 #include "cx/buffer.h"
universe@780 34
universe@780 35 #define ASSERT_ZERO_TERMINATED(str) CX_TEST_ASSERTM((str).ptr[(str).length] == '\0', \
universe@780 36 #str " is not zero terminated")
universe@780 37
universe@780 38 static size_t test_printf_write_func(
universe@780 39 void const *src,
universe@780 40 size_t esize,
universe@780 41 size_t ecount,
universe@780 42 void *target
universe@780 43 ) {
universe@780 44 memcpy(target, src, esize * ecount);
universe@780 45 return esize * ecount;
universe@780 46 }
universe@780 47
universe@780 48 CX_TEST(test_bprintf) {
universe@780 49 CxTestingAllocator talloc;
universe@780 50 cx_testing_allocator_init(&talloc);
universe@780 51 CxAllocator *alloc = &talloc.base;
universe@780 52 CX_TEST_DO {
universe@780 53 CxBuffer buf;
universe@780 54 cxBufferInit(&buf, NULL, 64, alloc, 0);
universe@780 55 size_t r = cx_bprintf(&buf, "This %s aged %u years in a %2XSK.", "Test", 10, 0xca);
universe@780 56 CX_TEST_ASSERT(r == 34);
universe@780 57 CX_TEST_ASSERT(buf.size == 34);
universe@780 58 buf.space[r] = '\0';
universe@780 59 CX_TEST_ASSERT(0 == strcmp(buf.space, "This Test aged 10 years in a CASK."));
universe@780 60 cxBufferDestroy(&buf);
universe@780 61 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
universe@780 62 }
universe@780 63 cx_testing_allocator_destroy(&talloc);
universe@780 64 }
universe@780 65
universe@780 66 CX_TEST(test_bprintf_large_string) {
universe@805 67 unsigned len = cx_printf_sbo_size;
universe@780 68 CxTestingAllocator talloc;
universe@780 69 cx_testing_allocator_init(&talloc);
universe@780 70 CxAllocator *alloc = &talloc.base;
universe@805 71 char *aaa = malloc(len);
universe@805 72 char *bbb = malloc(len);
universe@805 73 char *expected = malloc(2*len+16);
universe@805 74 memset(aaa, 'a', len-1);
universe@805 75 aaa[len-1] = 0;
universe@805 76 memset(bbb, 'b', len-1);
universe@805 77 bbb[len-1] = 0;
universe@780 78 sprintf(expected, "After %s comes %s.", aaa, bbb);
universe@780 79 CX_TEST_DO {
universe@780 80 CxBuffer buf;
universe@780 81 cxBufferInit(&buf, NULL, 64, alloc, CX_BUFFER_AUTO_EXTEND);
universe@780 82 size_t r = cx_bprintf(&buf, "After %s comes %s.", aaa, bbb);
universe@805 83 size_t er = 2*len-2+14;
universe@805 84 CX_TEST_ASSERT(r == er);
universe@805 85 CX_TEST_ASSERT(buf.size == er);
universe@780 86 cxBufferPut(&buf, 0);
universe@780 87 CX_TEST_ASSERT(0 == strcmp(expected, buf.space));
universe@780 88 cxBufferDestroy(&buf);
universe@780 89 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
universe@780 90 }
universe@780 91 free(aaa);
universe@780 92 free(bbb);
universe@780 93 free(expected);
universe@780 94 cx_testing_allocator_destroy(&talloc);
universe@780 95 }
universe@780 96
universe@780 97 CX_TEST(test_bprintf_nocap) {
universe@780 98 CxTestingAllocator talloc;
universe@780 99 cx_testing_allocator_init(&talloc);
universe@780 100 CxAllocator *alloc = &talloc.base;
universe@780 101 char space[20];
universe@780 102 memset(space, 'a', 20);
universe@780 103 CX_TEST_DO {
universe@780 104 CxBuffer buf;
universe@780 105 cxBufferInit(&buf, space, 16, alloc, 0);
universe@780 106 size_t r = cx_bprintf(&buf, "Hello %s with more than %d chars.", "string", 16);
universe@780 107 CX_TEST_ASSERT(r == 16);
universe@780 108 CX_TEST_ASSERT(buf.size == 16);
universe@780 109 CX_TEST_ASSERT(0 == memcmp(space, "Hello string witaaaa", 20));
universe@780 110 cxBufferDestroy(&buf);
universe@780 111 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
universe@780 112 }
universe@780 113 cx_testing_allocator_destroy(&talloc);
universe@780 114 }
universe@780 115
universe@780 116 CX_TEST(test_fprintf) {
universe@780 117 char const *h = "Hello";
universe@780 118 char buf[32];
universe@780 119 size_t r;
universe@780 120 CX_TEST_DO {
universe@780 121 r = cx_fprintf(buf, test_printf_write_func, "teststring");
universe@780 122 CX_TEST_ASSERT(r == 10);
universe@780 123 CX_TEST_ASSERT(0 == memcmp(buf, "teststring", r));
universe@780 124
universe@780 125 r = cx_fprintf(buf, test_printf_write_func, "[%10s]", h);
universe@780 126 CX_TEST_ASSERT(r == 12);
universe@780 127 CX_TEST_ASSERT(0 == memcmp(buf, "[ Hello]", r));
universe@780 128
universe@780 129 r = cx_fprintf(buf, test_printf_write_func, "[%-10s]", h);
universe@780 130 CX_TEST_ASSERT(r == 12);
universe@780 131 CX_TEST_ASSERT(0 == memcmp(buf, "[Hello ]", r));
universe@780 132
universe@780 133 r = cx_fprintf(buf, test_printf_write_func, "[%*s]", 10, h);
universe@780 134 CX_TEST_ASSERT(r == 12);
universe@780 135 CX_TEST_ASSERT(0 == memcmp(buf, "[ Hello]", r));
universe@780 136
universe@780 137 r = cx_fprintf(buf, test_printf_write_func, "[%-10.*s]", 4, h);
universe@780 138 CX_TEST_ASSERT(r == 12);
universe@780 139 CX_TEST_ASSERT(0 == memcmp(buf, "[Hell ]", r));
universe@780 140
universe@780 141 r = cx_fprintf(buf, test_printf_write_func, "[%-*.*s]", 10, 4, h);
universe@780 142 CX_TEST_ASSERT(r == 12);
universe@780 143 CX_TEST_ASSERT(0 == memcmp(buf, "[Hell ]", r));
universe@780 144
universe@780 145 r = cx_fprintf(buf, test_printf_write_func, "%c", 'A');
universe@780 146 CX_TEST_ASSERT(r == 1);
universe@780 147 CX_TEST_ASSERT(0 == memcmp(buf, "A", r));
universe@780 148
universe@780 149 r = cx_fprintf(buf, test_printf_write_func, "%i %d %.6i %i %.0i %+i %i", 1, 2, 3, 0, 0, 4, -4);
universe@780 150 CX_TEST_ASSERT(r == 19);
universe@780 151 CX_TEST_ASSERT(0 == memcmp(buf, "1 2 000003 0 +4 -4", r));
universe@780 152
universe@780 153 r = cx_fprintf(buf, test_printf_write_func, "%x %x %X %#x", 5, 10, 10, 6);
universe@780 154 CX_TEST_ASSERT(r == 9);
universe@780 155 CX_TEST_ASSERT(0 == memcmp(buf, "5 a A 0x6", r));
universe@780 156
universe@780 157 r = cx_fprintf(buf, test_printf_write_func, "%o %#o %#o", 10, 10, 4);
universe@780 158 CX_TEST_ASSERT(r == 9);
universe@780 159 CX_TEST_ASSERT(0 == memcmp(buf, "12 012 04", r));
universe@780 160
universe@780 161 r = cx_fprintf(buf, test_printf_write_func, "%05.2f %.2f %5.2f", 1.5, 1.5, 1.5);
universe@780 162 CX_TEST_ASSERT(r == 16);
universe@780 163 CX_TEST_ASSERT(0 == memcmp(buf, "01.50 1.50 1.50", r));
universe@780 164
universe@780 165 r = cx_fprintf(buf, test_printf_write_func, "'%*c'", 5, 'x');
universe@780 166 CX_TEST_ASSERT(r == 7);
universe@780 167 CX_TEST_ASSERT(0 == memcmp(buf, "' x'", r));
universe@780 168
universe@780 169 r = cx_fprintf(buf, test_printf_write_func, "'%*c'", -5, 'x');
universe@780 170 CX_TEST_ASSERT(r == 7);
universe@780 171 CX_TEST_ASSERT(0 == memcmp(buf, "'x '", r));
universe@780 172 }
universe@780 173 }
universe@780 174
universe@780 175 CX_TEST(test_asprintf) {
universe@780 176 CxTestingAllocator talloc;
universe@780 177 cx_testing_allocator_init(&talloc);
universe@780 178 CxAllocator *alloc = &talloc.base;
universe@780 179
universe@780 180 char const *h = "Hello";
universe@780 181
universe@780 182 int const specimen_count = 13;
universe@780 183 cxmutstr r[specimen_count];
universe@780 184 int specimen = 0;
universe@780 185
universe@780 186 CX_TEST_DO {
universe@780 187 r[specimen] = cx_asprintf_a(alloc, "teststring");
universe@780 188 CX_TEST_ASSERT(r[specimen].length == 10);
universe@780 189 ASSERT_ZERO_TERMINATED(r[specimen]);
universe@780 190 CX_TEST_ASSERT(0 == strcmp(r[specimen].ptr, "teststring"));
universe@780 191 specimen++;
universe@780 192
universe@780 193 r[specimen] = cx_asprintf_a(alloc, "[%10s]", h);
universe@780 194 CX_TEST_ASSERT(r[specimen].length == 12);
universe@780 195 ASSERT_ZERO_TERMINATED(r[specimen]);
universe@780 196 CX_TEST_ASSERT(0 == strcmp(r[specimen].ptr, "[ Hello]"));
universe@780 197 specimen++;
universe@780 198
universe@780 199 r[specimen] = cx_asprintf_a(alloc, "[%-10s]", h);
universe@780 200 CX_TEST_ASSERT(r[specimen].length == 12);
universe@780 201 ASSERT_ZERO_TERMINATED(r[specimen]);
universe@780 202 CX_TEST_ASSERT(0 == strcmp(r[specimen].ptr, "[Hello ]"));
universe@780 203 specimen++;
universe@780 204
universe@780 205 r[specimen] = cx_asprintf_a(alloc, "[%*s]", 10, h);
universe@780 206 CX_TEST_ASSERT(r[specimen].length == 12);
universe@780 207 ASSERT_ZERO_TERMINATED(r[specimen]);
universe@780 208 CX_TEST_ASSERT(0 == strcmp(r[specimen].ptr, "[ Hello]"));
universe@780 209 specimen++;
universe@780 210
universe@780 211 r[specimen] = cx_asprintf_a(alloc, "[%-10.*s]", 4, h);
universe@780 212 CX_TEST_ASSERT(r[specimen].length == 12);
universe@780 213 ASSERT_ZERO_TERMINATED(r[specimen]);
universe@780 214 CX_TEST_ASSERT(0 == strcmp(r[specimen].ptr, "[Hell ]"));
universe@780 215 specimen++;
universe@780 216
universe@780 217 r[specimen] = cx_asprintf_a(alloc, "[%-*.*s]", 10, 4, h);
universe@780 218 CX_TEST_ASSERT(r[specimen].length == 12);
universe@780 219 ASSERT_ZERO_TERMINATED(r[specimen]);
universe@780 220 CX_TEST_ASSERT(0 == strcmp(r[specimen].ptr, "[Hell ]"));
universe@780 221 specimen++;
universe@780 222
universe@780 223 r[specimen] = cx_asprintf_a(alloc, "%c", 'A');
universe@780 224 CX_TEST_ASSERT(r[specimen].length == 1);
universe@780 225 ASSERT_ZERO_TERMINATED(r[specimen]);
universe@780 226 CX_TEST_ASSERT(0 == strcmp(r[specimen].ptr, "A"));
universe@780 227 specimen++;
universe@780 228
universe@780 229 r[specimen] = cx_asprintf_a(alloc, "%i %d %.6i %i %.0i %+i %i", 1, 2, 3, 0, 0, 4, -4);
universe@780 230 CX_TEST_ASSERT(r[specimen].length == 19);
universe@780 231 ASSERT_ZERO_TERMINATED(r[specimen]);
universe@780 232 CX_TEST_ASSERT(0 == strcmp(r[specimen].ptr, "1 2 000003 0 +4 -4"));
universe@780 233 specimen++;
universe@780 234
universe@780 235 r[specimen] = cx_asprintf_a(alloc, "%x %x %X %#x", 5, 10, 10, 6);
universe@780 236 CX_TEST_ASSERT(r[specimen].length == 9);
universe@780 237 ASSERT_ZERO_TERMINATED(r[specimen]);
universe@780 238 CX_TEST_ASSERT(0 == strcmp(r[specimen].ptr, "5 a A 0x6"));
universe@780 239 specimen++;
universe@780 240
universe@780 241 r[specimen] = cx_asprintf_a(alloc, "%o %#o %#o", 10, 10, 4);
universe@780 242 CX_TEST_ASSERT(r[specimen].length == 9);
universe@780 243 ASSERT_ZERO_TERMINATED(r[specimen]);
universe@780 244 CX_TEST_ASSERT(0 == strcmp(r[specimen].ptr, "12 012 04"));
universe@780 245 specimen++;
universe@780 246
universe@780 247 r[specimen] = cx_asprintf_a(alloc, "%05.2f %.2f %5.2f", 1.5, 1.5, 1.5);
universe@780 248 CX_TEST_ASSERT(r[specimen].length == 16);
universe@780 249 ASSERT_ZERO_TERMINATED(r[specimen]);
universe@780 250 CX_TEST_ASSERT(0 == strcmp(r[specimen].ptr, "01.50 1.50 1.50"));
universe@780 251 specimen++;
universe@780 252
universe@780 253 r[specimen] = cx_asprintf_a(alloc, "'%*c'", 5, 'x');
universe@780 254 CX_TEST_ASSERT(r[specimen].length == 7);
universe@780 255 ASSERT_ZERO_TERMINATED(r[specimen]);
universe@780 256 CX_TEST_ASSERT(0 == strcmp(r[specimen].ptr, "' x'"));
universe@780 257 specimen++;
universe@780 258
universe@780 259 r[specimen] = cx_asprintf_a(alloc, "'%*c'", -5, 'x');
universe@780 260 CX_TEST_ASSERT(r[specimen].length == 7);
universe@780 261 ASSERT_ZERO_TERMINATED(r[specimen]);
universe@780 262 CX_TEST_ASSERT(0 == strcmp(r[specimen].ptr, "'x '"));
universe@780 263 specimen++;
universe@780 264
universe@780 265 CX_TEST_ASSERT(specimen == specimen_count); // self-test
universe@780 266
universe@780 267 for (int i = 0; i < specimen_count; i++) {
universe@780 268 cx_strfree_a(alloc, &r[i]);
universe@780 269 }
universe@780 270 CX_TEST_ASSERT(cx_testing_allocator_verify(&talloc));
universe@780 271 }
universe@780 272 cx_testing_allocator_destroy(&talloc);
universe@780 273 }
universe@780 274
universe@780 275 CX_TEST(test_asprintf_large_string) {
universe@805 276 unsigned len = cx_printf_sbo_size;
universe@805 277 char *aaa = malloc(len);
universe@805 278 char *bbb = malloc(len);
universe@805 279 char *expected = malloc(2*len+16);
universe@805 280 memset(aaa, 'a', len-1);
universe@805 281 aaa[len-1] = 0;
universe@805 282 memset(bbb, 'b', len-1);
universe@805 283 bbb[len-1] = 0;
universe@780 284 sprintf(expected, "After %s comes %s.", aaa, bbb);
universe@780 285 CX_TEST_DO {
universe@780 286 cxmutstr r = cx_asprintf("After %s comes %s.", aaa, bbb);
universe@805 287 CX_TEST_ASSERT(r.length == 2*len-2+14);
universe@780 288 ASSERT_ZERO_TERMINATED(r);
universe@780 289 CX_TEST_ASSERT(0 == strcmp(r.ptr, expected));
universe@780 290 cx_strfree(&r);
universe@780 291 }
universe@780 292 free(aaa);
universe@780 293 free(bbb);
universe@780 294 free(expected);
universe@780 295 }
universe@780 296
universe@780 297 CxTestSuite *cx_test_suite_printf(void) {
universe@780 298 CxTestSuite *suite = cx_test_suite_new("printf");
universe@780 299
universe@780 300 cx_test_register(suite, test_bprintf);
universe@780 301 cx_test_register(suite, test_bprintf_large_string);
universe@780 302 cx_test_register(suite, test_bprintf_nocap);
universe@780 303 cx_test_register(suite, test_fprintf);
universe@780 304 cx_test_register(suite, test_asprintf);
universe@780 305 cx_test_register(suite, test_asprintf_large_string);
universe@780 306
universe@780 307 return suite;
universe@780 308 }

mercurial