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