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