xref: /freebsd/lib/libc/tests/stdio/printbasic_test.c (revision 1ee0219205d3794b5d0dc6d885fa8895a6ec1dbf)
1*1ee02192SEnji Cooper /*-
2*1ee02192SEnji Cooper  * Copyright (c) 2009 David Schultz <das@FreeBSD.org>
3*1ee02192SEnji Cooper  * All rights reserved.
4*1ee02192SEnji Cooper  *
5*1ee02192SEnji Cooper  * Redistribution and use in source and binary forms, with or without
6*1ee02192SEnji Cooper  * modification, are permitted provided that the following conditions
7*1ee02192SEnji Cooper  * are met:
8*1ee02192SEnji Cooper  * 1. Redistributions of source code must retain the above copyright
9*1ee02192SEnji Cooper  *    notice, this list of conditions and the following disclaimer.
10*1ee02192SEnji Cooper  * 2. Redistributions in binary form must reproduce the above copyright
11*1ee02192SEnji Cooper  *    notice, this list of conditions and the following disclaimer in the
12*1ee02192SEnji Cooper  *    documentation and/or other materials provided with the distribution.
13*1ee02192SEnji Cooper  *
14*1ee02192SEnji Cooper  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15*1ee02192SEnji Cooper  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16*1ee02192SEnji Cooper  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17*1ee02192SEnji Cooper  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18*1ee02192SEnji Cooper  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19*1ee02192SEnji Cooper  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20*1ee02192SEnji Cooper  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21*1ee02192SEnji Cooper  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22*1ee02192SEnji Cooper  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23*1ee02192SEnji Cooper  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24*1ee02192SEnji Cooper  * SUCH DAMAGE.
25*1ee02192SEnji Cooper  */
26*1ee02192SEnji Cooper 
27*1ee02192SEnji Cooper /*
28*1ee02192SEnji Cooper  * Tests for basic and miscellaneous printf() formats.
29*1ee02192SEnji Cooper  */
30*1ee02192SEnji Cooper 
31*1ee02192SEnji Cooper #include <sys/cdefs.h>
32*1ee02192SEnji Cooper __FBSDID("$FreeBSD$");
33*1ee02192SEnji Cooper 
34*1ee02192SEnji Cooper #include <err.h>
35*1ee02192SEnji Cooper #include <limits.h>
36*1ee02192SEnji Cooper #include <locale.h>
37*1ee02192SEnji Cooper #include <stdio.h>
38*1ee02192SEnji Cooper #include <stdarg.h>
39*1ee02192SEnji Cooper #include <stddef.h>
40*1ee02192SEnji Cooper #include <stdint.h>
41*1ee02192SEnji Cooper #include <stdlib.h>
42*1ee02192SEnji Cooper #include <string.h>
43*1ee02192SEnji Cooper #include <wchar.h>
44*1ee02192SEnji Cooper 
45*1ee02192SEnji Cooper #include <atf-c.h>
46*1ee02192SEnji Cooper 
47*1ee02192SEnji Cooper #define	S_UINT64MAX	"18446744073709551615"
48*1ee02192SEnji Cooper #define	S_UINT32MAX	"4294967295"
49*1ee02192SEnji Cooper #define	S_INT64MIN	"-9223372036854775808"
50*1ee02192SEnji Cooper #define	S_INT32MIN	"-2147483648"
51*1ee02192SEnji Cooper 
52*1ee02192SEnji Cooper #define	S_SIZEMAX	(SIZE_MAX == UINT64_MAX ? S_UINT64MAX : S_UINT32MAX)
53*1ee02192SEnji Cooper #define	S_ULONGMAX	(ULONG_MAX == UINT64_MAX ? S_UINT64MAX : S_UINT32MAX)
54*1ee02192SEnji Cooper #define	S_ULLONGMAX	(ULLONG_MAX == UINT64_MAX ? S_UINT64MAX : S_UINT32MAX)
55*1ee02192SEnji Cooper 
56*1ee02192SEnji Cooper static void
57*1ee02192SEnji Cooper smash_stack(void)
58*1ee02192SEnji Cooper {
59*1ee02192SEnji Cooper 	static uint32_t junk = 0xdeadbeef;
60*1ee02192SEnji Cooper 	uint32_t buf[512];
61*1ee02192SEnji Cooper 	int i;
62*1ee02192SEnji Cooper 
63*1ee02192SEnji Cooper 	for (i = 0; i < sizeof(buf) / sizeof(buf[0]); i++)
64*1ee02192SEnji Cooper 		buf[i] = junk;
65*1ee02192SEnji Cooper }
66*1ee02192SEnji Cooper 
67*1ee02192SEnji Cooper #define	testfmt(result, fmt, ...)       \
68*1ee02192SEnji Cooper 	_testfmt((result), #__VA_ARGS__, fmt, __VA_ARGS__)
69*1ee02192SEnji Cooper static void
70*1ee02192SEnji Cooper _testfmt(const char *result, const char *argstr, const char *fmt,...)
71*1ee02192SEnji Cooper {
72*1ee02192SEnji Cooper #define	BUF	100
73*1ee02192SEnji Cooper 	wchar_t ws[BUF], wfmt[BUF], wresult[BUF];
74*1ee02192SEnji Cooper 	char s[BUF];
75*1ee02192SEnji Cooper 	va_list ap, ap2;
76*1ee02192SEnji Cooper 
77*1ee02192SEnji Cooper 	va_start(ap, fmt);
78*1ee02192SEnji Cooper 	va_copy(ap2, ap);
79*1ee02192SEnji Cooper 	smash_stack();
80*1ee02192SEnji Cooper 	vsnprintf(s, sizeof(s), fmt, ap);
81*1ee02192SEnji Cooper 	if (strcmp(result, s) != 0) {
82*1ee02192SEnji Cooper 		atf_tc_fail(
83*1ee02192SEnji Cooper 		    "printf(\"%s\", %s) ==> [%s], expected [%s]\n",
84*1ee02192SEnji Cooper 		    fmt, argstr, s, result);
85*1ee02192SEnji Cooper 	}
86*1ee02192SEnji Cooper 
87*1ee02192SEnji Cooper 	smash_stack();
88*1ee02192SEnji Cooper 	mbstowcs(ws, s, BUF - 1);
89*1ee02192SEnji Cooper 	mbstowcs(wfmt, fmt, BUF - 1);
90*1ee02192SEnji Cooper 	mbstowcs(wresult, result, BUF - 1);
91*1ee02192SEnji Cooper 	vswprintf(ws, sizeof(ws) / sizeof(ws[0]), wfmt, ap2);
92*1ee02192SEnji Cooper 	if (wcscmp(wresult, ws) != 0) {
93*1ee02192SEnji Cooper 		atf_tc_fail(
94*1ee02192SEnji Cooper 		    "wprintf(\"%ls\", %s) ==> [%ls], expected [%ls]\n",
95*1ee02192SEnji Cooper 		    wfmt, argstr, ws, wresult);
96*1ee02192SEnji Cooper 	}
97*1ee02192SEnji Cooper }
98*1ee02192SEnji Cooper 
99*1ee02192SEnji Cooper ATF_TC_WITHOUT_HEAD(int_within_limits);
100*1ee02192SEnji Cooper ATF_TC_BODY(int_within_limits, tc)
101*1ee02192SEnji Cooper {
102*1ee02192SEnji Cooper 
103*1ee02192SEnji Cooper 	ATF_REQUIRE(setlocale(LC_NUMERIC, "C"));
104*1ee02192SEnji Cooper 
105*1ee02192SEnji Cooper 	/* The test requires these to be true. */
106*1ee02192SEnji Cooper 	ATF_REQUIRE(UINTMAX_MAX == UINT64_MAX);
107*1ee02192SEnji Cooper 	ATF_REQUIRE(UINT_MAX == UINT32_MAX);
108*1ee02192SEnji Cooper 	ATF_REQUIRE(USHRT_MAX == 0xffff);
109*1ee02192SEnji Cooper 	ATF_REQUIRE(UCHAR_MAX == 0xff);
110*1ee02192SEnji Cooper 
111*1ee02192SEnji Cooper 	/* Make sure we handle signed vs. unsigned args correctly. */
112*1ee02192SEnji Cooper 	testfmt("-1", "%jd", (intmax_t)-1);
113*1ee02192SEnji Cooper 	testfmt(S_UINT64MAX, "%ju", UINT64_MAX);
114*1ee02192SEnji Cooper 
115*1ee02192SEnji Cooper 	testfmt("-1", "%td", (ptrdiff_t)-1);
116*1ee02192SEnji Cooper 	testfmt(S_SIZEMAX, "%tu", (size_t)-1);
117*1ee02192SEnji Cooper 
118*1ee02192SEnji Cooper 	testfmt("-1", "%zd", (ssize_t)-1);
119*1ee02192SEnji Cooper 	testfmt(S_SIZEMAX, "%zu", (ssize_t)-1);
120*1ee02192SEnji Cooper 
121*1ee02192SEnji Cooper 	testfmt("-1", "%ld", (long)-1);
122*1ee02192SEnji Cooper 	testfmt(S_ULONGMAX, "%lu", ULONG_MAX);
123*1ee02192SEnji Cooper 
124*1ee02192SEnji Cooper 	testfmt("-1", "%lld", (long long)-1);
125*1ee02192SEnji Cooper 	testfmt(S_ULONGMAX, "%lu", ULLONG_MAX);
126*1ee02192SEnji Cooper 
127*1ee02192SEnji Cooper 	testfmt("-1", "%d", -1);
128*1ee02192SEnji Cooper 	testfmt(S_UINT32MAX, "%lu", UINT32_MAX);
129*1ee02192SEnji Cooper 
130*1ee02192SEnji Cooper 	testfmt("-1", "%hd", -1);
131*1ee02192SEnji Cooper 	testfmt("65535", "%hu", USHRT_MAX);
132*1ee02192SEnji Cooper 
133*1ee02192SEnji Cooper 	testfmt("-1", "%hhd", -1);
134*1ee02192SEnji Cooper 	testfmt("255", "%hhu", UCHAR_MAX);
135*1ee02192SEnji Cooper }
136*1ee02192SEnji Cooper 
137*1ee02192SEnji Cooper ATF_TC_WITHOUT_HEAD(int_limits);
138*1ee02192SEnji Cooper ATF_TC_BODY(int_limits, tc)
139*1ee02192SEnji Cooper {
140*1ee02192SEnji Cooper 
141*1ee02192SEnji Cooper 	ATF_REQUIRE(setlocale(LC_NUMERIC, "C"));
142*1ee02192SEnji Cooper 
143*1ee02192SEnji Cooper 	/*
144*1ee02192SEnji Cooper 	 * Check that printing the largest negative number does not cause
145*1ee02192SEnji Cooper 	 * overflow when it is negated.
146*1ee02192SEnji Cooper 	 */
147*1ee02192SEnji Cooper 	testfmt(S_INT32MIN, "%d", INT_MIN);
148*1ee02192SEnji Cooper 	testfmt(S_INT64MIN, "%jd", INTMAX_MIN);
149*1ee02192SEnji Cooper }
150*1ee02192SEnji Cooper 
151*1ee02192SEnji Cooper ATF_TP_ADD_TCS(tp)
152*1ee02192SEnji Cooper {
153*1ee02192SEnji Cooper 
154*1ee02192SEnji Cooper 	ATF_TP_ADD_TC(tp, int_within_limits);
155*1ee02192SEnji Cooper 	ATF_TP_ADD_TC(tp, int_limits);
156*1ee02192SEnji Cooper 
157*1ee02192SEnji Cooper 	return (atf_no_error());
158*1ee02192SEnji Cooper }
159