Import Upstream version 2.72.4

This commit is contained in:
evinadmin 2023-07-04 11:23:22 +02:00
commit 4ef3ff9793
2003 changed files with 1332420 additions and 0 deletions

87
glib/gnulib/README Normal file
View file

@ -0,0 +1,87 @@
The files
asnprintf.c
printf-args.c
printf-args.h
printf-parse.c
printf-parse.h
vasnprintf.c
vasnprintf.h
are taken from the vasnprintf module of the GNUlib package, which can
be found at:
http://www.gnu.org/software/gnulib/
All files have been modified to include g-gnulib.h.
vasnprintf.c has also been modified to include support for long long
printing if the system printf doesn't. This code is protected by
#ifndef HAVE_LONG_LONG_FORMAT.
Code has been added to printf-args.[ch], printf-parse.c and vasnprintf.c
to support printing of __int64 values with the I64 format modifier. This
is protected by #ifdef HAVE_INT64_AND_I64.
The files
printf.h
printf.c
g-gnulib.h
have been written by me. printf.[hc] contain implementations of the
remaining functions in the printf family based on vasnprintf.
g-gnulib.h is included by all source files in order to move all
exported functions to the _g_gnulib namespace, replace malloc by
g_malloc and make sure that snprintf is only used if it implements
C99 return value semantics.
Matthias Clasen
November 1, 2003
To update:
* Create an empty directory, put a configure.ac file into it.
* Run gnulib-tool --lgpl=2 --import --lib=libgnu --source-base=lib \
--m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. \
--no-conditional-dependencies --no-libtool --macro-prefix=gl \
isnand-nolibm isnanf-nolibm isnanl-nolibm printf-frexpl \
signbit vasnprintf
* Then pick out the files that are already in glib/gnulib subdirectory
(the rest of the files are not needed):
asnprintf.c
c++defs.h
float+.h
fpucw.h
gnulib_math.h.in (rename from math.in.h)
isnan.c
isnand.c
isnand-nolibm.h
isnanf.c
isnanf-nolibm.h
isnanl.c
isnanl-nolibm.h
printf-args.c
printf-args.h
printf-frexp.c
printf-frexp.h
printf-frexpl.c
printf-frexpl.h
printf-parse.c
printf-parse.h
signbitd.c
signbitf.c
signbitl.c
vasnprintf.c
vasnprintf.h
verify.h
xsize.h
* Then look at the glib-gnulib.patch and re-introduce custom glib changes
contained in that patch.
* If gnulib_math.h.in got some new @variables@, these will have to be
somehow set in meson.build, otherwise meson would warn about them
at configure stage
LRN
June 06, 2018

26
glib/gnulib/arg-nonnull.h Normal file
View file

@ -0,0 +1,26 @@
/* A C macro for declaring that specific arguments must not be NULL.
Copyright (C) 2009-2018 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 Public License 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* _GL_ARG_NONNULL((n,...,m)) tells the compiler and static analyzer tools
that the values passed as arguments n, ..., m must be non-NULL pointers.
n = 1 stands for the first argument, n = 2 for the second argument etc. */
#ifndef _GL_ARG_NONNULL
# if (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) || __GNUC__ > 3
# define _GL_ARG_NONNULL(params) __attribute__ ((__nonnull__ params))
# else
# define _GL_ARG_NONNULL(params)
# endif
#endif

36
glib/gnulib/asnprintf.c Normal file
View file

@ -0,0 +1,36 @@
/* Formatted output to strings.
Copyright (C) 1999, 2002, 2006, 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 Public License as published by
the Free Software Foundation; either version 2.1, 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, see <https://www.gnu.org/licenses/>. */
#include <config.h>
#include "g-gnulib.h"
/* Specification. */
#include "vasnprintf.h"
#include <stdarg.h>
char *
asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
{
va_list args;
char *result;
va_start (args, format);
result = vasnprintf (resultbuf, lengthp, format, args);
va_end (args);
return result;
}

316
glib/gnulib/c++defs.h Normal file
View file

