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