mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-01-14 00:06:24 +01:00
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.
This commit is contained in:
parent
a1fbeb3e4f
commit
b532b9cecf
30
glib/gnulib/isinf.c
Normal file
30
glib/gnulib/isinf.c
Normal file
@ -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);
|
||||
}
|
40
glib/gnulib/isnanf-nolibm.h
Normal file
40
glib/gnulib/isnanf-nolibm.h
Normal file
@ -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
|
20
glib/gnulib/isnanf.c
Normal file
20
glib/gnulib/isnanf.c
Normal file
@ -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"
|
@ -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 ('.')],
|
||||
|
64
glib/gnulib/signbitd.c
Normal file
64
glib/gnulib/signbitd.c
Normal file
@ -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
|
||||
}
|
64
glib/gnulib/signbitf.c
Normal file
64
glib/gnulib/signbitf.c
Normal file
@ -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
|
||||
}
|
64
glib/gnulib/signbitl.c
Normal file
64
glib/gnulib/signbitl.c
Normal file
@ -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
|
||||
}
|
Loading…
Reference in New Issue
Block a user