changeset 16412:a50ff00ce4ee

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.
author Bruno Haible <bruno@clisp.org>
date Sat, 25 Feb 2012 18:27:46 +0100
parents 2c846fbb8f16
children 3a9564d7a3a5
files ChangeLog doc/posix-functions/remainder.texi lib/math.in.h lib/remainder.c m4/math_h.m4 m4/remainder.m4 modules/math modules/remainder tests/test-math-c++.cc
diffstat 9 files changed, 157 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2012-02-25  Bruno Haible  <bruno@clisp.org>
+
+	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  <bruno@clisp.org>
 
 	Tests for module 'fmodl'.
--- a/doc/posix-functions/remainder.texi
+++ b/doc/posix-functions/remainder.texi
@@ -8,10 +8,6 @@
 
 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 @@
 This function is not declared on some platforms:
 IRIX 5.3.
 @end itemize
+
+Portability problems not fixed by Gnulib:
+@itemize
+@end itemize
--- a/lib/math.in.h
+++ b/lib/math.in.h
@@ -898,6 +898,21 @@
 #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));
new file mode 100644
--- /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 <http://www.gnu.org/licenses/>.  */
+
+#include <config.h>
+
+/* Specification.  */
+#include <math.h>
+
+double
+remainder (double x, double y)
+{
+  double i = round (x / y);
+  return fma (- i, y, x);
+}
--- 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 @@
      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 @@
   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 @@
   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 @@
   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])
new file mode 100644
--- /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 <math.h>]])
+
+  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 <math.h>
+             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 <math.h>
+               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])
+])
--- a/modules/math
+++ b/modules/math
@@ -74,6 +74,7 @@
 	      -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 @@
 	      -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 @@
 	      -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' \
--- a/modules/remainder
+++ b/modules/remainder
@@ -2,12 +2,21 @@
 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:
 
--- a/tests/test-math-c++.cc
+++ b/tests/test-math-c++.cc
@@ -205,7 +205,9 @@
 #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));