@@@ wip tap 14
[mLib] / struct / t / dstr-putf-test.c
CommitLineData
eff136f6
MW
1#include "config.h"
2
3#include <assert.h>
4#include <float.h>
5#include <stdarg.h>
6#include <stdio.h>
7#include <stdlib.h>
8#include <string.h>
9
10#include "dstr.h"
36188114 11#include "macros.h"
3efcfd2d
MW
12#include "report.h"
13#include "tvec.h"
eff136f6 14
3efcfd2d 15static struct tvec_state tvstate;
eff136f6 16static dstr d = DSTR_INIT;
3efcfd2d 17static char strbuf[1024];
eff136f6 18
3efcfd2d 19#define TESTGROUP(name) TVEC_TESTGROUP_TAG(grp, &tvstate, name)
eff136f6
MW
20
21static void PRINTF_LIKE(1, 2) format(const char *fmt, ...)
22{
23 va_list ap;
24 va_start(ap, fmt);
25 dstr_reset(&d);
26 dstr_vputf(&d, fmt, &ap);
27 va_end(ap);
28}
29
30static void PRINTF_LIKE(1, 2) prepare(const char *fmt, ...)
31{
32 va_list ap;
33 int n;
34
35 va_start(ap, fmt);
36#ifdef HAVE_SNPRINTF
3efcfd2d 37 n = vsnprintf(strbuf, sizeof(strbuf), fmt, ap);
eff136f6 38#else
3efcfd2d 39 n = vsprintf(strbuf, fmt, ap);
eff136f6 40#endif
3efcfd2d 41 assert(0 <= n && n < sizeof(strbuf));
eff136f6
MW
42}
43
3efcfd2d 44#define TEST_KNOWN(fmtargs, want) do { \
eff136f6 45 format fmtargs; \
3efcfd2d
MW
46 tvec_claimeq_string(&tvstate, d.buf, d.len, want, strlen(want), \
47 __FILE__, __LINE__, "format " #fmtargs); \
eff136f6
MW
48} while (0)
49
3efcfd2d 50#define TEST_REF(fmtargs) do { \
eff136f6 51 format fmtargs; \
3efcfd2d
MW
52 prepare fmtargs; \
53 tvec_claimeq_string(&tvstate, d.buf, d.len, strbuf, strlen(strbuf), \
54 __FILE__, __LINE__, "format " #fmtargs); \
eff136f6
MW
55} while (0)
56
57#define LENGTHY \
58 "This is a rather longer string than the code is expecting: will it fit?"
59
3efcfd2d 60int main(int argc, char *argv[])
eff136f6 61{
3efcfd2d
MW
62 struct tvec_test test;
63 int argpos;
64
65 tvec_parseargs(argc, argv, &tvstate, &argpos, &tvec_adhocconfig);
66 if (argpos < argc) die(2, "no input files expected");
67 tvec_adhoc(&tvstate, &test);
68
69 TESTGROUP("basics") {
70 TEST_KNOWN(("Hello, world!"), "Hello, world!");
71 TEST_KNOWN(("just a ->%%<- sign"), "just a ->%<- sign");
72 }
73
74 TESTGROUP("integers") {
75 TEST_KNOWN(("Testing, testing, %d, %d, %d.", 1, 2, 3),
76 "Testing, testing, 1, 2, 3.");
77 TEST_KNOWN(("->%5d<-", 138), "-> 138<-");
78 TEST_KNOWN(("->%*d<-", 5, 138), "-> 138<-");
79 TEST_KNOWN(("->%-*d<-", 5, 138), "->138 <-");
80 TEST_KNOWN(("->%*d<-", -5, 138), "->138 <-");
81 TEST_KNOWN(("->%-*d<-", -5, 138), "->138 <-");
82 }
83
84 TESTGROUP("strings") {
85 TEST_KNOWN(("->%.*s<-", 5, "truncate me"), "->trunc<-");
86 TEST_KNOWN(("->%.*s<-", -5, "don't truncate me"),
87 "->don't truncate me<-");
88 TEST_KNOWN(("Truncation indirect: ->%.*s<-", 10,
89 "a long string to be chopped"),
90 "Truncation indirect: ->a long str<-");
91 }
92
93 TESTGROUP("combinations") {
94 TEST_KNOWN(("%08lx:%s", 0x65604204ul, "tripe-ec"), "65604204:tripe-ec");
95 TEST_REF(("big float: ->%f<- and integer %d\n", DBL_MAX, 42));
96 }
97
98 TESTGROUP("argument-order") {
99 TEST_KNOWN(("Testing, testing, %3$d, %2$d, %1$d.", 3, 2, 1),
100 "Testing, testing, 1, 2, 3.");
101 TEST_KNOWN(("Truncation indirect: ->%1$.*2$s<-",
102 "a long string to be chopped", 10),
103 "Truncation indirect: ->a long str<-");
104 }
105
106 TESTGROUP("misc")
107 TEST_KNOWN(("%s", LENGTHY), LENGTHY);
108
109 return (tvec_end(&tvstate));
eff136f6 110}