errno-h: document Haiku errors can’t be -1
[gnulib.git] / tests / test-vaszprintf-posix.c
blob73a0847058b0127ea75397156e4a87c58ad7a3b4
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. */
23 #include <config.h>
25 #include <stdio.h>
27 #include <stdarg.h>
28 #include <stddef.h>
29 #include <stdlib.h>
30 #include <string.h>
32 #include "macros.h"
33 #include "infinity.h"
34 #include "nan.h"
36 /* Test whether string[start_index..end_index-1] is a valid textual
37 representation of NaN. */
38 static int
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] == '-')
44 start_index++;
45 if (start_index + 3 <= end_index
46 && memcmp (string + start_index, uppercase ? "NAN" : "nan", 3) == 0)
48 start_index += 3;
49 if (start_index == end_index
50 || (string[start_index] == '(' && string[end_index - 1] == ')'))
51 return 1;
54 return 0;
57 static void
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. */
64 char *result;
65 ptrdiff_t retval =
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));
73 free (result);
76 { /* This test would fail on Solaris 11.4. */
77 char *result;
78 ptrdiff_t retval =
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));
86 free (result);
89 { /* This test would fail on FreeBSD 6.1, NetBSD 10.0. */
90 char *result;
91 ptrdiff_t retval =
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));
99 free (result);
102 { /* This test would fail on macOS 14, FreeBSD 14.0, OpenBSD 7.5, AIX 7.3,
103 Solaris 11.4. */
104 char *result;
105 ptrdiff_t retval =
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));
113 free (result);
116 /* Test the support of the %f format directive. */
118 { /* This test would fail on AIX 7.3, Solaris 11.4. */
119 char *result;
120 ptrdiff_t retval =
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));
126 free (result);
129 { /* This test would fail on AIX 7.3, Solaris 11.4. */
130 char *result;
131 ptrdiff_t retval =
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));
138 free (result);
141 { /* This test would fail on AIX 7.3, Solaris 11.4. */
142 char *result;
143 ptrdiff_t retval =
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));
149 free (result);
152 /* Test the support of the %e format directive. */
154 { /* This test would fail on AIX 7.3, Solaris 11.4. */
155 char *result;
156 ptrdiff_t retval =
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));
162 free (result);
165 { /* This test would fail on AIX 7.3, Solaris 11.4. */
166 char *result;
167 ptrdiff_t retval =
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));
174 free (result);
177 /* Test the support of the %g format directive. */
179 { /* This test would fail on AIX 7.3, Solaris 11.4. */
180 char *result;
181 ptrdiff_t retval =
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));
187 free (result);
190 { /* This test would fail on AIX 7.3, Solaris 11.4. */
191 char *result;
192 ptrdiff_t retval =
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));
199 free (result);
202 /* Test the support of large precision. */
204 { /* This test would fail on AIX 7.1. */
205 char *result;
206 ptrdiff_t retval =
207 my_aszprintf (&result, "%.4000d %d", 1234567, 99);
208 ASSERT (result != NULL);
209 size_t i;
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));
214 free (result);
217 /* Test the support of the 'b' conversion specifier for binary output of
218 integers. */
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. */
222 char *result;
223 ptrdiff_t retval =
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));
228 free (result);
232 static ptrdiff_t
233 my_aszprintf (char **result, const char *format, ...)
235 va_list args;
236 ptrdiff_t ret;
238 va_start (args, format);
239 ret = vaszprintf (result, format, args);
240 va_end (args);
241 return ret;
244 static void
245 test_vaszprintf ()
247 test_function (my_aszprintf);
250 static void
251 test_aszprintf ()
253 test_function (aszprintf);
257 main (int argc, char *argv[])
259 test_vaszprintf ();
260 test_aszprintf ();
261 return test_exit_status;