math: add portability warnings for classification macros
authorEric Blake <ebb9@byu.net>
Thu, 31 Dec 2009 20:48:15 +0000 (13:48 -0700)
committerEric Blake <ebb9@byu.net>
Mon, 11 Jan 2010 13:52:25 +0000 (06:52 -0700)
For interfaces which are defined to exist only as macros, implement
the proper magic needed to warn if the corresponding gnulib module was
not in use.  This solution avoids promoting arguments unnecessarily,
to allow reuse in case gnulib ever implements fpclassify, since
fpclassify(1e-40f) is different than fpclassify(1e-40).

* modules/math (Depends-on): Add warn-on-use.
(Makefile.am): Provide new substitutions.
* m4/math_h.m4 (gl_MATH_H): Require inline.
* lib/math.in.h (_GL_WARN_REAL_FLOATING_DECL)
(_GL_WARN_REAL_FLOATING_IMPL): New helper macros.
(isfinite, isinf, isnan, signbit) [GNULIB_POSIXCHECK]: Use them to
implement warnings.

Signed-off-by: Eric Blake <ebb9@byu.net>
ChangeLog
lib/math.in.h
m4/math_h.m4
modules/math

index 5fa0e6c..291b88b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2010-01-11  Eric Blake  <ebb9@byu.net>
 
+       math: add portability warnings for classification macros
+       * modules/math (Depends-on): Add warn-on-use.
+       (Makefile.am): Provide new substitutions.
+       * m4/math_h.m4 (gl_MATH_H): Require inline.
+       * lib/math.in.h (_GL_WARN_REAL_FLOATING_DECL)
+       (_GL_WARN_REAL_FLOATING_IMPL): New helper macros.
+       (isfinite, isinf, isnan, signbit) [GNULIB_POSIXCHECK]: Use them to
+       implement warnings.
+
        unistd: warn on use of environ without module
        * modules/unistd (Depends-on): Add warn-on-use.
        (Makefile.am): Provide new substitutions.
index 5cefd4d..7f09424 100644 (file)
 
 /* The definition of _GL_ARG_NONNULL is copied here.  */
 
