bug-gnulib
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

new modules 'isnan', 'isnanf', 'isnand'


From: Ben Pfaff
Subject: new modules 'isnan', 'isnanf', 'isnand'
Date: Mon, 07 Jul 2008 22:03:15 -0700
User-agent: Gnus/5.11 (Gnus v5.11) Emacs/22.2 (gnu/linux)

PSPP would like to use the isnan macro portably.  Gnulib, through
its isnanf-nolibm, isnand-nolibm, and isnanl modules, almost has
what it needs.  I've written up a change set that adds isnanf and
isnand modules, which correspond to isnanl, and then builds an
isnan module on top of them.

I've tested the set of modules to work on Debian locally and on
FreeBSD 6.2, RHEL5, and HP HP-UX 11i v3 via HP TestDrive.

Bruno, this affects your isnan* modules quite a bit.  If you want
me to redo it in some other fashion, or to break it up into
smaller chunks, please let me know.

commit 42b7746b365208453dd91665325be5bd8d14e65f
Author: Ben Pfaff <address@hidden>
Date:   Mon Jul 7 21:52:03 2008 -0700

    Add isnan, isnanf, isnand modules.

diff --git a/ChangeLog b/ChangeLog
index 6c5f522..e39bcdd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,79 @@
+2008-07-07  Ben Pfaff  <address@hidden>
+
+       New modules isnan, isnanf, isnand.
+       * doc/posix-functions/isnan.texi: Mention isnan module.
+       * lib/isnanf.h: Change to be a header file for new isnanf module
+       instead of for existing isnanf-nolibm module.
+       * lib/isnanf-nolibm.h: New file copied from old lib/isnanf.h.
+       * lib/isnand.h: Change to be a header file for new isnand module
+       instead of for existing isnand-nolibm module.
+       * lib/isnand-nolibm.h: New file copied from old lib/isnand.h.
+       * lib/math.in.h: Define isnan macro if we have decided to replace
+       it.
+       * modules/isnan: New file.
+       * modules/isnan-tests: New file.
+       * modules/isnanf-tests: New file.
+       * modules/isnanf-nolibm: Update header file from isnanf.h to
+       isnanf-nolibm.h.
+       * modules/isnanf-nolibm-tests: Update list of files given that
+       test-isnanf.c and test-isnanf-nolibm.c have been factored into a
+       common header file.
+       * modules/isnand: New file.
+       * modules/isnand-tests: New file.
+       * modules/isnand: New file.
+       * modules/isnand-nolibm: Update header file from isnand.h to
+       isnand-nolibm.h.
+       * modules/isnand-nolibm-tests: Update list of files given that
+       test-isnand.c and test-isnand-nolibm.c have been factored into a
+       common header file.
+       * modules/math: Add substitutions for isnan module.
+       * m4/math_h.m4: Initialize and substitute variables for isnan
+       module.
+       * m4/isnan.m4: New file.
+       * m4/isnanf.m4 (gl_FUNC_ISNANF): New macro.
+       (gl_HAVE_ISNANF_IN_LIBM): New macro.
+       (gl_BUILD_ISNANF): New macro used by gl_FUNC_ISNANF,
+       gl_FUNC_ISNANF_NO_LIBM, and gl_FUNC_ISNAN.
+       * m4/isnand.m4 (gl_FUNC_ISNAND): New macro.
+       (gl_BUILD_ISNAND): New macro used by gl_FUNC_ISNAND,
+       gl_FUNC_ISNAND_NO_LIBM, and gl_FUNC_ISNAN.
+       (gl_FUNC_ISNAND_NO_LIBM): Split partially into new macro
+       gl_HAVE_ISNAND_NO_LIBM so that gl_FUNC_ISNAND can use that
+       functionality also.
+       (gl_HAVE_ISNAND_IN_LIBM): New macro.
+       * m4/isnanl.h (gl_BUILD_ISNANL): New macro used by gl_FUNC_ISNANL,
+       gl_FUNC_ISNANL_NO_LIBM, and gl_FUNC_ISNAN.
+       * tests/test-isnan.c: New file.
+       * tests/test-isnand-nolibm.c: Renamed from test-isnand.c and most
+       of its content factored into tests/test-isnand.h.
+       * tests/test-isnand.h: New file.
+       * tests/test-isnand.c: New file.
+       * tests/test-isnanf-nolibm.c: Renamed from test-isnanf.c and most
+       of its content factored into tests/test-isnanf.h.
+       * tests/test-isnanf.h: New file.
+       * tests/test-isnanf.c: New file.
+       * lib/frexp.c: Use new isnand-nolibm.h instead of isnand.h.
+       * lib/isfinite.c: Likewise, and isnanf-nolibm.h instead of
+       isnanf.h.
+       * lib/signbitd.c: Likewise.
+       * lib/signbitf.c: Likewise.
+       * lib/vasnprintf.c: Likewise.
+       * tests/test-ceilf1.c: Likewise.
+       * tests/test-ceilf2.c: Likewise.
+       * tests/test-floorf1.c: Likewise.
+       * tests/test-floorf2.c: Likewise.
+       * tests/test-frexp.c: Likewise.
+       * tests/test-round1.c: Likewise.
+       * tests/test-round2.c: Likewise.
+       * tests/test-roundf1.c: Likewise.
+       * tests/test-strtod.c: Likewise.
+       * tests/test-trunc1.c: Likewise.
+       * tests/test-trunc2.c: Likewise.
+       * tests/test-truncf1.c: Likewise.
+       * tests/test-truncf2.c: Likewise.
+       * MODULES.html.sh: Add new modules.
+       * NEWS: Mention the changes.
+
 2008-07-04  Jim Meyering  <address@hidden>
 
        * users.txt: Add vc-dwim.
diff --git a/MODULES.html.sh b/MODULES.html.sh
index 8f3aa4f..8e24e23 100755
--- a/MODULES.html.sh
+++ b/MODULES.html.sh
@@ -1999,8 +1999,11 @@ func_all_modules ()
   func_module frexpl
   func_module frexpl-nolibm
   func_module isfinite
-  func_module isnanf-nolibm
+  func_module isnan
+  func_module isnand
   func_module isnand-nolibm
+  func_module isnanf
+  func_module isnanf-nolibm
   func_module isnanl
   func_module isnanl-nolibm
   func_module ldexpl
diff --git a/NEWS b/NEWS
index 75735e5..74ca234 100644
--- a/NEWS
+++ b/NEWS
@@ -6,6 +6,11 @@ User visible incompatible changes
 
 Date        Modules         Changes
 
+2008-07-07  isnanf-nolibm   The include file is changed from "isnanf.h"
+                            to "isnanf-nolibm.h".
+            isnand-nolibm   The include file is changed from "isnand.h"
+                            to "isnand-nolibm.h".
+
 2008-06-10  execute         The execute function takes an additional termsigp
                             argument. Passing termsigp = NULL is ok.
             wait-process    The wait_subprocess function takes an additional
