1 /* Test of POSIX compatible vasprintf() and asprintf() functions.
2 Copyright (C) 2007-2014 Free Software Foundation, Inc.
3
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.
8
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.
13
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>. */
16
17 /* Written by Bruno Haible <bruno@clisp.org>, 2007. */
18
19 #include <config.h>
20
21 #include <stdio.h>
22
23 #include <float.h>
24 #include <stdarg.h>
25 #include <stddef.h>
26 #include <stdint.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "macros.h"
31 #include "minus-zero.h"
32 #include "infinity.h"
33 #include "nan.h"
34
35 /* The SGI MIPS floating-point format does not distinguish 0.0 and -0.0. */
36 static int
have_minus_zero()37 have_minus_zero ()
38 {
39 static double plus_zero = 0.0;
40 double minus_zero = minus_zerod;
41 return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
42 }
43
44 /* Representation of an 80-bit 'long double' as an initializer for a sequence
45 of 'unsigned int' words. */
46 #ifdef WORDS_BIGENDIAN
47 # define LDBL80_WORDS(exponent,manthi,mantlo) \
48 { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
49 ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16), \
50 (unsigned int) (mantlo) << 16 \
51 }
52 #else
53 # define LDBL80_WORDS(exponent,manthi,mantlo) \
54 { mantlo, manthi, exponent }
55 #endif
56
57 static int
strmatch(const char * pattern,const char * string)58 strmatch (const char *pattern, const char *string)
59 {
60 if (strlen (pattern) != strlen (string))
61 return 0;
62 for (; *pattern != '\0'; pattern++, string++)
63 if (*pattern != '*' && *string != *pattern)
64 return 0;
65 return 1;
66 }
67
68 /* Test whether string[start_index..end_index-1] is a valid textual
69 representation of NaN. */
70 static int
strisnan(const char * string,size_t start_index,size_t end_index,int uppercase)71 strisnan (const char *string, size_t start_index, size_t end_index, int uppercase)
72 {
73 if (start_index < end_index)
74 {
75 if (string[start_index] == '-')
76 start_index++;
77 if (start_index + 3 <= end_index
78 && memcmp (string + start_index, uppercase ? "NAN" : "nan", 3) == 0)
79 {
80 start_index += 3;
81 if (start_index == end_index
82 || (string[start_index] == '(' && string[end_index - 1] == ')'))
83 return 1;
84 }
85 }
86 return 0;
87 }
88
89 static void
test_function(int (* my_asprintf)(char **,const char *,...))90 test_function (int (*my_asprintf) (char **, const char *, ...))
91 {
92 int repeat;
93
94 /* Test return value convention. */
95
96 for (repeat = 0; repeat <= 8; repeat++)
97 {
98 char *result;
99 int retval = asprintf (&result, "%d", 12345);
100 ASSERT (retval == 5);
101 ASSERT (result != NULL);
102 ASSERT (strcmp (result, "12345") == 0);
103 free (result);
104 }
105
106 /* Test support of size specifiers as in C99. */
107
108 {
109 char *result;
110 int retval =
111 my_asprintf (&result, "%ju %d", (uintmax_t) 12345671, 33, 44, 55);
112 ASSERT (result != NULL);
113 ASSERT (strcmp (result, "12345671 33") == 0);
114 ASSERT (retval == strlen (result));
115 free (result);
116 }
117
118 {
119 char *result;
120 int retval =
121 my_asprintf (&result, "%zu %d", (size_t) 12345672, 33, 44, 55);
122 ASSERT (result != NULL);
123 ASSERT (strcmp (result, "12345672 33") == 0);
124 ASSERT (retval == strlen (result));
125 free (result);
126 }
127
128 {
129 char *result;
130 int retval =
131 my_asprintf (&result, "%tu %d", (ptrdiff_t) 12345673, 33, 44, 55);
132 ASSERT (result != NULL);
133 ASSERT (strcmp (result, "12345673 33") == 0);
134 ASSERT (retval == strlen (result));
135 free (result);
136 }
137
138 {
139 char *result;
140 int retval =
141 my_asprintf (&result, "%Lg %d", (long double) 1.5, 33, 44, 55);
142 ASSERT (result != NULL);
143 ASSERT (strcmp (result, "1.5 33") == 0);
144 ASSERT (retval == strlen (result));
145 free (result);
146 }
147
148 /* Test the support of the 'a' and 'A' conversion specifier for hexadecimal
149 output of floating-point numbers. */
150
151 { /* A positive number. */
152 char *result;
153 int retval =
154 my_asprintf (&result, "%a %d", 3.1416015625, 33, 44, 55);
155 ASSERT (result != NULL);
156 ASSERT (strcmp (result, "0x1.922p+1 33") == 0
157 || strcmp (result, "0x3.244p+0 33") == 0
158 || strcmp (result, "0x6.488p-1 33") == 0
159 || strcmp (result, "0xc.91p-2 33") == 0);
160 ASSERT (retval == strlen (result));
161 free (result);
162 }
163
164 { /* A negative number. */
165 char *result;
166 int retval =
167 my_asprintf (&result, "%A %d", -3.1416015625, 33, 44, 55);
168 ASSERT (result != NULL);
169 ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
170 || strcmp (result, "-0X3.244P+0 33") == 0
171 || strcmp (result, "-0X6.488P-1 33") == 0
172 || strcmp (result, "-0XC.91P-2 33") == 0);
173 ASSERT (retval == strlen (result));
174 free (result);
175 }
176
177 { /* Positive zero. */
178 char *result;
179 int retval =
180 my_asprintf (&result, "%a %d", 0.0, 33, 44, 55);
181 ASSERT (result != NULL);
182 ASSERT (strcmp (result, "0x0p+0 33") == 0);
183 ASSERT (retval == strlen (result));
184 free (result);
185 }
186
187 { /* Negative zero. */
188 char *result;
189 int retval =
190 my_asprintf (&result, "%a %d", minus_zerod, 33, 44, 55);
191 ASSERT (result != NULL);
192 if (have_minus_zero ())
193 ASSERT (strcmp (result, "-0x0p+0 33") == 0);
194 ASSERT (retval == strlen (result));
195 free (result);
196 }
197
198 { /* Positive infinity. */
199 char *result;
200 int retval =
201 my_asprintf (&result, "%a %d", Infinityd (), 33, 44, 55);
202 ASSERT (result != NULL);
203 ASSERT (strcmp (result, "inf 33") == 0);
204 ASSERT (retval == strlen (result));
205 free (result);
206 }
207
208 { /* Negative infinity. */
209 char *result;
210 int retval =
211 my_asprintf (&result, "%a %d", - Infinityd (), 33, 44, 55);
212 ASSERT (result != NULL);
213 ASSERT (strcmp (result, "-inf 33") == 0);
214 ASSERT (retval == strlen (result));
215 free (result);
216 }
217
218 { /* NaN. */
219 char *result;
220 int retval =
221 my_asprintf (&result, "%a %d", NaNd (), 33, 44, 55);
222 ASSERT (result != NULL);
223 ASSERT (strlen (result) >= 3 + 3
224 && strisnan (result, 0, strlen (result) - 3, 0)
225 && strcmp (result + strlen (result) - 3, " 33") == 0);
226 ASSERT (retval == strlen (result));
227 free (result);
228 }
229
230 { /* Rounding near the decimal point. */
231 char *result;
232 int retval =
233 my_asprintf (&result, "%.0a %d", 1.5, 33, 44, 55);
234 ASSERT (result != NULL);
235 ASSERT (strcmp (result, "0x1p+0 33") == 0
236 || strcmp (result, "0x2p+0 33") == 0
237 || strcmp (result, "0x3p-1 33") == 0
238 || strcmp (result, "0x6p-2 33") == 0
239 || strcmp (result, "0xcp-3 33") == 0);
240 ASSERT (retval == strlen (result));
241 free (result);
242 }
243
244 { /* Rounding with precision 0. */
245 char *result;
246 int retval =
247 my_asprintf (&result, "%.0a %d", 1.51, 33, 44, 55);
248 ASSERT (result != NULL);
249 ASSERT (strcmp (result, "0x1p+0 33") == 0
250 || strcmp (result, "0x2p+0 33") == 0
251 || strcmp (result, "0x3p-1 33") == 0
252 || strcmp (result, "0x6p-2 33") == 0
253 || strcmp (result, "0xcp-3 33") == 0);
254 ASSERT (retval == strlen (result));
255 free (result);
256 }
257
258 { /* Rounding with precision 1. */
259 char *result;
260 int retval =
261 my_asprintf (&result, "%.1a %d", 1.51, 33, 44, 55);
262 ASSERT (result != NULL);
263 ASSERT (strcmp (result, "0x1.8p+0 33") == 0
264 || strcmp (result, "0x3.0p-1 33") == 0
265 || strcmp (result, "0x6.1p-2 33") == 0
266 || strcmp (result, "0xc.1p-3 33") == 0);
267 ASSERT (retval == strlen (result));
268 free (result);
269 }
270
271 { /* Rounding with precision 2. */
272 char *result;
273 int retval =
274 my_asprintf (&result, "%.2a %d", 1.51, 33, 44, 55);
275 ASSERT (result != NULL);
276 ASSERT (strcmp (result, "0x1.83p+0 33") == 0
277 || strcmp (result, "0x3.05p-1 33") == 0
278 || strcmp (result, "0x6.0ap-2 33") == 0
279 || strcmp (result, "0xc.14p-3 33") == 0);
280 ASSERT (retval == strlen (result));
281 free (result);
282 }
283
284 { /* Rounding with precision 3. */
285 char *result;
286 int retval =
287 my_asprintf (&result, "%.3a %d", 1.51, 33, 44, 55);
288 ASSERT (result != NULL);
289 ASSERT (strcmp (result, "0x1.829p+0 33") == 0
290 || strcmp (result, "0x3.052p-1 33") == 0
291 || strcmp (result, "0x6.0a4p-2 33") == 0
292 || strcmp (result, "0xc.148p-3 33") == 0);
293 ASSERT (retval == strlen (result));
294 free (result);
295 }
296
297 { /* Rounding can turn a ...FFF into a ...000. */
298 char *result;
299 int retval =
300 my_asprintf (&result, "%.3a %d", 1.49999, 33, 44, 55);
301 ASSERT (result != NULL);
302 ASSERT (strcmp (result, "0x1.800p+0 33") == 0
303 || strcmp (result, "0x3.000p-1 33") == 0
304 || strcmp (result, "0x6.000p-2 33") == 0
305 || strcmp (result, "0xc.000p-3 33") == 0);
306 ASSERT (retval == strlen (result));
307 free (result);
308 }
309
310 { /* Rounding can turn a ...FFF into a ...000.
311 This shows a Mac OS X 10.3.9 (Darwin 7.9) bug. */
312 char *result;
313 int retval =
314 my_asprintf (&result, "%.1a %d", 1.999, 33, 44, 55);
315 ASSERT (result != NULL);
316 ASSERT (strcmp (result, "0x1.0p+1 33") == 0
317 || strcmp (result, "0x2.0p+0 33") == 0
318 || strcmp (result, "0x4.0p-1 33") == 0
319 || strcmp (result, "0x8.0p-2 33") == 0);
320 ASSERT (retval == strlen (result));
321 free (result);
322 }
323
324 { /* Width. */
325 char *result;
326 int retval =
327 my_asprintf (&result, "%10a %d", 1.75, 33, 44, 55);
328 ASSERT (result != NULL);
329 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
330 || strcmp (result, " 0x3.8p-1 33") == 0
331 || strcmp (result, " 0x7p-2 33") == 0
332 || strcmp (result, " 0xep-3 33") == 0);
333 ASSERT (retval == strlen (result));
334 free (result);
335 }
336
337 { /* Small precision. */
338 char *result;
339 int retval =
340 my_asprintf (&result, "%.10a %d", 1.75, 33, 44, 55);
341 ASSERT (result != NULL);
342 ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
343 || strcmp (result, "0x3.8000000000p-1 33") == 0
344 || strcmp (result, "0x7.0000000000p-2 33") == 0
345 || strcmp (result, "0xe.0000000000p-3 33") == 0);
346 ASSERT (retval == strlen (result));
347 free (result);
348 }
349
350 { /* Large precision. */
351 char *result;
352 int retval =
353 my_asprintf (&result, "%.50a %d", 1.75, 33, 44, 55);
354 ASSERT (result != NULL);
355 ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
356 || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
357 || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
358 || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
359 ASSERT (retval == strlen (result));
360 free (result);
361 }
362
363 { /* FLAG_LEFT. */
364 char *result;
365 int retval =
366 my_asprintf (&result, "%-10a %d", 1.75, 33, 44, 55);
367 ASSERT (result != NULL);
368 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
369 || strcmp (result, "0x3.8p-1 33") == 0
370 || strcmp (result, "0x7p-2 33") == 0
371 || strcmp (result, "0xep-3 33") == 0);
372 ASSERT (retval == strlen (result));
373 free (result);
374 }
375
376 { /* FLAG_SHOWSIGN. */
377 char *result;
378 int retval =
379 my_asprintf (&result, "%+a %d", 1.75, 33, 44, 55);
380 ASSERT (result != NULL);
381 ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
382 || strcmp (result, "+0x3.8p-1 33") == 0
383 || strcmp (result, "+0x7p-2 33") == 0
384 || strcmp (result, "+0xep-3 33") == 0);
385 ASSERT (retval == strlen (result));
386 free (result);
387 }
388
389 { /* FLAG_SPACE. */
390 char *result;
391 int retval =
392 my_asprintf (&result, "% a %d", 1.75, 33, 44, 55);
393 ASSERT (result != NULL);
394 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
395 || strcmp (result, " 0x3.8p-1 33") == 0
396 || strcmp (result, " 0x7p-2 33") == 0
397 || strcmp (result, " 0xep-3 33") == 0);
398 ASSERT (retval == strlen (result));
399 free (result);
400 }
401
402 { /* FLAG_ALT. */
403 char *result;
404 int retval =
405 my_asprintf (&result, "%#a %d", 1.75, 33, 44, 55);
406 ASSERT (result != NULL);
407 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
408 || strcmp (result, "0x3.8p-1 33") == 0
409 || strcmp (result, "0x7.p-2 33") == 0
410 || strcmp (result, "0xe.p-3 33") == 0);
411 ASSERT (retval == strlen (result));
412 free (result);
413 }
414
415 { /* FLAG_ALT. */
416 char *result;
417 int retval =
418 my_asprintf (&result, "%#a %d", 1.0, 33, 44, 55);
419 ASSERT (result != NULL);
420 ASSERT (strcmp (result, "0x1.p+0 33") == 0
421 || strcmp (result, "0x2.p-1 33") == 0
422 || strcmp (result, "0x4.p-2 33") == 0
423 || strcmp (result, "0x8.p-3 33") == 0);
424 ASSERT (retval == strlen (result));
425 free (result);
426 }
427
428 { /* FLAG_ZERO with finite number. */
429 char *result;
430 int retval =
431 my_asprintf (&result, "%010a %d", 1.75, 33, 44, 55);
432 ASSERT (result != NULL);
433 ASSERT (strcmp (result, "0x001.cp+0 33") == 0
434 || strcmp (result, "0x003.8p-1 33") == 0
435 || strcmp (result, "0x00007p-2 33") == 0
436 || strcmp (result, "0x0000ep-3 33") == 0);
437 ASSERT (retval == strlen (result));
438 free (result);
439 }
440
441 { /* FLAG_ZERO with infinite number. */
442 char *result;
443 int retval =
444 my_asprintf (&result, "%010a %d", Infinityd (), 33, 44, 55);
445 ASSERT (result != NULL);
446 /* "0000000inf 33" is not a valid result; see
447 <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
448 ASSERT (strcmp (result, " inf 33") == 0);
449 ASSERT (retval == strlen (result));
450 free (result);
451 }
452
453 { /* FLAG_ZERO with NaN. */
454 char *result;
455 int retval =
456 my_asprintf (&result, "%050a %d", NaNd (), 33, 44, 55);
457 ASSERT (result != NULL);
458 /* "0000000nan 33" is not a valid result; see
459 <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
460 ASSERT (strlen (result) == 50 + 3
461 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
462 && strcmp (result + strlen (result) - 3, " 33") == 0);
463 ASSERT (retval == strlen (result));
464 free (result);
465 }
466
467 { /* A positive number. */
468 char *result;
469 int retval =
470 my_asprintf (&result, "%La %d", 3.1416015625L, 33, 44, 55);
471 ASSERT (result != NULL);
472 ASSERT (strcmp (result, "0x1.922p+1 33") == 0
473 || strcmp (result, "0x3.244p+0 33") == 0
474 || strcmp (result, "0x6.488p-1 33") == 0
475 || strcmp (result, "0xc.91p-2 33") == 0);
476 ASSERT (retval == strlen (result));
477 free (result);
478 }
479
480 { /* A negative number. */
481 char *result;
482 int retval =
483 my_asprintf (&result, "%LA %d", -3.1416015625L, 33, 44, 55);
484 ASSERT (result != NULL);
485 ASSERT (strcmp (result, "-0X1.922P+1 33") == 0
486 || strcmp (result, "-0X3.244P+0 33") == 0
487 || strcmp (result, "-0X6.488P-1 33") == 0
488 || strcmp (result, "-0XC.91P-2 33") == 0);
489 ASSERT (retval == strlen (result));
490 free (result);
491 }
492
493 { /* Positive zero. */
494 char *result;
495 int retval =
496 my_asprintf (&result, "%La %d", 0.0L, 33, 44, 55);
497 ASSERT (result != NULL);
498 ASSERT (strcmp (result, "0x0p+0 33") == 0);
499 ASSERT (retval == strlen (result));
500 free (result);
501 }
502
503 { /* Negative zero. */
504 char *result;
505 int retval =
506 my_asprintf (&result, "%La %d", minus_zerol, 33, 44, 55);
507 ASSERT (result != NULL);
508 if (have_minus_zero ())
509 ASSERT (strcmp (result, "-0x0p+0 33") == 0);
510 ASSERT (retval == strlen (result));
511 free (result);
512 }
513
514 { /* Positive infinity. */
515 char *result;
516 int retval =
517 my_asprintf (&result, "%La %d", Infinityl (), 33, 44, 55);
518 ASSERT (result != NULL);
519 ASSERT (strcmp (result, "inf 33") == 0);
520 ASSERT (retval == strlen (result));
521 free (result);
522 }
523
524 { /* Negative infinity. */
525 char *result;
526 int retval =
527 my_asprintf (&result, "%La %d", - Infinityl (), 33, 44, 55);
528 ASSERT (result != NULL);
529 ASSERT (strcmp (result, "-inf 33") == 0);
530 ASSERT (retval == strlen (result));
531 free (result);
532 }
533
534 { /* NaN. */
535 char *result;
536 int retval =
537 my_asprintf (&result, "%La %d", NaNl (), 33, 44, 55);
538 ASSERT (result != NULL);
539 ASSERT (strlen (result) >= 3 + 3
540 && strisnan (result, 0, strlen (result) - 3, 0)
541 && strcmp (result + strlen (result) - 3, " 33") == 0);
542 ASSERT (retval == strlen (result));
543 free (result);
544 }
545 #if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
546 { /* Quiet NaN. */
547 static union { unsigned int word[4]; long double value; } x =
548 { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
549 char *result;
550 int retval =
551 my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
552 ASSERT (result != NULL);
553 ASSERT (strlen (result) >= 3 + 3
554 && strisnan (result, 0, strlen (result) - 3, 0)
555 && strcmp (result + strlen (result) - 3, " 33") == 0);
556 ASSERT (retval == strlen (result));
557 free (result);
558 }
559 {
560 /* Signalling NaN. */
561 static union { unsigned int word[4]; long double value; } x =
562 { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
563 char *result;
564 int retval =
565 my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
566 ASSERT (result != NULL);
567 ASSERT (strlen (result) >= 3 + 3
568 && strisnan (result, 0, strlen (result) - 3, 0)
569 && strcmp (result + strlen (result) - 3, " 33") == 0);
570 ASSERT (retval == strlen (result));
571 free (result);
572 }
573 /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
574 Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
575 Intel IA-64 Architecture Software Developer's Manual, Volume 1:
576 Application Architecture.
577 Table 5-2 "Floating-Point Register Encodings"
578 Figure 5-6 "Memory to Floating-Point Register Data Translation"
579 */
580 { /* Pseudo-NaN. */
581 static union { unsigned int word[4]; long double value; } x =
582 { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
583 char *result;
584 int retval =
585 my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
586 ASSERT (result != NULL);
587 ASSERT (strlen (result) >= 3 + 3
588 && strisnan (result, 0, strlen (result) - 3, 0)
589 && strcmp (result + strlen (result) - 3, " 33") == 0);
590 ASSERT (retval == strlen (result));
591 free (result);
592 }
593 { /* Pseudo-Infinity. */
594 static union { unsigned int word[4]; long double value; } x =
595 { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
596 char *result;
597 int retval =
598 my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
599 ASSERT (result != NULL);
600 ASSERT (strlen (result) >= 3 + 3
601 && strisnan (result, 0, strlen (result) - 3, 0)
602 && strcmp (result + strlen (result) - 3, " 33") == 0);
603 ASSERT (retval == strlen (result));
604 free (result);
605 }
606 { /* Pseudo-Zero. */
607 static union { unsigned int word[4]; long double value; } x =
608 { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
609 char *result;
610 int retval =
611 my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
612 ASSERT (result != NULL);
613 ASSERT (strlen (result) >= 3 + 3
614 && strisnan (result, 0, strlen (result) - 3, 0)
615 && strcmp (result + strlen (result) - 3, " 33") == 0);
616 ASSERT (retval == strlen (result));
617 free (result);
618 }
619 { /* Unnormalized number. */
620 static union { unsigned int word[4]; long double value; } x =
621 { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
622 char *result;
623 int retval =
624 my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
625 ASSERT (result != NULL);
626 ASSERT (strlen (result) >= 3 + 3
627 && strisnan (result, 0, strlen (result) - 3, 0)
628 && strcmp (result + strlen (result) - 3, " 33") == 0);
629 ASSERT (retval == strlen (result));
630 free (result);
631 }
632 { /* Pseudo-Denormal. */
633 static union { unsigned int word[4]; long double value; } x =
634 { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
635 char *result;
636 int retval =
637 my_asprintf (&result, "%La %d", x.value, 33, 44, 55);
638 ASSERT (result != NULL);
639 ASSERT (strlen (result) >= 3 + 3
640 && strisnan (result, 0, strlen (result) - 3, 0)
641 && strcmp (result + strlen (result) - 3, " 33") == 0);
642 ASSERT (retval == strlen (result));
643 free (result);
644 }
645 #endif
646
647 { /* Rounding near the decimal point. */
648 char *result;
649 int retval =
650 my_asprintf (&result, "%.0La %d", 1.5L, 33, 44, 55);
651 ASSERT (result != NULL);
652 ASSERT (strcmp (result, "0x2p+0 33") == 0
653 || strcmp (result, "0x3p-1 33") == 0
654 || strcmp (result, "0x6p-2 33") == 0
655 || strcmp (result, "0xcp-3 33") == 0);
656 ASSERT (retval == strlen (result));
657 free (result);
658 }
659
660 { /* Rounding with precision 0. */
661 char *result;
662 int retval =
663 my_asprintf (&result, "%.0La %d", 1.51L, 33, 44, 55);
664 ASSERT (result != NULL);
665 ASSERT (strcmp (result, "0x2p+0 33") == 0
666 || strcmp (result, "0x3p-1 33") == 0
667 || strcmp (result, "0x6p-2 33") == 0
668 || strcmp (result, "0xcp-3 33") == 0);
669 ASSERT (retval == strlen (result));
670 free (result);
671 }
672
673 { /* Rounding with precision 1. */
674 char *result;
675 int retval =
676 my_asprintf (&result, "%.1La %d", 1.51L, 33, 44, 55);
677 ASSERT (result != NULL);
678 ASSERT (strcmp (result, "0x1.8p+0 33") == 0
679 || strcmp (result, "0x3.0p-1 33") == 0
680 || strcmp (result, "0x6.1p-2 33") == 0
681 || strcmp (result, "0xc.1p-3 33") == 0);
682 ASSERT (retval == strlen (result));
683 free (result);
684 }
685
686 { /* Rounding with precision 2. */
687 char *result;
688 int retval =
689 my_asprintf (&result, "%.2La %d", 1.51L, 33, 44, 55);
690 ASSERT (result != NULL);
691 ASSERT (strcmp (result, "0x1.83p+0 33") == 0
692 || strcmp (result, "0x3.05p-1 33") == 0
693 || strcmp (result, "0x6.0ap-2 33") == 0
694 || strcmp (result, "0xc.14p-3 33") == 0);
695 ASSERT (retval == strlen (result));
696 free (result);
697 }
698
699 { /* Rounding with precision 3. */
700 char *result;
701 int retval =
702 my_asprintf (&result, "%.3La %d", 1.51L, 33, 44, 55);
703 ASSERT (result != NULL);
704 ASSERT (strcmp (result, "0x1.829p+0 33") == 0
705 || strcmp (result, "0x3.052p-1 33") == 0
706 || strcmp (result, "0x6.0a4p-2 33") == 0
707 || strcmp (result, "0xc.148p-3 33") == 0);
708 ASSERT (retval == strlen (result));
709 free (result);
710 }
711
712 { /* Rounding can turn a ...FFF into a ...000. */
713 char *result;
714 int retval =
715 my_asprintf (&result, "%.3La %d", 1.49999L, 33, 44, 55);
716 ASSERT (result != NULL);
717 ASSERT (strcmp (result, "0x1.800p+0 33") == 0
718 || strcmp (result, "0x3.000p-1 33") == 0
719 || strcmp (result, "0x6.000p-2 33") == 0
720 || strcmp (result, "0xc.000p-3 33") == 0);
721 ASSERT (retval == strlen (result));
722 free (result);
723 }
724
725 { /* Rounding can turn a ...FFF into a ...000.
726 This shows a Mac OS X 10.3.9 (Darwin 7.9) bug and a
727 glibc 2.4 bug <http://sourceware.org/bugzilla/show_bug.cgi?id=2908>. */
728 char *result;
729 int retval =
730 my_asprintf (&result, "%.1La %d", 1.999L, 33, 44, 55);
731 ASSERT (result != NULL);
732 ASSERT (strcmp (result, "0x1.0p+1 33") == 0
733 || strcmp (result, "0x2.0p+0 33") == 0
734 || strcmp (result, "0x4.0p-1 33") == 0
735 || strcmp (result, "0x8.0p-2 33") == 0);
736 ASSERT (retval == strlen (result));
737 free (result);
738 }
739
740 { /* Width. */
741 char *result;
742 int retval =
743 my_asprintf (&result, "%10La %d", 1.75L, 33, 44, 55);
744 ASSERT (result != NULL);
745 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
746 || strcmp (result, " 0x3.8p-1 33") == 0
747 || strcmp (result, " 0x7p-2 33") == 0
748 || strcmp (result, " 0xep-3 33") == 0);
749 ASSERT (retval == strlen (result));
750 free (result);
751 }
752
753 { /* Small precision. */
754 char *result;
755 int retval =
756 my_asprintf (&result, "%.10La %d", 1.75L, 33, 44, 55);
757 ASSERT (result != NULL);
758 ASSERT (strcmp (result, "0x1.c000000000p+0 33") == 0
759 || strcmp (result, "0x3.8000000000p-1 33") == 0
760 || strcmp (result, "0x7.0000000000p-2 33") == 0
761 || strcmp (result, "0xe.0000000000p-3 33") == 0);
762 ASSERT (retval == strlen (result));
763 free (result);
764 }
765
766 { /* Large precision. */
767 char *result;
768 int retval =
769 my_asprintf (&result, "%.50La %d", 1.75L, 33, 44, 55);
770 ASSERT (result != NULL);
771 ASSERT (strcmp (result, "0x1.c0000000000000000000000000000000000000000000000000p+0 33") == 0
772 || strcmp (result, "0x3.80000000000000000000000000000000000000000000000000p-1 33") == 0
773 || strcmp (result, "0x7.00000000000000000000000000000000000000000000000000p-2 33") == 0
774 || strcmp (result, "0xe.00000000000000000000000000000000000000000000000000p-3 33") == 0);
775 ASSERT (retval == strlen (result));
776 free (result);
777 }
778
779 { /* FLAG_LEFT. */
780 char *result;
781 int retval =
782 my_asprintf (&result, "%-10La %d", 1.75L, 33, 44, 55);
783 ASSERT (result != NULL);
784 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
785 || strcmp (result, "0x3.8p-1 33") == 0
786 || strcmp (result, "0x7p-2 33") == 0
787 || strcmp (result, "0xep-3 33") == 0);
788 ASSERT (retval == strlen (result));
789 free (result);
790 }
791
792 { /* FLAG_SHOWSIGN. */
793 char *result;
794 int retval =
795 my_asprintf (&result, "%+La %d", 1.75L, 33, 44, 55);
796 ASSERT (result != NULL);
797 ASSERT (strcmp (result, "+0x1.cp+0 33") == 0
798 || strcmp (result, "+0x3.8p-1 33") == 0
799 || strcmp (result, "+0x7p-2 33") == 0
800 || strcmp (result, "+0xep-3 33") == 0);
801 ASSERT (retval == strlen (result));
802 free (result);
803 }
804
805 { /* FLAG_SPACE. */
806 char *result;
807 int retval =
808 my_asprintf (&result, "% La %d", 1.75L, 33, 44, 55);
809 ASSERT (result != NULL);
810 ASSERT (strcmp (result, " 0x1.cp+0 33") == 0
811 || strcmp (result, " 0x3.8p-1 33") == 0
812 || strcmp (result, " 0x7p-2 33") == 0
813 || strcmp (result, " 0xep-3 33") == 0);
814 ASSERT (retval == strlen (result));
815 free (result);
816 }
817
818 { /* FLAG_ALT. */
819 char *result;
820 int retval =
821 my_asprintf (&result, "%#La %d", 1.75L, 33, 44, 55);
822 ASSERT (result != NULL);
823 ASSERT (strcmp (result, "0x1.cp+0 33") == 0
824 || strcmp (result, "0x3.8p-1 33") == 0
825 || strcmp (result, "0x7.p-2 33") == 0
826 || strcmp (result, "0xe.p-3 33") == 0);
827 ASSERT (retval == strlen (result));
828 free (result);
829 }
830
831 { /* FLAG_ALT. */
832 char *result;
833 int retval =
834 my_asprintf (&result, "%#La %d", 1.0L, 33, 44, 55);
835 ASSERT (result != NULL);
836 ASSERT (strcmp (result, "0x1.p+0 33") == 0
837 || strcmp (result, "0x2.p-1 33") == 0
838 || strcmp (result, "0x4.p-2 33") == 0
839 || strcmp (result, "0x8.p-3 33") == 0);
840 ASSERT (retval == strlen (result));
841 free (result);
842 }
843
844 { /* FLAG_ZERO with finite number. */
845 char *result;
846 int retval =
847 my_asprintf (&result, "%010La %d", 1.75L, 33, 44, 55);
848 ASSERT (result != NULL);
849 ASSERT (strcmp (result, "0x001.cp+0 33") == 0
850 || strcmp (result, "0x003.8p-1 33") == 0
851 || strcmp (result, "0x00007p-2 33") == 0
852 || strcmp (result, "0x0000ep-3 33") == 0);
853 ASSERT (retval == strlen (result));
854 free (result);
855 }
856
857 { /* FLAG_ZERO with infinite number. */
858 char *result;
859 int retval =
860 my_asprintf (&result, "%010La %d", Infinityl (), 33, 44, 55);
861 ASSERT (result != NULL);
862 /* "0000000inf 33" is not a valid result; see
863 <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
864 ASSERT (strcmp (result, " inf 33") == 0);
865 ASSERT (retval == strlen (result));
866 free (result);
867 }
868
869 { /* FLAG_ZERO with NaN. */
870 char *result;
871 int retval =
872 my_asprintf (&result, "%050La %d", NaNl (), 33, 44, 55);
873 ASSERT (result != NULL);
874 /* "0000000nan 33" is not a valid result; see
875 <http://lists.gnu.org/archive/html/bug-gnulib/2007-04/msg00107.html> */
876 ASSERT (strlen (result) == 50 + 3
877 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
878 && strcmp (result + strlen (result) - 3, " 33") == 0);
879 ASSERT (retval == strlen (result));
880 free (result);
881 }
882
883 /* Test the support of the %f format directive. */
884
885 { /* A positive number. */
886 char *result;
887 int retval =
888 my_asprintf (&result, "%f %d", 12.75, 33, 44, 55);
889 ASSERT (result != NULL);
890 ASSERT (strcmp (result, "12.750000 33") == 0);
891 ASSERT (retval == strlen (result));
892 free (result);
893 }
894
895 { /* A larger positive number. */
896 char *result;
897 int retval =
898 my_asprintf (&result, "%f %d", 1234567.0, 33, 44, 55);
899 ASSERT (result != NULL);
900 ASSERT (strcmp (result, "1234567.000000 33") == 0);
901 ASSERT (retval == strlen (result));
902 free (result);
903 }
904
905 { /* Small and large positive numbers. */
906 static struct { double value; const char *string; } data[] =
907 {
908 { 1.234321234321234e-37, "0.000000" },
909 { 1.234321234321234e-36, "0.000000" },
910 { 1.234321234321234e-35, "0.000000" },
911 { 1.234321234321234e-34, "0.000000" },
912 { 1.234321234321234e-33, "0.000000" },
913 { 1.234321234321234e-32, "0.000000" },
914 { 1.234321234321234e-31, "0.000000" },
915 { 1.234321234321234e-30, "0.000000" },
916 { 1.234321234321234e-29, "0.000000" },
917 { 1.234321234321234e-28, "0.000000" },
918 { 1.234321234321234e-27, "0.000000" },
919 { 1.234321234321234e-26, "0.000000" },
920 { 1.234321234321234e-25, "0.000000" },
921 { 1.234321234321234e-24, "0.000000" },
922 { 1.234321234321234e-23, "0.000000" },
923 { 1.234321234321234e-22, "0.000000" },
924 { 1.234321234321234e-21, "0.000000" },
925 { 1.234321234321234e-20, "0.000000" },
926 { 1.234321234321234e-19, "0.000000" },
927 { 1.234321234321234e-18, "0.000000" },
928 { 1.234321234321234e-17, "0.000000" },
929 { 1.234321234321234e-16, "0.000000" },
930 { 1.234321234321234e-15, "0.000000" },
931 { 1.234321234321234e-14, "0.000000" },
932 { 1.234321234321234e-13, "0.000000" },
933 { 1.234321234321234e-12, "0.000000" },
934 { 1.234321234321234e-11, "0.000000" },
935 { 1.234321234321234e-10, "0.000000" },
936 { 1.234321234321234e-9, "0.000000" },
937 { 1.234321234321234e-8, "0.000000" },
938 { 1.234321234321234e-7, "0.000000" },
939 { 1.234321234321234e-6, "0.000001" },
940 { 1.234321234321234e-5, "0.000012" },
941 { 1.234321234321234e-4, "0.000123" },
942 { 1.234321234321234e-3, "0.001234" },
943 { 1.234321234321234e-2, "0.012343" },
944 { 1.234321234321234e-1, "0.123432" },
945 { 1.234321234321234, "1.234321" },
946 { 1.234321234321234e1, "12.343212" },
947 { 1.234321234321234e2, "123.432123" },
948 { 1.234321234321234e3, "1234.321234" },
949 { 1.234321234321234e4, "12343.212343" },
950 { 1.234321234321234e5, "123432.123432" },
951 { 1.234321234321234e6, "1234321.234321" },
952 { 1.234321234321234e7, "12343212.343212" },
953 { 1.234321234321234e8, "123432123.432123" },
954 { 1.234321234321234e9, "1234321234.321234" },
955 { 1.234321234321234e10, "12343212343.2123**" },
956 { 1.234321234321234e11, "123432123432.123***" },
957 { 1.234321234321234e12, "1234321234321.23****" },
958 { 1.234321234321234e13, "12343212343212.3*****" },
959 { 1.234321234321234e14, "123432123432123.******" },
960 { 1.234321234321234e15, "1234321234321234.000000" },
961 { 1.234321234321234e16, "123432123432123**.000000" },
962 { 1.234321234321234e17, "123432123432123***.000000" },
963 { 1.234321234321234e18, "123432123432123****.000000" },
964 { 1.234321234321234e19, "123432123432123*****.000000" },
965 { 1.234321234321234e20, "123432123432123******.000000" },
966 { 1.234321234321234e21, "123432123432123*******.000000" },
967 { 1.234321234321234e22, "123432123432123********.000000" },
968 { 1.234321234321234e23, "123432123432123*********.000000" },
969 { 1.234321234321234e24, "123432123432123**********.000000" },
970 { 1.234321234321234e25, "123432123432123***********.000000" },
971 { 1.234321234321234e26, "123432123432123************.000000" },
972 { 1.234321234321234e27, "123432123432123*************.000000" },
973 { 1.234321234321234e28, "123432123432123**************.000000" },
974 { 1.234321234321234e29, "123432123432123***************.000000" },
975 { 1.234321234321234e30, "123432123432123****************.000000" },
976 { 1.234321234321234e31, "123432123432123*****************.000000" },
977 { 1.234321234321234e32, "123432123432123******************.000000" },
978 { 1.234321234321234e33, "123432123432123*******************.000000" },
979 { 1.234321234321234e34, "123432123432123********************.000000" },
980 { 1.234321234321234e35, "123432123432123*********************.000000" },
981 { 1.234321234321234e36, "123432123432123**********************.000000" }
982 };
983 size_t k;
984 for (k = 0; k < SIZEOF (data); k++)
985 {
986 char *result;
987 int retval =
988 my_asprintf (&result, "%f", data[k].value);
989 ASSERT (result != NULL);
990 ASSERT (strmatch (data[k].string, result));
991 ASSERT (retval == strlen (result));
992 free (result);
993 }
994 }
995
996 { /* A negative number. */
997 char *result;
998 int retval =
999 my_asprintf (&result, "%f %d", -0.03125, 33, 44, 55);
1000 ASSERT (result != NULL);
1001 ASSERT (strcmp (result, "-0.031250 33") == 0);
1002 ASSERT (retval == strlen (result));
1003 free (result);
1004 }
1005
1006 { /* Positive zero. */
1007 char *result;
1008 int retval =
1009 my_asprintf (&result, "%f %d", 0.0, 33, 44, 55);
1010 ASSERT (result != NULL);
1011 ASSERT (strcmp (result, "0.000000 33") == 0);
1012 ASSERT (retval == strlen (result));
1013 free (result);
1014 }
1015
1016 { /* Negative zero. */
1017 char *result;
1018 int retval =
1019 my_asprintf (&result, "%f %d", minus_zerod, 33, 44, 55);
1020 ASSERT (result != NULL);
1021 if (have_minus_zero ())
1022 ASSERT (strcmp (result, "-0.000000 33") == 0);
1023 ASSERT (retval == strlen (result));
1024 free (result);
1025 }
1026
1027 { /* Positive infinity. */
1028 char *result;
1029 int retval =
1030 my_asprintf (&result, "%f %d", Infinityd (), 33, 44, 55);
1031 ASSERT (result != NULL);
1032 ASSERT (strcmp (result, "inf 33") == 0
1033 || strcmp (result, "infinity 33") == 0);
1034 ASSERT (retval == strlen (result));
1035 free (result);
1036 }
1037
1038 { /* Negative infinity. */
1039 char *result;
1040 int retval =
1041 my_asprintf (&result, "%f %d", - Infinityd (), 33, 44, 55);
1042 ASSERT (result != NULL);
1043 ASSERT (strcmp (result, "-inf 33") == 0
1044 || strcmp (result, "-infinity 33") == 0);
1045 ASSERT (retval == strlen (result));
1046 free (result);
1047 }
1048
1049 { /* NaN. */
1050 char *result;
1051 int retval =
1052 my_asprintf (&result, "%f %d", NaNd (), 33, 44, 55);
1053 ASSERT (result != NULL);
1054 ASSERT (strlen (result) >= 3 + 3
1055 && strisnan (result, 0, strlen (result) - 3, 0)
1056 && strcmp (result + strlen (result) - 3, " 33") == 0);
1057 ASSERT (retval == strlen (result));
1058 free (result);
1059 }
1060
1061 { /* Width. */
1062 char *result;
1063 int retval =
1064 my_asprintf (&result, "%10f %d", 1.75, 33, 44, 55);
1065 ASSERT (result != NULL);
1066 ASSERT (strcmp (result, " 1.750000 33") == 0);
1067 ASSERT (retval == strlen (result));
1068 free (result);
1069 }
1070
1071 { /* FLAG_LEFT. */
1072 char *result;
1073 int retval =
1074 my_asprintf (&result, "%-10f %d", 1.75, 33, 44, 55);
1075 ASSERT (result != NULL);
1076 ASSERT (strcmp (result, "1.750000 33") == 0);
1077 ASSERT (retval == strlen (result));
1078 free (result);
1079 }
1080
1081 { /* FLAG_SHOWSIGN. */
1082 char *result;
1083 int retval =
1084 my_asprintf (&result, "%+f %d", 1.75, 33, 44, 55);
1085 ASSERT (result != NULL);
1086 ASSERT (strcmp (result, "+1.750000 33") == 0);
1087 ASSERT (retval == strlen (result));
1088 free (result);
1089 }
1090
1091 { /* FLAG_SPACE. */
1092 char *result;
1093 int retval =
1094 my_asprintf (&result, "% f %d", 1.75, 33, 44, 55);
1095 ASSERT (result != NULL);
1096 ASSERT (strcmp (result, " 1.750000 33") == 0);
1097 ASSERT (retval == strlen (result));
1098 free (result);
1099 }
1100
1101 { /* FLAG_ALT. */
1102 char *result;
1103 int retval =
1104 my_asprintf (&result, "%#f %d", 1.75, 33, 44, 55);
1105 ASSERT (result != NULL);
1106 ASSERT (strcmp (result, "1.750000 33") == 0);
1107 ASSERT (retval == strlen (result));
1108 free (result);
1109 }
1110
1111 { /* FLAG_ALT. */
1112 char *result;
1113 int retval =
1114 my_asprintf (&result, "%#.f %d", 1.75, 33, 44, 55);
1115 ASSERT (result != NULL);
1116 ASSERT (strcmp (result, "2. 33") == 0);
1117 ASSERT (retval == strlen (result));
1118 free (result);
1119 }
1120
1121 { /* FLAG_ZERO with finite number. */
1122 char *result;
1123 int retval =
1124 my_asprintf (&result, "%015f %d", 1234.0, 33, 44, 55);
1125 ASSERT (result != NULL);
1126 ASSERT (strcmp (result, "00001234.000000 33") == 0);
1127 ASSERT (retval == strlen (result));
1128 free (result);
1129 }
1130
1131 { /* FLAG_ZERO with infinite number. */
1132 char *result;
1133 int retval =
1134 my_asprintf (&result, "%015f %d", - Infinityd (), 33, 44, 55);
1135 ASSERT (result != NULL);
1136 ASSERT (strcmp (result, " -inf 33") == 0
1137 || strcmp (result, " -infinity 33") == 0);
1138 ASSERT (retval == strlen (result));
1139 free (result);
1140 }
1141
1142 { /* FLAG_ZERO with NaN. */
1143 char *result;
1144 int retval =
1145 my_asprintf (&result, "%050f %d", NaNd (), 33, 44, 55);
1146 ASSERT (result != NULL);
1147 ASSERT (strlen (result) == 50 + 3
1148 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
1149 && strcmp (result + strlen (result) - 3, " 33") == 0);
1150 ASSERT (retval == strlen (result));
1151 free (result);
1152 }
1153
1154 { /* Precision. */
1155 char *result;
1156 int retval =
1157 my_asprintf (&result, "%.f %d", 1234.0, 33, 44, 55);
1158 ASSERT (result != NULL);
1159 ASSERT (strcmp (result, "1234 33") == 0);
1160 ASSERT (retval == strlen (result));
1161 free (result);
1162 }
1163
1164 { /* Precision with no rounding. */
1165 char *result;
1166 int retval =
1167 my_asprintf (&result, "%.2f %d", 999.951, 33, 44, 55);
1168 ASSERT (result != NULL);
1169 ASSERT (strcmp (result, "999.95 33") == 0);
1170 ASSERT (retval == strlen (result));
1171 free (result);
1172 }
1173
1174 { /* Precision with rounding. */
1175 char *result;
1176 int retval =
1177 my_asprintf (&result, "%.2f %d", 999.996, 33, 44, 55);
1178 ASSERT (result != NULL);
1179 ASSERT (strcmp (result, "1000.00 33") == 0);
1180 ASSERT (retval == strlen (result));
1181 free (result);
1182 }
1183
1184 { /* A positive number. */
1185 char *result;
1186 int retval =
1187 my_asprintf (&result, "%Lf %d", 12.75L, 33, 44, 55);
1188 ASSERT (result != NULL);
1189 ASSERT (strcmp (result, "12.750000 33") == 0);
1190 ASSERT (retval == strlen (result));
1191 free (result);
1192 }
1193
1194 { /* A larger positive number. */
1195 char *result;
1196 int retval =
1197 my_asprintf (&result, "%Lf %d", 1234567.0L, 33, 44, 55);
1198 ASSERT (result != NULL);
1199 ASSERT (strcmp (result, "1234567.000000 33") == 0);
1200 ASSERT (retval == strlen (result));
1201 free (result);
1202 }
1203
1204 { /* Small and large positive numbers. */
1205 static struct { long double value; const char *string; } data[] =
1206 {
1207 { 1.234321234321234e-37L, "0.000000" },
1208 { 1.234321234321234e-36L, "0.000000" },
1209 { 1.234321234321234e-35L, "0.000000" },
1210 { 1.234321234321234e-34L, "0.000000" },
1211 { 1.234321234321234e-33L, "0.000000" },
1212 { 1.234321234321234e-32L, "0.000000" },
1213 { 1.234321234321234e-31L, "0.000000" },
1214 { 1.234321234321234e-30L, "0.000000" },
1215 { 1.234321234321234e-29L, "0.000000" },
1216 { 1.234321234321234e-28L, "0.000000" },
1217 { 1.234321234321234e-27L, "0.000000" },
1218 { 1.234321234321234e-26L, "0.000000" },
1219 { 1.234321234321234e-25L, "0.000000" },
1220 { 1.234321234321234e-24L, "0.000000" },
1221 { 1.234321234321234e-23L, "0.000000" },
1222 { 1.234321234321234e-22L, "0.000000" },
1223 { 1.234321234321234e-21L, "0.000000" },
1224 { 1.234321234321234e-20L, "0.000000" },
1225 { 1.234321234321234e-19L, "0.000000" },
1226 { 1.234321234321234e-18L, "0.000000" },
1227 { 1.234321234321234e-17L, "0.000000" },
1228 { 1.234321234321234e-16L, "0.000000" },
1229 { 1.234321234321234e-15L, "0.000000" },
1230 { 1.234321234321234e-14L, "0.000000" },
1231 { 1.234321234321234e-13L, "0.000000" },
1232 { 1.234321234321234e-12L, "0.000000" },
1233 { 1.234321234321234e-11L, "0.000000" },
1234 { 1.234321234321234e-10L, "0.000000" },
1235 { 1.234321234321234e-9L, "0.000000" },
1236 { 1.234321234321234e-8L, "0.000000" },
1237 { 1.234321234321234e-7L, "0.000000" },
1238 { 1.234321234321234e-6L, "0.000001" },
1239 { 1.234321234321234e-5L, "0.000012" },
1240 { 1.234321234321234e-4L, "0.000123" },
1241 { 1.234321234321234e-3L, "0.001234" },
1242 { 1.234321234321234e-2L, "0.012343" },
1243 { 1.234321234321234e-1L, "0.123432" },
1244 { 1.234321234321234L, "1.234321" },
1245 { 1.234321234321234e1L, "12.343212" },
1246 { 1.234321234321234e2L, "123.432123" },
1247 { 1.234321234321234e3L, "1234.321234" },
1248 { 1.234321234321234e4L, "12343.212343" },
1249 { 1.234321234321234e5L, "123432.123432" },
1250 { 1.234321234321234e6L, "1234321.234321" },
1251 { 1.234321234321234e7L, "12343212.343212" },
1252 { 1.234321234321234e8L, "123432123.432123" },
1253 { 1.234321234321234e9L, "1234321234.321234" },
1254 { 1.234321234321234e10L, "12343212343.2123**" },
1255 { 1.234321234321234e11L, "123432123432.123***" },
1256 { 1.234321234321234e12L, "1234321234321.23****" },
1257 { 1.234321234321234e13L, "12343212343212.3*****" },
1258 { 1.234321234321234e14L, "123432123432123.******" },
1259 { 1.234321234321234e15L, "1234321234321234.000000" },
1260 { 1.234321234321234e16L, "123432123432123**.000000" },
1261 { 1.234321234321234e17L, "123432123432123***.000000" },
1262 { 1.234321234321234e18L, "123432123432123****.000000" },
1263 { 1.234321234321234e19L, "123432123432123*****.000000" },
1264 { 1.234321234321234e20L, "123432123432123******.000000" },
1265 { 1.234321234321234e21L, "123432123432123*******.000000" },
1266 { 1.234321234321234e22L, "123432123432123********.000000" },
1267 { 1.234321234321234e23L, "123432123432123*********.000000" },
1268 { 1.234321234321234e24L, "123432123432123**********.000000" },
1269 { 1.234321234321234e25L, "123432123432123***********.000000" },
1270 { 1.234321234321234e26L, "123432123432123************.000000" },
1271 { 1.234321234321234e27L, "123432123432123*************.000000" },
1272 { 1.234321234321234e28L, "123432123432123**************.000000" },
1273 { 1.234321234321234e29L, "123432123432123***************.000000" },
1274 { 1.234321234321234e30L, "123432123432123****************.000000" },
1275 { 1.234321234321234e31L, "123432123432123*****************.000000" },
1276 { 1.234321234321234e32L, "123432123432123******************.000000" },
1277 { 1.234321234321234e33L, "123432123432123*******************.000000" },
1278 { 1.234321234321234e34L, "123432123432123********************.000000" },
1279 { 1.234321234321234e35L, "123432123432123*********************.000000" },
1280 { 1.234321234321234e36L, "123432123432123**********************.000000" }
1281 };
1282 size_t k;
1283 for (k = 0; k < SIZEOF (data); k++)
1284 {
1285 char *result;
1286 int retval =
1287 my_asprintf (&result, "%Lf", data[k].value);
1288 ASSERT (result != NULL);
1289 ASSERT (strmatch (data[k].string, result));
1290 ASSERT (retval == strlen (result));
1291 free (result);
1292 }
1293 }
1294
1295 { /* A negative number. */
1296 char *result;
1297 int retval =
1298 my_asprintf (&result, "%Lf %d", -0.03125L, 33, 44, 55);
1299 ASSERT (result != NULL);
1300 ASSERT (strcmp (result, "-0.031250 33") == 0);
1301 ASSERT (retval == strlen (result));
1302 free (result);
1303 }
1304
1305 { /* Positive zero. */
1306 char *result;
1307 int retval =
1308 my_asprintf (&result, "%Lf %d", 0.0L, 33, 44, 55);
1309 ASSERT (result != NULL);
1310 ASSERT (strcmp (result, "0.000000 33") == 0);
1311 ASSERT (retval == strlen (result));
1312 free (result);
1313 }
1314
1315 { /* Negative zero. */
1316 char *result;
1317 int retval =
1318 my_asprintf (&result, "%Lf %d", minus_zerol, 33, 44, 55);
1319 ASSERT (result != NULL);
1320 if (have_minus_zero ())
1321 ASSERT (strcmp (result, "-0.000000 33") == 0);
1322 ASSERT (retval == strlen (result));
1323 free (result);
1324 }
1325
1326 { /* Positive infinity. */
1327 char *result;
1328 int retval =
1329 my_asprintf (&result, "%Lf %d", Infinityl (), 33, 44, 55);
1330 ASSERT (result != NULL);
1331 ASSERT (strcmp (result, "inf 33") == 0
1332 || strcmp (result, "infinity 33") == 0);
1333 ASSERT (retval == strlen (result));
1334 free (result);
1335 }
1336
1337 { /* Negative infinity. */
1338 char *result;
1339 int retval =
1340 my_asprintf (&result, "%Lf %d", - Infinityl (), 33, 44, 55);
1341 ASSERT (result != NULL);
1342 ASSERT (strcmp (result, "-inf 33") == 0
1343 || strcmp (result, "-infinity 33") == 0);
1344 ASSERT (retval == strlen (result));
1345 free (result);
1346 }
1347
1348 { /* NaN. */
1349 char *result;
1350 int retval =
1351 my_asprintf (&result, "%Lf %d", NaNl (), 33, 44, 55);
1352 ASSERT (result != NULL);
1353 ASSERT (strlen (result) >= 3 + 3
1354 && strisnan (result, 0, strlen (result) - 3, 0)
1355 && strcmp (result + strlen (result) - 3, " 33") == 0);
1356 ASSERT (retval == strlen (result));
1357 free (result);
1358 }
1359 #if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
1360 { /* Quiet NaN. */
1361 static union { unsigned int word[4]; long double value; } x =
1362 { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
1363 char *result;
1364 int retval =
1365 my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
1366 ASSERT (result != NULL);
1367 ASSERT (strlen (result) >= 3 + 3
1368 && strisnan (result, 0, strlen (result) - 3, 0)
1369 && strcmp (result + strlen (result) - 3, " 33") == 0);
1370 ASSERT (retval == strlen (result));
1371 free (result);
1372 }
1373 {
1374 /* Signalling NaN. */
1375 static union { unsigned int word[4]; long double value; } x =
1376 { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
1377 char *result;
1378 int retval =
1379 my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
1380 ASSERT (result != NULL);
1381 ASSERT (strlen (result) >= 3 + 3
1382 && strisnan (result, 0, strlen (result) - 3, 0)
1383 && strcmp (result + strlen (result) - 3, " 33") == 0);
1384 ASSERT (retval == strlen (result));
1385 free (result);
1386 }
1387 /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
1388 Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
1389 Intel IA-64 Architecture Software Developer's Manual, Volume 1:
1390 Application Architecture.
1391 Table 5-2 "Floating-Point Register Encodings"
1392 Figure 5-6 "Memory to Floating-Point Register Data Translation"
1393 */
1394 { /* Pseudo-NaN. */
1395 static union { unsigned int word[4]; long double value; } x =
1396 { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
1397 char *result;
1398 int retval =
1399 my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
1400 ASSERT (result != NULL);
1401 ASSERT (strlen (result) >= 3 + 3
1402 && strisnan (result, 0, strlen (result) - 3, 0)
1403 && strcmp (result + strlen (result) - 3, " 33") == 0);
1404 ASSERT (retval == strlen (result));
1405 free (result);
1406 }
1407 { /* Pseudo-Infinity. */
1408 static union { unsigned int word[4]; long double value; } x =
1409 { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
1410 char *result;
1411 int retval =
1412 my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
1413 ASSERT (result != NULL);
1414 ASSERT (strlen (result) >= 3 + 3
1415 && strisnan (result, 0, strlen (result) - 3, 0)
1416 && strcmp (result + strlen (result) - 3, " 33") == 0);
1417 ASSERT (retval == strlen (result));
1418 free (result);
1419 }
1420 { /* Pseudo-Zero. */
1421 static union { unsigned int word[4]; long double value; } x =
1422 { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
1423 char *result;
1424 int retval =
1425 my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
1426 ASSERT (result != NULL);
1427 ASSERT (strlen (result) >= 3 + 3
1428 && strisnan (result, 0, strlen (result) - 3, 0)
1429 && strcmp (result + strlen (result) - 3, " 33") == 0);
1430 ASSERT (retval == strlen (result));
1431 free (result);
1432 }
1433 { /* Unnormalized number. */
1434 static union { unsigned int word[4]; long double value; } x =
1435 { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
1436 char *result;
1437 int retval =
1438 my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
1439 ASSERT (result != NULL);
1440 ASSERT (strlen (result) >= 3 + 3
1441 && strisnan (result, 0, strlen (result) - 3, 0)
1442 && strcmp (result + strlen (result) - 3, " 33") == 0);
1443 ASSERT (retval == strlen (result));
1444 free (result);
1445 }
1446 { /* Pseudo-Denormal. */
1447 static union { unsigned int word[4]; long double value; } x =
1448 { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
1449 char *result;
1450 int retval =
1451 my_asprintf (&result, "%Lf %d", x.value, 33, 44, 55);
1452 ASSERT (result != NULL);
1453 ASSERT (strlen (result) >= 3 + 3
1454 && strisnan (result, 0, strlen (result) - 3, 0)
1455 && strcmp (result + strlen (result) - 3, " 33") == 0);
1456 ASSERT (retval == strlen (result));
1457 free (result);
1458 }
1459 #endif
1460
1461 { /* Width. */
1462 char *result;
1463 int retval =
1464 my_asprintf (&result, "%10Lf %d", 1.75L, 33, 44, 55);
1465 ASSERT (result != NULL);
1466 ASSERT (strcmp (result, " 1.750000 33") == 0);
1467 ASSERT (retval == strlen (result));
1468 free (result);
1469 }
1470
1471 { /* FLAG_LEFT. */
1472 char *result;
1473 int retval =
1474 my_asprintf (&result, "%-10Lf %d", 1.75L, 33, 44, 55);
1475 ASSERT (result != NULL);
1476 ASSERT (strcmp (result, "1.750000 33") == 0);
1477 ASSERT (retval == strlen (result));
1478 free (result);
1479 }
1480
1481 { /* FLAG_SHOWSIGN. */
1482 char *result;
1483 int retval =
1484 my_asprintf (&result, "%+Lf %d", 1.75L, 33, 44, 55);
1485 ASSERT (result != NULL);
1486 ASSERT (strcmp (result, "+1.750000 33") == 0);
1487 ASSERT (retval == strlen (result));
1488 free (result);
1489 }
1490
1491 { /* FLAG_SPACE. */
1492 char *result;
1493 int retval =
1494 my_asprintf (&result, "% Lf %d", 1.75L, 33, 44, 55);
1495 ASSERT (result != NULL);
1496 ASSERT (strcmp (result, " 1.750000 33") == 0);
1497 ASSERT (retval == strlen (result));
1498 free (result);
1499 }
1500
1501 { /* FLAG_ALT. */
1502 char *result;
1503 int retval =
1504 my_asprintf (&result, "%#Lf %d", 1.75L, 33, 44, 55);
1505 ASSERT (result != NULL);
1506 ASSERT (strcmp (result, "1.750000 33") == 0);
1507 ASSERT (retval == strlen (result));
1508 free (result);
1509 }
1510
1511 { /* FLAG_ALT. */
1512 char *result;
1513 int retval =
1514 my_asprintf (&result, "%#.Lf %d", 1.75L, 33, 44, 55);
1515 ASSERT (result != NULL);
1516 ASSERT (strcmp (result, "2. 33") == 0);
1517 ASSERT (retval == strlen (result));
1518 free (result);
1519 }
1520
1521 { /* FLAG_ZERO with finite number. */
1522 char *result;
1523 int retval =
1524 my_asprintf (&result, "%015Lf %d", 1234.0L, 33, 44, 55);
1525 ASSERT (result != NULL);
1526 ASSERT (strcmp (result, "00001234.000000 33") == 0);
1527 ASSERT (retval == strlen (result));
1528 free (result);
1529 }
1530
1531 { /* FLAG_ZERO with infinite number. */
1532 char *result;
1533 int retval =
1534 my_asprintf (&result, "%015Lf %d", - Infinityl (), 33, 44, 55);
1535 ASSERT (result != NULL);
1536 ASSERT (strcmp (result, " -inf 33") == 0
1537 || strcmp (result, " -infinity 33") == 0);
1538 ASSERT (retval == strlen (result));
1539 free (result);
1540 }
1541
1542 { /* FLAG_ZERO with NaN. */
1543 char *result;
1544 int retval =
1545 my_asprintf (&result, "%050Lf %d", NaNl (), 33, 44, 55);
1546 ASSERT (result != NULL);
1547 ASSERT (strlen (result) == 50 + 3
1548 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
1549 && strcmp (result + strlen (result) - 3, " 33") == 0);
1550 ASSERT (retval == strlen (result));
1551 free (result);
1552 }
1553
1554 { /* Precision. */
1555 char *result;
1556 int retval =
1557 my_asprintf (&result, "%.Lf %d", 1234.0L, 33, 44, 55);
1558 ASSERT (result != NULL);
1559 ASSERT (strcmp (result, "1234 33") == 0);
1560 ASSERT (retval == strlen (result));
1561 free (result);
1562 }
1563
1564 { /* Precision with no rounding. */
1565 char *result;
1566 int retval =
1567 my_asprintf (&result, "%.2Lf %d", 999.951L, 33, 44, 55);
1568 ASSERT (result != NULL);
1569 ASSERT (strcmp (result, "999.95 33") == 0);
1570 ASSERT (retval == strlen (result));
1571 free (result);
1572 }
1573
1574 { /* Precision with rounding. */
1575 char *result;
1576 int retval =
1577 my_asprintf (&result, "%.2Lf %d", 999.996L, 33, 44, 55);
1578 ASSERT (result != NULL);
1579 ASSERT (strcmp (result, "1000.00 33") == 0);
1580 ASSERT (retval == strlen (result));
1581 free (result);
1582 }
1583
1584 /* Test the support of the %F format directive. */
1585
1586 { /* A positive number. */
1587 char *result;
1588 int retval =
1589 my_asprintf (&result, "%F %d", 12.75, 33, 44, 55);
1590 ASSERT (result != NULL);
1591 ASSERT (strcmp (result, "12.750000 33") == 0);
1592 ASSERT (retval == strlen (result));
1593 free (result);
1594 }
1595
1596 { /* A larger positive number. */
1597 char *result;
1598 int retval =
1599 my_asprintf (&result, "%F %d", 1234567.0, 33, 44, 55);
1600 ASSERT (result != NULL);
1601 ASSERT (strcmp (result, "1234567.000000 33") == 0);
1602 ASSERT (retval == strlen (result));
1603 free (result);
1604 }
1605
1606 { /* A negative number. */
1607 char *result;
1608 int retval =
1609 my_asprintf (&result, "%F %d", -0.03125, 33, 44, 55);
1610 ASSERT (result != NULL);
1611 ASSERT (strcmp (result, "-0.031250 33") == 0);
1612 ASSERT (retval == strlen (result));
1613 free (result);
1614 }
1615
1616 { /* Positive zero. */
1617 char *result;
1618 int retval =
1619 my_asprintf (&result, "%F %d", 0.0, 33, 44, 55);
1620 ASSERT (result != NULL);
1621 ASSERT (strcmp (result, "0.000000 33") == 0);
1622 ASSERT (retval == strlen (result));
1623 free (result);
1624 }
1625
1626 { /* Negative zero. */
1627 char *result;
1628 int retval =
1629 my_asprintf (&result, "%F %d", minus_zerod, 33, 44, 55);
1630 ASSERT (result != NULL);
1631 if (have_minus_zero ())
1632 ASSERT (strcmp (result, "-0.000000 33") == 0);
1633 ASSERT (retval == strlen (result));
1634 free (result);
1635 }
1636
1637 { /* Positive infinity. */
1638 char *result;
1639 int retval =
1640 my_asprintf (&result, "%F %d", Infinityd (), 33, 44, 55);
1641 ASSERT (result != NULL);
1642 ASSERT (strcmp (result, "INF 33") == 0
1643 || strcmp (result, "INFINITY 33") == 0);
1644 ASSERT (retval == strlen (result));
1645 free (result);
1646 }
1647
1648 { /* Negative infinity. */
1649 char *result;
1650 int retval =
1651 my_asprintf (&result, "%F %d", - Infinityd (), 33, 44, 55);
1652 ASSERT (result != NULL);
1653 ASSERT (strcmp (result, "-INF 33") == 0
1654 || strcmp (result, "-INFINITY 33") == 0);
1655 ASSERT (retval == strlen (result));
1656 free (result);
1657 }
1658
1659 { /* NaN. */
1660 char *result;
1661 int retval =
1662 my_asprintf (&result, "%F %d", NaNd (), 33, 44, 55);
1663 ASSERT (result != NULL);
1664 ASSERT (strlen (result) >= 3 + 3
1665 && strisnan (result, 0, strlen (result) - 3, 1)
1666 && strcmp (result + strlen (result) - 3, " 33") == 0);
1667 ASSERT (retval == strlen (result));
1668 free (result);
1669 }
1670
1671 { /* FLAG_ZERO. */
1672 char *result;
1673 int retval =
1674 my_asprintf (&result, "%015F %d", 1234.0, 33, 44, 55);
1675 ASSERT (result != NULL);
1676 ASSERT (strcmp (result, "00001234.000000 33") == 0);
1677 ASSERT (retval == strlen (result));
1678 free (result);
1679 }
1680
1681 { /* FLAG_ZERO with infinite number. */
1682 char *result;
1683 int retval =
1684 my_asprintf (&result, "%015F %d", - Infinityd (), 33, 44, 55);
1685 ASSERT (result != NULL);
1686 ASSERT (strcmp (result, " -INF 33") == 0
1687 || strcmp (result, " -INFINITY 33") == 0);
1688 ASSERT (retval == strlen (result));
1689 free (result);
1690 }
1691
1692 { /* Precision. */
1693 char *result;
1694 int retval =
1695 my_asprintf (&result, "%.F %d", 1234.0, 33, 44, 55);
1696 ASSERT (result != NULL);
1697 ASSERT (strcmp (result, "1234 33") == 0);
1698 ASSERT (retval == strlen (result));
1699 free (result);
1700 }
1701
1702 { /* Precision with no rounding. */
1703 char *result;
1704 int retval =
1705 my_asprintf (&result, "%.2F %d", 999.951, 33, 44, 55);
1706 ASSERT (result != NULL);
1707 ASSERT (strcmp (result, "999.95 33") == 0);
1708 ASSERT (retval == strlen (result));
1709 free (result);
1710 }
1711
1712 { /* Precision with rounding. */
1713 char *result;
1714 int retval =
1715 my_asprintf (&result, "%.2F %d", 999.996, 33, 44, 55);
1716 ASSERT (result != NULL);
1717 ASSERT (strcmp (result, "1000.00 33") == 0);
1718 ASSERT (retval == strlen (result));
1719 free (result);
1720 }
1721
1722 { /* A positive number. */
1723 char *result;
1724 int retval =
1725 my_asprintf (&result, "%LF %d", 12.75L, 33, 44, 55);
1726 ASSERT (result != NULL);
1727 ASSERT (strcmp (result, "12.750000 33") == 0);
1728 ASSERT (retval == strlen (result));
1729 free (result);
1730 }
1731
1732 { /* A larger positive number. */
1733 char *result;
1734 int retval =
1735 my_asprintf (&result, "%LF %d", 1234567.0L, 33, 44, 55);
1736 ASSERT (result != NULL);
1737 ASSERT (strcmp (result, "1234567.000000 33") == 0);
1738 ASSERT (retval == strlen (result));
1739 free (result);
1740 }
1741
1742 { /* A negative number. */
1743 char *result;
1744 int retval =
1745 my_asprintf (&result, "%LF %d", -0.03125L, 33, 44, 55);
1746 ASSERT (result != NULL);
1747 ASSERT (strcmp (result, "-0.031250 33") == 0);
1748 ASSERT (retval == strlen (result));
1749 free (result);
1750 }
1751
1752 { /* Positive zero. */
1753 char *result;
1754 int retval =
1755 my_asprintf (&result, "%LF %d", 0.0L, 33, 44, 55);
1756 ASSERT (result != NULL);
1757 ASSERT (strcmp (result, "0.000000 33") == 0);
1758 ASSERT (retval == strlen (result));
1759 free (result);
1760 }
1761
1762 { /* Negative zero. */
1763 char *result;
1764 int retval =
1765 my_asprintf (&result, "%LF %d", minus_zerol, 33, 44, 55);
1766 ASSERT (result != NULL);
1767 if (have_minus_zero ())
1768 ASSERT (strcmp (result, "-0.000000 33") == 0);
1769 ASSERT (retval == strlen (result));
1770 free (result);
1771 }
1772
1773 { /* Positive infinity. */
1774 char *result;
1775 int retval =
1776 my_asprintf (&result, "%LF %d", Infinityl (), 33, 44, 55);
1777 ASSERT (result != NULL);
1778 ASSERT (strcmp (result, "INF 33") == 0
1779 || strcmp (result, "INFINITY 33") == 0);
1780 ASSERT (retval == strlen (result));
1781 free (result);
1782 }
1783
1784 { /* Negative infinity. */
1785 char *result;
1786 int retval =
1787 my_asprintf (&result, "%LF %d", - Infinityl (), 33, 44, 55);
1788 ASSERT (result != NULL);
1789 ASSERT (strcmp (result, "-INF 33") == 0
1790 || strcmp (result, "-INFINITY 33") == 0);
1791 ASSERT (retval == strlen (result));
1792 free (result);
1793 }
1794
1795 { /* NaN. */
1796 char *result;
1797 int retval =
1798 my_asprintf (&result, "%LF %d", NaNl (), 33, 44, 55);
1799 ASSERT (result != NULL);
1800 ASSERT (strlen (result) >= 3 + 3
1801 && strisnan (result, 0, strlen (result) - 3, 1)
1802 && strcmp (result + strlen (result) - 3, " 33") == 0);
1803 ASSERT (retval == strlen (result));
1804 free (result);
1805 }
1806
1807 { /* FLAG_ZERO. */
1808 char *result;
1809 int retval =
1810 my_asprintf (&result, "%015LF %d", 1234.0L, 33, 44, 55);
1811 ASSERT (result != NULL);
1812 ASSERT (strcmp (result, "00001234.000000 33") == 0);
1813 ASSERT (retval == strlen (result));
1814 free (result);
1815 }
1816
1817 { /* FLAG_ZERO with infinite number. */
1818 char *result;
1819 int retval =
1820 my_asprintf (&result, "%015LF %d", - Infinityl (), 33, 44, 55);
1821 ASSERT (result != NULL);
1822 ASSERT (strcmp (result, " -INF 33") == 0
1823 || strcmp (result, " -INFINITY 33") == 0);
1824 ASSERT (retval == strlen (result));
1825 free (result);
1826 }
1827
1828 { /* Precision. */
1829 char *result;
1830 int retval =
1831 my_asprintf (&result, "%.LF %d", 1234.0L, 33, 44, 55);
1832 ASSERT (result != NULL);
1833 ASSERT (strcmp (result, "1234 33") == 0);
1834 ASSERT (retval == strlen (result));
1835 free (result);
1836 }
1837
1838 { /* Precision with no rounding. */
1839 char *result;
1840 int retval =
1841 my_asprintf (&result, "%.2LF %d", 999.951L, 33, 44, 55);
1842 ASSERT (result != NULL);
1843 ASSERT (strcmp (result, "999.95 33") == 0);
1844 ASSERT (retval == strlen (result));
1845 free (result);
1846 }
1847
1848 { /* Precision with rounding. */
1849 char *result;
1850 int retval =
1851 my_asprintf (&result, "%.2LF %d", 999.996L, 33, 44, 55);
1852 ASSERT (result != NULL);
1853 ASSERT (strcmp (result, "1000.00 33") == 0);
1854 ASSERT (retval == strlen (result));
1855 free (result);
1856 }
1857
1858 /* Test the support of the %e format directive. */
1859
1860 { /* A positive number. */
1861 char *result;
1862 int retval =
1863 my_asprintf (&result, "%e %d", 12.75, 33, 44, 55);
1864 ASSERT (result != NULL);
1865 ASSERT (strcmp (result, "1.275000e+01 33") == 0
1866 || strcmp (result, "1.275000e+001 33") == 0);
1867 ASSERT (retval == strlen (result));
1868 free (result);
1869 }
1870
1871 { /* A larger positive number. */
1872 char *result;
1873 int retval =
1874 my_asprintf (&result, "%e %d", 1234567.0, 33, 44, 55);
1875 ASSERT (result != NULL);
1876 ASSERT (strcmp (result, "1.234567e+06 33") == 0
1877 || strcmp (result, "1.234567e+006 33") == 0);
1878 ASSERT (retval == strlen (result));
1879 free (result);
1880 }
1881
1882 { /* Small and large positive numbers. */
1883 static struct { double value; const char *string; } data[] =
1884 {
1885 { 1.234321234321234e-37, "1.234321e-37" },
1886 { 1.234321234321234e-36, "1.234321e-36" },
1887 { 1.234321234321234e-35, "1.234321e-35" },
1888 { 1.234321234321234e-34, "1.234321e-34" },
1889 { 1.234321234321234e-33, "1.234321e-33" },
1890 { 1.234321234321234e-32, "1.234321e-32" },
1891 { 1.234321234321234e-31, "1.234321e-31" },
1892 { 1.234321234321234e-30, "1.234321e-30" },
1893 { 1.234321234321234e-29, "1.234321e-29" },
1894 { 1.234321234321234e-28, "1.234321e-28" },
1895 { 1.234321234321234e-27, "1.234321e-27" },
1896 { 1.234321234321234e-26, "1.234321e-26" },
1897 { 1.234321234321234e-25, "1.234321e-25" },
1898 { 1.234321234321234e-24, "1.234321e-24" },
1899 { 1.234321234321234e-23, "1.234321e-23" },
1900 { 1.234321234321234e-22, "1.234321e-22" },
1901 { 1.234321234321234e-21, "1.234321e-21" },
1902 { 1.234321234321234e-20, "1.234321e-20" },
1903 { 1.234321234321234e-19, "1.234321e-19" },
1904 { 1.234321234321234e-18, "1.234321e-18" },
1905 { 1.234321234321234e-17, "1.234321e-17" },
1906 { 1.234321234321234e-16, "1.234321e-16" },
1907 { 1.234321234321234e-15, "1.234321e-15" },
1908 { 1.234321234321234e-14, "1.234321e-14" },
1909 { 1.234321234321234e-13, "1.234321e-13" },
1910 { 1.234321234321234e-12, "1.234321e-12" },
1911 { 1.234321234321234e-11, "1.234321e-11" },
1912 { 1.234321234321234e-10, "1.234321e-10" },
1913 { 1.234321234321234e-9, "1.234321e-09" },
1914 { 1.234321234321234e-8, "1.234321e-08" },
1915 { 1.234321234321234e-7, "1.234321e-07" },
1916 { 1.234321234321234e-6, "1.234321e-06" },
1917 { 1.234321234321234e-5, "1.234321e-05" },
1918 { 1.234321234321234e-4, "1.234321e-04" },
1919 { 1.234321234321234e-3, "1.234321e-03" },
1920 { 1.234321234321234e-2, "1.234321e-02" },
1921 { 1.234321234321234e-1, "1.234321e-01" },
1922 { 1.234321234321234, "1.234321e+00" },
1923 { 1.234321234321234e1, "1.234321e+01" },
1924 { 1.234321234321234e2, "1.234321e+02" },
1925 { 1.234321234321234e3, "1.234321e+03" },
1926 { 1.234321234321234e4, "1.234321e+04" },
1927 { 1.234321234321234e5, "1.234321e+05" },
1928 { 1.234321234321234e6, "1.234321e+06" },
1929 { 1.234321234321234e7, "1.234321e+07" },
1930 { 1.234321234321234e8, "1.234321e+08" },
1931 { 1.234321234321234e9, "1.234321e+09" },
1932 { 1.234321234321234e10, "1.234321e+10" },
1933 { 1.234321234321234e11, "1.234321e+11" },
1934 { 1.234321234321234e12, "1.234321e+12" },
1935 { 1.234321234321234e13, "1.234321e+13" },
1936 { 1.234321234321234e14, "1.234321e+14" },
1937 { 1.234321234321234e15, "1.234321e+15" },
1938 { 1.234321234321234e16, "1.234321e+16" },
1939 { 1.234321234321234e17, "1.234321e+17" },
1940 { 1.234321234321234e18, "1.234321e+18" },
1941 { 1.234321234321234e19, "1.234321e+19" },
1942 { 1.234321234321234e20, "1.234321e+20" },
1943 { 1.234321234321234e21, "1.234321e+21" },
1944 { 1.234321234321234e22, "1.234321e+22" },
1945 { 1.234321234321234e23, "1.234321e+23" },
1946 { 1.234321234321234e24, "1.234321e+24" },
1947 { 1.234321234321234e25, "1.234321e+25" },
1948 { 1.234321234321234e26, "1.234321e+26" },
1949 { 1.234321234321234e27, "1.234321e+27" },
1950 { 1.234321234321234e28, "1.234321e+28" },
1951 { 1.234321234321234e29, "1.234321e+29" },
1952 { 1.234321234321234e30, "1.234321e+30" },
1953 { 1.234321234321234e31, "1.234321e+31" },
1954 { 1.234321234321234e32, "1.234321e+32" },
1955 { 1.234321234321234e33, "1.234321e+33" },
1956 { 1.234321234321234e34, "1.234321e+34" },
1957 { 1.234321234321234e35, "1.234321e+35" },
1958 { 1.234321234321234e36, "1.234321e+36" }
1959 };
1960 size_t k;
1961 for (k = 0; k < SIZEOF (data); k++)
1962 {
1963 char *result;
1964 int retval =
1965 my_asprintf (&result, "%e", data[k].value);
1966 const char *expected = data[k].string;
1967 ASSERT (result != NULL);
1968 ASSERT (strcmp (result, expected) == 0
1969 /* Some implementations produce exponents with 3 digits. */
1970 || (strlen (result) == strlen (expected) + 1
1971 && memcmp (result, expected, strlen (expected) - 2) == 0
1972 && result[strlen (expected) - 2] == '0'
1973 && strcmp (result + strlen (expected) - 1,
1974 expected + strlen (expected) - 2)
1975 == 0));
1976 ASSERT (retval == strlen (result));
1977 free (result);
1978 }
1979 }
1980
1981 { /* A negative number. */
1982 char *result;
1983 int retval =
1984 my_asprintf (&result, "%e %d", -0.03125, 33, 44, 55);
1985 ASSERT (result != NULL);
1986 ASSERT (strcmp (result, "-3.125000e-02 33") == 0
1987 || strcmp (result, "-3.125000e-002 33") == 0);
1988 ASSERT (retval == strlen (result));
1989 free (result);
1990 }
1991
1992 { /* Positive zero. */
1993 char *result;
1994 int retval =
1995 my_asprintf (&result, "%e %d", 0.0, 33, 44, 55);
1996 ASSERT (result != NULL);
1997 ASSERT (strcmp (result, "0.000000e+00 33") == 0
1998 || strcmp (result, "0.000000e+000 33") == 0);
1999 ASSERT (retval == strlen (result));
2000 free (result);
2001 }
2002
2003 { /* Negative zero. */
2004 char *result;
2005 int retval =
2006 my_asprintf (&result, "%e %d", minus_zerod, 33, 44, 55);
2007 ASSERT (result != NULL);
2008 if (have_minus_zero ())
2009 ASSERT (strcmp (result, "-0.000000e+00 33") == 0
2010 || strcmp (result, "-0.000000e+000 33") == 0);
2011 ASSERT (retval == strlen (result));
2012 free (result);
2013 }
2014
2015 { /* Positive infinity. */
2016 char *result;
2017 int retval =
2018 my_asprintf (&result, "%e %d", Infinityd (), 33, 44, 55);
2019 ASSERT (result != NULL);
2020 ASSERT (strcmp (result, "inf 33") == 0
2021 || strcmp (result, "infinity 33") == 0);
2022 ASSERT (retval == strlen (result));
2023 free (result);
2024 }
2025
2026 { /* Negative infinity. */
2027 char *result;
2028 int retval =
2029 my_asprintf (&result, "%e %d", - Infinityd (), 33, 44, 55);
2030 ASSERT (result != NULL);
2031 ASSERT (strcmp (result, "-inf 33") == 0
2032 || strcmp (result, "-infinity 33") == 0);
2033 ASSERT (retval == strlen (result));
2034 free (result);
2035 }
2036
2037 { /* NaN. */
2038 char *result;
2039 int retval =
2040 my_asprintf (&result, "%e %d", NaNd (), 33, 44, 55);
2041 ASSERT (result != NULL);
2042 ASSERT (strlen (result) >= 3 + 3
2043 && strisnan (result, 0, strlen (result) - 3, 0)
2044 && strcmp (result + strlen (result) - 3, " 33") == 0);
2045 ASSERT (retval == strlen (result));
2046 free (result);
2047 }
2048
2049 { /* Width. */
2050 char *result;
2051 int retval =
2052 my_asprintf (&result, "%15e %d", 1.75, 33, 44, 55);
2053 ASSERT (result != NULL);
2054 ASSERT (strcmp (result, " 1.750000e+00 33") == 0
2055 || strcmp (result, " 1.750000e+000 33") == 0);
2056 ASSERT (retval == strlen (result));
2057 free (result);
2058 }
2059
2060 { /* FLAG_LEFT. */
2061 char *result;
2062 int retval =
2063 my_asprintf (&result, "%-15e %d", 1.75, 33, 44, 55);
2064 ASSERT (result != NULL);
2065 ASSERT (strcmp (result, "1.750000e+00 33") == 0
2066 || strcmp (result, "1.750000e+000 33") == 0);
2067 ASSERT (retval == strlen (result));
2068 free (result);
2069 }
2070
2071 { /* FLAG_SHOWSIGN. */
2072 char *result;
2073 int retval =
2074 my_asprintf (&result, "%+e %d", 1.75, 33, 44, 55);
2075 ASSERT (result != NULL);
2076 ASSERT (strcmp (result, "+1.750000e+00 33") == 0
2077 || strcmp (result, "+1.750000e+000 33") == 0);
2078 ASSERT (retval == strlen (result));
2079 free (result);
2080 }
2081
2082 { /* FLAG_SPACE. */
2083 char *result;
2084 int retval =
2085 my_asprintf (&result, "% e %d", 1.75, 33, 44, 55);
2086 ASSERT (result != NULL);
2087 ASSERT (strcmp (result, " 1.750000e+00 33") == 0
2088 || strcmp (result, " 1.750000e+000 33") == 0);
2089 ASSERT (retval == strlen (result));
2090 free (result);
2091 }
2092
2093 { /* FLAG_ALT. */
2094 char *result;
2095 int retval =
2096 my_asprintf (&result, "%#e %d", 1.75, 33, 44, 55);
2097 ASSERT (result != NULL);
2098 ASSERT (strcmp (result, "1.750000e+00 33") == 0
2099 || strcmp (result, "1.750000e+000 33") == 0);
2100 ASSERT (retval == strlen (result));
2101 free (result);
2102 }
2103
2104 { /* FLAG_ALT. */
2105 char *result;
2106 int retval =
2107 my_asprintf (&result, "%#.e %d", 1.75, 33, 44, 55);
2108 ASSERT (result != NULL);
2109 ASSERT (strcmp (result, "2.e+00 33") == 0
2110 || strcmp (result, "2.e+000 33") == 0);
2111 ASSERT (retval == strlen (result));
2112 free (result);
2113 }
2114
2115 { /* FLAG_ALT. */
2116 char *result;
2117 int retval =
2118 my_asprintf (&result, "%#.e %d", 9.75, 33, 44, 55);
2119 ASSERT (result != NULL);
2120 ASSERT (strcmp (result, "1.e+01 33") == 0
2121 || strcmp (result, "1.e+001 33") == 0);
2122 ASSERT (retval == strlen (result));
2123 free (result);
2124 }
2125
2126 { /* FLAG_ZERO with finite number. */
2127 char *result;
2128 int retval =
2129 my_asprintf (&result, "%015e %d", 1234.0, 33, 44, 55);
2130 ASSERT (result != NULL);
2131 ASSERT (strcmp (result, "0001.234000e+03 33") == 0
2132 || strcmp (result, "001.234000e+003 33") == 0);
2133 ASSERT (retval == strlen (result));
2134 free (result);
2135 }
2136
2137 { /* FLAG_ZERO with infinite number. */
2138 char *result;
2139 int retval =
2140 my_asprintf (&result, "%015e %d", - Infinityd (), 33, 44, 55);
2141 ASSERT (result != NULL);
2142 ASSERT (strcmp (result, " -inf 33") == 0
2143 || strcmp (result, " -infinity 33") == 0);
2144 ASSERT (retval == strlen (result));
2145 free (result);
2146 }
2147
2148 { /* FLAG_ZERO with NaN. */
2149 char *result;
2150 int retval =
2151 my_asprintf (&result, "%050e %d", NaNd (), 33, 44, 55);
2152 ASSERT (result != NULL);
2153 ASSERT (strlen (result) == 50 + 3
2154 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
2155 && strcmp (result + strlen (result) - 3, " 33") == 0);
2156 ASSERT (retval == strlen (result));
2157 free (result);
2158 }
2159
2160 { /* Precision. */
2161 char *result;
2162 int retval =
2163 my_asprintf (&result, "%.e %d", 1234.0, 33, 44, 55);
2164 ASSERT (result != NULL);
2165 ASSERT (strcmp (result, "1e+03 33") == 0
2166 || strcmp (result, "1e+003 33") == 0);
2167 ASSERT (retval == strlen (result));
2168 free (result);
2169 }
2170
2171 { /* Precision with no rounding. */
2172 char *result;
2173 int retval =
2174 my_asprintf (&result, "%.4e %d", 999.951, 33, 44, 55);
2175 ASSERT (result != NULL);
2176 ASSERT (strcmp (result, "9.9995e+02 33") == 0
2177 || strcmp (result, "9.9995e+002 33") == 0);
2178 ASSERT (retval == strlen (result));
2179 free (result);
2180 }
2181
2182 { /* Precision with rounding. */
2183 char *result;
2184 int retval =
2185 my_asprintf (&result, "%.4e %d", 999.996, 33, 44, 55);
2186 ASSERT (result != NULL);
2187 ASSERT (strcmp (result, "1.0000e+03 33") == 0
2188 || strcmp (result, "1.0000e+003 33") == 0);
2189 ASSERT (retval == strlen (result));
2190 free (result);
2191 }
2192
2193 { /* A positive number. */
2194 char *result;
2195 int retval =
2196 my_asprintf (&result, "%Le %d", 12.75L, 33, 44, 55);
2197 ASSERT (result != NULL);
2198 ASSERT (strcmp (result, "1.275000e+01 33") == 0
2199 || strcmp (result, "1.275000e+001 33") == 0);
2200 ASSERT (retval == strlen (result));
2201 free (result);
2202 }
2203
2204 { /* A larger positive number. */
2205 char *result;
2206 int retval =
2207 my_asprintf (&result, "%Le %d", 1234567.0L, 33, 44, 55);
2208 ASSERT (result != NULL);
2209 ASSERT (strcmp (result, "1.234567e+06 33") == 0
2210 || strcmp (result, "1.234567e+006 33") == 0);
2211 ASSERT (retval == strlen (result));
2212 free (result);
2213 }
2214
2215 { /* Small and large positive numbers. */
2216 static struct { long double value; const char *string; } data[] =
2217 {
2218 { 1.234321234321234e-37L, "1.234321e-37" },
2219 { 1.234321234321234e-36L, "1.234321e-36" },
2220 { 1.234321234321234e-35L, "1.234321e-35" },
2221 { 1.234321234321234e-34L, "1.234321e-34" },
2222 { 1.234321234321234e-33L, "1.234321e-33" },
2223 { 1.234321234321234e-32L, "1.234321e-32" },
2224 { 1.234321234321234e-31L, "1.234321e-31" },
2225 { 1.234321234321234e-30L, "1.234321e-30" },
2226 { 1.234321234321234e-29L, "1.234321e-29" },
2227 { 1.234321234321234e-28L, "1.234321e-28" },
2228 { 1.234321234321234e-27L, "1.234321e-27" },
2229 { 1.234321234321234e-26L, "1.234321e-26" },
2230 { 1.234321234321234e-25L, "1.234321e-25" },
2231 { 1.234321234321234e-24L, "1.234321e-24" },
2232 { 1.234321234321234e-23L, "1.234321e-23" },
2233 { 1.234321234321234e-22L, "1.234321e-22" },
2234 { 1.234321234321234e-21L, "1.234321e-21" },
2235 { 1.234321234321234e-20L, "1.234321e-20" },
2236 { 1.234321234321234e-19L, "1.234321e-19" },
2237 { 1.234321234321234e-18L, "1.234321e-18" },
2238 { 1.234321234321234e-17L, "1.234321e-17" },
2239 { 1.234321234321234e-16L, "1.234321e-16" },
2240 { 1.234321234321234e-15L, "1.234321e-15" },
2241 { 1.234321234321234e-14L, "1.234321e-14" },
2242 { 1.234321234321234e-13L, "1.234321e-13" },
2243 { 1.234321234321234e-12L, "1.234321e-12" },
2244 { 1.234321234321234e-11L, "1.234321e-11" },
2245 { 1.234321234321234e-10L, "1.234321e-10" },
2246 { 1.234321234321234e-9L, "1.234321e-09" },
2247 { 1.234321234321234e-8L, "1.234321e-08" },
2248 { 1.234321234321234e-7L, "1.234321e-07" },
2249 { 1.234321234321234e-6L, "1.234321e-06" },
2250 { 1.234321234321234e-5L, "1.234321e-05" },
2251 { 1.234321234321234e-4L, "1.234321e-04" },
2252 { 1.234321234321234e-3L, "1.234321e-03" },
2253 { 1.234321234321234e-2L, "1.234321e-02" },
2254 { 1.234321234321234e-1L, "1.234321e-01" },
2255 { 1.234321234321234L, "1.234321e+00" },
2256 { 1.234321234321234e1L, "1.234321e+01" },
2257 { 1.234321234321234e2L, "1.234321e+02" },
2258 { 1.234321234321234e3L, "1.234321e+03" },
2259 { 1.234321234321234e4L, "1.234321e+04" },
2260 { 1.234321234321234e5L, "1.234321e+05" },
2261 { 1.234321234321234e6L, "1.234321e+06" },
2262 { 1.234321234321234e7L, "1.234321e+07" },
2263 { 1.234321234321234e8L, "1.234321e+08" },
2264 { 1.234321234321234e9L, "1.234321e+09" },
2265 { 1.234321234321234e10L, "1.234321e+10" },
2266 { 1.234321234321234e11L, "1.234321e+11" },
2267 { 1.234321234321234e12L, "1.234321e+12" },
2268 { 1.234321234321234e13L, "1.234321e+13" },
2269 { 1.234321234321234e14L, "1.234321e+14" },
2270 { 1.234321234321234e15L, "1.234321e+15" },
2271 { 1.234321234321234e16L, "1.234321e+16" },
2272 { 1.234321234321234e17L, "1.234321e+17" },
2273 { 1.234321234321234e18L, "1.234321e+18" },
2274 { 1.234321234321234e19L, "1.234321e+19" },
2275 { 1.234321234321234e20L, "1.234321e+20" },
2276 { 1.234321234321234e21L, "1.234321e+21" },
2277 { 1.234321234321234e22L, "1.234321e+22" },
2278 { 1.234321234321234e23L, "1.234321e+23" },
2279 { 1.234321234321234e24L, "1.234321e+24" },
2280 { 1.234321234321234e25L, "1.234321e+25" },
2281 { 1.234321234321234e26L, "1.234321e+26" },
2282 { 1.234321234321234e27L, "1.234321e+27" },
2283 { 1.234321234321234e28L, "1.234321e+28" },
2284 { 1.234321234321234e29L, "1.234321e+29" },
2285 { 1.234321234321234e30L, "1.234321e+30" },
2286 { 1.234321234321234e31L, "1.234321e+31" },
2287 { 1.234321234321234e32L, "1.234321e+32" },
2288 { 1.234321234321234e33L, "1.234321e+33" },
2289 { 1.234321234321234e34L, "1.234321e+34" },
2290 { 1.234321234321234e35L, "1.234321e+35" },
2291 { 1.234321234321234e36L, "1.234321e+36" }
2292 };
2293 size_t k;
2294 for (k = 0; k < SIZEOF (data); k++)
2295 {
2296 char *result;
2297 int retval =
2298 my_asprintf (&result, "%Le", data[k].value);
2299 const char *expected = data[k].string;
2300 ASSERT (result != NULL);
2301 ASSERT (strcmp (result, expected) == 0
2302 /* Some implementations produce exponents with 3 digits. */
2303 || (strlen (result) == strlen (expected) + 1
2304 && memcmp (result, expected, strlen (expected) - 2) == 0
2305 && result[strlen (expected) - 2] == '0'
2306 && strcmp (result + strlen (expected) - 1,
2307 expected + strlen (expected) - 2)
2308 == 0));
2309 ASSERT (retval == strlen (result));
2310 free (result);
2311 }
2312 }
2313
2314 { /* A negative number. */
2315 char *result;
2316 int retval =
2317 my_asprintf (&result, "%Le %d", -0.03125L, 33, 44, 55);
2318 ASSERT (result != NULL);
2319 ASSERT (strcmp (result, "-3.125000e-02 33") == 0
2320 || strcmp (result, "-3.125000e-002 33") == 0);
2321 ASSERT (retval == strlen (result));
2322 free (result);
2323 }
2324
2325 { /* Positive zero. */
2326 char *result;
2327 int retval =
2328 my_asprintf (&result, "%Le %d", 0.0L, 33, 44, 55);
2329 ASSERT (result != NULL);
2330 ASSERT (strcmp (result, "0.000000e+00 33") == 0
2331 || strcmp (result, "0.000000e+000 33") == 0);
2332 ASSERT (retval == strlen (result));
2333 free (result);
2334 }
2335
2336 { /* Negative zero. */
2337 char *result;
2338 int retval =
2339 my_asprintf (&result, "%Le %d", minus_zerol, 33, 44, 55);
2340 ASSERT (result != NULL);
2341 if (have_minus_zero ())
2342 ASSERT (strcmp (result, "-0.000000e+00 33") == 0
2343 || strcmp (result, "-0.000000e+000 33") == 0);
2344 ASSERT (retval == strlen (result));
2345 free (result);
2346 }
2347
2348 { /* Positive infinity. */
2349 char *result;
2350 int retval =
2351 my_asprintf (&result, "%Le %d", Infinityl (), 33, 44, 55);
2352 ASSERT (result != NULL);
2353 ASSERT (strcmp (result, "inf 33") == 0
2354 || strcmp (result, "infinity 33") == 0);
2355 ASSERT (retval == strlen (result));
2356 free (result);
2357 }
2358
2359 { /* Negative infinity. */
2360 char *result;
2361 int retval =
2362 my_asprintf (&result, "%Le %d", - Infinityl (), 33, 44, 55);
2363 ASSERT (result != NULL);
2364 ASSERT (strcmp (result, "-inf 33") == 0
2365 || strcmp (result, "-infinity 33") == 0);
2366 ASSERT (retval == strlen (result));
2367 free (result);
2368 }
2369
2370 { /* NaN. */
2371 char *result;
2372 int retval =
2373 my_asprintf (&result, "%Le %d", NaNl (), 33, 44, 55);
2374 ASSERT (result != NULL);
2375 ASSERT (strlen (result) >= 3 + 3
2376 && strisnan (result, 0, strlen (result) - 3, 0)
2377 && strcmp (result + strlen (result) - 3, " 33") == 0);
2378 ASSERT (retval == strlen (result));
2379 free (result);
2380 }
2381 #if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
2382 { /* Quiet NaN. */
2383 static union { unsigned int word[4]; long double value; } x =
2384 { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
2385 char *result;
2386 int retval =
2387 my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
2388 ASSERT (result != NULL);
2389 ASSERT (strlen (result) >= 3 + 3
2390 && strisnan (result, 0, strlen (result) - 3, 0)
2391 && strcmp (result + strlen (result) - 3, " 33") == 0);
2392 ASSERT (retval == strlen (result));
2393 free (result);
2394 }
2395 {
2396 /* Signalling NaN. */
2397 static union { unsigned int word[4]; long double value; } x =
2398 { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
2399 char *result;
2400 int retval =
2401 my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
2402 ASSERT (result != NULL);
2403 ASSERT (strlen (result) >= 3 + 3
2404 && strisnan (result, 0, strlen (result) - 3, 0)
2405 && strcmp (result + strlen (result) - 3, " 33") == 0);
2406 ASSERT (retval == strlen (result));
2407 free (result);
2408 }
2409 /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
2410 Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
2411 Intel IA-64 Architecture Software Developer's Manual, Volume 1:
2412 Application Architecture.
2413 Table 5-2 "Floating-Point Register Encodings"
2414 Figure 5-6 "Memory to Floating-Point Register Data Translation"
2415 */
2416 { /* Pseudo-NaN. */
2417 static union { unsigned int word[4]; long double value; } x =
2418 { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
2419 char *result;
2420 int retval =
2421 my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
2422 ASSERT (result != NULL);
2423 ASSERT (strlen (result) >= 3 + 3
2424 && strisnan (result, 0, strlen (result) - 3, 0)
2425 && strcmp (result + strlen (result) - 3, " 33") == 0);
2426 ASSERT (retval == strlen (result));
2427 free (result);
2428 }
2429 { /* Pseudo-Infinity. */
2430 static union { unsigned int word[4]; long double value; } x =
2431 { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
2432 char *result;
2433 int retval =
2434 my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
2435 ASSERT (result != NULL);
2436 ASSERT (strlen (result) >= 3 + 3
2437 && strisnan (result, 0, strlen (result) - 3, 0)
2438 && strcmp (result + strlen (result) - 3, " 33") == 0);
2439 ASSERT (retval == strlen (result));
2440 free (result);
2441 }
2442 { /* Pseudo-Zero. */
2443 static union { unsigned int word[4]; long double value; } x =
2444 { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
2445 char *result;
2446 int retval =
2447 my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
2448 ASSERT (result != NULL);
2449 ASSERT (strlen (result) >= 3 + 3
2450 && strisnan (result, 0, strlen (result) - 3, 0)
2451 && strcmp (result + strlen (result) - 3, " 33") == 0);
2452 ASSERT (retval == strlen (result));
2453 free (result);
2454 }
2455 { /* Unnormalized number. */
2456 static union { unsigned int word[4]; long double value; } x =
2457 { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
2458 char *result;
2459 int retval =
2460 my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
2461 ASSERT (result != NULL);
2462 ASSERT (strlen (result) >= 3 + 3
2463 && strisnan (result, 0, strlen (result) - 3, 0)
2464 && strcmp (result + strlen (result) - 3, " 33") == 0);
2465 ASSERT (retval == strlen (result));
2466 free (result);
2467 }
2468 { /* Pseudo-Denormal. */
2469 static union { unsigned int word[4]; long double value; } x =
2470 { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
2471 char *result;
2472 int retval =
2473 my_asprintf (&result, "%Le %d", x.value, 33, 44, 55);
2474 ASSERT (result != NULL);
2475 ASSERT (strlen (result) >= 3 + 3
2476 && strisnan (result, 0, strlen (result) - 3, 0)
2477 && strcmp (result + strlen (result) - 3, " 33") == 0);
2478 ASSERT (retval == strlen (result));
2479 free (result);
2480 }
2481 #endif
2482
2483 { /* Width. */
2484 char *result;
2485 int retval =
2486 my_asprintf (&result, "%15Le %d", 1.75L, 33, 44, 55);
2487 ASSERT (result != NULL);
2488 ASSERT (strcmp (result, " 1.750000e+00 33") == 0
2489 || strcmp (result, " 1.750000e+000 33") == 0);
2490 ASSERT (retval == strlen (result));
2491 free (result);
2492 }
2493
2494 { /* FLAG_LEFT. */
2495 char *result;
2496 int retval =
2497 my_asprintf (&result, "%-15Le %d", 1.75L, 33, 44, 55);
2498 ASSERT (result != NULL);
2499 ASSERT (strcmp (result, "1.750000e+00 33") == 0
2500 || strcmp (result, "1.750000e+000 33") == 0);
2501 ASSERT (retval == strlen (result));
2502 free (result);
2503 }
2504
2505 { /* FLAG_SHOWSIGN. */
2506 char *result;
2507 int retval =
2508 my_asprintf (&result, "%+Le %d", 1.75L, 33, 44, 55);
2509 ASSERT (result != NULL);
2510 ASSERT (strcmp (result, "+1.750000e+00 33") == 0
2511 || strcmp (result, "+1.750000e+000 33") == 0);
2512 ASSERT (retval == strlen (result));
2513 free (result);
2514 }
2515
2516 { /* FLAG_SPACE. */
2517 char *result;
2518 int retval =
2519 my_asprintf (&result, "% Le %d", 1.75L, 33, 44, 55);
2520 ASSERT (result != NULL);
2521 ASSERT (strcmp (result, " 1.750000e+00 33") == 0
2522 || strcmp (result, " 1.750000e+000 33") == 0);
2523 ASSERT (retval == strlen (result));
2524 free (result);
2525 }
2526
2527 { /* FLAG_ALT. */
2528 char *result;
2529 int retval =
2530 my_asprintf (&result, "%#Le %d", 1.75L, 33, 44, 55);
2531 ASSERT (result != NULL);
2532 ASSERT (strcmp (result, "1.750000e+00 33") == 0
2533 || strcmp (result, "1.750000e+000 33") == 0);
2534 ASSERT (retval == strlen (result));
2535 free (result);
2536 }
2537
2538 { /* FLAG_ALT. */
2539 char *result;
2540 int retval =
2541 my_asprintf (&result, "%#.Le %d", 1.75L, 33, 44, 55);
2542 ASSERT (result != NULL);
2543 ASSERT (strcmp (result, "2.e+00 33") == 0
2544 || strcmp (result, "2.e+000 33") == 0);
2545 ASSERT (retval == strlen (result));
2546 free (result);
2547 }
2548
2549 { /* FLAG_ALT. */
2550 char *result;
2551 int retval =
2552 my_asprintf (&result, "%#.Le %d", 9.75L, 33, 44, 55);
2553 ASSERT (result != NULL);
2554 ASSERT (strcmp (result, "1.e+01 33") == 0
2555 || strcmp (result, "1.e+001 33") == 0);
2556 ASSERT (retval == strlen (result));
2557 free (result);
2558 }
2559
2560 { /* FLAG_ZERO with finite number. */
2561 char *result;
2562 int retval =
2563 my_asprintf (&result, "%015Le %d", 1234.0L, 33, 44, 55);
2564 ASSERT (result != NULL);
2565 ASSERT (strcmp (result, "0001.234000e+03 33") == 0
2566 || strcmp (result, "001.234000e+003 33") == 0);
2567 ASSERT (retval == strlen (result));
2568 free (result);
2569 }
2570
2571 { /* FLAG_ZERO with infinite number. */
2572 char *result;
2573 int retval =
2574 my_asprintf (&result, "%015Le %d", - Infinityl (), 33, 44, 55);
2575 ASSERT (result != NULL);
2576 ASSERT (strcmp (result, " -inf 33") == 0
2577 || strcmp (result, " -infinity 33") == 0);
2578 ASSERT (retval == strlen (result));
2579 free (result);
2580 }
2581
2582 { /* FLAG_ZERO with NaN. */
2583 char *result;
2584 int retval =
2585 my_asprintf (&result, "%050Le %d", NaNl (), 33, 44, 55);
2586 ASSERT (result != NULL);
2587 ASSERT (strlen (result) == 50 + 3
2588 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
2589 && strcmp (result + strlen (result) - 3, " 33") == 0);
2590 ASSERT (retval == strlen (result));
2591 free (result);
2592 }
2593
2594 { /* Precision. */
2595 char *result;
2596 int retval =
2597 my_asprintf (&result, "%.Le %d", 1234.0L, 33, 44, 55);
2598 ASSERT (result != NULL);
2599 ASSERT (strcmp (result, "1e+03 33") == 0
2600 || strcmp (result, "1e+003 33") == 0);
2601 ASSERT (retval == strlen (result));
2602 free (result);
2603 }
2604
2605 { /* Precision with no rounding. */
2606 char *result;
2607 int retval =
2608 my_asprintf (&result, "%.4Le %d", 999.951L, 33, 44, 55);
2609 ASSERT (result != NULL);
2610 ASSERT (strcmp (result, "9.9995e+02 33") == 0
2611 || strcmp (result, "9.9995e+002 33") == 0);
2612 ASSERT (retval == strlen (result));
2613 free (result);
2614 }
2615
2616 { /* Precision with rounding. */
2617 char *result;
2618 int retval =
2619 my_asprintf (&result, "%.4Le %d", 999.996L, 33, 44, 55);
2620 ASSERT (result != NULL);
2621 ASSERT (strcmp (result, "1.0000e+03 33") == 0
2622 || strcmp (result, "1.0000e+003 33") == 0);
2623 ASSERT (retval == strlen (result));
2624 free (result);
2625 }
2626
2627 /* Test the support of the %g format directive. */
2628
2629 { /* A positive number. */
2630 char *result;
2631 int retval =
2632 my_asprintf (&result, "%g %d", 12.75, 33, 44, 55);
2633 ASSERT (result != NULL);
2634 ASSERT (strcmp (result, "12.75 33") == 0);
2635 ASSERT (retval == strlen (result));
2636 free (result);
2637 }
2638
2639 { /* A larger positive number. */
2640 char *result;
2641 int retval =
2642 my_asprintf (&result, "%g %d", 1234567.0, 33, 44, 55);
2643 ASSERT (result != NULL);
2644 ASSERT (strcmp (result, "1.23457e+06 33") == 0
2645 || strcmp (result, "1.23457e+006 33") == 0);
2646 ASSERT (retval == strlen (result));
2647 free (result);
2648 }
2649
2650 { /* Small and large positive numbers. */
2651 static struct { double value; const char *string; } data[] =
2652 {
2653 { 1.234321234321234e-37, "1.23432e-37" },
2654 { 1.234321234321234e-36, "1.23432e-36" },
2655 { 1.234321234321234e-35, "1.23432e-35" },
2656 { 1.234321234321234e-34, "1.23432e-34" },
2657 { 1.234321234321234e-33, "1.23432e-33" },
2658 { 1.234321234321234e-32, "1.23432e-32" },
2659 { 1.234321234321234e-31, "1.23432e-31" },
2660 { 1.234321234321234e-30, "1.23432e-30" },
2661 { 1.234321234321234e-29, "1.23432e-29" },
2662 { 1.234321234321234e-28, "1.23432e-28" },
2663 { 1.234321234321234e-27, "1.23432e-27" },
2664 { 1.234321234321234e-26, "1.23432e-26" },
2665 { 1.234321234321234e-25, "1.23432e-25" },
2666 { 1.234321234321234e-24, "1.23432e-24" },
2667 { 1.234321234321234e-23, "1.23432e-23" },
2668 { 1.234321234321234e-22, "1.23432e-22" },
2669 { 1.234321234321234e-21, "1.23432e-21" },
2670 { 1.234321234321234e-20, "1.23432e-20" },
2671 { 1.234321234321234e-19, "1.23432e-19" },
2672 { 1.234321234321234e-18, "1.23432e-18" },
2673 { 1.234321234321234e-17, "1.23432e-17" },
2674 { 1.234321234321234e-16, "1.23432e-16" },
2675 { 1.234321234321234e-15, "1.23432e-15" },
2676 { 1.234321234321234e-14, "1.23432e-14" },
2677 { 1.234321234321234e-13, "1.23432e-13" },
2678 { 1.234321234321234e-12, "1.23432e-12" },
2679 { 1.234321234321234e-11, "1.23432e-11" },
2680 { 1.234321234321234e-10, "1.23432e-10" },
2681 { 1.234321234321234e-9, "1.23432e-09" },
2682 { 1.234321234321234e-8, "1.23432e-08" },
2683 { 1.234321234321234e-7, "1.23432e-07" },
2684 { 1.234321234321234e-6, "1.23432e-06" },
2685 { 1.234321234321234e-5, "1.23432e-05" },
2686 { 1.234321234321234e-4, "0.000123432" },
2687 { 1.234321234321234e-3, "0.00123432" },
2688 { 1.234321234321234e-2, "0.0123432" },
2689 { 1.234321234321234e-1, "0.123432" },
2690 { 1.234321234321234, "1.23432" },
2691 { 1.234321234321234e1, "12.3432" },
2692 { 1.234321234321234e2, "123.432" },
2693 { 1.234321234321234e3, "1234.32" },
2694 { 1.234321234321234e4, "12343.2" },
2695 { 1.234321234321234e5, "123432" },
2696 { 1.234321234321234e6, "1.23432e+06" },
2697 { 1.234321234321234e7, "1.23432e+07" },
2698 { 1.234321234321234e8, "1.23432e+08" },
2699 { 1.234321234321234e9, "1.23432e+09" },
2700 { 1.234321234321234e10, "1.23432e+10" },
2701 { 1.234321234321234e11, "1.23432e+11" },
2702 { 1.234321234321234e12, "1.23432e+12" },
2703 { 1.234321234321234e13, "1.23432e+13" },
2704 { 1.234321234321234e14, "1.23432e+14" },
2705 { 1.234321234321234e15, "1.23432e+15" },
2706 { 1.234321234321234e16, "1.23432e+16" },
2707 { 1.234321234321234e17, "1.23432e+17" },
2708 { 1.234321234321234e18, "1.23432e+18" },
2709 { 1.234321234321234e19, "1.23432e+19" },
2710 { 1.234321234321234e20, "1.23432e+20" },
2711 { 1.234321234321234e21, "1.23432e+21" },
2712 { 1.234321234321234e22, "1.23432e+22" },
2713 { 1.234321234321234e23, "1.23432e+23" },
2714 { 1.234321234321234e24, "1.23432e+24" },
2715 { 1.234321234321234e25, "1.23432e+25" },
2716 { 1.234321234321234e26, "1.23432e+26" },
2717 { 1.234321234321234e27, "1.23432e+27" },
2718 { 1.234321234321234e28, "1.23432e+28" },
2719 { 1.234321234321234e29, "1.23432e+29" },
2720 { 1.234321234321234e30, "1.23432e+30" },
2721 { 1.234321234321234e31, "1.23432e+31" },
2722 { 1.234321234321234e32, "1.23432e+32" },
2723 { 1.234321234321234e33, "1.23432e+33" },
2724 { 1.234321234321234e34, "1.23432e+34" },
2725 { 1.234321234321234e35, "1.23432e+35" },
2726 { 1.234321234321234e36, "1.23432e+36" }
2727 };
2728 size_t k;
2729 for (k = 0; k < SIZEOF (data); k++)
2730 {
2731 char *result;
2732 int retval =
2733 my_asprintf (&result, "%g", data[k].value);
2734 const char *expected = data[k].string;
2735 ASSERT (result != NULL);
2736 ASSERT (strcmp (result, expected) == 0
2737 /* Some implementations produce exponents with 3 digits. */
2738 || (expected[strlen (expected) - 4] == 'e'
2739 && strlen (result) == strlen (expected) + 1
2740 && memcmp (result, expected, strlen (expected) - 2) == 0
2741 && result[strlen (expected) - 2] == '0'
2742 && strcmp (result + strlen (expected) - 1,
2743 expected + strlen (expected) - 2)
2744 == 0));
2745 ASSERT (retval == strlen (result));
2746 free (result);
2747 }
2748 }
2749
2750 { /* A negative number. */
2751 char *result;
2752 int retval =
2753 my_asprintf (&result, "%g %d", -0.03125, 33, 44, 55);
2754 ASSERT (result != NULL);
2755 ASSERT (strcmp (result, "-0.03125 33") == 0);
2756 ASSERT (retval == strlen (result));
2757 free (result);
2758 }
2759
2760 { /* Positive zero. */
2761 char *result;
2762 int retval =
2763 my_asprintf (&result, "%g %d", 0.0, 33, 44, 55);
2764 ASSERT (result != NULL);
2765 ASSERT (strcmp (result, "0 33") == 0);
2766 ASSERT (retval == strlen (result));
2767 free (result);
2768 }
2769
2770 { /* Negative zero. */
2771 char *result;
2772 int retval =
2773 my_asprintf (&result, "%g %d", minus_zerod, 33, 44, 55);
2774 ASSERT (result != NULL);
2775 if (have_minus_zero ())
2776 ASSERT (strcmp (result, "-0 33") == 0);
2777 ASSERT (retval == strlen (result));
2778 free (result);
2779 }
2780
2781 { /* Positive infinity. */
2782 char *result;
2783 int retval =
2784 my_asprintf (&result, "%g %d", Infinityd (), 33, 44, 55);
2785 ASSERT (result != NULL);
2786 ASSERT (strcmp (result, "inf 33") == 0
2787 || strcmp (result, "infinity 33") == 0);
2788 ASSERT (retval == strlen (result));
2789 free (result);
2790 }
2791
2792 { /* Negative infinity. */
2793 char *result;
2794 int retval =
2795 my_asprintf (&result, "%g %d", - Infinityd (), 33, 44, 55);
2796 ASSERT (result != NULL);
2797 ASSERT (strcmp (result, "-inf 33") == 0
2798 || strcmp (result, "-infinity 33") == 0);
2799 ASSERT (retval == strlen (result));
2800 free (result);
2801 }
2802
2803 { /* NaN. */
2804 char *result;
2805 int retval =
2806 my_asprintf (&result, "%g %d", NaNd (), 33, 44, 55);
2807 ASSERT (result != NULL);
2808 ASSERT (strlen (result) >= 3 + 3
2809 && strisnan (result, 0, strlen (result) - 3, 0)
2810 && strcmp (result + strlen (result) - 3, " 33") == 0);
2811 ASSERT (retval == strlen (result));
2812 free (result);
2813 }
2814
2815 { /* Width. */
2816 char *result;
2817 int retval =
2818 my_asprintf (&result, "%10g %d", 1.75, 33, 44, 55);
2819 ASSERT (result != NULL);
2820 ASSERT (strcmp (result, " 1.75 33") == 0);
2821 ASSERT (retval == strlen (result));
2822 free (result);
2823 }
2824
2825 { /* FLAG_LEFT. */
2826 char *result;
2827 int retval =
2828 my_asprintf (&result, "%-10g %d", 1.75, 33, 44, 55);
2829 ASSERT (result != NULL);
2830 ASSERT (strcmp (result, "1.75 33") == 0);
2831 ASSERT (retval == strlen (result));
2832 free (result);
2833 }
2834
2835 { /* FLAG_SHOWSIGN. */
2836 char *result;
2837 int retval =
2838 my_asprintf (&result, "%+g %d", 1.75, 33, 44, 55);
2839 ASSERT (result != NULL);
2840 ASSERT (strcmp (result, "+1.75 33") == 0);
2841 ASSERT (retval == strlen (result));
2842 free (result);
2843 }
2844
2845 { /* FLAG_SPACE. */
2846 char *result;
2847 int retval =
2848 my_asprintf (&result, "% g %d", 1.75, 33, 44, 55);
2849 ASSERT (result != NULL);
2850 ASSERT (strcmp (result, " 1.75 33") == 0);
2851 ASSERT (retval == strlen (result));
2852 free (result);
2853 }
2854
2855 { /* FLAG_ALT. */
2856 char *result;
2857 int retval =
2858 my_asprintf (&result, "%#g %d", 1.75, 33, 44, 55);
2859 ASSERT (result != NULL);
2860 ASSERT (strcmp (result, "1.75000 33") == 0);
2861 ASSERT (retval == strlen (result));
2862 free (result);
2863 }
2864
2865 { /* FLAG_ALT. */
2866 char *result;
2867 int retval =
2868 my_asprintf (&result, "%#.g %d", 1.75, 33, 44, 55);
2869 ASSERT (result != NULL);
2870 ASSERT (strcmp (result, "2. 33") == 0);
2871 ASSERT (retval == strlen (result));
2872 free (result);
2873 }
2874
2875 { /* FLAG_ALT. */
2876 char *result;
2877 int retval =
2878 my_asprintf (&result, "%#.g %d", 9.75, 33, 44, 55);
2879 ASSERT (result != NULL);
2880 ASSERT (strcmp (result, "1.e+01 33") == 0
2881 || strcmp (result, "1.e+001 33") == 0);
2882 ASSERT (retval == strlen (result));
2883 free (result);
2884 }
2885
2886 { /* FLAG_ZERO with finite number. */
2887 char *result;
2888 int retval =
2889 my_asprintf (&result, "%010g %d", 1234.0, 33, 44, 55);
2890 ASSERT (result != NULL);
2891 ASSERT (strcmp (result, "0000001234 33") == 0);
2892 ASSERT (retval == strlen (result));
2893 free (result);
2894 }
2895
2896 { /* FLAG_ZERO with infinite number. */
2897 char *result;
2898 int retval =
2899 my_asprintf (&result, "%015g %d", - Infinityd (), 33, 44, 55);
2900 ASSERT (result != NULL);
2901 ASSERT (strcmp (result, " -inf 33") == 0
2902 || strcmp (result, " -infinity 33") == 0);
2903 ASSERT (retval == strlen (result));
2904 free (result);
2905 }
2906
2907 { /* FLAG_ZERO with NaN. */
2908 char *result;
2909 int retval =
2910 my_asprintf (&result, "%050g %d", NaNd (), 33, 44, 55);
2911 ASSERT (result != NULL);
2912 ASSERT (strlen (result) == 50 + 3
2913 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
2914 && strcmp (result + strlen (result) - 3, " 33") == 0);
2915 ASSERT (retval == strlen (result));
2916 free (result);
2917 }
2918
2919 { /* Precision. */
2920 char *result;
2921 int retval =
2922 my_asprintf (&result, "%.g %d", 1234.0, 33, 44, 55);
2923 ASSERT (result != NULL);
2924 ASSERT (strcmp (result, "1e+03 33") == 0
2925 || strcmp (result, "1e+003 33") == 0);
2926 ASSERT (retval == strlen (result));
2927 free (result);
2928 }
2929
2930 { /* Precision with no rounding. */
2931 char *result;
2932 int retval =
2933 my_asprintf (&result, "%.5g %d", 999.951, 33, 44, 55);
2934 ASSERT (result != NULL);
2935 ASSERT (strcmp (result, "999.95 33") == 0);
2936 ASSERT (retval == strlen (result));
2937 free (result);
2938 }
2939
2940 { /* Precision with rounding. */
2941 char *result;
2942 int retval =
2943 my_asprintf (&result, "%.5g %d", 999.996, 33, 44, 55);
2944 ASSERT (result != NULL);
2945 ASSERT (strcmp (result, "1000 33") == 0);
2946 ASSERT (retval == strlen (result));
2947 free (result);
2948 }
2949
2950 { /* A positive number. */
2951 char *result;
2952 int retval =
2953 my_asprintf (&result, "%Lg %d", 12.75L, 33, 44, 55);
2954 ASSERT (result != NULL);
2955 ASSERT (strcmp (result, "12.75 33") == 0);
2956 ASSERT (retval == strlen (result));
2957 free (result);
2958 }
2959
2960 { /* A larger positive number. */
2961 char *result;
2962 int retval =
2963 my_asprintf (&result, "%Lg %d", 1234567.0L, 33, 44, 55);
2964 ASSERT (result != NULL);
2965 ASSERT (strcmp (result, "1.23457e+06 33") == 0
2966 || strcmp (result, "1.23457e+006 33") == 0);
2967 ASSERT (retval == strlen (result));
2968 free (result);
2969 }
2970
2971 { /* Small and large positive numbers. */
2972 static struct { long double value; const char *string; } data[] =
2973 {
2974 { 1.234321234321234e-37L, "1.23432e-37" },
2975 { 1.234321234321234e-36L, "1.23432e-36" },
2976 { 1.234321234321234e-35L, "1.23432e-35" },
2977 { 1.234321234321234e-34L, "1.23432e-34" },
2978 { 1.234321234321234e-33L, "1.23432e-33" },
2979 { 1.234321234321234e-32L, "1.23432e-32" },
2980 { 1.234321234321234e-31L, "1.23432e-31" },
2981 { 1.234321234321234e-30L, "1.23432e-30" },
2982 { 1.234321234321234e-29L, "1.23432e-29" },
2983 { 1.234321234321234e-28L, "1.23432e-28" },
2984 { 1.234321234321234e-27L, "1.23432e-27" },
2985 { 1.234321234321234e-26L, "1.23432e-26" },
2986 { 1.234321234321234e-25L, "1.23432e-25" },
2987 { 1.234321234321234e-24L, "1.23432e-24" },
2988 { 1.234321234321234e-23L, "1.23432e-23" },
2989 { 1.234321234321234e-22L, "1.23432e-22" },
2990 { 1.234321234321234e-21L, "1.23432e-21" },
2991 { 1.234321234321234e-20L, "1.23432e-20" },
2992 { 1.234321234321234e-19L, "1.23432e-19" },
2993 { 1.234321234321234e-18L, "1.23432e-18" },
2994 { 1.234321234321234e-17L, "1.23432e-17" },
2995 { 1.234321234321234e-16L, "1.23432e-16" },
2996 { 1.234321234321234e-15L, "1.23432e-15" },
2997 { 1.234321234321234e-14L, "1.23432e-14" },
2998 { 1.234321234321234e-13L, "1.23432e-13" },
2999 { 1.234321234321234e-12L, "1.23432e-12" },
3000 { 1.234321234321234e-11L, "1.23432e-11" },
3001 { 1.234321234321234e-10L, "1.23432e-10" },
3002 { 1.234321234321234e-9L, "1.23432e-09" },
3003 { 1.234321234321234e-8L, "1.23432e-08" },
3004 { 1.234321234321234e-7L, "1.23432e-07" },
3005 { 1.234321234321234e-6L, "1.23432e-06" },
3006 { 1.234321234321234e-5L, "1.23432e-05" },
3007 { 1.234321234321234e-4L, "0.000123432" },
3008 { 1.234321234321234e-3L, "0.00123432" },
3009 { 1.234321234321234e-2L, "0.0123432" },
3010 { 1.234321234321234e-1L, "0.123432" },
3011 { 1.234321234321234L, "1.23432" },
3012 { 1.234321234321234e1L, "12.3432" },
3013 { 1.234321234321234e2L, "123.432" },
3014 { 1.234321234321234e3L, "1234.32" },
3015 { 1.234321234321234e4L, "12343.2" },
3016 { 1.234321234321234e5L, "123432" },
3017 { 1.234321234321234e6L, "1.23432e+06" },
3018 { 1.234321234321234e7L, "1.23432e+07" },
3019 { 1.234321234321234e8L, "1.23432e+08" },
3020 { 1.234321234321234e9L, "1.23432e+09" },
3021 { 1.234321234321234e10L, "1.23432e+10" },
3022 { 1.234321234321234e11L, "1.23432e+11" },
3023 { 1.234321234321234e12L, "1.23432e+12" },
3024 { 1.234321234321234e13L, "1.23432e+13" },
3025 { 1.234321234321234e14L, "1.23432e+14" },
3026 { 1.234321234321234e15L, "1.23432e+15" },
3027 { 1.234321234321234e16L, "1.23432e+16" },
3028 { 1.234321234321234e17L, "1.23432e+17" },
3029 { 1.234321234321234e18L, "1.23432e+18" },
3030 { 1.234321234321234e19L, "1.23432e+19" },
3031 { 1.234321234321234e20L, "1.23432e+20" },
3032 { 1.234321234321234e21L, "1.23432e+21" },
3033 { 1.234321234321234e22L, "1.23432e+22" },
3034 { 1.234321234321234e23L, "1.23432e+23" },
3035 { 1.234321234321234e24L, "1.23432e+24" },
3036 { 1.234321234321234e25L, "1.23432e+25" },
3037 { 1.234321234321234e26L, "1.23432e+26" },
3038 { 1.234321234321234e27L, "1.23432e+27" },
3039 { 1.234321234321234e28L, "1.23432e+28" },
3040 { 1.234321234321234e29L, "1.23432e+29" },
3041 { 1.234321234321234e30L, "1.23432e+30" },
3042 { 1.234321234321234e31L, "1.23432e+31" },
3043 { 1.234321234321234e32L, "1.23432e+32" },
3044 { 1.234321234321234e33L, "1.23432e+33" },
3045 { 1.234321234321234e34L, "1.23432e+34" },
3046 { 1.234321234321234e35L, "1.23432e+35" },
3047 { 1.234321234321234e36L, "1.23432e+36" }
3048 };
3049 size_t k;
3050 for (k = 0; k < SIZEOF (data); k++)
3051 {
3052 char *result;
3053 int retval =
3054 my_asprintf (&result, "%Lg", data[k].value);
3055 const char *expected = data[k].string;
3056 ASSERT (result != NULL);
3057 ASSERT (strcmp (result, expected) == 0
3058 /* Some implementations produce exponents with 3 digits. */
3059 || (expected[strlen (expected) - 4] == 'e'
3060 && strlen (result) == strlen (expected) + 1
3061 && memcmp (result, expected, strlen (expected) - 2) == 0
3062 && result[strlen (expected) - 2] == '0'
3063 && strcmp (result + strlen (expected) - 1,
3064 expected + strlen (expected) - 2)
3065 == 0));
3066 ASSERT (retval == strlen (result));
3067 free (result);
3068 }
3069 }
3070
3071 { /* A negative number. */
3072 char *result;
3073 int retval =
3074 my_asprintf (&result, "%Lg %d", -0.03125L, 33, 44, 55);
3075 ASSERT (result != NULL);
3076 ASSERT (strcmp (result, "-0.03125 33") == 0);
3077 ASSERT (retval == strlen (result));
3078 free (result);
3079 }
3080
3081 { /* Positive zero. */
3082 char *result;
3083 int retval =
3084 my_asprintf (&result, "%Lg %d", 0.0L, 33, 44, 55);
3085 ASSERT (result != NULL);
3086 ASSERT (strcmp (result, "0 33") == 0);
3087 ASSERT (retval == strlen (result));
3088 free (result);
3089 }
3090
3091 { /* Negative zero. */
3092 char *result;
3093 int retval =
3094 my_asprintf (&result, "%Lg %d", minus_zerol, 33, 44, 55);
3095 ASSERT (result != NULL);
3096 if (have_minus_zero ())
3097 ASSERT (strcmp (result, "-0 33") == 0);
3098 ASSERT (retval == strlen (result));
3099 free (result);
3100 }
3101
3102 { /* Positive infinity. */
3103 char *result;
3104 int retval =
3105 my_asprintf (&result, "%Lg %d", Infinityl (), 33, 44, 55);
3106 ASSERT (result != NULL);
3107 ASSERT (strcmp (result, "inf 33") == 0
3108 || strcmp (result, "infinity 33") == 0);
3109 ASSERT (retval == strlen (result));
3110 free (result);
3111 }
3112
3113 { /* Negative infinity. */
3114 char *result;
3115 int retval =
3116 my_asprintf (&result, "%Lg %d", - Infinityl (), 33, 44, 55);
3117 ASSERT (result != NULL);
3118 ASSERT (strcmp (result, "-inf 33") == 0
3119 || strcmp (result, "-infinity 33") == 0);
3120 ASSERT (retval == strlen (result));
3121 free (result);
3122 }
3123
3124 { /* NaN. */
3125 char *result;
3126 int retval =
3127 my_asprintf (&result, "%Lg %d", NaNl (), 33, 44, 55);
3128 ASSERT (result != NULL);
3129 ASSERT (strlen (result) >= 3 + 3
3130 && strisnan (result, 0, strlen (result) - 3, 0)
3131 && strcmp (result + strlen (result) - 3, " 33") == 0);
3132 ASSERT (retval == strlen (result));
3133 free (result);
3134 }
3135 #if CHECK_PRINTF_SAFE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
3136 { /* Quiet NaN. */
3137 static union { unsigned int word[4]; long double value; } x =
3138 { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
3139 char *result;
3140 int retval =
3141 my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
3142 ASSERT (result != NULL);
3143 ASSERT (strlen (result) >= 3 + 3
3144 && strisnan (result, 0, strlen (result) - 3, 0)
3145 && strcmp (result + strlen (result) - 3, " 33") == 0);
3146 ASSERT (retval == strlen (result));
3147 free (result);
3148 }
3149 {
3150 /* Signalling NaN. */
3151 static union { unsigned int word[4]; long double value; } x =
3152 { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
3153 char *result;
3154 int retval =
3155 my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
3156 ASSERT (result != NULL);
3157 ASSERT (strlen (result) >= 3 + 3
3158 && strisnan (result, 0, strlen (result) - 3, 0)
3159 && strcmp (result + strlen (result) - 3, " 33") == 0);
3160 ASSERT (retval == strlen (result));
3161 free (result);
3162 }
3163 /* The isnanl function should recognize Pseudo-NaNs, Pseudo-Infinities,
3164 Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
3165 Intel IA-64 Architecture Software Developer's Manual, Volume 1:
3166 Application Architecture.
3167 Table 5-2 "Floating-Point Register Encodings"
3168 Figure 5-6 "Memory to Floating-Point Register Data Translation"
3169 */
3170 { /* Pseudo-NaN. */
3171 static union { unsigned int word[4]; long double value; } x =
3172 { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
3173 char *result;
3174 int retval =
3175 my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
3176 ASSERT (result != NULL);
3177 ASSERT (strlen (result) >= 3 + 3
3178 && strisnan (result, 0, strlen (result) - 3, 0)
3179 && strcmp (result + strlen (result) - 3, " 33") == 0);
3180 ASSERT (retval == strlen (result));
3181 free (result);
3182 }
3183 { /* Pseudo-Infinity. */
3184 static union { unsigned int word[4]; long double value; } x =
3185 { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
3186 char *result;
3187 int retval =
3188 my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
3189 ASSERT (result != NULL);
3190 ASSERT (strlen (result) >= 3 + 3
3191 && strisnan (result, 0, strlen (result) - 3, 0)
3192 && strcmp (result + strlen (result) - 3, " 33") == 0);
3193 ASSERT (retval == strlen (result));
3194 free (result);
3195 }
3196 { /* Pseudo-Zero. */
3197 static union { unsigned int word[4]; long double value; } x =
3198 { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
3199 char *result;
3200 int retval =
3201 my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
3202 ASSERT (result != NULL);
3203 ASSERT (strlen (result) >= 3 + 3
3204 && strisnan (result, 0, strlen (result) - 3, 0)
3205 && strcmp (result + strlen (result) - 3, " 33") == 0);
3206 ASSERT (retval == strlen (result));
3207 free (result);
3208 }
3209 { /* Unnormalized number. */
3210 static union { unsigned int word[4]; long double value; } x =
3211 { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
3212 char *result;
3213 int retval =
3214 my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
3215 ASSERT (result != NULL);
3216 ASSERT (strlen (result) >= 3 + 3
3217 && strisnan (result, 0, strlen (result) - 3, 0)
3218 && strcmp (result + strlen (result) - 3, " 33") == 0);
3219 ASSERT (retval == strlen (result));
3220 free (result);
3221 }
3222 { /* Pseudo-Denormal. */
3223 static union { unsigned int word[4]; long double value; } x =
3224 { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
3225 char *result;
3226 int retval =
3227 my_asprintf (&result, "%Lg %d", x.value, 33, 44, 55);
3228 ASSERT (result != NULL);
3229 ASSERT (strlen (result) >= 3 + 3
3230 && strisnan (result, 0, strlen (result) - 3, 0)
3231 && strcmp (result + strlen (result) - 3, " 33") == 0);
3232 ASSERT (retval == strlen (result));
3233 free (result);
3234 }
3235 #endif
3236
3237 { /* Width. */
3238 char *result;
3239 int retval =
3240 my_asprintf (&result, "%10Lg %d", 1.75L, 33, 44, 55);
3241 ASSERT (result != NULL);
3242 ASSERT (strcmp (result, " 1.75 33") == 0);
3243 ASSERT (retval == strlen (result));
3244 free (result);
3245 }
3246
3247 { /* FLAG_LEFT. */
3248 char *result;
3249 int retval =
3250 my_asprintf (&result, "%-10Lg %d", 1.75L, 33, 44, 55);
3251 ASSERT (result != NULL);
3252 ASSERT (strcmp (result, "1.75 33") == 0);
3253 ASSERT (retval == strlen (result));
3254 free (result);
3255 }
3256
3257 { /* FLAG_SHOWSIGN. */
3258 char *result;
3259 int retval =
3260 my_asprintf (&result, "%+Lg %d", 1.75L, 33, 44, 55);
3261 ASSERT (result != NULL);
3262 ASSERT (strcmp (result, "+1.75 33") == 0);
3263 ASSERT (retval == strlen (result));
3264 free (result);
3265 }
3266
3267 { /* FLAG_SPACE. */
3268 char *result;
3269 int retval =
3270 my_asprintf (&result, "% Lg %d", 1.75L, 33, 44, 55);
3271 ASSERT (result != NULL);
3272 ASSERT (strcmp (result, " 1.75 33") == 0);
3273 ASSERT (retval == strlen (result));
3274 free (result);
3275 }
3276
3277 { /* FLAG_ALT. */
3278 char *result;
3279 int retval =
3280 my_asprintf (&result, "%#Lg %d", 1.75L, 33, 44, 55);
3281 ASSERT (result != NULL);
3282 ASSERT (strcmp (result, "1.75000 33") == 0);
3283 ASSERT (retval == strlen (result));
3284 free (result);
3285 }
3286
3287 { /* FLAG_ALT. */
3288 char *result;
3289 int retval =
3290 my_asprintf (&result, "%#.Lg %d", 1.75L, 33, 44, 55);
3291 ASSERT (result != NULL);
3292 ASSERT (strcmp (result, "2. 33") == 0);
3293 ASSERT (retval == strlen (result));
3294 free (result);
3295 }
3296
3297 { /* FLAG_ALT. */
3298 char *result;
3299 int retval =
3300 my_asprintf (&result, "%#.Lg %d", 9.75L, 33, 44, 55);
3301 ASSERT (result != NULL);
3302 ASSERT (strcmp (result, "1.e+01 33") == 0
3303 || strcmp (result, "1.e+001 33") == 0);
3304 ASSERT (retval == strlen (result));
3305 free (result);
3306 }
3307
3308 { /* FLAG_ZERO with finite number. */
3309 char *result;
3310 int retval =
3311 my_asprintf (&result, "%010Lg %d", 1234.0L, 33, 44, 55);
3312 ASSERT (result != NULL);
3313 ASSERT (strcmp (result, "0000001234 33") == 0);
3314 ASSERT (retval == strlen (result));
3315 free (result);
3316 }
3317
3318 { /* FLAG_ZERO with infinite number. */
3319 char *result;
3320 int retval =
3321 my_asprintf (&result, "%015Lg %d", - Infinityl (), 33, 44, 55);
3322 ASSERT (result != NULL);
3323 ASSERT (strcmp (result, " -inf 33") == 0
3324 || strcmp (result, " -infinity 33") == 0);
3325 ASSERT (retval == strlen (result));
3326 free (result);
3327 }
3328
3329 { /* FLAG_ZERO with NaN. */
3330 char *result;
3331 int retval =
3332 my_asprintf (&result, "%050Lg %d", NaNl (), 33, 44, 55);
3333 ASSERT (result != NULL);
3334 ASSERT (strlen (result) == 50 + 3
3335 && strisnan (result, strspn (result, " "), strlen (result) - 3, 0)
3336 && strcmp (result + strlen (result) - 3, " 33") == 0);
3337 ASSERT (retval == strlen (result));
3338 free (result);
3339 }
3340
3341 { /* Precision. */
3342 char *result;
3343 int retval =
3344 my_asprintf (&result, "%.Lg %d", 1234.0L, 33, 44, 55);
3345 ASSERT (result != NULL);
3346 ASSERT (strcmp (result, "1e+03 33") == 0
3347 || strcmp (result, "1e+003 33") == 0);
3348 ASSERT (retval == strlen (result));
3349 free (result);
3350 }
3351
3352 { /* Precision with no rounding. */
3353 char *result;
3354 int retval =
3355 my_asprintf (&result, "%.5Lg %d", 999.951L, 33, 44, 55);
3356 ASSERT (result != NULL);
3357 ASSERT (strcmp (result, "999.95 33") == 0);
3358 ASSERT (retval == strlen (result));
3359 free (result);
3360 }
3361
3362 { /* Precision with rounding. */
3363 char *result;
3364 int retval =
3365 my_asprintf (&result, "%.5Lg %d", 999.996L, 33, 44, 55);
3366 ASSERT (result != NULL);
3367 ASSERT (strcmp (result, "1000 33") == 0);
3368 ASSERT (retval == strlen (result));
3369 free (result);
3370 }
3371
3372 /* Test the support of the %n format directive. */
3373
3374 {
3375 int count = -1;
3376 char *result;
3377 int retval =
3378 my_asprintf (&result, "%d %n", 123, &count, 33, 44, 55);
3379 ASSERT (result != NULL);
3380 ASSERT (strcmp (result, "123 ") == 0);
3381 ASSERT (retval == strlen (result));
3382 ASSERT (count == 4);
3383 free (result);
3384 }
3385
3386 /* Test the support of the POSIX/XSI format strings with positions. */
3387
3388 {
3389 char *result;
3390 int retval =
3391 my_asprintf (&result, "%2$d %1$d", 33, 55);
3392 ASSERT (result != NULL);
3393 ASSERT (strcmp (result, "55 33") == 0);
3394 ASSERT (retval == strlen (result));
3395 free (result);
3396 }
3397
3398 /* Test the support of the grouping flag. */
3399
3400 {
3401 char *result;
3402 int retval =
3403 my_asprintf (&result, "%'d %d", 1234567, 99);
3404 ASSERT (result != NULL);
3405 ASSERT (result[strlen (result) - 1] == '9');
3406 ASSERT (retval == strlen (result));
3407 free (result);
3408 }
3409
3410 /* Test the support of the left-adjust flag. */
3411
3412 {
3413 char *result;
3414 int retval =
3415 my_asprintf (&result, "a%*sc", -3, "b");
3416 ASSERT (result != NULL);
3417 ASSERT (strcmp (result, "ab c") == 0);
3418 ASSERT (retval == strlen (result));
3419 free (result);
3420 }
3421
3422 {
3423 char *result;
3424 int retval =
3425 my_asprintf (&result, "a%-*sc", 3, "b");
3426 ASSERT (result != NULL);
3427 ASSERT (strcmp (result, "ab c") == 0);
3428 ASSERT (retval == strlen (result));
3429 free (result);
3430 }
3431
3432 {
3433 char *result;
3434 int retval =
3435 my_asprintf (&result, "a%-*sc", -3, "b");
3436 ASSERT (result != NULL);
3437 ASSERT (strcmp (result, "ab c") == 0);
3438 ASSERT (retval == strlen (result));
3439 free (result);
3440 }
3441
3442 /* Test the support of large precision. */
3443
3444 {
3445 char *result;
3446 int retval =
3447 my_asprintf (&result, "%.4000d %d", 1234567, 99);
3448 size_t i;
3449 ASSERT (result != NULL);
3450 for (i = 0; i < 4000 - 7; i++)
3451 ASSERT (result[i] == '0');
3452 ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
3453 ASSERT (retval == strlen (result));
3454 free (result);
3455 }
3456
3457 {
3458 char *result;
3459 int retval =
3460 my_asprintf (&result, "%.*d %d", 4000, 1234567, 99);
3461 size_t i;
3462 ASSERT (result != NULL);
3463 for (i = 0; i < 4000 - 7; i++)
3464 ASSERT (result[i] == '0');
3465 ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
3466 ASSERT (retval == strlen (result));
3467 free (result);
3468 }
3469
3470 {
3471 char *result;
3472 int retval =
3473 my_asprintf (&result, "%.4000d %d", -1234567, 99);
3474 size_t i;
3475 ASSERT (result != NULL);
3476 ASSERT (result[0] == '-');
3477 for (i = 0; i < 4000 - 7; i++)
3478 ASSERT (result[1 + i] == '0');
3479 ASSERT (strcmp (result + 1 + 4000 - 7, "1234567 99") == 0);
3480 ASSERT (retval == strlen (result));
3481 free (result);
3482 }
3483
3484 {
3485 char *result;
3486 int retval =
3487 my_asprintf (&result, "%.4000u %d", 1234567, 99);
3488 size_t i;
3489 ASSERT (result != NULL);
3490 for (i = 0; i < 4000 - 7; i++)
3491 ASSERT (result[i] == '0');
3492 ASSERT (strcmp (result + 4000 - 7, "1234567 99") == 0);
3493 ASSERT (retval == strlen (result));
3494 free (result);
3495 }
3496
3497 {
3498 char *result;
3499 int retval =
3500 my_asprintf (&result, "%.4000o %d", 1234567, 99);
3501 size_t i;
3502 ASSERT (result != NULL);
3503 for (i = 0; i < 4000 - 7; i++)
3504 ASSERT (result[i] == '0');
3505 ASSERT (strcmp (result + 4000 - 7, "4553207 99") == 0);
3506 ASSERT (retval == strlen (result));
3507 free (result);
3508 }
3509
3510 {
3511 char *result;
3512 int retval =
3513 my_asprintf (&result, "%.4000x %d", 1234567, 99);
3514 size_t i;
3515 ASSERT (result != NULL);
3516 for (i = 0; i < 4000 - 6; i++)
3517 ASSERT (result[i] == '0');
3518 ASSERT (strcmp (result + 4000 - 6, "12d687 99") == 0);
3519 ASSERT (retval == strlen (result));
3520 free (result);
3521 }
3522
3523 {
3524 char *result;
3525 int retval =
3526 my_asprintf (&result, "%#.4000x %d", 1234567, 99);
3527 size_t i;
3528 ASSERT (result != NULL);
3529 ASSERT (result[0] == '0');
3530 ASSERT (result[1] == 'x');
3531 for (i = 0; i < 4000 - 6; i++)
3532 ASSERT (result[2 + i] == '0');
3533 ASSERT (strcmp (result + 2 + 4000 - 6, "12d687 99") == 0);
3534 ASSERT (retval == strlen (result));
3535 free (result);
3536 }
3537
3538 {
3539 char *result;
3540 int retval =
3541 my_asprintf (&result, "%.4000f %d", 1.0, 99);
3542 size_t i;
3543 ASSERT (result != NULL);
3544 ASSERT (result[0] == '1');
3545 ASSERT (result[1] == '.');
3546 for (i = 0; i < 4000; i++)
3547 ASSERT (result[2 + i] == '0');
3548 ASSERT (strcmp (result + 2 + 4000, " 99") == 0);
3549 ASSERT (retval == strlen (result));
3550 free (result);
3551 }
3552
3553 {
3554 char *result;
3555 int retval =
3556 my_asprintf (&result, "%.511f %d", 1.0, 99);
3557 size_t i;
3558 ASSERT (result != NULL);
3559 ASSERT (result[0] == '1');
3560 ASSERT (result[1] == '.');
3561 for (i = 0; i < 511; i++)
3562 ASSERT (result[2 + i] == '0');
3563 ASSERT (strcmp (result + 2 + 511, " 99") == 0);
3564 ASSERT (retval == strlen (result));
3565 free (result);
3566 }
3567
3568 {
3569 char input[5000];
3570 char *result;
3571 int retval;
3572 size_t i;
3573
3574 for (i = 0; i < sizeof (input) - 1; i++)
3575 input[i] = 'a' + ((1000000 / (i + 1)) % 26);
3576 input[i] = '\0';
3577 retval = my_asprintf (&result, "%.4000s %d", input, 99);
3578 ASSERT (result != NULL);
3579 ASSERT (memcmp (result, input, 4000) == 0);
3580 ASSERT (strcmp (result + 4000, " 99") == 0);
3581 ASSERT (retval == strlen (result));
3582 free (result);
3583 }
3584
3585 /* Test the support of the %s format directive. */
3586
3587 /* To verify that these tests succeed, it is necessary to run them under
3588 a tool that checks against invalid memory accesses, such as ElectricFence
3589 or "valgrind --tool=memcheck". */
3590 {
3591 size_t i;
3592
3593 for (i = 1; i <= 8; i++)
3594 {
3595 char *block;
3596 char *result;
3597 int retval;
3598
3599 block = (char *) malloc (i);
3600 memcpy (block, "abcdefgh", i);
3601 retval = my_asprintf (&result, "%.*s", (int) i, block);
3602 ASSERT (result != NULL);
3603 ASSERT (memcmp (result, block, i) == 0);
3604 ASSERT (result[i] == '\0');
3605 ASSERT (retval == strlen (result));
3606 free (result);
3607 free (block);
3608 }
3609 }
3610 #if HAVE_WCHAR_T
3611 {
3612 size_t i;
3613
3614 for (i = 1; i <= 8; i++)
3615 {
3616 wchar_t *block;
3617 size_t j;
3618 char *result;
3619 int retval;
3620
3621 block = (wchar_t *) malloc (i * sizeof (wchar_t));
3622 for (j = 0; j < i; j++)
3623 block[j] = "abcdefgh"[j];
3624 retval = my_asprintf (&result, "%.*ls", (int) i, block);
3625 ASSERT (result != NULL);
3626 ASSERT (memcmp (result, "abcdefgh", i) == 0);
3627 ASSERT (result[i] == '\0');
3628 ASSERT (retval == strlen (result));
3629 free (result);
3630 free (block);
3631 }
3632 }
3633 #endif
3634 }
3635
3636 static int
my_asprintf(char ** result,const char * format,...)3637 my_asprintf (char **result, const char *format, ...)
3638 {
3639 va_list args;
3640 int ret;
3641
3642 va_start (args, format);
3643 ret = vasprintf (result, format, args);
3644 va_end (args);
3645 return ret;
3646 }
3647
3648 static void
test_vasprintf()3649 test_vasprintf ()
3650 {
3651 test_function (my_asprintf);
3652 }
3653
3654 static void
test_asprintf()3655 test_asprintf ()
3656 {
3657 test_function (asprintf);
3658 }
3659
3660 int
main(int argc,char * argv[])3661 main (int argc, char *argv[])
3662 {
3663 test_vasprintf ();
3664 test_asprintf ();
3665 return 0;
3666 }
3667