changeset 29956:77787be75d50

Add isnand module.
author Ben Pfaff <blp@cs.stanford.edu>
date Sat, 12 Jul 2008 10:45:22 -0700
parents e4b084d57f9e
children 32f770d84f87
files ChangeLog MODULES.html.sh lib/isnand.h m4/isnand.m4 modules/isnand modules/isnand-nolibm-tests modules/isnand-tests tests/test-isnand-nolibm.c tests/test-isnand.c tests/test-isnand.h
diffstat 10 files changed, 266 insertions(+), 65 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Sat Jul 12 10:41:34 2008 -0700
+++ b/ChangeLog	Sat Jul 12 10:45:22 2008 -0700
@@ -1,3 +1,24 @@
+2008-07-10  Ben Pfaff  <blp@gnu.org>
+
+	Add isnand module.
+	* lib/isnand.h: New file.
+	* m4/isnand.m4 (gl_FUNC_ISNAND): New macro.
+	(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_BUILD_ISNAND): New macro used by gl_FUNC_ISNAND,
+	gl_FUNC_ISNAND_NO_LIBM, and gl_FUNC_ISNAN.
+	(gl_HAVE_ISNAND_IN_LIBM): New macro.
+	* modules/isnand: New file.
+	* modules/isnand-tests: New file.
+	* modules/isnand-nolibm-tests: Add tests/test-isnand.h to list of
+	files.
+	* tests/test-isnand-nolibm.c: factored most of its contents into
+	new file tests/test-isnand.h.
+	* tests/test-isnand.h: New file.
+	* tests/test-isnand.c: New file.
+	* MODULES.html.sh: Mention new module.
+
 2008-07-10  Ben Pfaff  <blp@gnu.org>
 
 	* lib/isnanf.h: Rename lib/isnanf-nolibm.h.
--- a/MODULES.html.sh	Sat Jul 12 10:41:34 2008 -0700
+++ b/MODULES.html.sh	Sat Jul 12 10:45:22 2008 -0700
@@ -2000,6 +2000,7 @@
   func_module frexpl-nolibm
   func_module isfinite
   func_module isnanf-nolibm
+  func_module isnand
   func_module isnand-nolibm
   func_module isnanl
   func_module isnanl-nolibm
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/lib/isnand.h	Sat Jul 12 10:45:22 2008 -0700
@@ -0,0 +1,33 @@
+/* Test for NaN.
+   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/>.  */
+
+#if HAVE_ISNAND
+/* 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
--- a/m4/isnand.m4	Sat Jul 12 10:41:34 2008 -0700
+++ b/m4/isnand.m4	Sat Jul 12 10:45:22 2008 -0700
@@ -1,13 +1,80 @@
-# 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
+  dnl The variable gl_func_isnand set here is used by isnan.m4.
+  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],
 [
+  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],
     [
@@ -24,13 +91,6 @@
         [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],
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/isnand	Sat Jul 12 10:45:22 2008 -0700
@@ -0,0 +1,30 @@
+Description:
+isnand() function: test for NaN.
+
+Files:
+lib/isnand.h
+lib/isnand.c
+lib/isnan.c
+lib/float+.h
+m4/isnand.m4
+
+Depends-on:
+fpieee
+
+configure.ac:
+gl_FUNC_ISNAND
+
+Makefile.am:
+
+Include:
+#include "isnand.h"
+
+Link:
+$(ISNAND_LIBM)
+
+License:
+LGPL
+
+Maintainer:
+Bruno Haible
+
--- a/modules/isnand-nolibm-tests	Sat Jul 12 10:41:34 2008 -0700
+++ b/modules/isnand-nolibm-tests	Sat Jul 12 10:45:22 2008 -0700
@@ -1,5 +1,6 @@
 Files:
 tests/test-isnand-nolibm.c
+tests/test-isnand.h
 tests/nan.h
 
 Depends-on:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/modules/isnand-tests	Sat Jul 12 10:45:22 2008 -0700
@@ -0,0 +1,15 @@
+Files:
+tests/test-isnand.c
+tests/test-isnand.h
+tests/nan.h
+
+Depends-on:
+
+configure.ac:
+gl_DOUBLE_EXPONENT_LOCATION
+
+Makefile.am:
+TESTS += test-isnand
+check_PROGRAMS += test-isnand
+test_isnand_LDADD = $(LDADD) @ISNAND_LIBM@
+
--- a/tests/test-isnand-nolibm.c	Sat Jul 12 10:41:34 2008 -0700
+++ b/tests/test-isnand-nolibm.c	Sat Jul 12 10:45:22 2008 -0700
@@ -14,65 +14,9 @@
    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 Bruno Haible <bruno@clisp.org>, 2007.  */
-
 #include <config.h>
 
 #include "isnand-nolibm.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)
+#include "test-isnand.h"
 
-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;
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-isnand.c	Sat Jul 12 10:45:22 2008 -0700
@@ -0,0 +1,22 @@
+/* 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/>.  */
+
+#include <config.h>
+
+#include "isnand.h"
+
+#include "test-isnand.h"
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-isnand.h	Sat Jul 12 10:45:22 2008 -0700
@@ -0,0 +1,74 @@
+/* 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 Bruno Haible <bruno@clisp.org>, 2007.  */
+
+#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 (!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;
+}