# $Id: Head.U,v 3.0.1.9 1997/02/28 15:02:09 ram Exp $
#
-# Generated on Sat Aug 14 02:03:17 EET DST 1999 [metaconfig 3.0 PL70]
+# Generated on Mon Aug 16 19:31:58 EET DST 1999 [metaconfig 3.0 PL70]
# (with additional metaconfig patches by perlbug@perl.com)
cat >/tmp/c1$$ <<EOF
d_isascii=''
d_killpg=''
d_lchown=''
+d_ldbl_dig=''
d_link=''
d_locconv=''
d_lockf=''
startperl=''
startsh=''
stdchar=''
-d_fgetpos64=''
-d_fopen64=''
-d_freopen64=''
-d_fseek64=''
-d_fseeko64=''
-d_fsetpos64=''
-d_ftell64=''
-d_ftello64=''
-d_tmpfile64=''
d_stdio_stream_array=''
stdio_stream_array=''
d_strtoull=''
: check for long doubles
echo " "
-echo $n "Checking to see if your system supports long doubles...$c" >&4
+echo $n "Checking to see if your system supports long double...$c" >&4
echo 'long double foo() { long double x; x = 7.0; return x; }' > try.c
if $cc $optimize $ccflags -c try.c >/dev/null 2>&1; then
val="$define"
set fsetpos d_fsetpos
eval $inlibc
-
-if $test X"$use64bits" = X"$define"; then
- : see if fgetpos64 exists
- set fgetpos64 d_fgetpos64
- eval $inlibc
-
- : see if fopen64 exists
- set freopen64 d_fopen64
- eval $inlibc
-
- : see if freopen64 exists
- set freopen64 d_freopen64
- eval $inlibc
-
- : see if fseek64 exists
- set fseek64 d_fseek64
- eval $inlibc
-
- : see if fseeko64 exists
- set fseeko64 d_fseeko64
- eval $inlibc
-
- : see if fsetpos64 exists
- set fsetpos64 d_fsetpos64
- eval $inlibc
-
- : see if ftell64 exists
- set ftell64 d_ftell64
- eval $inlibc
-
- : see if ftello64 exists
- set ftello64 d_ftello64
- eval $inlibc
-
- : see if tmpfile64 exists
- set tmpfile64 d_tmpfile64
- eval $inlibc
-else
- val="$undef"
- for xxx in d_fgetpos64 d_fopen64 d_freopen64 d_fseek64 d_fseeko64 d_fsetpos64 d_ftell64 d_ftello64 d_tmpfile64
- do
- set $xxx
- eval $setvar
- done
-fi
-
: see if this is a sys/param system
set sys/param.h i_sysparam
eval $inhdr
set d_lchown
eval $setvar
+: See if number of significant digits in a double precision number is known
+echo " "
+$cat >ldbl_dig.c <<EOM
+#$i_limits I_LIMITS
+#$i_float I_FLOAT
+#ifdef I_LIMITS
+#include <limits.h>
+#endif
+#ifdef I_FLOAT
+#include <float.h>
+#endif
+#ifdef LDBL_DIG
+printf("Contains LDBL_DIG");
+#endif
+EOM
+$cppstdin $cppflags $cppminus < ldbl_dig.c >ldbl_dig.E 2>/dev/null
+if $contains 'LDBL_DIG' ldbl_dig.E >/dev/null 2>&1; then
+ echo "LDBL_DIG found." >&4
+ val="$define"
+else
+ echo "LDBL_DIG NOT found." >&4
+ val="$undef"
+fi
+$rm -f ldbl_dig.?
+set d_ldbl_dig
+eval $setvar
+
: see if link exists
set link d_link
eval $inlibc
d_fd_macros='$d_fd_macros'
d_fd_set='$d_fd_set'
d_fds_bits='$d_fds_bits'
-d_fgetpos64='$d_fgetpos64'
d_fgetpos='$d_fgetpos'
d_flexfnam='$d_flexfnam'
d_flock='$d_flock'
-d_fopen64='$d_fopen64'
d_fork='$d_fork'
d_fpathconf='$d_fpathconf'
d_fpos64_t='$d_fpos64_t'
-d_freopen64='$d_freopen64'
-d_fseek64='$d_fseek64'
-d_fseeko64='$d_fseeko64'
d_fseeko='$d_fseeko'
-d_fsetpos64='$d_fsetpos64'
d_fsetpos='$d_fsetpos'
d_fstatfs='$d_fstatfs'
d_fstatvfs='$d_fstatvfs'
-d_ftell64='$d_ftell64'
-d_ftello64='$d_ftello64'
d_ftello='$d_ftello'
d_ftime='$d_ftime'
d_getgrent='$d_getgrent'
d_isascii='$d_isascii'
d_killpg='$d_killpg'
d_lchown='$d_lchown'
+d_ldbl_dig='$d_ldbl_dig'
d_link='$d_link'
d_llseek='$d_llseek'
d_locconv='$d_locconv'
d_telldirproto='$d_telldirproto'
d_time='$d_time'
d_times='$d_times'
-d_tmpfile64='$d_tmpfile64'
d_truncate='$d_truncate'
d_tzname='$d_tzname'
d_umask='$d_umask'
*/
#$d_hasmntopt HAS_HASMNTOPT /**/
+/* HAS_LDBL_DIG:
+ * This symbol, if defined, indicates that this system's <float.h>
+ * or <limits.h> defines the symbol LDBL_DIG, which is the number
+ * of significant digits in a long double precision number. Unlike
+ * for DBL_DIG, there's no good guess for LDBL_DIG if it is undefined.
+ */
+#$d_ldbl_dig HAS_LDBL_DIG /* */
+
/* HAS_MADVISE:
* This symbol, if defined, indicates that the madvise system call is
* available to map a file into memory.
*/
#define STARTPERL "$startperl" /**/
-/* HAS_FSETPOS64:
- * This symbol, if defined, indicates that the fsetpos64 routine is
- * available to setpos files larger than 2 gigabytes.
- */
-#$d_fsetpos64 HAS_FSETPOS64 /**/
-
/* HAS_STDIO_STREAM_ARRAY:
* This symbol, if defined, tells that there is an array
* holding the stdio streams.
#include "perl.h"
#include "regcomp.h"
-#ifndef DBL_DIG
-#define DBL_DIG 15 /* A guess that works lots of places */
-#endif
-
void
Perl_dump_indent(pTHX_ I32 level, PerlIO *file, const char* pat, ...)
{
if (type >= SVt_PVNV || type == SVt_NV) {
RESTORE_NUMERIC_STANDARD();
#ifdef USE_LONG_DOUBLE
- Perl_dump_indent(aTHX_ level, file, " NV = %.*" PERL_PRIgldbl "\n", DBL_DIG, SvNVX(sv));
+ Perl_dump_indent(aTHX_ level, file, " NV = %.*" PERL_PRIgldbl "\n", LDBL_DIG, SvNVX(sv));
#else
Perl_dump_indent(aTHX_ level, file, " NV = %.*g\n", DBL_DIG, SvNVX(sv));
#endif
cat > UU/use64bits.cbu <<'EOCBU'
case "$use64bits" in
$define|true|[yY]*)
- case "`uname -r`" in
+ case "`oslevel`" in
3.*|4.[012].*)
cat >&4 <<EOM
-AIX `uname -r` does not support 64-bit interfaces.
-You should upgrade to at least AIX 4.3.
+AIX `oslevel` does not support 64-bit interfaces.
+You should upgrade to at least AIX 4.2.
EOM
exit 1
;;
# _Somehow_ in AIX 4.3.1.0 the above getconf call manages to
# insert(?) *something* to $ldflags so that later (in Configure) evaluating
# $ldflags causes a newline after the '-b64' (the result of the getconf).
+ # (nothing strange shows up in $ldflags even in hexdump;
+ # so it may be something in the shell, instead?)
# Try it out: just uncomment the below line and rerun Configure:
# echo >& "AIX $ldflags mystery" ; exit 1
# Just don't ask me how AIX does it.
- # Therefore the line re-evaluating ldflags: it seems to drop the whatever
- # AIX managed to break. --jhi
+ # Therefore the line re-evaluating ldflags: it seems to bypass
+ # the whatever it was AIX managed to break. --jhi
ldflags="`echo $ldflags`"
- libswanted="$libswanted `getconf XBS5_LPBIG_OFFBIG_LIBS 2>/dev/null|sed -e 's@^-l@@' -e 's@ -l@ @g'`"
+ libswanted="$libswanted `getconf XBS5_ILP32_OFFBIG_LIBS 2>/dev/null|sed -e 's@^-l@@' -e 's@ -l@ @g'`"
# When a 64-bit cc becomes available $archname64
# may need setting so that $archname gets it attached.
;;
EOCBU
# This script UU/uselongdouble.cbu will get 'called-back' by Configure
-# after it has prompted the user for whether to use 64 bits.
+# after it has prompted the user for whether to use long doubles.
cat > UU/uselongdouble.cbu <<'EOCBU'
case "$uselongdouble" in
$define|true|[yY]*)
EOM
exit 1
fi
- if [ ! -d /lib/pa20_64 ]; then
+ if [ ! -f /lib/pa20_64/libc.sl ]; then
cat <<EOM >&4
-You do not seem to have the 64-bit libraries, /lib/pa20_64.
+You do not seem to have the 64-bit libraries in /lib/pa20_64.
+Most importantly, I cannot find /lib/pa20_64/libc.sl.
Cannot continue, aborting.
EOM
exit 1
while (isSPACE(*p))
++p;
- PL_egid = I_V(Atol(p));
+ PL_egid = Atol(p);
for (i = 0; i < NGROUPS; ++i) {
while (*p && !isSPACE(*p))
++p;
++p;
if (!*p)
break;
- gary[i] = I_V(Atol(p));
+ gary[i] = Atol(p);
}
if (i)
(void)setgroups(i, gary);
# define UV_MAX PERL_UQUAD_MAX
# define UV_MIN PERL_UQUAD_MIN
# endif
-# define IV_SIZEOF 8
-# define UV_SIZEOF 8
+# define IVSIZF 8
+# define UVSIZE 8
# define IV_IS_QUAD
# define UV_IS_QUAD
#else
# define UV_MAX PERL_ULONG_MAX
# define UV_MIN PERL_ULONG_MIN
# endif
-# define UV_SIZEOF LONGSIZE
-# define IV_SIZEOF LONGSIZE
# if LONGSIZE == 8
# define IV_IS_QUAD
# define UV_IS_QUAD
# undef IV_IS_QUAD
# undef UV_IS_QUAD
# endif
-# define UV_SIZEOF LONGSIZE
-# define IV_SIZEOF LONGSIZE
+# define UVSIZE LONGSIZE
+# define IVSIZE LONGSIZE
#endif
+#define IV_DIG (BIT_DIGITS(IVSIZE * 8) + 1)
+#define UV_DIG (BIT_DIGITS(IVSIZE * 8) + 1)
#ifdef USE_LONG_DOUBLE
# if defined(HAS_LONG_DOUBLE) && (LONG_DOUBLESIZE > DOUBLESIZE)
# define LDoub_t long double
+# else
+# undef USE_LONG_DOUBLE /* Ouch! */
# endif
#endif
+#ifdef OVR_DBL_DIG
+/* Use an overridden DBL_DIG */
+# ifdef DBL_DIG
+# undef DBL_DIG
+# endif
+# define DBL_DIG OVR_DBL_DIG
+#else
+/* The following is all to get DBL_DIG, in order to pick a nice
+ default value for printing floating point numbers in Gconvert.
+ (see config.h)
+*/
+#ifdef I_LIMITS
+#include <limits.h>
+#endif
+#ifdef I_FLOAT
+#include <float.h>
+#endif
+#ifndef HAS_DBL_DIG
+#define DBL_DIG 15 /* A guess that works lots of places */
+#endif
+#endif
+
+#ifdef OVR_LDBL_DIG
+/* Use an overridden LDBL_DIG */
+# ifdef LDBL_DIG
+# undef LDBL_DIG
+# endif
+# define LDBL_DIG OVR_LDBL_DIG
+#else
+/* The following is all to get LDBL_DIG, in order to pick a nice
+ default value for printing floating point numbers in Gconvert.
+ (see config.h)
+*/
+#ifdef I_LIMITS
+#include <limits.h>
+#endif
+#ifdef I_FLOAT
+#include <float.h>
+#endif
+#ifndef HAS_LDBL_DIG
+#if LONG_DOUBLESIZE == 10
+#define LDBL_DIG 18 /* assume IEEE */
+#else
+#if LONG_DOUBLESIZE == 16
+#define LDBL_DIG 33 /* assume IEEE */
+#else
+#if LONG_DOUBLESIZE == DOUBLESIZE
+#define LDBL_DIG DBL_DIG /* bummer */
+#endif
+#endif
+#endif
+#endif
+#endif
+
#ifdef USE_LONG_DOUBLE
# define HAS_LDOUB
typedef LDoub_t NV;
+# define NVSIZE LONG_DOUBLESIZE
+# define NV_DIG LDBL_DIG
# define Perl_modf modfl
# define Perl_frexp frexpl
# define Perl_cos cosl
# define Perl_fmod fmodl
#else
typedef double NV;
+# define NVSIZE DOUBLESIZE
+# define NV_DIG DBL_DIG
# define Perl_modf modf
# define Perl_frexp frexp
# define Perl_cos cos
# define USE_64_BIT_STDIO
#endif
-#ifdef __sgi /* UGLY. See below. */
+/* I couldn't find any -Ddefine or -flags in IRIX 6.5 that would
+ * have done the necessary symbol renaming using cpp. --jhi */
+#ifdef __sgi
#define USE_FOPEN64
#define USE_FSEEK64
#define USE_FTELL64
#define U_V(what) (cast_uv((NV)(what)))
#endif
+/* These do not care about the fractional part, only about the range. */
+#define NV_WITHIN_IV(nv) (I_V(nv) >= IV_MIN && I_V(nv) <= IV_MAX)
+#define NV_WITHIN_UV(nv) ((nv)>=0.0&&U_V(nv) >= UV_MIN&&U_V(nv) <= UV_MAX)
+
+#define IV_FITS_IN_NV
+/* Is this strictly correct? */
+#if IVSIZE >= NVSIZE
+# undef IV_FITS_IN_NV
+#else
+ /* Greater-than-or-EQUAL because L?DBL_DIG doesn't necessarily
+ * mean that all the powers of two that are L?DBL_DIG digits long
+ * can be represented by the (long)? doubles sized L?DBL_DIG digits. */
+# if IV_DIG >= NV_DIG
+# undef IV_FITS_IN_NV
+# endif
+#endif
+/* Often there are DBL_MANT_DIG and LDBL_MANT_DIG
+ * that would give more precise results. */
+
/* Used with UV/IV arguments: */
/* XXXX: need to speed it up */
#define CLUMP_2UV(iv) ((iv) < 0 ? 0 : (UV)(iv))
int
PerlIO_setpos(PerlIO *f, const Fpos_t *pos)
{
-#if defined(USE_64_BIT_STDIO) && defined(HAS_FSETPOS64)
+#if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
return fsetpos64(f, pos);
#else
return fsetpos(f, pos);
int
PerlIO_getpos(PerlIO *f, Fpos_t *pos)
{
-#if defined(USE_64_BIT_STDIO) && defined(HAS_FSETPOS64)
+#if defined(USE_64_BIT_STDIO) && defined(USE_FSETPOS64)
return fgetpos64(f, pos);
#else
return fgetpos(f, pos);
Unfortunately, bit operations (&, <<, ...) and vec() do not work,
they are limited to 32 bits.
-Last but not least: note that due to Perl's tendency to always use
-floating point numbers the quads are not true integers. They may lose
-their precision due to rounding errors, and when they get large their
-less significant digits will fall off.
-
+Last but not least: note that due to Perl's habit of always using
+floating point numbers the quads are still not true integers. When
+quads overflow their limits (18446744073709551615 unsigned,
+-9223372036854775808...9223372036854775807 signed), they are silently
+promoted to floating point numbers, after which they will
+start losing precision (their lower digits).
+
+=head2 Large file support
+
+If you have filesystems that support "large files" (files larger than
+2 gigabytes), you may now also be able to create and access them from Perl.
+
+Note that in addition to requiring a proper file system to do this you
+may also need to adjust your per-process (or even your per-system)
+maximum filesize limits before running Perl scripts that try to handle
+large files, especially if you intend to write such files.
+
+Adjusting your file system/system limits is outside the scope of Perl.
+For process limits, you may try to increase the limits using your
+shell's limit/ulimit command before running Perl. The BSD::Resource
+extension (not included with the standard Perl distribution) may also
+be of use.
+
+(Large file support is also related to 64-bit support, for obvious reasons)
+
=head2 Better syntax checks on parenthesized unary operators
Expressions such as:
#define POPul ((unsigned long)SvIVx(POPs))
#ifdef HAS_QUAD
#define POPq ((Quad_t)SvIVx(POPs))
+#define POPuq ((Uquad_t)SvIVx(POPs))
#endif
#define TOPs (*sp)
#define TOPul ((unsigned long)SvIV(TOPs))
#ifdef HAS_QUAD
#define TOPq ((Quad_t)SvIV(TOPs))
+#define TOPuq ((Uquad_t)SvIV(TOPs))
#endif
/* Go to some pains in the rare event that we must extend the stack. */
#define dPOPiv IV value = POPi
#define dTOPuv UV value = TOPu
#define dPOPuv UV value = POPu
+#ifdef HAS_QUAD
+#define dTOPqv Quad_t value = TOPu
+#define dPOPqv Quad_t value = POPu
+#define dTOPuqv Uquad_t value = TOPuq
+#define dPOPuqv Uquad_t value = POPuq
+#endif
#define dPOPXssrl(X) SV *right = POPs; SV *left = CAT2(X,s)
#define dPOPXnnrl(X) NV right = POPn; NV left = CAT2(X,n)
#define PERL_IN_SV_C
#include "perl.h"
-#ifdef OVR_DBL_DIG
-/* Use an overridden DBL_DIG */
-# ifdef DBL_DIG
-# undef DBL_DIG
-# endif
-# define DBL_DIG OVR_DBL_DIG
-#else
-/* The following is all to get DBL_DIG, in order to pick a nice
- default value for printing floating point numbers in Gconvert.
- (see config.h)
-*/
-#ifdef I_LIMITS
-#include <limits.h>
-#endif
-#ifdef I_FLOAT
-#include <float.h>
-#endif
-#ifndef HAS_DBL_DIG
-#define DBL_DIG 15 /* A guess that works lots of places */
-#endif
-#endif
-
#ifdef PERL_OBJECT
#define VTBL this->*vtbl
#else /* !PERL_OBJECT */
goto tokensave;
}
if (SvNOKp(sv)) {
- Gconvert(SvNVX(sv), DBL_DIG, 0, tmpbuf);
+ Gconvert(SvNVX(sv), NV_DIG, 0, tmpbuf);
tsv = Nullsv;
goto tokensave;
}
else
#endif /*apollo*/
{
- Gconvert(SvNVX(sv), DBL_DIG, 0, s);
+ Gconvert(SvNVX(sv), NV_DIG, 0, s);
}
errno = olderrno;
#ifdef FIXNEGATIVEZERO
char *eptr = Nullch;
STRLEN elen = 0;
- char ebuf[TYPE_DIGITS(int) * 2 + 16]; /* large enough for "%#.#f" */
+ char ebuf[TYPE_DIGITS(IV) * 2 + 16];
+ /* large enough for "%#.#f" --chip */
+ /* what about long double NVs? --jhi */
char c;
int i;
unsigned base;
}
sub explain {
- print STDERR <<EOM;
+ print <<EOM;
#
# If the lfs (large file support: large meaning larger than two gigabytes)
-# tests fail, it may mean either that your process is not allowed to write
-# large files or that the file system you are running the tests on doesn't
-# support large files, or both.
+# tests are skipped or fail, it may mean either that your process is not
+# allowed to write large files or that the file system you are running
+# the tests on doesn't support large files, or both. You may also need
+# to reconfigure your kernel. (This is all very system-dependent.)
#
# Perl may still be able to support large files, once you have
-# such a process and such a file system.
+# such a process and such a (file) system.
#
EOM
}
# Nota bene: bit operations (&, |, ^, ~, <<, >>, vec) are not 64-bit clean.
# See the beginning of pp.c and the explanation next to IBW/UBW.
-no warning 'overflow'; # so that using > 0xfffffff constants doesn't whine
+# so that using > 0xfffffff constants and 32+ bit
+# shifts and vector sizes doesn't cause noise
+no warning 'overflow';
-print "1..30\n";
+print "1..36\n";
my $q = 12345678901;
my $r = 23456789012;
my $f = 0xffffffff;
my $x;
-
+my $y;
$x = unpack "q", pack "q", $q;
print "not " unless $x == $q && $x > $f;
print "not " unless $x == -11111110111 && -$x > $f;
print "ok 27\n";
-$x = $q * $r;
-print "not " unless $x == 289589985190657035812 && $x > $f;
+$x = $q * 1234567;
+print "not " unless $x == 15241567763770867 && $x > $f;
print "ok 28\n";
-$x /= $r;
+$x /= 1234567;
print "not " unless $x == $q && $x > $f;
print "ok 29\n";
$x = 98765432109 % 12345678901;
print "not " unless $x == 901;
print "ok 30\n";
+
+# The following six adapted from op/inc.
+
+$a = 9223372036854775807;
+$c = $a++;
+print "not " unless $a == 9223372036854775808;
+print "ok 31\n";
+
+$a = 9223372036854775807;
+$c = ++$a;
+print "not " unless $a == 9223372036854775808;
+print "ok 32\n";
+
+$a = 9223372036854775807;
+$c = $a + 1;
+print "not " unless $a == 9223372036854775808;
+print "ok 33\n";
+
+$a = -9223372036854775808;
+$c = $a--;
+print "not " unless $a == -9223372036854775809;
+print "ok 34\n";
+
+$a = -9223372036854775808;
+$c = --$a;
+print "not " unless $a == -9223372036854775809;
+print "ok 35\n";
+
+$a = -9223372036854775808;
+$c = $a - 1;
+print "not " unless $a == -9223372036854775809;
+print "ok 36\n";
+
+
}
sub explain {
- print STDERR <<EOM;
+ print <<EOM;
#
# If the lfs (large file support: large meaning larger than two gigabytes)
-# tests fail, it may mean either that your process is not allowed to write
-# large files or that the file system you are running the tests on doesn't
-# support large files, or both.
+# tests are skipped or fail, it may mean either that your process is not
+# allowed to write large files or that the file system you are running
+# the tests on doesn't support large files, or both. You may also need
+# to reconfigure your kernel. (This is all very system-dependent.)
#
# Perl may still be able to support large files, once you have
-# such a process and such a file system.
+# such a process and such a (file) system.
#
EOM
}
$ perl_d_chroot="undef"
$ perl_d_cuserid="define"
$ perl_d_dbl_dig="define"
+$ perl_d_ldbl_dig="define"
$ perl_d_difftime="define"
$ perl_d_fork="undef"
$ perl_d_getlogin="define"
$ WC "d_chroot='" + perl_d_chroot + "'"
$ WC "d_cuserid='" + perl_d_cuserid + "'"
$ WC "d_dbl_dig='" + perl_d_dbl_dig + "'"
+$ WC "d_ldbl_dig='" + perl_d_dbl_dig + "'"
$ WC "d_difftime='" + perl_d_difftime + "'"
$ WC "d_fork='" + perl_d_fork + "'"
$ WC "d_getlogin='" + perl_d_getlogin + "'"