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