diff options
Diffstat (limited to 'tests/lib/test_printfrr.c')
| -rw-r--r-- | tests/lib/test_printfrr.c | 115 |
1 files changed, 111 insertions, 4 deletions
diff --git a/tests/lib/test_printfrr.c b/tests/lib/test_printfrr.c index 24de3fa88d..21b3a916b8 100644 --- a/tests/lib/test_printfrr.c +++ b/tests/lib/test_printfrr.c @@ -59,21 +59,88 @@ static void printcmp(const char *fmt, ...) errors++; } -static void printchk(const char *ref, const char *fmt, ...) PRINTFRR(2, 3); -static void printchk(const char *ref, const char *fmt, ...) +static int printchk(const char *ref, const char *fmt, ...) PRINTFRR(2, 3); +static int printchk(const char *ref, const char *fmt, ...) { va_list ap; char bufrr[256]; + bool truncfail = false; + size_t i; + size_t expectlen; + memset(bufrr, 0xcc, sizeof(bufrr)); va_start(ap, fmt); - vsnprintfrr(bufrr, sizeof(bufrr), fmt, ap); + expectlen = vsnprintfrr(NULL, 0, fmt, ap); + va_end(ap); + + va_start(ap, fmt); + vsnprintfrr(bufrr, 7, fmt, ap); va_end(ap); - printf("fmt: \"%s\"\nref: \"%s\"\nfrr: \"%s\"\n%s\n\n", + if (strnlen(bufrr, 7) == 7) + truncfail = true; + if (strnlen(bufrr, 7) < 7 && strncmp(ref, bufrr, 6) != 0) + truncfail = true; + for (i = 7; i < sizeof(bufrr); i++) + if (bufrr[i] != (char)0xcc) { + truncfail = true; + break; + } + + if (truncfail) { + printf("truncation test FAILED:\n" + "fmt: \"%s\"\nref: \"%s\"\nfrr[:7]: \"%s\"\n%s\n\n", + fmt, ref, bufrr, strcmp(ref, bufrr) ? "ERROR" : "ok"); + errors++; + } + + struct fmt_outpos outpos[16]; + struct fbuf fb = { + .buf = bufrr, + .pos = bufrr, + .len = sizeof(bufrr) - 1, + .outpos = outpos, + .outpos_n = array_size(outpos), + }; + + va_start(ap, fmt); + vbprintfrr(&fb, fmt, ap); + fb.pos[0] = '\0'; + va_end(ap); + + printf("fmt: \"%s\"\nref: \"%s\"\nfrr: \"%s\"\n%s\n", fmt, ref, bufrr, strcmp(ref, bufrr) ? "ERROR" : "ok"); if (strcmp(ref, bufrr)) errors++; + if (strlen(bufrr) != expectlen) { + printf("return value <> length mismatch\n"); + errors++; + } + + for (size_t i = 0; i < fb.outpos_i; i++) + printf("\t[%zu: %u..%u] = \"%.*s\"\n", i, + outpos[i].off_start, + outpos[i].off_end, + (int)(outpos[i].off_end - outpos[i].off_start), + bufrr + outpos[i].off_start); + printf("\n"); + return 0; +} + +static void test_va(const char *ref, const char *fmt, ...) PRINTFRR(2, 3); +static void test_va(const char *ref, const char *fmt, ...) +{ + struct va_format vaf; + va_list ap; + + va_start(ap, fmt); + vaf.fmt = fmt; + vaf.va = ≈ + + printchk(ref, "VA [%pVA] %s", &vaf, "--"); + + va_end(ap); } int main(int argc, char **argv) @@ -112,9 +179,12 @@ int main(int argc, char **argv) inet_aton("192.168.1.2", &ip); printchk("192.168.1.2", "%pI4", &ip); printchk(" 192.168.1.2", "%20pI4", &ip); + printchk("192.168.1.2 ", "%-20pI4", &ip); printcmp("%p", &ip); + test_va("VA [192.168.1.2 1234] --", "%pI4 %u", &ip, 1234); + snprintfrr(buf, sizeof(buf), "test%s", "#1"); csnprintfrr(buf, sizeof(buf), "test%s", "#2"); assert(strcmp(buf, "test#1test#2") == 0); @@ -146,5 +216,42 @@ int main(int argc, char **argv) sg.src.s_addr = INADDR_ANY; printchk("(*,224.1.2.3)", "%pSG4", &sg); + uint8_t randhex[] = { 0x12, 0x34, 0x00, 0xca, 0xfe, 0x00, 0xaa, 0x55 }; + + FMT_NSTD(printchk("12 34 00 ca fe 00 aa 55", "%.8pHX", randhex)); + FMT_NSTD(printchk("12 34 00 ca fe 00 aa 55", "%.*pHX", + (int)sizeof(randhex), randhex)); + FMT_NSTD(printchk("12 34 00 ca", "%.4pHX", randhex)); + + printchk("12 34 00 ca fe 00 aa 55", "%8pHX", randhex); + printchk("12 34 00 ca fe 00 aa 55", "%*pHX", + (int)sizeof(randhex), randhex); + printchk("12 34 00 ca", "%4pHX", randhex); + + printchk("", "%pHX", randhex); + + printchk("12:34:00:ca:fe:00:aa:55", "%8pHXc", randhex); + printchk("123400cafe00aa55", "%8pHXn", randhex); + + printchk("/test/pa\\ th/\\~spe\\ncial\\x01/file.name", "%pSE", + "/test/pa th/~spe\ncial\x01/file.name"); + printchk("/test/pa\\ th/\\~spe\\n", "%17pSE", + "/test/pa th/~spe\ncial\x01/file.name"); + + char nulltest[] = { 'n', 'u', 0, 'l', 'l' }; + + printchk("nu\\x00ll", "%5pSE", nulltest); + printchk("nu\\x00ll", "%*pSE", 5, nulltest); + + printchk("bl\\\"ah\\x01te[st\\nab]c", "%pSQ", + "bl\"ah\x01te[st\nab]c"); + printchk("\"bl\\\"ah\\x01te[st\\nab]c\"", "%pSQq", + "bl\"ah\x01te[st\nab]c"); + printchk("\"bl\\\"ah\\x01te[st\\x0aab\\]c\"", "%pSQqs", + "bl\"ah\x01te[st\nab]c"); + printchk("\"\"", "%pSQqn", ""); + printchk("\"\"", "%pSQqn", (char *)NULL); + printchk("(null)", "%pSQq", (char *)NULL); + return !!errors; } |
