diff options
39 files changed, 802 insertions, 266 deletions
@@ -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 @@ -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 diff --git a/bits/mathdef.h b/bits/mathdef.h index 93b60bd..1514099 100644 --- a/bits/mathdef.h +++ b/bits/mathdef.h @@ -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 diff --git a/bits/stat.h b/bits/stat.h index dab0cd0..3648fed 100644 --- a/bits/stat.h +++ b/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 */ diff --git a/bits/types.h b/bits/types.h index fdb36f0..51fadd1 100644 --- a/bits/types.h +++ b/bits/types.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. */ diff --git a/include/sys/stat.h b/include/sys/stat.h index be9bdd0..16950eb 100644 --- a/include/sys/stat.h +++ b/include/sys/stat.h @@ -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) diff --git a/intl/loadmsgcat.c b/intl/loadmsgcat.c index a67223f..de05342 100644 --- a/intl/loadmsgcat.c +++ b/intl/loadmsgcat.c @@ -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 diff --git a/libio/fileops.c b/libio/fileops.c index ffc57f1..a0cc2f7 100644 --- a/libio/fileops.c +++ b/libio/fileops.c @@ -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) diff --git a/libio/oldfileops.c b/libio/oldfileops.c index 71a2bc2..b426e88 100644 --- a/libio/oldfileops.c +++ b/libio/oldfileops.c @@ -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) diff --git a/manual/arith.texi b/manual/arith.texi index d0863f9..a5ba31d 100644 --- a/manual/arith.texi +++ b/manual/arith.texi @@ -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 diff --git a/manual/math.texi b/manual/math.texi index 478678f..d6206eb 100644 --- a/manual/math.texi +++ b/manual/math.texi @@ -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 diff --git a/manual/time.texi b/manual/time.texi index b67ef63..f38c2eb 100644 --- a/manual/time.texi +++ b/manual/time.texi @@ -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 diff --git a/math/complex.h b/math/complex.h index f4b1d46..72b1e59 100644 --- a/math/complex.h +++ b/math/complex.h @@ -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 diff --git a/math/libm-test.c b/math/libm-test.c index c77cbee..5d68b49 100644 --- a/math/libm-test.c +++ b/math/libm-test.c @@ -4813,6 +4813,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, MATHTYPE x, MATHTYPE epsilon) @@ -5205,6 +5249,7 @@ main (int argc, char *argv[]) ctanh_test (); csqrt_test (); cpow_test (); + fma_test (); /* special tests */ identities (); diff --git a/math/math.h b/math/math.h index 5105584..0aedaf1 100644 --- a/math/math.h +++ b/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 diff --git a/string/strndup.c b/string/strndup.c index 6bcfa9a..cd971e1 100644 --- a/string/strndup.c +++ b/string/strndup.c @@ -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); diff --git a/sunrpc/xcrypt.c b/sunrpc/xcrypt.c index df191f5..ec41100 100644 --- a/sunrpc/xcrypt.c +++ b/sunrpc/xcrypt.c @@ -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"; diff --git a/sysdeps/alpha/fpu/bits/mathdef.h b/sysdeps/alpha/fpu/bits/mathdef.h index 0bc9c94..1c25940 100644 --- a/sysdeps/alpha/fpu/bits/mathdef.h +++ b/sysdeps/alpha/fpu/bits/mathdef.h @@ -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 diff --git a/sysdeps/generic/bits/mathdef.h b/sysdeps/generic/bits/mathdef.h index 93b60bd..1514099 100644 --- a/sysdeps/generic/bits/mathdef.h +++ b/sysdeps/generic/bits/mathdef.h @@ -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 diff --git a/sysdeps/generic/bits/stat.h b/sysdeps/generic/bits/stat.h index dab0cd0..3648fed 100644 --- a/sysdeps/generic/bits/stat.h +++ b/sysdeps/generic/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 */ diff --git a/sysdeps/generic/bits/types.h b/sysdeps/generic/bits/types.h index fdb36f0..51fadd1 100644 --- a/sysdeps/generic/bits/types.h +++ b/sysdeps/generic/bits/types.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. */ diff --git a/sysdeps/i386/fpu/bits/mathdef.h b/sysdeps/i386/fpu/bits/mathdef.h index 2387a39..9d0bd84 100644 --- a/sysdeps/i386/fpu/bits/mathdef.h +++ b/sysdeps/i386/fpu/bits/mathdef.h @@ -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 diff --git a/sysdeps/ieee754/bits/nan.h b/sysdeps/ieee754/bits/nan.h index 94988ce..05a9d6a 100644 --- a/sysdeps/ieee754/bits/nan.h +++ b/sysdeps/ieee754/bits/nan.h @@ -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 diff --git a/sysdeps/m68k/bits/nan.h b/sysdeps/m68k/bits/nan.h deleted file mode 100644 index b4efddf..0000000 --- a/sysdeps/m68k/bits/nan.h +++ /dev/null @@ -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 */ diff --git a/sysdeps/m68k/fpu/bits/mathdef.h b/sysdeps/m68k/fpu/bits/mathdef.h index c2b4eff..e3d33a5 100644 --- a/sysdeps/m68k/fpu/bits/mathdef.h +++ b/sysdeps/m68k/fpu/bits/mathdef.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 diff --git a/sysdeps/posix/getcwd.c b/sysdeps/posix/getcwd.c index 2ae3c1e..d40d8d6 100644 --- a/sysdeps/posix/getcwd.c +++ b/sysdeps/posix/getcwd.c @@ -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 diff --git a/sysdeps/powerpc/bits/mathdef.h b/sysdeps/powerpc/bits/mathdef.h index 9f91863..3923a54 100644 --- a/sysdeps/powerpc/bits/mathdef.h +++ b/sysdeps/powerpc/bits/mathdef.h @@ -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 diff --git a/sysdeps/sparc/fpu/bits/mathdef.h b/sysdeps/sparc/fpu/bits/mathdef.h index 505d724..1355310 100644 --- a/sysdeps/sparc/fpu/bits/mathdef.h +++ b/sysdeps/sparc/fpu/bits/mathdef.h @@ -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 diff --git a/sysdeps/unix/arm/sysdep.S b/sysdeps/unix/arm/sysdep.S index 5d3ad55..d59500e 100644 --- a/sysdeps/unix/arm/sysdep.S +++ b/sysdeps/unix/arm/sysdep.S @@ -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 diff --git a/sysdeps/unix/sysv/linux/arm/profil-counter.h b/sysdeps/unix/sysv/linux/arm/profil-counter.h index 802cbd5..d84e70e 100644 --- a/sysdeps/unix/sysv/linux/arm/profil-counter.h +++ b/sysdeps/unix/sysv/linux/arm/profil-counter.h @@ -22,5 +22,5 @@ void profil_counter (int signo, struct sigcontext sc) { - profil_count ((void *) sc.eip); + profil_count ((void *) sc.reg.ARM_pc); } diff --git a/sysdeps/unix/sysv/linux/arm/sysdep.h b/sysdeps/unix/sysv/linux/arm/sysdep.h index 0aa085d..af08277 100644 --- a/sysdeps/unix/sysv/linux/arm/sysdep.h +++ b/sysdeps/unix/sysv/linux/arm/sysdep.h @@ -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 diff --git a/sysdeps/unix/sysv/linux/getcwd.c b/sysdeps/unix/sysv/linux/getcwd.c new file mode 100644 index 0000000..eea0b46 --- /dev/null +++ b/sysdeps/unix/sysv/linux/getcwd.c @@ -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> diff --git a/sysdeps/wordsize-32/inttypes.h b/sysdeps/wordsize-32/inttypes.h index 7bb8cbd..371b40b 100644 --- a/sysdeps/wordsize-32/inttypes.h +++ b/sysdeps/wordsize-32/inttypes.h @@ -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) diff --git a/sysdeps/wordsize-64/inttypes.h b/sysdeps/wordsize-64/inttypes.h index 9967fc0..5f11fc9 100644 --- a/sysdeps/wordsize-64/inttypes.h +++ b/sysdeps/wordsize-64/inttypes.h @@ -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) diff --git a/time/mktime.c b/time/mktime.c index 7a94c21..406f55e 100644 --- a/time/mktime.c +++ b/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: */ diff --git a/time/offtime.c b/time/offtime.c index a4b59ed..52e4070 100644 --- a/time/offtime.c +++ b/time/offtime.c @@ -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; } diff --git a/time/strftime.c b/time/strftime.c index e66a444..0ebc913 100644 --- a/time/strftime.c +++ b/time/strftime.c @@ -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); \ diff --git a/time/time.h b/time/time.h index f60599d..3e039ad 100644 --- a/time/time.h +++ b/time/time.h @@ -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. */ diff --git a/time/tzset.c b/time/tzset.c index 0793027..64e2087 100644 --- a/time/tzset.c +++ b/time/tzset.c @@ -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); |