[glib/gnulib.msvc.fixes: 7/9] build: Check for more math.h functions in gnulib
- From: Chun-wei Fan <fanchunwei src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib/gnulib.msvc.fixes: 7/9] build: Check for more math.h functions in gnulib
- Date: Mon, 8 Apr 2019 09:51:40 +0000 (UTC)
commit b532b9cecf977b6e42e1c63503a800495fae1e0c
Author: Chun-wei Fan <fanchunwei src gnome org>
Date: Thu Mar 28 18:27:33 2019 +0800
build: Check for more math.h functions in gnulib
There are now C99 functions that the printf items want to use that may
not be necessarily supported by the math.h that is shipped by the
compiler, such as signbit(), isinf(), isnan() and isfinite() and their
double, long and float counterparts.
This checks for whether these functions are provided by the math.h
shipped by the compiler, and builds the gnulib implementations of them
if they cannot be found. Currently no attempt is made to check whether
these, if available from the compiler's math.h, are compliant with the
specs.
glib/gnulib/isinf.c | 30 +++++++++++++++++++++
glib/gnulib/isnanf-nolibm.h | 40 ++++++++++++++++++++++++++++
glib/gnulib/isnanf.c | 20 ++++++++++++++
glib/gnulib/meson.build | 35 +++++++++++++++++++++----
glib/gnulib/signbitd.c | 64 +++++++++++++++++++++++++++++++++++++++++++++
glib/gnulib/signbitf.c | 64 +++++++++++++++++++++++++++++++++++++++++++++
glib/gnulib/signbitl.c | 64 +++++++++++++++++++++++++++++++++++++++++++++
7 files changed, 312 insertions(+), 5 deletions(-)
---
diff --git a/glib/gnulib/isinf.c b/glib/gnulib/isinf.c
new file mode 100644
index 000000000..e7b44b98d
--- /dev/null
+++ b/glib/gnulib/isinf.c
@@ -0,0 +1,30 @@
+#ifndef _MSC_VER
+#error "This implementation is currently supported for Visual Studio only!"
+#endif
+
+#include "config.h"
+#include <gnulib_math.h>
+#include <float.h>
+#include <math.h>
+
+int
+gl_isinff (float x)
+{
+#if defined (_WIN64) && (defined (_M_X64) || defined (_M_AMD64))
+ return !_finitef (x);
+#else
+ return !_finite (x);
+#endif
+}
+
+int
+gl_isinfd (double x)
+{
+ return !_finite (x);
+}
+
+int
+gl_isinfl (long double x)
+{
+ return gl_isinfd (x);
+}
\ No newline at end of file
diff --git a/glib/gnulib/isnanf-nolibm.h b/glib/gnulib/isnanf-nolibm.h
new file mode 100644
index 000000000..47c52f7f3
--- /dev/null
+++ b/glib/gnulib/isnanf-nolibm.h
@@ -0,0 +1,40 @@
+/* Test for NaN that does not need libm.
+ Copyright (C) 2007-2019 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General PublicLicense as published by
+ the Free Software Foundation; either version 2.1 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 Lesser General PublicLicense for more details.
+
+ You should have received a copy of the GNU Lesser General PublicLicense
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#if HAVE_ISNANF_IN_LIBC
+/* Get declaration of isnan macro or (older) isnanf function. */
+# include <math.h>
+# if __GNUC__ >= 4
+ /* GCC 4.0 and newer provides three built-ins for isnan. */
+# undef isnanf
+# define isnanf(x) __builtin_isnanf ((float)(x))
+# elif defined isnan
+# undef isnanf
+# define isnanf(x) isnan ((float)(x))
+# else
+ /* Get declaration of isnanf(), if not declared in <math.h>. */
+# if defined __sgi
+ /* We can't include <ieeefp.h>, because it conflicts with our definition of
+ isnand. Therefore declare isnanf separately. */
+extern int isnanf (float x);
+# endif
+# endif
+#else
+/* Test whether X is a NaN. */
+# undef isnanf
+# define isnanf rpl_isnanf
+extern int isnanf (float x);
+#endif
diff --git a/glib/gnulib/isnanf.c b/glib/gnulib/isnanf.c
new file mode 100644
index 000000000..8651733a1
--- /dev/null
+++ b/glib/gnulib/isnanf.c
@@ -0,0 +1,20 @@
+/* Test for NaN that does not need libm.
+ Copyright (C) 2007, 2009-2019 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General PublicLicense as published by
+ the Free Software Foundation; either version 2.1 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 Lesser General PublicLicense for more details.
+
+ You should have received a copy of the GNU Lesser General PublicLicense
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible <bruno clisp org>, 2007. */
+
+#define USE_FLOAT
+#include "isnan.c"
diff --git a/glib/gnulib/meson.build b/glib/gnulib/meson.build
index 2d369a6ef..af697f29c 100644
--- a/glib/gnulib/meson.build
+++ b/glib/gnulib/meson.build
@@ -51,10 +51,6 @@ unneeded_funcs = [
'ILOGB',
'ILOGBF',
'ILOGBL',
- 'ISFINITE',
- 'ISINF',
- 'ISNAN',
- 'ISNANF',
'LDEXPF',
'LOG',
'LOG10',
@@ -84,7 +80,6 @@ unneeded_funcs = [
'ROUND',
'ROUNDF',
'ROUNDL',
- 'SIGNBIT',
'SINF',
'SINHF',
'SINL',
@@ -110,9 +105,14 @@ endforeach
needed_funcs = [
'FREXP',
'FREXPL',
+ 'ISFINITE',
+ 'ISINF',
+ 'ISNAN',
'ISNAND',
+ 'ISNANF',
'ISNANL',
'LDEXPL',
+ 'SIGNBIT',
]
foreach f : needed_funcs
@@ -296,6 +296,29 @@ endif
math_h_config.set ('REPLACE_LDEXPL', gl_cv_func_ldexpl_works ? 0 : 1)
math_h_config.set ('HAVE_DECL_LDEXPL', gl_cv_func_ldexpl_decl ? 0 : 1)
+inf_tmpl = '''#include <math.h>
+ double x;
+ int main () {return @0@ (x);}
+ '''
+
+other_needed_math_sources = []
+# Some compilers may not have isfinite, isinf available
+foreach f: ['isfinite', 'isinf', 'isnan', 'isnanf', 'signbit']
+ links = cc.links (inf_tmpl.format('@0@'.format(f)),
+ dependencies : [libm])
+ math_h_config.set ('HAVE_@0@'.format(f.to_upper()), links ? 1 : 0)
+ math_h_config.set ('HAVE_@0@_IN_LIBC'.format(f.to_upper()), links ? 1 : 0)
+ math_h_config.set ('REPLACE_@0@'.format(f.to_upper()), links ? 0 : 1)
+ set_variable ('have_@0@'.format(f), links)
+ if not links
+ if f == 'signbit'
+ other_needed_math_sources += [ 'signbitd.c', 'signbitf.c', 'signbitl.c' ]
+ elif f != 'isfinite' and f != 'isnan'
+ other_needed_math_sources += [ '@0@.c'.format(f) ]
+ endif
+ endif
+endforeach
+
math_h = configure_file (input: 'gnulib_math.h.in',
output: 'gnulib_math.h',
configuration: math_h_config)
@@ -309,6 +332,8 @@ if not gl_cv_func_frexpl_works
gnulib_sources += ['frexpl.c']
endif
+gnulib_sources += other_needed_math_sources
+
gnulib_lib = static_library('gnulib', gnulib_sources,
dependencies : [libm],
include_directories : [configinc, glibinc, include_directories ('.')],
diff --git a/glib/gnulib/signbitd.c b/glib/gnulib/signbitd.c
new file mode 100644
index 000000000..7b20f9b2c
--- /dev/null
+++ b/glib/gnulib/signbitd.c
@@ -0,0 +1,64 @@
+/* signbit() macro: Determine the sign bit of a floating-point number.
+ Copyright (C) 2007-2019 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General PublicLicense as published by
+ the Free Software Foundation; either version 2.1 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 Lesser General PublicLicense for more details.
+
+ You should have received a copy of the GNU Lesser General PublicLicense
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <math.h>
+
+#include <string.h>
+#include "isnand-nolibm.h"
+#include "float+.h"
+
+#ifdef gl_signbitd_OPTIMIZED_MACRO
+# undef gl_signbitd
+#endif
+
+int
+gl_signbitd (double arg)
+{
+#if defined DBL_SIGNBIT_WORD && defined DBL_SIGNBIT_BIT
+ /* The use of a union to extract the bits of the representation of a
+ 'long double' is safe in practice, despite of the "aliasing rules" of
+ C99, because the GCC docs say
+ "Even with '-fstrict-aliasing', type-punning is allowed, provided the
+ memory is accessed through the union type."
+ and similarly for other compilers. */
+# define NWORDS \
+ ((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+ union { double value; unsigned int word[NWORDS]; } m;
+ m.value = arg;
+ return (m.word[DBL_SIGNBIT_WORD] >> DBL_SIGNBIT_BIT) & 1;
+#elif HAVE_COPYSIGN_IN_LIBC
+ return copysign (1.0, arg) < 0;
+#else
+ /* This does not do the right thing for NaN, but this is irrelevant for
+ most use cases. */
+ if (isnand (arg))
+ return 0;
+ if (arg < 0.0)
+ return 1;
+ else if (arg == 0.0)
+ {
+ /* Distinguish 0.0 and -0.0. */
+ static double plus_zero = 0.0;
+ double arg_mem = arg;
+ return (memcmp (&plus_zero, &arg_mem, SIZEOF_DBL) != 0);
+ }
+ else
+ return 0;
+#endif
+}
diff --git a/glib/gnulib/signbitf.c b/glib/gnulib/signbitf.c
new file mode 100644
index 000000000..57e6ef4c7
--- /dev/null
+++ b/glib/gnulib/signbitf.c
@@ -0,0 +1,64 @@
+/* signbit() macro: Determine the sign bit of a floating-point number.
+ Copyright (C) 2007, 2009-2019 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General PublicLicense as published by
+ the Free Software Foundation; either version 2.1 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 Lesser General PublicLicense for more details.
+
+ You should have received a copy of the GNU Lesser General PublicLicense
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <math.h>
+
+#include <string.h>
+#include "isnanf-nolibm.h"
+#include "float+.h"
+
+#ifdef gl_signbitf_OPTIMIZED_MACRO
+# undef gl_signbitf
+#endif
+
+int
+gl_signbitf (float arg)
+{
+#if defined FLT_SIGNBIT_WORD && defined FLT_SIGNBIT_BIT
+ /* The use of a union to extract the bits of the representation of a
+ 'long double' is safe in practice, despite of the "aliasing rules" of
+ C99, because the GCC docs say
+ "Even with '-fstrict-aliasing', type-punning is allowed, provided the
+ memory is accessed through the union type."
+ and similarly for other compilers. */
+# define NWORDS \
+ ((sizeof (float) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+ union { float value; unsigned int word[NWORDS]; } m;
+ m.value = arg;
+ return (m.word[FLT_SIGNBIT_WORD] >> FLT_SIGNBIT_BIT) & 1;
+#elif HAVE_COPYSIGNF_IN_LIBC
+ return copysignf (1.0f, arg) < 0;
+#else
+ /* This does not do the right thing for NaN, but this is irrelevant for
+ most use cases. */
+ if (isnanf (arg))
+ return 0;
+ if (arg < 0.0f)
+ return 1;
+ else if (arg == 0.0f)
+ {
+ /* Distinguish 0.0f and -0.0f. */
+ static float plus_zero = 0.0f;
+ float arg_mem = arg;
+ return (memcmp (&plus_zero, &arg_mem, SIZEOF_FLT) != 0);
+ }
+ else
+ return 0;
+#endif
+}
diff --git a/glib/gnulib/signbitl.c b/glib/gnulib/signbitl.c
new file mode 100644
index 000000000..b1714aadc
--- /dev/null
+++ b/glib/gnulib/signbitl.c
@@ -0,0 +1,64 @@
+/* signbit() macro: Determine the sign bit of a floating-point number.
+ Copyright (C) 2007, 2009-2019 Free Software Foundation, Inc.
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General PublicLicense as published by
+ the Free Software Foundation; either version 2.1 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 Lesser General PublicLicense for more details.
+
+ You should have received a copy of the GNU Lesser General PublicLicense
+ along with this program. If not, see <https://www.gnu.org/licenses/>. */
+
+#include <config.h>
+
+/* Specification. */
+#include <math.h>
+
+#include <string.h>
+#include "isnanl-nolibm.h"
+#include "float+.h"
+
+#ifdef gl_signbitl_OPTIMIZED_MACRO
+# undef gl_signbitl
+#endif
+
+int
+gl_signbitl (long double arg)
+{
+#if defined LDBL_SIGNBIT_WORD && defined LDBL_SIGNBIT_BIT
+ /* The use of a union to extract the bits of the representation of a
+ 'long double' is safe in practice, despite of the "aliasing rules" of
+ C99, because the GCC docs say
+ "Even with '-fstrict-aliasing', type-punning is allowed, provided the
+ memory is accessed through the union type."
+ and similarly for other compilers. */
+# define NWORDS \
+ ((sizeof (long double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
+ union { long double value; unsigned int word[NWORDS]; } m;
+ m.value = arg;
+ return (m.word[LDBL_SIGNBIT_WORD] >> LDBL_SIGNBIT_BIT) & 1;
+#elif HAVE_COPYSIGNL_IN_LIBC
+ return copysignl (1.0L, arg) < 0;
+#else
+ /* This does not do the right thing for NaN, but this is irrelevant for
+ most use cases. */
+ if (isnanl (arg))
+ return 0;
+ if (arg < 0.0L)
+ return 1;
+ else if (arg == 0.0L)
+ {
+ /* Distinguish 0.0L and -0.0L. */
+ static long double plus_zero = 0.0L;
+ long double arg_mem = arg;
+ return (memcmp (&plus_zero, &arg_mem, SIZEOF_LDBL) != 0);
+ }
+ else
+ return 0;
+#endif
+}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]