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