Fix last ChangeLog entry.
[gnulib.git] / tests / test-szprintf-posix.h
blobc813261b1458d01503c1e7fb2feee26a99ae180e
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. */
23 #include "infinity.h"
24 #include "nan.h"
26 /* Test whether string[start_index..end_index-1] is a valid textual
27 representation of NaN. */
28 static int
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] == '-')
34 start_index++;
35 if (start_index + 3 <= end_index
36 && memcmp (string + start_index, uppercase ? "NAN" : "nan", 3) == 0)
38 start_index += 3;
39 if (start_index == end_index
40 || (string[start_index] == '(' && string[end_index - 1] == ')'))
41 return 1;
44 return 0;
47 static void
48 test_function (ptrdiff_t (*my_szprintf) (char *, const char *, ...))
50 char result[5000];
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. */
56 ptrdiff_t retval =
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. */
66 ptrdiff_t retval =
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. */
76 ptrdiff_t retval =
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,
86 Solaris 11.4. */
87 ptrdiff_t retval =
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. */
99 ptrdiff_t retval =
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. */
107 ptrdiff_t retval =
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. */
116 ptrdiff_t retval =
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. */
126 ptrdiff_t retval =
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. */
134 ptrdiff_t retval =
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. */
145 ptrdiff_t retval =
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. */
153 ptrdiff_t retval =
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. */
164 ptrdiff_t retval =
165 my_szprintf (result, "%.4000d %d", 1234567, 99);
166 size_t i;
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
174 integers. */
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. */
178 ptrdiff_t retval =
179 my_szprintf (result, "%b %d", 12345, 33, 44, 55);
180 ASSERT (strcmp (result, "11000000111001 33") == 0);
181 ASSERT (retval == strlen (result));