Update.
1997-11-13 01:07 Ulrich Drepper <drepper@cygnus.com> * manual/arith.texi: Update documentation according to most recent ISO C 9X draft. Document fma, fdim, fmin, and fmax. * manual/math.texi: Allow multiple defitino of mul etc. * math/complex.h (I): Define using _Complex_U not _Imaginary_I. * math/libm-test.c: Add tests for fma. * math/math.h: Describe DECIMAL_DIG macro. Pretty print. * sysdeps/alpha/fpu/bits/mathdef.h: Define INFINITY as of type float. Define DECIMAL_DIG. * sysdeps/generic/bits/mathdef.h: Likewise. * sysdeps/i386/bits/mathdef.h: Likewise. * sysdeps/m68k/fpu/bits/mathdef.h: Likewise. * sysdeps/powerpc/bits/mathdef.h: Likewise. * sysdeps/sparc/fpu/bits/mathdef.h: Likewise. * sysdeps/ieee754/bits/nan.h: Define NAN as of type float. * sysdeps/m68k/bits/nan.h. Likewise. Remove NANF and NANL. 1997-11-12 17:50 Ulrich Drepper <drepper@cygnus.com> * sunrpc/xcrypt.c: Don't process #ident preprocessor instruction. Reported by Philip Blundell <pb@nexus.co.uk>. * string/strndup.c: Use K&R like definition. * sysdeps/unix/sysv/linux/getcwd.c: New file. Use kernel information instead of longish search for the name. * sysdeps/posix/getcwd.c: Add support for use of the code as a backup solution. 1997-11-12 15:31 Philip Blundell <pb@nexus.co.uk> * sysdeps/unix/sysv/linux/arm/sysdep.h (SYS_ify): Don't add SWI_BASE in twice. * sysdeps/unix/sysv/linux/arm/profil-counter.h (profil_counter): Use correct name to access PC. * sysdeps/unix/arm/sysdep.S: Include <bits/errno.h> not <errnos.h>. * sysdeps/generic/bits/types.h: Add __ino64_t and __off64_t. * sysdeps/generic/bits/stat.h: Add struct stat64. 1997-11-12 16:08 Ulrich Drepper <drepper@cygnus.com> * intl/loadmsgcat.c [_LIBC] (fstat): Don't define as __fstat since now we have a definition as _fxstat. * libio/fileops.c: Likewise. * libio/oldfileops.c: Likewise. Reported by Andreas Jaeger <aj@arthur.rhein-neckar.de>. 1997-11-12 Andreas Jaeger <aj@arthur.rhein-neckar.de> * sysdeps/wordsize-32/inttypes.h (SIG_ATOMIC_MAX): Correct value. * sysdeps/wordsize-64/inttypes.h (SIG_ATOMIC_MAX): Likewise. 1997-11-11 Paul Eggert <eggert@twinsun.com> Add overflow checking for 64-bit time_t and 32-bit int. * time/time.h (__offtime): Now returns int. * time/offtime.c (__offtime): Return nonzero if successful; check for tm_year overflow. (DIV): New macro. (LEAPS_THRU_END_OF): Handle negative years correctly. * time/tzset.c (__tz_convert): Return NULL if offtime cannot convert. * time/mktime.c (ranged_convert): New function. (ydhms_tm_diff): Return nonzero if TP is null. (__mktime_internal): Handle cases correctly even if they are near or past the limits of time_t values that can be broken down to struct tm. (print_tm, check_result, main): Diagnose localtime failures. * manual/time.texi: Document the fact that localtime returns 0 if the time can't be represented. 1997-11-12 06:03 Ulrich Drepper <drepper@cygnus.com> * time/strftime.c (memset_space, memset_zero): Use MEMPCPY, not mempcpy. Patch by Ken'ichi Handa <handa@etl.go.jp>. * manual/time.texi: Document %F and %f format for strftime. * manual/arith.texi: Document copysign, nextafter and nan. 1997-11-06 Andreas Jaeger <aj@arthur.rhein-neckar.de> * test-installation.pl: New file. Tests for some installation problems.
This commit is contained in:
parent
cc3fa75512
commit
fe0ec73edb
7
BUGS
7
BUGS
@ -1,7 +1,7 @@
|
||||
List of known bugs (certainly very incomplete)
|
||||
----------------------------------------------
|
||||
|
||||
Time-stamp: <1997-11-05T16:59:11+0100 drepper>
|
||||
Time-stamp: <1997-11-12T04:42:03+0100 drepper>
|
||||
|
||||
This following list contains those bugs which I'm aware of. Please
|
||||
make sure that bugs you report are not listed here. If you can fix one
|
||||
@ -55,6 +55,11 @@ Severity: [ *] to [***]
|
||||
checked for errors, but the whole file containing the same
|
||||
category.
|
||||
[PR libc/207]
|
||||
|
||||
[ *] The libm-ieee `asin' function gives wrong results (at least for 0.5).
|
||||
|
||||
[ *] _IO_getline can loop forever, at least with C++
|
||||
[PR libc/332]
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
Ulrich Drepper
|
||||
drepper@cygnus.com
|
||||
|
98
ChangeLog
98
ChangeLog
@ -1,3 +1,101 @@
|
||||
1997-11-13 01:07 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* manual/arith.texi: Update documentation according to most recent
|
||||
ISO C 9X draft.
|
||||
Document fma, fdim, fmin, and fmax.
|
||||
* manual/math.texi: Allow multiple defitino of mul etc.
|
||||
|
||||
* math/complex.h (I): Define using _Complex_U not _Imaginary_I.
|
||||
|
||||
* math/libm-test.c: Add tests for fma.
|
||||
|
||||
* math/math.h: Describe DECIMAL_DIG macro. Pretty print.
|
||||
|
||||
* sysdeps/alpha/fpu/bits/mathdef.h: Define INFINITY as of type float.
|
||||
Define DECIMAL_DIG.
|
||||
* sysdeps/generic/bits/mathdef.h: Likewise.
|
||||
* sysdeps/i386/bits/mathdef.h: Likewise.
|
||||
* sysdeps/m68k/fpu/bits/mathdef.h: Likewise.
|
||||
* sysdeps/powerpc/bits/mathdef.h: Likewise.
|
||||
* sysdeps/sparc/fpu/bits/mathdef.h: Likewise.
|
||||
|
||||
* sysdeps/ieee754/bits/nan.h: Define NAN as of type float.
|
||||
* sysdeps/m68k/bits/nan.h. Likewise. Remove NANF and NANL.
|
||||
|
||||
1997-11-12 17:50 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* sunrpc/xcrypt.c: Don't process #ident preprocessor instruction.
|
||||
Reported by Philip Blundell <pb@nexus.co.uk>.
|
||||
|
||||
* string/strndup.c: Use K&R like definition.
|
||||
|
||||
* sysdeps/unix/sysv/linux/getcwd.c: New file. Use kernel information
|
||||
instead of longish search for the name.
|
||||
* sysdeps/posix/getcwd.c: Add support for use of the code as a
|
||||
backup solution.
|
||||
|
||||
1997-11-12 15:31 Philip Blundell <pb@nexus.co.uk>
|
||||
|
||||
* sysdeps/unix/sysv/linux/arm/sysdep.h (SYS_ify): Don't add
|
||||
SWI_BASE in twice.
|
||||
|
||||
* sysdeps/unix/sysv/linux/arm/profil-counter.h (profil_counter):
|
||||
Use correct name to access PC.
|
||||
|
||||
* sysdeps/unix/arm/sysdep.S: Include <bits/errno.h> not <errnos.h>.
|
||||
|
||||
* sysdeps/generic/bits/types.h: Add __ino64_t and __off64_t.
|
||||
* sysdeps/generic/bits/stat.h: Add struct stat64.
|
||||
|
||||
1997-11-12 16:08 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* intl/loadmsgcat.c [_LIBC] (fstat): Don't define as __fstat since
|
||||
now we have a definition as _fxstat.
|
||||
* libio/fileops.c: Likewise.
|
||||
* libio/oldfileops.c: Likewise.
|
||||
Reported by Andreas Jaeger <aj@arthur.rhein-neckar.de>.
|
||||
|
||||
1997-11-12 Andreas Jaeger <aj@arthur.rhein-neckar.de>
|
||||
|
||||
* sysdeps/wordsize-32/inttypes.h (SIG_ATOMIC_MAX): Correct value.
|
||||
* sysdeps/wordsize-64/inttypes.h (SIG_ATOMIC_MAX): Likewise.
|
||||
|
||||
1997-11-11 Paul Eggert <eggert@twinsun.com>
|
||||
|
||||
Add overflow checking for 64-bit time_t and 32-bit int.
|
||||
|
||||
* time/time.h (__offtime): Now returns int.
|
||||
|
||||
* time/offtime.c (__offtime): Return nonzero if successful;
|
||||
check for tm_year overflow.
|
||||
(DIV): New macro.
|
||||
(LEAPS_THRU_END_OF): Handle negative years correctly.
|
||||
|
||||
* time/tzset.c (__tz_convert): Return NULL if offtime cannot convert.
|
||||
|
||||
* time/mktime.c (ranged_convert): New function.
|
||||
(ydhms_tm_diff): Return nonzero if TP is null.
|
||||
(__mktime_internal): Handle cases correctly even if they are near or
|
||||
past the limits of time_t values that can be broken down to struct tm.
|
||||
(print_tm, check_result, main): Diagnose localtime failures.
|
||||
|
||||
* manual/time.texi: Document the fact that localtime returns 0
|
||||
if the time can't be represented.
|
||||
|
||||
1997-11-12 06:03 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* time/strftime.c (memset_space, memset_zero): Use MEMPCPY, not
|
||||
mempcpy. Patch by Ken'ichi Handa <handa@etl.go.jp>.
|
||||
|
||||
* manual/time.texi: Document %F and %f format for strftime.
|
||||
|
||||
* manual/arith.texi: Document copysign, nextafter and nan.
|
||||
|
||||
1997-11-06 Andreas Jaeger <aj@arthur.rhein-neckar.de>
|
||||
|
||||
* test-installation.pl: New file. Tests for some installation
|
||||
problems.
|
||||
|
||||
1997-11-11 21:30 Ulrich Drepper <drepper@cygnus.com>
|
||||
|
||||
* include/sys/stat.h: Define stat, fstat, lstat and *64 variants
|
||||
|
@ -31,10 +31,13 @@ typedef double double_t; /* `double' expressions are evaluated as
|
||||
/* Signal that both types are `double'. */
|
||||
#define FLT_EVAL_METHOD 1
|
||||
|
||||
/* Define `INFINITY' as value of type `float_t'. */
|
||||
#define INFINITY HUGE_VAL
|
||||
/* Define `INFINITY' as value of type `float'. */
|
||||
#define INFINITY HUGE_VALF
|
||||
|
||||
|
||||
/* The values returned by `ilogb' for 0 and NaN respectively. */
|
||||
#define FP_ILOGB0 0x80000001
|
||||
#define FP_ILOGBNAN 0x7fffffff
|
||||
|
||||
/* Number of decimal digits for the `double' type. */
|
||||
#define DECIMAL_DIG 15
|
||||
|
20
bits/stat.h
20
bits/stat.h
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1992, 1996 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1992, 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -70,5 +70,23 @@ struct stat
|
||||
#define __S_IWRITE 0200 /* Write by owner. */
|
||||
#define __S_IEXEC 0100 /* Execute by owner. */
|
||||
|
||||
#ifdef __USE_LARGEFILE64
|
||||
struct stat64
|
||||
{
|
||||
__dev_t st_dev; /* Device. */
|
||||
|
||||
__ino64_t st_ino; /* File serial number. */
|
||||
__mode_t st_mode; /* File mode. */
|
||||
__nlink_t st_nlink; /* Link count. */
|
||||
__uid_t st_uid; /* User ID of the file's owner. */
|
||||
__gid_t st_gid; /* Group ID of the file's group.*/
|
||||
__off64_t st_size; /* Size of file, in bytes. */
|
||||
|
||||
__time_t st_atime; /* Time of last access. */
|
||||
__time_t st_mtime; /* Time of last modification. */
|
||||
__time_t st_ctime; /* Time of last status change. */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* bits/stat.h */
|
||||
|
@ -67,6 +67,8 @@ typedef __u_quad_t __fsid_t; /* Type of file system IDs. */
|
||||
typedef long int __clock_t; /* Type of CPU usage counts. */
|
||||
typedef long int __rlim_t; /* Type for resource measurement. */
|
||||
typedef __quad_t __rlim64_t; /* Type for resource measurement (LFS). */
|
||||
typedef __quad_t __ino64_t; /* Type for file serial numbers. */
|
||||
typedef __loff_t __off64_t; /* Type of file izes and offsets. */
|
||||
|
||||
/* Everythin' else. */
|
||||
typedef long int __daddr_t; /* The type of a disk address. */
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define stat(fname, buf) __xstat (_STAT_VER, fname, buf)
|
||||
#define fstat(fd, buf) __fxstat (_STAT_VER, fd, buf)
|
||||
#define lstat(fname, buf) __lxstat (_STAT_VER, fname, buf)
|
||||
#define __lstat(fname, buf) __lxstat (_STAT_VER, fname, buf)
|
||||
#define stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf)
|
||||
#define fstat64(fd, buf) __fxstat64 (_STAT_VER, fd, buf)
|
||||
#define lstat64(fname, buf) __lxstat64 (_STAT_VER, fname, buf)
|
||||
|
@ -48,7 +48,6 @@
|
||||
/* Rename the non ISO C functions. This is required by the standard
|
||||
because some ISO C functions will require linking with this object
|
||||
file and the name space must not be polluted. */
|
||||
# define fstat __fstat
|
||||
# define open __open
|
||||
# define close __close
|
||||
# define read __read
|
||||
|
@ -45,7 +45,6 @@ extern int errno;
|
||||
#ifdef _LIBC
|
||||
# define open(Name, Flags, Prot) __open (Name, Flags, Prot)
|
||||
# define close(FD) __close (FD)
|
||||
# define fstat(FD, Statbuf) __fstat (FD, Statbuf)
|
||||
# define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
|
||||
# define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
|
||||
# define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
|
||||
|
@ -49,7 +49,6 @@ extern int errno;
|
||||
#ifdef _LIBC
|
||||
# define open(Name, Flags, Prot) __open (Name, Flags, Prot)
|
||||
# define close(FD) __close (FD)
|
||||
# define fstat(FD, Statbuf) __fstat (FD, Statbuf)
|
||||
# define lseek(FD, Offset, Whence) __lseek (FD, Offset, Whence)
|
||||
# define read(FD, Buf, NBytes) __read (FD, Buf, NBytes)
|
||||
# define write(FD, Buf, NBytes) __write (FD, Buf, NBytes)
|
||||
|
@ -1,3 +1,19 @@
|
||||
@c We need some definitions here.
|
||||
@ifclear cdor
|
||||
@ifhtml
|
||||
@set cdot ·
|
||||
@end ifhtml
|
||||
@iftex
|
||||
@set cdot @cdot
|
||||
@end iftex
|
||||
@ifclear cdot
|
||||
@set cdot x
|
||||
@end ifclear
|
||||
@macro mul
|
||||
@value{cdot}
|
||||
@end macro
|
||||
@end ifclear
|
||||
|
||||
@node Arithmetic, Date and Time, Mathematics, Top
|
||||
@chapter Low-Level Arithmetic Functions
|
||||
|
||||
@ -18,6 +34,8 @@ These functions are declared in the header files @file{math.h} and
|
||||
* Normalization Functions:: Hacks for radix-2 representations.
|
||||
* Rounding and Remainders:: Determining the integer and
|
||||
fractional parts of a float.
|
||||
* Arithmetic on FP Values:: Setting and Modifying Single Bits of FP Values.
|
||||
* Special arithmetic on FPs:: Special Arithmetic on FPs.
|
||||
* Integer Division:: Functions for performing integer
|
||||
division.
|
||||
* Parsing of Numbers:: Functions for ``reading'' numbers
|
||||
@ -40,7 +58,7 @@ these situations. There is a special value for infinity.
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypevr Macro float_t INFINITY
|
||||
@deftypevr Macro float INFINITY
|
||||
An expression representing the infinite value. @code{INFINITY} values are
|
||||
produced by mathematical operations like @code{1.0 / 0.0}. It is
|
||||
possible to continue the computations with this value since the basic
|
||||
@ -85,7 +103,7 @@ a NaN.
|
||||
|
||||
@comment math.h
|
||||
@comment GNU
|
||||
@deftypevr Macro double NAN
|
||||
@deftypevr Macro float NAN
|
||||
An expression representing a value which is ``not a number''. This
|
||||
macro is a GNU extension, available only on machines that support ``not
|
||||
a number'' values---that is to say, on all machines that support IEEE
|
||||
@ -106,15 +124,39 @@ imaginary part of the numbers. In mathematics one uses the symbol ``i''
|
||||
to mark a number as imaginary. For convenience the @file{complex.h}
|
||||
header defines two macros which allow to use a similar easy notation.
|
||||
|
||||
@deftypevr Macro float_t _Imaginary_I
|
||||
This macro is a (compiler specific) representation of the value ``1i''.
|
||||
I.e., it is the value for which
|
||||
@deftypevr Macro {const float complex} _Complex_I
|
||||
This macro is a representation of the complex number ``@math{0+1i}''.
|
||||
Computing
|
||||
|
||||
@smallexample
|
||||
_Complex_I * _Complex_I = -1
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
leads to a real-valued result. If no @code{imaginary} types are
|
||||
available it is easiest to use this value to construct complex numbers
|
||||
from real values:
|
||||
|
||||
@smallexample
|
||||
3.0 - _Complex_I * 4.0
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
Without an optimizing compiler this is more expensive than the use of
|
||||
@code{_Imaginary_I} but with is better than nothing. You can avoid all
|
||||
the hassles if you use the @code{I} macro below if the name is not
|
||||
problem.
|
||||
|
||||
@deftypevr Macro {const float imaginary} _Imaginary_I
|
||||
This macro is a representation of the value ``@math{1i}''. I.e., it is
|
||||
the value for which
|
||||
|
||||
@smallexample
|
||||
_Imaginary_I * _Imaginary_I = -1
|
||||
@end smallexample
|
||||
|
||||
@noindent
|
||||
The result is not of type @code{float imaginary} but instead @code{float}.
|
||||
One can use it to easily construct complex number like in
|
||||
|
||||
@smallexample
|
||||
@ -129,11 +171,16 @@ imaginary part -4.0.
|
||||
@noindent
|
||||
A more intuitive approach is to use the following macro.
|
||||
|
||||
@deftypevr Macro float_t I
|
||||
@deftypevr Macro {const float imaginary} I
|
||||
This macro has exactly the same value as @code{_Imaginary_I}. The
|
||||
problem is that the name @code{I} very easily can clash with macros or
|
||||
variables in programs and so it might be a good idea to avoid this name
|
||||
and stay at the safe side by using @code{_Imaginary_I}.
|
||||
|
||||
If the implementation does not support the @code{imaginary} types
|
||||
@code{I} is defined as @code{_Complex_I} which is the second best
|
||||
solution. It still can be used in the same way but requires a most
|
||||
clever compiler to get the same results.
|
||||
@end deftypevr
|
||||
|
||||
|
||||
@ -379,7 +426,7 @@ whose imaginary part is @var{y}, the absolute value is @w{@code{sqrt
|
||||
|
||||
@pindex math.h
|
||||
@pindex stdlib.h
|
||||
Prototypes for @code{abs} and @code{labs} are in @file{stdlib.h};
|
||||
Prototypes for @code{abs}, @code{labs} and @code{llabs} are in @file{stdlib.h};
|
||||
@code{fabs}, @code{fabsf} and @code{fabsl} are declared in @file{math.h};
|
||||
@code{cabs}, @code{cabsf} and @code{cabsl} are declared in @file{complex.h}.
|
||||
|
||||
@ -400,6 +447,15 @@ This is similar to @code{abs}, except that both the argument and result
|
||||
are of type @code{long int} rather than @code{int}.
|
||||
@end deftypefun
|
||||
|
||||
@comment stdlib.h
|
||||
@comment ISO
|
||||
@deftypefun {long long int} llabs (long long int @var{number})
|
||||
This is similar to @code{abs}, except that both the argument and result
|
||||
are of type @code{long long int} rather than @code{int}.
|
||||
|
||||
This function is defined in @w{ISO C 9X}.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double fabs (double @var{number})
|
||||
@ -512,29 +568,6 @@ The value returned by @code{logb} is one less than the value that
|
||||
@code{frexp} would store into @code{*@var{exponent}}.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double copysign (double @var{value}, double @var{sign})
|
||||
@deftypefunx float copysignf (float @var{value}, float @var{sign})
|
||||
@deftypefunx {long double} copysignl (long double @var{value}, long double @var{sign})
|
||||
These functions return a value whose absolute value is the
|
||||
same as that of @var{value}, and whose sign matches that of @var{sign}.
|
||||
This function appears in BSD and was standardized in @w{ISO C 9X}.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun int signbit (@emph{float-type} @var{x})
|
||||
@code{signbit} is a generic macro which can work on all floating-point
|
||||
types. It returns a nonzero value if the value of @var{x} has its sign
|
||||
bit set.
|
||||
|
||||
This is not the same as @code{x < 0.0} since in some floating-point
|
||||
formats (e.g., @w{IEEE 754}) the zero value is optionally signed. The
|
||||
comparison @code{-0.0 < 0.0} will not be true while @code{signbit
|
||||
(-0.0)} will return a nonzero value.
|
||||
@end deftypefun
|
||||
|
||||
@node Rounding and Remainders
|
||||
@section Rounding and Remainder Functions
|
||||
@cindex rounding functions
|
||||
@ -652,6 +685,161 @@ If @var{denominator} is zero, @code{drem} fails and sets @code{errno} to
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@node Arithmetic on FP Values
|
||||
@section Setting and modifying Single Bits of FP Values
|
||||
@cindex FP arithmetic
|
||||
|
||||
In certain situations it is too complicated (or expensive) to modify a
|
||||
floating-point value by the normal operations. For a few operations
|
||||
@w{ISO C 9X} defines functions to modify the floating-point value
|
||||
directly.
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double copysign (double @var{x}, double @var{y})
|
||||
@deftypefunx float copysignf (float @var{x}, float @var{y})
|
||||
@deftypefunx {long double} copysignl (long double @var{x}, long double @var{y})
|
||||
The @code{copysign} function allows to specifiy the sign of the
|
||||
floating-point value given in the parameter @var{x} by discarding the
|
||||
prior content and replacing it with the sign of the value @var{y}.
|
||||
The so found value is returned.
|
||||
|
||||
This function also works and throws no exception if the parameter
|
||||
@var{x} is a @code{NaN}. If the platform supports the signed zero
|
||||
representation @var{x} might also be zero.
|
||||
|
||||
This function is defined in @w{IEC 559} (and the appendix with
|
||||
recommended functions in @w{IEEE 754}/@w{IEEE 854}).
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun int signbit (@emph{float-type} @var{x})
|
||||
@code{signbit} is a generic macro which can work on all floating-point
|
||||
types. It returns a nonzero value if the value of @var{x} has its sign
|
||||
bit set.
|
||||
|
||||
This is not the same as @code{x < 0.0} since in some floating-point
|
||||
formats (e.g., @w{IEEE 754}) the zero value is optionally signed. The
|
||||
comparison @code{-0.0 < 0.0} will not be true while @code{signbit
|
||||
(-0.0)} will return a nonzero value.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double nextafter (double @var{x}, double @var{y})
|
||||
@deftypefunx float nextafterf (float @var{x}, float @var{y})
|
||||
@deftypefunx {long double} nextafterl (long double @var{x}, long double @var{y})
|
||||
The @code{nextafter} function returns the next representable neighbor of
|
||||
@var{x} in the direction towards @var{y}. Depending on the used data
|
||||
type the steps make have a different size. If @math{@var{x} = @var{y}}
|
||||
the function simply returns @var{x}. If either value is a @code{NaN}
|
||||
one the @code{NaN} values is returned. Otherwise a value corresponding
|
||||
to the value of the least significant bit in the mantissa is
|
||||
added/subtracted (depending on the direction). If the resulting value
|
||||
is not finite but @var{x} is, overflow is signaled. Underflow is
|
||||
signaled if the resulting value is a denormalized number (if the @w{IEEE
|
||||
754}/@w{IEEE 854} representation is used).
|
||||
|
||||
This function is defined in @w{IEC 559} (and the appendix with
|
||||
recommended functions in @w{IEEE 754}/@w{IEEE 854}).
|
||||
@end deftypefun
|
||||
|
||||
@cindex NaN
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double nan (const char *@var{tagp})
|
||||
@deftypefunx float nanf (const char *@var{tagp})
|
||||
@deftypefunx {long double} nanl (const char *@var{tagp})
|
||||
The @code{nan} function returns a representation of the NaN value. If
|
||||
quiet NaNs are supported by the platform a call like @code{nan
|
||||
("@var{n-char-sequence}")} is equivalent to @code{strtod
|
||||
("NAN(@var{n-char-sequence})")}. The exact implementation is left
|
||||
unspecified but on systems using IEEE arithmethic the
|
||||
@var{n-char-sequence} specifies the bits of the mantissa for the NaN
|
||||
value.
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@node Special arithmetic on FPs
|
||||
@section Special Arithmetic on FPs
|
||||
@cindex positive difference
|
||||
@cindex minimum
|
||||
@cindex maximum
|
||||
|
||||
A frequent operation of numbers is the determination of mimuma, maxima,
|
||||
or the difference between numbers. The @w{ISO C 9X} standard introduces
|
||||
three functions which implement this efficiently while also providing
|
||||
some useful functions which is not so efficient to implement. Machine
|
||||
specific implementation might perform this very efficient.
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double fmin (double @var{x}, double @var{y})
|
||||
@deftypefunx float fminf (float @var{x}, float @var{y})
|
||||
@deftypefunx {long double} fminl (long double @var{x}, long double @var{y})
|
||||
The @code{fmin} function determine the minimum of the two values @var{x}
|
||||
and @var{y} and returns it.
|
||||
|
||||
If an argument is NaN it as treated as missing and the other value is
|
||||
returned. If both values are NaN one of the values is returned.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double fmax (double @var{x}, double @var{y})
|
||||
@deftypefunx float fmaxf (float @var{x}, float @var{y})
|
||||
@deftypefunx {long double} fmaxl (long double @var{x}, long double @var{y})
|
||||
The @code{fmax} function determine the maximum of the two values @var{x}
|
||||
and @var{y} and returns it.
|
||||
|
||||
If an argument is NaN it as treated as missing and the other value is
|
||||
returned. If both values are NaN one of the values is returned.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double fdim (double @var{x}, double @var{y})
|
||||
@deftypefunx float fdimf (float @var{x}, float @var{y})
|
||||
@deftypefunx {long double} fdiml (long double @var{x}, long double @var{y})
|
||||
The @code{fdim} function computes the positive difference between
|
||||
@var{x} and @var{y} and returns this value. @dfn{Positive difference}
|
||||
means that if @var{x} is greater than @var{y} the value @math{@var{x} -
|
||||
@var{y}} is returned. Otherwise the return value is @math{+0}.
|
||||
|
||||
If any of the arguments is NaN this value is returned. If both values
|
||||
are NaN, one of the values is returned.
|
||||
@end deftypefun
|
||||
|
||||
@comment math.h
|
||||
@comment ISO
|
||||
@deftypefun double fma (double @var{x}, double @var{y}, double @var{z})
|
||||
@deftypefunx float fmaf (float @var{x}, float @var{y}, float @var{z})
|
||||
@deftypefunx {long double} fmal (long double @var{x}, long double @var{y}, long double @var{z})
|
||||
@cindex butterfly
|
||||
The name of the function @code{fma} means floating-point multiply-add.
|
||||
I.e., the operation performed is @math{(@var{x} @mul{} @var{y}) +
|
||||
@var{z}}. The speciality of this function is that the intermediate
|
||||
result is not rounded and the addition is performed with the full
|
||||
precision of the multiplcation.
|
||||
|
||||
This function was introduced because some processors provide such a
|
||||
function in their FPU implementation. Since compilers cannot optimize
|
||||
code which performs the operation in single steps using this opcode
|
||||
because of rounding differences the operation is available separately so
|
||||
the programmer can select when the rounding of the intermediate result
|
||||
is not important.
|
||||
|
||||
@vindex FP_FAST_FMA
|
||||
If the @file{math.h} header defines the symbol @code{FP_FAST_FMA} (or
|
||||
@code{FP_FAST_FMAF} and @code{FP_FAST_FMAL} for @code{float} and
|
||||
@code{long double} respectively) the processor typically defines the
|
||||
operation in hardware. The symbols might also be defined if the
|
||||
software implementation is as fast as a multiply and an add but in the
|
||||
GNU C Library the macros indicate hardware support.
|
||||
@end deftypefun
|
||||
|
||||
|
||||
@node Integer Division
|
||||
@section Integer Division
|
||||
@cindex integer division functions
|
||||
|
@ -1,4 +1,5 @@
|
||||
@c We need some definitions here.
|
||||
@ifclear cdot
|
||||
@ifhtml
|
||||
@set cdot ·
|
||||
@end ifhtml
|
||||
@ -8,15 +9,16 @@
|
||||
@ifclear cdot
|
||||
@set cdot x
|
||||
@end ifclear
|
||||
@macro mul
|
||||
@value{cdot}
|
||||
@end macro
|
||||
@end ifclear
|
||||
@iftex
|
||||
@set infty @infty
|
||||
@end iftex
|
||||
@ifclear infty
|
||||
@set infty oo
|
||||
@end ifclear
|
||||
@macro mul
|
||||
@value{cdot}
|
||||
@end macro
|
||||
@macro infinity
|
||||
@value{infty}
|
||||
@end macro
|
||||
|
@ -531,6 +531,10 @@ might be overwritten by subsequent calls to @code{ctime}, @code{gmtime},
|
||||
or @code{localtime}. (But no other library function overwrites the contents
|
||||
of this object.)
|
||||
|
||||
The return value is the null pointer if @var{time} cannot be represented
|
||||
as a broken-down time; typically this is because the year cannot fit into
|
||||
an @code{int}.
|
||||
|
||||
Calling @code{localtime} has one other effect: it sets the variable
|
||||
@code{tzname} with information about the current time zone. @xref{Time
|
||||
Zone Functions}.
|
||||
@ -784,6 +788,18 @@ The day of the month like with @code{%d}, but padded with blank (range
|
||||
|
||||
This format is a POSIX.2 extension.
|
||||
|
||||
@item %f
|
||||
The day of the week as a decimal number (range @code{1} through
|
||||
@code{7}), Monday being @code{1}.
|
||||
|
||||
This format is a @w{ISO C 9X} extension.
|
||||
|
||||
@item %F
|
||||
The date using the format @code{%Y-%m-%d}. This is the form specified
|
||||
in the @w{ISO 8601} standard and is the preferred form for all uses.
|
||||
|
||||
This format is a @w{ISO C 9X} extension.
|
||||
|
||||
@item %g
|
||||
The year corresponding to the ISO week number, but without the century
|
||||
(range @code{00} through @code{99}). This has the same format and value
|
||||
|
@ -40,9 +40,10 @@ __BEGIN_DECLS
|
||||
XXX This probably has to go into a gcc related file. */
|
||||
#define _Complex_I (1.0iF)
|
||||
|
||||
/* Another more descriptive name is `I'. */
|
||||
/* Another more descriptive name is `I'.
|
||||
XXX Once we have the imaginary support switch this to _Imaginary_I. */
|
||||
#undef I
|
||||
#define I _Imaginary_I
|
||||
#define I _Complex_I
|
||||
|
||||
|
||||
/* Optimization aids. This is not yet implemented in gcc and once it
|
||||
|
@ -4812,6 +4812,50 @@ llround_test (void)
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
fma_test (void)
|
||||
{
|
||||
check ("fma(1.0, 2.0, 3.0) = 5.0", FUNC(fma) (1.0, 2.0, 3.0), 5.0);
|
||||
check_isnan ("fma(NaN, 2.0, 3.0) = NaN", FUNC(fma) (nan_value, 2.0, 3.0));
|
||||
check_isnan ("fma(1.0, NaN, 3.0) = NaN", FUNC(fma) (1.0, nan_value, 3.0));
|
||||
check_isnan_maybe_exc ("fma(1.0, 2.0, NaN) = NaN",
|
||||
FUNC(fma) (1.0, 2.0, nan_value), INVALID_EXCEPTION);
|
||||
check_isnan_maybe_exc ("fma(+Inf, 0.0, NaN) = NaN",
|
||||
FUNC(fma) (plus_infty, 0.0, nan_value),
|
||||
INVALID_EXCEPTION);
|
||||
check_isnan_maybe_exc ("fma(-Inf, 0.0, NaN) = NaN",
|
||||
FUNC(fma) (minus_infty, 0.0, nan_value),
|
||||
INVALID_EXCEPTION);
|
||||
check_isnan_maybe_exc ("fma(0.0, +Inf, NaN) = NaN",
|
||||
FUNC(fma) (0.0, plus_infty, nan_value),
|
||||
INVALID_EXCEPTION);
|
||||
check_isnan_maybe_exc ("fma(0.0, -Inf, NaN) = NaN",
|
||||
FUNC(fma) (0.0, minus_infty, nan_value),
|
||||
INVALID_EXCEPTION);
|
||||
check_isnan_exc ("fma(+Inf, 0.0, 1.0) = NaN",
|
||||
FUNC(fma) (plus_infty, 0.0, 1.0), INVALID_EXCEPTION);
|
||||
check_isnan_exc ("fma(-Inf, 0.0, 1.0) = NaN",
|
||||
FUNC(fma) (minus_infty, 0.0, 1.0), INVALID_EXCEPTION);
|
||||
check_isnan_exc ("fma(0.0, +Inf, 1.0) = NaN",
|
||||
FUNC(fma) (0.0, plus_infty, 1.0), INVALID_EXCEPTION);
|
||||
check_isnan_exc ("fma(0.0, -Inf, 1.0) = NaN",
|
||||
FUNC(fma) (0.0, minus_infty, 1.0), INVALID_EXCEPTION);
|
||||
|
||||
check_isnan_exc ("fma(+Inf, +Inf, -Inf) = NaN",
|
||||
FUNC(fma) (plus_infty, plus_infty, minus_infty),
|
||||
INVALID_EXCEPTION);
|
||||
check_isnan_exc ("fma(-Inf, +Inf, +Inf) = NaN",
|
||||
FUNC(fma) (minus_infty, plus_infty, plus_infty),
|
||||
INVALID_EXCEPTION);
|
||||
check_isnan_exc ("fma(+Inf, -Inf, +Inf) = NaN",
|
||||
FUNC(fma) (plus_infty, minus_infty, plus_infty),
|
||||
INVALID_EXCEPTION);
|
||||
check_isnan_exc ("fma(-Inf, -Inf, -Inf) = NaN",
|
||||
FUNC(fma) (minus_infty, minus_infty, minus_infty),
|
||||
INVALID_EXCEPTION);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
inverse_func_pair_test (const char *test_name,
|
||||
mathfunc f1, mathfunc inverse,
|
||||
@ -5205,6 +5249,7 @@ main (int argc, char *argv[])
|
||||
ctanh_test ();
|
||||
csqrt_test ();
|
||||
cpow_test ();
|
||||
fma_test ();
|
||||
|
||||
/* special tests */
|
||||
identities ();
|
||||
|
69
math/math.h
69
math/math.h
@ -68,37 +68,37 @@ __BEGIN_DECLS
|
||||
/* Include the file of declarations again, this time using `float'
|
||||
instead of `double' and appending f to each function name. */
|
||||
|
||||
#ifndef _Mfloat_
|
||||
# define _Mfloat_ float
|
||||
#endif
|
||||
#define _Mdouble_ _Mfloat_
|
||||
#ifdef __STDC__
|
||||
# define __MATH_PRECNAME(name,r) name##f##r
|
||||
#else
|
||||
# define __MATH_PRECNAME(name,r) name/**/f/**/r
|
||||
#endif
|
||||
#include <bits/mathcalls.h>
|
||||
#undef _Mdouble_
|
||||
#undef __MATH_PRECNAME
|
||||
|
||||
#if __STDC__ - 0 || __GNUC__ - 0
|
||||
/* Include the file of declarations again, this time using `long double'
|
||||
instead of `double' and appending l to each function name. */
|
||||
|
||||
# ifndef _Mlong_double_
|
||||
# define _Mlong_double_ long double
|
||||
# ifndef _Mfloat_
|
||||
# define _Mfloat_ float
|
||||
# endif
|
||||
# define _Mdouble_ _Mlong_double_
|
||||
# define _Mdouble_ _Mfloat_
|
||||
# ifdef __STDC__
|
||||
# define __MATH_PRECNAME(name,r) name##l##r
|
||||
# define __MATH_PRECNAME(name,r) name##f##r
|
||||
# else
|
||||
# define __MATH_PRECNAME(name,r) name/**/l/**/r
|
||||
# define __MATH_PRECNAME(name,r) name/**/f/**/r
|
||||
# endif
|
||||
# include <bits/mathcalls.h>
|
||||
# undef _Mdouble_
|
||||
# undef __MATH_PRECNAME
|
||||
|
||||
#endif /* __STDC__ || __GNUC__ */
|
||||
# if __STDC__ - 0 || __GNUC__ - 0
|
||||
/* Include the file of declarations again, this time using `long double'
|
||||
instead of `double' and appending l to each function name. */
|
||||
|
||||
# ifndef _Mlong_double_
|
||||
# define _Mlong_double_ long double
|
||||
# endif
|
||||
# define _Mdouble_ _Mlong_double_
|
||||
# ifdef __STDC__
|
||||
# define __MATH_PRECNAME(name,r) name##l##r
|
||||
# else
|
||||
# define __MATH_PRECNAME(name,r) name/**/l/**/r
|
||||
# endif
|
||||
# include <bits/mathcalls.h>
|
||||
# undef _Mdouble_
|
||||
# undef __MATH_PRECNAME
|
||||
|
||||
# endif /* __STDC__ || __GNUC__ */
|
||||
|
||||
#endif /* Use misc or ISO C 9X. */
|
||||
#undef __MATHDECL_1
|
||||
@ -118,23 +118,23 @@ extern int signgam;
|
||||
/* Get the architecture specific values describing the floating-point
|
||||
evaluation. The following symbols will get defined:
|
||||
|
||||
float_t floating-point type at least as wide as `float' used
|
||||
float_t floating-point type at least as wide as `float' used
|
||||
to evaluate `float' expressions
|
||||
double_t floating-point type at least as wide as `double' used
|
||||
double_t floating-point type at least as wide as `double' used
|
||||
to evaluate `double' expressions
|
||||
|
||||
FLT_EVAL_METHOD
|
||||
FLT_EVAL_METHOD
|
||||
Defined to
|
||||
0 if `float_t' is `float' and `double_t' is `double'
|
||||
1 if `float_t' and `double_t' are `double'
|
||||
2 if `float_t' and `double_t' are `long double'
|
||||
else `float_t' and `double_t' are unspecified
|
||||
|
||||
INFINITY representation of the infinity value of type `float_t'
|
||||
INFINITY representation of the infinity value of type `float'
|
||||
|
||||
FP_FAST_FMA
|
||||
FP_FAST_FMAF
|
||||
FP_FAST_FMAL
|
||||
FP_FAST_FMA
|
||||
FP_FAST_FMAF
|
||||
FP_FAST_FMAL
|
||||
If defined it indicates that the the `fma' function
|
||||
generally executes about as fast as a multiply and an add.
|
||||
This macro is defined only iff the `fma' function is
|
||||
@ -143,6 +143,9 @@ extern int signgam;
|
||||
FP_ILOGB0 Expands to a value returned by `ilogb (0.0)'.
|
||||
FP_ILOGBNAN Expands to a value returned by `ilogb (NAN)'.
|
||||
|
||||
DECIMAL_DIG Number of decimal digits supported by conversion between
|
||||
decimal and all internal floating-point formats.
|
||||
|
||||
*/
|
||||
# include <bits/mathdef.h>
|
||||
|
||||
@ -211,8 +214,8 @@ extern _LIB_VERSION_TYPE _LIB_VERSION;
|
||||
/* In SVID error handling, `matherr' is called with this description
|
||||
of the exceptional condition.
|
||||
|
||||
We have a problem when using C++ since `exception' is reserved in
|
||||
C++. */
|
||||
We have a problem when using C++ since `exception' is a reserved
|
||||
name in C++. */
|
||||
# ifdef __cplusplus
|
||||
struct __exception
|
||||
# else
|
||||
@ -307,7 +310,7 @@ extern int matherr __P ((struct exception *__exc));
|
||||
for unordered numbers. Since many FPUs provide special
|
||||
instructions to support these operations and these tests are
|
||||
defined in <bits/mathinline.h>, we define the generic macros at
|
||||
this late point. */
|
||||
this late point and only if they are not defined yet. */
|
||||
|
||||
/* Return nonzero value if X is greater than Y. */
|
||||
# ifndef isgreater
|
||||
|
@ -35,7 +35,9 @@ char *malloc ();
|
||||
#endif
|
||||
|
||||
char *
|
||||
__strndup (const char *s, size_t n)
|
||||
__strndup (s, n)
|
||||
const char *s;
|
||||
size_t n;
|
||||
{
|
||||
size_t len = strnlen (s, n);
|
||||
char *new = malloc (len + 1);
|
||||
|
@ -31,7 +31,9 @@
|
||||
* Copyright (c) 1986-1991 by Sun Microsystems Inc.
|
||||
*/
|
||||
|
||||
#if 0
|
||||
#ident "@(#)xcrypt.c 1.11 94/08/23 SMI"
|
||||
#endif
|
||||
|
||||
#if !defined(lint) && defined(SCCSIDS)
|
||||
static char sccsid[] = "@(#)xcrypt.c 1.3 89/03/24 Copyr 1986 Sun Micro";
|
||||
|
@ -17,38 +17,38 @@
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _MATH_H
|
||||
#error "Never use <bits/mathdef.h> directly; include <math.h> instead"
|
||||
# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
|
||||
#endif
|
||||
|
||||
/* FIXME! This file describes properties of the compiler, not the machine;
|
||||
it should not be part of libc! */
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if __STDC__ == 1
|
||||
# if __STDC__ == 1
|
||||
|
||||
/* In GNU or ANSI mode, gcc leaves `float' expressions as-is. */
|
||||
typedef float float_t;
|
||||
typedef double double_t;
|
||||
|
||||
/* Signal that types stay as they were declared. */
|
||||
#define FLT_EVAL_METHOD 0
|
||||
# define FLT_EVAL_METHOD 0
|
||||
|
||||
/* Define `INFINITY' as value of type `float_t'. */
|
||||
#define INFINITY HUGE_VALF
|
||||
/* Define `INFINITY' as value of type `float'. */
|
||||
# define INFINITY HUGE_VALF
|
||||
|
||||
#else
|
||||
# else
|
||||
|
||||
/* For `gcc -traditional', `float' expressions are evaluated as `double'. */
|
||||
typedef double float_t;
|
||||
typedef double double_t;
|
||||
|
||||
/* Signal that both types are `double'. */
|
||||
#define FLT_EVAL_METHOD 1
|
||||
# define FLT_EVAL_METHOD 1
|
||||
|
||||
/* Define `INFINITY' as value of type `float_t'. */
|
||||
#define INFINITY HUGE_VAL
|
||||
/* Define `INFINITY' as value of type `float'. */
|
||||
# define INFINITY HUGE_VALF
|
||||
|
||||
#endif
|
||||
# endif
|
||||
#else
|
||||
|
||||
/* Wild guess at types for float_t and double_t. */
|
||||
@ -56,9 +56,12 @@ typedef double float_t;
|
||||
typedef double double_t;
|
||||
|
||||
/* Strange compiler, we don't know how it works. */
|
||||
#define FLT_EVAL_METHOD -1
|
||||
# define FLT_EVAL_METHOD -1
|
||||
|
||||
/* Define `INFINITY' as value of type `float_t'. */
|
||||
#define INFINITY HUGE_VAL
|
||||
/* Define `INFINITY' as value of type `float'. */
|
||||
# define INFINITY HUGE_VALF
|
||||
|
||||
#endif
|
||||
|
||||
/* Number of decimal digits for the `double' type. */
|
||||
#define DECIMAL_DIG 15
|
||||
|
@ -31,10 +31,13 @@ typedef double double_t; /* `double' expressions are evaluated as
|
||||
/* Signal that both types are `double'. */
|
||||
#define FLT_EVAL_METHOD 1
|
||||
|
||||
/* Define `INFINITY' as value of type `float_t'. */
|
||||
#define INFINITY HUGE_VAL
|
||||
/* Define `INFINITY' as value of type `float'. */
|
||||
#define INFINITY HUGE_VALF
|
||||
|
||||
|
||||
/* The values returned by `ilogb' for 0 and NaN respectively. */
|
||||
#define FP_ILOGB0 0x80000001
|
||||
#define FP_ILOGBNAN 0x7fffffff
|
||||
|
||||
/* Number of decimal digits for the `double' type. */
|
||||
#define DECIMAL_DIG 15
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (C) 1992, 1996 Free Software Foundation, Inc.
|
||||
/* Copyright (C) 1992, 1996, 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
@ -70,5 +70,23 @@ struct stat
|
||||
#define __S_IWRITE 0200 /* Write by owner. */
|
||||
#define __S_IEXEC 0100 /* Execute by owner. */
|
||||
|
||||
#ifdef __USE_LARGEFILE64
|
||||
struct stat64
|
||||
{
|
||||
__dev_t st_dev; /* Device. */
|
||||
|
||||
__ino64_t st_ino; /* File serial number. */
|
||||
__mode_t st_mode; /* File mode. */
|
||||
__nlink_t st_nlink; /* Link count. */
|
||||
__uid_t st_uid; /* User ID of the file's owner. */
|
||||
__gid_t st_gid; /* Group ID of the file's group.*/
|
||||
__off64_t st_size; /* Size of file, in bytes. */
|
||||
|
||||
__time_t st_atime; /* Time of last access. */
|
||||
__time_t st_mtime; /* Time of last modification. */
|
||||
__time_t st_ctime; /* Time of last status change. */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
#endif /* bits/stat.h */
|
||||
|
@ -67,6 +67,8 @@ typedef __u_quad_t __fsid_t; /* Type of file system IDs. */
|
||||
typedef long int __clock_t; /* Type of CPU usage counts. */
|
||||
typedef long int __rlim_t; /* Type for resource measurement. */
|
||||
typedef __quad_t __rlim64_t; /* Type for resource measurement (LFS). */
|
||||
typedef __quad_t __ino64_t; /* Type for file serial numbers. */
|
||||
typedef __loff_t __off64_t; /* Type of file izes and offsets. */
|
||||
|
||||
/* Everythin' else. */
|
||||
typedef long int __daddr_t; /* The type of a disk address. */
|
||||
|
@ -22,8 +22,8 @@
|
||||
|
||||
|
||||
/* The ix87 FPUs evaluate all values in the 80 bit floating-point format
|
||||
which is also available for the user as `long double'. Therefore
|
||||
we define: */
|
||||
which is also available for the user as `long double'. Therefore we
|
||||
define: */
|
||||
typedef long double float_t; /* `float' expressions are evaluated as
|
||||
`long double'. */
|
||||
typedef long double double_t; /* `double' expressions are evaluated as
|
||||
@ -32,10 +32,12 @@ typedef long double double_t; /* `double' expressions are evaluated as
|
||||
/* Signal that both types are `long double'. */
|
||||
#define FLT_EVAL_METHOD 2
|
||||
|
||||
/* Define `INFINITY' as value of type `float_t'. */
|
||||
#define INFINITY HUGE_VALL
|
||||
|
||||
/* Define `INFINITY' as value of type `float'. */
|
||||
#define INFINITY HUGE_VALF
|
||||
|
||||
/* The values returned by `ilogb' for 0 and NaN respectively. */
|
||||
#define FP_ILOGB0 0x80000000
|
||||
#define FP_ILOGBNAN 0x80000000
|
||||
|
||||
/* Number of decimal digits for the `long double' type. */
|
||||
#define DECIMAL_DIG 18
|
||||
|
@ -26,12 +26,7 @@
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
# define NAN \
|
||||
(__extension__ \
|
||||
((union { unsigned __l __attribute__((__mode__(__DI__))); double __d; }) \
|
||||
{ __l: 0x7ff8000000000000ULL }).__d)
|
||||
|
||||
# define NANF \
|
||||
# define NAN \
|
||||
(__extension__ \
|
||||
((union { unsigned __l __attribute__((__mode__(__SI__))); float __d; }) \
|
||||
{ __l: 0x7fc00000UL }).__d)
|
||||
@ -41,23 +36,13 @@
|
||||
# include <endian.h>
|
||||
|
||||
# if __BYTE_ORDER == __BIG_ENDIAN
|
||||
# define __nan_bytes { 0x7f, 0xf8, 0, 0, 0, 0, 0, 0 }
|
||||
# define __nanf_bytes { 0x7f, 0xc0, 0, 0 }
|
||||
# define __nan_bytes { 0x7f, 0xc0, 0, 0 }
|
||||
# endif
|
||||
# if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
# define __nan_bytes { 0, 0, 0, 0, 0, 0, 0xf8, 0x7f }
|
||||
# define __nanf_bytes { 0, 0, 0xc0, 0x7f }
|
||||
# define __nan_bytes { 0, 0, 0xc0, 0x7f }
|
||||
# endif
|
||||
|
||||
static union { unsigned char __c[8]; double __d; } __nan = { __nan_bytes };
|
||||
static union { unsigned char __c[4]; double __d; } __nan = { __nan_bytes };
|
||||
# define NAN (__nan.__d)
|
||||
|
||||
static union { unsigned char __c[4]; double __d; } __nanf = { __nanf_bytes };
|
||||
# define NANF (__nanf.__d)
|
||||
|
||||
#endif /* GCC. */
|
||||
|
||||
/* Generally there is no separate `long double' format and it is the
|
||||
same as `double'. */
|
||||
|
||||
#define NANL NAN
|
||||
|
@ -1,59 +0,0 @@
|
||||
/* `NAN' constants for m68k.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _NAN_H
|
||||
|
||||
#define _NAN_H 1
|
||||
|
||||
/* IEEE Not A Number. */
|
||||
|
||||
#ifdef __GNUC__
|
||||
|
||||
#define NAN \
|
||||
(__extension__ \
|
||||
((union { unsigned long long __l; double __d; }) \
|
||||
{ __l: 0x7fffffffffffffffULL }).__d)
|
||||
|
||||
#define NANF \
|
||||
(__extension__ \
|
||||
((union { unsigned long __l; float __f; }) \
|
||||
{ __l: 0x7fffffffUL }).__f)
|
||||
|
||||
#define NANL \
|
||||
(__extension__ \
|
||||
((union { unsigned long __l[3]; long double __ld; }) \
|
||||
{ __l: { 0x7fff0000UL, 0xffffffffUL, 0xffffffffUL } }).__ld)
|
||||
|
||||
#else
|
||||
|
||||
static union { unsigned char __c[8]; double __d; } __nan =
|
||||
{ { 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
|
||||
#define NAN (__nan.__d)
|
||||
|
||||
static union { unsigned char __c[4]; float __f; } __nanf =
|
||||
{ { 0x7f, 0xff, 0xff, 0xff } };
|
||||
#define NANF (__nanf.__f)
|
||||
|
||||
static union { unsigned char __c[12]; long double __ld; } __nanl =
|
||||
{ { 0x7f, 0xff, 0, 0, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
|
||||
#define NANL (__nanl.__ld)
|
||||
|
||||
#endif /* GCC. */
|
||||
|
||||
#endif /* nan.h */
|
@ -32,9 +32,12 @@ typedef long double double_t; /* `double' expressions are evaluated as
|
||||
/* Signal that both types are `long double'. */
|
||||
#define FLT_EVAL_METHOD 2
|
||||
|
||||
/* Define `INFINITY' as value of type `float_t'. */
|
||||
#define INFINITY HUGE_VALL
|
||||
/* Define `INFINITY' as value of type `float'. */
|
||||
#define INFINITY HUGE_VALF
|
||||
|
||||
/* The values returned by `ilogb' for 0 and NaN respectively. */
|
||||
#define FP_ILOGB0 0x80000000
|
||||
#define FP_ILOGBNAN 0x7fffffff
|
||||
|
||||
/* Number of decimal digits for the `long double' type. */
|
||||
#define DECIMAL_DIG 18
|
||||
|
@ -190,12 +190,17 @@ extern char *alloca ();
|
||||
# define __getcwd getcwd
|
||||
#endif
|
||||
|
||||
#ifndef GETCWD_STORAGE_CLASS
|
||||
# define GETCWD_STORAGE_CLASS
|
||||
#endif
|
||||
|
||||
/* Get the pathname of the current working directory, and put it in SIZE
|
||||
bytes of BUF. Returns NULL if the directory couldn't be determined or
|
||||
SIZE was too small. If successful, returns BUF. In GNU, if BUF is
|
||||
NULL, an array is allocated with `malloc'; the array is SIZE bytes long,
|
||||
unless SIZE <= 0, in which case it is as big as necessary. */
|
||||
|
||||
GETCWD_STORAGE_CLASS
|
||||
char *
|
||||
__getcwd (buf, size)
|
||||
char *buf;
|
||||
@ -396,6 +401,6 @@ __getcwd (buf, size)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef _LIBC
|
||||
#if defined _LIBC && !defined __getcwd
|
||||
weak_alias (__getcwd, getcwd)
|
||||
#endif
|
||||
|
@ -17,7 +17,7 @@
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _MATH_H
|
||||
#error "Never use <bits/mathdef.h> directly; include <math.h> instead"
|
||||
# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
|
||||
#endif
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
gcc! */
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if __STDC__ == 1
|
||||
# if __STDC__ == 1
|
||||
|
||||
/* In GNU or ANSI mode, gcc leaves `float' expressions as-is. */
|
||||
typedef float float_t; /* `float' expressions are evaluated as
|
||||
@ -37,12 +37,12 @@ typedef double double_t; /* `double' expressions are evaluated as
|
||||
`double'. */
|
||||
|
||||
/* Signal that types stay as they were declared. */
|
||||
#define FLT_EVAL_METHOD 0
|
||||
# define FLT_EVAL_METHOD 0
|
||||
|
||||
/* Define `INFINITY' as value of type `float_t'. */
|
||||
#define INFINITY HUGE_VALF
|
||||
/* Define `INFINITY' as value of type `float'. */
|
||||
# define INFINITY HUGE_VALF
|
||||
|
||||
#else
|
||||
# else
|
||||
|
||||
/* For `gcc -traditional', `float' expressions are evaluated as `double'. */
|
||||
typedef double float_t; /* `float' expressions are evaluated as
|
||||
@ -51,12 +51,12 @@ typedef double double_t; /* `double' expressions are evaluated as
|
||||
`double'. */
|
||||
|
||||
/* Signal that both types are `double'. */
|
||||
#define FLT_EVAL_METHOD 1
|
||||
# define FLT_EVAL_METHOD 1
|
||||
|
||||
/* Define `INFINITY' as value of type `float_t'. */
|
||||
#define INFINITY HUGE_VAL
|
||||
/* Define `INFINITY' as value of type `float'. */
|
||||
# define INFINITY HUGE_VALF
|
||||
|
||||
#endif
|
||||
# endif
|
||||
#else
|
||||
|
||||
/* Wild guess at types for float_t and double_t. */
|
||||
@ -64,13 +64,16 @@ typedef double float_t;
|
||||
typedef double double_t;
|
||||
|
||||
/* Strange compiler, we don't know how it works. */
|
||||
#define FLT_EVAL_METHOD -1
|
||||
# define FLT_EVAL_METHOD -1
|
||||
|
||||
/* Define `INFINITY' as value of type `float_t'. */
|
||||
#define INFINITY HUGE_VAL
|
||||
/* Define `INFINITY' as value of type `float'. */
|
||||
# define INFINITY HUGE_VALF
|
||||
|
||||
#endif
|
||||
|
||||
/* The values returned by `ilogb' for 0 and NaN respectively. */
|
||||
#define FP_ILOGB0 0x80000001
|
||||
#define FP_ILOGBNAN 0x7fffffff
|
||||
|
||||
/* Number of decimal digits for the `double' type. */
|
||||
#define DECIMAL_DIG 15
|
||||
|
@ -17,38 +17,38 @@
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#ifndef _MATH_H
|
||||
#error "Never use <bits/mathdef.h> directly; include <math.h> instead"
|
||||
# error "Never use <bits/mathdef.h> directly; include <math.h> instead"
|
||||
#endif
|
||||
|
||||
/* FIXME! This file describes properties of the compiler, not the machine;
|
||||
it should not be part of libc! */
|
||||
|
||||
#ifdef __GNUC__
|
||||
#if __STDC__ == 1
|
||||
# if __STDC__ == 1
|
||||
|
||||
/* In GNU or ANSI mode, gcc leaves `float' expressions as-is. */
|
||||
typedef float float_t;
|
||||
typedef double double_t;
|
||||
|
||||
/* Signal that types stay as they were declared. */
|
||||
#define FLT_EVAL_METHOD 0
|
||||
# define FLT_EVAL_METHOD 0
|
||||
|
||||
/* Define `INFINITY' as value of type `float_t'. */
|
||||
#define INFINITY HUGE_VALF
|
||||
/* Define `INFINITY' as value of type `float'. */
|
||||
# define INFINITY HUGE_VALF
|
||||
|
||||
#else
|
||||
# else
|
||||
|
||||
/* For `gcc -traditional', `float' expressions are evaluated as `double'. */
|
||||
typedef double float_t;
|
||||
typedef double double_t;
|
||||
|
||||
/* Signal that both types are `double'. */
|
||||
#define FLT_EVAL_METHOD 1
|
||||
# define FLT_EVAL_METHOD 1
|
||||
|
||||
/* Define `INFINITY' as value of type `float_t'. */
|
||||
#define INFINITY HUGE_VAL
|
||||
/* Define `INFINITY' as value of type `float'. */
|
||||
# define INFINITY HUGE_VALF
|
||||
|
||||
#endif
|
||||
# endif
|
||||
#else
|
||||
|
||||
/* Wild guess at types for float_t and double_t. */
|
||||
@ -56,13 +56,16 @@ typedef double float_t;
|
||||
typedef double double_t;
|
||||
|
||||
/* Strange compiler, we don't know how it works. */
|
||||
#define FLT_EVAL_METHOD -1
|
||||
# define FLT_EVAL_METHOD -1
|
||||
|
||||
/* Define `INFINITY' as value of type `float_t'. */
|
||||
#define INFINITY HUGE_VAL
|
||||
/* Define `INFINITY' as value of type `float'. */
|
||||
# define INFINITY HUGE_VALF
|
||||
|
||||
#endif
|
||||
|
||||
/* The values returned by `ilogb' for 0 and NaN respectively. */
|
||||
#define FP_ILOGB0 0x80000001
|
||||
#define FP_ILOGBNAN 0x7fffffff
|
||||
|
||||
/* Number of decimal digits for the `double' type. */
|
||||
#define DECIMAL_DIG 15
|
||||
|
@ -18,13 +18,13 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
#define _ERRNO_H
|
||||
#include <errnos.h>
|
||||
#include <bits/errno.h>
|
||||
|
||||
.globl C_SYMBOL_NAME(errno)
|
||||
.globl syscall_error
|
||||
|
||||
_errno_loc: .long C_SYMBOL_NAME(errno)
|
||||
|
||||
|
||||
#undef syscall_error
|
||||
#ifdef NO_UNDERSCORES
|
||||
__syscall_error:
|
||||
@ -39,7 +39,7 @@ syscall_error:
|
||||
moveq r0, $EAGAIN /* Yes; translate it to EAGAIN. */
|
||||
#endif
|
||||
#ifndef PIC
|
||||
ldr r1, _errno_loc
|
||||
ldr r1, _errno_loc
|
||||
str r0, [r1]
|
||||
#endif
|
||||
mvn r0, $0
|
||||
|
@ -22,5 +22,5 @@
|
||||
void
|
||||
profil_counter (int signo, struct sigcontext sc)
|
||||
{
|
||||
profil_count ((void *) sc.eip);
|
||||
profil_count ((void *) sc.reg.ARM_pc);
|
||||
}
|
||||
|
@ -29,8 +29,8 @@
|
||||
of the kernel. But these symbols do not follow the SYS_* syntax
|
||||
so we have to redefine the `SYS_ify' macro here. */
|
||||
#undef SYS_ify
|
||||
#define SWI_BASE (9 << 20)
|
||||
#define SYS_ify(syscall_name) (SWI_BASE + __NR_##syscall_name)
|
||||
#define SWI_BASE (0x900000)
|
||||
#define SYS_ify(syscall_name) (__NR_##syscall_name)
|
||||
|
||||
|
||||
#ifdef ASSEMBLER
|
||||
|
94
sysdeps/unix/sysv/linux/getcwd.c
Normal file
94
sysdeps/unix/sysv/linux/getcwd.c
Normal file
@ -0,0 +1,94 @@
|
||||
/* Determine current working directory. Linux version.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
|
||||
|
||||
The GNU C Library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
The GNU C Library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with the GNU C Library; see the file COPYING.LIB. If not,
|
||||
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||
Boston, MA 02111-1307, USA. */
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
/* #define NDEBUG 1 */
|
||||
#include <assert.h>
|
||||
|
||||
/* The "proc" filesystem provides an easy method to retrieve the value.
|
||||
For each process, the corresponding directory contains a symbolic link
|
||||
named `cwd'. Reading the content of this link immediate gives us the
|
||||
information. But we have to take care for systems which do not have
|
||||
the proc filesystem mounted. Use the POSIX implementation in this case. */
|
||||
static char *generic_getcwd (char *buf, size_t size);
|
||||
|
||||
char *
|
||||
__getcwd (char *buf, size_t size)
|
||||
{
|
||||
int save_errno;
|
||||
char *path;
|
||||
int n;
|
||||
char *result;
|
||||
|
||||
if (size == 0)
|
||||
{
|
||||
if (buf != NULL)
|
||||
{
|
||||
__set_errno (EINVAL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size = PATH_MAX + 1;
|
||||
}
|
||||
|
||||
if (buf != NULL)
|
||||
path = buf;
|
||||
else
|
||||
{
|
||||
path = malloc (size);
|
||||
if (path == NULL)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
save_errno = errno;
|
||||
n = __readlink ("/proc/self/cwd", path, size);
|
||||
if (n != -1)
|
||||
{
|
||||
if (n >= size)
|
||||
{
|
||||
/* This should never happen when we allocate the buffer here. */
|
||||
assert (buf == NULL);
|
||||
__set_errno (ERANGE);
|
||||
return NULL;
|
||||
}
|
||||
path[n] = '\0';
|
||||
return buf ?: (char *) realloc (path, (size_t) n + 1);
|
||||
}
|
||||
|
||||
/* Something went wrong. Restore the error number and use the generic
|
||||
version. */
|
||||
__set_errno (save_errno);
|
||||
result = generic_getcwd (path, size);
|
||||
|
||||
if (result == NULL && buf == NULL)
|
||||
free (path);
|
||||
|
||||
return result;
|
||||
}
|
||||
weak_alias (__getcwd, getcwd)
|
||||
|
||||
/* Get the code for the generic version. */
|
||||
#define GETCWD_STORAGE_CLASS static
|
||||
#define __getcwd generic_getcwd
|
||||
#include <sysdeps/posix/getcwd.c>
|
@ -353,7 +353,7 @@ typedef unsigned long long int uint_fast64_t;
|
||||
|
||||
/* Limits of `sig_atomic_t'. */
|
||||
#define SIG_ATOMIC_MIN (-2147483647-1)
|
||||
#define SIG_ATOMIC_MAX (-2147483647-1)
|
||||
#define SIG_ATOMIC_MAX (2147483647)
|
||||
|
||||
/* Limit of `size_t' type. */
|
||||
#define SIZE_MAX (4294967295U)
|
||||
|
@ -353,7 +353,7 @@ typedef unsigned long int uint_fast64_t;
|
||||
|
||||
/* Limits of `sig_atomic_t'. */
|
||||
#define SIG_ATOMIC_MIN (-2147483647-1)
|
||||
#define SIG_ATOMIC_MAX (-2147483647-1)
|
||||
#define SIG_ATOMIC_MAX (2147483647)
|
||||
|
||||
/* Limit of `size_t' type. */
|
||||
#define SIZE_MAX (18446744073709551615uL)
|
||||
|
164
time/mktime.c
164
time/mktime.c
@ -102,6 +102,9 @@ const unsigned short int __mon_yday[2][13] =
|
||||
{ 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
|
||||
};
|
||||
|
||||
static struct tm *ranged_convert __P ((struct tm *(*) __P ((const time_t *,
|
||||
struct tm *)),
|
||||
time_t *, struct tm *));
|
||||
static time_t ydhms_tm_diff __P ((int, int, int, int, int, const struct tm *));
|
||||
time_t __mktime_internal __P ((struct tm *,
|
||||
struct tm *(*) (const time_t *, struct tm *),
|
||||
@ -134,30 +137,36 @@ localtime_r (t, tp)
|
||||
measured in seconds, ignoring leap seconds.
|
||||
YEAR uses the same numbering as TM->tm_year.
|
||||
All values are in range, except possibly YEAR.
|
||||
If TP is null, return a nonzero value.
|
||||
If overflow occurs, yield the low order bits of the correct answer. */
|
||||
static time_t
|
||||
ydhms_tm_diff (year, yday, hour, min, sec, tp)
|
||||
int year, yday, hour, min, sec;
|
||||
const struct tm *tp;
|
||||
{
|
||||
/* Compute intervening leap days correctly even if year is negative.
|
||||
Take care to avoid int overflow. time_t overflow is OK, since
|
||||
only the low order bits of the correct time_t answer are needed.
|
||||
Don't convert to time_t until after all divisions are done, since
|
||||
time_t might be unsigned. */
|
||||
int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
|
||||
int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
|
||||
int a100 = a4 / 25 - (a4 % 25 < 0);
|
||||
int b100 = b4 / 25 - (b4 % 25 < 0);
|
||||
int a400 = a100 >> 2;
|
||||
int b400 = b100 >> 2;
|
||||
int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
|
||||
time_t years = year - (time_t) tp->tm_year;
|
||||
time_t days = (365 * years + intervening_leap_days
|
||||
+ (yday - tp->tm_yday));
|
||||
return (60 * (60 * (24 * days + (hour - tp->tm_hour))
|
||||
+ (min - tp->tm_min))
|
||||
+ (sec - tp->tm_sec));
|
||||
if (!tp)
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
/* Compute intervening leap days correctly even if year is negative.
|
||||
Take care to avoid int overflow. time_t overflow is OK, since
|
||||
only the low order bits of the correct time_t answer are needed.
|
||||
Don't convert to time_t until after all divisions are done, since
|
||||
time_t might be unsigned. */
|
||||
int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3);
|
||||
int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3);
|
||||
int a100 = a4 / 25 - (a4 % 25 < 0);
|
||||
int b100 = b4 / 25 - (b4 % 25 < 0);
|
||||
int a400 = a100 >> 2;
|
||||
int b400 = b100 >> 2;
|
||||
int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400);
|
||||
time_t years = year - (time_t) tp->tm_year;
|
||||
time_t days = (365 * years + intervening_leap_days
|
||||
+ (yday - tp->tm_yday));
|
||||
return (60 * (60 * (24 * days + (hour - tp->tm_hour))
|
||||
+ (min - tp->tm_min))
|
||||
+ (sec - tp->tm_sec));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -178,6 +187,54 @@ mktime (tp)
|
||||
return __mktime_internal (tp, localtime_r, &localtime_offset);
|
||||
}
|
||||
|
||||
/* Use CONVERT to convert *T to a broken down time in *TP.
|
||||
If *T is out of range for conversion, adjust it so that
|
||||
it is the nearest in-range value and then convert that. */
|
||||
static struct tm *
|
||||
ranged_convert (convert, t, tp)
|
||||
struct tm *(*convert) __P ((const time_t *, struct tm *));
|
||||
time_t *t;
|
||||
struct tm *tp;
|
||||
{
|
||||
struct tm *r;
|
||||
|
||||
if (! (r = (*convert) (t, tp)) && *t)
|
||||
{
|
||||
time_t bad = *t;
|
||||
time_t ok = 0;
|
||||
struct tm tm;
|
||||
|
||||
/* BAD is a known unconvertible time_t, and OK is a known good one.
|
||||
Use binary search to narrow the range between BAD and OK until
|
||||
they differ by 1. */
|
||||
while (bad != ok + (bad < 0 ? -1 : 1))
|
||||
{
|
||||
time_t mid = *t = (bad < 0
|
||||
? bad + ((ok - bad) >> 1)
|
||||
: ok + ((bad - ok) >> 1));
|
||||
if ((r = (*convert) (t, tp)))
|
||||
{
|
||||
tm = *r;
|
||||
ok = mid;
|
||||
}
|
||||
else
|
||||
bad = mid;
|
||||
}
|
||||
|
||||
if (!r && ok)
|
||||
{
|
||||
/* The last conversion attempt failed;
|
||||
revert to the most recent successful attempt. */
|
||||
*t = ok;
|
||||
*tp = tm;
|
||||
r = tp;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/* Convert *TP to a time_t value, inverting
|
||||
the monotonic and mostly-unit-linear conversion function CONVERT.
|
||||
Use *OFFSET to keep track of a guess at the offset of the result,
|
||||
@ -243,7 +300,8 @@ __mktime_internal (tp, convert, offset)
|
||||
t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm);
|
||||
|
||||
for (t = t0 + *offset;
|
||||
(dt = ydhms_tm_diff (year, yday, hour, min, sec, (*convert) (&t, &tm)));
|
||||
(dt = ydhms_tm_diff (year, yday, hour, min, sec,
|
||||
ranged_convert (convert, &t, &tm)));
|
||||
t += dt)
|
||||
if (--remaining_probes == 0)
|
||||
return -1;
|
||||
@ -263,7 +321,7 @@ __mktime_internal (tp, convert, offset)
|
||||
{
|
||||
struct tm otm;
|
||||
if (! (dt = ydhms_tm_diff (year, yday, hour, min, sec,
|
||||
(*convert) (&ot, &otm))))
|
||||
ranged_convert (convert, &ot, &otm))))
|
||||
{
|
||||
t = ot;
|
||||
tm = otm;
|
||||
@ -283,7 +341,8 @@ __mktime_internal (tp, convert, offset)
|
||||
/* Adjust time to reflect the tm_sec requested, not the normalized value.
|
||||
Also, repair any damage from a false match due to a leap second. */
|
||||
t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60);
|
||||
(*convert) (&t, &tm);
|
||||
if (! (*convert) (&t, &tm))
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -333,25 +392,28 @@ static void
|
||||
print_tm (tp)
|
||||
struct tm *tp;
|
||||
{
|
||||
printf ("%04d-%02d-%02d %02d:%02d:%02d yday %03d wday %d isdst %d",
|
||||
tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday,
|
||||
tp->tm_hour, tp->tm_min, tp->tm_sec,
|
||||
tp->tm_yday, tp->tm_wday, tp->tm_isdst);
|
||||
if (tp)
|
||||
printf ("%04d-%02d-%02d %02d:%02d:%02d yday %03d wday %d isdst %d",
|
||||
tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday,
|
||||
tp->tm_hour, tp->tm_min, tp->tm_sec,
|
||||
tp->tm_yday, tp->tm_wday, tp->tm_isdst);
|
||||
else
|
||||
printf ("0");
|
||||
}
|
||||
|
||||
static int
|
||||
check_result (tk, tmk, tl, tml)
|
||||
check_result (tk, tmk, tl, lt)
|
||||
time_t tk;
|
||||
struct tm tmk;
|
||||
time_t tl;
|
||||
struct tm tml;
|
||||
struct tm *lt;
|
||||
{
|
||||
if (tk != tl || not_equal_tm (&tmk, &tml))
|
||||
if (tk != tl || !lt || not_equal_tm (&tmk, lt))
|
||||
{
|
||||
printf ("mktime (");
|
||||
print_tm (&tmk);
|
||||
printf (")\nyields (");
|
||||
print_tm (&tml);
|
||||
print_tm (lt);
|
||||
printf (") == %ld, should be %ld\n", (long) tl, (long) tk);
|
||||
return 1;
|
||||
}
|
||||
@ -366,6 +428,7 @@ main (argc, argv)
|
||||
{
|
||||
int status = 0;
|
||||
struct tm tm, tmk, tml;
|
||||
struct tm *lt;
|
||||
time_t tk, tl;
|
||||
char trailer;
|
||||
|
||||
@ -382,11 +445,16 @@ main (argc, argv)
|
||||
tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]);
|
||||
tmk = tm;
|
||||
tl = mktime (&tmk);
|
||||
tml = *localtime (&tl);
|
||||
lt = localtime (&tl);
|
||||
if (lt)
|
||||
{
|
||||
tml = *lt;
|
||||
lt = &tml;
|
||||
}
|
||||
printf ("mktime returns %ld == ", (long) tl);
|
||||
print_tm (&tmk);
|
||||
printf ("\n");
|
||||
status = check_result (tl, tmk, tl, tml);
|
||||
status = check_result (tl, tmk, tl, lt);
|
||||
}
|
||||
else if (argc == 4 || (argc == 5 && strcmp (argv[4], "-") == 0))
|
||||
{
|
||||
@ -397,19 +465,35 @@ main (argc, argv)
|
||||
if (argc == 4)
|
||||
for (tl = from; tl <= to; tl += by)
|
||||
{
|
||||
tml = *localtime (&tl);
|
||||
tmk = tml;
|
||||
tk = mktime (&tmk);
|
||||
status |= check_result (tk, tmk, tl, tml);
|
||||
lt = localtime (&tl);
|
||||
if (lt)
|
||||
{
|
||||
tmk = tml = *lt;
|
||||
tk = mktime (&tmk);
|
||||
status |= check_result (tk, tmk, tl, tml);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("localtime (%ld) yields 0\n", (long) tl);
|
||||
status = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
for (tl = from; tl <= to; tl += by)
|
||||
{
|
||||
/* Null benchmark. */
|
||||
tml = *localtime (&tl);
|
||||
tmk = tml;
|
||||
tk = tl;
|
||||
status |= check_result (tk, tmk, tl, tml);
|
||||
lt = localtime (&tl);
|
||||
if (lt)
|
||||
{
|
||||
tmk = tml = *lt;
|
||||
tk = tl;
|
||||
status |= check_result (tk, tmk, tl, tml);
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("localtime (%ld) yields 0\n", (long) tl);
|
||||
status = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -426,6 +510,6 @@ main (argc, argv)
|
||||
|
||||
/*
|
||||
Local Variables:
|
||||
compile-command: "gcc -DDEBUG=1 -Wall -O -g mktime.c -o mktime"
|
||||
compile-command: "gcc -DDEBUG -D__EXTENSIONS__ -DHAVE_LIMITS_H -DHAVE_LOCALTIME_R -DSTDC_HEADERS -Wall -W -O -g mktime.c -o mktime"
|
||||
End:
|
||||
*/
|
||||
|
@ -26,8 +26,9 @@ extern const unsigned short int __mon_yday[2][13];
|
||||
|
||||
/* Compute the `struct tm' representation of *T,
|
||||
offset OFFSET seconds east of UTC,
|
||||
and store year, yday, mon, mday, wday, hour, min, sec into *TP. */
|
||||
void
|
||||
and store year, yday, mon, mday, wday, hour, min, sec into *TP.
|
||||
Return nonzero if successful. */
|
||||
int
|
||||
__offtime (t, offset, tp)
|
||||
const time_t *t;
|
||||
long int offset;
|
||||
@ -59,7 +60,8 @@ __offtime (t, offset, tp)
|
||||
tp->tm_wday += 7;
|
||||
y = 1970;
|
||||
|
||||
#define LEAPS_THRU_END_OF(y) ((y) / 4 - (y) / 100 + (y) / 400)
|
||||
#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0))
|
||||
#define LEAPS_THRU_END_OF(y) (DIV (y, 4) - DIV (y, 100) + DIV (y, 400))
|
||||
|
||||
while (days < 0 || days >= (__isleap (y) ? 366 : 365))
|
||||
{
|
||||
@ -73,6 +75,8 @@ __offtime (t, offset, tp)
|
||||
y = yg;
|
||||
}
|
||||
tp->tm_year = y - 1900;
|
||||
if (tp->tm_year != y - 1900)
|
||||
return 0;
|
||||
tp->tm_yday = days;
|
||||
ip = __mon_yday[__isleap(y)];
|
||||
for (y = 11; days < (long int) ip[y]; --y)
|
||||
@ -80,4 +84,5 @@ __offtime (t, offset, tp)
|
||||
days -= ip[y];
|
||||
tp->tm_mon = y;
|
||||
tp->tm_mday = days + 1;
|
||||
return 1;
|
||||
}
|
||||
|
@ -182,7 +182,7 @@ localtime_r (t, tp)
|
||||
return tp;
|
||||
}
|
||||
# endif /* ! HAVE_LOCALTIME_R */
|
||||
#endif /* ! defined (_LIBC) */
|
||||
#endif /* ! defined _LIBC */
|
||||
|
||||
|
||||
#if !defined memset && !defined HAVE_MEMSET && !defined _LIBC
|
||||
@ -202,7 +202,7 @@ static const char zeroes[16] = /* "0000000000000000" */
|
||||
do \
|
||||
{ \
|
||||
int _this = _len > 16 ? 16 : _len; \
|
||||
(P) = mempcpy ((P), spaces, _this); \
|
||||
(P) = MEMPCPY ((P), spaces, _this); \
|
||||
_len -= _this; \
|
||||
} \
|
||||
while (_len > 0); \
|
||||
@ -215,7 +215,7 @@ static const char zeroes[16] = /* "0000000000000000" */
|
||||
do \
|
||||
{ \
|
||||
int _this = _len > 16 ? 16 : _len; \
|
||||
(P) = mempcpy ((P), zeroes, _this); \
|
||||
(P) = MEMPCPY ((P), zeroes, _this); \
|
||||
_len -= _this; \
|
||||
} \
|
||||
while (_len > 0); \
|
||||
|
@ -226,10 +226,11 @@ extern struct tm *localtime_r __P ((__const time_t *__timer,
|
||||
|
||||
/* Compute the `struct tm' representation of *T,
|
||||
offset OFFSET seconds east of UTC,
|
||||
and store year, yday, mon, mday, wday, hour, min, sec into *TP. */
|
||||
extern void __offtime __P ((__const time_t *__timer,
|
||||
long int __offset,
|
||||
struct tm *__TP));
|
||||
and store year, yday, mon, mday, wday, hour, min, sec into *TP.
|
||||
Return nonzero if successful. */
|
||||
extern int __offtime __P ((__const time_t *__timer,
|
||||
long int __offset,
|
||||
struct tm *__tp));
|
||||
|
||||
/* Return a string of the form "Day Mon dd hh:mm:ss yyyy\n"
|
||||
that is the representation of TP in this format. */
|
||||
|
@ -616,8 +616,7 @@ __tz_convert (const time_t *timer, int use_localtime, struct tm *tp)
|
||||
}
|
||||
else
|
||||
{
|
||||
__offtime (timer, 0, tp);
|
||||
if (! tz_compute (*timer, tp))
|
||||
if (! (__offtime (timer, 0, tp) && tz_compute (*timer, tp)))
|
||||
tp = NULL;
|
||||
leap_correction = 0L;
|
||||
leap_extra_secs = 0;
|
||||
@ -638,8 +637,10 @@ __tz_convert (const time_t *timer, int use_localtime, struct tm *tp)
|
||||
tp->tm_gmtoff = 0L;
|
||||
}
|
||||
|
||||
__offtime (timer, tp->tm_gmtoff - leap_correction, tp);
|
||||
tp->tm_sec += leap_extra_secs;
|
||||
if (__offtime (timer, tp->tm_gmtoff - leap_correction, tp))
|
||||
tp->tm_sec += leap_extra_secs;
|
||||
else
|
||||
tp = NULL;
|
||||
}
|
||||
|
||||
__libc_lock_unlock (tzset_lock);
|
||||
|
Loading…
Reference in New Issue
Block a user