+/* Helper macros to define a portability warning for the
+   classification macro FUNC called with VALUE.  POSIX declares the
+   classification macros with an argument of real-floating (that is,
+   one of float, double, or long double).  */
+#define _GL_WARN_REAL_FLOATING_DECL(func) \
+static inline int                                                   \
+rpl_ ## func ## f (float f)                                         \
+{                                                                   \
+  return func (f);                                                  \
+}                                                                   \
+static inline int                                                   \
+rpl_ ## func ## d (double d)                                        \
+{                                                                   \
+  return func (d);                                                  \
+}                                                                   \
+static inline int                                                   \
+rpl_ ## func ## l (long double l)                                   \
+{                                                                   \
+  return func (l);                                                  \
+}                                                                   \
+_GL_WARN_ON_USE (rpl_ ## func ## f, #func " is unportable - "       \
+                 "use gnulib module " #func " for portability");    \
+_GL_WARN_ON_USE (rpl_ ## func ## d, #func " is unportable - "       \
+                 "use gnulib module " #func " for portability");    \
+_GL_WARN_ON_USE (rpl_ ## func ## l, #func " is unportable - "       \
+                 "use gnulib module " #func " for portability")
+#define _GL_WARN_REAL_FLOATING_IMPL(func, value) \
+  (sizeof (value) == sizeof (float) ? rpl_ ## func ## f (value)     \
+   : sizeof (value) == sizeof (double) ? rpl_ ## func ## d (value)  \
+   : rpl_ ## func ## l (value))
+
 
 #ifdef __cplusplus
 extern "C" {
@@ -386,7 +417,11 @@ extern int gl_isfinitel (long double x);
     gl_isfinitef (x))
 # endif
 #elif defined GNULIB_POSIXCHECK
-  /* How to override a macro?  */
+# if defined isfinite
+_GL_WARN_REAL_FLOATING_DECL (isfinite);
+#  undef isfinite
+#  define isfinite(x) _GL_WARN_REAL_FLOATING_IMPL (isfinite, x)
+# endif
 #endif
 
 
@@ -402,7 +437,11 @@ extern int gl_isinfl (long double x);
     gl_isinff (x))
 # endif
 #elif defined GNULIB_POSIXCHECK
-  /* How to override a macro?  */
+# if defined isinf
+_GL_WARN_REAL_FLOATING_DECL (isinf);
+#  undef isinf
+#  define isinf(x) _GL_WARN_REAL_FLOATING_IMPL (isinf, x)
+# endif
 #endif
 
 
@@ -501,7 +540,11 @@ extern int rpl_isnanl (long double x);
     gl_isnan_f (x))
 # endif
 #elif defined GNULIB_POSIXCHECK
-  /* How to override a macro?  */
+# if defined isnan
+_GL_WARN_REAL_FLOATING_DECL (isnan);
+#  undef isnan
+#  define isnan(x) _GL_WARN_REAL_FLOATING_IMPL (isnan, x)
+# endif
 #endif
 
 
@@ -557,7 +600,11 @@ extern int gl_signbitl (long double arg);
     gl_signbitf (x))
 # endif
 #elif defined GNULIB_POSIXCHECK
-  /* How to override a macro?  */
+# if defined signbit
+_GL_WARN_REAL_FLOATING_DECL (signbit);
+#  undef signbit
+#  define signbit(x) _GL_WARN_REAL_FLOATING_IMPL (signbit, x)
+# endif
 #endif
 
 
index 00cbeb7..bd8128b 100644 (file)
@@ -1,4 +1,4 @@
-# math_h.m4 serial 14
+# math_h.m4 serial 15
 dnl Copyright (C) 2007-2010 Free Software Foundation, Inc.
 dnl This file is free software; the Free Software Foundation
 dnl gives unlimited permission to copy and/or distribute it,
@@ -8,6 +8,8 @@ AC_DEFUN([gl_MATH_H],
 [
   AC_REQUIRE([gl_MATH_H_DEFAULTS])
   gl_CHECK_NEXT_HEADERS([math.h])
+  AC_REQUIRE([AC_C_INLINE])
+
   AC_CACHE_CHECK([whether NAN macro works], [gl_cv_header_math_nan_works],
     [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@include <math.h>]],
       [[/* Solaris 10 has a broken definition of NAN.  Other platforms
index 0e2bc0b..dda67df 100644 (file)
@@ -6,9 +6,10 @@ lib/math.in.h
 m4/math_h.m4
 
 Depends-on:
+arg-nonnull
 include_next
 link-warning
-arg-nonnull
+warn-on-use
 
 configure.ac:
 gl_MATH_H
@@ -18,7 +19,7 @@ BUILT_SOURCES += math.h
 
 # We need the following in order to create <math.h> when the system
 # doesn't have one that works with the given compiler.
-math.h: math.in.h $(LINK_WARNING_H) $(ARG_NONNULL_H)
+math.h: math.in.h $(LINK_WARNING_H) $(WARN_ON_USE_H) $(ARG_NONNULL_H)
        $(AM_V_GEN)rm -f $@-t $@ && \
        { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */' && \
          sed -e 's|@''INCLUDE_NEXT_AS_FIRST_DIRECTIVE''@|$(INCLUDE_NEXT_AS_FIRST_DIRECTIVE)|g' \
@@ -81,6 +82,7 @@ math.h: math.in.h $(LINK_WARNING_H) $(ARG_NONNULL_H)
              -e 's|@''REPLACE_TRUNCL''@|$(REPLACE_TRUNCL)|g' \
              -e '/definition of GL_LINK_WARNING/r $(LINK_WARNING_H)' \
              -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \
+             -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \
              < $(srcdir)/math.in.h; \
        } > $@-t && \
        mv $@-t $@