1 | /* |
---|
2 | * snprintf test suite. |
---|
3 | * |
---|
4 | * Written by Russ Allbery <rra@stanford.edu> |
---|
5 | * Copyright 2009 Board of Trustees, Leland Stanford Jr. University |
---|
6 | * Copyright (c) 2004, 2005, 2006 |
---|
7 | * by Internet Systems Consortium, Inc. ("ISC") |
---|
8 | * Copyright (c) 1991, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, |
---|
9 | * 2002, 2003 by The Internet Software Consortium and Rich Salz |
---|
10 | * |
---|
11 | * See LICENSE for licensing terms. |
---|
12 | */ |
---|
13 | |
---|
14 | #include <config.h> |
---|
15 | #include <portable/system.h> |
---|
16 | |
---|
17 | #include <tests/tap/basic.h> |
---|
18 | |
---|
19 | int test_snprintf(char *str, size_t count, const char *fmt, ...); |
---|
20 | int test_vsnprintf(char *str, size_t count, const char *fmt, va_list args); |
---|
21 | |
---|
22 | static const char string[] = "abcdefghijklmnopqrstuvwxyz0123456789"; |
---|
23 | |
---|
24 | static const char *const fp_formats[] = { |
---|
25 | "%-1.5f", "%1.5f", "%31.9f", "%10.5f", "% 10.5f", "%+22.9f", |
---|
26 | "%+4.9f", "%01.3f", "%3.1f", "%3.2f", "%.0f", "%.1f", |
---|
27 | "%f", |
---|
28 | |
---|
29 | /* %e and %g formats aren't really implemented yet. */ |
---|
30 | #if 0 |
---|
31 | "%-1.5e", "%1.5e", "%31.9e", "%10.5e", "% 10.5e", "%+22.9e", |
---|
32 | "%+4.9e", "%01.3e", "%3.1e", "%3.2e", "%.0e", "%.1e", |
---|
33 | "%e", |
---|
34 | "%-1.5g", "%1.5g", "%31.9g", "%10.5g", "% 10.5g", "%+22.9g", |
---|
35 | "%+4.9g", "%01.3g", "%3.1g", "%3.2g", "%.0g", "%.1g", |
---|
36 | "%g", |
---|
37 | #endif |
---|
38 | NULL |
---|
39 | }; |
---|
40 | static const char *const int_formats[] = { |
---|
41 | "%-1.5d", "%1.5d", "%31.9d", "%5.5d", "%10.5d", "% 10.5d", |
---|
42 | "%+22.30d", "%01.3d", "%4d", "%d", "%ld", NULL |
---|
43 | }; |
---|
44 | static const char *const uint_formats[] = { |
---|
45 | "%-1.5lu", "%1.5lu", "%31.9lu", "%5.5lu", "%10.5lu", "% 10.5lu", |
---|
46 | "%+6.30lu", "%01.3lu", "%4lu", "%lu", "%4lx", "%4lX", |
---|
47 | "%01.3lx", "%1lo", NULL |
---|
48 | }; |
---|
49 | static const char *const llong_formats[] = { |
---|
50 | "%lld", "%-1.5lld", "%1.5lld", "%123.9lld", "%5.5lld", |
---|
51 | "%10.5lld", "% 10.5lld", "%+22.33lld", "%01.3lld", "%4lld", |
---|
52 | NULL |
---|
53 | }; |
---|
54 | static const char *const ullong_formats[] = { |
---|
55 | "%llu", "%-1.5llu", "%1.5llu", "%123.9llu", "%5.5llu", |
---|
56 | "%10.5llu", "% 10.5llu", "%+22.33llu", "%01.3llu", "%4llu", |
---|
57 | "%llx", "%llo", NULL |
---|
58 | }; |
---|
59 | |
---|
60 | static const double fp_nums[] = { |
---|
61 | -1.5, 134.21, 91340.2, 341.1234, 0203.9, 0.96, 0.996, 0.9996, 1.996, |
---|
62 | 4.136, 0.1, 0.01, 0.001, 10.1, 0 |
---|
63 | }; |
---|
64 | static long int_nums[] = { |
---|
65 | -1, 134, 91340, 341, 0203, 0 |
---|
66 | }; |
---|
67 | static unsigned long uint_nums[] = { |
---|
68 | (unsigned long) -1, 134, 91340, 341, 0203, 0 |
---|
69 | }; |
---|
70 | static long long llong_nums[] = { |
---|
71 | ~(long long) 0, /* All-1 bit pattern. */ |
---|
72 | (~(unsigned long long) 0) >> 1, /* Largest signed long long. */ |
---|
73 | -150, 134, 91340, 341, |
---|
74 | 0 |
---|
75 | }; |
---|
76 | static unsigned long long ullong_nums[] = { |
---|
77 | ~(unsigned long long) 0, /* All-1 bit pattern. */ |
---|
78 | (~(unsigned long long) 0) >> 1, /* Largest signed long long. */ |
---|
79 | 134, 91340, 341, |
---|
80 | 0 |
---|
81 | }; |
---|
82 | |
---|
83 | |
---|
84 | static void |
---|
85 | test_format(bool truncate, const char *expected, int count, |
---|
86 | const char *format, ...) |
---|
87 | { |
---|
88 | char buf[128]; |
---|
89 | int result; |
---|
90 | va_list args; |
---|
91 | |
---|
92 | va_start(args, format); |
---|
93 | result = test_vsnprintf(buf, truncate ? 32 : sizeof(buf), format, args); |
---|
94 | va_end(args); |
---|
95 | is_string(expected, buf, "format %s, wanted %s", format, expected); |
---|
96 | is_int(count, result, "...and output length correct"); |
---|
97 | } |
---|
98 | |
---|
99 | |
---|
100 | int |
---|
101 | main(void) |
---|
102 | { |
---|
103 | int n, i, count; |
---|
104 | unsigned int j; |
---|
105 | long lcount; |
---|
106 | char lgbuf[128]; |
---|
107 | |
---|
108 | plan(8 + |
---|
109 | (18 + (ARRAY_SIZE(fp_formats) - 1) * ARRAY_SIZE(fp_nums) |
---|
110 | + (ARRAY_SIZE(int_formats) - 1) * ARRAY_SIZE(int_nums) |
---|
111 | + (ARRAY_SIZE(uint_formats) - 1) * ARRAY_SIZE(uint_nums) |
---|
112 | + (ARRAY_SIZE(llong_formats) - 1) * ARRAY_SIZE(llong_nums) |
---|
113 | + (ARRAY_SIZE(ullong_formats) - 1) * ARRAY_SIZE(ullong_nums)) * 2); |
---|
114 | |
---|
115 | is_int(4, test_snprintf(NULL, 0, "%s", "abcd"), "simple string length"); |
---|
116 | is_int(2, test_snprintf(NULL, 0, "%d", 20), "number length"); |
---|
117 | is_int(7, test_snprintf(NULL, 0, "Test %.2s", "abcd"), "limited string"); |
---|
118 | is_int(1, test_snprintf(NULL, 0, "%c", 'a'), "character length"); |
---|
119 | is_int(0, test_snprintf(NULL, 0, ""), "empty format length"); |
---|
120 | |
---|
121 | test_format(true, "abcd", 4, "%s", "abcd"); |
---|
122 | test_format(true, "20", 2, "%d", 20); |
---|
123 | test_format(true, "Test ab", 7, "Test %.2s", "abcd"); |
---|
124 | test_format(true, "a", 1, "%c", 'a'); |
---|
125 | test_format(true, "", 0, ""); |
---|
126 | test_format(true, "abcdefghijklmnopqrstuvwxyz01234", 36, "%s", string); |
---|
127 | test_format(true, "abcdefghij", 10, "%.10s", string); |
---|
128 | test_format(true, " abcdefghij", 12, "%12.10s", string); |
---|
129 | test_format(true, " abcdefghijklmnopqrstuvwxyz0", 40, "%40s", string); |
---|
130 | test_format(true, "abcdefghij ", 14, "%-14.10s", string); |
---|
131 | test_format(true, " abcdefghijklmnopq", 50, "%50s", string); |
---|
132 | test_format(true, "%abcd%", 6, "%%%0s%%", "abcd"); |
---|
133 | test_format(true, "", 0, "%.0s", string); |
---|
134 | test_format(true, "abcdefghijklmnopqrstuvwxyz 444", 32, "%.26s %d", |
---|
135 | string, 4444); |
---|
136 | test_format(true, "abcdefghijklmnopqrstuvwxyz -2.", 32, "%.26s %.1f", |
---|
137 | string, -2.5); |
---|
138 | test_format(true, "abcdefghij4444", 14, "%.10s%n%d", string, &count, 4444); |
---|
139 | is_int(10, count, "correct output from %%n"); |
---|
140 | test_format(true, "abcdefghijklmnopqrstuvwxyz01234", 36, "%n%s%ln", |
---|
141 | &count, string, &lcount); |
---|
142 | is_int(0, count, "correct output from two %%n"); |
---|
143 | is_int(31, lcount, "correct output from long %%ln"); |
---|
144 | test_format(true, "(null)", 6, "%s", NULL); |
---|
145 | |
---|
146 | n = 26; |
---|
147 | for (i = 0; fp_formats[i] != NULL; i++) |
---|
148 | for (j = 0; j < ARRAY_SIZE(fp_nums); j++) { |
---|
149 | count = sprintf(lgbuf, fp_formats[i], fp_nums[j]); |
---|
150 | test_format(false, lgbuf, count, fp_formats[i], fp_nums[j]); |
---|
151 | } |
---|
152 | for (i = 0; int_formats[i] != NULL; i++) |
---|
153 | for (j = 0; j < ARRAY_SIZE(int_nums); j++) { |
---|
154 | count = sprintf(lgbuf, int_formats[i], int_nums[j]); |
---|
155 | test_format(false, lgbuf, count, int_formats[i], int_nums[j]); |
---|
156 | } |
---|
157 | for (i = 0; uint_formats[i] != NULL; i++) |
---|
158 | for (j = 0; j < ARRAY_SIZE(uint_nums); j++) { |
---|
159 | count = sprintf(lgbuf, uint_formats[i], uint_nums[j]); |
---|
160 | test_format(false, lgbuf, count, uint_formats[i], uint_nums[j]); |
---|
161 | } |
---|
162 | for (i = 0; llong_formats[i] != NULL; i++) |
---|
163 | for (j = 0; j < ARRAY_SIZE(llong_nums); j++) { |
---|
164 | count = sprintf(lgbuf, llong_formats[i], llong_nums[j]); |
---|
165 | test_format(false, lgbuf, count, llong_formats[i], llong_nums[j]); |
---|
166 | } |
---|
167 | for (i = 0; ullong_formats[i] != NULL; i++) |
---|
168 | for (j = 0; j < ARRAY_SIZE(ullong_nums); j++) { |
---|
169 | count = sprintf(lgbuf, ullong_formats[i], ullong_nums[j]); |
---|
170 | test_format(false, lgbuf, count, ullong_formats[i], |
---|
171 | ullong_nums[j]); |
---|
172 | } |
---|
173 | |
---|
174 | return 0; |
---|
175 | } |
---|