diff --git a/doc/posix-functions/isnan.texi b/doc/posix-functions/isnan.texi
index 90395c7..d951120 100644
--- a/doc/posix-functions/isnan.texi
+++ b/doc/posix-functions/isnan.texi
@@ -4,10 +4,13 @@
 
 POSIX specification: @url{http://www.opengroup.org/susv3xsh/isnan.html}
 
-Gnulib module: ---
+Gnulib module: isnan
 
 Portability problems fixed by Gnulib:
 @itemize
address@hidden
+This macro is missing on some platforms and does not always yield
+correct results on others.
 @end itemize
 
 Portability problems not fixed by Gnulib:
diff --git a/lib/frexp.c b/lib/frexp.c
index 4fd0819..7e1f5d1 100644
--- a/lib/frexp.c
+++ b/lib/frexp.c
@@ -27,7 +27,7 @@
 # include "isnanl-nolibm.h"
 # include "fpucw.h"
 #else
-# include "isnand.h"
+# include "isnand-nolibm.h"
 #endif
 
 /* This file assumes FLT_RADIX = 2.  If FLT_RADIX is a power of 2 greater
diff --git a/lib/isfinite.c b/lib/isfinite.c
index e648929..b7baff4 100644
--- a/lib/isfinite.c
+++ b/lib/isfinite.c
@@ -19,8 +19,8 @@
 
 #include <config.h>
 
-#include "isnanf.h"
-#include "isnand.h"
+#include "isnanf-nolibm.h"
+#include "isnand-nolibm.h"
 #include "isnanl-nolibm.h"
 
 int gl_isfinitef (float x)
diff --git a/lib/isnand.h b/lib/isnand-nolibm.h
similarity index 100%
copy from lib/isnand.h
copy to lib/isnand-nolibm.h
diff --git a/lib/isnand.h b/lib/isnand.h
index d248b2f..d809aaa 100644
--- a/lib/isnand.h
+++ b/lib/isnand.h
@@ -1,4 +1,4 @@
-/* Test for NaN that does not need libm.
+/* Test for NaN.
    Copyright (C) 2007-2008 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
@@ -14,7 +14,7 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#if HAVE_ISNAND_IN_LIBC
+#if HAVE_ISNAND
 /* Get declaration of isnan macro.  */
 # include <math.h>
 # if __GNUC__ >= 4
diff --git a/lib/isnanf.h b/lib/isnanf-nolibm.h
similarity index 100%
copy from lib/isnanf.h
copy to lib/isnanf-nolibm.h
diff --git a/lib/isnanf.h b/lib/isnanf.h
index 774942c..69492e1 100644
--- a/lib/isnanf.h
+++ b/lib/isnanf.h
@@ -1,4 +1,4 @@
-/* Test for NaN that does not need libm.
+/* Test for NaN.
    Copyright (C) 2007-2008 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
@@ -14,7 +14,7 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#if HAVE_ISNANF_IN_LIBC
+#if HAVE_ISNANF
 /* Get declaration of isnan macro or (older) isnanf function.  */
 # include <math.h>
 # if __GNUC__ >= 4
diff --git a/lib/math.in.h b/lib/math.in.h
index f500824..85f3785 100644
--- a/lib/math.in.h
+++ b/lib/math.in.h
@@ -381,6 +381,41 @@ extern int gl_isfinitel (long double x);
 #endif
 
 
+#if @GNULIB_ISNAN@
+# if @REPLACE_ISNAN@
+/* We can't just use the isnanf macro (e.g.) as exposed by
+   isnanf.h (e.g.) here, because those may end up being macros
+   that recursively expand back to isnan.  So use the gnulib
+   replacements for them directly. */
+#  if HAVE_ISNANF && __GNUC__ >= 4
+#   define gl_isnan_f(x) __builtin_isnan ((float)(x))
+#  else
+extern int rpl_isnanf (float x);
+#   define gl_isnan_f(x) rpl_isnanf (x)
+#  endif
+#  if HAVE_ISNAND && __GNUC__ >= 4
+#   define gl_isnan_d(x) __builtin_isnan ((double)(x))
+#  else
+extern int rpl_isnand (double x);
+#   define gl_isnan_d(x) rpl_isnand (x)
+#  endif
+#  if HAVE_ISNANL && __GNUC__ >= 4
+#   define gl_isnan_l(x) __builtin_isnan ((long double)(x))
+#  else
+extern int rpl_isnanl (long double x);
+#   define gl_isnan_l(x) rpl_isnanl (x)
+#  endif
+#  undef isnan
+#  define isnan(x) \
+   (sizeof (x) == sizeof (long double) ? gl_isnan_l (x) : \
+    sizeof (x) == sizeof (double) ? gl_isnan_d (x) : \
+    gl_isnan_f (x))
+# endif
+#elif defined GNULIB_POSIXCHECK
+  /* How to override a macro?  */
+#endif
+
+
 #if @GNULIB_SIGNBIT@
 # if @REPLACE_SIGNBIT_USING_GCC@
 #  undef signbit
diff --git a/lib/signbitd.c b/lib/signbitd.c
index 8871de7..9a7d725 100644
--- a/lib/signbitd.c
+++ b/lib/signbitd.c
@@ -20,7 +20,7 @@
 #include <math.h>
 
 #include <string.h>
-#include "isnand.h"
+#include "isnand-nolibm.h"
 #include "float+.h"
 
 #undef gl_signbitd
diff --git a/lib/signbitf.c b/lib/signbitf.c
index 8b0f93c..d03fcdd 100644
--- a/lib/signbitf.c
+++ b/lib/signbitf.c
@@ -20,7 +20,7 @@
 #include <math.h>
 
 #include <string.h>
-#include "isnanf.h"
+#include "isnanf-nolibm.h"
 #include "float+.h"
 
 #undef gl_signbitf
diff --git a/lib/vasnprintf.c b/lib/vasnprintf.c
index 472ce23..89829c9 100644
--- a/lib/vasnprintf.c
+++ b/lib/vasnprintf.c
@@ -95,7 +95,7 @@
 
 #if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
 # include <math.h>
-# include "isnand.h"
+# include "isnand-nolibm.h"
 #endif
 
 #if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined 
IN_LIBINTL
@@ -106,7 +106,7 @@
 
 #if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
 # include <math.h>
-# include "isnand.h"
+# include "isnand-nolibm.h"
 # include "printf-frexp.h"
 #endif
 
diff --git a/m4/isnan.m4 b/m4/isnan.m4
new file mode 100644
index 0000000..fb28c64
--- /dev/null
+++ b/m4/isnan.m4
@@ -0,0 +1,31 @@
+# isnan.m4 serial 1
+dnl Copyright (C) 2007-2008 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_ISNAN],
+[
+  AC_REQUIRE([gl_FUNC_ISNANF])
+  AC_REQUIRE([gl_FUNC_ISNAND])
+  AC_REQUIRE([gl_FUNC_ISNANL])
+
+  ISNAN_LIBM="$ISNANF_LIBM $ISNAND_LIBM $ISNANL_LIBM"
+  AC_SUBST([ISNAN_LIBM])
+
+  # If we replaced any of the underlying isnan* functions, replace
+  # the isnan macro; it undoubtedly suffers from the same flaws.
+  AC_MSG_CHECKING([whether isnan macro works])
+  if test $gl_func_isnanf = yes \
+     && test $gl_func_isnand = yes \
+     && test $gl_func_isnanl = yes; then
+    AC_MSG_RESULT([yes])
+  else
+    # Make sure the rpl_isnan[fdl] functions get built.
+    gl_BUILD_ISNANF
+    gl_BUILD_ISNAND
+    gl_BUILD_ISNANL
+    REPLACE_ISNAN=1
+    AC_MSG_RESULT([no])
+  fi
+])
diff --git a/m4/isnand.m4 b/m4/isnand.m4
index 7783b42..fbbac21 100644
--- a/m4/isnand.m4
+++ b/m4/isnand.m4
@@ -1,14 +1,81 @@
-# isnand.m4 serial 2
+# isnand.m4 serial 3
 dnl Copyright (C) 2007-2008 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.
 
