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