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