tests/test_printf.c

Fri, 29 Dec 2023 17:27:14 +0100

author
Mike Becker <universe@uap-core.de>
date
Fri, 29 Dec 2023 17:27:14 +0100
changeset 780
9965df621652
child 805
26500fc24058
permissions
-rw-r--r--

migrate printf tests - relates to #342

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

mercurial