1 /*-
2  * Copyright (c) 2023 Dag-Erling Smørgrav
3  *
4  * SPDX-License-Identifier: BSD-2-Clause
5  */
6 
7 #include <assert.h>
8 #include <limits.h>
9 #include <locale.h>
10 #include <stdint.h>
11 #include <stdio.h>
12 #include <wchar.h>
13 
14 #include <atf-c.h>
15 
16 #ifndef nitems
17 #define nitems(a) (sizeof(a) / sizeof(a[0]))
18 #endif
19 
20 #define SWPRINTF_TEST(output, format, ...)				\
21 	do {								\
22 		wchar_t buf[256];					\
23 		assert(wcslen(L##output) < nitems(buf));		\
24 		int ret = swprintf(buf, nitems(buf), L##format,		\
25 		    __VA_ARGS__);					\
26 		ATF_CHECK_EQ(wcslen(L##output), ret);			\
27 		if (ret > 0) {						\
28 			ATF_CHECK_EQ(0, wcscmp(L##output, buf));	\
29 		}							\
30 	} while (0)
31 
32 ATF_TC_WITHOUT_HEAD(swprintf_b);
33 ATF_TC_BODY(swprintf_b, tc)
34 {
35 	SWPRINTF_TEST("0", "%b", 0);
36 	SWPRINTF_TEST("           0", "%12b", 0);
37 	SWPRINTF_TEST("000000000000", "%012b", 0);
38 	SWPRINTF_TEST("1", "%b", 1);
39 	SWPRINTF_TEST("           1", "%12b", 1);
40 	SWPRINTF_TEST("000000000001", "%012b", 1);
41 	SWPRINTF_TEST("1111111111111111111111111111111", "%b", INT_MAX);
42 	SWPRINTF_TEST("0", "%#b", 0);
43 	SWPRINTF_TEST("           0", "%#12b", 0);
44 	SWPRINTF_TEST("000000000000", "%#012b", 0);
45 	SWPRINTF_TEST("0b1", "%#b", 1);
46 	SWPRINTF_TEST("         0b1", "%#12b", 1);
47 	SWPRINTF_TEST("0b0000000001", "%#012b", 1);
48 	SWPRINTF_TEST("0b1111111111111111111111111111111", "%#b", INT_MAX);
49 }
50 
51 ATF_TC_WITHOUT_HEAD(swprintf_B);
52 ATF_TC_BODY(swprintf_B, tc)
53 {
54 	SWPRINTF_TEST("0", "%B", 0);
55 	SWPRINTF_TEST("           0", "%12B", 0);
56 	SWPRINTF_TEST("000000000000", "%012B", 0);
57 	SWPRINTF_TEST("1", "%B", 1);
58 	SWPRINTF_TEST("           1", "%12B", 1);
59 	SWPRINTF_TEST("000000000001", "%012B", 1);
60 	SWPRINTF_TEST("1111111111111111111111111111111", "%B", INT_MAX);
61 	SWPRINTF_TEST("0", "%#B", 0);
62 	SWPRINTF_TEST("           0", "%#12B", 0);
63 	SWPRINTF_TEST("000000000000", "%#012B", 0);
64 	SWPRINTF_TEST("0B1", "%#B", 1);
65 	SWPRINTF_TEST("         0B1", "%#12B", 1);
66 	SWPRINTF_TEST("0B0000000001", "%#012B", 1);
67 	SWPRINTF_TEST("0B1111111111111111111111111111111", "%#B", INT_MAX);
68 }
69 
70 ATF_TC_WITHOUT_HEAD(swprintf_d);
71 ATF_TC_BODY(swprintf_d, tc)
72 {
73 	SWPRINTF_TEST("0", "%d", 0);
74 	SWPRINTF_TEST("           0", "%12d", 0);
75 	SWPRINTF_TEST("000000000000", "%012d", 0);
76 	SWPRINTF_TEST("1", "%d", 1);
77 	SWPRINTF_TEST("           1", "%12d", 1);
78 	SWPRINTF_TEST("000000000001", "%012d", 1);
79 	SWPRINTF_TEST("2147483647", "%d", INT_MAX);
80 	SWPRINTF_TEST("  2147483647", "%12d", INT_MAX);
81 	SWPRINTF_TEST("002147483647", "%012d", INT_MAX);
82 	SWPRINTF_TEST("2,147,483,647", "%'d", INT_MAX);
83 }
84 
85 ATF_TC_WITHOUT_HEAD(swprintf_x);
86 ATF_TC_BODY(swprintf_x, tc)
87 {
88 	SWPRINTF_TEST("0", "%x", 0);
89 	SWPRINTF_TEST("           0", "%12x", 0);
90 	SWPRINTF_TEST("000000000000", "%012x", 0);
91 	SWPRINTF_TEST("1", "%x", 1);
92 	SWPRINTF_TEST("           1", "%12x", 1);
93 	SWPRINTF_TEST("000000000001", "%012x", 1);
94 	SWPRINTF_TEST("7fffffff", "%x", INT_MAX);
95 	SWPRINTF_TEST("    7fffffff", "%12x", INT_MAX);
96 	SWPRINTF_TEST("00007fffffff", "%012x", INT_MAX);
97 	SWPRINTF_TEST("0", "%#x", 0);
98 	SWPRINTF_TEST("           0", "%#12x", 0);
99 	SWPRINTF_TEST("000000000000", "%#012x", 0);
100 	SWPRINTF_TEST("0x1", "%#x", 1);
101 	SWPRINTF_TEST("         0x1", "%#12x", 1);
102 	SWPRINTF_TEST("0x0000000001", "%#012x", 1);
103 	SWPRINTF_TEST("0x7fffffff", "%#x", INT_MAX);
104 	SWPRINTF_TEST("  0x7fffffff", "%#12x", INT_MAX);
105 	SWPRINTF_TEST("0x007fffffff", "%#012x", INT_MAX);
106 }
107 
108 ATF_TC_WITHOUT_HEAD(swprintf_X);
109 ATF_TC_BODY(swprintf_X, tc)
110 {
111 	SWPRINTF_TEST("0", "%X", 0);
112 	SWPRINTF_TEST("           0", "%12X", 0);
113 	SWPRINTF_TEST("000000000000", "%012X", 0);
114 	SWPRINTF_TEST("1", "%X", 1);
115 	SWPRINTF_TEST("           1", "%12X", 1);
116 	SWPRINTF_TEST("000000000001", "%012X", 1);
117 	SWPRINTF_TEST("7FFFFFFF", "%X", INT_MAX);
118 	SWPRINTF_TEST("    7FFFFFFF", "%12X", INT_MAX);
119 	SWPRINTF_TEST("00007FFFFFFF", "%012X", INT_MAX);
120 	SWPRINTF_TEST("0", "%#X", 0);
121 	SWPRINTF_TEST("           0", "%#12X", 0);
122 	SWPRINTF_TEST("000000000000", "%#012X", 0);
123 	SWPRINTF_TEST("0X1", "%#X", 1);
124 	SWPRINTF_TEST("         0X1", "%#12X", 1);
125 	SWPRINTF_TEST("0X0000000001", "%#012X", 1);
126 	SWPRINTF_TEST("0X7FFFFFFF", "%#X", INT_MAX);
127 	SWPRINTF_TEST("  0X7FFFFFFF", "%#12X", INT_MAX);
128 	SWPRINTF_TEST("0X007FFFFFFF", "%#012X", INT_MAX);
129 }
130 
131 ATF_TP_ADD_TCS(tp)
132 {
133 	setlocale(LC_NUMERIC, "en_US.UTF-8");
134 	ATF_TP_ADD_TC(tp, swprintf_b);
135 	ATF_TP_ADD_TC(tp, swprintf_B);
136 	ATF_TP_ADD_TC(tp, swprintf_d);
137 	ATF_TP_ADD_TC(tp, swprintf_x);
138 	ATF_TP_ADD_TC(tp, swprintf_X);
139 	return (atf_no_error());
140 }
141