1 /* Test of POSIX compatible vszprintf() and szprintf() functions.
2 Copyright (C) 2007-2025 Free Software Foundation, Inc.
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <https://www.gnu.org/licenses/>. */
17 /* Written by Bruno Haible <bruno@clisp.org>, 2024. */
19 /* This test exercises only a few POSIX compliance problems that are still
20 visible on platforms relevant in 2024. For a much more complete test suite,
21 see test-sprintf-posix.h. */
26 /* Test whether string[start_index..end_index-1] is a valid textual
27 representation of NaN. */
29 strisnan (const char *string
, size_t start_index
, size_t end_index
, int uppercase
)
31 if (start_index
< end_index
)
33 if (string
[start_index
] == '-')
35 if (start_index
+ 3 <= end_index
36 && memcmp (string
+ start_index
, uppercase
? "NAN" : "nan", 3) == 0)
39 if (start_index
== end_index
40 || (string
[start_index
] == '(' && string
[end_index
- 1] == ')'))
48 test_function (ptrdiff_t (*my_szprintf
) (char *, const char *, ...))
52 /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
53 output of floating-point numbers. */
55 { /* This test would fail on Solaris 11.4. */
57 my_szprintf (result
, "%a %d", 3.1416015625, 33, 44, 55);
58 ASSERT (strcmp (result
, "0x1.922p+1 33") == 0
59 || strcmp (result
, "0x3.244p+0 33") == 0
60 || strcmp (result
, "0x6.488p-1 33") == 0
61 || strcmp (result
, "0xc.91p-2 33") == 0);
62 ASSERT (retval
== strlen (result
));
65 { /* This test would fail on Solaris 11.4. */
67 my_szprintf (result
, "%A %d", -3.1416015625, 33, 44, 55);
68 ASSERT (strcmp (result
, "-0X1.922P+1 33") == 0
69 || strcmp (result
, "-0X3.244P+0 33") == 0
70 || strcmp (result
, "-0X6.488P-1 33") == 0
71 || strcmp (result
, "-0XC.91P-2 33") == 0);
72 ASSERT (retval
== strlen (result
));
75 { /* This test would fail on FreeBSD 6.1, NetBSD 10.0. */
77 my_szprintf (result
, "%.2a %d", 1.51, 33, 44, 55);
78 ASSERT (strcmp (result
, "0x1.83p+0 33") == 0
79 || strcmp (result
, "0x3.05p-1 33") == 0
80 || strcmp (result
, "0x6.0ap-2 33") == 0
81 || strcmp (result
, "0xc.14p-3 33") == 0);
82 ASSERT (retval
== strlen (result
));
85 { /* This test would fail on macOS 14, FreeBSD 14.0, OpenBSD 7.5, AIX 7.3,
88 my_szprintf (result
, "%.0a %d", 1.51, 33, 44, 55);
89 ASSERT (strcmp (result
, "0x2p+0 33") == 0
90 || strcmp (result
, "0x3p-1 33") == 0
91 || strcmp (result
, "0x6p-2 33") == 0
92 || strcmp (result
, "0xcp-3 33") == 0);
93 ASSERT (retval
== strlen (result
));
96 /* Test the support of the %f format directive. */
98 { /* This test would fail on AIX 7.3, Solaris 11.4. */
100 my_szprintf (result
, "%f %d", Infinityd (), 33, 44, 55);
101 ASSERT (strcmp (result
, "inf 33") == 0
102 || strcmp (result
, "infinity 33") == 0);
103 ASSERT (retval
== strlen (result
));
106 { /* This test would fail on AIX 7.3, Solaris 11.4. */
108 my_szprintf (result
, "%f %d", NaNd (), 33, 44, 55);
109 ASSERT (strlen (result
) >= 3 + 3
110 && strisnan (result
, 0, strlen (result
) - 3, 0)
111 && strcmp (result
+ strlen (result
) - 3, " 33") == 0);
112 ASSERT (retval
== strlen (result
));
115 { /* This test would fail on AIX 7.3, Solaris 11.4. */
117 my_szprintf (result
, "%010f %d", Infinityd (), 33, 44, 55);
118 ASSERT (strcmp (result
, " inf 33") == 0
119 || strcmp (result
, " infinity 33") == 0);
120 ASSERT (retval
== strlen (result
));
123 /* Test the support of the %e format directive. */
125 { /* This test would fail on AIX 7.3, Solaris 11.4. */
127 my_szprintf (result
, "%e %d", Infinityd (), 33, 44, 55);
128 ASSERT (strcmp (result
, "inf 33") == 0
129 || strcmp (result
, "infinity 33") == 0);
130 ASSERT (retval
== strlen (result
));
133 { /* This test would fail on AIX 7.3, Solaris 11.4. */
135 my_szprintf (result
, "%e %d", NaNd (), 33, 44, 55);
136 ASSERT (strlen (result
) >= 3 + 3
137 && strisnan (result
, 0, strlen (result
) - 3, 0)
138 && strcmp (result
+ strlen (result
) - 3, " 33") == 0);
139 ASSERT (retval
== strlen (result
));
142 /* Test the support of the %g format directive. */
144 { /* This test would fail on AIX 7.3, Solaris 11.4. */
146 my_szprintf (result
, "%g %d", Infinityd (), 33, 44, 55);
147 ASSERT (strcmp (result
, "inf 33") == 0
148 || strcmp (result
, "infinity 33") == 0);
149 ASSERT (retval
== strlen (result
));
152 { /* This test would fail on AIX 7.3, Solaris 11.4. */
154 my_szprintf (result
, "%g %d", NaNd (), 33, 44, 55);
155 ASSERT (strlen (result
) >= 3 + 3
156 && strisnan (result
, 0, strlen (result
) - 3, 0)
157 && strcmp (result
+ strlen (result
) - 3, " 33") == 0);
158 ASSERT (retval
== strlen (result
));
161 /* Test the support of large precision. */
163 { /* This test would fail on AIX 7.1. */
165 my_szprintf (result
, "%.4000d %d", 1234567, 99);
167 for (i
= 0; i
< 4000 - 7; i
++)
168 ASSERT (result
[i
] == '0');
169 ASSERT (strcmp (result
+ 4000 - 7, "1234567 99") == 0);
170 ASSERT (retval
== strlen (result
));
173 /* Test the support of the 'b' conversion specifier for binary output of
176 { /* This test would fail on glibc 2.34, musl libc, macOS 14,
177 FreeBSD 13.2, NetBSD 10.0, OpenBSD 7.5, AIX 7.3, Solaris 11.4. */
179 my_szprintf (result
, "%b %d", 12345, 33, 44, 55);
180 ASSERT (strcmp (result
, "11000000111001 33") == 0);
181 ASSERT (retval
== strlen (result
));