chiark / gitweb /
struct/buf.c: Add functions for serializing and deserializing `kludge64'.
[mLib] / struct / t / dstr-putf-test.c
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"
11 #include "macros.h"
12
13 static int win = 0, lose = 0;
14 static dstr d = DSTR_INIT;
15 static char buf[1024];
16
17 static void check(const char *what, const char *want)
18 {
19   if (STRCMP(want, ==, d.buf))
20     win++;
21   else {
22     lose++;
23     fprintf(stderr, "test failed: %s\n  expected: %s\n     found: %s\n",
24             what, want, d.buf);
25   }
26 }
27
28 static void PRINTF_LIKE(1, 2) format(const char *fmt, ...)
29 {
30   va_list ap;
31   va_start(ap, fmt);
32   dstr_reset(&d);
33   dstr_vputf(&d, fmt, &ap);
34   va_end(ap);
35 }
36
37 static void PRINTF_LIKE(1, 2) prepare(const char *fmt, ...)
38 {
39   va_list ap;
40   int n;
41
42   va_start(ap, fmt);
43 #ifdef HAVE_SNPRINTF
44   n = vsnprintf(buf, sizeof(buf), fmt, ap);
45 #else
46   n = vsprintf(buf, fmt, ap);
47 #endif
48   assert(0 <= n && n < sizeof(buf));
49 }
50
51 #define TEST1(fmtargs) do {                                             \
52   format fmtargs;                                                       \
53   prepare fmtargs;                                                      \
54   check(#fmtargs, buf);                                                 \
55 } while (0)
56
57 #define TEST2(fmtargs, want) do {                                       \
58   format fmtargs;                                                       \
59   check(#fmtargs, want);                                                \
60 } while (0)
61
62 #define LENGTHY \
63   "This is a rather longer string than the code is expecting: will it fit?"
64
65 int main(void)
66 {
67   TEST2(("Hello, world!"), "Hello, world!");
68   TEST2(("just a ->%%<- sign"), "just a ->%<- sign");
69   TEST2(("Testing, testing, %d, %d, %d.", 1, 2, 3),
70         "Testing, testing, 1, 2, 3.");
71   TEST2(("->%5d<-", 138), "->  138<-");
72   TEST2(("->%*d<-", 5, 138), "->  138<-");
73   TEST2(("->%-*d<-", 5, 138), "->138  <-");
74   TEST2(("->%*d<-", -5, 138), "->138  <-");
75   TEST2(("->%-*d<-", -5, 138), "->138  <-");
76   TEST2(("->%.*s<-", 5, "truncate me"), "->trunc<-");
77   TEST2(("->%.*s<-", -5, "don't truncate me"), "->don't truncate me<-");
78   TEST2(("Truncation indirect: ->%.*s<-", 10, "a long string to be chopped"),
79         "Truncation indirect: ->a long str<-");
80   TEST2(("%08lx:%s", 0x65604204ul, "tripe-ec"), "65604204:tripe-ec");
81   TEST2(("%s", LENGTHY), LENGTHY);
82
83   TEST1(("big float: ->%f<- and integer %d\n", DBL_MAX, 42));
84
85   TEST2(("Testing, testing, %3$d, %2$d, %1$d.", 3, 2, 1),
86         "Testing, testing, 1, 2, 3.");
87   TEST2(("Truncation indirect: ->%1$.*2$s<-",
88          "a long string to be chopped", 10),
89         "Truncation indirect: ->a long str<-");
90
91   if (!lose) printf("All tests successful.\n");
92   else printf("FAILED %d of %d tests.\n", lose, win + lose);
93   return (!!lose);
94 }