From 59cd972bd4e6d5a53e31ed175779f24c63d4b6c4 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 25 Feb 2012 18:27:46 +0100 Subject: [PATCH] remainder: Support for MSVC. * lib/math.in.h (remainder): New declaration. * lib/remainder.c: New file. * m4/remainder.m4: New file. * modules/remainder (Files): Add lib/remainder.c, m4/remainder.m4. (Depends-on): Add math, round, fma. (configure.ac): Use results of gl_FUNC_REMAINDER. * m4/math_h.m4 (gl_MATH_H): Test whether remainder is declared. (gl_MATH_H_DEFAULTS): Initialize GNULIB_REMAINDER, HAVE_REMAINDER, HAVE_DECL_REMAINDER. * modules/math (Makefile.am): Substitute GNULIB_REMAINDER, HAVE_REMAINDER, HAVE_DECL_REMAINDER. * tests/test-math-c++.cc: Check the declaration of remainder. * doc/posix-functions/remainder.texi: Mention that the MSVC and IRIX 5 problems are fixed. --- ChangeLog | 18 ++++++++++ doc/posix-functions/remainder.texi | 8 ++--- lib/math.in.h | 15 ++++++++ lib/remainder.c | 27 ++++++++++++++ m4/math_h.m4 | 6 +++- m4/remainder.m4 | 72 ++++++++++++++++++++++++++++++++++++++ modules/math | 3 ++ modules/remainder | 11 +++++- tests/test-math-c++.cc | 4 ++- 9 files changed, 157 insertions(+), 7 deletions(-) create mode 100644 lib/remainder.c create mode 100644 m4/remainder.m4 diff --git a/ChangeLog b/ChangeLog index 6c341da58..55bb83881 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,23 @@ 2012-02-25 Bruno Haible + remainder: Support for MSVC. + * lib/math.in.h (remainder): New declaration. + * lib/remainder.c: New file. + * m4/remainder.m4: New file. + * modules/remainder (Files): Add lib/remainder.c, m4/remainder.m4. + (Depends-on): Add math, round, fma. + (configure.ac): Use results of gl_FUNC_REMAINDER. + * m4/math_h.m4 (gl_MATH_H): Test whether remainder is declared. + (gl_MATH_H_DEFAULTS): Initialize GNULIB_REMAINDER, HAVE_REMAINDER, + HAVE_DECL_REMAINDER. + * modules/math (Makefile.am): Substitute GNULIB_REMAINDER, + HAVE_REMAINDER, HAVE_DECL_REMAINDER. + * tests/test-math-c++.cc: Check the declaration of remainder. + * doc/posix-functions/remainder.texi: Mention that the MSVC and IRIX 5 + problems are fixed. + +2012-02-25 Bruno Haible + Tests for module 'fmodl'. * modules/fmodl-tests: New file. * tests/test-fmodl.c: New file. diff --git a/doc/posix-functions/remainder.texi b/doc/posix-functions/remainder.texi index 59ff2e4c5..efce83053 100644 --- a/doc/posix-functions/remainder.texi +++ b/doc/posix-functions/remainder.texi @@ -8,10 +8,6 @@ Gnulib module: remainder Portability problems fixed by Gnulib: @itemize -@end itemize - -Portability problems not fixed by Gnulib: -@itemize @item This function is missing on some platforms: MSVC 9. @@ -19,3 +15,7 @@ MSVC 9. This function is not declared on some platforms: IRIX 5.3. @end itemize + +Portability problems not fixed by Gnulib: +@itemize +@end itemize diff --git a/lib/math.in.h b/lib/math.in.h index 87e42586a..f2a3e52f3 100644 --- a/lib/math.in.h +++ b/lib/math.in.h @@ -898,6 +898,21 @@ _GL_WARN_ON_USE (powf, "powf is unportable - " #endif +#if @GNULIB_REMAINDER@ +# if !@HAVE_REMAINDER@ || !@HAVE_DECL_REMAINDER@ +_GL_FUNCDECL_SYS (remainder, double, (double x, double y)); +# endif +_GL_CXXALIAS_SYS (remainder, double, (double x, double y)); +_GL_CXXALIASWARN (remainder); +#elif defined GNULIB_POSIXCHECK +# undef remainder +# if HAVE_RAW_DECL_REMAINDER +_GL_WARN_ON_USE (remainder, "remainder is unportable - " + "use gnulib module remainder for portability"); +# endif +#endif + + #if @GNULIB_RINTF@ # if !@HAVE_RINTF@ _GL_FUNCDECL_SYS (rintf, float, (float x)); diff --git a/lib/remainder.c b/lib/remainder.c new file mode 100644 index 000000000..c4e7c7ac0 --- /dev/null +++ b/lib/remainder.c @@ -0,0 +1,27 @@ +/* Remainder. + Copyright (C) 2012 Free Software Foundation, Inc. + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include + +/* Specification. */ +#include + +double +remainder (double x, double y) +{ + double i = round (x / y); + return fma (- i, y, x); +} diff --git a/m4/math_h.m4 b/m4/math_h.m4 index 410cdde3f..8f554d1c0 100644 --- a/m4/math_h.m4 +++ b/m4/math_h.m4 @@ -1,4 +1,4 @@ -# math_h.m4 serial 59 +# math_h.m4 serial 60 dnl Copyright (C) 2007-2012 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -43,6 +43,7 @@ AC_DEFUN([gl_MATH_H], ceilf ceill copysign copysignf copysignl cosf cosl coshf expf expl fabsf fabsl floorf floorl fma fmaf fmal fmodf fmodl frexpf frexpl ldexpf ldexpl logb logf logl log10f modff modfl powf + remainder rint rintf rintl round roundf roundl sinf sinl sinhf sqrtf sqrtl tanf tanl tanhf trunc truncf truncl]) ]) @@ -104,6 +105,7 @@ AC_DEFUN([gl_MATH_H_DEFAULTS], GNULIB_MODFF=0; AC_SUBST([GNULIB_MODFF]) GNULIB_MODFL=0; AC_SUBST([GNULIB_MODFL]) GNULIB_POWF=0; AC_SUBST([GNULIB_POWF]) + GNULIB_REMAINDER=0; AC_SUBST([GNULIB_REMAINDER]) GNULIB_RINT=0; AC_SUBST([GNULIB_RINT]) GNULIB_RINTF=0; AC_SUBST([GNULIB_RINTF]) GNULIB_RINTL=0; AC_SUBST([GNULIB_RINTL]) @@ -156,6 +158,7 @@ AC_DEFUN([gl_MATH_H_DEFAULTS], HAVE_MODFF=1; AC_SUBST([HAVE_MODFF]) HAVE_MODFL=1; AC_SUBST([HAVE_MODFL]) HAVE_POWF=1; AC_SUBST([HAVE_POWF]) + HAVE_REMAINDER=1; AC_SUBST([HAVE_REMAINDER]) HAVE_RINT=1; AC_SUBST([HAVE_RINT]) HAVE_RINTF=1; AC_SUBST([HAVE_RINTF]) HAVE_RINTL=1; AC_SUBST([HAVE_RINTL]) @@ -180,6 +183,7 @@ AC_DEFUN([gl_MATH_H_DEFAULTS], HAVE_DECL_LDEXPL=1; AC_SUBST([HAVE_DECL_LDEXPL]) HAVE_DECL_LOGB=1; AC_SUBST([HAVE_DECL_LOGB]) HAVE_DECL_LOGL=1; AC_SUBST([HAVE_DECL_LOGL]) + HAVE_DECL_REMAINDER=1; AC_SUBST([HAVE_DECL_REMAINDER]) HAVE_DECL_ROUND=1; AC_SUBST([HAVE_DECL_ROUND]) HAVE_DECL_ROUNDF=1; AC_SUBST([HAVE_DECL_ROUNDF]) HAVE_DECL_ROUNDL=1; AC_SUBST([HAVE_DECL_ROUNDL]) diff --git a/m4/remainder.m4 b/m4/remainder.m4 new file mode 100644 index 000000000..6cc0001b5 --- /dev/null +++ b/m4/remainder.m4 @@ -0,0 +1,72 @@ +# remainder.m4 serial 1 +dnl Copyright (C) 2012 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_REMAINDER], +[ + AC_REQUIRE([gl_MATH_H_DEFAULTS]) + + dnl Test whether remainder() is declared. On IRIX 5.3 it is not declared. + AC_CHECK_DECL([remainder], , [HAVE_DECL_REMAINDER=0], [[#include ]]) + + REMAINDER_LIBM= + AC_CACHE_CHECK([whether remainder() can be used without linking with libm], + [gl_cv_func_remainder_no_libm], + [ + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#ifndef __NO_MATH_INLINES + # define __NO_MATH_INLINES 1 /* for glibc */ + #endif + #include + double x; + double y;]], + [[return remainder (x, y) > 1;]])], + [gl_cv_func_remainder_no_libm=yes], + [gl_cv_func_remainder_no_libm=no]) + ]) + if test $gl_cv_func_remainder_no_libm = no; then + AC_CACHE_CHECK([whether remainder() can be used with libm], + [gl_cv_func_remainder_in_libm], + [ + save_LIBS="$LIBS" + LIBS="$LIBS -lm" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM( + [[#ifndef __NO_MATH_INLINES + # define __NO_MATH_INLINES 1 /* for glibc */ + #endif + #include + double x; + double y;]], + [[return remainder (x, y) > 1;]])], + [gl_cv_func_remainder_in_libm=yes], + [gl_cv_func_remainder_in_libm=no]) + LIBS="$save_LIBS" + ]) + if test $gl_cv_func_remainder_in_libm = yes; then + REMAINDER_LIBM=-lm + fi + fi + if test $gl_cv_func_remainder_no_libm = no \ + && test $gl_cv_func_remainder_in_libm = no; then + HAVE_REMAINDER=0 + dnl Find libraries needed to link lib/remainder.c. + AC_REQUIRE([gl_FUNC_ROUND]) + AC_REQUIRE([gl_FUNC_FMA]) + REMAINDER_LIBM= + dnl Append $ROUND_LIBM to REMAINDER_LIBM, avoiding gratuitous duplicates. + case " $REMAINDER_LIBM " in + *" $ROUND_LIBM "*) ;; + *) REMAINDER_LIBM="$REMAINDER_LIBM $ROUND_LIBM" ;; + esac + dnl Append $FMA_LIBM to REMAINDER_LIBM, avoiding gratuitous duplicates. + case " $REMAINDER_LIBM " in + *" $FMA_LIBM "*) ;; + *) REMAINDER_LIBM="$REMAINDER_LIBM $FMA_LIBM" ;; + esac + fi + AC_SUBST([REMAINDER_LIBM]) +]) diff --git a/modules/math b/modules/math index 6394b3c18..42f5fea5a 100644 --- a/modules/math +++ b/modules/math @@ -74,6 +74,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's/@''GNULIB_MODFF''@/$(GNULIB_MODFF)/g' \ -e 's/@''GNULIB_MODFL''@/$(GNULIB_MODFL)/g' \ -e 's/@''GNULIB_POWF''@/$(GNULIB_POWF)/g' \ + -e 's/@''GNULIB_REMAINDER''@/$(GNULIB_REMAINDER)/g' \ -e 's/@''GNULIB_RINT''@/$(GNULIB_RINT)/g' \ -e 's/@''GNULIB_RINTF''@/$(GNULIB_RINTF)/g' \ -e 's/@''GNULIB_RINTL''@/$(GNULIB_RINTL)/g' \ @@ -126,6 +127,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's|@''HAVE_MODFF''@|$(HAVE_MODFF)|g' \ -e 's|@''HAVE_MODFL''@|$(HAVE_MODFL)|g' \ -e 's|@''HAVE_POWF''@|$(HAVE_POWF)|g' \ + -e 's|@''HAVE_REMAINDER''@|$(HAVE_REMAINDER)|g' \ -e 's|@''HAVE_RINT''@|$(HAVE_RINT)|g' \ -e 's|@''HAVE_RINTF''@|$(HAVE_RINTF)|g' \ -e 's|@''HAVE_RINTL''@|$(HAVE_RINTL)|g' \ @@ -150,6 +152,7 @@ math.h: math.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $( -e 's|@''HAVE_DECL_LDEXPL''@|$(HAVE_DECL_LDEXPL)|g' \ -e 's|@''HAVE_DECL_LOGB''@|$(HAVE_DECL_LOGB)|g' \ -e 's|@''HAVE_DECL_LOGL''@|$(HAVE_DECL_LOGL)|g' \ + -e 's|@''HAVE_DECL_REMAINDER''@|$(HAVE_DECL_REMAINDER)|g' \ -e 's|@''HAVE_DECL_ROUND''@|$(HAVE_DECL_ROUND)|g' \ -e 's|@''HAVE_DECL_ROUNDF''@|$(HAVE_DECL_ROUNDF)|g' \ -e 's|@''HAVE_DECL_ROUNDL''@|$(HAVE_DECL_ROUNDL)|g' \ diff --git a/modules/remainder b/modules/remainder index 36d75bdc1..f5a8dd931 100644 --- a/modules/remainder +++ b/modules/remainder @@ -2,12 +2,21 @@ Description: remainder() function: floating-point remainder function. Files: +lib/remainder.c +m4/remainder.m4 m4/mathfunc.m4 Depends-on: +math +round [test $HAVE_REMAINDER = 0] +fma [test $HAVE_REMAINDER = 0] configure.ac: -gl_COMMON_DOUBLE_MATHFUNC([remainder]) +gl_FUNC_REMAINDER +if test $HAVE_REMAINDER = 0; then + AC_LIBOBJ([remainder]) +fi +gl_MATH_MODULE_INDICATOR([remainder]) Makefile.am: diff --git a/tests/test-math-c++.cc b/tests/test-math-c++.cc index f092bc2f5..758f352ec 100644 --- a/tests/test-math-c++.cc +++ b/tests/test-math-c++.cc @@ -205,7 +205,9 @@ SIGNATURE_CHECK (GNULIB_NAMESPACE::powf, float, (float, float)); #endif //SIGNATURE_CHECK (GNULIB_NAMESPACE::pow, double, (double, double)); -//SIGNATURE_CHECK (GNULIB_NAMESPACE::remainder, double, (double, double)); +#if GNULIB_TEST_REMAINDER +SIGNATURE_CHECK (GNULIB_NAMESPACE::remainder, double, (double, double)); +#endif #if GNULIB_TEST_RINTF SIGNATURE_CHECK (GNULIB_NAMESPACE::rintf, float, (float)); -- 2.11.0