summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorschwarze <>2020-07-09 01:49:15 +0000
committerschwarze <>2020-07-09 01:49:15 +0000
commit52b64c85919c83f37c06ee740395852d6d5da007 (patch)
tree960158046001c18a1bc34f24ece02cbc99e29320
parent37d5a25565b15c9551037a5a3f774b99d0af3b34 (diff)
downloadopenbsd-52b64c85919c83f37c06ee740395852d6d5da007.tar.gz
openbsd-52b64c85919c83f37c06ee740395852d6d5da007.tar.bz2
openbsd-52b64c85919c83f37c06ee740395852d6d5da007.zip
New regression tests for integral type conversions
and for their modifiers, written from scratch.
-rw-r--r--src/regress/lib/libc/printf/Makefile4
-rw-r--r--src/regress/lib/libc/printf/int.c376
2 files changed, 378 insertions, 2 deletions
diff --git a/src/regress/lib/libc/printf/Makefile b/src/regress/lib/libc/printf/Makefile
index fba2bd105f..5125fc64da 100644
--- a/src/regress/lib/libc/printf/Makefile
+++ b/src/regress/lib/libc/printf/Makefile
@@ -1,6 +1,6 @@
1# $OpenBSD: Makefile,v 1.2 2020/07/08 01:18:04 schwarze Exp $ 1# $OpenBSD: Makefile,v 1.3 2020/07/09 01:49:15 schwarze Exp $
2 2
3PROGS = fp string 3PROGS = fp int string
4 4
5REGRESS_TARGETS = ${PROGS:S/^/run-regress-/} 5REGRESS_TARGETS = ${PROGS:S/^/run-regress-/}
6 6
diff --git a/src/regress/lib/libc/printf/int.c b/src/regress/lib/libc/printf/int.c
new file mode 100644
index 0000000000..d6ecb7a98d
--- /dev/null
+++ b/src/regress/lib/libc/printf/int.c
@@ -0,0 +1,376 @@
1/* $OpenBSD: int.c,v 1.1 2020/07/09 01:49:15 schwarze Exp $ */
2/*
3 * Copyright (c) 2020 Ingo Schwarze <schwarze@openbsd.org>
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 *
17 * Test the %c, %lc, %s, and %ls conversion specifiers with all their
18 * modifiers, in particular with the minus flag, width, and maxbytes.
19 * Also verify that other flags do nothing useful.
20 */
21#include <err.h>
22#include <stddef.h>
23#include <stdint.h>
24#include <stdio.h>
25#include <string.h>
26#include <unistd.h>
27
28enum int_size {
29 S_CHAR,
30 S_SHORT,
31 S_INT,
32 S_LONG,
33 S_LL,
34 S_MAX,
35 S_PTR,
36 S_SIZE
37};
38
39void ti(const char *, enum int_size, long long, const char *);
40void tu(const char *, enum int_size, unsigned long long, const char *);
41
42static int badret, badlen, badout; /* Error counters. */
43static int verbose; /* For debugging. */
44
45
46/*
47 * Print the signed integer i with the format fmt,
48 * check that the result matches what we want,
49 * and report and count the error on failure.
50 */
51void
52ti(const char *fmt, enum int_size sz, long long i, const char *want)
53{
54 char buf[32];
55 size_t len;
56 int irc, happy;
57
58 happy = 1;
59 switch (sz) {
60 case S_CHAR:
61 irc = snprintf(buf, sizeof(buf), fmt, (signed char)i);
62 break;
63 case S_SHORT:
64 irc = snprintf(buf, sizeof(buf), fmt, (short)i);
65 break;
66 case S_INT:
67 irc = snprintf(buf, sizeof(buf), fmt, (int)i);
68 break;
69 case S_LONG:
70 irc = snprintf(buf, sizeof(buf), fmt, (long)i);
71 break;
72 case S_LL:
73 irc = snprintf(buf, sizeof(buf), fmt, (long long)i);
74 break;
75 case S_MAX:
76 irc = snprintf(buf, sizeof(buf), fmt, (intmax_t)i);
77 break;
78 case S_PTR:
79 irc = snprintf(buf, sizeof(buf), fmt, (ptrdiff_t)i);
80 break;
81 case S_SIZE:
82 irc = snprintf(buf, sizeof(buf), fmt, (ssize_t)i);
83 break;
84 default:
85 warnx("printf(\"%s\", %lld) unknown size code %d",
86 fmt, i, sz);
87 badret++;
88 return;
89 }
90 len = strlen(want);
91 if (irc < 0) {
92 warn("printf(\"%s\", %lld) returned %d", fmt, i, irc);
93 badret++;
94 return;
95 }
96 if ((unsigned long long)irc != len) {
97 warnx("printf(\"%s\", %lld) returned %d (expected %zu)",
98 fmt, i, irc, len);
99 badlen++;
100 happy = 0;
101 }
102 if (strcmp(buf, want) != 0) {
103 warnx("printf(\"%s\", %lld) wrote \"%s\" (expected \"%s\")",
104 fmt, i, buf, want);
105 badout++;
106 happy = 0;
107 }
108 if (verbose && happy)
109 warnx("printf(\"%s\", %lld) wrote \"%s\" length %d (OK)",
110 fmt, i, buf, irc);
111}
112
113/*
114 * Print the unsigned integer i with the format fmt,
115 * check that the result matches what we want,
116 * and report and count the error on failure.
117 */
118void
119tu(const char *fmt, enum int_size sz, unsigned long long i, const char *want)
120{
121 char buf[32];
122 size_t len;
123 int irc, happy;
124
125 happy = 1;
126 switch (sz) {
127 case S_CHAR:
128 irc = snprintf(buf, sizeof(buf), fmt, (unsigned char)i);
129 break;
130 case S_SHORT:
131 irc = snprintf(buf, sizeof(buf), fmt, (unsigned short)i);
132 break;
133 case S_INT:
134 irc = snprintf(buf, sizeof(buf), fmt, (unsigned int)i);
135 break;
136 case S_LONG:
137 irc = snprintf(buf, sizeof(buf), fmt, (unsigned long)i);
138 break;
139 case S_LL:
140 irc = snprintf(buf, sizeof(buf), fmt, (unsigned long long)i);
141 break;
142 case S_MAX:
143 irc = snprintf(buf, sizeof(buf), fmt, (uintmax_t)i);
144 break;
145 case S_SIZE:
146 irc = snprintf(buf, sizeof(buf), fmt, (size_t)i);
147 break;
148 default:
149 warnx("printf(\"%s\", %llu) unknown size code %d",
150 fmt, i, sz);
151 badret++;
152 return;
153 }
154 len = strlen(want);
155 if (irc < 0) {
156 warn("printf(\"%s\", %llu) returned %d", fmt, i, irc);
157 badret++;
158 return;
159 }
160 if ((unsigned long long)irc != len) {
161 warnx("printf(\"%s\", %llu) returned %d (expected %zu)",
162 fmt, i, irc, len);
163 badlen++;
164 happy = 0;
165 }
166 if (strcmp(buf, want) != 0) {
167 warnx("printf(\"%s\", %llu) wrote \"%s\" (expected \"%s\")",
168 fmt, i, buf, want);
169 badout++;
170 happy = 0;
171 }
172 if (verbose && happy)
173 warnx("printf(\"%s\", %llu) wrote \"%s\" length %d (OK)",
174 fmt, i, buf, irc);
175}
176
177int
178main(int argc, char *argv[])
179{
180 int badarg, picky;
181 char ch;
182
183 badarg = picky = 0;
184 while ((ch = getopt(argc, argv, "pv")) != -1) {
185 switch (ch) {
186 case 'p':
187 picky = 1;
188 break;
189 case 'v':
190 verbose = 1;
191 break;
192 default:
193 badarg = 1;
194 break;
195 }
196 }
197 argc -= optind;
198 argv += optind;
199 if (argc > 0) {
200 warnx("unexpected argument \"%s\"", *argv);
201 badarg = 1;
202 }
203 if (badarg) {
204 fputs("usage: int [-pv]\n", stderr);
205 return 1;
206 }
207
208 /*
209 * Valid use cases of %d.
210 */
211
212 ti("<%d>", S_INT, 0, "<0>");
213 ti("<%d>", S_INT, 1, "<1>");
214 ti("<%d>", S_INT, -1, "<-1>");
215 ti("<%d>", S_INT, 42, "<42>");
216 ti("<%d>", S_INT, INT32_MAX, "<2147483647>");
217 ti("<%d>", S_INT, INT32_MIN, "<-2147483648>");
218 ti("<% d>", S_INT, 42, "< 42>");
219 ti("<% d>", S_INT, -42, "<-42>");
220 ti("<%+d>", S_INT, 42, "<+42>");
221 ti("<%+d>", S_INT, -42, "<-42>");
222 ti("<% +d>", S_INT, 42, "<+42>");
223 ti("<% +d>", S_INT, -42, "<-42>");
224 ti("<%-4d>", S_INT, 42, "<42 >");
225 ti("<% -4d>", S_INT, 42, "< 42 >");
226 ti("<%+-4d>", S_INT, 42, "<+42 >");
227 ti("<%04d>", S_INT, 42, "<0042>");
228 ti("<%-04d>", S_INT, 42, "<42 >");
229 ti("<% 04d>", S_INT, 42, "< 042>");
230 ti("<%+04d>", S_INT, 42, "<+042>");
231 ti("<%4.3d>", S_INT, 42, "< 042>");
232 ti("<% 5.3d>", S_INT, 42, "< 042>");
233 ti("<%+5.3d>", S_INT, 42, "< +042>");
234 ti("<%-4.3d>", S_INT, 42, "<042 >");
235 ti("<%04.3d>", S_INT, 42, "< 042>");
236
237 ti("<%hhd>", S_CHAR, INT8_MIN, "<-128>");
238 ti("<%hhd>", S_CHAR, -1, "<-1>");
239 ti("<%hhd>", S_CHAR, 0, "<0>");
240 ti("<%hhd>", S_CHAR, 1, "<1>");
241 ti("<%hhd>", S_CHAR, INT8_MAX, "<127>");
242 ti("<%+.4hhd>", S_CHAR, 42, "<+0042>");
243 ti("<% 04hhd>", S_CHAR, 42, "< 042>");
244
245 ti("<%hd>", S_SHORT, INT16_MIN, "<-32768>");
246 ti("<%hd>", S_SHORT, -1, "<-1>");
247 ti("<%hd>", S_SHORT, 0, "<0>");
248 ti("<%hd>", S_SHORT, 1, "<1>");
249 ti("<%hd>", S_SHORT, INT16_MAX, "<32767>");
250
251 ti("<%hld>", S_LONG, INT32_MIN, "<-2147483648>");
252 ti("<%hld>", S_LONG, -1, "<-1>");
253 ti("<%hld>", S_LONG, 0, "<0>");
254 ti("<%hld>", S_LONG, 1, "<1>");
255 ti("<%hld>", S_LONG, INT32_MAX, "<2147483647>");
256
257 ti("<%hlld>", S_LL, INT64_MIN, "<-9223372036854775808>");
258 ti("<%hlld>", S_LL, -1, "<-1>");
259 ti("<%hlld>", S_LL, 0, "<0>");
260 ti("<%hlld>", S_LL, 1, "<1>");
261 ti("<%hlld>", S_LL, INT64_MAX, "<9223372036854775807>");
262 ti("<%h-19lld>", S_LL, 123456789123456789LL, "<123456789123456789 >");
263
264 ti("<%hjd>", S_MAX, INT64_MIN, "<-9223372036854775808>");
265 ti("<%hjd>", S_MAX, -1, "<-1>");
266 ti("<%hjd>", S_MAX, 0, "<0>");
267 ti("<%hjd>", S_MAX, 1, "<1>");
268 ti("<%hjd>", S_MAX, INT64_MAX, "<9223372036854775807>");
269
270 ti("<%htd>", S_PTR, INT32_MIN, "<-2147483648>");
271 ti("<%htd>", S_PTR, -1, "<-1>");
272 ti("<%htd>", S_PTR, 0, "<0>");
273 ti("<%htd>", S_PTR, 1, "<1>");
274 ti("<%htd>", S_PTR, INT32_MAX, "<2147483647>");
275
276 ti("<%hzd>", S_SIZE, INT32_MIN, "<-2147483648>");
277 ti("<%hzd>", S_SIZE, -1, "<-1>");
278 ti("<%hzd>", S_SIZE, 0, "<0>");
279 ti("<%hzd>", S_SIZE, 1, "<1>");
280 ti("<%hzd>", S_SIZE, INT32_MAX, "<2147483647>");
281
282 /*
283 * Undefined behaviour of %d.
284 * Do not test by default to avoid noise.
285 * But provide the tests anyway to help track down
286 * unintended changes of behaviour when needed.
287 */
288
289 if (picky) {
290 ti("<%#d>", S_INT, 42, "<42>");
291 ti("<%Ld>", S_INT, 42, "<42>");
292 }
293
294 /*
295 * Valid use cases of %u.
296 */
297
298 tu("<%u>", S_INT, 0, "<0>");
299 tu("<%u>", S_INT, 1, "<1>");
300 tu("<%u>", S_INT, 42, "<42>");
301 tu("<%u>", S_INT, UINT32_MAX, "<4294967295>");
302 tu("<%-4u>", S_INT, 42, "<42 >");
303 tu("<%04u>", S_INT, 42, "<0042>");
304 tu("<%-04u>", S_INT, 42, "<42 >");
305 tu("<%4.3u>", S_INT, 42, "< 042>");
306 tu("<%-4.3u>", S_INT, 42, "<042 >");
307 tu("<%04.3u>", S_INT, 42, "< 042>");
308
309 tu("<%hhu>", S_CHAR, 0, "<0>");
310 tu("<%hhu>", S_CHAR, UINT8_MAX, "<255>");
311 tu("<%hhu>", S_CHAR, -1, "<255>");
312 tu("<%-4hhu>", S_CHAR, 42, "<42 >");
313 tu("<%04hhu>", S_CHAR, 42, "<0042>");
314
315 tu("<%hu>", S_SHORT, 0, "<0>");
316 tu("<%hu>", S_SHORT, UINT16_MAX, "<65535>");
317 tu("<%hlu>", S_LONG, 0, "<0>");
318 tu("<%hlu>", S_LONG, UINT32_MAX, "<4294967295>");
319 tu("<%hllu>", S_LL, 0, "<0>");
320 tu("<%hllu>", S_LL, UINT64_MAX, "<18446744073709551615>");
321 tu("<%h-19llu>", S_LL, 123456789123456789ULL, "<123456789123456789 >");
322 tu("<%hju>", S_MAX, 0, "<0>");
323 tu("<%hju>", S_MAX, UINT64_MAX, "<18446744073709551615>");
324 tu("<%hzu>", S_SIZE, 0, "<0>");
325 tu("<%hzu>", S_SIZE, UINT32_MAX, "<4294967295>");
326
327 tu("<%hho>", S_CHAR, 0, "<0>");
328 tu("<%#hho>", S_CHAR, 0, "<0>");
329 tu("<%hho>", S_CHAR, UINT8_MAX, "<377>");
330 tu("<%#hho>", S_CHAR, UINT8_MAX, "<0377>");
331 tu("<%hho>", S_CHAR, -1, "<377>");
332 tu("<%#hho>", S_CHAR, -1, "<0377>");
333 tu("<%-4hho>", S_CHAR, 42, "<52 >");
334 tu("<%#-4hho>", S_CHAR, 42, "<052 >");
335 tu("<%04hho>", S_CHAR, 42, "<0052>");
336 tu("<%#04hho>", S_CHAR, 42, "<0052>");
337
338 tu("<%hx>", S_SHORT, 0, "<0>");
339 tu("<%#hx>", S_SHORT, 0, "<0>");
340 tu("<%hX>", S_SHORT, 0, "<0>");
341 tu("<%#hX>", S_SHORT, 0, "<0>");
342 tu("<%hx>", S_SHORT, 1, "<1>");
343 tu("<%#hx>", S_SHORT, 1, "<0x1>");
344 tu("<%hX>", S_SHORT, 1, "<1>");
345 tu("<%#hX>", S_SHORT, 1, "<0X1>");
346 tu("<%hx>", S_SHORT, 10, "<a>");
347 tu("<%#hx>", S_SHORT, 10, "<0xa>");
348 tu("<%hX>", S_SHORT, 10, "<A>");
349 tu("<%#hX>", S_SHORT, 10, "<0XA>");
350 tu("<%hx>", S_SHORT, UINT16_MAX, "<ffff>");
351 tu("<%#hx>", S_SHORT, UINT16_MAX, "<0xffff>");
352 tu("<%hX>", S_SHORT, UINT16_MAX, "<FFFF>");
353 tu("<%#hX>", S_SHORT, UINT16_MAX, "<0XFFFF>");
354
355 /*
356 * Undefined behaviour of %u.
357 */
358
359 if (picky) {
360 tu("<%#u>", S_INT, 42, "<42>");
361 tu("<% u>", S_INT, 42, "<42>");
362 tu("<%+u>", S_INT, 42, "<42>");
363 tu("<%Lu>", S_INT, 42, "<42>");
364 }
365
366 /*
367 * Summarize the results.
368 */
369
370 if (badret + badlen + badout)
371 errx(1, "ERRORS: %d fail + %d mismatch (incl. %d bad length)",
372 badret, badout, badlen);
373 else if (verbose)
374 warnx("SUCCESS");
375 return 0;
376}