1 /* Test of POSIX compatible vaszprintf() and aszprintf() 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-vasprintf-posix.c. */
36 /* Test whether string[start_index..end_index-1] is a valid textual
37 representation of NaN. */
39 strisnan (const char *string
, size_t start_index
, size_t end_index
, int uppercase
)
41 if (start_index
< end_index
)
43 if (string
[start_index
] == '-')
45 if (start_index
+ 3 <= end_index
46 && memcmp (string
+ start_index
, uppercase
? "NAN" : "nan", 3) == 0)
49 if (start_index
== end_index
50 || (string
[start_index
] == '(' && string
[end_index
- 1] == ')'))
58 test_function (ptrdiff_t (*my_aszprintf
) (char **, const char *, ...))
60 /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
61 output of floating-point numbers. */
63 { /* This test would fail on Solaris 11.4. */
66 my_aszprintf (&result
, "%a %d", 3.1416015625, 33, 44, 55);
67 ASSERT (result
!= NULL
);
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
));
76 { /* This test would fail on Solaris 11.4. */
79 my_aszprintf (&result
, "%A %d", -3.1416015625, 33, 44, 55);
80 ASSERT (result
!= NULL
);
81 ASSERT (strcmp (result
, "-0X1.922P+1 33") == 0
82 || strcmp (result
, "-0X3.244P+0 33") == 0
83 || strcmp (result
, "-0X6.488P-1 33") == 0
84 || strcmp (result
, "-0XC.91P-2 33") == 0);
85 ASSERT (retval
== strlen (result
));
89 { /* This test would fail on FreeBSD 6.1, NetBSD 10.0. */
92 my_aszprintf (&result
, "%.2a %d", 1.51, 33, 44, 55);
93 ASSERT (result
!= NULL
);
94 ASSERT (strcmp (result
, "0x1.83p+0 33") == 0
95 || strcmp (result
, "0x3.05p-1 33") == 0
96 || strcmp (result
, "0x6.0ap-2 33") == 0
97 || strcmp (result
, "0xc.14p-3 33") == 0);
98 ASSERT (retval
== strlen (result
));
102 { /* This test would fail on macOS 14, FreeBSD 14.0, OpenBSD 7.5, AIX 7.3,
106 my_aszprintf (&result
, "%.0a %d", 1.51, 33, 44, 55);
107 ASSERT (result
!= NULL
);
108 ASSERT (strcmp (result
, "0x2p+0 33") == 0
109 || strcmp (result
, "0x3p-1 33") == 0
110 || strcmp (result
, "0x6p-2 33") == 0
111 || strcmp (result
, "0xcp-3 33") == 0);
112 ASSERT (retval
== strlen (result
));
116 /* Test the support of the %f format directive. */
118 { /* This test would fail on AIX 7.3, Solaris 11.4. */
121 my_aszprintf (&result
, "%f %d", Infinityd (), 33, 44, 55);
122 ASSERT (result
!= NULL
);
123 ASSERT (strcmp (result
, "inf 33") == 0
124 || strcmp (result
, "infinity 33") == 0);
125 ASSERT (retval
== strlen (result
));
129 { /* This test would fail on AIX 7.3, Solaris 11.4. */
132 my_aszprintf (&result
, "%f %d", NaNd (), 33, 44, 55);
133 ASSERT (result
!= NULL
);
134 ASSERT (strlen (result
) >= 3 + 3
135 && strisnan (result
, 0, strlen (result
) - 3, 0)
136 && strcmp (result
+ strlen (result
) - 3, " 33") == 0);
137 ASSERT (retval
== strlen (result
));
141 { /* This test would fail on AIX 7.3, Solaris 11.4. */
144 my_aszprintf (&result
, "%010f %d", Infinityd (), 33, 44, 55);
145 ASSERT (result
!= NULL
);
146 ASSERT (strcmp (result
, " inf 33") == 0
147 || strcmp (result
, " infinity 33") == 0);
148 ASSERT (retval
== strlen (result
));
152 /* Test the support of the %e format directive. */
154 { /* This test would fail on AIX 7.3, Solaris 11.4. */
157 my_aszprintf (&result
, "%e %d", Infinityd (), 33, 44, 55);
158 ASSERT (result
!= NULL
);
159 ASSERT (strcmp (result
, "inf 33") == 0
160 || strcmp (result
, "infinity 33") == 0);
161 ASSERT (retval
== strlen (result
));
165 { /* This test would fail on AIX 7.3, Solaris 11.4. */
168 my_aszprintf (&result
, "%e %d", NaNd (), 33, 44, 55);
169 ASSERT (result
!= NULL
);
170 ASSERT (strlen (result
) >= 3 + 3
171 && strisnan (result
, 0, strlen (result
) - 3, 0)
172 && strcmp (result
+ strlen (result
) - 3, " 33") == 0);
173 ASSERT (retval
== strlen (result
));
177 /* Test the support of the %g format directive. */
179 { /* This test would fail on AIX 7.3, Solaris 11.4. */
182 my_aszprintf (&result
, "%g %d", Infinityd (), 33, 44, 55);
183 ASSERT (result
!= NULL
);
184 ASSERT (strcmp (result
, "inf 33") == 0
185 || strcmp (result
, "infinity 33") == 0);
186 ASSERT (retval
== strlen (result
));
190 { /* This test would fail on AIX 7.3, Solaris 11.4. */
193 my_aszprintf (&result
, "%g %d", NaNd (), 33, 44, 55);
194 ASSERT (result
!= NULL
);
195 ASSERT (strlen (result
) >= 3 + 3
196 && strisnan (result
, 0, strlen (result
) - 3, 0)
197 && strcmp (result
+ strlen (result
) - 3, " 33") == 0);
198 ASSERT (retval
== strlen (result
));
202 /* Test the support of large precision. */
204 { /* This test would fail on AIX 7.1. */
207 my_aszprintf (&result
, "%.4000d %d", 1234567, 99);
208 ASSERT (result
!= NULL
);
210 for (i
= 0; i
< 4000 - 7; i
++)
211 ASSERT (result
[i
] == '0');
212 ASSERT (strcmp (result
+ 4000 - 7, "1234567 99") == 0);
213 ASSERT (retval
== strlen (result
));
217 /* Test the support of the 'b' conversion specifier for binary output of
220 { /* This test would fail on glibc 2.34, musl libc, macOS 14,
221 FreeBSD 13.2, NetBSD 10.0, OpenBSD 7.5, AIX 7.3, Solaris 11.4. */
224 my_aszprintf (&result
, "%b %d", 12345, 33, 44, 55);
225 ASSERT (result
!= NULL
);
226 ASSERT (strcmp (result
, "11000000111001 33") == 0);
227 ASSERT (retval
== strlen (result
));
233 my_aszprintf (char **result
, const char *format
, ...)
238 va_start (args
, format
);
239 ret
= vaszprintf (result
, format
, args
);
247 test_function (my_aszprintf
);
253 test_function (aszprintf
);
257 main (int argc
, char *argv
[])
261 return test_exit_status
;