maint: update copyright
[gnulib.git] / m4 / strtod.m4
1 # strtod.m4 serial 22
2 dnl Copyright (C) 2002-2003, 2006-2014 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   m4_ifdef([gl_FUNC_STRTOD_OBSOLETE], [
11     dnl Test whether strtod is declared.
12     dnl Don't call AC_FUNC_STRTOD, because it does not have the right guess
13     dnl when cross-compiling.
14     dnl Don't call AC_CHECK_FUNCS([strtod]) because it would collide with the
15     dnl ac_cv_func_strtod variable set by the AC_FUNC_STRTOD macro.
16     AC_CHECK_DECLS_ONCE([strtod])
17     if test $ac_cv_have_decl_strtod != yes; then
18       HAVE_STRTOD=0
19     fi
20   ])
21   if test $HAVE_STRTOD = 1; then
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   int result = 0;
37   {
38     /* In some old versions of Linux (2000 or before), strtod mis-parses
39        strings with leading '+'.  */
40     const char *string = " +69";
41     char *term;
42     double value = strtod (string, &term);
43     if (value != 69 || term != (string + 4))
44       result |= 1;
45   }
46   {
47     /* Under Solaris 2.4, strtod returns the wrong value for the
48        terminating character under some conditions.  */
49     const char *string = "NaN";
50     char *term;
51     strtod (string, &term);
52     if (term != string && *(term - 1) == 0)
53       result |= 2;
54   }
55   {
56     /* Older glibc and Cygwin mis-parse "-0x".  */
57     const char *string = "-0x";
58     char *term;
59     double value = strtod (string, &term);
60     double zero = 0.0;
61     if (1.0 / value != -1.0 / zero || term != (string + 2))
62       result |= 4;
63   }
64   {
65     /* Many platforms do not parse hex floats.  */
66     const char *string = "0XaP+1";
67     char *term;
68     double value = strtod (string, &term);
69     if (value != 20.0 || term != (string + 6))
70       result |= 8;
71   }
72   {
73     /* Many platforms do not parse infinities.  HP-UX 11.31 parses inf,
74        but mistakenly sets errno.  */
75     const char *string = "inf";
76     char *term;
77     double value;
78     errno = 0;
79     value = strtod (string, &term);
80     if (value != HUGE_VAL || term != (string + 3) || errno)
81       result |= 16;
82   }
83   {
84     /* glibc 2.7 and cygwin 1.5.24 misparse "nan()".  */
85     const char *string = "nan()";
86     char *term;
87     double value = strtod (string, &term);
88     if (numeric_equal (value, value) || term != (string + 5))
89       result |= 32;
90   }
91   {
92     /* darwin 10.6.1 misparses "nan(".  */
93     const char *string = "nan(";
94     char *term;
95     double value = strtod (string, &term);
96     if (numeric_equal (value, value) || term != (string + 3))
97       result |= 64;
98   }
99   return result;
100 ]])],
101         [gl_cv_func_strtod_works=yes],
102         [gl_cv_func_strtod_works=no],
103         [dnl The last known bugs in glibc strtod(), as of this writing,
104          dnl were fixed in version 2.8
105          AC_EGREP_CPP([Lucky user],
106            [
107 #include <features.h>
108 #ifdef __GNU_LIBRARY__
109  #if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 8) || (__GLIBC__ > 2)) \
110      && !defined __UCLIBC__
111   Lucky user
112  #endif
113 #endif
114            ],
115            [gl_cv_func_strtod_works="guessing yes"],
116            [gl_cv_func_strtod_works="guessing no"])])])
117     case "$gl_cv_func_strtod_works" in
118       *yes) ;;
119       *)
120         REPLACE_STRTOD=1
121         ;;
122     esac
123   fi
124 ])
125
126 # Prerequisites of lib/strtod.c.
127 AC_DEFUN([gl_PREREQ_STRTOD], [
128   AC_REQUIRE([gl_CHECK_LDEXP_NO_LIBM])
129   if test $gl_cv_func_ldexp_no_libm = yes; then
130     AC_DEFINE([HAVE_LDEXP_IN_LIBC], [1],
131       [Define if the ldexp function is available in libc.])
132   fi
133 ])