@ -0,0 +1,316 @@
/* C++ compatible function declaration macros.
Copyright (C) 2010-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 Public License 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
#ifndef _GL_CXXDEFS_H
#define _GL_CXXDEFS_H
/* Begin/end the GNULIB_NAMESPACE namespace. */
#if defined __cplusplus && defined GNULIB_NAMESPACE
# define _GL_BEGIN_NAMESPACE namespace GNULIB_NAMESPACE {
# define _GL_END_NAMESPACE }
#else
# define _GL_BEGIN_NAMESPACE
# define _GL_END_NAMESPACE
#endif
/* The three most frequent use cases of these macros are:
* For providing a substitute for a function that is missing on some
platforms, but is declared and works fine on the platforms on which
it exists:
#if @GNULIB_FOO@
# if !@HAVE_FOO@
_GL_FUNCDECL_SYS (foo, ...);
# endif
_GL_CXXALIAS_SYS (foo, ...);
_GL_CXXALIASWARN (foo);
#elif defined GNULIB_POSIXCHECK
...
#endif
* For providing a replacement for a function that exists on all platforms,
but is broken/insufficient and needs to be replaced on some platforms:
#if @GNULIB_FOO@
# if @REPLACE_FOO@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef foo
# define foo rpl_foo
# endif
_GL_FUNCDECL_RPL (foo, ...);
_GL_CXXALIAS_RPL (foo, ...);
# else
_GL_CXXALIAS_SYS (foo, ...);
# endif
_GL_CXXALIASWARN (foo);
#elif defined GNULIB_POSIXCHECK
...
#endif
* For providing a replacement for a function that exists on some platforms
but is broken/insufficient and needs to be replaced on some of them and
is additionally either missing or undeclared on some other platforms:
#if @GNULIB_FOO@
# if @REPLACE_FOO@
# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
# undef foo
# define foo rpl_foo
# endif
_GL_FUNCDECL_RPL (foo, ...);
_GL_CXXALIAS_RPL (foo, ...);
# else
# if !@HAVE_FOO@ or if !@HAVE_DECL_FOO@
_GL_FUNCDECL_SYS (foo, ...);
# endif
_GL_CXXALIAS_SYS (foo, ...);
# endif
_GL_CXXALIASWARN (foo);
#elif defined GNULIB_POSIXCHECK
...
#endif
*/
/* _GL_EXTERN_C declaration;
performs the declaration with C linkage. */
#if defined __cplusplus
# define _GL_EXTERN_C extern "C"
#else
# define _GL_EXTERN_C extern
#endif
/* _GL_FUNCDECL_RPL (func, rettype, parameters_and_attributes);
declares a replacement function, named rpl_func, with the given prototype,
consisting of return type, parameters, and attributes.
Example:
_GL_FUNCDECL_RPL (open, int, (const char *filename, int flags, ...)
_GL_ARG_NONNULL ((1)));
*/
#define _GL_FUNCDECL_RPL(func,rettype,parameters_and_attributes) \
_GL_FUNCDECL_RPL_1 (rpl_##func, rettype, parameters_and_attributes)
#define _GL_FUNCDECL_RPL_1(rpl_func,rettype,parameters_and_attributes) \
_GL_EXTERN_C rettype rpl_func parameters_and_attributes
/* _GL_FUNCDECL_SYS (func, rettype, parameters_and_attributes);
declares the system function, named func, with the given prototype,
consisting of return type, parameters, and attributes.
Example:
_GL_FUNCDECL_SYS (open, int, (const char *filename, int flags, ...)
_GL_ARG_NONNULL ((1)));
*/
#define _GL_FUNCDECL_SYS(func,rettype,parameters_and_attributes) \
_GL_EXTERN_C rettype func parameters_and_attributes
/* _GL_CXXALIAS_RPL (func, rettype, parameters);
declares a C++ alias called GNULIB_NAMESPACE::func
that redirects to rpl_func, if GNULIB_NAMESPACE is defined.
Example:
_GL_CXXALIAS_RPL (open, int, (const char *filename, int flags, ...));
Wrapping rpl_func in an object with an inline conversion operator
avoids a reference to rpl_func unless GNULIB_NAMESPACE::func is
actually used in the program. */
#define _GL_CXXALIAS_RPL(func,rettype,parameters) \
_GL_CXXALIAS_RPL_1 (func, rpl_##func, rettype, parameters)
#if defined __cplusplus && defined GNULIB_NAMESPACE
# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
namespace GNULIB_NAMESPACE \
{ \
static const struct _gl_ ## func ## _wrapper \
{ \
typedef rettype (*type) parameters; \
\
inline operator type () const \
{ \
return ::rpl_func; \
} \
} func = {}; \
} \
_GL_EXTERN_C int _gl_cxxalias_dummy
#else
# define _GL_CXXALIAS_RPL_1(func,rpl_func,rettype,parameters) \
_GL_EXTERN_C int _gl_cxxalias_dummy
#endif
/* _GL_CXXALIAS_RPL_CAST_1 (func, rpl_func, rettype, parameters);
is like _GL_CXXALIAS_RPL_1 (func, rpl_func, rettype, parameters);
except that the C function rpl_func may have a slightly different
declaration. A cast is used to silence the "invalid conversion" error
that would otherwise occur. */
#if defined __cplusplus && defined GNULIB_NAMESPACE
# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
namespace GNULIB_NAMESPACE \
{ \
static const struct _gl_ ## func ## _wrapper \
{ \
typedef rettype (*type) parameters; \
\
inline operator type () const \
{ \
return reinterpret_cast<type>(::rpl_func); \
} \
} func = {}; \
} \
_GL_EXTERN_C int _gl_cxxalias_dummy
#else
# define _GL_CXXALIAS_RPL_CAST_1(func,rpl_func,rettype,parameters) \
_GL_EXTERN_C int _gl_cxxalias_dummy
#endif
/* _GL_CXXALIAS_SYS (func, rettype, parameters);
declares a C++ alias called GNULIB_NAMESPACE::func
that redirects to the system provided function func, if GNULIB_NAMESPACE
is defined.
Example:
_GL_CXXALIAS_SYS (open, int, (const char *filename, int flags, ...));
Wrapping func in an object with an inline conversion operator
avoids a reference to func unless GNULIB_NAMESPACE::func is
actually used in the program. */
#if defined __cplusplus && defined GNULIB_NAMESPACE
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
namespace GNULIB_NAMESPACE \
{ \
static const struct _gl_ ## func ## _wrapper \
{ \
typedef rettype (*type) parameters; \
\
inline operator type () const \
{ \
return ::func; \
} \
} func = {}; \
} \
_GL_EXTERN_C int _gl_cxxalias_dummy
#else
# define _GL_CXXALIAS_SYS(func,rettype,parameters) \
_GL_EXTERN_C int _gl_cxxalias_dummy
#endif
/* _GL_CXXALIAS_SYS_CAST (func, rettype, parameters);
is like _GL_CXXALIAS_SYS (func, rettype, parameters);
except that the C function func may have a slightly different declaration.
A cast is used to silence the "invalid conversion" error that would
otherwise occur. */
#if defined __cplusplus && defined GNULIB_NAMESPACE
# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
namespace GNULIB_NAMESPACE \
{ \
static const struct _gl_ ## func ## _wrapper \
{ \
typedef rettype (*type) parameters; \
\
inline operator type () const \
{ \
return reinterpret_cast<type>(::func); \
} \
} func = {}; \
} \
_GL_EXTERN_C int _gl_cxxalias_dummy
#else
# define _GL_CXXALIAS_SYS_CAST(func,rettype,parameters) \
_GL_EXTERN_C int _gl_cxxalias_dummy
#endif
/* _GL_CXXALIAS_SYS_CAST2 (func, rettype, parameters, rettype2, parameters2);
is like _GL_CXXALIAS_SYS (func, rettype, parameters);
except that the C function is picked among a set of overloaded functions,
namely the one with rettype2 and parameters2. Two consecutive casts
are used to silence the "cannot find a match" and "invalid conversion"
errors that would otherwise occur. */
#if defined __cplusplus && defined GNULIB_NAMESPACE
/* The outer cast must be a reinterpret_cast.
The inner cast: When the function is defined as a set of overloaded
functions, it works as a static_cast<>, choosing the designated variant.
When the function is defined as a single variant, it works as a
reinterpret_cast<>. The parenthesized cast syntax works both ways. */
# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
namespace GNULIB_NAMESPACE \
{ \
static const struct _gl_ ## func ## _wrapper \
{ \
typedef rettype (*type) parameters; \
\
inline operator type () const \
{ \
return reinterpret_cast<type>((rettype2 (*) parameters2)(::func)); \
} \
} func = {}; \
} \
_GL_EXTERN_C int _gl_cxxalias_dummy
#else
# define _GL_CXXALIAS_SYS_CAST2(func,rettype,parameters,rettype2,parameters2) \
_GL_EXTERN_C int _gl_cxxalias_dummy
#endif
/* _GL_CXXALIASWARN (func);
causes a warning to be emitted when ::func is used but not when
GNULIB_NAMESPACE::func is used. func must be defined without overloaded
variants. */
#if defined __cplusplus && defined GNULIB_NAMESPACE
# define _GL_CXXALIASWARN(func) \
_GL_CXXALIASWARN_1 (func, GNULIB_NAMESPACE)
# define _GL_CXXALIASWARN_1(func,namespace) \
_GL_CXXALIASWARN_2 (func, namespace)
/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
we enable the warning only when not optimizing. */
# if !__OPTIMIZE__
# define _GL_CXXALIASWARN_2(func,namespace) \
_GL_WARN_ON_USE (func, \
"The symbol ::" #func " refers to the system function. " \
"Use " #namespace "::" #func " instead.")
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
# define _GL_CXXALIASWARN_2(func,namespace) \
extern __typeof__ (func) func
# else
# define _GL_CXXALIASWARN_2(func,namespace) \
_GL_EXTERN_C int _gl_cxxalias_dummy
# endif
#else
# define _GL_CXXALIASWARN(func) \
_GL_EXTERN_C int _gl_cxxalias_dummy
#endif
/* _GL_CXXALIASWARN1 (func, rettype, parameters_and_attributes);
causes a warning to be emitted when the given overloaded variant of ::func
is used but not when GNULIB_NAMESPACE::func is used. */
#if defined __cplusplus && defined GNULIB_NAMESPACE
# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
_GL_CXXALIASWARN1_1 (func, rettype, parameters_and_attributes, \
GNULIB_NAMESPACE)
# define _GL_CXXALIASWARN1_1(func,rettype,parameters_and_attributes,namespace) \
_GL_CXXALIASWARN1_2 (func, rettype, parameters_and_attributes, namespace)
/* To work around GCC bug <https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43881>,
we enable the warning only when not optimizing. */
# if !__OPTIMIZE__
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
_GL_WARN_ON_USE_CXX (func, rettype, parameters_and_attributes, \
"The symbol ::" #func " refers to the system function. " \
"Use " #namespace "::" #func " instead.")
# elif __GNUC__ >= 3 && GNULIB_STRICT_CHECKING
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
extern __typeof__ (func) func
# else
# define _GL_CXXALIASWARN1_2(func,rettype,parameters_and_attributes,namespace) \
_GL_EXTERN_C int _gl_cxxalias_dummy
# endif
#else
# define _GL_CXXALIASWARN1(func,rettype,parameters_and_attributes) \
_GL_EXTERN_C int _gl_cxxalias_dummy
#endif
#endif /* _GL_CXXDEFS_H */

147
glib/gnulib/float+.h Normal file
View file

@ -0,0 +1,147 @@
/* Supplemental information about the floating-point formats.
Copyright (C) 2007, 2009-2019 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2007.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1, 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, see <https://www.gnu.org/licenses/>. */
#ifndef _FLOATPLUS_H
#define _FLOATPLUS_H
#include <float.h>
#include <limits.h>
/* Number of bits in the mantissa of a floating-point number, including the
"hidden bit". */
#if FLT_RADIX == 2
# define FLT_MANT_BIT FLT_MANT_DIG
# define DBL_MANT_BIT DBL_MANT_DIG
# define LDBL_MANT_BIT LDBL_MANT_DIG
#elif FLT_RADIX == 4
# define FLT_MANT_BIT (FLT_MANT_DIG * 2)
# define DBL_MANT_BIT (DBL_MANT_DIG * 2)
# define LDBL_MANT_BIT (LDBL_MANT_DIG * 2)
#elif FLT_RADIX == 16
# define FLT_MANT_BIT (FLT_MANT_DIG * 4)
# define DBL_MANT_BIT (DBL_MANT_DIG * 4)
# define LDBL_MANT_BIT (LDBL_MANT_DIG * 4)
#endif
/* Bit mask that can be used to mask the exponent, as an unsigned number. */
#define FLT_EXP_MASK ((FLT_MAX_EXP - FLT_MIN_EXP) | 7)
#define DBL_EXP_MASK ((DBL_MAX_EXP - DBL_MIN_EXP) | 7)
#define LDBL_EXP_MASK ((LDBL_MAX_EXP - LDBL_MIN_EXP) | 7)
/* Number of bits used for the exponent of a floating-point number, including
the exponent's sign. */
#define FLT_EXP_BIT \
(FLT_EXP_MASK < 0x100 ? 8 : \
FLT_EXP_MASK < 0x200 ? 9 : \
FLT_EXP_MASK < 0x400 ? 10 : \
FLT_EXP_MASK < 0x800 ? 11 : \
FLT_EXP_MASK < 0x1000 ? 12 : \
FLT_EXP_MASK < 0x2000 ? 13 : \
FLT_EXP_MASK < 0x4000 ? 14 : \
FLT_EXP_MASK < 0x8000 ? 15 : \
FLT_EXP_MASK < 0x10000 ? 16 : \
FLT_EXP_MASK < 0x20000 ? 17 : \
FLT_EXP_MASK < 0x40000 ? 18 : \
FLT_EXP_MASK < 0x80000 ? 19 : \
FLT_EXP_MASK < 0x100000 ? 20 : \
FLT_EXP_MASK < 0x200000 ? 21 : \
FLT_EXP_MASK < 0x400000 ? 22 : \
FLT_EXP_MASK < 0x800000 ? 23 : \
FLT_EXP_MASK < 0x1000000 ? 24 : \
FLT_EXP_MASK < 0x2000000 ? 25 : \
FLT_EXP_MASK < 0x4000000 ? 26 : \
FLT_EXP_MASK < 0x8000000 ? 27 : \
FLT_EXP_MASK < 0x10000000 ? 28 : \
FLT_EXP_MASK < 0x20000000 ? 29 : \
FLT_EXP_MASK < 0x40000000 ? 30 : \
FLT_EXP_MASK <= 0x7fffffff ? 31 : \
32)
#define DBL_EXP_BIT \
(DBL_EXP_MASK < 0x100 ? 8 : \
DBL_EXP_MASK < 0x200 ? 9 : \
DBL_EXP_MASK < 0x400 ? 10 : \
DBL_EXP_MASK < 0x800 ? 11 : \
DBL_EXP_MASK < 0x1000 ? 12 : \
DBL_EXP_MASK < 0x2000 ? 13 : \
DBL_EXP_MASK < 0x4000 ? 14 : \
DBL_EXP_MASK < 0x8000 ? 15 : \
DBL_EXP_MASK < 0x10000 ? 16 : \
DBL_EXP_MASK < 0x20000 ? 17 : \
DBL_EXP_MASK < 0x40000 ? 18 : \
DBL_EXP_MASK < 0x80000 ? 19 : \
DBL_EXP_MASK < 0x100000 ? 20 : \
DBL_EXP_MASK < 0x200000 ? 21 : \
DBL_EXP_MASK < 0x400000 ? 22 : \
DBL_EXP_MASK < 0x800000 ? 23 : \
DBL_EXP_MASK < 0x1000000 ? 24 : \
DBL_EXP_MASK < 0x2000000 ? 25 : \
DBL_EXP_MASK < 0x4000000 ? 26 : \
DBL_EXP_MASK < 0x8000000 ? 27 : \
DBL_EXP_MASK < 0x10000000 ? 28 : \
DBL_EXP_MASK < 0x20000000 ? 29 : \
DBL_EXP_MASK < 0x40000000 ? 30 : \
DBL_EXP_MASK <= 0x7fffffff ? 31 : \
32)
#define LDBL_EXP_BIT \
(LDBL_EXP_MASK < 0x100 ? 8 : \
LDBL_EXP_MASK < 0x200 ? 9 : \
LDBL_EXP_MASK < 0x400 ? 10 : \
LDBL_EXP_MASK < 0x800 ? 11 : \
LDBL_EXP_MASK < 0x1000 ? 12 : \
LDBL_EXP_MASK < 0x2000 ? 13 : \
LDBL_EXP_MASK < 0x4000 ? 14 : \
LDBL_EXP_MASK < 0x8000 ? 15 : \
LDBL_EXP_MASK < 0x10000 ? 16 : \
LDBL_EXP_MASK < 0x20000 ? 17 : \
LDBL_EXP_MASK < 0x40000 ? 18 : \
LDBL_EXP_MASK < 0x80000 ? 19 : \
LDBL_EXP_MASK < 0x100000 ? 20 : \
LDBL_EXP_MASK < 0x200000 ? 21 : \
LDBL_EXP_MASK < 0x400000 ? 22 : \
LDBL_EXP_MASK < 0x800000 ? 23 : \
LDBL_EXP_MASK < 0x1000000 ? 24 : \
LDBL_EXP_MASK < 0x2000000 ? 25 : \
LDBL_EXP_MASK < 0x4000000 ? 26 : \
LDBL_EXP_MASK < 0x8000000 ? 27 : \
LDBL_EXP_MASK < 0x10000000 ? 28 : \
LDBL_EXP_MASK < 0x20000000 ? 29 : \
LDBL_EXP_MASK < 0x40000000 ? 30 : \
LDBL_EXP_MASK <= 0x7fffffff ? 31 : \
32)
/* Number of bits used for a floating-point number: the mantissa (not
counting the "hidden bit", since it may or may not be explicit), the
exponent, and the sign. */
#define FLT_TOTAL_BIT ((FLT_MANT_BIT - 1) + FLT_EXP_BIT + 1)
#define DBL_TOTAL_BIT ((DBL_MANT_BIT - 1) + DBL_EXP_BIT + 1)
#define LDBL_TOTAL_BIT ((LDBL_MANT_BIT - 1) + LDBL_EXP_BIT + 1)
/* Number of bytes used for a floating-point number.
This can be smaller than the 'sizeof'. For example, on i386 systems,
'long double' most often have LDBL_MANT_BIT = 64, LDBL_EXP_BIT = 16, hence
LDBL_TOTAL_BIT = 80 bits, i.e. 10 bytes of consecutive memory, but
sizeof (long double) = 12 or = 16. */
#define SIZEOF_FLT ((FLT_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT)
#define SIZEOF_DBL ((DBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT)
#define SIZEOF_LDBL ((LDBL_TOTAL_BIT + CHAR_BIT - 1) / CHAR_BIT)
/* Verify that SIZEOF_FLT <= sizeof (float) etc. */
typedef int verify_sizeof_flt[SIZEOF_FLT <= sizeof (float) ? 1 : -1];
typedef int verify_sizeof_dbl[SIZEOF_DBL <= sizeof (double) ? 1 : - 1];
typedef int verify_sizeof_ldbl[SIZEOF_LDBL <= sizeof (long double) ? 1 : - 1];
#endif /* _FLOATPLUS_H */

108
glib/gnulib/fpucw.h Normal file
View file

@ -0,0 +1,108 @@
/* Manipulating the FPU control word. -*- coding: utf-8 -*-
Copyright (C) 2007-2019 Free Software Foundation, Inc.
Written by Bruno Haible <bruno@clisp.org>, 2007.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
#ifndef _FPUCW_H
#define _FPUCW_H
/* The i386 floating point hardware (the 387 compatible FPU, not the modern
SSE/SSE2 hardware) has a controllable rounding precision. It is specified
through the 'PC' bits in the FPU control word ('fctrl' register). (See
the GNU libc i386 <fpu_control.h> header for details.)
On some platforms, such as Linux or Solaris, the default precision setting
is set to "extended precision". This means that 'long double' instructions
operate correctly, but 'double' computations often produce slightly
different results as on strictly IEEE 754 conforming systems.
On some platforms, such as NetBSD, the default precision is set to
"double precision". This means that 'long double' instructions will operate
only as 'double', i.e. lead to wrong results. Similarly on FreeBSD 6.4, at
least for the division of 'long double' numbers.
The FPU control word is under control of the application, i.e. it is
not required to be set either way by the ABI. (In fact, the i386 ABI
https://www.linux-mips.org/pub/linux/mips/doc/ABI/abi386-4.pdf page 3-12 = page 38
is not clear about it. But in any case, gcc treats the control word
like a "preserved" register: it emits code that assumes that the control
word is preserved across calls, and it restores the control word at the
end of functions that modify it.)
See Vincent Lefèvre's page https://www.vinc17.net/research/extended.en.html
for a good explanation.
See http://www.uwsg.iu.edu/hypermail/linux/kernel/0103.0/0453.html for
some argumentation which setting should be the default. */
/* This header file provides the following facilities:
fpucw_t integral type holding the value of 'fctrl'
FPU_PC_MASK bit mask denoting the precision control
FPU_PC_DOUBLE precision control for 53 bits mantissa
FPU_PC_EXTENDED precision control for 64 bits mantissa
GET_FPUCW () yields the current FPU control word
SET_FPUCW (word) sets the FPU control word
DECL_LONG_DOUBLE_ROUNDING variable declaration for
BEGIN/END_LONG_DOUBLE_ROUNDING
BEGIN_LONG_DOUBLE_ROUNDING () starts a sequence of instructions with
'long double' safe operation precision
END_LONG_DOUBLE_ROUNDING () ends a sequence of instructions with
'long double' safe operation precision
*/
/* Inline assembler like this works only with GNU C. */
#if (defined __i386__ || defined __x86_64__) && defined __GNUC__
typedef unsigned short fpucw_t; /* glibc calls this fpu_control_t */
# define FPU_PC_MASK 0x0300
# define FPU_PC_DOUBLE 0x200 /* glibc calls this _FPU_DOUBLE */
# define FPU_PC_EXTENDED 0x300 /* glibc calls this _FPU_EXTENDED */
# define GET_FPUCW() \
({ fpucw_t _cw; \
__asm__ __volatile__ ("fnstcw %0" : "=m" (*&_cw)); \
_cw; \
})
# define SET_FPUCW(word) \
(void)({ fpucw_t _ncw = (word); \
__asm__ __volatile__ ("fldcw %0" : : "m" (*&_ncw)); \
})
# define DECL_LONG_DOUBLE_ROUNDING \
fpucw_t oldcw;
# define BEGIN_LONG_DOUBLE_ROUNDING() \
(void)(oldcw = GET_FPUCW (), \
SET_FPUCW ((oldcw & ~FPU_PC_MASK) | FPU_PC_EXTENDED))
# define END_LONG_DOUBLE_ROUNDING() \
SET_FPUCW (oldcw)
#else
typedef unsigned int fpucw_t;
# define FPU_PC_MASK 0
# define FPU_PC_DOUBLE 0
# define FPU_PC_EXTENDED 0
# define GET_FPUCW() 0
# define SET_FPUCW(word) (void)(word)
# define DECL_LONG_DOUBLE_ROUNDING
# define BEGIN_LONG_DOUBLE_ROUNDING()
# define END_LONG_DOUBLE_ROUNDING()
#endif
#endif /* _FPUCW_H */

22
glib/gnulib/frexp.c Normal file
View file

@ -0,0 +1,22 @@
#include <config.h>
/* Specification. */
#include <gnulib_math.h>
#include <float.h>
#include "isnand-nolibm.h"
double rpl_frexp (double x, int *expptr)
{
if (x == 0.0 || x == -0.0)
{
*expptr = x;
return x;
}
else if (isnan (x))
return x;
else if (isinf (x))
return x;
#undef frexp
return frexp (x, expptr);
}

21
glib/gnulib/frexpl.c Normal file
View file

@ -0,0 +1,21 @@
#include <config.h>
#include <gnulib_math.h>
#include <float.h>
#include <math.h>
long double rpl_frexpl (long double x, int *expptr)
{
if (x == 0.0L || x == -0.0L)
{
*expptr = x;
return x;
}
else if (isnanl (x))
return x;
else if (isinf (x))
return x;
#ifndef _MSC_VER
#undef frexpl
#endif
return frexpl (x, expptr);
}

46
glib/gnulib/g-gnulib.h Normal file
View file

@ -0,0 +1,46 @@
/* GLIB - Library of useful routines for C programming
* Copyright (C) 2003 Matthias Clasen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __G_GNULIB_H__
#include "config.h"
#include <stdlib.h>
#include "glib/glib.h"
/* Private namespace for gnulib functions */
#define asnprintf _g_gnulib_asnprintf
#define vasnprintf _g_gnulib_vasnprintf
#define printf_parse _g_gnulib_printf_parse
#define printf_fetchargs _g_gnulib_printf_fetchargs
/* Use GLib memory allocation */
#undef malloc
#undef realloc
#undef free
#define malloc g_malloc
#define realloc g_realloc
#define free g_free
/* Ensure only C99 snprintf gets used */
#undef HAVE_SNPRINTF
#ifdef HAVE_C99_SNPRINTF
#define HAVE_SNPRINTF 1
#else
#define HAVE_SNPRINTF 0
#endif
#endif /* __G_GNULIB_H__ */

View file

@ -0,0 +1,101 @@
# Copyright (C) 2002-2004, 2006-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
double_exponent_test = '''
#include <float.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#define NWORDS \
((sizeof (double) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
typedef union { double value; unsigned int word[NWORDS]; } memory_double;
static unsigned int ored_words[NWORDS];
static unsigned int anded_words[NWORDS];
static void add_to_ored_words (double x)
{
memory_double m;
size_t i;
/* Clear it first, in case sizeof (double) < sizeof (memory_double). */
memset (&m, 0, sizeof (memory_double));
m.value = x;
for (i = 0; i < NWORDS; i++)
{
ored_words[i] |= m.word[i];
anded_words[i] &= m.word[i];
}
}
int main ()
{
size_t j;
FILE *fp = stdout;
if (fp == NULL)
return 1;
for (j = 0; j < NWORDS; j++)
anded_words[j] = ~ (unsigned int) 0;
add_to_ored_words (0.25);
add_to_ored_words (0.5);
add_to_ored_words (1.0);
add_to_ored_words (2.0);
add_to_ored_words (4.0);
/* Remove bits that are common (e.g. if representation of the first mantissa
bit is explicit). */
for (j = 0; j < NWORDS; j++)
ored_words[j] &= ~anded_words[j];
/* Now find the nonzero word. */
for (j = 0; j < NWORDS; j++)
if (ored_words[j] != 0)
break;
if (j < NWORDS)
{
size_t i;
for (i = j + 1; i < NWORDS; i++)
if (ored_words[i] != 0)
{
fprintf (fp, "-1/-1");
return (fclose (fp) != 0);
}
for (i = 0; ; i++)
if ((ored_words[j] >> i) & 1)
{
fprintf (fp, "%d/%d", (int) j, (int) i);
return (fclose (fp) != 0);
}
}
fprintf (fp, "-1/-1");
return (fclose (fp) != 0);
}
'''
gl_cv_cc_double_expbit0_word = -1
gl_cv_cc_double_expbit0_bit = -1
if not meson.is_cross_build() or meson.has_exe_wrapper()
run_result = cc.run(double_exponent_test,
name : 'where to find the exponent in a \'double\'')
if run_result.compiled() and run_result.returncode() == 0
out = run_result.stdout ().split ('/')
if out.length () == 2
gl_cv_cc_double_expbit0_word = out[0].to_int ()
gl_cv_cc_double_expbit0_bit = out[1].to_int ()
endif
endif
else
# On ARM, there are two 'double' floating-point formats, used by
# different sets of instructions: The older FPA instructions assume
# that they are stored in big-endian word order, while the words
# (like integer types) are stored in little-endian byte order.
# The newer VFP instructions assume little-endian order
# consistently.
if (cc.get_define ('arm') == '' and
cc.get_define ('__arm') == '' and
cc.get_define ('__arm__') == '')
gl_cv_cc_double_expbit0_bit = 20
if host_machine.endian () == 'big'
gl_cv_cc_double_expbit0_word = 0
else
gl_cv_cc_double_expbit0_word = 1
endif
endif
endif

View file

@ -0,0 +1,110 @@
# Copyright (C) 2002-2004, 2006-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
frexp_test = '''
#define HAVE_DECL_ALARM 0
#include <float.h>
#include <math.h>
#include <string.h>
#if HAVE_DECL_ALARM
# include <signal.h>
# include <unistd.h>
#endif
/* HP cc on HP-UX 10.20 has a bug with the constant expression -0.0.
ICC 10.0 has a bug when optimizing the expression -zero.
The expression -DBL_MIN * DBL_MIN does not work when cross-compiling
to PowerPC on Mac OS X 10.5. */
#if defined __hpux || defined __sgi || defined __ICC
static double
compute_minus_zero (void)
{
return -DBL_MIN * DBL_MIN;
}
# define minus_zero compute_minus_zero ()
#else
double minus_zero = -0.0;
#endif
int main()
{
int result = 0;
int i;
volatile double x;
double zero = 0.0;
#if HAVE_DECL_ALARM
/* NeXTstep 3.3 frexp() runs into an endless loop when called on an infinite
number. Let the test fail in this case. */
signal (SIGALRM, SIG_DFL);
alarm (5);
#endif
/* Test on denormalized numbers. */
for (i = 1, x = 1.0; i >= DBL_MIN_EXP; i--, x *= 0.5)
;
if (x > 0.0)
{
int exp;
double y = frexp (x, &exp);
/* On machines with IEEE754 arithmetic: x = 1.11254e-308, exp = -1022.
On NetBSD: y = 0.75. Correct: y = 0.5. */
if (y != 0.5)
result |= 1;
}
/* Test on infinite numbers. */
x = 1.0 / zero;
{
int exp;
double y = frexp (x, &exp);
if (y != x)
result |= 2;
}
/* Test on negative zero. */
x = minus_zero;
{
int exp;
double y = frexp (x, &exp);
if (memcmp (&y, &x, sizeof x))
result |= 4;
}
x = 0.0;
{
int exp;
double y = frexp (x, &exp);
if (memcmp (&y, &x, sizeof x))
result |= 8;
}
return result;
}'''
if not meson.is_cross_build() or meson.has_exe_wrapper()
run_result = cc.run(frexp_test,
name : 'frexp works',
dependencies : [libm])
rc = run_result.returncode()
gl_cv_func_frexp_works = run_result.compiled() and rc == 0
gl_cv_func_frexp_broken_beyond_repair = not gl_cv_func_frexp_works
# bit 1 is not set
if (rc == 1 or rc == 3 or rc == 5 or rc == 9 or
rc == 7 or rc == 11 or rc == 13)
gl_cv_func_frexp_broken_beyond_repair = true
else
gl_cv_func_frexp_broken_beyond_repair = false
endif
else
if (host_system.startswith ('netbsd') or
host_system.startswith ('irix'))
gl_cv_func_frexp_works = false
gl_cv_func_frexp_broken_beyond_repair = true
elif host_system == 'windows'
if cc.get_id () == 'msvc' or cc.get_id() == 'clang-cl'
gl_cv_func_frexp_works = true
gl_cv_func_frexp_broken_beyond_repair = false
else
gl_cv_func_frexp_works = false
gl_cv_func_frexp_broken_beyond_repair = false
endif
else
gl_cv_func_frexp_works = true
gl_cv_func_frexp_broken_beyond_repair = false
endif
endif

View file

@ -0,0 +1,141 @@
# Copyright (C) 2007-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
frexpl_test = '''
#include <float.h>
#include <math.h>
/* Override the values of <float.h>, like done in float.in.h. */
#if defined __i386__ && (defined __BEOS__ || defined __OpenBSD__)
# undef LDBL_MIN_EXP
# define LDBL_MIN_EXP (-16381)
#endif
#if defined __i386__ && (defined __FreeBSD__ || defined __DragonFly__)
# undef LDBL_MIN_EXP
# define LDBL_MIN_EXP (-16381)
#endif
#if (defined _ARCH_PPC || defined _POWER) && defined _AIX && (LDBL_MANT_DIG == 106) && defined __GNUC__
# undef LDBL_MIN_EXP
# define LDBL_MIN_EXP DBL_MIN_EXP
#endif
#if defined __sgi && (LDBL_MANT_DIG >= 106)
# if defined __GNUC__
# undef LDBL_MIN_EXP
# define LDBL_MIN_EXP DBL_MIN_EXP
# endif
#endif
extern
#ifdef __cplusplus
"C"
#endif
#if !defined (_MSC_VER) || defined (TEST_FREXPL_DECL)
long double frexpl (long double, int *);
#endif
int main()
{
int result = 0;
volatile long double x;
/* Test on finite numbers that fails on AIX 5.1. */
x = 16.0L;
{
int exp = -9999;
frexpl (x, &exp);
if (exp != 5)
result |= 1;
}
/* Test on finite numbers that fails on Mac OS X 10.4, because its frexpl
function returns an invalid (incorrectly normalized) value: it returns
y = { 0x3fe028f5, 0xc28f5c28, 0x3c9eb851, 0xeb851eb8 }
but the correct result is
0.505L = { 0x3fe028f5, 0xc28f5c29, 0xbc547ae1, 0x47ae1480 } */
x = 1.01L;
{
int exp = -9999;
long double y = frexpl (x, &exp);
if (!(exp == 1 && y == 0.505L))
result |= 2;
}
/* Test on large finite numbers. This fails on BeOS at i = 16322, while
LDBL_MAX_EXP = 16384.
In the loop end test, we test x against Infinity, rather than comparing
i with LDBL_MAX_EXP, because BeOS <float.h> has a wrong LDBL_MAX_EXP. */
{
int i;
for (i = 1, x = 1.0L; x != x + x; i++, x *= 2.0L)
{
int exp = -9999;
frexpl (x, &exp);
if (exp != i)
{
result |= 4;
break;
}
}
}
/* Test on denormalized numbers. */
{
int i;
for (i = 1, x = 1.0L; i >= LDBL_MIN_EXP; i--, x *= 0.5L)
;
if (x > 0.0L)
{
int exp;
long double y = frexpl (x, &exp);
/* On machines with IEEE854 arithmetic: x = 1.68105e-4932,
exp = -16382, y = 0.5. On Mac OS X 10.5: exp = -16384, y = 0.5. */
if (exp != LDBL_MIN_EXP - 1)
result |= 8;
}
}
/* Test on infinite numbers. */
/* The dance around 0.0L is an attempt to prevent MSVC from erroring out */
x = 0.0L;
x = 1.0L / x;
{
int exp;
long double y = frexpl (x, &exp);
if (y != x)
result |= 16;
}
return result;
}
'''
if not meson.is_cross_build() or meson.has_exe_wrapper()
run_result = cc.run(frexpl_test,
name : 'frexpl works',
dependencies : [libm])
rc = run_result.returncode()
gl_cv_func_frexpl_works = run_result.compiled() and rc == 0
gl_cv_func_frexpl_broken_beyond_repair = not gl_cv_func_frexpl_works
# bit 1 is not set
if (rc == 16)
gl_cv_func_frexpl_broken_beyond_repair = false
else
gl_cv_func_frexpl_broken_beyond_repair = true
endif
else
if (host_system.startswith ('aix') or
host_system.startswith ('beos') or
host_system.startswith ('irix'))
gl_cv_func_frexpl_works = false
gl_cv_func_frexpl_broken_beyond_repair = true
elif (host_system == 'windows')
gl_cv_func_frexpl_works = false
gl_cv_func_frexpl_broken_beyond_repair = false
else
gl_cv_func_frexpl_works = true
gl_cv_func_frexpl_broken_beyond_repair = false
endif
endif
frexpl_test_decl = '''
#define TEST_FREXPL_DECL 1
''' + frexpl_test
build_result = cc.compiles(frexpl_test_decl,
name : 'frexpl prototype can be re-listed')
gl_cv_func_frexpl_decl = build_result

View file

@ -0,0 +1,57 @@
# Copyright (C) 2002-2004, 2006-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
ldexpl_test = '''
#include <math.h>
extern
#ifdef __cplusplus
"C"
#endif
#if !defined (_MSC_VER) || defined (TEST_LDEXPL_DECL)
long double ldexpl (long double, int);
#endif
int main()
{
int result = 0;
{
volatile long double x = 1.0;
volatile long double y = ldexpl (x, -1);
if (y != 0.5L)
result |= 1;
}
{
volatile long double x = 1.73205L;
volatile long double y = ldexpl (x, 0);
if (y != x)
result |= 2;
}
return result;
}
'''
if not meson.is_cross_build() or meson.has_exe_wrapper()
run_result = cc.run(ldexpl_test,
name : 'ldexpl works',
dependencies : [libm])
gl_cv_func_ldexpl_works = run_result.compiled() and run_result.returncode() == 0
else
if host_system.startswith ('aix')
gl_cv_func_ldexpl_works = false
elif host_system == 'windows'
gl_cv_func_ldexpl_works = true
else
gl_cv_func_ldexpl_works = true
endif
endif
ldexpl_test_decl = '''
#define TEST_LDEXPL_DECL 1
''' + ldexpl_test
build_result = cc.compiles(ldexpl_test_decl,
name : 'ldexpl prototype can be re-listed')
gl_cv_func_ldexpl_decl = build_result

View file

@ -0,0 +1,94 @@
# Copyright (C) 2002-2004, 2006-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# Test whether the *printf family of functions supports the 'a' and 'A'
# conversion specifier for hexadecimal output of floating-point numbers.
# (ISO C99, POSIX:2001)
# Result is gl_cv_func_printf_directive_a.
printf_directive_a_test = '''
#include <stdio.h>
#include <string.h>
static char buf[100];
static double zero = 0.0;
int main ()
{
int result = 0;
if (sprintf (buf, "%a %d", 3.1416015625, 33, 44, 55) < 0
|| (strcmp (buf, "0x1.922p+1 33") != 0
&& strcmp (buf, "0x3.244p+0 33") != 0
&& strcmp (buf, "0x6.488p-1 33") != 0
&& strcmp (buf, "0xc.91p-2 33") != 0))
result |= 1;
if (sprintf (buf, "%A %d", -3.1416015625, 33, 44, 55) < 0
|| (strcmp (buf, "-0X1.922P+1 33") != 0
&& strcmp (buf, "-0X3.244P+0 33") != 0
&& strcmp (buf, "-0X6.488P-1 33") != 0
&& strcmp (buf, "-0XC.91P-2 33") != 0))
result |= 2;
/* This catches a FreeBSD 6.1 bug: it doesn't round. */
if (sprintf (buf, "%.2a %d", 1.51, 33, 44, 55) < 0
|| (strcmp (buf, "0x1.83p+0 33") != 0
&& strcmp (buf, "0x3.05p-1 33") != 0
&& strcmp (buf, "0x6.0ap-2 33") != 0
&& strcmp (buf, "0xc.14p-3 33") != 0))
result |= 4;
/* This catches a Mac OS X 10.12.4 (Darwin 16.5) bug: it doesn't round. */
if (sprintf (buf, "%.0a %d", 1.51, 33, 44, 55) < 0
|| (strcmp (buf, "0x2p+0 33") != 0
&& strcmp (buf, "0x3p-1 33") != 0
&& strcmp (buf, "0x6p-2 33") != 0
&& strcmp (buf, "0xcp-3 33") != 0))
result |= 4;
/* This catches a FreeBSD 6.1 bug. See
<https://lists.gnu.org/r/bug-gnulib/2007-04/msg00107.html> */
if (sprintf (buf, "%010a %d", 1.0 / zero, 33, 44, 55) < 0
|| buf[0] == '0')
result |= 8;
/* This catches a Mac OS X 10.3.9 (Darwin 7.9) bug. */
if (sprintf (buf, "%.1a", 1.999) < 0
|| (strcmp (buf, "0x1.0p+1") != 0
&& strcmp (buf, "0x2.0p+0") != 0
&& strcmp (buf, "0x4.0p-1") != 0
&& strcmp (buf, "0x8.0p-2") != 0))
result |= 16;
/* This catches the same Mac OS X 10.3.9 (Darwin 7.9) bug and also a
glibc 2.4 bug <https://sourceware.org/bugzilla/show_bug.cgi?id=2908>. */
if (sprintf (buf, "%.1La", 1.999L) < 0
|| (strcmp (buf, "0x1.0p+1") != 0
&& strcmp (buf, "0x2.0p+0") != 0
&& strcmp (buf, "0x4.0p-1") != 0
&& strcmp (buf, "0x8.0p-2") != 0))
result |= 32;
return result;
}
'''
glibc_printf_directive_a_test = '''
#include <features.h>
#ifdef __GNU_LIBRARY__
#if ((__GLIBC__ == 2 && __GLIBC_MINOR__ >= 5) || (__GLIBC__ > 2)) && !defined __UCLIBC__
#else
#error Too old glibc
#endif
#else
#error Not glibc
#endif
int main () { return 0; }
'''
if not meson.is_cross_build() or meson.has_exe_wrapper()
run_result = cc.run(printf_directive_a_test,
name : 'printf supports the \'a\' and \'A\' directives')
gl_cv_func_printf_directive_a = run_result.compiled() and run_result.returncode() == 0
else
if host_system == 'linux'
gl_cv_func_printf_directive_a = cc.compiles(glibc_printf_directive_a_test)
elif host_system == 'windows'
gl_cv_func_printf_directive_a = false
else
gl_cv_func_printf_directive_a = false
endif
endif

View file

@ -0,0 +1,81 @@
# Copyright (C) 2002-2004, 2006-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# Test whether the *printf family of functions supports the %F format
# directive. (ISO C99, POSIX:2001)
# Result is gl_cv_func_printf_directive_f.
printf_directive_f_test = '''
#include <stdio.h>
#include <string.h>
static char buf[100];
static double zero = 0.0;
int main ()
{
int result = 0;
if (sprintf (buf, "%F %d", 1234567.0, 33, 44, 55) < 0
|| strcmp (buf, "1234567.000000 33") != 0)
result |= 1;
if (sprintf (buf, "%F", 1.0 / zero) < 0
|| (strcmp (buf, "INF") != 0 && strcmp (buf, "INFINITY") != 0))
result |= 2;
/* This catches a Cygwin 1.5.x bug. */
if (sprintf (buf, "%.F", 1234.0) < 0
|| strcmp (buf, "1234") != 0)
result |= 4;
return result;
}
'''
if not meson.is_cross_build() or meson.has_exe_wrapper()
run_result = cc.run(printf_directive_f_test,
name : 'printf supports the \'F\' directive')
gl_cv_func_printf_directive_f = run_result.compiled() and run_result.returncode() == 0
else
if host_system in ['linux', 'android']
gl_cv_func_printf_directive_f = true
elif (host_system.startswith ('freebsd1') or
host_system.startswith ('freebsd2') or
host_system.startswith ('freebsd3') or
host_system.startswith ('freebsd4') or
host_system.startswith ('freebsd5'))
gl_cv_func_printf_directive_f = false
elif (host_system.startswith ('freebsd') or
host_system.startswith ('kfreebsd'))
gl_cv_func_printf_directive_f = true
elif (host_system.startswith ('darwin1') or
host_system.startswith ('darwin2') or
host_system.startswith ('darwin3') or
host_system.startswith ('darwin4') or
host_system.startswith ('darwin5') or
host_system.startswith ('darwin6'))
gl_cv_func_printf_directive_f = false
elif host_system.startswith ('darwin')
gl_cv_func_printf_directive_f = true
# Split the check from the main if statement, ensure that
# some meson versions (old ones, presumable) won't try
# to evaluate host_system[9] when it's shorter than that
elif host_system.startswith ('solaris2.')
if (host_system[9] == '1' and
'0123456789'.contains (host_system[10])) or
('23456789'.contains (host_system[9]) == '1' and
'0123456789'.contains (host_system[10]))
gl_cv_func_printf_directive_f = true
elif host_system.startswith ('solaris')
gl_cv_func_printf_directive_f = false
endif
elif host_system.startswith ('solaris')
gl_cv_func_printf_directive_f = false
elif host_system == 'windows'
# Guess yes on MSVC, no on mingw.
if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl'
gl_cv_func_printf_directive_f = true
else
gl_cv_func_printf_directive_f = false
endif
else
gl_cv_func_printf_directive_f = false
endif
endif

View file

@ -0,0 +1,82 @@
# Copyright (C) 2002-2004, 2006-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# Test whether the *printf family of functions supports the %ls format
# directive and in particular, when a precision is specified, whether
# the functions stop converting the wide string argument when the number
# of bytes that have been produced by this conversion equals or exceeds
# the precision.
# Result is gl_cv_func_printf_directive_ls.
printf_directive_ls_test = '''
/* Tru64 with Desktop Toolkit C has a bug: <stdio.h> must be included before
<wchar.h>.
BSD/OS 4.0.1 has a bug: <stddef.h>, <stdio.h> and <time.h> must be
included before <wchar.h>. */
#include <stddef.h>
#include <stdio.h>
#include <time.h>
#include <wchar.h>
#include <string.h>
int main ()
{
int result = 0;
char buf[100];
/* Test whether %ls works at all.
This test fails on OpenBSD 4.0, IRIX 6.5, Solaris 2.6, Haiku, but not on
Cygwin 1.5. */
{
static const wchar_t wstring[] = { 'a', 'b', 'c', 0 };
buf[0] = '\0';
if (sprintf (buf, "%ls", wstring) < 0
|| strcmp (buf, "abc") != 0)
result |= 1;
}
/* This test fails on IRIX 6.5, Solaris 2.6, Cygwin 1.5, Haiku (with an
assertion failure inside libc), but not on OpenBSD 4.0. */
{
static const wchar_t wstring[] = { 'a', 0 };
buf[0] = '\0';
if (sprintf (buf, "%ls", wstring) < 0
|| strcmp (buf, "a") != 0)
result |= 2;
}
/* Test whether precisions in %ls are supported as specified in ISO C 99
section 7.19.6.1:
"If a precision is specified, no more than that many bytes are written
(including shift sequences, if any), and the array shall contain a
null wide character if, to equal the multibyte character sequence
length given by the precision, the function would need to access a
wide character one past the end of the array."
This test fails on Solaris 10. */
{
static const wchar_t wstring[] = { 'a', 'b', (wchar_t) 0xfdfdfdfd, 0 };
buf[0] = '\0';
if (sprintf (buf, "%.2ls", wstring) < 0
|| strcmp (buf, "ab") != 0)
result |= 8;
}
return result;
}
'''
if not meson.is_cross_build() or meson.has_exe_wrapper()
run_result = cc.run(printf_directive_ls_test,
name : 'printf supports the \'ls\' directive')
gl_cv_func_printf_directive_ls = run_result.compiled() and run_result.returncode() == 0
else
if (host_system.startswith ('openbsd') or
host_system.startswith ('irix') or
host_system.startswith ('solaris') or
host_system.startswith ('cygwin') or
host_system.startswith ('beos') or
host_system.startswith ('haiku'))
gl_cv_func_printf_directive_ls = false
elif host_system == 'windows'
gl_cv_func_printf_directive_ls = true
else
gl_cv_func_printf_directive_ls = true
endif
endif

View file

@ -0,0 +1,73 @@
# Copyright (C) 2002-2004, 2006-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# Test whether the *printf family of functions recovers gracefully in case
# of an out-of-memory condition, or whether it crashes the entire program.
# Result is gl_cv_func_printf_enomem.
printf_enomem_test = '''
#include <stdio.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <errno.h>
int main()
{
struct rlimit limit;
int ret;
nocrash_init ();
/* Some printf implementations allocate temporary space with malloc. */
/* On BSD systems, malloc() is limited by RLIMIT_DATA. */
#ifdef RLIMIT_DATA
if (getrlimit (RLIMIT_DATA, &limit) < 0)
return 77;
if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
limit.rlim_max = 5000000;
limit.rlim_cur = limit.rlim_max;
if (setrlimit (RLIMIT_DATA, &limit) < 0)
return 77;
#endif
/* On Linux systems, malloc() is limited by RLIMIT_AS. */
#ifdef RLIMIT_AS
if (getrlimit (RLIMIT_AS, &limit) < 0)
return 77;
if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
limit.rlim_max = 5000000;
limit.rlim_cur = limit.rlim_max;
if (setrlimit (RLIMIT_AS, &limit) < 0)
return 77;
#endif
/* Some printf implementations allocate temporary space on the stack. */
#ifdef RLIMIT_STACK
if (getrlimit (RLIMIT_STACK, &limit) < 0)
return 77;
if (limit.rlim_max == RLIM_INFINITY || limit.rlim_max > 5000000)
limit.rlim_max = 5000000;
limit.rlim_cur = limit.rlim_max;
if (setrlimit (RLIMIT_STACK, &limit) < 0)
return 77;
#endif
ret = printf ("%.5000000f", 1.0);
return !(ret == 5000002 || (ret < 0 && errno == ENOMEM));
}
'''
if not meson.is_cross_build() or meson.has_exe_wrapper()
run_result = cc.run(printf_enomem_test,
name : 'printf survives out-of-memory conditions')
gl_cv_func_printf_enomem = run_result.compiled() and run_result.returncode() == 0
else
# If we don't know, assume the worst.
gl_cv_func_printf_enomem = false
if (host_system == 'linux' or
host_system == 'solaris' or
host_system == 'sunos' or
host_system == 'aix' or
host_system == 'irix' or
host_system == 'beos' or
host_system == 'haiku')
gl_cv_func_printf_enomem = true
endif
endif

View file

@ -0,0 +1,37 @@
# Copyright (C) 2002-2004, 2006-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# Test whether the *printf family of functions supports the - flag correctly.
# (ISO C99.) See
# <https://lists.gnu.org/r/bug-coreutils/2008-02/msg00035.html>
# Result is gl_cv_func_printf_flag_leftadjust.
printf_flag_grouping_test = '''
#include <stdio.h>
#include <string.h>
static char buf[100];
int main ()
{
if (sprintf (buf, "%'d %d", 1234567, 99) < 0
|| buf[strlen (buf) - 1] != '9')
return 1;
return 0;
}'''
if not meson.is_cross_build() or meson.has_exe_wrapper()
run_result = cc.run(printf_flag_grouping_test,
name : 'printf supports the grouping flag')
gl_cv_func_printf_flag_grouping = run_result.compiled() and run_result.returncode() == 0
else
if host_system.startswith ('cygwin')
gl_cv_func_printf_flag_grouping = false
elif host_system.startswith ('netbsd')
gl_cv_func_printf_flag_grouping = false
elif host_system == 'windows'
gl_cv_func_printf_flag_grouping = false
else
gl_cv_func_printf_flag_grouping = true
endif
endif

View file

@ -0,0 +1,39 @@
# Copyright (C) 2002-2004, 2006-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# Test whether the *printf family of functions supports the - flag correctly.
# (ISO C99.) See
# <https://lists.gnu.org/r/bug-coreutils/2008-02/msg00035.html>
# Result is gl_cv_func_printf_flag_leftadjust.
printf_flag_leftadjust_test = '''
#include <stdio.h>
#include <string.h>
static char buf[100];
int main ()
{
/* Check that a '-' flag is not annihilated by a negative width. */
if (sprintf (buf, "a%-*sc", -3, "b") < 0
|| strcmp (buf, "ab c") != 0)
return 1;
return 0;
}
'''
if not meson.is_cross_build() or meson.has_exe_wrapper()
run_result = cc.run(printf_flag_leftadjust_test,
name : 'printf supports the left-adjust flag correctly')
gl_cv_func_printf_flag_leftadjust = run_result.compiled() and run_result.returncode() == 0
else
if host_system.startswith ('hpux11')
gl_cv_func_printf_flag_leftadjust = true
elif host_system.startswith ('hpux')
gl_cv_func_printf_flag_leftadjust = false
elif host_system == 'windows'
gl_cv_func_printf_flag_leftadjust = true
else
gl_cv_func_printf_flag_leftadjust = true
endif
endif

View file

@ -0,0 +1,40 @@
# Copyright (C) 2002-2004, 2006-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# Test whether the *printf family of functions supports padding of non-finite
# values with the 0 flag correctly. (ISO C99 + TC1 + TC2.) See
# <https://lists.gnu.org/r/bug-gnulib/2007-04/msg00107.html>
# Result is gl_cv_func_printf_flag_zero.
printf_flag_zero_test = '''
#include <stdio.h>
#include <string.h>
static char buf[100];
static double zero = 0.0;
int main ()
{
if (sprintf (buf, "%010f", 1.0 / zero, 33, 44, 55) < 0
|| (strcmp (buf, " inf") != 0
&& strcmp (buf, " infinity") != 0))
return 1;
return 0;
}
'''
if not meson.is_cross_build() or meson.has_exe_wrapper()
run_result = cc.run(printf_flag_zero_test,
name : 'printf supports the zero flag correctly')
gl_cv_func_printf_flag_zero = run_result.compiled() and run_result.returncode() == 0
else
if host_system in ['linux', 'android']
gl_cv_func_printf_flag_zero = true
elif host_system.startswith ('beos')
gl_cv_func_printf_flag_zero = true
elif host_system == 'windows'
gl_cv_func_printf_flag_zero = false
else
gl_cv_func_printf_flag_zero = false
endif
endif

View file

@ -0,0 +1,135 @@
# Copyright (C) 2002-2004, 2006-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# Test whether the *printf family of functions supports infinite and NaN
# 'double' arguments and negative zero arguments in the %f, %e, %g
# directives. (ISO C99, POSIX:2001)
# Result is gl_cv_func_printf_infinite.
printf_infinite_double_test = '''
#include <stdio.h>
#include <string.h>
static int
strisnan (const char *string, size_t start_index, size_t end_index)
{
if (start_index < end_index)
{
if (string[start_index] == '-')
start_index++;
if (start_index + 3 <= end_index
&& memcmp (string + start_index, "nan", 3) == 0)
{
start_index += 3;
if (start_index == end_index
|| (string[start_index] == '(' && string[end_index - 1] == ')'))
return 1;
}
}
return 0;
}
static int
have_minus_zero ()
{
static double plus_zero = 0.0;
double minus_zero = - plus_zero;
return memcmp (&plus_zero, &minus_zero, sizeof (double)) != 0;
}
static char buf[10000];
static double zero = 0.0;
int main ()
{
int result = 0;
if (sprintf (buf, "%f", 1.0 / zero) < 0
|| (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
result |= 1;
if (sprintf (buf, "%f", -1.0 / zero) < 0
|| (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
result |= 1;
if (sprintf (buf, "%f", zero / zero) < 0
|| !strisnan (buf, 0, strlen (buf)))
result |= 2;
if (sprintf (buf, "%e", 1.0 / zero) < 0
|| (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
result |= 4;
if (sprintf (buf, "%e", -1.0 / zero) < 0
|| (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
result |= 4;
if (sprintf (buf, "%e", zero / zero) < 0
|| !strisnan (buf, 0, strlen (buf)))
result |= 8;
if (sprintf (buf, "%g", 1.0 / zero) < 0
|| (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
result |= 16;
if (sprintf (buf, "%g", -1.0 / zero) < 0
|| (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
result |= 16;
if (sprintf (buf, "%g", zero / zero) < 0
|| !strisnan (buf, 0, strlen (buf)))
result |= 32;
/* This test fails on HP-UX 10.20. */
if (have_minus_zero ())
if (sprintf (buf, "%g", - zero) < 0
|| strcmp (buf, "-0") != 0)
result |= 64;
return result;
}
'''
if not meson.is_cross_build() or meson.has_exe_wrapper()
run_result = cc.run(printf_infinite_double_test,
name : 'printf supports infinite \'double\' arguments')
gl_cv_func_printf_infinite = run_result.compiled() and run_result.returncode() == 0
else
if host_system in ['linux', 'android']
gl_cv_func_printf_infinite = true
elif (host_system.startswith ('freebsd1') or
host_system.startswith ('freebsd2') or
host_system.startswith ('freebsd3') or
host_system.startswith ('freebsd4') or
host_system.startswith ('freebsd5'))
gl_cv_func_printf_infinite = false
elif (host_system.startswith ('freebsd') or
host_system.startswith ('kfreebsd'))
gl_cv_func_printf_infinite = true
elif (host_system.startswith ('darwin1') or
host_system.startswith ('darwin2') or
host_system.startswith ('darwin3') or
host_system.startswith ('darwin4') or
host_system.startswith ('darwin5'))
gl_cv_func_printf_infinite = false
elif host_system.startswith ('darwin')
gl_cv_func_printf_infinite = true
elif (host_system.startswith ('hpux7') or
host_system.startswith ('hpux8') or
host_system.startswith ('hpux9') or
host_system.startswith ('hpux10'))
gl_cv_func_printf_infinite = false
elif host_system.startswith ('hpux')
gl_cv_func_printf_infinite = true
elif (host_system.startswith ('netbsd1') or
host_system.startswith ('netbsd2') or
host_system.startswith ('netbsdelf1') or
host_system.startswith ('netbsdelf2') or
host_system.startswith ('netbsdaout1') or
host_system.startswith ('netbsdaout2') or
host_system.startswith ('netbsdcoff1') or
host_system.startswith ('netbsdcoff2'))
gl_cv_func_printf_infinite = false
elif host_system.startswith ('netbsd')
gl_cv_func_printf_infinite = true
elif host_system.startswith ('beos')
gl_cv_func_printf_infinite = true
elif host_system.startswith ('windows')
# Guess yes on MSVC, no on mingw.
if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl'
gl_cv_func_printf_infinite = true
else
gl_cv_func_printf_infinite = false
endif
else
# If we don't know, assume the worst.
gl_cv_func_printf_infinite = false
endif
endif

View file

@ -0,0 +1,208 @@
# Copyright (C) 2002-2004, 2006-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# Test whether the *printf family of functions supports infinite and NaN
# 'long double' arguments in the %f, %e, %g directives. (ISO C99, POSIX:2001)
# Result is gl_cv_func_printf_infinite_long_double.
# The user can set or unset the variable gl_printf_safe to indicate
# that he wishes a safe handling of non-IEEE-754 'long double' values.
check_print_safe = ''
if get_variable ('gl_printf_safe', false)
check_print_safe = '''
#if ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
/* 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 union { unsigned int word[4]; long double value; } x =
{ LDBL80_WORDS (0xFFFF, 0xC3333333, 0x00000000) };
if (sprintf (buf, "%Lf", x.value) < 0
|| !strisnan (buf, 0, strlen (buf)))
result |= 2;
if (sprintf (buf, "%Le", x.value) < 0
|| !strisnan (buf, 0, strlen (buf)))
result |= 2;
if (sprintf (buf, "%Lg", x.value) < 0
|| !strisnan (buf, 0, strlen (buf)))
result |= 2;
}
{
/* Signalling NaN. */
static union { unsigned int word[4]; long double value; } x =
{ LDBL80_WORDS (0xFFFF, 0x83333333, 0x00000000) };
if (sprintf (buf, "%Lf", x.value) < 0
|| !strisnan (buf, 0, strlen (buf)))
result |= 2;
if (sprintf (buf, "%Le", x.value) < 0
|| !strisnan (buf, 0, strlen (buf)))
result |= 2;
if (sprintf (buf, "%Lg", x.value) < 0
|| !strisnan (buf, 0, strlen (buf)))
result |= 2;
}
{ /* Pseudo-NaN. */
static union { unsigned int word[4]; long double value; } x =
{ LDBL80_WORDS (0xFFFF, 0x40000001, 0x00000000) };
if (sprintf (buf, "%Lf", x.value) <= 0)
result |= 4;
if (sprintf (buf, "%Le", x.value) <= 0)
result |= 4;
if (sprintf (buf, "%Lg", x.value) <= 0)
result |= 4;
}
{ /* Pseudo-Infinity. */
static union { unsigned int word[4]; long double value; } x =
{ LDBL80_WORDS (0xFFFF, 0x00000000, 0x00000000) };
if (sprintf (buf, "%Lf", x.value) <= 0)
result |= 8;
if (sprintf (buf, "%Le", x.value) <= 0)
result |= 8;
if (sprintf (buf, "%Lg", x.value) <= 0)
result |= 8;
}
{ /* Pseudo-Zero. */
static union { unsigned int word[4]; long double value; } x =
{ LDBL80_WORDS (0x4004, 0x00000000, 0x00000000) };
if (sprintf (buf, "%Lf", x.value) <= 0)
result |= 16;
if (sprintf (buf, "%Le", x.value) <= 0)
result |= 16;
if (sprintf (buf, "%Lg", x.value) <= 0)
result |= 16;
}
{ /* Unnormalized number. */
static union { unsigned int word[4]; long double value; } x =
{ LDBL80_WORDS (0x4000, 0x63333333, 0x00000000) };
if (sprintf (buf, "%Lf", x.value) <= 0)
result |= 32;
if (sprintf (buf, "%Le", x.value) <= 0)
result |= 32;
if (sprintf (buf, "%Lg", x.value) <= 0)
result |= 32;
}
{ /* Pseudo-Denormal. */
static union { unsigned int word[4]; long double value; } x =
{ LDBL80_WORDS (0x0000, 0x83333333, 0x00000000) };
if (sprintf (buf, "%Lf", x.value) <= 0)
result |= 64;
if (sprintf (buf, "%Le", x.value) <= 0)
result |= 64;
if (sprintf (buf, "%Lg", x.value) <= 0)
result |= 64;
}
#endif
'''
endif
printf_infinite_long_double_test = '''
#include <float.h>
#include <stdio.h>
#include <string.h>
static int
strisnan (const char *string, size_t start_index, size_t end_index)
{
if (start_index < end_index)
{
if (string[start_index] == '-')
start_index++;
if (start_index + 3 <= end_index
&& memcmp (string + start_index, "nan", 3) == 0)
{
start_index += 3;
if (start_index == end_index
|| (string[start_index] == '(' && string[end_index - 1] == ')'))
return 1;
}
}
return 0;
}
static char buf[10000];
static long double zeroL = 0.0L;
int main ()
{
int result = 0;
nocrash_init();
if (sprintf (buf, "%Lf", 1.0L / zeroL) < 0
|| (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
result |= 1;
if (sprintf (buf, "%Lf", -1.0L / zeroL) < 0
|| (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
result |= 1;
if (sprintf (buf, "%Lf", zeroL / zeroL) < 0
|| !strisnan (buf, 0, strlen (buf)))
result |= 1;
if (sprintf (buf, "%Le", 1.0L / zeroL) < 0
|| (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
result |= 1;
if (sprintf (buf, "%Le", -1.0L / zeroL) < 0
|| (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
result |= 1;
if (sprintf (buf, "%Le", zeroL / zeroL) < 0
|| !strisnan (buf, 0, strlen (buf)))
result |= 1;
if (sprintf (buf, "%Lg", 1.0L / zeroL) < 0
|| (strcmp (buf, "inf") != 0 && strcmp (buf, "infinity") != 0))
result |= 1;
if (sprintf (buf, "%Lg", -1.0L / zeroL) < 0
|| (strcmp (buf, "-inf") != 0 && strcmp (buf, "-infinity") != 0))
result |= 1;
if (sprintf (buf, "%Lg", zeroL / zeroL) < 0
|| !strisnan (buf, 0, strlen (buf)))
result |= 1;
''' + check_print_safe + '''
return result;
}
'''
if gl_cv_func_printf_long_double
if not meson.is_cross_build() or meson.has_exe_wrapper()
run_result = cc.run(printf_infinite_long_double_test,
name : 'printf supports infinite \'long double\' arguments')
gl_cv_func_printf_infinite_long_double = (run_result.compiled() and run_result.returncode() == 0)
else
if host_machine.cpu_family() == 'x86_64'
gl_cv_func_printf_infinite_long_double = false
else
if host_system in ['linux', 'android']
gl_cv_func_printf_infinite_long_double = true
elif (host_system.startswith ('freebsd1') or
host_system.startswith ('freebsd2') or
host_system.startswith ('freebsd3') or
host_system.startswith ('freebsd4') or
host_system.startswith ('freebsd5'))
gl_cv_func_printf_infinite_long_double = false
elif (host_system.startswith ('freebsd') or
host_system.startswith ('kfreebsd'))
gl_cv_func_printf_infinite_long_double = true
elif (host_system.startswith ('hpux7') or
host_system.startswith ('hpux8') or
host_system.startswith ('hpux9') or
host_system.startswith ('hpux10'))
gl_cv_func_printf_infinite = false
elif host_system.startswith ('hpux')
gl_cv_func_printf_infinite_long_double = true
elif host_system == 'windows'
# Guess yes on MSVC, no on mingw.
if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl'
gl_cv_func_printf_infinite_long_double = true
else
gl_cv_func_printf_infinite_long_double = false
endif
else
gl_cv_func_printf_infinite_long_double = false
endif
endif
endif
endif

View file

@ -0,0 +1,50 @@
# Copyright (C) 2002-2004, 2006-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# Test whether the *printf family of functions supports 'long double'
# arguments together with the 'L' size specifier. (ISO C99, POSIX:2001)
# Result is gl_cv_func_printf_long_double.
printf_long_double_test = '''
#include <stdio.h>
#include <string.h>
static char buf[10000];
int main ()
{
int result = 0;
buf[0] = '\0';
if (sprintf (buf, "%Lf %d", 1.75L, 33, 44, 55) < 0
|| strcmp (buf, "1.750000 33") != 0)
result |= 1;
buf[0] = '\0';
if (sprintf (buf, "%Le %d", 1.75L, 33, 44, 55) < 0
|| strcmp (buf, "1.750000e+00 33") != 0)
result |= 2;
buf[0] = '\0';
if (sprintf (buf, "%Lg %d", 1.75L, 33, 44, 55) < 0
|| strcmp (buf, "1.75 33") != 0)
result |= 4;
return result;
}
'''
if not meson.is_cross_build() or meson.has_exe_wrapper()
run_result = cc.run(printf_long_double_test,
name : 'printf supports \'long double\' arguments')
gl_cv_func_printf_long_double = run_result.compiled() and run_result.returncode() == 0
else
if host_system.startswith ('beos')
gl_cv_func_printf_long_double = false
elif host_system == 'windows'
# Guess yes on MSVC, no on mingw.
if cc.get_id() == 'msvc' or cc.get_id() == 'clang-cl'
gl_cv_func_printf_long_double = true
else
gl_cv_func_printf_long_double = false
endif
else
gl_cv_func_printf_long_double = true
endif
endif

View file

@ -0,0 +1,54 @@
# Copyright (C) 2002-2004, 2006-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# Test whether the *printf family of functions supports large precisions.
# On mingw, precisions larger than 512 are treated like 512, in integer,
# floating-point or pointer output. On Solaris 10/x86, precisions larger
# than 510 in floating-point output crash the program. On Solaris 10/SPARC,
# precisions larger than 510 in floating-point output yield wrong results.
# On AIX 7.1, precisions larger than 998 in floating-point output yield
# wrong results. On BeOS, precisions larger than 1044 crash the program.
# Result is gl_cv_func_printf_precision.
printf_precision_test = '''
#include <stdio.h>
#include <string.h>
static char buf[5000];
int main ()
{
int result = 0;
#ifdef __BEOS__
/* On BeOS, this would crash and show a dialog box. Avoid the crash. */
return 1;
#endif
if (sprintf (buf, "%.4000d %d", 1, 33, 44) < 4000 + 3)
result |= 1;
if (sprintf (buf, "%.4000f %d", 1.0, 33, 44) < 4000 + 5)
result |= 2;
if (sprintf (buf, "%.511f %d", 1.0, 33, 44) < 511 + 5
|| buf[0] != '1')
result |= 4;
if (sprintf (buf, "%.999f %d", 1.0, 33, 44) < 999 + 5
|| buf[0] != '1')
result |= 4;
return result;
}
'''
if not meson.is_cross_build() or meson.has_exe_wrapper()
run_result = cc.run(printf_precision_test,
name : 'printf supports large precisions')
gl_cv_func_printf_precision = run_result.compiled() and run_result.returncode() == 0
else
gl_cv_func_printf_precision = true
# Guess no only on Solaris, native Windows, and BeOS systems.
if (host_system == 'windows' or
host_system == 'beos' or
host_system == 'haiku' or
host_system == 'sunos' or
host_system == 'solaris')
gl_cv_func_printf_precision = false
endif
endif

View file

@ -0,0 +1,24 @@
# Copyright (C) 2002-2004, 2006-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# gl_LONG_DOUBLE_VS_DOUBLE
# determines whether 'long double' and 'double' have the same representation.
# The currently known platforms where this is the case are:
# Linux/HPPA, Minix 3.1.8, AIX 5, AIX 6 and 7 with xlc, MSVC 9.
long_double_eq_double_test = '''
#include <float.h>
int main ()
{
typedef int check[sizeof (long double) == sizeof (double)
&& LDBL_MANT_DIG == DBL_MANT_DIG
&& LDBL_MAX_EXP == DBL_MAX_EXP
&& LDBL_MIN_EXP == DBL_MIN_EXP
? 1 : -1];
return check;
}
'''
gl_cv_long_double_equals_double = cc.compiles(long_double_eq_double_test)

View file

@ -0,0 +1,103 @@
# Copyright (C) 2002-2004, 2006-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# Copyright 2012-2018 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
gl_extern_inline = '''
/* Please see the Gnulib manual for how to use these macros.
Suppress extern inline with HP-UX cc, as it appears to be broken; see
<https://lists.gnu.org/r/bug-texinfo/2013-02/msg00030.html>.
Suppress extern inline with Sun C in standards-conformance mode, as it
mishandles inline functions that call each other. E.g., for 'inline void f
(void) { } inline void g (void) { f (); }', c99 incorrectly complains
'reference to static identifier "f" in extern inline function'.
This bug was observed with Sun C 5.12 SunOS_i386 2011/11/16.
Suppress extern inline (with or without __attribute__ ((__gnu_inline__)))
on configurations that mistakenly use 'static inline' to implement
functions or macros in standard C headers like <ctype.h>. For example,
if isdigit is mistakenly implemented via a static inline function,
a program containing an extern inline function that calls isdigit
may not work since the C standard prohibits extern inline functions
from calling static functions. This bug is known to occur on:
OS X 10.8 and earlier; see:
https://lists.gnu.org/r/bug-gnulib/2012-12/msg00023.html
DragonFly; see
http://muscles.dragonflybsd.org/bulk/bleeding-edge-potential/latest-per-pkg/ah-tty-0.3.12.log
FreeBSD; see:
https://lists.gnu.org/r/bug-gnulib/2014-07/msg00104.html
OS X 10.9 has a macro __header_inline indicating the bug is fixed for C and
for clang but remains for g++; see <https://trac.macports.org/ticket/41033>.
Assume DragonFly and FreeBSD will be similar. */
#if (((defined __APPLE__ && defined __MACH__) \
|| defined __DragonFly__ || defined __FreeBSD__) \
&& (defined __header_inline \
? (defined __cplusplus && defined __GNUC_STDC_INLINE__ \
&& ! defined __clang__) \
: ((! defined _DONT_USE_CTYPE_INLINE_ \
&& (defined __GNUC__ || defined __cplusplus)) \
|| (defined _FORTIFY_SOURCE && 0 < _FORTIFY_SOURCE \
&& defined __GNUC__ && ! defined __cplusplus))))
# define _GL_EXTERN_INLINE_STDHEADER_BUG
#endif
#if ((__GNUC__ \
? defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__ \
: (199901L <= __STDC_VERSION__ \
&& !defined __HP_cc \
&& !defined __PGI \
&& !(defined __SUNPRO_C && __STDC__))) \
&& !defined _GL_EXTERN_INLINE_STDHEADER_BUG)
# define _GL_INLINE inline
# define _GL_EXTERN_INLINE extern inline
# define _GL_EXTERN_INLINE_IN_USE
#elif (2 < __GNUC__ + (7 <= __GNUC_MINOR__) && !defined __STRICT_ANSI__ \
&& !defined _GL_EXTERN_INLINE_STDHEADER_BUG)
# if defined __GNUC_GNU_INLINE__ && __GNUC_GNU_INLINE__
/* __gnu_inline__ suppresses a GCC 4.2 diagnostic. */
# define _GL_INLINE extern inline __attribute__ ((__gnu_inline__)) __attribute__ ((always_inline))
# else
# define _GL_INLINE extern inline
# endif
# define _GL_EXTERN_INLINE extern
# define _GL_EXTERN_INLINE_IN_USE
#else
# define _GL_INLINE static _GL_UNUSED
# define _GL_EXTERN_INLINE static _GL_UNUSED
#endif
/* In GCC 4.6 (inclusive) to 5.1 (exclusive),
suppress bogus "no previous prototype for 'FOO'"
and "no previous declaration for 'FOO'" diagnostics,
when FOO is an inline function in the header; see
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54113> and
<https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63877>. */
#if __GNUC__ == 4 && 6 <= __GNUC_MINOR__
# if defined __GNUC_STDC_INLINE__ && __GNUC_STDC_INLINE__
# define _GL_INLINE_HEADER_CONST_PRAGMA
# else
# define _GL_INLINE_HEADER_CONST_PRAGMA \
_Pragma ("GCC diagnostic ignored \"-Wsuggest-attribute=const\"")
# endif
# define _GL_INLINE_HEADER_BEGIN \
_Pragma ("GCC diagnostic push") \
_Pragma ("GCC diagnostic ignored \"-Wmissing-prototypes\"") \
_Pragma ("GCC diagnostic ignored \"-Wmissing-declarations\"") \
_GL_INLINE_HEADER_CONST_PRAGMA
# define _GL_INLINE_HEADER_END \
_Pragma ("GCC diagnostic pop")
#else
# define _GL_INLINE_HEADER_BEGIN
# define _GL_INLINE_HEADER_END
#endif
'''

View file

@ -0,0 +1,460 @@
These changes are mostly inherited from previous iterations
of gnulib-printf-in-glib.
Here are explanations for some of them:
* g-gnulib.h is a minimal replacement for gnulib config.h
* gnulib_math.h is a processed copy of gnulib math.in.h
We can't keep it named math.h, since we need to include
both the system math.h and this header in some places.
* gnulib_math.h needs _GL_ATTRIBUTE_CONST, put it directly
there instead of getting it from config.h
Also, instead of copying _GL_FUNCDECL_RPL and _GL_WARN_ON_USE
we simply include headers where these macros are defined.
* isnan source files get extra includes, in gnulib these
were probably handled by makefiles and/or configure scripts
* glib has a test result named HAVE_LONG_LONG instead of HAVE_LONG_LONG_INT,
so make the code use that
* One of the goals of using this gnulib implementation in glib is
to have C99-compliant 3-digit exponent, therefore gnulib
ifdefs that *disable* that behaviour are altered to keep it enabled.
Another possible location for such a change is where %n use is
being enabled or disabled. That, however, is not activated anyway,
because this code is made not to use snprintf
* glib has G_MAXSIZE instead of SIZE_MAX, so use that
* The code is made to use glib alloca header
--- glib-82c3e92/glib/gnulib/asnprintf.c 2019-02-09 09:44:55.013866300 +0000
+++ glib-82c3e92/glib/gnulib/asnprintf.c 2019-02-09 10:08:46.444859600 +0000
@@ -16,6 +16,8 @@
#include <config.h>
+#include "g-gnulib.h"
+
/* Specification. */
#include "vasnprintf.h"
--- glib-82c3e92/glib/gnulib/isnand.c 2019-02-09 09:44:56.075691800 +0000
+++ glib-82c3e92/glib/gnulib/isnand.c 2019-02-09 10:09:35.443191100 +0000
@@ -16,4 +16,7 @@
/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
+#include <config.h>
+#include "gnulib_math.h"
+#include "isnand-nolibm.h"
#include "isnan.c"
--- glib-82c3e92/glib/gnulib/isnand-nolibm.h 2019-02-09 09:44:55.973651800 +0000
+++ glib-82c3e92/glib/gnulib/isnand-nolibm.h 2019-02-09 10:09:17.089604000 +0000
@@ -16,7 +16,7 @@
#if HAVE_ISNAND_IN_LIBC
/* Get declaration of isnan macro. */
-# include <math.h>
+# include <gnulib_math.h>
# if __GNUC__ >= 4
/* GCC 4.0 and newer provides three built-ins for isnan. */
# undef isnand
--- glib-82c3e92/glib/gnulib/isnanl.c 2019-02-09 09:44:56.285650400 +0000
+++ glib-82c3e92/glib/gnulib/isnanl.c 2019-02-09 10:10:00.060305200 +0000
@@ -17,4 +17,7 @@
/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
#define USE_LONG_DOUBLE
+#include <config.h>
+#include "gnulib_math.h"
+#include "isnanl-nolibm.h"
#include "isnan.c"
--- glib-82c3e92/glib/gnulib/isnanl-nolibm.h 2019-02-09 09:44:56.181628200 +0000
+++ glib-82c3e92/glib/gnulib/isnanl-nolibm.h 2019-02-09 10:09:45.731187400 +0000
@@ -16,7 +16,7 @@
#if HAVE_ISNANL_IN_LIBC
/* Get declaration of isnan macro or (older) isnanl function. */
-# include <math.h>
+# include <gnulib_math.h>
# if __GNUC__ >= 4
/* GCC 4.0 and newer provides three built-ins for isnan. */
# undef isnanl
--- glib-82c3e92/glib/gnulib/printf-args.c 2019-02-09 09:44:57.147081400 +0000
+++ glib-82c3e92/glib/gnulib/printf-args.c 2019-02-09 10:10:45.869597700 +0000
@@ -24,6 +24,8 @@
# include <config.h>
#endif
+#include "g-gnulib.h"
+
/* Specification. */
#ifndef PRINTF_FETCHARGS
# include "printf-args.h"
@@ -65,7 +67,7 @@
case TYPE_ULONGINT:
ap->a.a_ulongint = va_arg (args, unsigned long int);
break;
-#if HAVE_LONG_LONG_INT
+#if HAVE_LONG_LONG
case TYPE_LONGLONGINT:
ap->a.a_longlongint = va_arg (args, long long int);
break;
@@ -135,7 +137,7 @@
case TYPE_COUNT_LONGINT_POINTER:
ap->a.a_count_longint_pointer = va_arg (args, long int *);
break;
-#if HAVE_LONG_LONG_INT
+#if HAVE_LONG_LONG
case TYPE_COUNT_LONGLONGINT_POINTER:
ap->a.a_count_longlongint_pointer = va_arg (args, long long int *);
break;
--- glib-82c3e92/glib/gnulib/printf-args.h 2019-02-09 09:44:57.245167700 +0000
+++ glib-82c3e92/glib/gnulib/printf-args.h 2019-02-09 10:10:55.543592500 +0000
@@ -57,7 +57,7 @@
TYPE_UINT,
TYPE_LONGINT,
TYPE_ULONGINT,
-#if HAVE_LONG_LONG_INT
+#if HAVE_LONG_LONG
TYPE_LONGLONGINT,
TYPE_ULONGLONGINT,
#endif
@@ -76,7 +76,7 @@
TYPE_COUNT_SHORT_POINTER,
TYPE_COUNT_INT_POINTER,
TYPE_COUNT_LONGINT_POINTER
-#if HAVE_LONG_LONG_INT
+#if HAVE_LONG_LONG
, TYPE_COUNT_LONGLONGINT_POINTER
#endif
#if ENABLE_UNISTDIO
@@ -101,7 +101,7 @@
unsigned int a_uint;
long int a_longint;
unsigned long int a_ulongint;
-#if HAVE_LONG_LONG_INT
+#if HAVE_LONG_LONG
long long int a_longlongint;
unsigned long long int a_ulonglongint;
#endif
@@ -121,7 +121,7 @@
short * a_count_short_pointer;
int * a_count_int_pointer;
long int * a_count_longint_pointer;
-#if HAVE_LONG_LONG_INT
+#if HAVE_LONG_LONG
long long int * a_count_longlongint_pointer;
#endif
#if ENABLE_UNISTDIO
--- glib-82c3e92/glib/gnulib/printf-frexp.c 2019-02-09 09:44:57.355099800 +0000
+++ glib-82c3e92/glib/gnulib/printf-frexp.c 2019-02-09 10:11:15.476905600 +0000
@@ -26,7 +26,7 @@
#endif
#include <float.h>
-#include <math.h>
+#include <gnulib_math.h>
#ifdef USE_LONG_DOUBLE
# include "fpucw.h"
#endif
--- glib-82c3e92/glib/gnulib/printf-parse.c 2019-02-09 09:44:57.790835100 +0000
+++ glib-82c3e92/glib/gnulib/printf-parse.c 2019-02-09 10:11:32.783744500 +0000
@@ -31,6 +31,8 @@
# include <config.h>
#endif
+#include "g-gnulib.h"
+
/* Specification. */
#ifndef PRINTF_PARSE
# include "printf-parse.h"
@@ -447,7 +449,7 @@
switch (c)
{
case 'd': case 'i':
-#if HAVE_LONG_LONG_INT
+#if HAVE_LONG_LONG
/* If 'long long' exists and is larger than 'long': */
if (flags >= 16 || (flags & 4))
type = TYPE_LONGLONGINT;
@@ -465,7 +467,7 @@
type = TYPE_INT;
break;
case 'o': case 'u': case 'x': case 'X':
-#if HAVE_LONG_LONG_INT
+#if HAVE_LONG_LONG
/* If 'long long' exists and is larger than 'long': */
if (flags >= 16 || (flags & 4))
type = TYPE_ULONGLONGINT;
@@ -525,7 +527,7 @@
type = TYPE_POINTER;
break;
case 'n':
-#if HAVE_LONG_LONG_INT
+#if HAVE_LONG_LONG
/* If 'long long' exists and is larger than 'long': */
if (flags >= 16 || (flags & 4))
type = TYPE_COUNT_LONGLONGINT_POINTER;
--- glib-82c3e92/glib/gnulib/vasnprintf.c 2019-02-09 09:44:58.585342000 +0000
+++ glib-82c3e92/glib/gnulib/vasnprintf.c 2019-02-09 10:22:13.196848200 +0000
@@ -43,19 +43,21 @@
DCHAR_IS_UINT16_T Set to 1 if DCHAR_T is uint16_t.
DCHAR_IS_UINT32_T Set to 1 if DCHAR_T is uint32_t. */
+#ifndef _WIN32
/* Tell glibc's <stdio.h> to provide a prototype for snprintf().
This must come before <config.h> because <config.h> may include
<features.h>, and once <features.h> has been included, it's too late. */
#ifndef _GNU_SOURCE
# define _GNU_SOURCE 1
#endif
+#endif
#ifndef VASNPRINTF
# include <config.h>
#endif
-#ifndef IN_LIBINTL
-# include <alloca.h>
-#endif
+#include "glib/galloca.h"
+
+#include "g-gnulib.h"
/* Specification. */
#ifndef VASNPRINTF
@@ -90,29 +92,29 @@
#include "verify.h"
#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
-# include <math.h>
+# include <gnulib_math.h>
# include "float+.h"
#endif
#if (NEED_PRINTF_DOUBLE || NEED_PRINTF_INFINITE_DOUBLE) && !defined IN_LIBINTL
-# include <math.h>
+# include <gnulib_math.h>
# include "isnand-nolibm.h"
#endif
#if (NEED_PRINTF_LONG_DOUBLE || NEED_PRINTF_INFINITE_LONG_DOUBLE) && !defined IN_LIBINTL
-# include <math.h>
+# include <gnulib_math.h>
# include "isnanl-nolibm.h"
# include "fpucw.h"
#endif
#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_DOUBLE) && !defined IN_LIBINTL
-# include <math.h>
+# include <gnulib_math.h>
# include "isnand-nolibm.h"
# include "printf-frexp.h"
#endif
#if (NEED_PRINTF_DIRECTIVE_A || NEED_PRINTF_LONG_DOUBLE) && !defined IN_LIBINTL
-# include <math.h>
+# include <gnulib_math.h>
# include "isnanl-nolibm.h"
# include "printf-frexpl.h"
# include "fpucw.h"
@@ -1553,7 +1555,7 @@
switch (conversion)
{
case 'd': case 'i': case 'u':
-# if HAVE_LONG_LONG_INT
+# if HAVE_LONG_LONG
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
@@ -1583,7 +1585,7 @@
break;
case 'o':
-# if HAVE_LONG_LONG_INT
+# if HAVE_LONG_LONG
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
@@ -1611,7 +1613,7 @@
break;
case 'x': case 'X':
-# if HAVE_LONG_LONG_INT
+# if HAVE_LONG_LONG
if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
tmp_length =
(unsigned int) (sizeof (unsigned long long) * CHAR_BIT
@@ -1939,7 +1941,7 @@
case TYPE_COUNT_LONGINT_POINTER:
*a.arg[dp->arg_index].a.a_count_longint_pointer = length;
break;
-#if HAVE_LONG_LONG_INT
+#if HAVE_LONG_LONG
case TYPE_COUNT_LONGLONGINT_POINTER:
*a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
break;
@@ -4245,7 +4247,7 @@
static const wchar_t decimal_format[] =
/* Produce the same number of exponent digits
as the native printf implementation. */
-# if defined _WIN32 && ! defined __CYGWIN__
+# if (defined _WIN32 && FALSE) && ! defined __CYGWIN__
{ '%', '+', '.', '3', 'd', '\0' };
# else
{ '%', '+', '.', '2', 'd', '\0' };
@@ -4259,7 +4261,7 @@
static const char decimal_format[] =
/* Produce the same number of exponent digits
as the native printf implementation. */
-# if defined _WIN32 && ! defined __CYGWIN__
+# if (defined _WIN32 && FALSE) && ! defined __CYGWIN__
"%+.3d";
# else
"%+.2d";
@@ -4438,7 +4440,7 @@
static const wchar_t decimal_format[] =
/* Produce the same number of exponent digits
as the native printf implementation. */
-# if defined _WIN32 && ! defined __CYGWIN__
+# if (defined _WIN32 && FALSE) && ! defined __CYGWIN__
{ '%', '+', '.', '3', 'd', '\0' };
# else
{ '%', '+', '.', '2', 'd', '\0' };
@@ -4452,7 +4454,7 @@
static const char decimal_format[] =
/* Produce the same number of exponent digits
as the native printf implementation. */
-# if defined _WIN32 && ! defined __CYGWIN__
+# if (defined _WIN32 && FALSE) && ! defined __CYGWIN__
"%+.3d";
# else
"%+.2d";
@@ -4510,7 +4512,7 @@
*p++ = '+';
/* Produce the same number of exponent digits as
the native printf implementation. */
-# if defined _WIN32 && ! defined __CYGWIN__
+# if (defined _WIN32 && FALSE) && ! defined __CYGWIN__
*p++ = '0';
# endif
*p++ = '0';
@@ -4835,10 +4837,10 @@
switch (type)
{
-#if HAVE_LONG_LONG_INT
+#if HAVE_LONG_LONG
case TYPE_LONGLONGINT:
case TYPE_ULONGLONGINT:
-# if defined _WIN32 && ! defined __CYGWIN__
+# if (defined _WIN32 && FALSE) && ! defined __CYGWIN__
*fbp++ = 'I';
*fbp++ = '6';
*fbp++ = '4';
@@ -5063,7 +5065,7 @@
SNPRINTF_BUF (arg);
}
break;
-#if HAVE_LONG_LONG_INT
+#if HAVE_LONG_LONG
case TYPE_LONGLONGINT:
{
long long int arg = a.arg[dp->arg_index].a.a_longlongint;
--- glib-82c3e92/glib/gnulib/xsize.h 2019-02-09 09:44:59.231076600 +0000
+++ glib-82c3e92/glib/gnulib/xsize.h 2019-02-09 10:21:28.789553900 +0000
@@ -18,10 +18,12 @@
#ifndef _XSIZE_H
#define _XSIZE_H
+#include <glib.h>
+
/* Get size_t. */
#include <stddef.h>
-/* Get SIZE_MAX. */
+/* Get G_MAXSIZE. */
#include <limits.h>
#if HAVE_STDINT_H
# include <stdint.h>
@@ -42,8 +44,8 @@
returns a piece of memory that is way too small, and the program then
crashes while attempting to fill the memory.
To avoid this, the functions and macros in this file check for overflow.
- The convention is that SIZE_MAX represents overflow.
- malloc (SIZE_MAX) is not guaranteed to fail -- think of a malloc
+ The convention is that G_MAXSIZE represents overflow.
+ malloc (G_MAXSIZE) is not guaranteed to fail -- think of a malloc
implementation that uses mmap --, it's recommended to use size_overflow_p()
or size_in_bounds_p() before invoking malloc().
The example thus becomes:
@@ -53,7 +55,7 @@
/* Convert an arbitrary value >= 0 to type size_t. */
#define xcast_size_t(N) \
- ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX)
+ ((N) <= G_MAXSIZE ? (size_t) (N) : G_MAXSIZE)
/* Sum of two sizes, with overflow check. */
XSIZE_INLINE size_t
@@ -63,7 +65,7 @@
xsum (size_t size1, size_t size2)
{
size_t sum = size1 + size2;
- return (sum >= size1 ? sum : SIZE_MAX);
+ return (sum >= size1 ? sum : G_MAXSIZE);
}
/* Sum of three sizes, with overflow check. */
@@ -94,23 +96,23 @@
xmax (size_t size1, size_t size2)
{
/* No explicit check is needed here, because for any n:
- max (SIZE_MAX, n) == SIZE_MAX and max (n, SIZE_MAX) == SIZE_MAX. */
+ max (G_MAXSIZE, n) == G_MAXSIZE and max (n, G_MAXSIZE) == G_MAXSIZE. */
return (size1 >= size2 ? size1 : size2);
}
/* Multiplication of a count with an element size, with overflow check.
The count must be >= 0 and the element size must be > 0.
This is a macro, not a function, so that it works correctly even
- when N is of a wider type and N > SIZE_MAX. */
+ when N is of a wider type and N > G_MAXSIZE. */
#define xtimes(N, ELSIZE) \
- ((N) <= SIZE_MAX / (ELSIZE) ? (size_t) (N) * (ELSIZE) : SIZE_MAX)
+ ((N) <= G_MAXSIZE / (ELSIZE) ? (size_t) (N) * (ELSIZE) : G_MAXSIZE)
/* Check for overflow. */
#define size_overflow_p(SIZE) \
- ((SIZE) == SIZE_MAX)
+ ((SIZE) == G_MAXSIZE)
/* Check against overflow. */
#define size_in_bounds_p(SIZE) \
- ((SIZE) != SIZE_MAX)
+ ((SIZE) != G_MAXSIZE)
_GL_INLINE_HEADER_END
--- a/glib/gnulib/gnulib_math.h.in
+++ b/glib/gnulib/gnulib_math.h.in
@@ -25,6 +25,13 @@
/* The include_next requires a split double-inclusion guard. */
#@INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ @NEXT_AS_FIRST_DIRECTIVE_MATH_H@
+/* The __const__ attribute was added in gcc 2.95. */
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 95)
+# define _GL_ATTRIBUTE_CONST __attribute__ ((__const__))
+#else
+# define _GL_ATTRIBUTE_CONST /* empty */
+#endif
+
#ifndef _@GUARD_PREFIX@_MATH_H
#define _@GUARD_PREFIX@_MATH_H
@@ -41,9 +48,9 @@ _GL_INLINE_HEADER_BEGIN
# define _GL_MATH_INLINE _GL_INLINE
#endif
-/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */
+#include "c++defs.h"
-/* The definition of _GL_ARG_NONNULL is copied here. */
+#include "arg-nonnull.h"
/* The definition of _GL_WARN_ON_USE is copied here. */

2451
glib/gnulib/gnulib_math.h.in Normal file

File diff suppressed because it is too large Load diff

30
glib/gnulib/isinf.c Normal file
View 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);
}

189
glib/gnulib/isnan.c Normal file
View file

@ -0,0 +1,189 @@
/* 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 Public License 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
#include <config.h>
/* Specification. */
#ifdef USE_LONG_DOUBLE
/* Specification found in math.h or isnanl-nolibm.h. */
extern int rpl_isnanl (long double x) _GL_ATTRIBUTE_CONST;
#elif ! defined USE_FLOAT
/* Specification found in math.h or isnand-nolibm.h. */
extern int rpl_isnand (double x);
#else /* defined USE_FLOAT */
/* Specification found in math.h or isnanf-nolibm.h. */
extern int rpl_isnanf (float x);
#endif
#include <float.h>
#include <string.h>
#include "float+.h"
#ifdef USE_LONG_DOUBLE
# define FUNC rpl_isnanl
# define DOUBLE long double
# define MAX_EXP LDBL_MAX_EXP
# define MIN_EXP LDBL_MIN_EXP
# if defined LDBL_EXPBIT0_WORD && defined LDBL_EXPBIT0_BIT
# define KNOWN_EXPBIT0_LOCATION
# define EXPBIT0_WORD LDBL_EXPBIT0_WORD
# define EXPBIT0_BIT LDBL_EXPBIT0_BIT
# endif
# define SIZE SIZEOF_LDBL
# define L_(literal) literal##L
#elif ! defined USE_FLOAT
# define FUNC rpl_isnand
# define DOUBLE double
# define MAX_EXP DBL_MAX_EXP
# define MIN_EXP DBL_MIN_EXP
# if defined DBL_EXPBIT0_WORD && defined DBL_EXPBIT0_BIT
# define KNOWN_EXPBIT0_LOCATION
# define EXPBIT0_WORD DBL_EXPBIT0_WORD
# define EXPBIT0_BIT DBL_EXPBIT0_BIT
# endif
# define SIZE SIZEOF_DBL
# define L_(literal) literal
#else /* defined USE_FLOAT */
# define FUNC rpl_isnanf
# define DOUBLE float
# define MAX_EXP FLT_MAX_EXP
# define MIN_EXP FLT_MIN_EXP
# if defined FLT_EXPBIT0_WORD && defined FLT_EXPBIT0_BIT
# define KNOWN_EXPBIT0_LOCATION
# define EXPBIT0_WORD FLT_EXPBIT0_WORD
# define EXPBIT0_BIT FLT_EXPBIT0_BIT
# endif
# define SIZE SIZEOF_FLT
# define L_(literal) literal##f
#endif
#define EXP_MASK ((MAX_EXP - MIN_EXP) | 7)
#define NWORDS \
((sizeof (DOUBLE) + sizeof (unsigned int) - 1) / sizeof (unsigned int))
typedef union { DOUBLE value; unsigned int word[NWORDS]; } memory_double;
/* Most hosts nowadays use IEEE floating point, so they use IEC 60559
representations, have infinities and NaNs, and do not trap on
exceptions. Define IEEE_FLOATING_POINT if this host is one of the
typical ones. The C11 macro __STDC_IEC_559__ is close to what is
wanted here, but is not quite right because this file does not require
all the features of C11 Annex F (and does not require C11 at all,
for that matter). */
#define IEEE_FLOATING_POINT (FLT_RADIX == 2 && FLT_MANT_DIG == 24 \
&& FLT_MIN_EXP == -125 && FLT_MAX_EXP == 128)
int
FUNC (DOUBLE x)
{
#if defined KNOWN_EXPBIT0_LOCATION && IEEE_FLOATING_POINT
# if defined USE_LONG_DOUBLE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
/* Special CPU dependent code is needed to treat bit patterns outside the
IEEE 754 specification (such as Pseudo-NaNs, Pseudo-Infinities,
Pseudo-Zeroes, Unnormalized Numbers, and Pseudo-Denormals) as NaNs.
These bit patterns are:
- exponent = 0x0001..0x7FFF, mantissa bit 63 = 0,
- exponent = 0x0000, mantissa bit 63 = 1.
The NaN bit pattern is:
- exponent = 0x7FFF, mantissa >= 0x8000000000000001. */
memory_double m;
unsigned int exponent;
m.value = x;
exponent = (m.word[EXPBIT0_WORD] >> EXPBIT0_BIT) & EXP_MASK;
# ifdef WORDS_BIGENDIAN
/* Big endian: EXPBIT0_WORD = 0, EXPBIT0_BIT = 16. */
if (exponent == 0)
return 1 & (m.word[0] >> 15);
else if (exponent == EXP_MASK)
return (((m.word[0] ^ 0x8000U) << 16) | m.word[1] | (m.word[2] >> 16)) != 0;
else
return 1 & ~(m.word[0] >> 15);
# else
/* Little endian: EXPBIT0_WORD = 2, EXPBIT0_BIT = 0. */
if (exponent == 0)
return (m.word[1] >> 31);
else if (exponent == EXP_MASK)
return ((m.word[1] ^ 0x80000000U) | m.word[0]) != 0;
else
return (m.word[1] >> 31) ^ 1;
# endif
# else
/* Be careful to not do any floating-point operation on x, such as x == x,
because x may be a signaling NaN. */
# if defined __SUNPRO_C || defined __ICC || defined _MSC_VER \
|| defined __DECC || defined __TINYC__ \
|| (defined __sgi && !defined __GNUC__)
/* The Sun C 5.0, Intel ICC 10.0, Microsoft Visual C/C++ 9.0, Compaq (ex-DEC)
6.4, and TinyCC compilers don't recognize the initializers as constant
expressions. The Compaq compiler also fails when constant-folding
0.0 / 0.0 even when constant-folding is not required. The Microsoft
Visual C/C++ compiler also fails when constant-folding 1.0 / 0.0 even
when constant-folding is not required. The SGI MIPSpro C compiler
complains about "floating-point operation result is out of range". */
static DOUBLE zero = L_(0.0);
memory_double nan;
DOUBLE plus_inf = L_(1.0) / zero;
DOUBLE minus_inf = -L_(1.0) / zero;
nan.value = zero / zero;
# else
static memory_double nan = { L_(0.0) / L_(0.0) };
static DOUBLE plus_inf = L_(1.0) / L_(0.0);
static DOUBLE minus_inf = -L_(1.0) / L_(0.0);
# endif
{
memory_double m;
/* A NaN can be recognized through its exponent. But exclude +Infinity and
-Infinity, which have the same exponent. */
m.value = x;
if (((m.word[EXPBIT0_WORD] ^ nan.word[EXPBIT0_WORD])
& (EXP_MASK << EXPBIT0_BIT))
== 0)
return (memcmp (&m.value, &plus_inf, SIZE) != 0
&& memcmp (&m.value, &minus_inf, SIZE) != 0);
else
return 0;
}
# endif
#else
/* The configuration did not find sufficient information, or does
not use IEEE floating point. Give up about the signaling NaNs;
handle only the quiet NaNs. */
if (x == x)
{
# if defined USE_LONG_DOUBLE && ((defined __ia64 && LDBL_MANT_DIG == 64) || (defined __x86_64__ || defined __amd64__) || (defined __i386 || defined __i386__ || defined _I386 || defined _M_IX86 || defined _X86_)) && !HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
/* Detect any special bit patterns that pass ==; see comment above. */
memory_double m1;
memory_double m2;
memset (&m1.value, 0, SIZE);
memset (&m2.value, 0, SIZE);
m1.value = x;
m2.value = x + (x ? 0.0L : -0.0L);
if (memcmp (&m1.value, &m2.value, SIZE) != 0)
return 1;
# endif
return 0;
}
else
return 1;
#endif
}

View file

@ -0,0 +1,33 @@
/* 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 Public License 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
#if HAVE_ISNAND_IN_LIBC
/* Get declaration of isnan macro. */
# include <gnulib_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

22
glib/gnulib/isnand.c Normal file
View file

@ -0,0 +1,22 @@
/* Test for NaN that does not need libm.
Copyright (C) 2008-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 Public License 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* Written by Bruno Haible <bruno@clisp.org>, 2008. */
#include <config.h>
#include "gnulib_math.h"
#include "isnand-nolibm.h"
#include "isnan.c"

View 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
View 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"

View file

@ -0,0 +1,33 @@
/* 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 Public License 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
#if HAVE_ISNANL_IN_LIBC
/* Get declaration of isnan macro or (older) isnanl function. */
# include <gnulib_math.h>
# if __GNUC__ >= 4
/* GCC 4.0 and newer provides three built-ins for isnan. */
# undef isnanl
# define isnanl(x) __builtin_isnanl ((long double)(x))
# elif defined isnan
# undef isnanl
# define isnanl(x) isnan ((long double)(x))
# endif
#else
/* Test whether X is a NaN. */
# undef isnanl
# define isnanl rpl_isnanl
extern int isnanl (long double x);
#endif

23
glib/gnulib/isnanl.c Normal file
View file

@ -0,0 +1,23 @@
/* 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 Public License 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* Written by Bruno Haible <bruno@clisp.org>, 2007. */
#define USE_LONG_DOUBLE
#include <config.h>
#include "gnulib_math.h"
#include "isnanl-nolibm.h"
#include "isnan.c"

371
glib/gnulib/meson.build Normal file
View file

@ -0,0 +1,371 @@
# glib enables -Werror=format-nonliteral by default, but the embedded gnulib
# needs to handle user provided format strings.
extra_gnulib_args = cc.get_supported_arguments([
'-Wno-format-nonliteral', '-Wno-duplicated-branches'])
math_h_config = configuration_data ()
unneeded_funcs = [
'ACOSF',
'ACOSL',
'ASINF',
'ASINL',
'ATAN2F',
'ATANF',
'ATANL',
'CBRT',
'CBRTF',
'CBRTL',
'CEIL',
'CEILF',
'CEILL',
'COPYSIGN',
'COPYSIGNF',
'COPYSIGNL',
'COSF',
'COSHF',
'COSL',
'EXP2',
'EXP2F',
'EXP2L',
'EXPF',
'EXPL',
'EXPM1',
'EXPM1F',
'EXPM1L',
'FABSF',
'FABSL',
'FLOOR',
'FLOORF',
'FLOORL',
'FMA',
'FMAF',
'FMAL',
'FMOD',
'FMODF',
'FMODL',
'FREXPF',
'HYPOT',
'HYPOTF',
'HYPOTL',
'ILOGB',
'ILOGBF',
'ILOGBL',
'LDEXPF',
'LOG',
'LOG10',
'LOG10F',
'LOG10L',
'LOG1P',
'LOG1PF',
'LOG1PL',
'LOG2',
'LOG2F',
'LOG2L',
'LOGB',
'LOGBF',
'LOGBL',
'LOGF',
'LOGL',
'MODF',
'MODFF',
'MODFL',
'POWF',
'REMAINDER',
'REMAINDERF',
'REMAINDERL',
'RINT',
'RINTF',
'RINTL',
'ROUND',
'ROUNDF',
'ROUNDL',
'SINF',
'SINHF',
'SINL',
'SQRTF',
'SQRTL',
'TANF',
'TANHF',
'TANL',
'TRUNC',
'TRUNCF',
'TRUNCL',
]
foreach f : unneeded_funcs
math_h_config.set ('GNULIB_' + f, 0)
# These are not used in practice, guarded by
# the appropriate GNULIB_*, but meson config
# processor doesn't know that
math_h_config.set ('HAVE_' + f, 'variable not used')
math_h_config.set ('REPLACE_' + f, 'variable not used')
endforeach
needed_funcs = [
'FREXP',
'FREXPL',
'ISFINITE',
'ISINF',
'ISNAN',
'ISNAND',
'ISNANF',
'ISNANL',
'LDEXPL',
'SIGNBIT',
]
foreach f : needed_funcs
math_h_config.set ('GNULIB_' + f, 1)
endforeach
math_h_config.set ('GUARD_PREFIX', 'GL')
decls_for_unused_funcs = [
'ACOSL',
'ASINL',
'ATANL',
'CBRTF',
'CBRTL',
'CEILF',
'CEILL',
'COPYSIGNF',
'COSL',
'EXP2',
'EXP2F',
'EXP2L',
'EXPL',
'EXPM1L',
'FLOORF',
'FLOORL',
'LOG10L',
'LOG2',
'LOG2F',
'LOG2L',
'LOGB',
'LOGL',
'REMAINDER',
'REMAINDERL',
'RINTF',
'ROUND',
'ROUNDF',
'ROUNDL',
'SINL',
'SQRTL',
'TANL',
'TRUNC',
'TRUNCF',
'TRUNCL',
]
foreach f : decls_for_unused_funcs
math_h_config.set ('HAVE_DECL_' + f, 0)
endforeach
decls_for_used_funcs = [
'frexpl',
'ldexpl',
]
foreach f : decls_for_used_funcs
compiles = cc.compiles('''#include <math.h>
int main ()
{
(void) @0@;
return 0;
}
'''.format (f))
math_h_config.set ('HAVE_DECL_' + f.to_upper (), compiles ? 1 : 0)
set_variable ('have_decl_' + f, compiles ? true : false)
endforeach
nan_tmpl = '''#include <math.h>
#if __GNUC__ >= 4
# undef @0@
# define @0@(x) @2@ ((@1@)(x))
#else
# undef @0@
# define @0@(x) isnan ((@1@)(x))
#endif
double x;
int main () {return @0@ (x);}
'''
links = cc.links (nan_tmpl.format ('isnand', 'double', '__builtin_isnan'),
dependencies : [libm])
math_h_config.set ('HAVE_ISNAN', links ? 1 : 0)
set_variable ('have_isnan', links)
math_h_config.set ('HAVE_ISNAND', links ? 1 : 0)
set_variable ('have_isnand', links)
if links
extra_gnulib_args += '-DHAVE_ISNAN_IN_LIBC'
extra_gnulib_args += '-DHAVE_ISNAND_IN_LIBC'
endif
links = cc.links (nan_tmpl.format ('isnanf', 'float', '__builtin_isnanf'),
dependencies : [libm])
math_h_config.set ('HAVE_ISNANF', links ? 1 : 0)
set_variable ('have_isnanf', links)
if links
extra_gnulib_args += '-DHAVE_ISNANF_IN_LIBC'
endif
links = cc.links (nan_tmpl.format ('isnanl', 'long double', '__builtin_isnanl'),
dependencies : [libm])
math_h_config.set ('HAVE_ISNANL', links ? 1 : 0)
set_variable ('have_isnanl', links)
if links
extra_gnulib_args += '-DHAVE_ISNANL_IN_LIBC'
endif
math_h_config.set ('REPLACE_ISNAN', (have_isnand and have_isnanf and have_isnanl) ? 0 : 1)
other_needed_math_sources = []
if not (have_isnand and have_isnanf and have_isnanl)
other_needed_math_sources += [ 'isnand.c', 'isnanf.c', 'isnanl.c' ]
endif
links = cc.links ('''#include <math.h>
double x;
int y;
int main () {return ldexp (x, y) < 1;}
''',
dependencies : [libm])
math_h_config.set ('HAVE_LDEXP', links ? 1 : 0)
math_h_config.set ('HAVE_LDEXP_IN_LIBC', links ? 1 : 0)
set_variable ('have_ldexp', links)
links = cc.links ('''#include <math.h>
long double x;
int main () {return ldexpl (x, -1) > 0;}
''',
dependencies : [libm])
math_h_config.set ('HAVE_LDEXPL', links ? 1 : 0)
math_h_config.set ('HAVE_LDEXPL_IN_LIBC', links ? 1 : 0)
set_variable ('have_ldexpl', links)
links = cc.links ('''#include <math.h>
double x;
int main () {int e; return frexp (x, &e) > 0;}
''',
dependencies : [libm])
math_h_config.set ('HAVE_FREXP', links ? 1 : 0)
math_h_config.set ('HAVE_FREXP_IN_LIBC', links ? 1 : 0)
set_variable ('have_frexp', links)
links = cc.links ('''#include <math.h>
long double x;
int main () {int e; return frexpl (x, &e) > 0;}
''',
dependencies : [libm])
math_h_config.set ('HAVE_FREXPL', links ? 1 : 0)
math_h_config.set ('HAVE_FREXPL_IN_LIBC', links ? 1 : 0)
set_variable ('have_frexpl', links)
math_h_config.set ('INCLUDE_NEXT_AS_FIRST_DIRECTIVE', 'include')
math_h_config.set ('NEXT_AS_FIRST_DIRECTIVE_MATH_H', '<math.h>')
math_h_config.set ('PRAGMA_COLUMNS', '')
math_h_config.set ('PRAGMA_SYSTEM_HEADER', '')
compiles = cc.compiles ('''
#include <math.h>
/* Solaris 10 has a broken definition of NAN. Other platforms
fail to provide NAN, or provide it only in C99 mode; this
test only needs to fail when NAN is provided but wrong. */
int main () {
float f = 1.0f;
#ifdef NAN
f = NAN;
#endif
return f == 0;
}
''')
math_h_config.set ('REPLACE_NAN', compiles ? 0 : 1)
if have_frexp
subdir ('gl_cv_func_frexp_works')
else
gl_cv_func_frexp_works = false
gl_cv_func_frexp_broken_beyond_repair = true
endif
if have_frexpl
subdir ('gl_cv_func_frexpl_works')
else
gl_cv_func_frexpl_works = false
gl_cv_func_frexpl_broken_beyond_repair = true
endif
if not gl_cv_func_frexp_works and gl_cv_func_frexp_broken_beyond_repair
error ('frexp() is missing or broken beyond repair, and we have nothing to replace it with')
endif
if not gl_cv_func_frexpl_works and gl_cv_func_frexpl_broken_beyond_repair
error ('frexpl() is missing or broken beyond repair, and we have nothing to replace it with')
endif
math_h_config.set ('REPLACE_FREXP', gl_cv_func_frexp_works ? 0 : 1)
math_h_config.set ('REPLACE_FREXPL', gl_cv_func_frexpl_works ? 0 : 1)
math_h_config.set ('HAVE_DECL_FREXPL', gl_cv_func_frexpl_decl ? 0 : 1)
math_h_config.set ('REPLACE_ITOLD', 0)
math_h_config.set ('REPLACE_HUGE_VAL', 0)
math_h_config.set ('REPLACE_SIGNBIT_USING_GCC', 0)
if have_ldexpl
subdir ('gl_cv_func_ldexpl_works')
else
gl_cv_func_ldexpl_works = false
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);}
'''
# Some compilers may not have isfinite, isinf available
foreach f: ['isfinite', 'isinf', '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)
gnulib_sources = ['asnprintf.c', 'printf.c', 'printf-args.c', 'printf-parse.c', 'printf-frexp.c', 'printf-frexpl.c', 'vasnprintf.c', 'xsize.c']
if not gl_cv_func_frexp_works
gnulib_sources += ['frexp.c']
endif
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 ('.')],
pic : true,
c_args : ['-DGCC_LINT=1', '-DLIBDIR="@0@"'.format(glib_libdir), '-DGLIB_COMPILATION', '-DG_LOG_DOMAIN="GLib"' ] + glib_hidden_visibility_args + extra_gnulib_args)
gnulib_libm_dependency = [libm]

189
glib/gnulib/printf-args.c Normal file
View file

@ -0,0 +1,189 @@
/* Decomposed printf argument list.
Copyright (C) 1999, 2002-2003, 2005-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 Public License as published by
the Free Software Foundation; either version 2.1, 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, see <https://www.gnu.org/licenses/>. */
/* This file can be parametrized with the following macros:
ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions.
PRINTF_FETCHARGS Name of the function to be defined.
STATIC Set to 'static' to declare the function static. */
#ifndef PRINTF_FETCHARGS
# include <config.h>
#endif
#include "g-gnulib.h"
/* Specification. */
#ifndef PRINTF_FETCHARGS
# include "printf-args.h"
#endif
#ifdef STATIC
STATIC
#endif
int
PRINTF_FETCHARGS (va_list args, arguments *a)
{
size_t i;
argument *ap;
for (i = 0, ap = &a->arg[0]; i < a->count; i++, ap++)
switch (ap->type)
{
case TYPE_SCHAR:
ap->a.a_schar = va_arg (args, /*signed char*/ int);
break;
case TYPE_UCHAR:
ap->a.a_uchar = va_arg (args, /*unsigned char*/ int);
break;
case TYPE_SHORT:
ap->a.a_short = va_arg (args, /*short*/ int);
break;
case TYPE_USHORT:
ap->a.a_ushort = va_arg (args, /*unsigned short*/ int);
break;
case TYPE_INT:
ap->a.a_int = va_arg (args, int);
break;
case TYPE_UINT:
ap->a.a_uint = va_arg (args, unsigned int);
break;
case TYPE_LONGINT:
ap->a.a_longint = va_arg (args, long int);
break;
case TYPE_ULONGINT:
ap->a.a_ulongint = va_arg (args, unsigned long int);
break;
#if HAVE_LONG_LONG
case TYPE_LONGLONGINT:
ap->a.a_longlongint = va_arg (args, long long int);
break;
case TYPE_ULONGLONGINT:
ap->a.a_ulonglongint = va_arg (args, unsigned long long int);
break;
#endif
case TYPE_DOUBLE:
ap->a.a_double = va_arg (args, double);
break;
case TYPE_LONGDOUBLE:
ap->a.a_longdouble = va_arg (args, long double);
break;
case TYPE_CHAR:
ap->a.a_char = va_arg (args, int);
break;
#if HAVE_WINT_T
case TYPE_WIDE_CHAR:
/* Although ISO C 99 7.24.1.(2) says that wint_t is "unchanged by
default argument promotions", this is not the case in mingw32,
where wint_t is 'unsigned short'. */
ap->a.a_wide_char =
(sizeof (wint_t) < sizeof (int)
? (wint_t) va_arg (args, int)
: va_arg (args, wint_t));
break;
#endif
case TYPE_STRING:
ap->a.a_string = va_arg (args, const char *);
/* A null pointer is an invalid argument for "%s", but in practice
it occurs quite frequently in printf statements that produce
debug output. Use a fallback in this case. */
if (ap->a.a_string == NULL)
ap->a.a_string = "(NULL)";
break;
#if HAVE_WCHAR_T
case TYPE_WIDE_STRING:
ap->a.a_wide_string = va_arg (args, const wchar_t *);
/* A null pointer is an invalid argument for "%ls", but in practice
it occurs quite frequently in printf statements that produce
debug output. Use a fallback in this case. */
if (ap->a.a_wide_string == NULL)
{
static const wchar_t wide_null_string[] =
{
(wchar_t)'(',
(wchar_t)'N', (wchar_t)'U', (wchar_t)'L', (wchar_t)'L',
(wchar_t)')',
(wchar_t)0
};
ap->a.a_wide_string = wide_null_string;
}
break;
#endif
case TYPE_POINTER:
ap->a.a_pointer = va_arg (args, void *);
break;
case TYPE_COUNT_SCHAR_POINTER:
ap->a.a_count_schar_pointer = va_arg (args, signed char *);
break;
case TYPE_COUNT_SHORT_POINTER:
ap->a.a_count_short_pointer = va_arg (args, short *);
break;
case TYPE_COUNT_INT_POINTER:
ap->a.a_count_int_pointer = va_arg (args, int *);
break;
case TYPE_COUNT_LONGINT_POINTER:
ap->a.a_count_longint_pointer = va_arg (args, long int *);
break;
#if HAVE_LONG_LONG
case TYPE_COUNT_LONGLONGINT_POINTER:
ap->a.a_count_longlongint_pointer = va_arg (args, long long int *);
break;
#endif
#if ENABLE_UNISTDIO
/* The unistdio extensions. */
case TYPE_U8_STRING:
ap->a.a_u8_string = va_arg (args, const uint8_t *);
/* A null pointer is an invalid argument for "%U", but in practice
it occurs quite frequently in printf statements that produce
debug output. Use a fallback in this case. */
if (ap->a.a_u8_string == NULL)
{
static const uint8_t u8_null_string[] =
{ '(', 'N', 'U', 'L', 'L', ')', 0 };
ap->a.a_u8_string = u8_null_string;
}
break;
case TYPE_U16_STRING:
ap->a.a_u16_string = va_arg (args, const uint16_t *);
/* A null pointer is an invalid argument for "%lU", but in practice
it occurs quite frequently in printf statements that produce
debug output. Use a fallback in this case. */
if (ap->a.a_u16_string == NULL)
{
static const uint16_t u16_null_string[] =
{ '(', 'N', 'U', 'L', 'L', ')', 0 };
ap->a.a_u16_string = u16_null_string;
}
break;
case TYPE_U32_STRING:
ap->a.a_u32_string = va_arg (args, const uint32_t *);
/* A null pointer is an invalid argument for "%llU", but in practice
it occurs quite frequently in printf statements that produce
debug output. Use a fallback in this case. */
if (ap->a.a_u32_string == NULL)
{
static const uint32_t u32_null_string[] =
{ '(', 'N', 'U', 'L', 'L', ')', 0 };
ap->a.a_u32_string = u32_null_string;
}
break;
#endif
default:
/* Unknown type. */
return -1;
}
return 0;
}

158
glib/gnulib/printf-args.h Normal file
View file

@ -0,0 +1,158 @@
/* Decomposed printf argument list.
Copyright (C) 1999, 2002-2003, 2006-2007, 2011-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 Public License as published by
the Free Software Foundation; either version 2.1, 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, see <https://www.gnu.org/licenses/>. */
#ifndef _PRINTF_ARGS_H
#define _PRINTF_ARGS_H
/* This file can be parametrized with the following macros:
ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions.
PRINTF_FETCHARGS Name of the function to be declared.
STATIC Set to 'static' to declare the function static. */
/* Default parameters. */
#ifndef PRINTF_FETCHARGS
# define PRINTF_FETCHARGS printf_fetchargs
#endif
/* Get size_t. */
#include <stddef.h>
/* Get wchar_t. */
#if HAVE_WCHAR_T
# include <stddef.h>
#endif
/* Get wint_t. */
#if HAVE_WINT_T
# include <wchar.h>
#endif
/* Get va_list. */
#include <stdarg.h>
/* Argument types */
typedef enum
{
TYPE_NONE,
TYPE_SCHAR,
TYPE_UCHAR,
TYPE_SHORT,
TYPE_USHORT,
TYPE_INT,
TYPE_UINT,
TYPE_LONGINT,
TYPE_ULONGINT,
#if HAVE_LONG_LONG
TYPE_LONGLONGINT,
TYPE_ULONGLONGINT,
#endif
TYPE_DOUBLE,
TYPE_LONGDOUBLE,
TYPE_CHAR,
#if HAVE_WINT_T
TYPE_WIDE_CHAR,
#endif
TYPE_STRING,
#if HAVE_WCHAR_T
TYPE_WIDE_STRING,
#endif
TYPE_POINTER,
TYPE_COUNT_SCHAR_POINTER,
TYPE_COUNT_SHORT_POINTER,
TYPE_COUNT_INT_POINTER,
TYPE_COUNT_LONGINT_POINTER
#if HAVE_LONG_LONG
, TYPE_COUNT_LONGLONGINT_POINTER
#endif
#if ENABLE_UNISTDIO
/* The unistdio extensions. */
, TYPE_U8_STRING
, TYPE_U16_STRING
, TYPE_U32_STRING
#endif
} arg_type;
/* Polymorphic argument */
typedef struct
{
arg_type type;
union
{
signed char a_schar;
unsigned char a_uchar;
short a_short;
unsigned short a_ushort;
int a_int;
unsigned int a_uint;
long int a_longint;
unsigned long int a_ulongint;
#if HAVE_LONG_LONG
long long int a_longlongint;
unsigned long long int a_ulonglongint;
#endif
float a_float;
double a_double;
long double a_longdouble;
int a_char;
#if HAVE_WINT_T
wint_t a_wide_char;
#endif
const char* a_string;
#if HAVE_WCHAR_T
const wchar_t* a_wide_string;
#endif
void* a_pointer;
signed char * a_count_schar_pointer;
short * a_count_short_pointer;
int * a_count_int_pointer;
long int * a_count_longint_pointer;
#if HAVE_LONG_LONG
long long int * a_count_longlongint_pointer;
#endif
#if ENABLE_UNISTDIO
/* The unistdio extensions. */
const uint8_t * a_u8_string;
const uint16_t * a_u16_string;
const uint32_t * a_u32_string;
#endif
}
a;
}
argument;
/* Number of directly allocated arguments (no malloc() needed). */
#define N_DIRECT_ALLOC_ARGUMENTS 7
typedef struct
{
size_t count;
argument *arg;
argument direct_alloc_arg[N_DIRECT_ALLOC_ARGUMENTS];
}
arguments;
/* Fetch the arguments, putting them into a. */
#ifdef STATIC
STATIC
#else
extern
#endif
int PRINTF_FETCHARGS (va_list args, arguments *a);
#endif /* _PRINTF_ARGS_H */

190
glib/gnulib/printf-frexp.c Normal file
View file

@ -0,0 +1,190 @@
/* Split a double into fraction and mantissa, for hexadecimal printf.
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 Public License 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
#if ! defined USE_LONG_DOUBLE
# include <config.h>
#endif
/* Specification. */
#ifdef USE_LONG_DOUBLE
# include "printf-frexpl.h"
#else
# include "printf-frexp.h"
#endif
#include <float.h>
#include <gnulib_math.h>
#ifdef USE_LONG_DOUBLE
# include "fpucw.h"
#endif
/* This file assumes FLT_RADIX = 2. If FLT_RADIX is a power of 2 greater
than 2, or not even a power of 2, some rounding errors can occur, so that
then the returned mantissa is only guaranteed to be <= 2.0, not < 2.0. */
#ifdef USE_LONG_DOUBLE
# define FUNC printf_frexpl
# define DOUBLE long double
# define MIN_EXP LDBL_MIN_EXP
# if HAVE_FREXPL_IN_LIBC && HAVE_LDEXPL_IN_LIBC
# define USE_FREXP_LDEXP
# define FREXP frexpl
# define LDEXP ldexpl
# endif
# define DECL_ROUNDING DECL_LONG_DOUBLE_ROUNDING
# define BEGIN_ROUNDING() BEGIN_LONG_DOUBLE_ROUNDING ()
# define END_ROUNDING() END_LONG_DOUBLE_ROUNDING ()
# define L_(literal) literal##L
#else
# define FUNC printf_frexp
# define DOUBLE double
# define MIN_EXP DBL_MIN_EXP
# if HAVE_FREXP_IN_LIBC && HAVE_LDEXP_IN_LIBC
# define USE_FREXP_LDEXP
# define FREXP frexp
# define LDEXP ldexp
# endif
# define DECL_ROUNDING
# define BEGIN_ROUNDING()
# define END_ROUNDING()
# define L_(literal) literal
#endif
DOUBLE
FUNC (DOUBLE x, int *expptr)
{
int exponent;
DECL_ROUNDING
BEGIN_ROUNDING ();
#ifdef USE_FREXP_LDEXP
/* frexp and ldexp are usually faster than the loop below. */
x = FREXP (x, &exponent);
x = x + x;
exponent -= 1;
if (exponent < MIN_EXP - 1)
{
x = LDEXP (x, exponent - (MIN_EXP - 1));
exponent = MIN_EXP - 1;
}
#else
{
/* Since the exponent is an 'int', it fits in 64 bits. Therefore the
loops are executed no more than 64 times. */
DOUBLE pow2[64]; /* pow2[i] = 2^2^i */
DOUBLE powh[64]; /* powh[i] = 2^-2^i */
int i;
exponent = 0;
if (x >= L_(1.0))
{
/* A nonnegative exponent. */
{
DOUBLE pow2_i; /* = pow2[i] */
DOUBLE powh_i; /* = powh[i] */
/* Invariants: pow2_i = 2^2^i, powh_i = 2^-2^i,
x * 2^exponent = argument, x >= 1.0. */
for (i = 0, pow2_i = L_(2.0), powh_i = L_(0.5);
;
i++, pow2_i = pow2_i * pow2_i, powh_i = powh_i * powh_i)
{
if (x >= pow2_i)
{
exponent += (1 << i);
x *= powh_i;
}
else
break;
pow2[i] = pow2_i;
powh[i] = powh_i;
}
}
/* Here 1.0 <= x < 2^2^i. */
}
else
{
/* A negative exponent. */
{
DOUBLE pow2_i; /* = pow2[i] */
DOUBLE powh_i; /* = powh[i] */
/* Invariants: pow2_i = 2^2^i, powh_i = 2^-2^i,
x * 2^exponent = argument, x < 1.0, exponent >= MIN_EXP - 1. */
for (i = 0, pow2_i = L_(2.0), powh_i = L_(0.5);
;
i++, pow2_i = pow2_i * pow2_i, powh_i = powh_i * powh_i)
{
if (exponent - (1 << i) < MIN_EXP - 1)
break;
exponent -= (1 << i);
x *= pow2_i;
if (x >= L_(1.0))
break;
pow2[i] = pow2_i;
powh[i] = powh_i;
}
}
/* Here either x < 1.0 and exponent - 2^i < MIN_EXP - 1 <= exponent,
or 1.0 <= x < 2^2^i and exponent >= MIN_EXP - 1. */
if (x < L_(1.0))
/* Invariants: x * 2^exponent = argument, x < 1.0 and
exponent - 2^i < MIN_EXP - 1 <= exponent. */
while (i > 0)
{
i--;
if (exponent - (1 << i) >= MIN_EXP - 1)
{
exponent -= (1 << i);
x *= pow2[i];
if (x >= L_(1.0))
break;
}
}
/* Here either x < 1.0 and exponent = MIN_EXP - 1,
or 1.0 <= x < 2^2^i and exponent >= MIN_EXP - 1. */
}
/* Invariants: x * 2^exponent = argument, and
either x < 1.0 and exponent = MIN_EXP - 1,
or 1.0 <= x < 2^2^i and exponent >= MIN_EXP - 1. */
while (i > 0)
{
i--;
if (x >= pow2[i])
{
exponent += (1 << i);
x *= powh[i];
}
}
/* Here either x < 1.0 and exponent = MIN_EXP - 1,
or 1.0 <= x < 2.0 and exponent >= MIN_EXP - 1. */
}
#endif
END_ROUNDING ();
*expptr = exponent;
return x;
}

View file

@ -0,0 +1,23 @@
/* Split a double into fraction and mantissa, for hexadecimal printf.
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 Public License 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* Write a finite, positive number x as
x = mantissa * 2^exp
where exp >= DBL_MIN_EXP - 1,
mantissa < 2.0,
if x is not a denormalized number then mantissa >= 1.0.
Store exp in *EXPPTR and return mantissa. */
extern double printf_frexp (double x, int *expptr);

View file

@ -0,0 +1,37 @@
/* Split a 'long double' into fraction and mantissa, for hexadecimal printf.
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 Public License 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
#include <config.h>
#if HAVE_SAME_LONG_DOUBLE_AS_DOUBLE
/* Specification. */
# include "printf-frexpl.h"
# include "printf-frexp.h"
long double
printf_frexpl (long double x, int *expptr)
{
return printf_frexp (x, expptr);
}
#else
# define USE_LONG_DOUBLE
# include "printf-frexp.c"
#endif

View file

@ -0,0 +1,23 @@
/* Split a 'long double' into fraction and mantissa, for hexadecimal printf.
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 Public License 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* Write a finite, positive number x as
x = mantissa * 2^exp
where exp >= LDBL_MIN_EXP - 1,
mantissa < 2.0,
if x is not a denormalized number then mantissa >= 1.0.
Store exp in *EXPPTR and return mantissa. */
extern long double printf_frexpl (long double x, int *expptr);

640
glib/gnulib/printf-parse.c Normal file
View file

@ -0,0 +1,640 @@
/* Formatted output to strings.
Copyright (C) 1999-2000, 2002-2003, 2006-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 Public License as published by
the Free Software Foundation; either version 2.1, 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, see <https://www.gnu.org/licenses/>. */
/* This file can be parametrized with the following macros:
CHAR_T The element type of the format string.
CHAR_T_ONLY_ASCII Set to 1 to enable verification that all characters
in the format string are ASCII.
DIRECTIVE Structure denoting a format directive.
Depends on CHAR_T.
DIRECTIVES Structure denoting the set of format directives of a
format string. Depends on CHAR_T.
PRINTF_PARSE Function that parses a format string.
Depends on CHAR_T.
STATIC Set to 'static' to declare the function static.
ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions. */
#ifndef PRINTF_PARSE
# include <config.h>
#endif
#include "g-gnulib.h"
/* Specification. */
#ifndef PRINTF_PARSE
# include "printf-parse.h"
#endif
/* Default parameters. */
#ifndef PRINTF_PARSE
# define PRINTF_PARSE printf_parse
# define CHAR_T char
# define DIRECTIVE char_directive
# define DIRECTIVES char_directives
#endif
/* Get size_t, NULL. */
#include <stddef.h>
/* Get intmax_t. */
#if defined IN_LIBINTL || defined IN_LIBASPRINTF
# if HAVE_STDINT_H_WITH_UINTMAX
# include <stdint.h>
# endif
# if HAVE_INTTYPES_H_WITH_UINTMAX
# include <inttypes.h>
# endif
#else
# include <stdint.h>
#endif
/* malloc(), realloc(), free(). */
#include <stdlib.h>
/* memcpy(). */
#include <string.h>
/* errno. */
#include <errno.h>
/* Checked size_t computations. */
#include "xsize.h"
#if CHAR_T_ONLY_ASCII
/* c_isascii(). */
# include "c-ctype.h"
#endif
#ifdef STATIC
STATIC
#endif
int
PRINTF_PARSE (const CHAR_T *format, DIRECTIVES *d, arguments *a)
{
const CHAR_T *cp = format; /* pointer into format */
size_t arg_posn = 0; /* number of regular arguments consumed */
size_t d_allocated; /* allocated elements of d->dir */
size_t a_allocated; /* allocated elements of a->arg */
size_t max_width_length = 0;
size_t max_precision_length = 0;
d->count = 0;
d_allocated = N_DIRECT_ALLOC_DIRECTIVES;
d->dir = d->direct_alloc_dir;
a->count = 0;
a_allocated = N_DIRECT_ALLOC_ARGUMENTS;
a->arg = a->direct_alloc_arg;
#define REGISTER_ARG(_index_,_type_) \
{ \
size_t n = (_index_); \
if (n >= a_allocated) \
{ \
size_t memory_size; \
argument *memory; \
\
a_allocated = xtimes (a_allocated, 2); \
if (a_allocated <= n) \
a_allocated = xsum (n, 1); \
memory_size = xtimes (a_allocated, sizeof (argument)); \
if (size_overflow_p (memory_size)) \
/* Overflow, would lead to out of memory. */ \
goto out_of_memory; \
memory = (argument *) (a->arg != a->direct_alloc_arg \
? realloc (a->arg, memory_size) \
: malloc (memory_size)); \
if (memory == NULL) \
/* Out of memory. */ \
goto out_of_memory; \
if (a->arg == a->direct_alloc_arg) \
memcpy (memory, a->arg, a->count * sizeof (argument)); \
a->arg = memory; \
} \
while (a->count <= n) \
a->arg[a->count++].type = TYPE_NONE; \
if (a->arg[n].type == TYPE_NONE) \
a->arg[n].type = (_type_); \
else if (a->arg[n].type != (_type_)) \
/* Ambiguous type for positional argument. */ \
goto error; \
}
while (*cp != '\0')
{
CHAR_T c = *cp++;
if (c == '%')
{
size_t arg_index = ARG_NONE;
DIRECTIVE *dp = &d->dir[d->count]; /* pointer to next directive */
/* Initialize the next directive. */
dp->dir_start = cp - 1;
dp->flags = 0;
dp->width_start = NULL;
dp->width_end = NULL;
dp->width_arg_index = ARG_NONE;
dp->precision_start = NULL;
dp->precision_end = NULL;
dp->precision_arg_index = ARG_NONE;
dp->arg_index = ARG_NONE;
/* Test for positional argument. */
if (*cp >= '0' && *cp <= '9')
{
const CHAR_T *np;
for (np = cp; *np >= '0' && *np <= '9'; np++)
;
if (*np == '$')
{
size_t n = 0;
for (np = cp; *np >= '0' && *np <= '9'; np++)
n = xsum (xtimes (n, 10), *np - '0');
if (n == 0)
/* Positional argument 0. */
goto error;
if (size_overflow_p (n))
/* n too large, would lead to out of memory later. */
goto error;
arg_index = n - 1;
cp = np + 1;
}
}
/* Read the flags. */
for (;;)
{
if (*cp == '\'')
{
dp->flags |= FLAG_GROUP;
cp++;
}
else if (*cp == '-')
{
dp->flags |= FLAG_LEFT;
cp++;
}
else if (*cp == '+')
{
dp->flags |= FLAG_SHOWSIGN;
cp++;
}
else if (*cp == ' ')
{
dp->flags |= FLAG_SPACE;
cp++;
}
else if (*cp == '#')
{
dp->flags |= FLAG_ALT;
cp++;
}
else if (*cp == '0')
{
dp->flags |= FLAG_ZERO;
cp++;
}
#if __GLIBC__ >= 2 && !defined __UCLIBC__
else if (*cp == 'I')
{
dp->flags |= FLAG_LOCALIZED;
cp++;
}
#endif
else
break;
}
/* Parse the field width. */
if (*cp == '*')
{
dp->width_start = cp;
cp++;
dp->width_end = cp;
if (max_width_length < 1)
max_width_length = 1;
/* Test for positional argument. */
if (*cp >= '0' && *cp <= '9')
{
const CHAR_T *np;
for (np = cp; *np >= '0' && *np <= '9'; np++)
;
if (*np == '$')
{
size_t n = 0;
for (np = cp; *np >= '0' && *np <= '9'; np++)
n = xsum (xtimes (n, 10), *np - '0');
if (n == 0)
/* Positional argument 0. */
goto error;
if (size_overflow_p (n))
/* n too large, would lead to out of memory later. */
goto error;
dp->width_arg_index = n - 1;
cp = np + 1;
}
}
if (dp->width_arg_index == ARG_NONE)
{
dp->width_arg_index = arg_posn++;
if (dp->width_arg_index == ARG_NONE)
/* arg_posn wrapped around. */
goto error;
}
REGISTER_ARG (dp->width_arg_index, TYPE_INT);
}
else if (*cp >= '0' && *cp <= '9')
{
size_t width_length;
dp->width_start = cp;
for (; *cp >= '0' && *cp <= '9'; cp++)
;
dp->width_end = cp;
width_length = dp->width_end - dp->width_start;
if (max_width_length < width_length)
max_width_length = width_length;
}
/* Parse the precision. */
if (*cp == '.')
{
cp++;
if (*cp == '*')
{
dp->precision_start = cp - 1;
cp++;
dp->precision_end = cp;
if (max_precision_length < 2)
max_precision_length = 2;
/* Test for positional argument. */
if (*cp >= '0' && *cp <= '9')
{
const CHAR_T *np;
for (np = cp; *np >= '0' && *np <= '9'; np++)
;
if (*np == '$')
{
size_t n = 0;
for (np = cp; *np >= '0' && *np <= '9'; np++)
n = xsum (xtimes (n, 10), *np - '0');
if (n == 0)
/* Positional argument 0. */
goto error;
if (size_overflow_p (n))
/* n too large, would lead to out of memory
later. */
goto error;
dp->precision_arg_index = n - 1;
cp = np + 1;
}
}
if (dp->precision_arg_index == ARG_NONE)
{
dp->precision_arg_index = arg_posn++;
if (dp->precision_arg_index == ARG_NONE)
/* arg_posn wrapped around. */
goto error;
}
REGISTER_ARG (dp->precision_arg_index, TYPE_INT);
}
else
{
size_t precision_length;
dp->precision_start = cp - 1;
for (; *cp >= '0' && *cp <= '9'; cp++)
;
dp->precision_end = cp;
precision_length = dp->precision_end - dp->precision_start;
if (max_precision_length < precision_length)
max_precision_length = precision_length;
}
}
{
arg_type type;
/* Parse argument type/size specifiers. */
{
int flags = 0;
for (;;)
{
if (*cp == 'h')
{
flags |= (1 << (flags & 1));
cp++;
}
else if (*cp == 'L')
{
flags |= 4;
cp++;
}
else if (*cp == 'l')
{
flags += 8;
cp++;
}
else if (*cp == 'j')
{
if (sizeof (intmax_t) > sizeof (long))
{
/* intmax_t = long long */
flags += 16;
}
else if (sizeof (intmax_t) > sizeof (int))
{
/* intmax_t = long */
flags += 8;
}
cp++;
}
else if (*cp == 'z' || *cp == 'Z')
{
/* 'z' is standardized in ISO C 99, but glibc uses 'Z'
because the warning facility in gcc-2.95.2 understands
only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784). */
if (sizeof (size_t) > sizeof (long))
{
/* size_t = long long */
flags += 16;
}
else if (sizeof (size_t) > sizeof (int))
{
/* size_t = long */
flags += 8;
}
cp++;
}
else if (*cp == 't')
{
if (sizeof (ptrdiff_t) > sizeof (long))
{
/* ptrdiff_t = long long */
flags += 16;
}
else if (sizeof (ptrdiff_t) > sizeof (int))
{
/* ptrdiff_t = long */
flags += 8;
}
cp++;
}
#if defined __APPLE__ && defined __MACH__
/* On Mac OS X 10.3, PRIdMAX is defined as "qd".
We cannot change it to "lld" because PRIdMAX must also
be understood by the system's printf routines. */
else if (*cp == 'q')
{
if (64 / 8 > sizeof (long))
{
/* int64_t = long long */
flags += 16;
}
else
{
/* int64_t = long */
flags += 8;
}
cp++;
}
#endif
#if defined _WIN32 && ! defined __CYGWIN__
/* On native Windows, PRIdMAX is defined as "I64d".
We cannot change it to "lld" because PRIdMAX must also
be understood by the system's printf routines. */
else if (*cp == 'I' && cp[1] == '6' && cp[2] == '4')
{
if (64 / 8 > sizeof (long))
{
/* __int64 = long long */
flags += 16;
}
else
{
/* __int64 = long */
flags += 8;
}
cp += 3;
}
#endif
else
break;
}
/* Read the conversion character. */
c = *cp++;
switch (c)
{
case 'd': case 'i':
#if HAVE_LONG_LONG
/* If 'long long' exists and is larger than 'long': */
if (flags >= 16 || (flags & 4))
type = TYPE_LONGLONGINT;
else
#endif
/* If 'long long' exists and is the same as 'long', we parse
"lld" into TYPE_LONGINT. */
if (flags >= 8)
type = TYPE_LONGINT;
else if (flags & 2)
type = TYPE_SCHAR;
else if (flags & 1)
type = TYPE_SHORT;
else
type = TYPE_INT;
break;
case 'o': case 'u': case 'x': case 'X':
#if HAVE_LONG_LONG
/* If 'long long' exists and is larger than 'long': */
if (flags >= 16 || (flags & 4))
type = TYPE_ULONGLONGINT;
else
#endif
/* If 'unsigned long long' exists and is the same as
'unsigned long', we parse "llu" into TYPE_ULONGINT. */
if (flags >= 8)
type = TYPE_ULONGINT;
else if (flags & 2)
type = TYPE_UCHAR;
else if (flags & 1)
type = TYPE_USHORT;
else
type = TYPE_UINT;
break;
case 'f': case 'F': case 'e': case 'E': case 'g': case 'G':
case 'a': case 'A':
if (flags >= 16 || (flags & 4))
type = TYPE_LONGDOUBLE;
else
type = TYPE_DOUBLE;
break;
case 'c':
if (flags >= 8)
#if HAVE_WINT_T
type = TYPE_WIDE_CHAR;
#else
goto error;
#endif
else
type = TYPE_CHAR;
break;
#if HAVE_WINT_T
case 'C':
type = TYPE_WIDE_CHAR;
c = 'c';
break;
#endif
case 's':
if (flags >= 8)
#if HAVE_WCHAR_T
type = TYPE_WIDE_STRING;
#else
goto error;
#endif
else
type = TYPE_STRING;
break;
#if HAVE_WCHAR_T
case 'S':
type = TYPE_WIDE_STRING;
c = 's';
break;
#endif
case 'p':
type = TYPE_POINTER;
break;
case 'n':
#if HAVE_LONG_LONG
/* If 'long long' exists and is larger than 'long': */
if (flags >= 16 || (flags & 4))
type = TYPE_COUNT_LONGLONGINT_POINTER;
else
#endif
/* If 'long long' exists and is the same as 'long', we parse
"lln" into TYPE_COUNT_LONGINT_POINTER. */
if (flags >= 8)
type = TYPE_COUNT_LONGINT_POINTER;
else if (flags & 2)
type = TYPE_COUNT_SCHAR_POINTER;
else if (flags & 1)
type = TYPE_COUNT_SHORT_POINTER;
else
type = TYPE_COUNT_INT_POINTER;
break;
#if ENABLE_UNISTDIO
/* The unistdio extensions. */
case 'U':
if (flags >= 16)
type = TYPE_U32_STRING;
else if (flags >= 8)
type = TYPE_U16_STRING;
else
type = TYPE_U8_STRING;
break;
#endif
case '%':
type = TYPE_NONE;
break;
default:
/* Unknown conversion character. */
goto error;
}
}
if (type != TYPE_NONE)
{
dp->arg_index = arg_index;
if (dp->arg_index == ARG_NONE)
{
dp->arg_index = arg_posn++;
if (dp->arg_index == ARG_NONE)
/* arg_posn wrapped around. */
goto error;
}
REGISTER_ARG (dp->arg_index, type);
}
dp->conversion = c;
dp->dir_end = cp;
}
d->count++;
if (d->count >= d_allocated)
{
size_t memory_size;
DIRECTIVE *memory;
d_allocated = xtimes (d_allocated, 2);
memory_size = xtimes (d_allocated, sizeof (DIRECTIVE));
if (size_overflow_p (memory_size))
/* Overflow, would lead to out of memory. */
goto out_of_memory;
memory = (DIRECTIVE *) (d->dir != d->direct_alloc_dir
? realloc (d->dir, memory_size)
: malloc (memory_size));
if (memory == NULL)
/* Out of memory. */
goto out_of_memory;
if (d->dir == d->direct_alloc_dir)
memcpy (memory, d->dir, d->count * sizeof (DIRECTIVE));
d->dir = memory;
}
}
#if CHAR_T_ONLY_ASCII
else if (!c_isascii (c))
{
/* Non-ASCII character. Not supported. */
goto error;
}
#endif
}
d->dir[d->count].dir_start = cp;
d->max_width_length = max_width_length;
d->max_precision_length = max_precision_length;
return 0;
error:
if (a->arg != a->direct_alloc_arg)
free (a->arg);
if (d->dir != d->direct_alloc_dir)
free (d->dir);
errno = EINVAL;
return -1;
out_of_memory:
if (a->arg != a->direct_alloc_arg)
free (a->arg);
if (d->dir != d->direct_alloc_dir)
free (d->dir);
errno = ENOMEM;
return -1;
}
#undef PRINTF_PARSE
#undef DIRECTIVES
#undef DIRECTIVE
#undef CHAR_T_ONLY_ASCII
#undef CHAR_T

193
glib/gnulib/printf-parse.h Normal file
View file

@ -0,0 +1,193 @@
/* Parse printf format string.
Copyright (C) 1999, 2002-2003, 2005, 2007, 2010-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 Public License as published by
the Free Software Foundation; either version 2.1, 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, see <https://www.gnu.org/licenses/>. */
#ifndef _PRINTF_PARSE_H
#define _PRINTF_PARSE_H
/* This file can be parametrized with the following macros:
ENABLE_UNISTDIO Set to 1 to enable the unistdio extensions.
STATIC Set to 'static' to declare the function static. */
#if HAVE_FEATURES_H
# include <features.h> /* for __GLIBC__, __UCLIBC__ */
#endif
#include "printf-args.h"
/* Flags */
#define FLAG_GROUP 1 /* ' flag */
#define FLAG_LEFT 2 /* - flag */
#define FLAG_SHOWSIGN 4 /* + flag */
#define FLAG_SPACE 8 /* space flag */
#define FLAG_ALT 16 /* # flag */
#define FLAG_ZERO 32
#if __GLIBC__ >= 2 && !defined __UCLIBC__
# define FLAG_LOCALIZED 64 /* I flag, uses localized digits */
#endif
/* arg_index value indicating that no argument is consumed. */
#define ARG_NONE (~(size_t)0)
/* xxx_directive: A parsed directive.
xxx_directives: A parsed format string. */
/* Number of directly allocated directives (no malloc() needed). */
#define N_DIRECT_ALLOC_DIRECTIVES 7
/* A parsed directive. */
typedef struct
{
const char* dir_start;
const char* dir_end;
int flags;
const char* width_start;
const char* width_end;
size_t width_arg_index;
const char* precision_start;
const char* precision_end;
size_t precision_arg_index;
char conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */
size_t arg_index;
}
char_directive;
/* A parsed format string. */
typedef struct
{
size_t count;
char_directive *dir;
size_t max_width_length;
size_t max_precision_length;
char_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES];
}
char_directives;
#if ENABLE_UNISTDIO
/* A parsed directive. */
typedef struct
{
const uint8_t* dir_start;
const uint8_t* dir_end;
int flags;
const uint8_t* width_start;
const uint8_t* width_end;
size_t width_arg_index;
const uint8_t* precision_start;
const uint8_t* precision_end;
size_t precision_arg_index;
uint8_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */
size_t arg_index;
}
u8_directive;
/* A parsed format string. */
typedef struct
{
size_t count;
u8_directive *dir;
size_t max_width_length;
size_t max_precision_length;
u8_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES];
}
u8_directives;
/* A parsed directive. */
typedef struct
{
const uint16_t* dir_start;
const uint16_t* dir_end;
int flags;
const uint16_t* width_start;
const uint16_t* width_end;
size_t width_arg_index;
const uint16_t* precision_start;
const uint16_t* precision_end;
size_t precision_arg_index;
uint16_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */
size_t arg_index;
}
u16_directive;
/* A parsed format string. */
typedef struct
{
size_t count;
u16_directive *dir;
size_t max_width_length;
size_t max_precision_length;
u16_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES];
}
u16_directives;
/* A parsed directive. */
typedef struct
{
const uint32_t* dir_start;
const uint32_t* dir_end;
int flags;
const uint32_t* width_start;
const uint32_t* width_end;
size_t width_arg_index;
const uint32_t* precision_start;
const uint32_t* precision_end;
size_t precision_arg_index;
uint32_t conversion; /* d i o u x X f F e E g G a A c s p n U % but not C S */
size_t arg_index;
}
u32_directive;
/* A parsed format string. */
typedef struct
{
size_t count;
u32_directive *dir;
size_t max_width_length;
size_t max_precision_length;
u32_directive direct_alloc_dir[N_DIRECT_ALLOC_DIRECTIVES];
}
u32_directives;
#endif
/* Parses the format string. Fills in the number N of directives, and fills
in directives[0], ..., directives[N-1], and sets directives[N].dir_start
to the end of the format string. Also fills in the arg_type fields of the
arguments and the needed count of arguments. */
#if ENABLE_UNISTDIO
extern int
ulc_printf_parse (const char *format, char_directives *d, arguments *a);
extern int
u8_printf_parse (const uint8_t *format, u8_directives *d, arguments *a);
extern int
u16_printf_parse (const uint16_t *format, u16_directives *d,
arguments *a);
extern int
u32_printf_parse (const uint32_t *format, u32_directives *d,
arguments *a);
#else
# ifdef STATIC
STATIC
# else
extern
# endif
int printf_parse (const char *format, char_directives *d, arguments *a);
#endif
#endif /* _PRINTF_PARSE_H */

145
glib/gnulib/printf.c Normal file
View file

@ -0,0 +1,145 @@
/* GLIB - Library of useful routines for C programming
* Copyright (C) 2003 Matthias Clasen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
/*
* Modified by the GLib Team and others 2003. See the AUTHORS
* file for a list of people on the GLib Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GLib at ftp://ftp.gtk.org/pub/gtk/.
*/
#include <config.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "g-gnulib.h"
#include "vasnprintf.h"
#include "printf.h"
int _g_gnulib_printf (char const *format, ...)
{
va_list args;
int retval;
va_start (args, format);
retval = _g_gnulib_vprintf (format, args);
va_end (args);
return retval;
}
int _g_gnulib_fprintf (FILE *file, char const *format, ...)
{
va_list args;
int retval;
va_start (args, format);
retval = _g_gnulib_vfprintf (file, format, args);
va_end (args);
return retval;
}
int _g_gnulib_sprintf (char *string, char const *format, ...)
{
va_list args;
int retval;
va_start (args, format);
retval = _g_gnulib_vsprintf (string, format, args);
va_end (args);
return retval;
}
int _g_gnulib_snprintf (char *string, size_t n, char const *format, ...)
{
va_list args;
int retval;
va_start (args, format);
retval = _g_gnulib_vsnprintf (string, n, format, args);
va_end (args);
return retval;
}
int _g_gnulib_vprintf (char const *format, va_list args)
{
return _g_gnulib_vfprintf (stdout, format, args);
}
int _g_gnulib_vfprintf (FILE *file, char const *format, va_list args)
{
char *result;
size_t length, rlength;
result = vasnprintf (NULL, &length, format, args);
if (result == NULL)
return -1;
rlength = fwrite (result, 1, length, file);
free (result);
return rlength;
}
int _g_gnulib_vsprintf (char *string, char const *format, va_list args)
{
char *result;
size_t length;
result = vasnprintf (NULL, &length, format, args);
if (result == NULL)
return -1;
memcpy (string, result, length + 1);
free (result);
return length;
}
int _g_gnulib_vsnprintf (char *string, size_t n, char const *format, va_list args)
{
char *result;
size_t length;
result = vasnprintf (NULL, &length, format, args);
if (result == NULL)
return -1;
if (n > 0)
{
memcpy (string, result, MIN(length + 1, n));
string[n - 1] = 0;
}
free (result);
return length;
}
int _g_gnulib_vasprintf (char **result, char const *format, va_list args)
{
size_t length;
*result = vasnprintf (NULL, &length, format, args);
if (*result == NULL)
return -1;
return length;
}

52
glib/gnulib/printf.h Normal file
View file

@ -0,0 +1,52 @@
/* GLIB - Library of useful routines for C programming
* Copyright (C) 2003 Matthias Clasen
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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 Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __GNULIB_PRINTF_H__
#define __GNULIB_PRINTF_H__
#include <stdarg.h>
#include <stdio.h>
int _g_gnulib_printf (char const *format,
...);
int _g_gnulib_fprintf (FILE *file,
char const *format,
...);
int _g_gnulib_sprintf (char *string,
char const *format,
...);
int _g_gnulib_snprintf (char *string,
size_t n,
char const *format,
...);
int _g_gnulib_vprintf (char const *format,
va_list args);
int _g_gnulib_vfprintf (FILE *file,
char const *format,
va_list args);
int _g_gnulib_vsprintf (char *string,
char const *format,
va_list args);
int _g_gnulib_vsnprintf (char *string,
size_t n,
char const *format,
va_list args);
int _g_gnulib_vasprintf (char **result,
char const *format,
va_list args);
#endif /* __GNULIB_PRINTF_H__ */

64
glib/gnulib/signbitd.c Normal file
View 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 <gnulib_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
View 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 <gnulib_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
View 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 <gnulib_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
}

5632
glib/gnulib/vasnprintf.c Normal file

File diff suppressed because it is too large Load diff

79
glib/gnulib/vasnprintf.h Normal file
View file

@ -0,0 +1,79 @@
/* vsprintf with automatic memory allocation.
Copyright (C) 2002-2004, 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 Public License as published by
the Free Software Foundation; either version 2.1, 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with this program; if not, see <https://www.gnu.org/licenses/>. */
#ifndef _VASNPRINTF_H
#define _VASNPRINTF_H
/* Get va_list. */
#include <stdarg.h>
/* Get size_t. */
#include <stddef.h>
/* The __attribute__ feature is available in gcc versions 2.5 and later.
The __-protected variants of the attributes 'format' and 'printf' are
accepted by gcc versions 2.6.4 (effectively 2.7) and later.
We enable _GL_ATTRIBUTE_FORMAT only if these are supported too, because
gnulib and libintl do '#define printf __printf__' when they override
the 'printf' function. */
#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7)
# define _GL_ATTRIBUTE_FORMAT(spec) __attribute__ ((__format__ spec))
#else
# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */
#endif
#ifdef __cplusplus
extern "C" {
#endif
/* Write formatted output to a string dynamically allocated with malloc().
You can pass a preallocated buffer for the result in RESULTBUF and its
size in *LENGTHP; otherwise you pass RESULTBUF = NULL.
If successful, return the address of the string (this may be = RESULTBUF
if no dynamic memory allocation was necessary) and set *LENGTHP to the
number of resulting bytes, excluding the trailing NUL. Upon error, set
errno and return NULL.
When dynamic memory allocation occurs, the preallocated buffer is left
alone (with possibly modified contents). This makes it possible to use
a statically allocated or stack-allocated buffer, like this:
char buf[100];
size_t len = sizeof (buf);
char *output = vasnprintf (buf, &len, format, args);
if (output == NULL)
... error handling ...;
else
{
... use the output string ...;
if (output != buf)
free (output);
}
*/
#if REPLACE_VASNPRINTF
# define asnprintf rpl_asnprintf
# define vasnprintf rpl_vasnprintf
#endif
extern char * asnprintf (char *resultbuf, size_t *lengthp, const char *format, ...)
_GL_ATTRIBUTE_FORMAT ((__printf__, 3, 4));
extern char * vasnprintf (char *resultbuf, size_t *lengthp, const char *format, va_list args)
_GL_ATTRIBUTE_FORMAT ((__printf__, 3, 0));
#ifdef __cplusplus
}
#endif
#endif /* _VASNPRINTF_H */

283
glib/gnulib/verify.h Normal file
View file

@ -0,0 +1,283 @@
/* Compile-time assert-like macros.
Copyright (C) 2005-2006, 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 Public License 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* Written by Paul Eggert, Bruno Haible, and Jim Meyering. */
#ifndef _GL_VERIFY_H
#define _GL_VERIFY_H
/* Define _GL_HAVE__STATIC_ASSERT to 1 if _Static_assert works as per C11.
This is supported by GCC 4.6.0 and later, in C mode, and its use
here generates easier-to-read diagnostics when verify (R) fails.
Define _GL_HAVE_STATIC_ASSERT to 1 if static_assert works as per C++11.
This is supported by GCC 6.1.0 and later, in C++ mode.
Use this only with GCC. If we were willing to slow 'configure'
down we could also use it with other compilers, but since this
affects only the quality of diagnostics, why bother? */
#if (4 < __GNUC__ + (6 <= __GNUC_MINOR__) \
&& (201112L <= __STDC_VERSION__ || !defined __STRICT_ANSI__) \
&& !defined __cplusplus)
# define _GL_HAVE__STATIC_ASSERT 1
#endif
#if (6 <= __GNUC__) && defined __cplusplus
# define _GL_HAVE_STATIC_ASSERT 1
#endif
/* FreeBSD 9.1 <sys/cdefs.h>, included by <stddef.h> and lots of other
system headers, defines a conflicting _Static_assert that is no
better than ours; override it. */
#ifndef _GL_HAVE_STATIC_ASSERT
# include <stddef.h>
# undef _Static_assert
#endif
/* Each of these macros verifies that its argument R is nonzero. To
be portable, R should be an integer constant expression. Unlike
assert (R), there is no run-time overhead.
If _Static_assert works, verify (R) uses it directly. Similarly,
_GL_VERIFY_TRUE works by packaging a _Static_assert inside a struct
that is an operand of sizeof.
The code below uses several ideas for C++ compilers, and for C
compilers that do not support _Static_assert:
* The first step is ((R) ? 1 : -1). Given an expression R, of
integral or boolean or floating-point type, this yields an
expression of integral type, whose value is later verified to be
constant and nonnegative.
* Next this expression W is wrapped in a type
struct _gl_verify_type {
unsigned int _gl_verify_error_if_negative: W;
}.
If W is negative, this yields a compile-time error. No compiler can
deal with a bit-field of negative size.
One might think that an array size check would have the same
effect, that is, that the type struct { unsigned int dummy[W]; }
would work as well. However, inside a function, some compilers
(such as C++ compilers and GNU C) allow local parameters and
variables inside array size expressions. With these compilers,
an array size check would not properly diagnose this misuse of
the verify macro:
void function (int n) { verify (n < 0); }
* For the verify macro, the struct _gl_verify_type will need to
somehow be embedded into a declaration. To be portable, this
declaration must declare an object, a constant, a function, or a
typedef name. If the declared entity uses the type directly,
such as in
struct dummy {...};
typedef struct {...} dummy;
extern struct {...} *dummy;
extern void dummy (struct {...} *);
extern struct {...} *dummy (void);
two uses of the verify macro would yield colliding declarations
if the entity names are not disambiguated. A workaround is to
attach the current line number to the entity name:
#define _GL_CONCAT0(x, y) x##y
#define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
extern struct {...} * _GL_CONCAT (dummy, __LINE__);
But this has the problem that two invocations of verify from
within the same macro would collide, since the __LINE__ value
would be the same for both invocations. (The GCC __COUNTER__
macro solves this problem, but is not portable.)
A solution is to use the sizeof operator. It yields a number,
getting rid of the identity of the type. Declarations like
extern int dummy [sizeof (struct {...})];
extern void dummy (int [sizeof (struct {...})]);
extern int (*dummy (void)) [sizeof (struct {...})];
can be repeated.
* Should the implementation use a named struct or an unnamed struct?
Which of the following alternatives can be used?
extern int dummy [sizeof (struct {...})];
extern int dummy [sizeof (struct _gl_verify_type {...})];
extern void dummy (int [sizeof (struct {...})]);
extern void dummy (int [sizeof (struct _gl_verify_type {...})]);
extern int (*dummy (void)) [sizeof (struct {...})];
extern int (*dummy (void)) [sizeof (struct _gl_verify_type {...})];
In the second and sixth case, the struct type is exported to the
outer scope; two such declarations therefore collide. GCC warns
about the first, third, and fourth cases. So the only remaining
possibility is the fifth case:
extern int (*dummy (void)) [sizeof (struct {...})];
* GCC warns about duplicate declarations of the dummy function if
-Wredundant-decls is used. GCC 4.3 and later have a builtin
__COUNTER__ macro that can let us generate unique identifiers for
each dummy function, to suppress this warning.
* This implementation exploits the fact that older versions of GCC,
which do not support _Static_assert, also do not warn about the
last declaration mentioned above.
* GCC warns if -Wnested-externs is enabled and verify() is used
within a function body; but inside a function, you can always
arrange to use verify_expr() instead.
* In C++, any struct definition inside sizeof is invalid.
Use a template type to work around the problem. */
/* Concatenate two preprocessor tokens. */
#define _GL_CONCAT(x, y) _GL_CONCAT0 (x, y)
#define _GL_CONCAT0(x, y) x##y
/* _GL_COUNTER is an integer, preferably one that changes each time we
use it. Use __COUNTER__ if it works, falling back on __LINE__
otherwise. __LINE__ isn't perfect, but it's better than a
constant. */
#if defined __COUNTER__ && __COUNTER__ != __COUNTER__
# define _GL_COUNTER __COUNTER__
#else
# define _GL_COUNTER __LINE__
#endif
/* Generate a symbol with the given prefix, making it unique if
possible. */
#define _GL_GENSYM(prefix) _GL_CONCAT (prefix, _GL_COUNTER)
/* Verify requirement R at compile-time, as an integer constant expression
that returns 1. If R is false, fail at compile-time, preferably
with a diagnostic that includes the string-literal DIAGNOSTIC. */
#define _GL_VERIFY_TRUE(R, DIAGNOSTIC) \
(!!sizeof (_GL_VERIFY_TYPE (R, DIAGNOSTIC)))
#ifdef __cplusplus
# if !GNULIB_defined_struct__gl_verify_type
template <int w>
struct _gl_verify_type {
unsigned int _gl_verify_error_if_negative: w;
};
# define GNULIB_defined_struct__gl_verify_type 1
# endif
# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
_gl_verify_type<(R) ? 1 : -1>
#elif defined _GL_HAVE__STATIC_ASSERT
# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
struct { \
_Static_assert (R, DIAGNOSTIC); \
int _gl_dummy; \
}
#else
# define _GL_VERIFY_TYPE(R, DIAGNOSTIC) \
struct { unsigned int _gl_verify_error_if_negative: (R) ? 1 : -1; }
#endif
/* Verify requirement R at compile-time, as a declaration without a
trailing ';'. If R is false, fail at compile-time, preferably
with a diagnostic that includes the string-literal DIAGNOSTIC.
Unfortunately, unlike C11, this implementation must appear as an
ordinary declaration, and cannot appear inside struct { ... }. */
#ifdef _GL_HAVE__STATIC_ASSERT
# define _GL_VERIFY _Static_assert
#else
# define _GL_VERIFY(R, DIAGNOSTIC) \
extern int (*_GL_GENSYM (_gl_verify_function) (void)) \
[_GL_VERIFY_TRUE (R, DIAGNOSTIC)]
#endif
/* _GL_STATIC_ASSERT_H is defined if this code is copied into assert.h. */
#ifdef _GL_STATIC_ASSERT_H
# if !defined _GL_HAVE__STATIC_ASSERT && !defined _Static_assert
# define _Static_assert(R, DIAGNOSTIC) _GL_VERIFY (R, DIAGNOSTIC)
# endif
# if !defined _GL_HAVE_STATIC_ASSERT && !defined static_assert
# define static_assert _Static_assert /* C11 requires this #define. */
# endif
#endif
/* @assert.h omit start@ */
/* Each of these macros verifies that its argument R is nonzero. To
be portable, R should be an integer constant expression. Unlike
assert (R), there is no run-time overhead.
There are two macros, since no single macro can be used in all
contexts in C. verify_true (R) is for scalar contexts, including
integer constant expression contexts. verify (R) is for declaration
contexts, e.g., the top level. */
/* Verify requirement R at compile-time, as an integer constant expression.
Return 1. This is equivalent to verify_expr (R, 1).
verify_true is obsolescent; please use verify_expr instead. */
#define verify_true(R) _GL_VERIFY_TRUE (R, "verify_true (" #R ")")
/* Verify requirement R at compile-time. Return the value of the
expression E. */
#define verify_expr(R, E) \
(_GL_VERIFY_TRUE (R, "verify_expr (" #R ", " #E ")") ? (E) : (E))
/* Verify requirement R at compile-time, as a declaration without a
trailing ';'. */
#ifdef __GNUC__
# define verify(R) _GL_VERIFY (R, "verify (" #R ")")
#else
/* PGI barfs if R is long. Play it safe. */
# define verify(R) _GL_VERIFY (R, "verify (...)")
#endif
#ifndef __has_builtin
# define __has_builtin(x) 0
#endif
/* Assume that R always holds. This lets the compiler optimize
accordingly. R should not have side-effects; it may or may not be
evaluated. Behavior is undefined if R is false. */
#if (__has_builtin (__builtin_unreachable) \
|| 4 < __GNUC__ + (5 <= __GNUC_MINOR__))
# define assume(R) ((R) ? (void) 0 : __builtin_unreachable ())
#elif 1200 <= _MSC_VER
# define assume(R) __assume (R)
#elif ((defined GCC_LINT || defined lint) \
&& (__has_builtin (__builtin_trap) \
|| 3 < __GNUC__ + (3 < __GNUC_MINOR__ + (4 <= __GNUC_PATCHLEVEL__))))
/* Doing it this way helps various packages when configured with
--enable-gcc-warnings, which compiles with -Dlint. It's nicer
when 'assume' silences warnings even with older GCCs. */
# define assume(R) ((R) ? (void) 0 : __builtin_trap ())
#else
/* Some tools grok NOTREACHED, e.g., Oracle Studio 12.6. */
# define assume(R) ((R) ? (void) 0 : /*NOTREACHED*/ (void) 0)
#endif
/* @assert.h omit end@ */
#endif

3
glib/gnulib/xsize.c Normal file
View file

@ -0,0 +1,3 @@
#include <config.h>
#define XSIZE_INLINE _GL_EXTERN_INLINE
#include "xsize.h"

119
glib/gnulib/xsize.h Normal file
View file

@ -0,0 +1,119 @@
/* xsize.h -- Checked size_t computations.
Copyright (C) 2003, 2008-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 Public License as published by
the Free Software Foundation; either version 2.1, 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 Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, see <https://www.gnu.org/licenses/>. */
#ifndef _XSIZE_H
#define _XSIZE_H
#include <glib.h>
/* Get size_t. */
#include <stddef.h>
/* Get G_MAXSIZE. */
#include <limits.h>
#if HAVE_STDINT_H
# include <stdint.h>
#endif
#ifndef _GL_INLINE_HEADER_BEGIN
#error "Please include config.h first."
#endif
_GL_INLINE_HEADER_BEGIN
#ifndef XSIZE_INLINE
# define XSIZE_INLINE _GL_INLINE
#endif
/* The size of memory objects is often computed through expressions of
type size_t. Example:
void* p = malloc (header_size + n * element_size).
These computations can lead to overflow. When this happens, malloc()
returns a piece of memory that is way too small, and the program then
crashes while attempting to fill the memory.
To avoid this, the functions and macros in this file check for overflow.
The convention is that G_MAXSIZE represents overflow.
malloc (G_MAXSIZE) is not guaranteed to fail -- think of a malloc
implementation that uses mmap --, it's recommended to use size_overflow_p()
or size_in_bounds_p() before invoking malloc().
The example thus becomes:
size_t size = xsum (header_size, xtimes (n, element_size));
void *p = (size_in_bounds_p (size) ? malloc (size) : NULL);
*/
/* Convert an arbitrary value >= 0 to type size_t. */
#define xcast_size_t(N) \
((N) <= G_MAXSIZE ? (size_t) (N) : G_MAXSIZE)
/* Sum of two sizes, with overflow check. */
XSIZE_INLINE size_t
#if __GNUC__ >= 3
__attribute__ ((__pure__))
#endif
xsum (size_t size1, size_t size2)
{
size_t sum = size1 + size2;
return (sum >= size1 ? sum : G_MAXSIZE);
}
/* Sum of three sizes, with overflow check. */
XSIZE_INLINE size_t
#if __GNUC__ >= 3
__attribute__ ((__pure__))
#endif
xsum3 (size_t size1, size_t size2, size_t size3)
{
return xsum (xsum (size1, size2), size3);
}
/* Sum of four sizes, with overflow check. */
XSIZE_INLINE size_t
#if __GNUC__ >= 3
__attribute__ ((__pure__))
#endif
xsum4 (size_t size1, size_t size2, size_t size3, size_t size4)
{
return xsum (xsum (xsum (size1, size2), size3), size4);
}
/* Maximum of two sizes, with overflow check. */
XSIZE_INLINE size_t
#if __GNUC__ >= 3
__attribute__ ((__pure__))
#endif
xmax (size_t size1, size_t size2)
{
/* No explicit check is needed here, because for any n:
max (G_MAXSIZE, n) == G_MAXSIZE and max (n, G_MAXSIZE) == G_MAXSIZE. */
return (size1 >= size2 ? size1 : size2);
}
/* Multiplication of a count with an element size, with overflow check.
The count must be >= 0 and the element size must be > 0.
This is a macro, not a function, so that it works correctly even
when N is of a wider type and N > G_MAXSIZE. */
#define xtimes(N, ELSIZE) \
((N) <= G_MAXSIZE / (ELSIZE) ? (size_t) (N) * (ELSIZE) : G_MAXSIZE)
/* Check for overflow. */
#define size_overflow_p(SIZE) \
((SIZE) == G_MAXSIZE)
/* Check against overflow. */
#define size_in_bounds_p(SIZE) \
((SIZE) != G_MAXSIZE)
_GL_INLINE_HEADER_END
#endif /* _XSIZE_H */