remainder: Support for MSVC.
authorBruno Haible <bruno@clisp.org>
Sat, 25 Feb 2012 17:27:46 +0000 (18:27 +0100)
committerBruno Haible <bruno@clisp.org>
Sat, 25 Feb 2012 17:56:37 +0000 (18:56 +0100)
* 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
doc/posix-functions/remainder.texi
lib/math.in.h
lib/remainder.c [new file with mode: 0644]
m4/math_h.m4
m4/remainder.m4 [new file with mode: 0644]
modules/math
modules/remainder
tests/test-math-c++.cc

index 6c341da..55bb838 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,23 @@
 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'.
        * modules/fmodl-tests: New file.
        * tests/test-fmodl.c: New file.
index 59ff2e4..efce830 100644 (file)
@@ -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
index 87e4258..f2a3e52 100644 (file)
@@ -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 (file)
index 0000000..c4e7c7a
--- /dev/null
@@ -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);
+}
index 410cdde..8f554d1 100644 (file)
@@ -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 (file)
index 0000000..6cc0001
--- /dev/null
@@ -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])
+])
index 6394b3c..42f5fea 100644 (file)
@@ -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' \
index 36d75bd..f5a8dd9 100644 (file)
@@ -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:
 
index f092bc2..758f352 100644 (file)
@@ -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));