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