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