strtod: Stop using AC_FUNC_STRTOD.
[pspp] / m4 / strtod.m4
1 # strtod.m4 serial 15
2 dnl Copyright (C) 2002-2003, 2006-2010 Free Software Foundation, Inc.
3 dnl This file is free software; the Free Software Foundation
4 dnl gives unlimited permission to copy and/or distribute it,
5 dnl with or without modifications, as long as this notice is preserved.
6
7 AC_DEFUN([gl_FUNC_STRTOD],
8 [
9   AC_REQUIRE([gl_STDLIB_H_DEFAULTS])
10   dnl Test whether strtod is declared.
11   dnl Don't call AC_FUNC_STRTOD, because it does not have the right guess
12   dnl when cross-compiling.
13   dnl Don't call AC_CHECK_FUNCS([strtod]) because it would collide with the
14   dnl ac_cv_func_strtod variable set by the AC_FUNC_STRTOD macro,
15   AC_CHECK_DECLS_ONCE([strtod])
16   if test $ac_cv_have_decl_strtod != yes; then
17     HAVE_STRTOD=0
18     gl_PREREQ_STRTOD
19     dnl Use undocumented macro to set POW_LIB correctly.
20     _AC_LIBOBJ_STRTOD
21   else
22     AC_CACHE_CHECK([whether strtod obeys C99], [gl_cv_func_strtod_works],
23       [AC_RUN_IFELSE([AC_LANG_PROGRAM([[
24 #include <stdlib.h>
25 #include <math.h>
26 #include <errno.h>
27 /* Compare two numbers with ==.
28    This is a separate function because IRIX 6.5 "cc -O" miscompiles an
29    'x == x' test.  */
30 static int
31 numeric_equal (double x, double y)
32 {
33   return x == y;
34 }
35 ]], [[
36   {
37     /* In some old versions of Linux (2000 or before), strtod mis-parses
38        strings with leading '+'.  */
39     const char *string = " +69";
40     char *term;
41     double value = strtod (string, &term);
42     if (value != 69 || term != (string + 4))
43       return 1;
44   }
45   {
46     /* Under Solaris 2.4, strtod returns the wrong value for the
47        terminating character under some conditions.  */
48     const char *string = "NaN";
49     char *term;
50     strtod (string, &term);
51     if (term != string && *(term - 1) == 0)
52       return 1;
53   }
54   {
55     /* Older glibc and Cygwin mis-parse "-0x".  */
56     const char *string = "-0x";
57     char *term;
58     double value = strtod (string, &term);
59     double zero = 0.0;
60     if (1.0 / value != -1.0 / zero || term != (string + 2))
61       return 1;
62   }
63   {
64     /* Many platforms do not parse hex floats.  */
65     const char *string = "0XaP+1";
66     char *term;
67     double value = strtod (string, &term);
68     if (value != 20.0 || term != (string + 6))
69       return 1;
70   }
71   {
72     /* Many platforms do not parse infinities.  HP-UX 11.31 parses inf,
73        but mistakenly sets errno.  */
74     const char *string = "inf";
75     char *term;
76     double value;
77     errno = 0;
78     value = strtod (string, &term);
79     if (value != HUGE_VAL || term != (string + 3) || errno)
80       return 1;
81   }
82   {
83     /* glibc 2.7 and cygwin 1.5.24 misparse "nan()".  */
84     const char *string = "nan()";
85     char *term;
86     double value = strtod (string, &term);
87     if (numeric_equal (value, value) || term != (string + 5))
88       return 1;
89   }
90   {
91     /* darwin 10.6.1 misparses "nan(".  */
92     const char *string = "nan(";
93     char *term;
94     double value = strtod (string, &term);
95     if (numeric_equal (value, value) || term != (string + 3))
96       return 1;
97   }
98 ]])],
99         [gl_cv_func_strtod_works=yes],
100         [gl_cv_func_strtod_works=no],
101         [gl_cv_func_strtod_works="guessing no"])])
102     if test "$gl_cv_func_strtod_works" != yes; then
103       REPLACE_STRTOD=1
104       gl_PREREQ_STRTOD
105       dnl Use undocumented macro to set POW_LIB correctly.
106       _AC_LIBOBJ_STRTOD
107     fi
108   fi
109 ])
110
111 # Prerequisites of lib/strtod.c.
112 # The need for pow() is already handled by AC_FUNC_STRTOD.
113 AC_DEFUN([gl_PREREQ_STRTOD], [:])