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