+dnl Check how to get or define isnand().
+
+AC_DEFUN([gl_FUNC_ISNAND],
+[
+  ISNAND_LIBM=
+  gl_HAVE_ISNAND_NO_LIBM
+  if test $gl_cv_func_isnand_no_libm = no; then
+    gl_HAVE_ISNAND_IN_LIBM
+    if test $gl_cv_func_isnand_in_libm = yes; then
+      ISNAND_LIBM=-lm
+    fi
+  fi
+  if test $gl_cv_func_isnand_no_libm = yes \
+     || test $gl_cv_func_isnand_in_libm = yes; then
+    gl_func_isnand=yes
+    AC_DEFINE([HAVE_ISNAND], 1,
+      [Define if the isnan(double) function is available.])
+  else
+    gl_func_isnand=no
+    gl_BUILD_ISNAND
+  fi
+  AC_SUBST([ISNAND_LIBM])
+])
+
 dnl Check how to get or define isnand() without linking with libm.
 
 AC_DEFUN([gl_FUNC_ISNAND_NO_LIBM],
 [
-  AC_CACHE_CHECK([whether isnan(double) can be used without linking with libm],
+  gl_HAVE_ISNAND_NO_LIBM
+  if test $gl_cv_func_isnand_no_libm = yes; then
+    AC_DEFINE([HAVE_ISNAND_IN_LIBC], 1,
+      [Define if the isnan(double) function is available in libc.])
+  else
+    gl_BUILD_ISNAND
+  fi
+])
+
+dnl Pull in replacement isnand definition.
+AC_DEFUN([gl_BUILD_ISNAND],
+[
+    AC_LIBOBJ([isnand])
+    gl_DOUBLE_EXPONENT_LOCATION
+])
+
+dnl Test whether isnand() can be used with libm.
+
+AC_DEFUN([gl_HAVE_ISNAND_IN_LIBM],
+[
+  AC_CACHE_CHECK([whether isnan(double) can be used with libm],
+    [gl_cv_func_isnand_in_libm],
+    [
+      save_LIBS="$LIBS"
+      LIBS="$LIBS -lm"
+      AC_TRY_LINK([#include <math.h>
+                   #if __GNUC__ >= 4
+                   # undef isnand
+                   # define isnand(x) __builtin_isnand ((double)(x))
+                   #elif defined isnan
+                   # undef isnand
+                   # define isnand(x) isnan ((double)(x))
+                   #endif
+                   double x;],
+                  [return isnand (x);],
+        [gl_cv_func_isnand_in_libm=yes],
+        [gl_cv_func_isnand_in_libm=no])
+      LIBS="$save_LIBS"
+    ])
+])
+
+AC_DEFUN([gl_HAVE_ISNAND_NO_LIBM],
+[
+ AC_CACHE_CHECK([whether isnan(double) can be used without linking with libm],
     [gl_cv_func_isnand_no_libm],
     [
       AC_TRY_LINK([#include <math.h>
@@ -24,14 +91,7 @@ AC_DEFUN([gl_FUNC_ISNAND_NO_LIBM],
         [gl_cv_func_isnand_no_libm=yes],
         [gl_cv_func_isnand_no_libm=no])
     ])
-  if test $gl_cv_func_isnand_no_libm = yes; then
-    AC_DEFINE([HAVE_ISNAND_IN_LIBC], 1,
-      [Define if the isnan(double) function is available in libc.])
-  else
-    AC_LIBOBJ([isnand])
-    gl_DOUBLE_EXPONENT_LOCATION
-  fi
-])
+ ])
 
 AC_DEFUN([gl_DOUBLE_EXPONENT_LOCATION],
 [
diff --git a/m4/isnanf.m4 b/m4/isnanf.m4
index 1338955..ca4a199 100644
--- a/m4/isnanf.m4
+++ b/m4/isnanf.m4
@@ -1,9 +1,43 @@
-# isnanf.m4 serial 6
+# isnanf.m4 serial 7
 dnl Copyright (C) 2007-2008 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.
 
+dnl Check how to get or define isnanf().
+
+AC_DEFUN([gl_FUNC_ISNANF],
+[
+  ISNANF_LIBM=
+  gl_HAVE_ISNANF_NO_LIBM
+  if test $gl_cv_func_isnanf_no_libm = no; then
+    gl_HAVE_ISNANF_IN_LIBM
+    if test $gl_cv_func_isnanf_in_libm = yes; then
+      ISNANF_LIBM=-lm
+    fi
+  fi
+  if test $gl_cv_func_isnanf_no_libm = yes \
+     || test $gl_cv_func_isnanf_in_libm = yes; then
+    save_LIBS="$LIBS"
+    LIBS="$LIBS $ISNANF_LIBM"
+    gl_ISNANF_WORKS
+    LIBS="$save_LIBS"
+    case "$gl_cv_func_isnanf_works" in
+      *yes) gl_func_isnanf=yes ;;
+      *)    gl_func_isnanf=no; ISNANF_LIBM= ;;
+    esac
+  else
+    gl_func_isnanf=no
+  fi
+  if test $gl_func_isnanf = yes; then
+    AC_DEFINE([HAVE_ISNANF], 1,
+      [Define if the isnan(float) function is available.])
+  else
+    gl_BUILD_ISNANF
+  fi
+  AC_SUBST([ISNANF_LIBM])
+])
+
 dnl Check how to get or define isnanf() without linking with libm.
 
 AC_DEFUN([gl_FUNC_ISNANF_NO_LIBM],
@@ -21,9 +55,15 @@ AC_DEFUN([gl_FUNC_ISNANF_NO_LIBM],
     AC_DEFINE([HAVE_ISNANF_IN_LIBC], 1,
       [Define if the isnan(float) function is available in libc.])
   else
+    gl_BUILD_ISNANF
+  fi
+])
+
+dnl Pull in replacement isnanf definition.
+AC_DEFUN([gl_BUILD_ISNANF],
+[
     AC_LIBOBJ([isnanf])
     gl_FLOAT_EXPONENT_LOCATION
-  fi
 ])
 
 dnl Test whether isnanf() can be used without libm.
@@ -47,6 +87,30 @@ AC_DEFUN([gl_HAVE_ISNANF_NO_LIBM],
     ])
 ])
 
