Bump to m4 1.4.19
[platform/upstream/m4.git] / tests / test-strtod.c
1 /*
2  * Copyright (C) 2008-2021 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 <https://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     ASSERT (result == 0.5);
159     ASSERT (ptr == input + 2);
160     ASSERT (errno == 0);
161   }
162   {
163     const char input[] = " 1";
164     char *ptr;
165     double result;
166     errno = 0;
167     result = strtod (input, &ptr);
168     ASSERT (result == 1.0);
169     ASSERT (ptr == input + 2);
170     ASSERT (errno == 0);
171   }
172   {
173     const char input[] = "+1";
174     char *ptr;
175     double result;
176     errno = 0;
177     result = strtod (input, &ptr);
178     ASSERT (result == 1.0);
179     ASSERT (ptr == input + 2);
180     ASSERT (errno == 0);
181   }
182   {
183     const char input[] = "-1";
184     char *ptr;
185     double result;
186     errno = 0;
187     result = strtod (input, &ptr);
188     ASSERT (result == -1.0);
189     ASSERT (ptr == input + 2);
190     ASSERT (errno == 0);
191   }
192   {
193     const char input[] = "1e0";
194     char *ptr;
195     double result;
196     errno = 0;
197     result = strtod (input, &ptr);
198     ASSERT (result == 1.0);
199     ASSERT (ptr == input + 3);
200     ASSERT (errno == 0);
201   }
202   {
203     const char input[] = "1e+0";
204     char *ptr;
205     double result;
206     errno = 0;
207     result = strtod (input, &ptr);
208     ASSERT (result == 1.0);
209     ASSERT (ptr == input + 4);
210     ASSERT (errno == 0);
211   }
212   {
213     const char input[] = "1e-0";
214     char *ptr;
215     double result;
216     errno = 0;
217     result = strtod (input, &ptr);
218     ASSERT (result == 1.0);
219     ASSERT (ptr == input + 4);
220     ASSERT (errno == 0);
221   }
222   {
223     const char input[] = "1e1";
224     char *ptr;
225     double result;
226     errno = 0;
227     result = strtod (input, &ptr);
228     ASSERT (result == 10.0);
229     ASSERT (ptr == input + 3);
230     ASSERT (errno == 0);
231   }
232   {
233     const char input[] = "5e-1";
234     char *ptr;
235     double result;
236     errno = 0;
237     result = strtod (input, &ptr);
238     ASSERT (result == 0.5);
239     ASSERT (ptr == input + 4);
240     ASSERT (errno == 0);
241   }
242
243   /* Zero.  */
244   {
245     const char input[] = "0";
246     char *ptr;
247     double result;
248     errno = 0;
249     result = strtod (input, &ptr);
250     ASSERT (result == 0.0);
251     ASSERT (!signbit (result));
252     ASSERT (ptr == input + 1);
253     ASSERT (errno == 0);
254   }
255   {
256     const char input[] = ".0";
257     char *ptr;
258     double result;
259     errno = 0;
260     result = strtod (input, &ptr);
261     ASSERT (result == 0.0);
262     ASSERT (!signbit (result));
263     ASSERT (ptr == input + 2);
264     ASSERT (errno == 0);
265   }
266   {
267     const char input[] = "0e0";
268     char *ptr;
269     double result;
270     errno = 0;
271     result = strtod (input, &ptr);
272     ASSERT (result == 0.0);
273     ASSERT (!signbit (result));
274     ASSERT (ptr == input + 3);
275     ASSERT (errno == 0);
276   }
277   {
278     const char input[] = "0e+9999999";
279     char *ptr;
280     double result;
281     errno = 0;
282     result = strtod (input, &ptr);
283     ASSERT (result == 0.0);
284     ASSERT (!signbit (result));
285     ASSERT (ptr == input + 10);
286     ASSERT (errno == 0);
287   }
288   {
289     const char input[] = "0e-9999999";
290     char *ptr;
291     double result;
292     errno = 0;
293     result = strtod (input, &ptr);
294     ASSERT (result == 0.0);
295     ASSERT (!signbit (result));
296     ASSERT (ptr == input + 10);
297     ASSERT (errno == 0);
298   }
299   {
300     const char input[] = "-0";
301     char *ptr;
302     double result;
303     errno = 0;
304     result = strtod (input, &ptr);
305     ASSERT (result == 0.0);
306     ASSERT (!!signbit (result) == !!signbit (minus_zerod)); /* IRIX 6.5, OSF/1 4.0 */
307     ASSERT (ptr == input + 2);
308     ASSERT (errno == 0);
309   }
310
311   /* Suffixes.  */
312   {
313     const char input[] = "1f";
314     char *ptr;
315     double result;
316     errno = 0;
317     result = strtod (input, &ptr);
318     ASSERT (result == 1.0);
319     ASSERT (ptr == input + 1);
320     ASSERT (errno == 0);
321   }
322   {
323     const char input[] = "1.f";
324     char *ptr;
325     double result;
326     errno = 0;
327     result = strtod (input, &ptr);
328     ASSERT (result == 1.0);
329     ASSERT (ptr == input + 2);
330     ASSERT (errno == 0);
331   }
332   {
333     const char input[] = "1e";
334     char *ptr;
335     double result;
336     errno = 0;
337     result = strtod (input, &ptr);
338     ASSERT (result == 1.0);
339     ASSERT (ptr == input + 1);
340     ASSERT (errno == 0);
341   }
342   {
343     const char input[] = "1e+";
344     char *ptr;
345     double result;
346     errno = 0;
347     result = strtod (input, &ptr);
348     ASSERT (result == 1.0);
349     ASSERT (ptr == input + 1);
350     ASSERT (errno == 0);
351   }
352   {
353     const char input[] = "1e-";
354     char *ptr;
355     double result;
356     errno = 0;
357     result = strtod (input, &ptr);
358     ASSERT (result == 1.0);
359     ASSERT (ptr == input + 1);
360     ASSERT (errno == 0);
361   }
362   {
363     const char input[] = "1E 2";
364     char *ptr;
365     double result;
366     errno = 0;
367     result = strtod (input, &ptr);
368     ASSERT (result == 1.0);             /* HP-UX 11.11, IRIX 6.5, OSF/1 4.0 */
369     ASSERT (ptr == input + 1);          /* HP-UX 11.11, IRIX 6.5 */
370     ASSERT (errno == 0);
371   }
372   {
373     const char input[] = "0x";
374     char *ptr;
375     double result;
376     errno = 0;
377     result = strtod (input, &ptr);
378     ASSERT (result == 0.0);
379     ASSERT (!signbit (result));
380     ASSERT (ptr == input + 1);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
381     ASSERT (errno == 0);
382   }
383   {
384     const char input[] = "00x1";
385     char *ptr;
386     double result;
387     errno = 0;
388     result = strtod (input, &ptr);
389     ASSERT (result == 0.0);
390     ASSERT (!signbit (result));
391     ASSERT (ptr == input + 2);
392     ASSERT (errno == 0);
393   }
394   {
395     const char input[] = "-0x";
396     char *ptr;
397     double result;
398     errno = 0;
399     result = strtod (input, &ptr);
400     ASSERT (result == 0.0);
401     ASSERT (!!signbit (result) == !!signbit (minus_zerod)); /* Mac OS X 10.3, FreeBSD 6.2, IRIX 6.5, OSF/1 4.0 */
402     ASSERT (ptr == input + 2);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
403     ASSERT (errno == 0);
404   }
405   {
406     const char input[] = "0xg";
407     char *ptr;
408     double result;
409     errno = 0;
410     result = strtod (input, &ptr);
411     ASSERT (result == 0.0);
412     ASSERT (!signbit (result));
413     ASSERT (ptr == input + 1);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
414     ASSERT (errno == 0);
415   }
416   {
417     const char input[] = "0xp";
418     char *ptr;
419     double result;
420     errno = 0;
421     result = strtod (input, &ptr);
422     ASSERT (result == 0.0);
423     ASSERT (!signbit (result));
424     ASSERT (ptr == input + 1);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
425     ASSERT (errno == 0);
426   }
427   {
428     const char input[] = "0XP";
429     char *ptr;
430     double result;
431     errno = 0;
432     result = strtod (input, &ptr);
433     ASSERT (result == 0.0);
434     ASSERT (!signbit (result));
435     ASSERT (ptr == input + 1);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
436     ASSERT (errno == 0);
437   }
438   {
439     const char input[] = "0x.";
440     char *ptr;
441     double result;
442     errno = 0;
443     result = strtod (input, &ptr);
444     ASSERT (result == 0.0);
445     ASSERT (!signbit (result));
446     ASSERT (ptr == input + 1);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
447     ASSERT (errno == 0);
448   }
449   {
450     const char input[] = "0xp+";
451     char *ptr;
452     double result;
453     errno = 0;
454     result = strtod (input, &ptr);
455     ASSERT (result == 0.0);
456     ASSERT (!signbit (result));
457     ASSERT (ptr == input + 1);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
458     ASSERT (errno == 0);
459   }
460   {
461     const char input[] = "0xp+1";
462     char *ptr;
463     double result;
464     errno = 0;
465     result = strtod (input, &ptr);
466     ASSERT (result == 0.0);
467     ASSERT (!signbit (result));
468     ASSERT (ptr == input + 1);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
469     ASSERT (errno == 0);
470   }
471   {
472     const char input[] = "0x.p+1";
473     char *ptr;
474     double result;
475     errno = 0;
476     result = strtod (input, &ptr);
477     ASSERT (result == 0.0);
478     ASSERT (!signbit (result));
479     ASSERT (ptr == input + 1);          /* glibc-2.3.6, Mac OS X 10.3, FreeBSD 6.2, AIX 7.1 */
480     ASSERT (errno == 0);
481   }
482   {
483     const char input[] = "1p+1";
484     char *ptr;
485     double result;
486     errno = 0;
487     result = strtod (input, &ptr);
488     ASSERT (result == 1.0);
489     ASSERT (ptr == input + 1);
490     ASSERT (errno == 0);
491   }
492   {
493     const char input[] = "1P+1";
494     char *ptr;
495     double result;
496     errno = 0;
497     result = strtod (input, &ptr);
498     ASSERT (result == 1.0);
499     ASSERT (ptr == input + 1);
500     ASSERT (errno == 0);
501   }
502
503   /* Overflow/underflow.  */
504   {
505     const char input[] = "1E1000000";
506     char *ptr;
507     double result;
508     errno = 0;
509     result = strtod (input, &ptr);
510     ASSERT (result == HUGE_VAL);
511     ASSERT (ptr == input + 9);          /* OSF/1 5.1 */
512     ASSERT (errno == ERANGE);
513   }
514   {
515     const char input[] = "-1E1000000";
516     char *ptr;
517     double result;
518     errno = 0;
519     result = strtod (input, &ptr);
520     ASSERT (result == -HUGE_VAL);
521     ASSERT (ptr == input + 10);
522     ASSERT (errno == ERANGE);
523   }
524   {
525     const char input[] = "1E-100000";
526     char *ptr;
527     double result;
528     errno = 0;
529     result = strtod (input, &ptr);
530     ASSERT (0.0 <= result && result <= DBL_MIN);
531     ASSERT (!signbit (result));
532     ASSERT (ptr == input + 9);
533     ASSERT (errno == ERANGE);
534   }
535   {
536     const char input[] = "-1E-100000";
537     char *ptr;
538     double result;
539     errno = 0;
540     result = strtod (input, &ptr);
541     ASSERT (-DBL_MIN <= result && result <= 0.0);
542 #if 0
543     /* FIXME - this is glibc bug 5995; POSIX allows returning positive
544        0 on negative underflow, even though quality of implementation
545        demands preserving the sign.  Disable this test until fixed
546        glibc is more prevalent.  */
547     ASSERT (!!signbit (result) == !!signbit (minus_zerod)); /* glibc-2.3.6, mingw */
548 #endif
549     ASSERT (ptr == input + 10);
550     ASSERT (errno == ERANGE);
551   }
552   {
553     const char input[] = "1E 1000000";
554     char *ptr;
555     double result;
556     errno = 0;
557     result = strtod (input, &ptr);
558     ASSERT (result == 1.0);             /* HP-UX 11.11, IRIX 6.5, OSF/1 4.0 */
559     ASSERT (ptr == input + 1);          /* HP-UX 11.11, IRIX 6.5 */
560     ASSERT (errno == 0);
561   }
562   {
563     const char input[] = "0x1P 1000000";
564     char *ptr;
565     double result;
566     errno = 0;
567     result = strtod (input, &ptr);
568     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 */
569     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 */
570     ASSERT (errno == 0);
571   }
572
573   /* Infinity.  */
574   {
575     const char input[] = "iNf";
576     char *ptr;
577     double result;
578     errno = 0;
579     result = strtod (input, &ptr);
580     ASSERT (result == HUGE_VAL);        /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
581     ASSERT (ptr == input + 3);          /* OpenBSD 4.0, HP-UX 11.00, IRIX 6.5, OSF/1 5.1, Solaris 9, mingw */
582     ASSERT (errno == 0);                /* HP-UX 11.11, OSF/1 4.0 */
583   }
584   {
585     const char input[] = "-InF";
586     char *ptr;
587     double result;
588     errno = 0;
589     result = strtod (input, &ptr);
590     ASSERT (result == -HUGE_VAL);       /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
591     ASSERT (ptr == input + 4);          /* OpenBSD 4.0, HP-UX 11.00, IRIX 6.5, OSF/1 4.0, Solaris 9, mingw */
592     ASSERT (errno == 0);                /* HP-UX 11.11, OSF/1 4.0 */
593   }
594   {
595     const char input[] = "infinite";
596     char *ptr;
597     double result;
598     errno = 0;
599     result = strtod (input, &ptr);
600     ASSERT (result == HUGE_VAL);        /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
601     ASSERT (ptr == input + 3);          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
602     ASSERT (errno == 0);                /* OSF/1 4.0 */
603   }
604   {
605     const char input[] = "infinitY";
606     char *ptr;
607     double result;
608     errno = 0;
609     result = strtod (input, &ptr);
610     ASSERT (result == HUGE_VAL);        /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
611     ASSERT (ptr == input + 8);          /* OpenBSD 4.0, HP-UX 11.00, IRIX 6.5, OSF/1 5.1, Solaris 9, mingw */
612     ASSERT (errno == 0);                /* HP-UX 11.11, OSF/1 4.0 */
613   }
614   {
615     const char input[] = "infinitY.";
616     char *ptr;
617     double result;
618     errno = 0;
619     result = strtod (input, &ptr);
620     ASSERT (result == HUGE_VAL);        /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
621     ASSERT (ptr == input + 8);          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
622     ASSERT (errno == 0);                /* OSF/1 4.0 */
623   }
624
625   /* NaN.  Some processors set the sign bit of the default NaN, so all
626      we check is that using a sign changes the result.  */
627   {
628     const char input[] = "-nan";
629     char *ptr1;
630     char *ptr2;
631     double result1;
632     double result2;
633     errno = 0;
634     result1 = strtod (input, &ptr1);
635     result2 = strtod (input + 1, &ptr2);
636 #if 1 /* All known CPUs support NaNs.  */
637     ASSERT (isnand (result1));          /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
638     ASSERT (isnand (result2));          /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, mingw */
639 # if 0
640     /* Sign bits of NaN is a portability sticking point, not worth
641        worrying about.  */
642     ASSERT (!!signbit (result1) != !!signbit (result2)); /* glibc-2.3.6, IRIX 6.5, OSF/1 5.1, mingw */
643 # endif
644     ASSERT (ptr1 == input + 4);         /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
645     ASSERT (ptr2 == input + 4);         /* OpenBSD 4.0, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
646     ASSERT (errno == 0);                /* HP-UX 11.11 */
647 #else
648     ASSERT (result1 == 0.0);
649     ASSERT (result2 == 0.0);
650     ASSERT (!signbit (result1));
651     ASSERT (!signbit (result2));
652     ASSERT (ptr1 == input);
653     ASSERT (ptr2 == input + 1);
654     ASSERT (errno == 0 || errno == EINVAL);
655 #endif
656   }
657   {
658     const char input[] = "+nan(";
659     char *ptr1;
660     char *ptr2;
661     double result1;
662     double result2;
663     errno = 0;
664     result1 = strtod (input, &ptr1);
665     result2 = strtod (input + 1, &ptr2);
666 #if 1 /* All known CPUs support NaNs.  */
667     ASSERT (isnand (result1));          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
668     ASSERT (isnand (result2));          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
669     ASSERT (!!signbit (result1) == !!signbit (result2));
670     ASSERT (ptr1 == input + 4);         /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
671     ASSERT (ptr2 == input + 4);         /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, Solaris 2.5.1, mingw */
672     ASSERT (errno == 0);
673 #else
674     ASSERT (result1 == 0.0);
675     ASSERT (result2 == 0.0);
676     ASSERT (!signbit (result1));
677     ASSERT (!signbit (result2));
678     ASSERT (ptr1 == input);
679     ASSERT (ptr2 == input + 1);
680     ASSERT (errno == 0 || errno == EINVAL);
681 #endif
682   }
683   {
684     const char input[] = "-nan()";
685     char *ptr1;
686     char *ptr2;
687     double result1;
688     double result2;
689     errno = 0;
690     result1 = strtod (input, &ptr1);
691     result2 = strtod (input + 1, &ptr2);
692 #if 1 /* All known CPUs support NaNs.  */
693     ASSERT (isnand (result1));          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
694     ASSERT (isnand (result2));          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
695 # if 0
696     /* Sign bits of NaN is a portability sticking point, not worth
697        worrying about.  */
698     ASSERT (!!signbit (result1) != !!signbit (result2)); /* glibc-2.3.6, IRIX 6.5, OSF/1 5.1, mingw */
699 # endif
700     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 */
701     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 */
702     ASSERT (errno == 0);
703 #else
704     ASSERT (result1 == 0.0);
705     ASSERT (result2 == 0.0);
706     ASSERT (!signbit (result1));
707     ASSERT (!signbit (result2));
708     ASSERT (ptr1 == input);
709     ASSERT (ptr2 == input + 1);
710     ASSERT (errno == 0 || errno == EINVAL);
711 #endif
712   }
713   {
714     const char input[] = " nan().";
715     char *ptr;
716     double result;
717     errno = 0;
718     result = strtod (input, &ptr);
719 #if 1 /* All known CPUs support NaNs.  */
720     ASSERT (isnand (result));           /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
721     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 */
722     ASSERT (errno == 0);
723 #else
724     ASSERT (result == 0.0);
725     ASSERT (!signbit (result));
726     ASSERT (ptr == input);
727     ASSERT (errno == 0 || errno == EINVAL);
728 #endif
729   }
730   {
731     /* The behavior of nan(0) is implementation-defined, but all
732        implementations we know of which handle optional
733        n-char-sequences handle nan(0) the same as nan().  */
734     const char input[] = "-nan(0).";
735     char *ptr1;
736     char *ptr2;
737     double result1;
738     double result2;
739     errno = 0;
740     result1 = strtod (input, &ptr1);
741     result2 = strtod (input + 1, &ptr2);
742 #if 1 /* All known CPUs support NaNs.  */
743     ASSERT (isnand (result1));          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
744     ASSERT (isnand (result2));          /* OpenBSD 4.0, HP-UX 11.11, IRIX 6.5, OSF/1 5.1, mingw */
745 # if 0
746     /* Sign bits of NaN is a portability sticking point, not worth
747        worrying about.  */
748     ASSERT (!!signbit (result1) != !!signbit (result2)); /* glibc-2.3.6, IRIX 6.5, OSF/1 5.1, mingw */
749 # endif
750     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 */
751     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 */
752     ASSERT (errno == 0);
753 #else
754     ASSERT (result1 == 0.0);
755     ASSERT (result2 == 0.0);
756     ASSERT (!signbit (result1));
757     ASSERT (!signbit (result2));
758     ASSERT (ptr1 == input);
759     ASSERT (ptr2 == input + 1);
760     ASSERT (errno == 0 || errno == EINVAL);
761 #endif
762   }
763
764   /* Hex.  */
765   {
766     const char input[] = "0xa";
767     char *ptr;
768     double result;
769     errno = 0;
770     result = strtod (input, &ptr);
771     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 */
772     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 */
773     ASSERT (errno == 0);
774   }
775   {
776     const char input[] = "0XA";
777     char *ptr;
778     double result;
779     errno = 0;
780     result = strtod (input, &ptr);
781     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 */
782     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 */
783     ASSERT (errno == 0);
784   }
785   {
786     const char input[] = "0x1p";
787     char *ptr;
788     double result;
789     errno = 0;
790     result = strtod (input, &ptr);
791     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 */
792     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 */
793     ASSERT (errno == 0);
794   }
795   {
796     const char input[] = "0x1p+";
797     char *ptr;
798     double result;
799     errno = 0;
800     result = strtod (input, &ptr);
801     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 */
802     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 */
803     ASSERT (errno == 0);
804   }
805   {
806     const char input[] = "0x1P+";
807     char *ptr;
808     double result;
809     errno = 0;
810     result = strtod (input, &ptr);
811     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 */
812     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 */
813     ASSERT (errno == 0);
814   }
815   {
816     const char input[] = "0x1p+1";
817     char *ptr;
818     double result;
819     errno = 0;
820     result = strtod (input, &ptr);
821     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 */
822     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 */
823     ASSERT (errno == 0);
824   }
825   {
826     const char input[] = "0X1P+1";
827     char *ptr;
828     double result;
829     errno = 0;
830     result = strtod (input, &ptr);
831     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 */
832     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 */
833     ASSERT (errno == 0);
834   }
835   {
836     const char input[] = "0x1p+1a";
837     char *ptr;
838     double result;
839     errno = 0;
840     result = strtod (input, &ptr);
841     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 */
842     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 */
843     ASSERT (errno == 0);
844   }
845   {
846     const char input[] = "0x1p 2";
847     char *ptr;
848     double result;
849     errno = 0;
850     result = strtod (input, &ptr);
851     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 */
852     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 */
853     ASSERT (errno == 0);
854   }
855
856   /* Large buffers.  */
857   {
858     size_t m = 1000000;
859     char *input = malloc (m + 1);
860     if (input)
861       {
862         char *ptr;
863         double result;
864         memset (input, '\t', m - 1);
865         input[m - 1] = '1';
866         input[m] = '\0';
867         errno = 0;
868         result = strtod (input, &ptr);
869         ASSERT (result == 1.0);
870         ASSERT (ptr == input + m);
871         ASSERT (errno == 0);
872       }
873     free (input);
874   }
875   {
876     size_t m = 1000000;
877     char *input = malloc (m + 1);
878     if (input)
879       {
880         char *ptr;
881         double result;
882         memset (input, '0', m - 1);
883         input[m - 1] = '1';
884         input[m] = '\0';
885         errno = 0;
886         result = strtod (input, &ptr);
887         ASSERT (result == 1.0);
888         ASSERT (ptr == input + m);
889         ASSERT (errno == 0);
890       }
891     free (input);
892   }
893 #if 0
894   /* Newlib has an artificial limit of 20000 for the exponent.  TODO -
895      gnulib should fix this.  */
896   {
897     size_t m = 1000000;
898     char *input = malloc (m + 1);
899     if (input)
900       {
901         char *ptr;
902         double result;
903         input[0] = '.';
904         memset (input + 1, '0', m - 10);
905         input[m - 9] = '1';
906         input[m - 8] = 'e';
907         input[m - 7] = '+';
908         input[m - 6] = '9';
909         input[m - 5] = '9';
910         input[m - 4] = '9';
911         input[m - 3] = '9';
912         input[m - 2] = '9';
913         input[m - 1] = '1';
914         input[m] = '\0';
915         errno = 0;
916         result = strtod (input, &ptr);
917         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 */
918         ASSERT (ptr == input + m);      /* OSF/1 5.1 */
919         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 */
920       }
921     free (input);
922   }
923   {
924     size_t m = 1000000;
925     char *input = malloc (m + 1);
926     if (input)
927       {
928         char *ptr;
929         double result;
930         input[0] = '1';
931         memset (input + 1, '0', m - 9);
932         input[m - 8] = 'e';
933         input[m - 7] = '-';
934         input[m - 6] = '9';
935         input[m - 5] = '9';
936         input[m - 4] = '9';
937         input[m - 3] = '9';
938         input[m - 2] = '9';
939         input[m - 1] = '1';
940         input[m] = '\0';
941         errno = 0;
942         result = strtod (input, &ptr);
943         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 */
944         ASSERT (ptr == input + m);
945         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 */
946       }
947     free (input);
948   }
949 #endif
950   {
951     size_t m = 1000000;
952     char *input = malloc (m + 1);
953     if (input)
954       {
955         char *ptr;
956         double result;
957         input[0] = '-';
958         input[1] = '0';
959         input[2] = 'e';
960         input[3] = '1';
961         memset (input + 4, '0', m - 3);
962         input[m] = '\0';
963         errno = 0;
964         result = strtod (input, &ptr);
965         ASSERT (result == 0.0);
966         ASSERT (!!signbit (result) == !!signbit (minus_zerod)); /* IRIX 6.5, OSF/1 4.0 */
967         ASSERT (ptr == input + m);
968         ASSERT (errno == 0);
969       }
970     free (input);
971   }
972
973   /* Rounding.  */
974   /* TODO - is it worth some tests of rounding for typical IEEE corner
975      cases, such as .5 ULP rounding up to the smallest denormal and
976      not causing underflow, or DBL_MIN - .5 ULP not causing an
977      infinite loop?  */
978
979   return status;
980 }