pty: Activate the signature wrapper of forkpty.
[gnulib.git] / tests / test-strtod.c
1 /*
2  * Copyright (C) 2008-2013 Free Software Foundation, Inc.
3  * Written by Eric Blake
4  *
5  * This program is free software: you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 3 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
17
18 #include <config.h>
19
20 #include <stdlib.h>
21
22 #include "signature.h"
23 SIGNATURE_CHECK (strtod, double, (char const *, char **));
24
25 #include <errno.h>
26 #include <float.h>
27 #include <math.h>
28 #include <string.h>
29
30 #include "isnand-nolibm.h"
31 #include "minus-zero.h"
32 #include "macros.h"
33
34 /* Avoid requiring -lm just for fabs.  */
35 #define FABS(d) ((d) < 0.0 ? -(d) : (d))
36
37 int
38 main (void)
39 {
40   int status = 0;
41   /* Subject sequence empty or invalid.  */
42   {
43     const char input[] = "";
44     char *ptr;
45     double result;
46     errno = 0;
47     result = strtod (input, &ptr);
48     ASSERT (result == 0.0);
49     ASSERT (!signbit (result));
50     ASSERT (ptr == input);
51     ASSERT (errno == 0 || errno == EINVAL);
52   }
53   {
54     const char input[] = " ";
55     char *ptr;
56     double result;
57     errno = 0;
58     result = strtod (input, &ptr);
59     ASSERT (result == 0.0);
60     ASSERT (!signbit (result));
61     ASSERT (ptr == input);
62     ASSERT (errno == 0 || errno == EINVAL);
63   }
64   {
65     const char input[] = " +";
66     char *ptr;
67     double result;
68     errno = 0;
69     result = strtod (input, &ptr);
70     ASSERT (result == 0.0);
71     ASSERT (!signbit (result));
72     ASSERT (ptr == input);
73     ASSERT (errno == 0 || errno == EINVAL);
74   }
75   {
76     const char input[] = " .";
77     char *ptr;
78     double result;
79     errno = 0;
80     result = strtod (input, &ptr);
81     ASSERT (result == 0.0);
82     ASSERT (!signbit (result));
83     ASSERT (ptr == input);
84     ASSERT (errno == 0 || errno == EINVAL);
85   }
86   {
87     const char input[] = " .e0";
88     char *ptr;
89     double result;
90     errno = 0;
91     result = strtod (input, &ptr);
92     ASSERT (result == 0.0);
93     ASSERT (!signbit (result));
94     ASSERT (ptr == input);              /* IRIX 6.5, OSF/1 5.1 */
95     ASSERT (errno == 0 || errno == EINVAL);
96   }
97   {
98     const char input[] = " +.e-0";
99     char *ptr;
100     double result;
101     errno = 0;
102     result = strtod (input, &ptr);
103     ASSERT (result == 0.0);
104     ASSERT (!signbit (result));
105     ASSERT (ptr == input);              /* IRIX 6.5, OSF/1 5.1 */
106     ASSERT (errno == 0 || errno == EINVAL);
107   }
108   {
109     const char input[] = " in";
110     char *ptr;
111     double result;
112     errno = 0;
113     result = strtod (input, &ptr);
114     ASSERT (result == 0.0);
115     ASSERT (!signbit (result));
116     ASSERT (ptr == input);
117     ASSERT (errno == 0 || errno == EINVAL);
118   }
119   {
120     const char input[] = " na";
121     char *ptr;
122     double result;
123     errno = 0;
124     result = strtod (input, &ptr);
125     ASSERT (result == 0.0);
126     ASSERT (!signbit (result));
127     ASSERT (ptr == input);
128     ASSERT (errno == 0 || errno == EINVAL);
129   }
130
131   /* Simple floating point values.  */
132   {
133     const char input[] = "1";
134     char *ptr;
135     double result;
136     errno = 0;
137     result = strtod (input, &ptr);
138     ASSERT (result == 1.0);
139     ASSERT (ptr == input + 1);
140     ASSERT (errno == 0);
141   }
142   {
143     const char input[] = "1.";
144     char *ptr;
145     double result;
146     errno = 0;
147     result = strtod (input, &ptr);
148     ASSERT (result == 1.0);
149     ASSERT (ptr == input + 2);
150     ASSERT (errno == 0);
151   }
152   {
153     const char input[] = ".5";
154     char *ptr;
155     double result;
156     errno = 0;
157     result = strtod (input, &ptr);
158     /* FIXME - gnulib's version is rather inaccurate.  It would be
159        nice to guarantee an exact result, but for now, we settle for a
160        1-ulp error.  */
161     ASSERT (FABS (result - 0.5) < DBL_EPSILON);
162     ASSERT (ptr == input + 2);
163     ASSERT (errno == 0);
164   }
165   {
166     const char input[] = " 1";
167     char *ptr;
168     double result;
169     errno = 0;
170     result = strtod (input, &ptr);
171     ASSERT (result == 1.0);
172     ASSERT (ptr == input + 2);
173     ASSERT (errno == 0);
174   }
175   {
176     const char input[] = "+1";
177     char *ptr;
178     double result;
179     errno = 0;
180     result = strtod (input, &ptr);
181     ASSERT (result == 1.0);
182     ASSERT (ptr == input + 2);
183     ASSERT (errno == 0);
184   }
185   {
186     const char input[] = "-1";
187     char *ptr;
188     double result;
189     errno = 0;
190     result = strtod (input, &ptr);
191     ASSERT (result == -1.0);
192     ASSERT (ptr == input + 2);
193     ASSERT (errno == 0);
194   }
195   {
196     const char input[] = "1e0";
197     char *ptr;
198     double result;
199     errno = 0;
200     result = strtod (input, &ptr);
201     ASSERT (result == 1.0);
202     ASSERT (ptr == input + 3);
203     ASSERT (errno == 0);
204   }
205   {
206     const char input[] = "1e+0";
207     char *ptr;
208     double result;
209     errno = 0;
210     result = strtod (input, &ptr);
211     ASSERT (result == 1.0);
212     ASSERT (ptr == input + 4);
213     ASSERT (errno == 0);
214   }
215   {
216     const char input[] = "1e-0";
217     char *ptr;
218     double result;
219     errno = 0;
220     result = strtod (input, &ptr);
221     ASSERT (result == 1.0);
222     ASSERT (ptr == input + 4);
223     ASSERT (errno == 0);
224   }
225   {
226     const char input[] = "1e1";
227     char *ptr;
228     double result;
229     errno = 0;
230     result = strtod (input, &ptr);
231     ASSERT (result == 10.0);
232     ASSERT (ptr == input + 3);
233     ASSERT (errno == 0);
234   }
235   {
236     const char input[] = "5e-1";
237     char *ptr;
238     double result;
239     errno = 0;
240     result = strtod (input, &ptr);
241     /* FIXME - gnulib's version is rather inaccurate.  It would be
242        nice to guarantee an exact result, but for now, we settle for a
243        1-ulp error.  */
244     ASSERT (FABS (result - 0.5) < DBL_EPSILON);
245     ASSERT (ptr == input + 4);
246     ASSERT (errno == 0);
247   }
248
249   /* Zero.  */
250   {
251     const char input[] = "0";
252     char *ptr;
253     double result;
254     errno = 0;
255     result = strtod (input, &ptr);
256     ASSERT (result == 0.0);
257     ASSERT (!signbit (result));
258     ASSERT (ptr == input + 1);
259     ASSERT (errno == 0);
260   }
261   {
262     const char input[] = ".0";
263     char *ptr;
264     double result;
265     errno = 0;
266     result = strtod (input, &ptr);
267     ASSERT (result == 0.0);
268     ASSERT (!signbit (result));
269     ASSERT (ptr == input + 2);
270     ASSERT (errno == 0);
271   }
272   {
273     const char input[] = "0e0";
274     char *ptr;
275     double result;
276     errno = 0;
277     result = strtod (input, &ptr);
278     ASSERT (result == 0.0);
279     ASSERT (!signbit (result));
280     ASSERT (ptr == input + 3);
281     ASSERT (errno == 0);
282   }
283   {
284     const char input[] = "0e+9999999";
285     char *ptr;
286     double result;
287     errno = 0;
288     result = strtod (input, &ptr);
289     ASSERT (result == 0.0);
290     ASSERT (!signbit (result));
291     ASSERT (ptr == input + 10);
292     ASSERT (errno == 0);
293   }
294   {
295     const char input[] = "0e-9999999";
296     char *ptr;
297     double result;
298     errno = 0;
299     result = strtod (input, &ptr);
300     ASSERT (result == 0.0);
301     ASSERT (!signbit (result));
302     ASSERT (ptr == input + 10);
303     ASSERT (errno == 0);
304   }
305   {
306     const char input[] = "-0";
307     char *ptr;
308     double result;
309     errno = 0;
310     result = strtod (input, &ptr);
311     ASSERT (result == 0.0);
312     ASSERT (!!signbit (result) == !!signbit (minus_zerod)); /* IRIX 6.5, OSF/1 4.0 */
313     ASSERT (ptr == input + 2);
314     ASSERT (errno == 0);
315   }
316
317   /* Suffixes.  */
318   {
319     const char input[] = "1f";
320     char *ptr;
321     double result;
322     errno = 0;
323     result = strtod (input, &ptr);
324     ASSERT (result == 1.0);
325     ASSERT (ptr == input + 1);
326     ASSERT (errno == 0);
327   }
328   {
329     const char input[] = "1.f";
330     char *ptr;
331     double result;
332     errno = 0;
333     result = strtod (input, &ptr);
334     ASSERT (result == 1.0);
335     ASSERT (ptr == input + 2);
336     ASSERT (errno == 0);
337   }
338   {
339     const char input[] = "1e";
340     char *ptr;
341     double result;
342     errno = 0;
343     result = strtod (input, &ptr);
344     ASSERT (result == 1.0);
345     ASSERT (ptr == input + 1);
346     ASSERT (errno == 0);
347   }
348   {
349     const char input[] = "1e+";
350     char *ptr;
351     double result;
352     errno = 0;
353     result = strtod (input, &ptr);
354     ASSERT (result == 1.0);
355     ASSERT (ptr == input + 1);
356     ASSERT (errno == 0);
357   }
358   {
359     const char input[] = "1e-";
360     char *ptr;
361     double result;
362     errno = 0;
363     result = strtod (input, &ptr);
364     ASSERT (result == 1.0);
365     ASSERT (ptr == input + 1);
366     ASSERT (errno == 0);
367   }
368   {
369     const char input[] = "1E 2";
370     char *ptr;
371     double result;
372     errno = 0;
373     result = strtod (input, &ptr);
374     ASSERT (result == 1.0);             /* HP-UX 11.11, IRIX 6.5, OSF/1 4.0 */
375     ASSERT (ptr == input + 1);          /* HP-UX 11.11, IRIX 6.5 */
376     ASSERT (errno == 0);
377   }
378   {
379     const char input[] = "0x";
380     char *ptr;
381     double result;
382     errno = 0;
383     result = strtod (input, &ptr);
384     ASSERT (result == 0.0);
385     ASSERT (!signbit (result));
386     ASSERT (ptr == input + 1);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
387     ASSERT (errno == 0);
388   }
389   {
390     const char input[] = "00x1";
391     char *ptr;
392     double result;
393     errno = 0;
394     result = strtod (input, &ptr);
395     ASSERT (result == 0.0);
396     ASSERT (!signbit (result));
397     ASSERT (ptr == input + 2);
398     ASSERT (errno == 0);
399   }
400   {
401     const char input[] = "-0x";
402     char *ptr;
403     double result;
404     errno = 0;
405     result = strtod (input, &ptr);
406     ASSERT (result == 0.0);
407     ASSERT (!!signbit (result) == !!signbit (minus_zerod)); /* Mac OS X 10.3, FreeBSD 6.2, IRIX 6.5, OSF/1 4.0 */
408     ASSERT (ptr == input + 2);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
409     ASSERT (errno == 0);
410   }
411   {
412     const char input[] = "0xg";
413     char *ptr;
414     double result;
415     errno = 0;
416     result = strtod (input, &ptr);
417     ASSERT (result == 0.0);
418     ASSERT (!signbit (result));
419     ASSERT (ptr == input + 1);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
420     ASSERT (errno == 0);
421   }
422   {
423     const char input[] = "0xp";
424     char *ptr;
425     double result;
426     errno = 0;
427     result = strtod (input, &ptr);
428     ASSERT (result == 0.0);
429     ASSERT (!signbit (result));
430     ASSERT (ptr == input + 1);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
431     ASSERT (errno == 0);
432   }
433   {
434     const char input[] = "0XP";
435     char *ptr;
436     double result;
437     errno = 0;
438     result = strtod (input, &ptr);
439     ASSERT (result == 0.0);
440     ASSERT (!signbit (result));
441     ASSERT (ptr == input + 1);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
442     ASSERT (errno == 0);
443   }
444   {
445     const char input[] = "0x.";
446     char *ptr;
447     double result;
448     errno = 0;
449     result = strtod (input, &ptr);
450     ASSERT (result == 0.0);
451     ASSERT (!signbit (result));
452     ASSERT (ptr == input + 1);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
453     ASSERT (errno == 0);
454   }
455   {
456     const char input[] = "0xp+";
457     char *ptr;
458     double result;
459     errno = 0;
460     result = strtod (input, &ptr);
461     ASSERT (result == 0.0);
462     ASSERT (!signbit (result));
463     ASSERT (ptr == input + 1);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
464     ASSERT (errno == 0);
465   }
466   {
467     const char input[] = "0xp+1";
468     char *ptr;
469     double result;
470     errno = 0;
471     result = strtod (input, &ptr);
472     ASSERT (result == 0.0);
473     ASSERT (!signbit (result));
474     ASSERT (ptr == input + 1);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
475     ASSERT (errno == 0);
476   }
477   {
478     const char input[] = "0x.p+1";
479     char *ptr;
480     double result;
481     errno = 0;
482     result = strtod (input, &ptr);
483     ASSERT (result == 0.0);
484     ASSERT (!signbit (result));
485     ASSERT (ptr == input + 1);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
486     ASSERT (errno == 0);
487   }
488   {
489     const char input[] = "1p+1";
490     char *ptr;
491     double result;
492     errno = 0;
493     result = strtod (input, &ptr);
494     ASSERT (result == 1.0);
495     ASSERT (ptr == input + 1);
496     ASSERT (errno == 0);
497   }
498   {
499     const char input[] = "1P+1";
500     char *ptr;
501     double result;
502     errno = 0;
503     result = strtod (input, &ptr);
504     ASSERT (result == 1.0);
505     ASSERT (ptr == input + 1);
506     ASSERT (errno == 0);
507   }
508
509   /* Overflow/underflow.  */
510   {
511     const char input[] = "1E1000000";
512     char *ptr;
513     double result;
514     errno = 0;
515     result = strtod (input, &ptr);
516     ASSERT (result == HUGE_VAL);
517     ASSERT (ptr == input + 9);          /* OSF/1 5.1 */
518     ASSERT (errno == ERANGE);
519   }
520   {
521     const char input[] = "-1E1000000";
522     char *ptr;
523     double result;
524     errno = 0;
525     result = strtod (input, &ptr);
526     ASSERT (result == -HUGE_VAL);
527     ASSERT (ptr == input + 10);
528     ASSERT (errno == ERANGE);
529   }
530   {
531     const char input[] = "1E-100000";
532     char *ptr;
533     double result;
534     errno = 0;
535     result = strtod (input, &ptr);
536     ASSERT (0.0 <= result && result <= DBL_MIN);
537     ASSERT (!signbit (result));
538     ASSERT (ptr == input + 9);
539     ASSERT (errno == ERANGE);
540   }
541   {
542     const char input[] = "-1E-100000";
543     char *ptr;
544     double result;
545     errno = 0;
546     result = strtod (input, &ptr);
547     ASSERT (-DBL_MIN <= result && result <= 0.0);
548 #if 0
549     /* FIXME - this is glibc bug 5995; POSIX allows returning positive
550        0 on negative underflow, even though quality of implementation
551        demands preserving the sign.  Disable this test until fixed
552        glibc is more prevalent.  */
553     ASSERT (!!signbit (result) == !!signbit (minus_zerod)); /* glibc-2.3.6, mingw */
554 #endif
555     ASSERT (ptr == input + 10);
556     ASSERT (errno == ERANGE);
557   }
558   {
559     const char input[] = "1E 1000000";
560     char *ptr;
561     double result;
562     errno = 0;
563     result = strtod (input, &ptr);
564     ASSERT (result == 1.0);             /* HP-UX 11.11, IRIX 6.5, OSF/1 4.0 */
565     ASSERT (ptr == input + 1);          /* HP-UX 11.11, IRIX 6.5 */
566     ASSERT (errno == 0);
567   }
568   {
569     const char input[] = "0x1P 1000000";
570     char *ptr;
571     double result;
572     errno = 0;
573     result = strtod (input, &ptr);
574     ASSERT (result == 1.0);             /* NetBSD 3.0, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
575     ASSERT (ptr == input + 3);          /* NetBSD 3.0, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
576     ASSERT (errno == 0);
577   }
578
579   /* Infinity.  */
580   {
581     const char input[] = "iNf";
582     char *ptr;
583     double result;
584     errno = 0;
585     result = strtod (input, &ptr);
586     ASSERT (result == HUGE_VAL);        /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
587     ASSERT (ptr == input + 3);          /* OpenBSD 4.0, HP-UX 11.00, IRIX 6.5, OSF/1 5.1, Solaris 9, mingw */
588     ASSERT (errno == 0);                /* HP-UX 11.11, OSF/1 4.0 */
589   }
590   {
591     const char input[] = "-InF";
592     char *ptr;
593     double result;
594     errno = 0;
595     result = strtod (input, &ptr);
596     ASSERT (result == -HUGE_VAL);       /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
597     ASSERT (ptr == input + 4);          /* OpenBSD 4.0, HP-UX 11.00, IRIX 6.5, OSF/1 4.0, Solaris 9, mingw */
598     ASSERT (errno == 0);                /* HP-UX 11.11, OSF/1 4.0 */
599   }
600   {
601     const char input[] = "infinite";
602     char *ptr;
603     double result;
604     errno = 0;
605     result = strtod (input, &ptr);
606     ASSERT (result == HUGE_VAL);        /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
607     ASSERT (ptr == input + 3);          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
608     ASSERT (errno == 0);                /* OSF/1 4.0 */
609   }
610   {
611     const char input[] = "infinitY";
612     char *ptr;
613     double result;
614     errno = 0;
615     result = strtod (input, &ptr);
616     ASSERT (result == HUGE_VAL);        /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
617     ASSERT (ptr == input + 8);          /* OpenBSD 4.0, HP-UX 11.00, IRIX 6.5, OSF/1 5.1, Solaris 9, mingw */
618     ASSERT (errno == 0);                /* HP-UX 11.11, OSF/1 4.0 */
619   }
620   {
621     const char input[] = "infinitY.";
622     char *ptr;
623     double result;
624     errno = 0;
625     result = strtod (input, &ptr);
626     ASSERT (result == HUGE_VAL);        /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
627     ASSERT (ptr == input + 8);          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
628     ASSERT (errno == 0);                /* OSF/1 4.0 */
629   }
630
631   /* NaN.  Some processors set the sign bit of the default NaN, so all
632      we check is that using a sign changes the result.  */
633   {
634     const char input[] = "-nan";
635     char *ptr1;
636     char *ptr2;
637     double result1;
638     double result2;
639     errno = 0;
640     result1 = strtod (input, &ptr1);
641     result2 = strtod (input + 1, &ptr2);
642 #if 1 /* All known CPUs support NaNs.  */
643     ASSERT (isnand (result1));          /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
644     ASSERT (isnand (result2));          /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
645 # if 0
646     /* Sign bits of NaN is a portability sticking point, not worth
647        worrying about.  */
648     ASSERT (!!signbit (result1) != !!signbit (result2)); /* glibc-2.3.6, IRIX 6.5, OSF/1 5.1, mingw */
649 # endif
650     ASSERT (ptr1 == input + 4);         /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
651     ASSERT (ptr2 == input + 4);         /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
652     ASSERT (errno == 0);                /* HP-UX 11.11 */
653 #else
654     ASSERT (result1 == 0.0);
655     ASSERT (result2 == 0.0);
656     ASSERT (!signbit (result1));
657     ASSERT (!signbit (result2));
658     ASSERT (ptr1 == input);
659     ASSERT (ptr2 == input + 1);
660     ASSERT (errno == 0 || errno == EINVAL);
661 #endif
662   }
663   {
664     const char input[] = "+nan(";
665     char *ptr1;
666     char *ptr2;
667     double result1;
668     double result2;
669     errno = 0;
670     result1 = strtod (input, &ptr1);
671     result2 = strtod (input + 1, &ptr2);
672 #if 1 /* All known CPUs support NaNs.  */
673     ASSERT (isnand (result1));          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
674     ASSERT (isnand (result2));          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
675     ASSERT (!!signbit (result1) == !!signbit (result2));
676     ASSERT (ptr1 == input + 4);         /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
677     ASSERT (ptr2 == input + 4);         /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
678     ASSERT (errno == 0);
679 #else
680     ASSERT (result1 == 0.0);
681     ASSERT (result2 == 0.0);
682     ASSERT (!signbit (result1));
683     ASSERT (!signbit (result2));
684     ASSERT (ptr1 == input);
685     ASSERT (ptr2 == input + 1);
686     ASSERT (errno == 0 || errno == EINVAL);
687 #endif
688   }
689   {
690     const char input[] = "-nan()";
691     char *ptr1;
692     char *ptr2;
693     double result1;
694     double result2;
695     errno = 0;
696     result1 = strtod (input, &ptr1);
697     result2 = strtod (input + 1, &ptr2);
698 #if 1 /* All known CPUs support NaNs.  */
699     ASSERT (isnand (result1));          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
700     ASSERT (isnand (result2));          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
701 # if 0
702     /* Sign bits of NaN is a portability sticking point, not worth
703        worrying about.  */
704     ASSERT (!!signbit (result1) != !!signbit (result2)); /* glibc-2.3.6, IRIX 6.5, OSF/1 5.1, mingw */
705 # endif
706     ASSERT (ptr1 == input + 6);         /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
707     ASSERT (ptr2 == input + 6);         /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
708     ASSERT (errno == 0);
709 #else
710     ASSERT (result1 == 0.0);
711     ASSERT (result2 == 0.0);
712     ASSERT (!signbit (result1));
713     ASSERT (!signbit (result2));
714     ASSERT (ptr1 == input);
715     ASSERT (ptr2 == input + 1);
716     ASSERT (errno == 0 || errno == EINVAL);
717 #endif
718   }
719   {
720     const char input[] = " nan().";
721     char *ptr;
722     double result;
723     errno = 0;
724     result = strtod (input, &ptr);
725 #if 1 /* All known CPUs support NaNs.  */
726     ASSERT (isnand (result));           /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
727     ASSERT (ptr == input + 6);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
728     ASSERT (errno == 0);
729 #else
730     ASSERT (result == 0.0);
731     ASSERT (!signbit (result));
732     ASSERT (ptr == input);
733     ASSERT (errno == 0 || errno == EINVAL);
734 #endif
735   }
736   {
737     /* The behavior of nan(0) is implementation-defined, but all
738        implementations we know of which handle optional
739        n-char-sequences handle nan(0) the same as nan().  */
740     const char input[] = "-nan(0).";
741     char *ptr1;
742     char *ptr2;
743     double result1;
744     double result2;
745     errno = 0;
746     result1 = strtod (input, &ptr1);
747     result2 = strtod (input + 1, &ptr2);
748 #if 1 /* All known CPUs support NaNs.  */
749     ASSERT (isnand (result1));          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
750     ASSERT (isnand (result2));          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
751 # if 0
752     /* Sign bits of NaN is a portability sticking point, not worth
753        worrying about.  */
754     ASSERT (!!signbit (result1) != !!signbit (result2)); /* glibc-2.3.6, IRIX 6.5, OSF/1 5.1, mingw */
755 # endif
756     ASSERT (ptr1 == input + 7);         /* glibc-2.3.6, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
757     ASSERT (ptr2 == input + 7);         /* glibc-2.3.6, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
758     ASSERT (errno == 0);
759 #else
760     ASSERT (result1 == 0.0);
761     ASSERT (result2 == 0.0);
762     ASSERT (!signbit (result1));
763     ASSERT (!signbit (result2));
764     ASSERT (ptr1 == input);
765     ASSERT (ptr2 == input + 1);
766     ASSERT (errno == 0 || errno == EINVAL);
767 #endif
768   }
769
770   /* Hex.  */
771   {
772     const char input[] = "0xa";
773     char *ptr;
774     double result;
775     errno = 0;
776     result = strtod (input, &ptr);
777     ASSERT (result == 10.0);            /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
778     ASSERT (ptr == input + 3);          /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
779     ASSERT (errno == 0);
780   }
781   {
782     const char input[] = "0XA";
783     char *ptr;
784     double result;
785     errno = 0;
786     result = strtod (input, &ptr);
787     ASSERT (result == 10.0);            /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
788     ASSERT (ptr == input + 3);          /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
789     ASSERT (errno == 0);
790   }
791   {
792     const char input[] = "0x1p";
793     char *ptr;
794     double result;
795     errno = 0;
796     result = strtod (input, &ptr);
797     ASSERT (result == 1.0);             /* NetBSD 3.0, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
798     ASSERT (ptr == input + 3);          /* NetBSD 3.0, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
799     ASSERT (errno == 0);
800   }
801   {
802     const char input[] = "0x1p+";
803     char *ptr;
804     double result;
805     errno = 0;
806     result = strtod (input, &ptr);
807     ASSERT (result == 1.0);             /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
808     ASSERT (ptr == input + 3);          /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
809     ASSERT (errno == 0);
810   }
811   {
812     const char input[] = "0x1P+";
813     char *ptr;
814     double result;
815     errno = 0;
816     result = strtod (input, &ptr);
817     ASSERT (result == 1.0);             /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
818     ASSERT (ptr == input + 3);          /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
819     ASSERT (errno == 0);
820   }
821   {
822     const char input[] = "0x1p+1";
823     char *ptr;
824     double result;
825     errno = 0;
826     result = strtod (input, &ptr);
827     ASSERT (result == 2.0);             /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
828     ASSERT (ptr == input + 6);          /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
829     ASSERT (errno == 0);
830   }
831   {
832     const char input[] = "0X1P+1";
833     char *ptr;
834     double result;
835     errno = 0;
836     result = strtod (input, &ptr);
837     ASSERT (result == 2.0);             /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
838     ASSERT (ptr == input + 6);          /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
839     ASSERT (errno == 0);
840   }
841   {
842     const char input[] = "0x1p+1a";
843     char *ptr;
844     double result;
845     errno = 0;
846     result = strtod (input, &ptr);
847     ASSERT (result == 2.0);             /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
848     ASSERT (ptr == input + 6);          /* NetBSD 3.0, OpenBSD 4.0, AIX 5.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
849     ASSERT (errno == 0);
850   }
851   {
852     const char input[] = "0x1p 2";
853     char *ptr;
854     double result;
855     errno = 0;
856     result = strtod (input, &ptr);
857     ASSERT (result == 1.0);             /* NetBSD 3.0, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
858     ASSERT (ptr == input + 3);          /* NetBSD 3.0, OpenBSD 4.0, AIX 7.1, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 10, mingw */
859     ASSERT (errno == 0);
860   }
861
862   /* Large buffers.  */
863   {
864     size_t m = 1000000;
865     char *input = malloc (m + 1);
866     if (input)
867       {
868         char *ptr;
869         double result;
870         memset (input, '\t', m - 1);
871         input[m - 1] = '1';
872         input[m] = '\0';
873         errno = 0;
874         result = strtod (input, &ptr);
875         ASSERT (result == 1.0);
876         ASSERT (ptr == input + m);
877         ASSERT (errno == 0);
878       }
879     free (input);
880   }
881   {
882     size_t m = 1000000;
883     char *input = malloc (m + 1);
884     if (input)
885       {
886         char *ptr;
887         double result;
888         memset (input, '0', m - 1);
889         input[m - 1] = '1';
890         input[m] = '\0';
891         errno = 0;
892         result = strtod (input, &ptr);
893         ASSERT (result == 1.0);
894         ASSERT (ptr == input + m);
895         ASSERT (errno == 0);
896       }
897     free (input);
898   }
899 #if 0
900   /* Newlib has an artificial limit of 20000 for the exponent.  TODO -
901      gnulib should fix this.  */
902   {
903     size_t m = 1000000;
904     char *input = malloc (m + 1);
905     if (input)
906       {
907         char *ptr;
908         double result;
909         input[0] = '.';
910         memset (input + 1, '0', m - 10);
911         input[m - 9] = '1';
912         input[m - 8] = 'e';
913         input[m - 7] = '+';
914         input[m - 6] = '9';
915         input[m - 5] = '9';
916         input[m - 4] = '9';
917         input[m - 3] = '9';
918         input[m - 2] = '9';
919         input[m - 1] = '1';
920         input[m] = '\0';
921         errno = 0;
922         result = strtod (input, &ptr);
923         ASSERT (result == 1.0);         /* Mac OS X 10.3, FreeBSD 6.2, NetBSD 3.0, OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
924         ASSERT (ptr == input + m);      /* OSF/1 5.1 */
925         ASSERT (errno == 0);            /* Mac OS X 10.3, FreeBSD 6.2, NetBSD 3.0, OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
926       }
927     free (input);
928   }
929   {
930     size_t m = 1000000;
931     char *input = malloc (m + 1);
932     if (input)
933       {
934         char *ptr;
935         double result;
936         input[0] = '1';
937         memset (input + 1, '0', m - 9);
938         input[m - 8] = 'e';
939         input[m - 7] = '-';
940         input[m - 6] = '9';
941         input[m - 5] = '9';
942         input[m - 4] = '9';
943         input[m - 3] = '9';
944         input[m - 2] = '9';
945         input[m - 1] = '1';
946         input[m] = '\0';
947         errno = 0;
948         result = strtod (input, &ptr);
949         ASSERT (result == 1.0);         /* Mac OS X 10.3, FreeBSD 6.2, NetBSD 3.0, OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
950         ASSERT (ptr == input + m);
951         ASSERT (errno == 0);            /* Mac OS X 10.3, FreeBSD 6.2, NetBSD 3.0, OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
952       }
953     free (input);
954   }
955 #endif
956   {
957     size_t m = 1000000;
958     char *input = malloc (m + 1);
959     if (input)
960       {
961         char *ptr;
962         double result;
963         input[0] = '-';
964         input[1] = '0';
965         input[2] = 'e';
966         input[3] = '1';
967         memset (input + 4, '0', m - 3);
968         input[m] = '\0';
969         errno = 0;
970         result = strtod (input, &ptr);
971         ASSERT (result == 0.0);
972         ASSERT (!!signbit (result) == !!signbit (minus_zerod)); /* IRIX 6.5, OSF/1 4.0 */
973         ASSERT (ptr == input + m);
974         ASSERT (errno == 0);
975       }
976     free (input);
977   }
978
979   /* Rounding.  */
980   /* TODO - is it worth some tests of rounding for typical IEEE corner
981      cases, such as .5 ULP rounding up to the smallest denormal and
982      not causing underflow, or DBL_MIN - .5 ULP not causing an
983      infinite loop?  */
984
985   return status;
986 }