+dnl Test whether isnanf() can be used with libm.
+AC_DEFUN([gl_HAVE_ISNANF_IN_LIBM],
+[
+  AC_CACHE_CHECK([whether isnan(float) can be used with libm],
+    [gl_cv_func_isnanf_in_libm],
+    [
+      save_LIBS="$LIBS"
+      LIBS="$LIBS -lm"
+      AC_TRY_LINK([#include <math.h>
+                   #if __GNUC__ >= 4
+                   # undef isnanf
+                   # define isnanf(x) __builtin_isnanf ((float)(x))
+                   #elif defined isnan
+                   # undef isnanf
+                   # define isnanf(x) isnan ((float)(x))
+                   #endif
+                   float x;],
+                  [return isnanf (x);],
+        [gl_cv_func_isnanf_in_libm=yes],
+        [gl_cv_func_isnanf_in_libm=no])
+      LIBS="$save_LIBS"
+    ])
+])
+
 dnl Test whether isnanf() rejects Infinity (this fails on Solaris 2.5.1),
 dnl recognizes a NaN (this fails on IRIX 6.5 with cc), and recognizes a NaN
 dnl with in-memory representation 0x7fbfffff (this fails on IRIX 6.5).
diff --git a/m4/isnanl.m4 b/m4/isnanl.m4
index 660a898..4c26326 100644
--- a/m4/isnanl.m4
+++ b/m4/isnanl.m4
@@ -31,8 +31,7 @@ AC_DEFUN([gl_FUNC_ISNANL],
     AC_DEFINE([HAVE_ISNANL], 1,
       [Define if the isnan(long double) function is available.])
   else
-    AC_LIBOBJ([isnanl])
-    gl_LONG_DOUBLE_EXPONENT_LOCATION
+    gl_BUILD_ISNANL
   fi
   AC_SUBST([ISNANL_LIBM])
 ])
@@ -52,9 +51,15 @@ AC_DEFUN([gl_FUNC_ISNANL_NO_LIBM],
     AC_DEFINE([HAVE_ISNANL_IN_LIBC], 1,
       [Define if the isnan(long double) function is available in libc.])
   else
+    gl_BUILD_ISNANL
+  fi
+])
+
+dnl Pull in replacement isnanl definition.
+AC_DEFUN([gl_BUILD_ISNANL],
+[
     AC_LIBOBJ([isnanl])
     gl_LONG_DOUBLE_EXPONENT_LOCATION
-  fi
 ])
 
 dnl Test whether isnanl() can be used without libm.
