1*f68d7bfcSFaraz Vahedi /*
2*f68d7bfcSFaraz Vahedi * Copyright (c) 2026 Faraz Vahedi <kfv@kfv.io>
3*f68d7bfcSFaraz Vahedi *
4*f68d7bfcSFaraz Vahedi * SPDX-License-Identifier: BSD-2-Clause
5*f68d7bfcSFaraz Vahedi */
6*f68d7bfcSFaraz Vahedi
7*f68d7bfcSFaraz Vahedi /*
8*f68d7bfcSFaraz Vahedi * Tests for strfromd(3), strfromf(3), and strfroml(3).
9*f68d7bfcSFaraz Vahedi *
10*f68d7bfcSFaraz Vahedi * C23 §7.24.1.3 states that these functions are equivalent to snprintf(3),
11*f68d7bfcSFaraz Vahedi * albeit with some subtle exceptions, and therefore snprintf(3) is used as
12*f68d7bfcSFaraz Vahedi * the correctness oracle. Hardcoded string checks guard against both
13*f68d7bfcSFaraz Vahedi * producing the same wrong answer.
14*f68d7bfcSFaraz Vahedi */
15*f68d7bfcSFaraz Vahedi
16*f68d7bfcSFaraz Vahedi #include <errno.h>
17*f68d7bfcSFaraz Vahedi #include <float.h>
18*f68d7bfcSFaraz Vahedi #include <locale.h>
19*f68d7bfcSFaraz Vahedi #include <math.h>
20*f68d7bfcSFaraz Vahedi #include <stdio.h>
21*f68d7bfcSFaraz Vahedi #include <stdlib.h>
22*f68d7bfcSFaraz Vahedi #include <string.h>
23*f68d7bfcSFaraz Vahedi
24*f68d7bfcSFaraz Vahedi #include <atf-c.h>
25*f68d7bfcSFaraz Vahedi
26*f68d7bfcSFaraz Vahedi /*
27*f68d7bfcSFaraz Vahedi * Buffer large enough for any finite value in %f form, including LDBL_MAX on
28*f68d7bfcSFaraz Vahedi * platforms with 80-bit or 128-bit long double. Sizing for the full output
29*f68d7bfcSFaraz Vahedi * keeps the snprintf(3) oracle a full-length comparison rather than letting
30*f68d7bfcSFaraz Vahedi * both sides truncate alike.
31*f68d7bfcSFaraz Vahedi */
32*f68d7bfcSFaraz Vahedi #define FBUF 8192
33*f68d7bfcSFaraz Vahedi
34*f68d7bfcSFaraz Vahedi static void
check_d(const char * fmt,double val)35*f68d7bfcSFaraz Vahedi check_d(const char *fmt, double val)
36*f68d7bfcSFaraz Vahedi {
37*f68d7bfcSFaraz Vahedi char got[FBUF], ref[FBUF];
38*f68d7bfcSFaraz Vahedi int rlen, glen;
39*f68d7bfcSFaraz Vahedi
40*f68d7bfcSFaraz Vahedi rlen = snprintf(ref, sizeof(ref), fmt, val);
41*f68d7bfcSFaraz Vahedi glen = strfromd(got, sizeof(got), fmt, val);
42*f68d7bfcSFaraz Vahedi ATF_CHECK_MSG(glen == rlen,
43*f68d7bfcSFaraz Vahedi "strfromd(\"%s\", %g): return %d, want %d", fmt, val, glen, rlen);
44*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ_MSG(ref, got, "strfromd(\"%s\", %g)", fmt, val);
45*f68d7bfcSFaraz Vahedi }
46*f68d7bfcSFaraz Vahedi
47*f68d7bfcSFaraz Vahedi static void
check_f(const char * fmt,float val)48*f68d7bfcSFaraz Vahedi check_f(const char *fmt, float val)
49*f68d7bfcSFaraz Vahedi {
50*f68d7bfcSFaraz Vahedi char got[FBUF], ref[FBUF];
51*f68d7bfcSFaraz Vahedi int rlen, glen;
52*f68d7bfcSFaraz Vahedi
53*f68d7bfcSFaraz Vahedi rlen = snprintf(ref, sizeof(ref), fmt, (double)val);
54*f68d7bfcSFaraz Vahedi glen = strfromf(got, sizeof(got), fmt, val);
55*f68d7bfcSFaraz Vahedi ATF_CHECK_MSG(glen == rlen,
56*f68d7bfcSFaraz Vahedi "strfromf(\"%s\", %g): return %d, want %d",
57*f68d7bfcSFaraz Vahedi fmt, (double)val, glen, rlen);
58*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ_MSG(ref, got, "strfromf(\"%s\", %g)", fmt, (double)val);
59*f68d7bfcSFaraz Vahedi }
60*f68d7bfcSFaraz Vahedi
61*f68d7bfcSFaraz Vahedi static void
check_l(const char * fmt,long double val)62*f68d7bfcSFaraz Vahedi check_l(const char *fmt, long double val)
63*f68d7bfcSFaraz Vahedi {
64*f68d7bfcSFaraz Vahedi char got[FBUF], ref[FBUF], lfmt[32];
65*f68d7bfcSFaraz Vahedi int rlen, glen;
66*f68d7bfcSFaraz Vahedi
67*f68d7bfcSFaraz Vahedi /*
68*f68d7bfcSFaraz Vahedi * snprintf requires the 'L' length modifier for long double.
69*f68d7bfcSFaraz Vahedi */
70*f68d7bfcSFaraz Vahedi snprintf(lfmt, sizeof(lfmt), "%.*sL%c",
71*f68d7bfcSFaraz Vahedi (int)(strlen(fmt) - 1), fmt, fmt[strlen(fmt) - 1]);
72*f68d7bfcSFaraz Vahedi rlen = snprintf(ref, sizeof(ref), lfmt, val);
73*f68d7bfcSFaraz Vahedi glen = strfroml(got, sizeof(got), fmt, val);
74*f68d7bfcSFaraz Vahedi ATF_CHECK_MSG(glen == rlen,
75*f68d7bfcSFaraz Vahedi "strfroml(\"%s\", %Lg): return %d, want %d", fmt, val, glen, rlen);
76*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ_MSG(ref, got, "strfroml(\"%s\", %Lg)", fmt, val);
77*f68d7bfcSFaraz Vahedi }
78*f68d7bfcSFaraz Vahedi
79*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfromd_f);
ATF_TC_BODY(strfromd_f,tc)80*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfromd_f, tc)
81*f68d7bfcSFaraz Vahedi {
82*f68d7bfcSFaraz Vahedi char buf[FBUF];
83*f68d7bfcSFaraz Vahedi
84*f68d7bfcSFaraz Vahedi check_d("%f", 0.0);
85*f68d7bfcSFaraz Vahedi check_d("%f", 1.0);
86*f68d7bfcSFaraz Vahedi check_d("%f", -1.0);
87*f68d7bfcSFaraz Vahedi check_d("%f", 3.14159265358979);
88*f68d7bfcSFaraz Vahedi check_d("%f", 1.0 / 3.0);
89*f68d7bfcSFaraz Vahedi check_d("%f", 1e10);
90*f68d7bfcSFaraz Vahedi check_d("%f", 1e-10);
91*f68d7bfcSFaraz Vahedi check_d("%f", DBL_MAX);
92*f68d7bfcSFaraz Vahedi check_d("%f", DBL_MIN);
93*f68d7bfcSFaraz Vahedi check_d("%.0f", 3.14);
94*f68d7bfcSFaraz Vahedi check_d("%.0f", 3.5);
95*f68d7bfcSFaraz Vahedi check_d("%.0f", 4.5);
96*f68d7bfcSFaraz Vahedi check_d("%.2f", 3.14159);
97*f68d7bfcSFaraz Vahedi check_d("%.10f", 1.0 / 7.0);
98*f68d7bfcSFaraz Vahedi check_d("%.20f", 1.0);
99*f68d7bfcSFaraz Vahedi
100*f68d7bfcSFaraz Vahedi strfromd(buf, sizeof(buf), "%.6f", 0.0);
101*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("0.000000", buf);
102*f68d7bfcSFaraz Vahedi strfromd(buf, sizeof(buf), "%.6f", -1.5);
103*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("-1.500000", buf);
104*f68d7bfcSFaraz Vahedi }
105*f68d7bfcSFaraz Vahedi
106*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfromd_e);
ATF_TC_BODY(strfromd_e,tc)107*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfromd_e, tc)
108*f68d7bfcSFaraz Vahedi {
109*f68d7bfcSFaraz Vahedi char buf[FBUF];
110*f68d7bfcSFaraz Vahedi
111*f68d7bfcSFaraz Vahedi check_d("%e", 0.0);
112*f68d7bfcSFaraz Vahedi check_d("%e", 1.0);
113*f68d7bfcSFaraz Vahedi check_d("%e", -1.0);
114*f68d7bfcSFaraz Vahedi check_d("%e", 3.14159265358979);
115*f68d7bfcSFaraz Vahedi check_d("%e", 1e100);
116*f68d7bfcSFaraz Vahedi check_d("%e", 1e-100);
117*f68d7bfcSFaraz Vahedi check_d("%E", 2.718281828);
118*f68d7bfcSFaraz Vahedi check_d("%.0e", 3.14);
119*f68d7bfcSFaraz Vahedi check_d("%.2e", 12345.6789);
120*f68d7bfcSFaraz Vahedi check_d("%.15e", 1.0 / 3.0);
121*f68d7bfcSFaraz Vahedi
122*f68d7bfcSFaraz Vahedi strfromd(buf, sizeof(buf), "%e", 1.0);
123*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("1.000000e+00", buf);
124*f68d7bfcSFaraz Vahedi strfromd(buf, sizeof(buf), "%E", 1.0);
125*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("1.000000E+00", buf);
126*f68d7bfcSFaraz Vahedi }
127*f68d7bfcSFaraz Vahedi
128*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfromd_g);
ATF_TC_BODY(strfromd_g,tc)129*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfromd_g, tc)
130*f68d7bfcSFaraz Vahedi {
131*f68d7bfcSFaraz Vahedi char buf[FBUF];
132*f68d7bfcSFaraz Vahedi
133*f68d7bfcSFaraz Vahedi check_d("%g", 0.0);
134*f68d7bfcSFaraz Vahedi check_d("%g", 1.0);
135*f68d7bfcSFaraz Vahedi check_d("%g", 100000.0);
136*f68d7bfcSFaraz Vahedi check_d("%g", 1000000.0); /* exponent >= prec: hence %e */
137*f68d7bfcSFaraz Vahedi check_d("%g", 0.0001); /* exponent == -4: hence %f */
138*f68d7bfcSFaraz Vahedi check_d("%g", 0.00001); /* exponent < -4: hence %e */
139*f68d7bfcSFaraz Vahedi check_d("%g", 3.14159265358979);
140*f68d7bfcSFaraz Vahedi check_d("%G", 1.23e10);
141*f68d7bfcSFaraz Vahedi check_d("%.2g", 3.14159);
142*f68d7bfcSFaraz Vahedi check_d("%.0g", 3.14159);
143*f68d7bfcSFaraz Vahedi check_d("%.10g", 1.0 / 7.0);
144*f68d7bfcSFaraz Vahedi check_d("%g", DBL_MIN);
145*f68d7bfcSFaraz Vahedi check_d("%g", DBL_MAX);
146*f68d7bfcSFaraz Vahedi
147*f68d7bfcSFaraz Vahedi strfromd(buf, sizeof(buf), "%g", 1.0);
148*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("1", buf);
149*f68d7bfcSFaraz Vahedi strfromd(buf, sizeof(buf), "%g", 100.0);
150*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("100", buf);
151*f68d7bfcSFaraz Vahedi }
152*f68d7bfcSFaraz Vahedi
153*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfromd_a);
ATF_TC_BODY(strfromd_a,tc)154*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfromd_a, tc)
155*f68d7bfcSFaraz Vahedi {
156*f68d7bfcSFaraz Vahedi char buf[FBUF];
157*f68d7bfcSFaraz Vahedi
158*f68d7bfcSFaraz Vahedi check_d("%a", 0.0);
159*f68d7bfcSFaraz Vahedi check_d("%a", 1.0);
160*f68d7bfcSFaraz Vahedi check_d("%a", -1.0);
161*f68d7bfcSFaraz Vahedi check_d("%a", 0.5);
162*f68d7bfcSFaraz Vahedi check_d("%a", 1.5);
163*f68d7bfcSFaraz Vahedi check_d("%a", DBL_MIN);
164*f68d7bfcSFaraz Vahedi check_d("%a", DBL_MAX);
165*f68d7bfcSFaraz Vahedi check_d("%A", 1.0);
166*f68d7bfcSFaraz Vahedi check_d("%.4a", 1.0 / 3.0);
167*f68d7bfcSFaraz Vahedi check_d("%.0a", 1.5);
168*f68d7bfcSFaraz Vahedi
169*f68d7bfcSFaraz Vahedi strfromd(buf, sizeof(buf), "%a", 1.0);
170*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("0x1p+0", buf);
171*f68d7bfcSFaraz Vahedi strfromd(buf, sizeof(buf), "%a", 0.5);
172*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("0x1p-1", buf);
173*f68d7bfcSFaraz Vahedi strfromd(buf, sizeof(buf), "%A", 1.0);
174*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("0X1P+0", buf);
175*f68d7bfcSFaraz Vahedi }
176*f68d7bfcSFaraz Vahedi
177*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfromd_special);
ATF_TC_BODY(strfromd_special,tc)178*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfromd_special, tc)
179*f68d7bfcSFaraz Vahedi {
180*f68d7bfcSFaraz Vahedi char buf[FBUF];
181*f68d7bfcSFaraz Vahedi
182*f68d7bfcSFaraz Vahedi check_d("%f", INFINITY);
183*f68d7bfcSFaraz Vahedi check_d("%f", -INFINITY);
184*f68d7bfcSFaraz Vahedi check_d("%f", NAN);
185*f68d7bfcSFaraz Vahedi check_d("%e", INFINITY);
186*f68d7bfcSFaraz Vahedi check_d("%e", -INFINITY);
187*f68d7bfcSFaraz Vahedi check_d("%e", NAN);
188*f68d7bfcSFaraz Vahedi check_d("%g", INFINITY);
189*f68d7bfcSFaraz Vahedi check_d("%g", -INFINITY);
190*f68d7bfcSFaraz Vahedi check_d("%g", NAN);
191*f68d7bfcSFaraz Vahedi check_d("%a", INFINITY);
192*f68d7bfcSFaraz Vahedi check_d("%a", -INFINITY);
193*f68d7bfcSFaraz Vahedi check_d("%a", NAN);
194*f68d7bfcSFaraz Vahedi check_d("%F", INFINITY);
195*f68d7bfcSFaraz Vahedi check_d("%E", INFINITY);
196*f68d7bfcSFaraz Vahedi check_d("%G", INFINITY);
197*f68d7bfcSFaraz Vahedi check_d("%A", INFINITY);
198*f68d7bfcSFaraz Vahedi check_d("%f", -0.0);
199*f68d7bfcSFaraz Vahedi check_d("%g", -0.0);
200*f68d7bfcSFaraz Vahedi check_d("%e", -0.0);
201*f68d7bfcSFaraz Vahedi check_d("%a", -0.0);
202*f68d7bfcSFaraz Vahedi
203*f68d7bfcSFaraz Vahedi strfromd(buf, sizeof(buf), "%f", INFINITY);
204*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("inf", buf);
205*f68d7bfcSFaraz Vahedi strfromd(buf, sizeof(buf), "%F", INFINITY);
206*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("INF", buf);
207*f68d7bfcSFaraz Vahedi strfromd(buf, sizeof(buf), "%f", -INFINITY);
208*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("-inf", buf);
209*f68d7bfcSFaraz Vahedi strfromd(buf, sizeof(buf), "%f", NAN);
210*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("nan", buf);
211*f68d7bfcSFaraz Vahedi strfromd(buf, sizeof(buf), "%F", NAN);
212*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("NAN", buf);
213*f68d7bfcSFaraz Vahedi }
214*f68d7bfcSFaraz Vahedi
215*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfromd_truncation);
ATF_TC_BODY(strfromd_truncation,tc)216*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfromd_truncation, tc)
217*f68d7bfcSFaraz Vahedi {
218*f68d7bfcSFaraz Vahedi char buf[FBUF];
219*f68d7bfcSFaraz Vahedi int ret;
220*f68d7bfcSFaraz Vahedi
221*f68d7bfcSFaraz Vahedi /*
222*f68d7bfcSFaraz Vahedi * When n == 0 the buffer must not be touched and the return value
223*f68d7bfcSFaraz Vahedi * must still reflect the full output length.
224*f68d7bfcSFaraz Vahedi */
225*f68d7bfcSFaraz Vahedi buf[0] = 'X';
226*f68d7bfcSFaraz Vahedi ret = strfromd(buf, 0, "%f", 1.0);
227*f68d7bfcSFaraz Vahedi ATF_CHECK(ret > 0);
228*f68d7bfcSFaraz Vahedi ATF_CHECK_MSG(buf[0] == 'X', "buffer modified with n==0");
229*f68d7bfcSFaraz Vahedi
230*f68d7bfcSFaraz Vahedi /*
231*f68d7bfcSFaraz Vahedi * With a short buffer, a null terminated prefix is written and the
232*f68d7bfcSFaraz Vahedi * return value is the length that would have been needed.
233*f68d7bfcSFaraz Vahedi */
234*f68d7bfcSFaraz Vahedi ret = strfromd(buf, 5, "%.6f", 1.0);
235*f68d7bfcSFaraz Vahedi ATF_CHECK_MSG(ret == 8, "return %d, want 8", ret);
236*f68d7bfcSFaraz Vahedi ATF_CHECK_MSG(buf[4] == '\0', "not null terminated at buf[4]");
237*f68d7bfcSFaraz Vahedi ATF_CHECK_MSG(strncmp(buf, "1.00", 4) == 0,
238*f68d7bfcSFaraz Vahedi "prefix mismatch: got \"%.*s\"", 4, buf);
239*f68d7bfcSFaraz Vahedi }
240*f68d7bfcSFaraz Vahedi
241*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfromf_f);
ATF_TC_BODY(strfromf_f,tc)242*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfromf_f, tc)
243*f68d7bfcSFaraz Vahedi {
244*f68d7bfcSFaraz Vahedi check_f("%f", 0.0f);
245*f68d7bfcSFaraz Vahedi check_f("%f", 1.0f);
246*f68d7bfcSFaraz Vahedi check_f("%f", -1.0f);
247*f68d7bfcSFaraz Vahedi check_f("%f", 3.14159f);
248*f68d7bfcSFaraz Vahedi check_f("%.0f", 3.5f);
249*f68d7bfcSFaraz Vahedi check_f("%.2f", 3.14159f);
250*f68d7bfcSFaraz Vahedi check_f("%.9f", 1.0f / 3.0f);
251*f68d7bfcSFaraz Vahedi check_f("%f", FLT_MAX);
252*f68d7bfcSFaraz Vahedi check_f("%f", FLT_MIN);
253*f68d7bfcSFaraz Vahedi }
254*f68d7bfcSFaraz Vahedi
255*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfromf_e);
ATF_TC_BODY(strfromf_e,tc)256*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfromf_e, tc)
257*f68d7bfcSFaraz Vahedi {
258*f68d7bfcSFaraz Vahedi char buf[FBUF];
259*f68d7bfcSFaraz Vahedi
260*f68d7bfcSFaraz Vahedi check_f("%e", 0.0f);
261*f68d7bfcSFaraz Vahedi check_f("%e", 1.0f);
262*f68d7bfcSFaraz Vahedi check_f("%e", -1.0f);
263*f68d7bfcSFaraz Vahedi check_f("%e", 3.14159f);
264*f68d7bfcSFaraz Vahedi check_f("%E", 2.71828f);
265*f68d7bfcSFaraz Vahedi check_f("%.2e", 12345.6f);
266*f68d7bfcSFaraz Vahedi check_f("%.0e", 3.14f);
267*f68d7bfcSFaraz Vahedi
268*f68d7bfcSFaraz Vahedi strfromf(buf, sizeof(buf), "%e", 1.0f);
269*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("1.000000e+00", buf);
270*f68d7bfcSFaraz Vahedi }
271*f68d7bfcSFaraz Vahedi
272*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfromf_g);
ATF_TC_BODY(strfromf_g,tc)273*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfromf_g, tc)
274*f68d7bfcSFaraz Vahedi {
275*f68d7bfcSFaraz Vahedi char buf[FBUF];
276*f68d7bfcSFaraz Vahedi
277*f68d7bfcSFaraz Vahedi check_f("%g", 0.0f);
278*f68d7bfcSFaraz Vahedi check_f("%g", 1.0f);
279*f68d7bfcSFaraz Vahedi check_f("%g", 100000.0f);
280*f68d7bfcSFaraz Vahedi check_f("%g", 1000000.0f);
281*f68d7bfcSFaraz Vahedi check_f("%g", 0.0001f);
282*f68d7bfcSFaraz Vahedi check_f("%g", 0.00001f);
283*f68d7bfcSFaraz Vahedi check_f("%G", 1.23e10f);
284*f68d7bfcSFaraz Vahedi check_f("%.2g", 3.14159f);
285*f68d7bfcSFaraz Vahedi
286*f68d7bfcSFaraz Vahedi strfromf(buf, sizeof(buf), "%g", 1.0f);
287*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("1", buf);
288*f68d7bfcSFaraz Vahedi }
289*f68d7bfcSFaraz Vahedi
290*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfromf_a);
ATF_TC_BODY(strfromf_a,tc)291*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfromf_a, tc)
292*f68d7bfcSFaraz Vahedi {
293*f68d7bfcSFaraz Vahedi char buf[FBUF];
294*f68d7bfcSFaraz Vahedi
295*f68d7bfcSFaraz Vahedi check_f("%a", 0.0f);
296*f68d7bfcSFaraz Vahedi check_f("%a", 1.0f);
297*f68d7bfcSFaraz Vahedi check_f("%a", 0.5f);
298*f68d7bfcSFaraz Vahedi check_f("%a", -1.0f);
299*f68d7bfcSFaraz Vahedi check_f("%A", 1.0f);
300*f68d7bfcSFaraz Vahedi check_f("%.2a", 1.0f / 3.0f);
301*f68d7bfcSFaraz Vahedi
302*f68d7bfcSFaraz Vahedi strfromf(buf, sizeof(buf), "%a", 1.0f);
303*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("0x1p+0", buf);
304*f68d7bfcSFaraz Vahedi }
305*f68d7bfcSFaraz Vahedi
306*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfromf_special);
ATF_TC_BODY(strfromf_special,tc)307*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfromf_special, tc)
308*f68d7bfcSFaraz Vahedi {
309*f68d7bfcSFaraz Vahedi check_f("%f", INFINITY);
310*f68d7bfcSFaraz Vahedi check_f("%f", -INFINITY);
311*f68d7bfcSFaraz Vahedi check_f("%f", NAN);
312*f68d7bfcSFaraz Vahedi check_f("%e", INFINITY);
313*f68d7bfcSFaraz Vahedi check_f("%g", INFINITY);
314*f68d7bfcSFaraz Vahedi check_f("%a", INFINITY);
315*f68d7bfcSFaraz Vahedi check_f("%F", INFINITY);
316*f68d7bfcSFaraz Vahedi check_f("%f", -0.0f);
317*f68d7bfcSFaraz Vahedi check_f("%g", -0.0f);
318*f68d7bfcSFaraz Vahedi }
319*f68d7bfcSFaraz Vahedi
320*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfromf_truncation);
ATF_TC_BODY(strfromf_truncation,tc)321*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfromf_truncation, tc)
322*f68d7bfcSFaraz Vahedi {
323*f68d7bfcSFaraz Vahedi char buf[FBUF];
324*f68d7bfcSFaraz Vahedi int ret;
325*f68d7bfcSFaraz Vahedi
326*f68d7bfcSFaraz Vahedi buf[0] = 'X';
327*f68d7bfcSFaraz Vahedi ret = strfromf(buf, 0, "%f", 1.0f);
328*f68d7bfcSFaraz Vahedi ATF_CHECK(ret > 0);
329*f68d7bfcSFaraz Vahedi ATF_CHECK_MSG(buf[0] == 'X', "buffer modified with n==0");
330*f68d7bfcSFaraz Vahedi
331*f68d7bfcSFaraz Vahedi ret = strfromf(buf, 5, "%.6f", 1.0f);
332*f68d7bfcSFaraz Vahedi ATF_CHECK_MSG(ret == 8, "return %d, want 8", ret);
333*f68d7bfcSFaraz Vahedi ATF_CHECK_MSG(buf[4] == '\0', "not null terminated at buf[4]");
334*f68d7bfcSFaraz Vahedi }
335*f68d7bfcSFaraz Vahedi
336*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfroml_f);
ATF_TC_BODY(strfroml_f,tc)337*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfroml_f, tc)
338*f68d7bfcSFaraz Vahedi {
339*f68d7bfcSFaraz Vahedi check_l("%f", 0.0L);
340*f68d7bfcSFaraz Vahedi check_l("%f", 1.0L);
341*f68d7bfcSFaraz Vahedi check_l("%f", -1.0L);
342*f68d7bfcSFaraz Vahedi check_l("%f", 3.14159265358979323846L);
343*f68d7bfcSFaraz Vahedi check_l("%.0f", 3.5L);
344*f68d7bfcSFaraz Vahedi check_l("%.2f", 3.14159L);
345*f68d7bfcSFaraz Vahedi check_l("%.15f", 1.0L / 3.0L);
346*f68d7bfcSFaraz Vahedi check_l("%f", LDBL_MAX);
347*f68d7bfcSFaraz Vahedi check_l("%f", LDBL_MIN);
348*f68d7bfcSFaraz Vahedi }
349*f68d7bfcSFaraz Vahedi
350*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfroml_e);
ATF_TC_BODY(strfroml_e,tc)351*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfroml_e, tc)
352*f68d7bfcSFaraz Vahedi {
353*f68d7bfcSFaraz Vahedi char buf[FBUF];
354*f68d7bfcSFaraz Vahedi
355*f68d7bfcSFaraz Vahedi check_l("%e", 0.0L);
356*f68d7bfcSFaraz Vahedi check_l("%e", 1.0L);
357*f68d7bfcSFaraz Vahedi check_l("%e", -1.0L);
358*f68d7bfcSFaraz Vahedi check_l("%e", 3.14159265358979323846L);
359*f68d7bfcSFaraz Vahedi check_l("%E", 2.71828182845904523536L);
360*f68d7bfcSFaraz Vahedi check_l("%.2e", 12345.6789L);
361*f68d7bfcSFaraz Vahedi check_l("%.0e", 3.14L);
362*f68d7bfcSFaraz Vahedi check_l("%e", LDBL_MAX);
363*f68d7bfcSFaraz Vahedi check_l("%e", LDBL_MIN);
364*f68d7bfcSFaraz Vahedi
365*f68d7bfcSFaraz Vahedi strfroml(buf, sizeof(buf), "%e", 1.0L);
366*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("1.000000e+00", buf);
367*f68d7bfcSFaraz Vahedi }
368*f68d7bfcSFaraz Vahedi
369*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfroml_g);
ATF_TC_BODY(strfroml_g,tc)370*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfroml_g, tc)
371*f68d7bfcSFaraz Vahedi {
372*f68d7bfcSFaraz Vahedi char buf[FBUF];
373*f68d7bfcSFaraz Vahedi
374*f68d7bfcSFaraz Vahedi check_l("%g", 0.0L);
375*f68d7bfcSFaraz Vahedi check_l("%g", 1.0L);
376*f68d7bfcSFaraz Vahedi check_l("%g", 100000.0L);
377*f68d7bfcSFaraz Vahedi check_l("%g", 1000000.0L);
378*f68d7bfcSFaraz Vahedi check_l("%g", 0.0001L);
379*f68d7bfcSFaraz Vahedi check_l("%g", 0.00001L);
380*f68d7bfcSFaraz Vahedi check_l("%G", 1.23e10L);
381*f68d7bfcSFaraz Vahedi check_l("%.2g", 3.14159L);
382*f68d7bfcSFaraz Vahedi check_l("%.0g", 3.14159L);
383*f68d7bfcSFaraz Vahedi
384*f68d7bfcSFaraz Vahedi strfroml(buf, sizeof(buf), "%g", 1.0L);
385*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("1", buf);
386*f68d7bfcSFaraz Vahedi }
387*f68d7bfcSFaraz Vahedi
388*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfroml_a);
ATF_TC_BODY(strfroml_a,tc)389*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfroml_a, tc)
390*f68d7bfcSFaraz Vahedi {
391*f68d7bfcSFaraz Vahedi char buf[FBUF];
392*f68d7bfcSFaraz Vahedi
393*f68d7bfcSFaraz Vahedi check_l("%a", 0.0L);
394*f68d7bfcSFaraz Vahedi check_l("%a", 1.0L);
395*f68d7bfcSFaraz Vahedi check_l("%a", 0.5L);
396*f68d7bfcSFaraz Vahedi check_l("%a", -1.0L);
397*f68d7bfcSFaraz Vahedi check_l("%A", 1.0L);
398*f68d7bfcSFaraz Vahedi check_l("%.4a", 1.0L / 3.0L);
399*f68d7bfcSFaraz Vahedi check_l("%.0a", 1.5L);
400*f68d7bfcSFaraz Vahedi check_l("%a", LDBL_MAX);
401*f68d7bfcSFaraz Vahedi check_l("%a", LDBL_MIN);
402*f68d7bfcSFaraz Vahedi
403*f68d7bfcSFaraz Vahedi strfroml(buf, sizeof(buf), "%a", 1.0L);
404*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("0x1p+0", buf);
405*f68d7bfcSFaraz Vahedi }
406*f68d7bfcSFaraz Vahedi
407*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfroml_special);
ATF_TC_BODY(strfroml_special,tc)408*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfroml_special, tc)
409*f68d7bfcSFaraz Vahedi {
410*f68d7bfcSFaraz Vahedi check_l("%f", INFINITY);
411*f68d7bfcSFaraz Vahedi check_l("%f", -INFINITY);
412*f68d7bfcSFaraz Vahedi check_l("%f", NAN);
413*f68d7bfcSFaraz Vahedi check_l("%e", INFINITY);
414*f68d7bfcSFaraz Vahedi check_l("%g", INFINITY);
415*f68d7bfcSFaraz Vahedi check_l("%a", INFINITY);
416*f68d7bfcSFaraz Vahedi check_l("%F", INFINITY);
417*f68d7bfcSFaraz Vahedi check_l("%f", -0.0L);
418*f68d7bfcSFaraz Vahedi check_l("%g", -0.0L);
419*f68d7bfcSFaraz Vahedi #ifdef __HAVE_LONG_DOUBLE
420*f68d7bfcSFaraz Vahedi check_l("%.20f", 1.0L / 3.0L);
421*f68d7bfcSFaraz Vahedi check_l("%.20e", 1.0L / 7.0L);
422*f68d7bfcSFaraz Vahedi #endif
423*f68d7bfcSFaraz Vahedi }
424*f68d7bfcSFaraz Vahedi
425*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfroml_truncation);
ATF_TC_BODY(strfroml_truncation,tc)426*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfroml_truncation, tc)
427*f68d7bfcSFaraz Vahedi {
428*f68d7bfcSFaraz Vahedi char buf[FBUF];
429*f68d7bfcSFaraz Vahedi int ret;
430*f68d7bfcSFaraz Vahedi
431*f68d7bfcSFaraz Vahedi buf[0] = 'X';
432*f68d7bfcSFaraz Vahedi ret = strfroml(buf, 0, "%f", 1.0L);
433*f68d7bfcSFaraz Vahedi ATF_CHECK(ret > 0);
434*f68d7bfcSFaraz Vahedi ATF_CHECK_MSG(buf[0] == 'X', "buffer modified with n==0");
435*f68d7bfcSFaraz Vahedi
436*f68d7bfcSFaraz Vahedi ret = strfroml(buf, 5, "%.6f", 1.0L);
437*f68d7bfcSFaraz Vahedi ATF_CHECK_MSG(ret == 8, "return %d, want 8", ret);
438*f68d7bfcSFaraz Vahedi ATF_CHECK_MSG(buf[4] == '\0', "not null terminated at buf[4]");
439*f68d7bfcSFaraz Vahedi }
440*f68d7bfcSFaraz Vahedi
441*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfrom_locale);
ATF_TC_BODY(strfrom_locale,tc)442*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfrom_locale, tc)
443*f68d7bfcSFaraz Vahedi {
444*f68d7bfcSFaraz Vahedi char buf[FBUF];
445*f68d7bfcSFaraz Vahedi
446*f68d7bfcSFaraz Vahedi /*
447*f68d7bfcSFaraz Vahedi * strfrom* is equivalent to snprintf(3) and so honours LC_NUMERIC:
448*f68d7bfcSFaraz Vahedi * In a locale whose radix is not '.', the output must use that radix.
449*f68d7bfcSFaraz Vahedi * The check_* helpers already compare against snprintf in this locale;
450*f68d7bfcSFaraz Vahedi * the literal checks confirm the radix actually changed for both the
451*f68d7bfcSFaraz Vahedi * decimal and hexadecimal paths. Skip if the locale is unavailable.
452*f68d7bfcSFaraz Vahedi */
453*f68d7bfcSFaraz Vahedi if (setlocale(LC_NUMERIC, "de_DE.UTF-8") == NULL)
454*f68d7bfcSFaraz Vahedi atf_tc_skip("de_DE.UTF-8 locale not available");
455*f68d7bfcSFaraz Vahedi
456*f68d7bfcSFaraz Vahedi check_d("%f", 1.5);
457*f68d7bfcSFaraz Vahedi check_d("%e", 1.5);
458*f68d7bfcSFaraz Vahedi check_d("%g", 1.5);
459*f68d7bfcSFaraz Vahedi check_d("%a", 1.5);
460*f68d7bfcSFaraz Vahedi check_f("%f", 1.5f);
461*f68d7bfcSFaraz Vahedi check_l("%f", 1.5L);
462*f68d7bfcSFaraz Vahedi
463*f68d7bfcSFaraz Vahedi strfromd(buf, sizeof(buf), "%.1f", 1.5);
464*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("1,5", buf);
465*f68d7bfcSFaraz Vahedi strfromd(buf, sizeof(buf), "%a", 1.5);
466*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("0x1,8p+0", buf);
467*f68d7bfcSFaraz Vahedi }
468*f68d7bfcSFaraz Vahedi
469*f68d7bfcSFaraz Vahedi /*
470*f68d7bfcSFaraz Vahedi * Per C23 §7.24.1.3p2, format string outside the restricted grammar is
471*f68d7bfcSFaraz Vahedi * undefined behaviour. FreeBSD reports it as the programming error it
472*f68d7bfcSFaraz Vahedi * is; the conversion yields "EDOOFUS" and sets errno accordingly.
473*f68d7bfcSFaraz Vahedi */
474*f68d7bfcSFaraz Vahedi static void
check_edoofus(const char * fmt,int ret,const char * buf)475*f68d7bfcSFaraz Vahedi check_edoofus(const char *fmt, int ret, const char *buf)
476*f68d7bfcSFaraz Vahedi {
477*f68d7bfcSFaraz Vahedi ATF_CHECK_MSG(ret == 7, "%s: return %d, want 7", fmt, ret);
478*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ_MSG("EDOOFUS", buf, "%s: got \"%s\"", fmt, buf);
479*f68d7bfcSFaraz Vahedi ATF_CHECK_MSG(errno == EDOOFUS, "%s: errno %d, want %d", fmt, errno,
480*f68d7bfcSFaraz Vahedi EDOOFUS);
481*f68d7bfcSFaraz Vahedi }
482*f68d7bfcSFaraz Vahedi
483*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfrom_empty_format);
ATF_TC_BODY(strfrom_empty_format,tc)484*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfrom_empty_format, tc)
485*f68d7bfcSFaraz Vahedi {
486*f68d7bfcSFaraz Vahedi char buf[FBUF];
487*f68d7bfcSFaraz Vahedi int ret;
488*f68d7bfcSFaraz Vahedi
489*f68d7bfcSFaraz Vahedi errno = 0;
490*f68d7bfcSFaraz Vahedi ret = strfromd(buf, sizeof(buf), "", 1.0);
491*f68d7bfcSFaraz Vahedi check_edoofus("", ret, buf);
492*f68d7bfcSFaraz Vahedi }
493*f68d7bfcSFaraz Vahedi
494*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfrom_bad_specifier);
ATF_TC_BODY(strfrom_bad_specifier,tc)495*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfrom_bad_specifier, tc)
496*f68d7bfcSFaraz Vahedi {
497*f68d7bfcSFaraz Vahedi char buf[FBUF];
498*f68d7bfcSFaraz Vahedi int ret;
499*f68d7bfcSFaraz Vahedi
500*f68d7bfcSFaraz Vahedi errno = 0;
501*f68d7bfcSFaraz Vahedi ret = strfromd(buf, sizeof(buf), "%q", 1.0);
502*f68d7bfcSFaraz Vahedi check_edoofus("%q", ret, buf);
503*f68d7bfcSFaraz Vahedi
504*f68d7bfcSFaraz Vahedi errno = 0;
505*f68d7bfcSFaraz Vahedi ret = strfromf(buf, sizeof(buf), "%.2q", 1.0f);
506*f68d7bfcSFaraz Vahedi check_edoofus("%.2q", ret, buf);
507*f68d7bfcSFaraz Vahedi
508*f68d7bfcSFaraz Vahedi errno = 0;
509*f68d7bfcSFaraz Vahedi ret = strfroml(buf, sizeof(buf), "%", 1.0L);
510*f68d7bfcSFaraz Vahedi check_edoofus("%", ret, buf);
511*f68d7bfcSFaraz Vahedi
512*f68d7bfcSFaraz Vahedi errno = 0;
513*f68d7bfcSFaraz Vahedi ret = strfromd(buf, sizeof(buf), "f", 1.0);
514*f68d7bfcSFaraz Vahedi check_edoofus("f", ret, buf);
515*f68d7bfcSFaraz Vahedi
516*f68d7bfcSFaraz Vahedi errno = 0;
517*f68d7bfcSFaraz Vahedi ret = strfromd(buf, sizeof(buf), "%*f", 1.0);
518*f68d7bfcSFaraz Vahedi check_edoofus("%*f", ret, buf);
519*f68d7bfcSFaraz Vahedi
520*f68d7bfcSFaraz Vahedi errno = 0;
521*f68d7bfcSFaraz Vahedi ret = strfromd(buf, sizeof(buf), "%f ", 1.0);
522*f68d7bfcSFaraz Vahedi check_edoofus("%f ", ret, buf);
523*f68d7bfcSFaraz Vahedi }
524*f68d7bfcSFaraz Vahedi
525*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfrom_bad_format_truncation);
ATF_TC_BODY(strfrom_bad_format_truncation,tc)526*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfrom_bad_format_truncation, tc)
527*f68d7bfcSFaraz Vahedi {
528*f68d7bfcSFaraz Vahedi char buf[FBUF];
529*f68d7bfcSFaraz Vahedi int ret;
530*f68d7bfcSFaraz Vahedi
531*f68d7bfcSFaraz Vahedi /* The error string obeys the snprintf(3) truncation rules. */
532*f68d7bfcSFaraz Vahedi buf[0] = 'X';
533*f68d7bfcSFaraz Vahedi errno = 0;
534*f68d7bfcSFaraz Vahedi ret = strfromd(buf, 0, "%q", 1.0);
535*f68d7bfcSFaraz Vahedi ATF_CHECK_MSG(ret == 7, "return %d, want 7", ret);
536*f68d7bfcSFaraz Vahedi ATF_CHECK_MSG(buf[0] == 'X', "buffer modified with n==0");
537*f68d7bfcSFaraz Vahedi ATF_CHECK_EQ(EDOOFUS, errno);
538*f68d7bfcSFaraz Vahedi
539*f68d7bfcSFaraz Vahedi errno = 0;
540*f68d7bfcSFaraz Vahedi ret = strfromd(buf, 4, "%q", 1.0);
541*f68d7bfcSFaraz Vahedi ATF_CHECK_MSG(ret == 7, "return %d, want 7", ret);
542*f68d7bfcSFaraz Vahedi ATF_CHECK_STREQ("EDO", buf);
543*f68d7bfcSFaraz Vahedi ATF_CHECK_EQ(EDOOFUS, errno);
544*f68d7bfcSFaraz Vahedi }
545*f68d7bfcSFaraz Vahedi
546*f68d7bfcSFaraz Vahedi ATF_TC_WITHOUT_HEAD(strfrom_errno_preserved);
ATF_TC_BODY(strfrom_errno_preserved,tc)547*f68d7bfcSFaraz Vahedi ATF_TC_BODY(strfrom_errno_preserved, tc)
548*f68d7bfcSFaraz Vahedi {
549*f68d7bfcSFaraz Vahedi char buf[FBUF];
550*f68d7bfcSFaraz Vahedi
551*f68d7bfcSFaraz Vahedi errno = 0;
552*f68d7bfcSFaraz Vahedi strfromd(buf, sizeof(buf), "%f", 1.0);
553*f68d7bfcSFaraz Vahedi ATF_CHECK_EQ(0, errno);
554*f68d7bfcSFaraz Vahedi strfromf(buf, sizeof(buf), "%a", 1.0f);
555*f68d7bfcSFaraz Vahedi ATF_CHECK_EQ(0, errno);
556*f68d7bfcSFaraz Vahedi strfroml(buf, sizeof(buf), "%.3g", 1.0L);
557*f68d7bfcSFaraz Vahedi ATF_CHECK_EQ(0, errno);
558*f68d7bfcSFaraz Vahedi }
559*f68d7bfcSFaraz Vahedi
ATF_TP_ADD_TCS(tp)560*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TCS(tp)
561*f68d7bfcSFaraz Vahedi {
562*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfromd_f);
563*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfromd_e);
564*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfromd_g);
565*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfromd_a);
566*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfromd_special);
567*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfromd_truncation);
568*f68d7bfcSFaraz Vahedi
569*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfromf_f);
570*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfromf_e);
571*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfromf_g);
572*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfromf_a);
573*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfromf_special);
574*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfromf_truncation);
575*f68d7bfcSFaraz Vahedi
576*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfroml_f);
577*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfroml_e);
578*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfroml_g);
579*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfroml_a);
580*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfroml_special);
581*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfroml_truncation);
582*f68d7bfcSFaraz Vahedi
583*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfrom_locale);
584*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfrom_empty_format);
585*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfrom_bad_specifier);
586*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfrom_bad_format_truncation);
587*f68d7bfcSFaraz Vahedi ATF_TP_ADD_TC(tp, strfrom_errno_preserved);
588*f68d7bfcSFaraz Vahedi
589*f68d7bfcSFaraz Vahedi return (atf_no_error());
590*f68d7bfcSFaraz Vahedi }
591