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