This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
91f25ef04428448f5b29d403a23dd0481cd83887
[metaconfig.git] / U / perl / d_modfl.U
1 ?RCS: $Id$
2 ?RCS:
3 ?RCS: Copyright (c) 2000 Jarkko Hietaniemi
4 ?RCS:
5 ?RCS: You may distribute under the terms of either the GNU General Public
6 ?RCS: License or the Artistic License, as specified in the README file.
7 ?RCS:
8 ?MAKE:d_modfl d_modflproto d_modfl_pow32_bug: Inlibc Compile Hasproto cat \
9         rm_try test sPRIfldbl d_longdbl osname gccversion ccflags run \
10         uselongdouble i_math \
11         d_sqrtl d_aintl d_copysignl d_ilogbl d_scalbnl d_frexpl d_ldexpl
12 ?MAKE:  -pick add $@ %<
13 ?S:d_modfl:
14 ?S:     This variable conditionally defines the HAS_MODFL symbol, which
15 ?S:     indicates to the C program that the modfl() routine is available.
16 ?S:.
17 ?S:d_modflproto:
18 ?S:     This symbol, if defined, indicates that the system provides
19 ?S:     a prototype for the modfl() function.  Otherwise, it is up
20 ?S:     to the program to supply one.  C99 says it should be
21 ?S:             long double modfl(long double, long double *);
22 ?S:.
23 ?S:d_modfl_pow32_bug:
24 ?S:     This variable conditionally defines the HAS_MODFL_POW32_BUG symbol,
25 ?S:     which indicates that modfl() is broken for long doubles >= pow(2, 32).
26 ?S:     For example from 4294967303.150000 one would get 4294967302.000000
27 ?S:     and 1.150000.  The bug has been seen in certain versions of glibc,
28 ?S:     release 2.2.2 is known to be okay.
29 ?S:.
30 ?C:HAS_MODFL:
31 ?C:     This symbol, if defined, indicates that the modfl routine is
32 ?C:     available to split a long double x into a fractional part f and
33 ?C:     an integer part i such that |f| < 1.0 and (f + i) = x.
34 ?C:.
35 ?C:HAS_MODFL_PROTO:
36 ?C:     This symbol, if defined, indicates that the system provides
37 ?C:     a prototype for the modfl() function.  Otherwise, it is up
38 ?C:     to the program to supply one.
39 ?C:.
40 ?C:HAS_MODFL_POW32_BUG:
41 ?C:     This symbol, if defined, indicates that the modfl routine is
42 ?C:     broken for long doubles >= pow(2, 32).
43 ?C:     For example from 4294967303.150000 one would get 4294967302.000000
44 ?C:     and 1.150000.  The bug has been seen in certain versions of glibc,
45 ?C:     release 2.2.2 is known to be okay.
46 ?C:.
47 ?H:#$d_modfl HAS_MODFL          /**/
48 ?H:#$d_modflproto HAS_MODFL_PROTO               /**/
49 ?H:#$d_modfl_pow32_bug HAS_MODFL_POW32_BUG              /**/
50 ?H:.
51 ?T:foo saveccflags message
52 ?F:!try
53 ?LINT:set d_modflproto
54 ?LINT:change ccflags
55 : see if modfl exists
56 set modfl d_modfl
57 eval $inlibc
58
59 : see if prototype for modfl is available
60 echo " "
61 set d_modflproto modfl $i_math math.h
62 eval $hasproto
63
64 d_modfl_pow32_bug="$undef"
65
66 case "$d_longdbl$d_modfl" in
67 $define$define)
68         $cat <<EOM
69 Checking to see whether your modfl() is okay for large values...
70 EOM
71 $cat >try.c <<EOCP
72 #include <math.h>
73 #include <stdio.h>
74 EOCP
75 if $test "X$d_modflproto" != "X$define"; then
76         $cat >>try.c <<EOCP
77 /* Sigh. many current glibcs provide the function, but do not prototype it. */
78 long double modfl (long double, long double *);
79 EOCP
80 fi
81 $cat >>try.c <<EOCP
82 int main() {
83     long double nv = 4294967303.15;
84     long double v, w;
85     v = modfl(nv, &w);
86 #ifdef __GLIBC__
87     printf("glibc");
88 #endif
89     printf(" %"$sPRIfldbl" %"$sPRIfldbl" %"$sPRIfldbl"\n", nv, v, w);
90     return 0;
91 }
92 EOCP
93         case "$osname:$gccversion" in
94         aix:)   saveccflags="$ccflags"
95                 ccflags="$ccflags -qlongdouble" ;; # to avoid core dump
96         esac
97         set try
98         if eval $compile; then
99                 foo=`$run ./try`
100                 case "$foo" in
101                 *" 4294967303.150000 1.150000 4294967302.000000")
102                         echo >&4 "Your modfl() is broken for large values."
103                         d_modfl_pow32_bug="$define"
104                         case "$foo" in
105                         glibc)  echo >&4 "You should upgrade your glibc to at least 2.2.2 to get a fixed modfl()."
106                         ;;
107                         esac
108                         ;;
109                 *" 4294967303.150000 0.150000 4294967303.000000")
110                         echo >&4 "Your modfl() seems okay for large values."
111                         ;;
112                 *)      echo >&4 "I don't understand your modfl() at all."
113                         d_modfl="$undef"
114                         ;;
115                 esac
116                 $rm_try
117         else
118                 echo "I cannot figure out whether your modfl() is okay, assuming it isn't."
119                 d_modfl="$undef"
120         fi
121         case "$osname:$gccversion" in
122         aix:)   ccflags="$saveccflags" ;; # restore
123         esac
124         ;;
125 esac
126
127 if $test "$uselongdouble" = "$define"; then
128     message=""
129     if $test "$d_sqrtl" != "$define"; then
130         message="$message sqrtl"
131     fi
132     if $test "$d_modfl" != "$define"; then
133         if $test "$d_aintl:$d_copysignl" = "$define:$define"; then
134             echo "You have both aintl and copysignl, so I can emulate modfl."
135         else
136             message="$message modfl"
137         fi
138     fi
139     if $test "$d_frexpl" != "$define"; then
140         if $test "$d_ilogbl:$d_scalbnl" = "$define:$define"; then
141             echo "You have both ilogbl and scalbnl, so I can emulate frexpl."
142         else
143             message="$message frexpl"
144         fi
145     fi
146     if $test "$d_ldexpl" != "$define"; then
147         message="$message ldexpl"
148     fi
149
150     if $test "$message" != ""; then
151         $cat <<EOM >&4
152
153 *** You requested the use of long doubles but you do not seem to have
154 *** the following mathematical functions needed for long double support:
155 ***    $message
156 *** Please rerun Configure without -Duselongdouble and/or -Dusemorebits.
157 *** Cannot continue, aborting.
158
159 EOM
160
161         exit 1
162     fi
163 fi
164