diff --git a/m4/math_h.m4 b/m4/math_h.m4
index 902fdb5..0348f24 100644
--- a/m4/math_h.m4
+++ b/m4/math_h.m4
@@ -51,6 +51,7 @@ AC_DEFUN([gl_MATH_H_DEFAULTS],
   GNULIB_FREXP=0;    AC_SUBST([GNULIB_FREXP])
   GNULIB_FREXPL=0;   AC_SUBST([GNULIB_FREXPL])
   GNULIB_ISFINITE=0; AC_SUBST([GNULIB_ISFINITE])
+  GNULIB_ISNAN=0;    AC_SUBST([GNULIB_ISNAN])
   GNULIB_LDEXPL=0;   AC_SUBST([GNULIB_LDEXPL])
   GNULIB_MATHL=0;    AC_SUBST([GNULIB_MATHL])
   GNULIB_ROUND=0;    AC_SUBST([GNULIB_ROUND])
@@ -82,6 +83,7 @@ AC_DEFUN([gl_MATH_H_DEFAULTS],
   REPLACE_FREXPL=0;            AC_SUBST([REPLACE_FREXPL])
   REPLACE_HUGE_VAL=0;          AC_SUBST([REPLACE_HUGE_VAL])
   REPLACE_ISFINITE=0;          AC_SUBST([REPLACE_ISFINITE])
+  REPLACE_ISNAN=0;             AC_SUBST([REPLACE_ISNAN])
   REPLACE_LDEXPL=0;            AC_SUBST([REPLACE_LDEXPL])
   REPLACE_NAN=0;               AC_SUBST([REPLACE_NAN])
   REPLACE_ROUND=0;             AC_SUBST([REPLACE_ROUND])
diff --git a/modules/isnan b/modules/isnan
new file mode 100644
index 0000000..16972fa
--- /dev/null
+++ b/modules/isnan
@@ -0,0 +1,27 @@
+Description:
+isnan macro: test for NaN value.
+
+Files:
+m4/isnan.m4
+
+Depends-on:
+isnanf
+isnand
+isnanl
+math
+extensions
+
+configure.ac:
+gl_ISNAN
+gl_MATH_MODULE_INDICATOR([isnan])
+
+Makefile.am:
+
+Include:
+<math.h>
+
+License:
+GPL
+
+Maintainer:
+Ben Pfaff
diff --git a/modules/isnan-tests b/modules/isnan-tests
new file mode 100644
index 0000000..f06a783
--- /dev/null
+++ b/modules/isnan-tests
@@ -0,0 +1,16 @@
+Files:
+tests/test-isnan.c
+tests/nan.h
+
+Depends-on:
+
+configure.ac:
+gl_FLOAT_EXPONENT_LOCATION
+gl_DOUBLE_EXPONENT_LOCATION
+gl_LONG_DOUBLE_EXPONENT_LOCATION
+
+Makefile.am:
+TESTS += test-isnan
+check_PROGRAMS += test-isnan
+test_isnan_LDADD = $(LDADD) @ISNAN_LIBM@
+
diff --git a/modules/isnand-nolibm b/modules/isnand
similarity index 72%
copy from modules/isnand-nolibm
copy to modules/isnand
index 6bb8c7d..ab6cda5 100644
--- a/modules/isnand-nolibm
+++ b/modules/isnand
@@ -1,5 +1,5 @@
 Description:
-isnand() function: test for NaN, without requiring libm.
+isnand() function: test for NaN.
 
 Files:
 lib/isnand.h
@@ -12,13 +12,16 @@ Depends-on:
 fpieee
 
 configure.ac:
-gl_FUNC_ISNAND_NO_LIBM
+gl_FUNC_ISNAND
 
 Makefile.am:
 
 Include:
 #include "isnand.h"
 
+Link:
+$(ISNAND_LIBM)
+
 License:
 LGPL
 
diff --git a/modules/isnand-nolibm b/modules/isnand-nolibm
index 6bb8c7d..3fd1ee9 100644
--- a/modules/isnand-nolibm
+++ b/modules/isnand-nolibm
@@ -2,7 +2,7 @@ Description:
 isnand() function: test for NaN, without requiring libm.
 
 Files:
-lib/isnand.h
+lib/isnand-nolibm.h
 lib/isnand.c
 lib/isnan.c
 lib/float+.h
@@ -17,7 +17,7 @@ gl_FUNC_ISNAND_NO_LIBM
 Makefile.am:
 
 Include:
-#include "isnand.h"
+#include "isnand-nolibm.h"
 
 License:
 LGPL
diff --git a/modules/isnand-nolibm-tests b/modules/isnand-nolibm-tests
index 7fd37ba..6327334 100644
--- a/modules/isnand-nolibm-tests
+++ b/modules/isnand-nolibm-tests
@@ -1,5 +1,6 @@
 Files:
-tests/test-isnand.c
+tests/test-isnand-nolibm.c
+tests/test-isnand.h
 tests/nan.h
 
 Depends-on:
@@ -8,6 +9,6 @@ configure.ac:
 gl_DOUBLE_EXPONENT_LOCATION
 
 Makefile.am:
-TESTS += test-isnand
-check_PROGRAMS += test-isnand
+TESTS += test-isnand-nolibm
+check_PROGRAMS += test-isnand-nolibm
 
diff --git a/modules/isnand-nolibm-tests b/modules/isnand-tests
similarity index 71%
copy from modules/isnand-nolibm-tests
copy to modules/isnand-tests
index 7fd37ba..8d406fe 100644
--- a/modules/isnand-nolibm-tests
+++ b/modules/isnand-tests
@@ -1,5 +1,6 @@
 Files:
 tests/test-isnand.c
+tests/test-isnand.h
 tests/nan.h
 
 Depends-on:
@@ -10,4 +11,5 @@ gl_DOUBLE_EXPONENT_LOCATION
 Makefile.am:
 TESTS += test-isnand
 check_PROGRAMS += test-isnand
+test_isnand_LDADD = $(LDADD) @ISNAND_LIBM@
 
diff --git a/modules/isnanf-nolibm-tests b/modules/isnandf-tests
similarity index 71%
copy from modules/isnanf-nolibm-tests
copy to modules/isnandf-tests
index 8225ff4..6bd5adc 100644
--- a/modules/isnanf-nolibm-tests
+++ b/modules/isnandf-tests
@@ -1,5 +1,6 @@
 Files:
 tests/test-isnanf.c
+tests/test-isnanf.h
 tests/nan.h
 
 Depends-on:
@@ -10,4 +11,5 @@ gl_FLOAT_EXPONENT_LOCATION
 Makefile.am:
 TESTS += test-isnanf
 check_PROGRAMS += test-isnanf
+test_isnanf_LDADD = $(LDADD) @ISNANF_LIBM@
 
diff --git a/modules/isnanf-nolibm b/modules/isnanf
similarity index 72%
copy from modules/isnanf-nolibm
copy to modules/isnanf
index 3f90629..72da537 100644
--- a/modules/isnanf-nolibm
+++ b/modules/isnanf
@@ -1,5 +1,5 @@
 Description:
-isnanf() function: test for NaN, without requiring libm.
+isnanf() function: test for NaN.
 
 Files:
 lib/isnanf.h
@@ -12,13 +12,16 @@ Depends-on:
 fpieee
 
 configure.ac:
-gl_FUNC_ISNANF_NO_LIBM
+gl_FUNC_ISNANF
 
 Makefile.am:
 
 Include:
 #include "isnanf.h"
 
+Link:
+$(ISNANF_LIBM)
+
 License:
 LGPL
 
diff --git a/modules/isnanf-nolibm b/modules/isnanf-nolibm
index 3f90629..e6418b0 100644
--- a/modules/isnanf-nolibm
+++ b/modules/isnanf-nolibm
@@ -2,7 +2,7 @@ Description:
 isnanf() function: test for NaN, without requiring libm.
 
 Files:
-lib/isnanf.h
+lib/isnanf-nolibm.h
 lib/isnanf.c
 lib/isnan.c
 lib/float+.h
@@ -17,7 +17,7 @@ gl_FUNC_ISNANF_NO_LIBM
 Makefile.am:
 
 Include:
-#include "isnanf.h"
+#include "isnanf-nolibm.h"
 
 License:
 LGPL
diff --git a/modules/isnanf-nolibm-tests b/modules/isnanf-nolibm-tests
index 8225ff4..0e83930 100644
--- a/modules/isnanf-nolibm-tests
+++ b/modules/isnanf-nolibm-tests
@@ -1,5 +1,6 @@
 Files:
-tests/test-isnanf.c
+tests/test-isnanf-nolibm.c
+tests/test-isnanf.h
 tests/nan.h
 
 Depends-on:
@@ -8,6 +9,6 @@ configure.ac:
 gl_FLOAT_EXPONENT_LOCATION
 
 Makefile.am:
-TESTS += test-isnanf
-check_PROGRAMS += test-isnanf
+TESTS += test-isnanf-nolibm
+check_PROGRAMS += test-isnanf-nolibm
 
diff --git a/modules/isnanf-nolibm-tests b/modules/isnanf-tests
similarity index 71%
copy from modules/isnanf-nolibm-tests
copy to modules/isnanf-tests
index 8225ff4..6bd5adc 100644
--- a/modules/isnanf-nolibm-tests
+++ b/modules/isnanf-tests
@@ -1,5 +1,6 @@
 Files:
 tests/test-isnanf.c
+tests/test-isnanf.h
 tests/nan.h
 
 Depends-on:
@@ -10,4 +11,5 @@ gl_FLOAT_EXPONENT_LOCATION
 Makefile.am:
 TESTS += test-isnanf
 check_PROGRAMS += test-isnanf
+test_isnanf_LDADD = $(LDADD) @ISNANF_LIBM@
 
diff --git a/modules/math b/modules/math
index f3a38da..4be8501 100644
--- a/modules/math
+++ b/modules/math
@@ -29,6 +29,7 @@ math.h: math.in.h
              -e 's|@''GNULIB_FREXP''@|$(GNULIB_FREXP)|g' \
              -e 's|@''GNULIB_FREXPL''@|$(GNULIB_FREXPL)|g' \
              -e 's|@''GNULIB_ISFINITE''@|$(GNULIB_ISFINITE)|g' \
+             -e 's|@''GNULIB_ISNAN''@|$(GNULIB_ISNAN)|g' \
              -e 's|@''GNULIB_LDEXPL''@|$(GNULIB_LDEXPL)|g' \
              -e 's|@''GNULIB_MATHL''@|$(GNULIB_MATHL)|g' \
              -e 's|@''GNULIB_ROUND''@|$(GNULIB_ROUND)|g' \
@@ -59,6 +60,7 @@ math.h: math.in.h
              -e 's|@''REPLACE_FREXPL''@|$(REPLACE_FREXPL)|g' \
              -e 's|@''REPLACE_HUGE_VAL''@|$(REPLACE_HUGE_VAL)|g' \
              -e 's|@''REPLACE_ISFINITE''@|$(REPLACE_ISFINITE)|g' \
+             -e 's|@''REPLACE_ISNAN''@|$(REPLACE_ISNAN)|g' \
              -e 's|@''REPLACE_LDEXPL''@|$(REPLACE_LDEXPL)|g' \
              -e 's|@''REPLACE_NAN''@|$(REPLACE_NAN)|g' \
              -e 's|@''REPLACE_ROUND''@|$(REPLACE_ROUND)|g' \
diff --git a/tests/test-ceilf1.c b/tests/test-ceilf1.c
index 430e4ab..f17c19a 100644
--- a/tests/test-ceilf1.c
+++ b/tests/test-ceilf1.c
@@ -23,7 +23,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "isnanf.h"
+#include "isnanf-nolibm.h"
 #include "nan.h"
 
 #define ASSERT(expr) \
diff --git a/tests/test-ceilf2.c b/tests/test-ceilf2.c
index e6d69ec..17aac84 100644
--- a/tests/test-ceilf2.c
+++ b/tests/test-ceilf2.c
@@ -26,7 +26,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "isnanf.h"
+#include "isnanf-nolibm.h"
 
 #define ASSERT(expr) \
   do                                                                        \
diff --git a/tests/test-floorf1.c b/tests/test-floorf1.c
index 773e4bc..b9c4da4 100644
--- a/tests/test-floorf1.c
+++ b/tests/test-floorf1.c
@@ -23,7 +23,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "isnanf.h"
+#include "isnanf-nolibm.h"
 #include "nan.h"
 
 #define ASSERT(expr) \
diff --git a/tests/test-floorf2.c b/tests/test-floorf2.c
index 1521c22..e7fcd98 100644
--- a/tests/test-floorf2.c
+++ b/tests/test-floorf2.c
@@ -26,7 +26,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "isnanf.h"
+#include "isnanf-nolibm.h"
 
 #define ASSERT(expr) \
   do                                                                        \
diff --git a/tests/test-frexp.c b/tests/test-frexp.c
index c08056c..5d95063 100644
--- a/tests/test-frexp.c
+++ b/tests/test-frexp.c
@@ -24,7 +24,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "isnand.h"
+#include "isnand-nolibm.h"
 #include "nan.h"
 
 /* Avoid some warnings from "gcc -Wshadow".
diff --git a/tests/test-isnan.c b/tests/test-isnan.c
new file mode 100644
index 0000000..9761ee6
--- /dev/null
+++ b/tests/test-isnan.c
@@ -0,0 +1,228 @@
+/* Test of isnand() substitute.
+   Copyright (C) 2007-2008 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/>.  */
+
+/* Written by Ben Pfaff <address@hidden>, from code by Bruno
+   Haible <address@hidden>.  */
+
+#include <config.h>
+
+#include <math.h>
+
+#include <float.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "nan.h"
+
+#define ASSERT(expr) \
+  do                                                                        \
+    {                                                                       \
+      if (!(expr))                                                          \
+        {                                                                   \
+          fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
+          fflush (stderr);                                                  \
+          abort ();                                                         \
+        }                                                                   \
+    }                                                                       \
+  while (0)
+
+static void
+test_float (void)
+{
+  /* Finite values.  */
+  ASSERT (!isnan (3.141f));
+  ASSERT (!isnan (3.141e30f));
+  ASSERT (!isnan (3.141e-30f));
+  ASSERT (!isnan (-2.718f));
+  ASSERT (!isnan (-2.718e30f));
+  ASSERT (!isnan (-2.718e-30f));
+  ASSERT (!isnan (0.0f));
+  ASSERT (!isnan (-0.0f));
+  /* Infinite values.  */
+  ASSERT (!isnan (1.0f / 0.0f));
+  ASSERT (!isnan (-1.0f / 0.0f));
+  /* Quiet NaN.  */
+  ASSERT (isnan (NaNf ()));
+#if defined FLT_EXPBIT0_WORD && defined FLT_EXPBIT0_BIT
+  /* Signalling NaN.  */
+  {
+    #define NWORDSF \
+      ((sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+    typedef union { float value; unsigned int word[NWORDSF]; } memory_float;
+    memory_float m;
+    m.value = NaNf ();
+# if FLT_EXPBIT0_BIT > 0
+    m.word[FLT_EXPBIT0_WORD] ^= (unsigned int) 1 << (FLT_EXPBIT0_BIT - 1);
+# else
+    m.word[FLT_EXPBIT0_WORD + (FLT_EXPBIT0_WORD < NWORDSF / 2 ? 1 : - 1)]
+      ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
+# endif
+    if (FLT_EXPBIT0_WORD < NWORDSF / 2)
+      m.word[FLT_EXPBIT0_WORD + 1] |= (unsigned int) 1 << FLT_EXPBIT0_BIT;
+    else
+      m.word[0] |= (unsigned int) 1;
+    ASSERT (isnan (m.value));
+  }
+#endif
+}
+
+static void
+test_double (void)
+{
+  /* Finite values.  */
+  ASSERT (!isnan (3.141));
+  ASSERT (!isnan (3.141e30));
+  ASSERT (!isnan (3.141e-30));
+  ASSERT (!isnan (-2.718));
+  ASSERT (!isnan (-2.718e30));
+  ASSERT (!isnan (-2.718e-30));
+  ASSERT (!isnan (0.0));
+  ASSERT (!isnan (-0.0));
+  /* Infinite values.  */
+  ASSERT (!isnan (1.0 / 0.0));
+  ASSERT (!isnan (-1.0 / 0.0));
+  /* Quiet NaN.  */
+  ASSERT (isnan (NaNd ()));
+#if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
+  /* Signalling NaN.  */
+  {
+    #define NWORDSD \
+      ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+    typedef union { double value; unsigned int word[NWORDSD]; } memory_double;
+    memory_double m;
+    m.value = NaNd ();
+# if DBL_EXPBIT0_BIT > 0
+    m.word[DBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (DBL_EXPBIT0_BIT - 1);
+# else
+    m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDSD / 2 ? 1 : - 1)]
+      ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
+# endif
+    m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDSD / 2 ? 1 : - 1)]
+      |= (unsigned int) 1 << DBL_EXPBIT0_BIT;
+    ASSERT (isnan (m.value));
+  }
+#endif
+}
+
+static void
+test_long_double (void)
+{
+  #define NWORDSL \
+    ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned 
int))
+  typedef union { unsigned int word[NWORDSL]; long double value; }
+          memory_long_double;
+
+  /* Finite values.  */
+  ASSERT (!isnan (3.141L));
+  ASSERT (!isnan (3.141e30L));
+  ASSERT (!isnan (3.141e-30L));
+  ASSERT (!isnan (-2.718L));
+  ASSERT (!isnan (-2.718e30L));
+  ASSERT (!isnan (-2.718e-30L));
+  ASSERT (!isnan (0.0L));
+  ASSERT (!isnan (-0.0L));
+  /* Infinite values.  */
+  ASSERT (!isnan (1.0L / 0.0L));
+  ASSERT (!isnan (-1.0L / 0.0L));
+  /* Quiet NaN.  */
+  ASSERT (isnan (0.0L / 0.0L));
+
+#if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT
+  /* A bit pattern that is different from a Quiet NaN.  With a bit of luck,
+     it's a Signalling NaN.  */
+  {
+    memory_long_double m;
+    m.value = 0.0L / 0.0L;
+# if LDBL_EXPBIT0_BIT > 0
+    m.word[LDBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (LDBL_EXPBIT0_BIT - 1);
+# else
+    m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < NWORDSL / 2 ? 1 : - 1)]
+      ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
+# endif
+    m.word[LDBL_EXPBIT0_WORD + (LDBL_EXPBIT0_WORD < NWORDSL / 2 ? 1 : - 1)]
+      |= (unsigned int) 1 << LDBL_EXPBIT0_BIT;
+    ASSERT (isnan (m.value));
+  }
+#endif
+
+#if ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined 
__amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined 
_M_IX86 || defined _X86_))
+/* Representation of an 80-bit 'long double' as an initializer for a sequence
+   of 'unsigned int' words.  */
+# ifdef WORDS_BIGENDIAN
+#  define LDBL80_WORDS(exponent,manthi,mantlo) \
+     { ((unsigned int) (exponent) << 16) | ((unsigned int) (manthi) >> 16), \
+       ((unsigned int) (manthi) << 16) | (unsigned int) (mantlo) >> 16),    \
+       (unsigned int) (mantlo) << 16                                        \
+     }
+# else
+#  define LDBL80_WORDS(exponent,manthi,mantlo) \
+     { mantlo, manthi, exponent }
+# endif
+  { /* Quiet NaN.  */
+    static memory_long_double x =
+      { LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
+    ASSERT (isnan (x.value));
+  }
+  {
+    /* Signalling NaN.  */
+    static memory_long_double x =
+      { LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
+    ASSERT (isnan (x.value));
+  }
+  /* The isnan function should recognize Pseudo-NaNs, Pseudo-Infinities,
+     Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals, as defined in
+       Intel IA-64 Architecture Software Developer's Manual, Volume 1:
+       Application Architecture.
+       Table 5-2 "Floating-Point Register Encodings"
+       Figure 5-6 "Memory to Floating-Point Register Data Translation"
+   */
+  { /* Pseudo-NaN.  */
+    static memory_long_double x =
+      { LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
+    ASSERT (isnan (x.value));
+  }
+  { /* Pseudo-Infinity.  */
+    static memory_long_double x =
+      { LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
+    ASSERT (isnan (x.value));
+  }
+  { /* Pseudo-Zero.  */
+    static memory_long_double x =
+      { LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
+    ASSERT (isnan (x.value));
+  }
+  { /* Unnormalized number.  */
+    static memory_long_double x =
+      { LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
+    ASSERT (isnan (x.value));
+  }
+  { /* Pseudo-Denormal.  */
+    static memory_long_double x =
+      { LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
+    ASSERT (isnan (x.value));
+  }
+#endif
+}
+
+int
+main ()
+{
+  test_float ();
+  test_double ();
+  test_long_double ();
+  return 0;
+}
diff --git a/lib/isnand.h b/tests/test-isnand-nolibm.c
similarity index 60%
copy from lib/isnand.h
copy to tests/test-isnand-nolibm.c
index d248b2f..4cc9319 100644
--- a/lib/isnand.h
+++ b/tests/test-isnand-nolibm.c
@@ -1,4 +1,4 @@
-/* Test for NaN that does not need libm.
+/* Test of isnand() substitute.
    Copyright (C) 2007-2008 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
@@ -14,20 +14,11 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#if HAVE_ISNAND_IN_LIBC
-/* Get declaration of isnan macro.  */
-# include <math.h>
-# if __GNUC__ >= 4
-   /* GCC 4.0 and newer provides three built-ins for isnan.  */
-#  undef isnand
-#  define isnand(x) __builtin_isnan ((double)(x))
-# else
-#  undef isnand
-#  define isnand(x) isnan ((double)(x))
-# endif
-#else
-/* Test whether X is a NaN.  */
-# undef isnand
-# define isnand rpl_isnand
-extern int isnand (double x);
-#endif
+/* Written by Bruno Haible <address@hidden>, 2007.  */
+
+#include <config.h>
+
+#include "isnand-nolibm.h"
+
+#include "test-isnand.h"
+
diff --git a/tests/test-isnand.c b/tests/test-isnand.c
index d7b66c4..0ccada5 100644
--- a/tests/test-isnand.c
+++ b/tests/test-isnand.c
@@ -20,59 +20,5 @@
 
 #include "isnand.h"
 
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
+#include "test-isnand.h"
 
-#include "nan.h"
-
-#define ASSERT(expr) \
-  do                                                                        \
-    {                                                                       \
-      if (!(expr))                                                          \
-        {                                                                   \
-          fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
-          fflush (stderr);                                                  \
-          abort ();                                                         \
-        }                                                                   \
-    }                                                                       \
-  while (0)
-
-int
-main ()
-{
-  /* Finite values.  */
-  ASSERT (!isnand (3.141));
-  ASSERT (!isnand (3.141e30));
-  ASSERT (!isnand (3.141e-30));
-  ASSERT (!isnand (-2.718));
-  ASSERT (!isnand (-2.718e30));
-  ASSERT (!isnand (-2.718e-30));
-  ASSERT (!isnand (0.0));
-  ASSERT (!isnand (-0.0));
-  /* Infinite values.  */
-  ASSERT (!isnand (1.0 / 0.0));
-  ASSERT (!isnand (-1.0 / 0.0));
-  /* Quiet NaN.  */
-  ASSERT (isnand (NaNd ()));
-#if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
-  /* Signalling NaN.  */
-  {
-    #define NWORDS \
-      ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
-    typedef union { double value; unsigned int word[NWORDS]; } memory_double;
-    memory_double m;
-    m.value = NaNd ();
-# if DBL_EXPBIT0_BIT > 0
-    m.word[DBL_EXPBIT0_WORD] ^= (unsigned int) 1 << (DBL_EXPBIT0_BIT - 1);
-# else
-    m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
-      ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
-# endif
-    m.word[DBL_EXPBIT0_WORD + (DBL_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
-      |= (unsigned int) 1 << DBL_EXPBIT0_BIT;
-    ASSERT (isnand (m.value));
-  }
-#endif
-  return 0;
-}
diff --git a/tests/test-isnand.c b/tests/test-isnand.h
similarity index 98%
copy from tests/test-isnand.c
copy to tests/test-isnand.h
index d7b66c4..cf8cb5d 100644
--- a/tests/test-isnand.c
+++ b/tests/test-isnand.h
@@ -16,10 +16,6 @@
 
 /* Written by Bruno Haible <address@hidden>, 2007.  */
 
-#include <config.h>
-
-#include "isnand.h"
-
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/lib/isnand.h b/tests/test-isnanf-nolibm.c
similarity index 60%
copy from lib/isnand.h
copy to tests/test-isnanf-nolibm.c
index d248b2f..f7de586 100644
--- a/lib/isnand.h
+++ b/tests/test-isnanf-nolibm.c
@@ -1,4 +1,4 @@
-/* Test for NaN that does not need libm.
+/* Test of isnanf() substitute.
    Copyright (C) 2007-2008 Free Software Foundation, Inc.
 
    This program is free software: you can redistribute it and/or modify
@@ -14,20 +14,10 @@
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#if HAVE_ISNAND_IN_LIBC
-/* Get declaration of isnan macro.  */
-# include <math.h>
-# if __GNUC__ >= 4
-   /* GCC 4.0 and newer provides three built-ins for isnan.  */
-#  undef isnand
-#  define isnand(x) __builtin_isnan ((double)(x))
-# else
-#  undef isnand
-#  define isnand(x) isnan ((double)(x))
-# endif
-#else
-/* Test whether X is a NaN.  */
-# undef isnand
-# define isnand rpl_isnand
-extern int isnand (double x);
-#endif
+/* Written by Bruno Haible <address@hidden>, 2007.  */
+
+#include <config.h>
+
+#include "isnanf-nolibm.h"
+
+#include "test-isnanf.h"
diff --git a/tests/test-isnanf.c b/tests/test-isnanf.c
index 00fbfeb..ac695ff 100644
--- a/tests/test-isnanf.c
+++ b/tests/test-isnanf.c
@@ -20,61 +20,4 @@
 
 #include "isnanf.h"
 
-#include <limits.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "nan.h"
-
-#define ASSERT(expr) \
-  do                                                                        \
-    {                                                                       \
-      if (!(expr))                                                          \
-        {                                                                   \
-          fprintf (stderr, "%s:%d: assertion failed\n", __FILE__, __LINE__); \
-          fflush (stderr);                                                  \
-          abort ();                                                         \
-        }                                                                   \
-    }                                                                       \
-  while (0)
-
-int
-main ()
-{
-  /* Finite values.  */
-  ASSERT (!isnanf (3.141f));
-  ASSERT (!isnanf (3.141e30f));
-  ASSERT (!isnanf (3.141e-30f));
-  ASSERT (!isnanf (-2.718f));
-  ASSERT (!isnanf (-2.718e30f));
-  ASSERT (!isnanf (-2.718e-30f));
-  ASSERT (!isnanf (0.0f));
-  ASSERT (!isnanf (-0.0f));
-  /* Infinite values.  */
-  ASSERT (!isnanf (1.0f / 0.0f));
-  ASSERT (!isnanf (-1.0f / 0.0f));
-  /* Quiet NaN.  */
-  ASSERT (isnanf (NaNf ()));
-#if defined FLT_EXPBIT0_WORD && defined FLT_EXPBIT0_BIT
-  /* Signalling NaN.  */
-  {
-    #define NWORDS \
-      ((sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
-    typedef union { float value; unsigned int word[NWORDS]; } memory_float;
-    memory_float m;
-    m.value = NaNf ();
-# if FLT_EXPBIT0_BIT > 0
-    m.word[FLT_EXPBIT0_WORD] ^= (unsigned int) 1 << (FLT_EXPBIT0_BIT - 1);
-# else
-    m.word[FLT_EXPBIT0_WORD + (FLT_EXPBIT0_WORD < NWORDS / 2 ? 1 : - 1)]
-      ^= (unsigned int) 1 << (sizeof (unsigned int) * CHAR_BIT - 1);
-# endif
-    if (FLT_EXPBIT0_WORD < NWORDS / 2)
-      m.word[FLT_EXPBIT0_WORD + 1] |= (unsigned int) 1 << FLT_EXPBIT0_BIT;
-    else
-      m.word[0] |= (unsigned int) 1;
-    ASSERT (isnanf (m.value));
-  }
-#endif
-  return 0;
-}
+#include "test-isnanf.h"
diff --git a/tests/test-isnanf.c b/tests/test-isnanf.h
similarity index 98%
copy from tests/test-isnanf.c
copy to tests/test-isnanf.h
index 00fbfeb..7f6eb12 100644
--- a/tests/test-isnanf.c
+++ b/tests/test-isnanf.h
@@ -16,10 +16,6 @@
 
 /* Written by Bruno Haible <address@hidden>, 2007.  */
 
-#include <config.h>
-
-#include "isnanf.h"
-
 #include <limits.h>
 #include <stdio.h>
 #include <stdlib.h>
diff --git a/tests/test-round1.c b/tests/test-round1.c
index 2cf90f6..935eb10 100644
--- a/tests/test-round1.c
+++ b/tests/test-round1.c
@@ -25,7 +25,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "isnand.h"
+#include "isnand-nolibm.h"
 #include "nan.h"
 
 #define ASSERT(expr) \
diff --git a/tests/test-round2.c b/tests/test-round2.c
index aa993ef..b5944a9 100644
--- a/tests/test-round2.c
+++ b/tests/test-round2.c
@@ -37,7 +37,7 @@
 #ifdef USE_LONG_DOUBLE
 # error Long double not supported.
 #elif ! defined USE_FLOAT
-# include "isnand.h"
+# include "isnand-nolibm.h"
 # define ISNAN isnand
 # define FUNCTION "round"
 # define DOUBLE_UINT uint64_t
@@ -45,7 +45,7 @@
 # define NUM_HIGHBITS 13
 # define NUM_LOWBITS 4
 #else /* defined USE_FLOAT */
-# include "isnanf.h"
+# include "isnanf-nolibm.h"
 # define ISNAN isnanf
 # define FUNCTION "roundf"
 # define DOUBLE_UINT uint32_t
diff --git a/tests/test-roundf1.c b/tests/test-roundf1.c
index 0b6bc2f..60e1946 100644
--- a/tests/test-roundf1.c
+++ b/tests/test-roundf1.c
@@ -25,7 +25,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "isnanf.h"
+#include "isnanf-nolibm.h"
 #include "nan.h"
 
 #define ASSERT(expr) \
diff --git a/tests/test-strtod.c b/tests/test-strtod.c
index 12d3606..87d7062 100644
--- a/tests/test-strtod.c
+++ b/tests/test-strtod.c
@@ -25,7 +25,7 @@
 #include <stdio.h>
 #include <string.h>
 
-#include "isnand.h"
+#include "isnand-nolibm.h"
 
 #define ASSERT(expr) \
   do                                                                        \
diff --git a/tests/test-trunc1.c b/tests/test-trunc1.c
index 0449aa9..ebe4482 100644
--- a/tests/test-trunc1.c
+++ b/tests/test-trunc1.c
@@ -23,7 +23,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "isnand.h"
+#include "isnand-nolibm.h"
 #include "nan.h"
 
 #define ASSERT(expr) \
diff --git a/tests/test-trunc2.c b/tests/test-trunc2.c
index adf4e54..b13433f 100644
--- a/tests/test-trunc2.c
+++ b/tests/test-trunc2.c
@@ -26,7 +26,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "isnand.h"
+#include "isnand-nolibm.h"
 
 #define ASSERT(expr) \
   do                                                                        \
diff --git a/tests/test-truncf1.c b/tests/test-truncf1.c
index 16d8682..8d46840 100644
--- a/tests/test-truncf1.c
+++ b/tests/test-truncf1.c
@@ -23,7 +23,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "isnanf.h"
+#include "isnanf-nolibm.h"
 #include "nan.h"
 
 #define ASSERT(expr) \
diff --git a/tests/test-truncf2.c b/tests/test-truncf2.c
index 0a73371..dd849ab 100644
--- a/tests/test-truncf2.c
+++ b/tests/test-truncf2.c
@@ -26,7 +26,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#include "isnanf.h"
+#include "isnanf-nolibm.h"
 
 #define ASSERT(expr) \
   do                                                                        \


-- 
Ben Pfaff 
http://benpfaff.org





reply via email to

[Prev in Thread] Current Thread [Next in Thread]