summaryrefslogtreecommitdiff
path: root/Master/tlpkg/tlperl/lib/CORE/perl.h
diff options
context:
space:
mode:
Diffstat (limited to 'Master/tlpkg/tlperl/lib/CORE/perl.h')
-rw-r--r--Master/tlpkg/tlperl/lib/CORE/perl.h1610
1 files changed, 1165 insertions, 445 deletions
diff --git a/Master/tlpkg/tlperl/lib/CORE/perl.h b/Master/tlpkg/tlperl/lib/CORE/perl.h
index 1325de9b9d0..e840450a3d9 100644
--- a/Master/tlpkg/tlperl/lib/CORE/perl.h
+++ b/Master/tlpkg/tlperl/lib/CORE/perl.h
@@ -28,6 +28,17 @@
# include "config.h"
#endif
+/* NOTE 1: that with gcc -std=c89 the __STDC_VERSION__ is *not* defined
+ * because the __STDC_VERSION__ became a thing only with C90. Therefore,
+ * with gcc, HAS_C99 will never become true as long as we use -std=c89.
+
+ * NOTE 2: headers lie. Do not expect that if HAS_C99 gets to be true,
+ * all the C99 features are there and are correct. */
+#if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || \
+ defined(_STDC_C99)
+# define HAS_C99 1
+#endif
+
/* See L<perlguts/"The Perl API"> for detailed notes on
* PERL_IMPLICIT_CONTEXT and PERL_IMPLICIT_SYS */
@@ -129,15 +140,15 @@
# ifdef PERL_GLOBAL_STRUCT_PRIVATE
EXTERN_C struct perl_vars* Perl_GetVarsPrivate();
# define PERL_GET_VARS() Perl_GetVarsPrivate() /* see miniperlmain.c */
-# ifndef PERLIO_FUNCS_CONST
-# define PERLIO_FUNCS_CONST /* Can't have these lying around. */
-# endif
# else
# define PERL_GET_VARS() PL_VarsPtr
# endif
# endif
#endif
+/* this used to be off by default, now its on, see perlio.h */
+#define PERLIO_FUNCS_CONST
+
#define pVAR struct perl_vars* my_vars PERL_UNUSED_DECL
#ifdef PERL_GLOBAL_STRUCT
@@ -298,7 +309,7 @@
#endif
#ifndef PERL_UNUSED_DECL
-# if defined(HASATTRIBUTE_UNUSED) && !defined(__cplusplus)
+# if defined(HASATTRIBUTE_UNUSED) && (!defined(__cplusplus) || (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)))
# define PERL_UNUSED_DECL __attribute__unused__
# else
# define PERL_UNUSED_DECL
@@ -307,21 +318,22 @@
/* gcc -Wall:
* for silencing unused variables that are actually used most of the time,
- * but we cannot quite get rid of, such as "ax" in PPCODE+noargs xsubs
+ * but we cannot quite get rid of, such as "ax" in PPCODE+noargs xsubs,
+ * or variables/arguments that are used only in certain configurations.
*/
#ifndef PERL_UNUSED_ARG
# if defined(lint) && defined(S_SPLINT_S) /* www.splint.org */
# include <note.h>
# define PERL_UNUSED_ARG(x) NOTE(ARGUNUSED(x))
# else
-# define PERL_UNUSED_ARG(x) ((void)x)
+# define PERL_UNUSED_ARG(x) ((void)sizeof(x))
# endif
#endif
#ifndef PERL_UNUSED_VAR
-# define PERL_UNUSED_VAR(x) ((void)x)
+# define PERL_UNUSED_VAR(x) ((void)sizeof(x))
#endif
-#ifdef USE_ITHREADS
+#if defined(USE_ITHREADS) || defined(PERL_GLOBAL_STRUCT)
# define PERL_UNUSED_CONTEXT PERL_UNUSED_ARG(my_perl)
#else
# define PERL_UNUSED_CONTEXT
@@ -384,21 +396,32 @@
*
* Note that "pragma GCC diagnostic push/pop" was added in GCC 4.6, Mar 2011;
* clang only pretends to be GCC 4.2, but still supports push/pop.
+ *
+ * Note on usage: on non-gcc (or lookalike, like clang) compilers
+ * one cannot use these at file (global) level without warnings
+ * since they are defined as empty, which leads into the terminating
+ * semicolon being left alone on a line:
+ * ;
+ * which makes compilers mildly cranky. Therefore at file level one
+ * should use the GCC_DIAG_IGNORE and GCC_DIAG_RESTORE_FILE *without*
+ * the semicolons.
+ *
+ * (A dead-on-arrival solution would be to try to define the macros as
+ * NOOP or dNOOP, those don't work both inside functions and outside.)
*/
-#if defined(__clang) || \
+#if defined(__clang__) || defined(__clang) || \
(defined( __GNUC__) && ((__GNUC__ * 100) + __GNUC_MINOR__) >= 406)
-# define GCC_DIAG_DO_PRAGMA_(x) _Pragma (#x)
-
+# define GCC_DIAG_PRAGMA(x) _Pragma (#x)
+/* clang has "clang diagnostic" pragmas, but also understands gcc. */
# define GCC_DIAG_IGNORE(x) _Pragma("GCC diagnostic push") \
- GCC_DIAG_DO_PRAGMA_(GCC diagnostic ignored #x)
+ GCC_DIAG_PRAGMA(GCC diagnostic ignored #x)
# define GCC_DIAG_RESTORE _Pragma("GCC diagnostic pop")
#else
# define GCC_DIAG_IGNORE(w)
# define GCC_DIAG_RESTORE
#endif
-
#define NOOP /*EMPTY*/(void)0
/* cea2e8a9dd23747f accidentally lost the comment originally from the first
check in of thread.h, explaining why we need dNOOP at all: */
@@ -698,21 +721,11 @@
# endif
#endif
-#ifdef USE_NEXT_CTYPE
+#ifdef I_STDINT
+# include <stdint.h>
+#endif
-#if NX_CURRENT_COMPILER_RELEASE >= 500
-# include <bsd/ctypes.h>
-#else
-# if NX_CURRENT_COMPILER_RELEASE >= 400
-# include <objc/NXCType.h>
-# else /* NX_CURRENT_COMPILER_RELEASE < 400 */
-# include <appkit/NXCType.h>
-# endif /* NX_CURRENT_COMPILER_RELEASE >= 400 */
-#endif /* NX_CURRENT_COMPILER_RELEASE >= 500 */
-
-#else /* !USE_NEXT_CTYPE */
#include <ctype.h>
-#endif /* USE_NEXT_CTYPE */
#ifdef METHOD /* Defined by OSF/1 v3.0 by ctype.h */
#undef METHOD
@@ -746,11 +759,18 @@
# if !defined(NO_LOCALE_MONETARY) && defined(LC_MONETARY)
# define USE_LOCALE_MONETARY
# endif
+# if !defined(NO_LOCALE_TIME) && defined(LC_TIME)
+# define USE_LOCALE_TIME
+# endif
# ifndef WIN32 /* No wrapper except on Windows */
# define my_setlocale(a,b) setlocale(a,b)
# endif
#endif /* !NO_LOCALE && HAS_SETLOCALE */
+/* Is $^ENCODING set, or are we under the encoding pragma? */
+#define IN_ENCODING UNLIKELY(PL_encoding \
+ || (PL_lex_encoding && _get_encoding() != NULL))
+
#include <setjmp.h>
#ifdef I_SYS_PARAM
@@ -895,13 +915,18 @@ EXTERN_C int usleep(unsigned int);
# define PERL_STRLEN_EXPAND_SHIFT 2
#endif
-#if defined(STANDARD_C) && defined(I_STDDEF)
+#if defined(STANDARD_C) && defined(I_STDDEF) && !defined(PERL_GCC_PEDANTIC)
# include <stddef.h>
# define STRUCT_OFFSET(s,m) offsetof(s,m)
#else
# define STRUCT_OFFSET(s,m) (Size_t)(&(((s *)0)->m))
#endif
+/* ptrdiff_t is C11, so undef it under pedantic builds */
+#ifdef PERL_GCC_PEDANTIC
+# undef HAS_PTRDIFF_T
+#endif
+
#ifndef __SYMBIAN32__
# if defined(I_STRING) || defined(__cplusplus)
# include <string.h>
@@ -939,7 +964,7 @@ EXTERN_C int usleep(unsigned int);
# define CHECK_MALLOC_TAINT(newval) \
CHECK_MALLOC_TOO_LATE_FOR_( \
if (newval) { \
- panic_write2("panic: tainting with $ENV{PERL_MALLOC_OPT}\n");\
+ PERL_UNUSED_RESULT(panic_write2("panic: tainting with $ENV{PERL_MALLOC_OPT}\n"));\
exit(1); })
# define MALLOC_CHECK_TAINT(argc,argv,env) STMT_START { \
if (doing_taint(argc,argv,env)) { \
@@ -1200,6 +1225,8 @@ EXTERN_C char *crypt(const char *, const char *);
# define SS_DEVOFFLINE SS$_DEVOFFLINE
# define SS_IVCHAN SS$_IVCHAN
# define SS_NORMAL SS$_NORMAL
+# define SS_NOPRIV SS$_NOPRIV
+# define SS_BUFFEROVF SS$_BUFFEROVF
#else
# define LIB_INVARG 0
# define RMS_DIR 0
@@ -1213,6 +1240,8 @@ EXTERN_C char *crypt(const char *, const char *);
# define SS_DEVOFFLINE 0
# define SS_IVCHAN 0
# define SS_NORMAL 0
+# define SS_NOPRIV 0
+# define SS_BUFFEROVF 0
#endif
#ifdef WIN32
@@ -1242,19 +1271,22 @@ EXTERN_C char *crypt(const char *, const char *);
#define ERRSV GvSVn(PL_errgv)
+/* contains inlined gv_add_by_type */
#define CLEAR_ERRSV() STMT_START { \
- if (!GvSV(PL_errgv)) { \
- sv_setpvs(GvSV(gv_add_by_type(PL_errgv, SVt_PV)), ""); \
- } else if (SvREADONLY(GvSV(PL_errgv))) { \
- SvREFCNT_dec(GvSV(PL_errgv)); \
- GvSV(PL_errgv) = newSVpvs(""); \
+ SV ** const svp = &GvSV(PL_errgv); \
+ if (!*svp) { \
+ goto clresv_newemptypv; \
+ } else if (SvREADONLY(*svp)) { \
+ SvREFCNT_dec_NN(*svp); \
+ clresv_newemptypv: \
+ *svp = newSVpvs(""); \
} else { \
- SV *const errsv = GvSV(PL_errgv); \
+ SV *const errsv = *svp; \
sv_setpvs(errsv, ""); \
+ SvPOK_only(errsv); \
if (SvMAGICAL(errsv)) { \
mg_free(errsv); \
} \
- SvPOK_only(errsv); \
} \
} STMT_END
@@ -1340,10 +1372,6 @@ EXTERN_C char *crypt(const char *, const char *);
/* Configure already sets Direntry_t */
#if defined(I_DIRENT)
# include <dirent.h>
- /* NeXT needs dirent + sys/dir.h */
-# if defined(I_SYS_DIR) && (defined(NeXT) || defined(__NeXT__))
-# include <sys/dir.h>
-# endif
#else
# ifdef I_SYS_NDIR
# include <sys/ndir.h>
@@ -1542,30 +1570,70 @@ EXTERN_C char *crypt(const char *, const char *);
* that should be true only if the snprintf()/vsnprintf() are true
* to the standard. */
+#define PERL_SNPRINTF_CHECK(len, max, api) STMT_START { if ((max) > 0 && (Size_t)len >= (max)) Perl_croak_nocontext("panic: %s buffer overflow", STRINGIFY(api)); } STMT_END
+
+#ifdef USE_QUADMATH
+# define my_snprintf Perl_my_snprintf
+# define PERL_MY_SNPRINTF_GUARDED
+#else
#if defined(HAS_SNPRINTF) && defined(HAS_C99_VARIADIC_MACROS) && !(defined(DEBUGGING) && !defined(PERL_USE_GCC_BRACE_GROUPS)) && !defined(PERL_GCC_PEDANTIC)
# ifdef PERL_USE_GCC_BRACE_GROUPS
-# define my_snprintf(buffer, len, ...) ({ int __len__ = snprintf(buffer, len, __VA_ARGS__); if ((len) > 0 && (Size_t)__len__ >= (len)) Perl_croak_nocontext("panic: snprintf buffer overflow"); __len__; })
+# define my_snprintf(buffer, max, ...) ({ int len = snprintf(buffer, max, __VA_ARGS__); PERL_SNPRINTF_CHECK(len, max, snprintf); len; })
# define PERL_MY_SNPRINTF_GUARDED
# else
-# define my_snprintf(buffer, len, ...) snprintf(buffer, len, __VA_ARGS__)
+# define my_snprintf(buffer, max, ...) snprintf(buffer, max, __VA_ARGS__)
# endif
#else
# define my_snprintf Perl_my_snprintf
# define PERL_MY_SNPRINTF_GUARDED
#endif
+#endif
+/* There is no quadmath_vsnprintf, and therefore my_vsnprintf()
+ * dies if called under USE_QUADMATH. */
#if defined(HAS_VSNPRINTF) && defined(HAS_C99_VARIADIC_MACROS) && !(defined(DEBUGGING) && !defined(PERL_USE_GCC_BRACE_GROUPS)) && !defined(PERL_GCC_PEDANTIC)
# ifdef PERL_USE_GCC_BRACE_GROUPS
-# define my_vsnprintf(buffer, len, ...) ({ int __len__ = vsnprintf(buffer, len, __VA_ARGS__); if ((len) > 0 && (Size_t)__len__ >= (Size_t)(len)) Perl_croak_nocontext("panic: vsnprintf buffer overflow"); __len__; })
+# define my_vsnprintf(buffer, max, ...) ({ int len = vsnprintf(buffer, max, __VA_ARGS__); PERL_SNPRINTF_CHECK(len, max, vsnprintf); len; })
# define PERL_MY_VSNPRINTF_GUARDED
# else
-# define my_vsnprintf(buffer, len, ...) vsnprintf(buffer, len, __VA_ARGS__)
+# define my_vsnprintf(buffer, max, ...) vsnprintf(buffer, max, __VA_ARGS__)
# endif
#else
# define my_vsnprintf Perl_my_vsnprintf
# define PERL_MY_VSNPRINTF_GUARDED
#endif
+/* You will definitely need to use the PERL_MY_SNPRINTF_POST_GUARD()
+ * or PERL_MY_VSNPRINTF_POST_GUARD() if you otherwise decide to ignore
+ * the result of my_snprintf() or my_vsnprintf(). (No, you should not
+ * completely ignore it: otherwise you cannot know whether your output
+ * was too long.)
+ *
+ * int len = my_sprintf(buf, max, ...);
+ * PERL_MY_SNPRINTF_POST_GUARD(len, max);
+ *
+ * The trick is that in certain platforms [a] the my_sprintf() already
+ * contains the sanity check, while in certain platforms [b] it needs
+ * to be done as a separate step. The POST_GUARD is that step-- in [a]
+ * platforms the POST_GUARD actually does nothing since the check has
+ * already been done. Watch out for the max being the same in both calls.
+ *
+ * If you actually use the snprintf/vsnprintf return value already,
+ * you assumedly are checking its validity somehow. But you can
+ * insert the POST_GUARD() also in that case. */
+
+#ifndef PERL_MY_SNPRINTF_GUARDED
+# define PERL_MY_SNPRINTF_POST_GUARD(len, max) PERL_SNPRINTF_CHECK(len, max, snprintf)
+#else
+# define PERL_MY_SNPRINTF_POST_GUARD(len, max) PERL_UNUSED_VAR(len)
+#endif
+
+#ifndef PERL_MY_VSNPRINTF_GUARDED
+# define PERL_MY_VSNPRINTF_POST_GUARD(len, max) PERL_SNPRINTF_CHECK(len, max, vsnprintf)
+#else
+# define PERL_MY_VSNPRINTF_POST_GUARD(len, max) PERL_UNUSED_VAR(len)
+#endif
+
#ifdef HAS_STRLCAT
# define my_strlcat strlcat
#else
@@ -1642,7 +1710,8 @@ typedef UVTYPE UV;
# endif
#endif
-#define SSize_t_MAX (SSize_t)(~(size_t)0 >> 1)
+#define Size_t_MAX (~(Size_t)0)
+#define SSize_t_MAX (SSize_t)(~(Size_t)0 >> 1)
#define IV_DIG (BIT_DIGITS(IVSIZE * 8))
#define UV_DIG (BIT_DIGITS(UVSIZE * 8))
@@ -1701,11 +1770,9 @@ typedef UVTYPE UV;
#define FPTR2DPTR(t,p) ((t)PTR2nat(p)) /* function pointer to data pointer */
#ifdef USE_LONG_DOUBLE
-# if defined(HAS_LONG_DOUBLE) && LONG_DOUBLESIZE == DOUBLESIZE
-# define LONG_DOUBLE_EQUALS_DOUBLE
-# endif
-# if !(defined(HAS_LONG_DOUBLE) && (LONG_DOUBLESIZE > DOUBLESIZE))
-# undef USE_LONG_DOUBLE /* Ouch! */
+# if LONG_DOUBLESIZE == DOUBLESIZE
+# define LONG_DOUBLE_EQUALS_DOUBLE
+# undef USE_LONG_DOUBLE /* Ouch! */
# endif
#endif
@@ -1807,86 +1874,156 @@ typedef NVTYPE NV;
/* Also Tru64 cc has broken NaN comparisons. */
# define NAN_COMPARE_BROKEN
#endif
+#if defined(__sgi)
+# define NAN_COMPARE_BROKEN
+#endif
#ifdef USE_LONG_DOUBLE
# ifdef I_SUNMATH
# include <sunmath.h>
# endif
-# define NV_DIG LDBL_DIG
-# ifdef LDBL_MANT_DIG
-# define NV_MANT_DIG LDBL_MANT_DIG
-# endif
-# ifdef LDBL_MIN
-# define NV_MIN LDBL_MIN
-# endif
-# ifdef LDBL_MAX
-# define NV_MAX LDBL_MAX
-# endif
-# ifdef LDBL_MIN_10_EXP
-# define NV_MIN_10_EXP LDBL_MIN_10_EXP
-# endif
-# ifdef LDBL_MAX_10_EXP
-# define NV_MAX_10_EXP LDBL_MAX_10_EXP
-# endif
-# ifdef LDBL_EPSILON
-# define NV_EPSILON LDBL_EPSILON
-# endif
-# ifdef LDBL_MAX
-# define NV_MAX LDBL_MAX
+# if defined(LDBL_DIG)
+# define NV_DIG LDBL_DIG
+# ifdef LDBL_MANT_DIG
+# define NV_MANT_DIG LDBL_MANT_DIG
+# endif
+# ifdef LDBL_MIN
+# define NV_MIN LDBL_MIN
+# endif
+# ifdef LDBL_MAX
+# define NV_MAX LDBL_MAX
+# endif
+# ifdef LDBL_MIN_EXP
+# define NV_MIN_EXP LDBL_MIN_EXP
+# endif
+# ifdef LDBL_MAX_EXP
+# define NV_MAX_EXP LDBL_MAX_EXP
+# endif
+# ifdef LDBL_MIN_10_EXP
+# define NV_MIN_10_EXP LDBL_MIN_10_EXP
+# endif
+# ifdef LDBL_MAX_10_EXP
+# define NV_MAX_10_EXP LDBL_MAX_10_EXP
+# endif
+# ifdef LDBL_EPSILON
+# define NV_EPSILON LDBL_EPSILON
+# endif
+# ifdef LDBL_MAX
+# define NV_MAX LDBL_MAX
/* Having LDBL_MAX doesn't necessarily mean that we have LDBL_MIN... -Allen */
-# else
-# ifdef HUGE_VALL
-# define NV_MAX HUGE_VALL
# else
-# ifdef HUGE_VAL
-# define NV_MAX ((NV)HUGE_VAL)
+# ifdef HUGE_VALL
+# define NV_MAX HUGE_VALL
# endif
# endif
# endif
-# ifdef HAS_SQRTL
+# if defined(HAS_SQRTL)
+# define Perl_acos acosl
+# define Perl_asin asinl
+# define Perl_atan atanl
+# define Perl_atan2 atan2l
+# define Perl_ceil ceill
# define Perl_cos cosl
-# define Perl_sin sinl
-# define Perl_sqrt sqrtl
+# define Perl_cosh coshl
# define Perl_exp expl
-# define Perl_log logl
-# define Perl_atan2 atan2l
-# define Perl_pow powl
+/* no Perl_fabs, but there's PERL_ABS */
# define Perl_floor floorl
-# define Perl_ceil ceill
# define Perl_fmod fmodl
+# define Perl_log logl
+# define Perl_log10 log10l
+# define Perl_pow powl
+# define Perl_sin sinl
+# define Perl_sinh sinhl
+# define Perl_sqrt sqrtl
+# define Perl_tan tanl
+# define Perl_tanh tanhl
# endif
/* e.g. libsunmath doesn't have modfl and frexpl as of mid-March 2000 */
-# ifdef HAS_MODFL
-# define Perl_modf(x,y) modfl(x,y)
+# ifndef Perl_modf
+# ifdef HAS_MODFL
+# define Perl_modf(x,y) modfl(x,y)
/* eg glibc 2.2 series seems to provide modfl on ppc and arm, but has no
prototype in <math.h> */
-# ifndef HAS_MODFL_PROTO
+# ifndef HAS_MODFL_PROTO
EXTERN_C long double modfl(long double, long double *);
-# endif
-# else
-# if defined(HAS_AINTL) && defined(HAS_COPYSIGNL)
+# endif
+# elif (defined(HAS_TRUNCL) || defined(HAS_AINTL)) && defined(HAS_COPYSIGNL)
extern long double Perl_my_modfl(long double x, long double *ip);
# define Perl_modf(x,y) Perl_my_modfl(x,y)
# endif
# endif
-# ifdef HAS_FREXPL
-# define Perl_frexp(x,y) frexpl(x,y)
-# else
-# if defined(HAS_ILOGBL) && defined(HAS_SCALBNL)
- extern long double Perl_my_frexpl(long double x, int *e);
-# define Perl_frexp(x,y) Perl_my_frexpl(x,y)
+# ifndef Perl_frexp
+# ifdef HAS_FREXPL
+# define Perl_frexp(x,y) frexpl(x,y)
+# else
+# if defined(HAS_ILOGBL) && defined(HAS_SCALBNL)
+extern long double Perl_my_frexpl(long double x, int *e);
+# define Perl_frexp(x,y) Perl_my_frexpl(x,y)
+# endif
+# endif
+# endif
+# ifndef Perl_ldexp
+# ifdef HAS_LDEXPL
+# define Perl_ldexp(x, y) ldexpl(x,y)
+# else
+# if defined(HAS_SCALBNL) && FLT_RADIX == 2
+# define Perl_ldexp(x,y) scalbnl(x,y)
+# endif
# endif
# endif
# ifndef Perl_isnan
-# ifdef HAS_ISNANL
+# if defined(HAS_ISNANL) && !(defined(isnan) && defined(HAS_C99))
# define Perl_isnan(x) isnanl(x)
# endif
# endif
# ifndef Perl_isinf
-# ifdef HAS_FINITEL
-# define Perl_isinf(x) !(finitel(x)||Perl_isnan(x))
+# if defined(HAS_ISINFL) && !(defined(isinf) && defined(HAS_C99))
+# define Perl_isinf(x) isinfl(x)
+# elif defined(LDBL_MAX) && !defined(NAN_COMPARE_BROKEN)
+# define Perl_isinf(x) ((x) > LDBL_MAX || (x) < -LDBL_MAX)
# endif
# endif
+# ifndef Perl_isfinite
+# define Perl_isfinite(x) Perl_isfinitel(x)
+# endif
+#elif defined(USE_QUADMATH) && defined(I_QUADMATH)
+# include <quadmath.h>
+# define NV_DIG FLT128_DIG
+# define NV_MANT_DIG FLT128_MANT_DIG
+# define NV_MIN FLT128_MIN
+# define NV_MAX FLT128_MAX
+# define NV_MIN_EXP FLT128_MIN_EXP
+# define NV_MAX_EXP FLT128_MAX_EXP
+# define NV_EPSILON FLT128_EPSILON
+# define NV_MIN_10_EXP FLT128_MIN_10_EXP
+# define NV_MAX_10_EXP FLT128_MAX_10_EXP
+# define NV_INF HUGE_VALQ
+# define NV_NAN nanq("0")
+# define Perl_acos acosq
+# define Perl_asin asinq
+# define Perl_atan atanq
+# define Perl_atan2 atan2q
+# define Perl_ceil ceilq
+# define Perl_cos cosq
+# define Perl_cosh coshq
+# define Perl_exp expq
+/* no Perl_fabs, but there's PERL_ABS */
+# define Perl_floor floorq
+# define Perl_fmod fmodq
+# define Perl_log logq
+# define Perl_log10 log10q
+# define Perl_pow powq
+# define Perl_sin sinq
+# define Perl_sinh sinhq
+# define Perl_sqrt sqrtq
+# define Perl_tan tanq
+# define Perl_tanh tanhq
+# define Perl_modf(x,y) modfq(x,y)
+# define Perl_frexp(x,y) frexpq(x,y)
+# define Perl_ldexp(x, y) ldexpq(x,y)
+# define Perl_isinf(x) isinfq(x)
+# define Perl_isnan(x) isnanq(x)
+# define Perl_isfinite(x) !(isnanq(x) || isinfq(x))
#else
# define NV_DIG DBL_DIG
# ifdef DBL_MANT_DIG
@@ -1898,6 +2035,12 @@ EXTERN_C long double modfl(long double, long double *);
# ifdef DBL_MAX
# define NV_MAX DBL_MAX
# endif
+# ifdef DBL_MIN_EXP
+# define NV_MIN_EXP DBL_MIN_EXP
+# endif
+# ifdef DBL_MAX_EXP
+# define NV_MAX_EXP DBL_MAX_EXP
+# endif
# ifdef DBL_MIN_10_EXP
# define NV_MIN_10_EXP DBL_MIN_10_EXP
# endif
@@ -1915,30 +2058,121 @@ EXTERN_C long double modfl(long double, long double *);
# define NV_MAX HUGE_VAL
# endif
# endif
+
+/* These math interfaces are C89. */
+# define Perl_acos acos
+# define Perl_asin asin
+# define Perl_atan atan
+# define Perl_atan2 atan2
+# define Perl_ceil ceil
# define Perl_cos cos
-# define Perl_sin sin
-# define Perl_sqrt sqrt
+# define Perl_cosh cosh
# define Perl_exp exp
-# define Perl_log log
-# define Perl_atan2 atan2
-# define Perl_pow pow
+/* no Perl_fabs, but there's PERL_ABS */
# define Perl_floor floor
-# define Perl_ceil ceil
# define Perl_fmod fmod
+# define Perl_log log
+# define Perl_log10 log10
+# define Perl_pow pow
+# define Perl_sin sin
+# define Perl_sinh sinh
+# define Perl_sqrt sqrt
+# define Perl_tan tan
+# define Perl_tanh tanh
+
# define Perl_modf(x,y) modf(x,y)
# define Perl_frexp(x,y) frexp(x,y)
+# define Perl_ldexp(x,y) ldexp(x,y)
+
+# ifndef Perl_isnan
+# ifdef HAS_ISNAN
+# define Perl_isnan(x) isnan(x)
+# endif
+# endif
+# ifndef Perl_isinf
+# if defined(HAS_ISINF)
+# define Perl_isinf(x) isinf(x)
+# elif defined(DBL_MAX) && !defined(NAN_COMPARE_BROKEN)
+# define Perl_isinf(x) ((x) > DBL_MAX || (x) < -DBL_MAX)
+# endif
+# endif
+# ifndef Perl_isfinite
+# ifdef HAS_ISFINITE
+# define Perl_isfinite(x) isfinite(x)
+# elif defined(HAS_FINITE)
+# define Perl_isfinite(x) finite(x)
+# endif
+# endif
#endif
-/* rumor has it that Win32 has _fpclass() */
+/* fpclassify(): C99. It is supposed to be a macro that switches on
+* the sizeof() of its argument, so there's no need for e.g. fpclassifyl().*/
+#if !defined(Perl_fp_class) && defined(HAS_FPCLASSIFY)
+# include <math.h>
+# if defined(FP_INFINITE) && defined(FP_NAN)
+# define Perl_fp_class(x) fpclassify(x)
+# define Perl_fp_class_inf(x) (Perl_fp_class(x)==FP_INFINITE)
+# define Perl_fp_class_nan(x) (Perl_fp_class(x)==FP_NAN)
+# define Perl_fp_class_norm(x) (Perl_fp_class(x)==FP_NORMAL)
+# define Perl_fp_class_denorm(x) (Perl_fp_class(x)==FP_SUBNORMAL)
+# define Perl_fp_class_zero(x) (Perl_fp_class(x)==FP_ZERO)
+# elif defined(FP_PLUS_INF) && defined(FP_QNAN)
+/* Some versions of HP-UX (10.20) have (only) fpclassify() but which is
+ * actually not the C99 fpclassify, with its own set of return defines. */
+# define Perl_fp_class(x) fpclassify(x)
+# define Perl_fp_class_pinf(x) (Perl_fp_class(x)==FP_PLUS_INF)
+# define Perl_fp_class_ninf(x) (Perl_fp_class(x)==FP_MINUS_INF)
+# define Perl_fp_class_snan(x) (Perl_fp_class(x)==FP_SNAN)
+# define Perl_fp_class_qnan(x) (Perl_fp_class(x)==FP_QNAN)
+# define Perl_fp_class_pnorm(x) (Perl_fp_class(x)==FP_PLUS_NORM)
+# define Perl_fp_class_nnorm(x) (Perl_fp_class(x)==FP_MINUS_NORM)
+# define Perl_fp_class_pdenorm(x) (Perl_fp_class(x)==FP_PLUS_DENORM)
+# define Perl_fp_class_ndenorm(x) (Perl_fp_class(x)==FP_MINUS_DENORM)
+# define Perl_fp_class_pzero(x) (Perl_fp_class(x)==FP_PLUS_ZERO)
+# define Perl_fp_class_nzero(x) (Perl_fp_class(x)==FP_MINUS_ZERO)
+# else
+# undef Perl_fp_class /* Unknown set of defines */
+# endif
+#endif
+
+/* fp_classify(): Legacy: VMS, maybe Unicos? The values, however,
+ * are identical to the C99 fpclassify(). */
+#if !defined(Perl_fp_class) && defined(HAS_FP_CLASSIFY)
+# include <math.h>
+# ifdef __VMS
+ /* FP_INFINITE and others are here rather than in math.h as C99 stipulates */
+# include <fp.h>
+ /* oh, and the isnormal macro has a typo in it! */
+# undef isnormal
+# define isnormal(x) Perl_fp_class_norm(x)
+# endif
+# if defined(FP_INFINITE) && defined(FP_NAN)
+# define Perl_fp_class(x) fp_classify(x)
+# define Perl_fp_class_inf(x) (Perl_fp_class(x)==FP_INFINITE)
+# define Perl_fp_class_nan(x) (Perl_fp_class(x)==FP_NAN)
+# define Perl_fp_class_norm(x) (Perl_fp_class(x)==FP_NORMAL)
+# define Perl_fp_class_denorm(x) (Perl_fp_class(x)==FP_SUBNORMAL)
+# define Perl_fp_class_zero(x) (Perl_fp_class(x)==FP_ZERO)
+# else
+# undef Perl_fp_class /* Unknown set of defines */
+# endif
+#endif
-/* SGI has fpclassl... but not with the same result values,
- * and it's via a typedef (not via #define), so will need to redo Configure
- * to use. Not worth the trouble, IMO, at least until the below is used
- * more places. Also has fp_class_l, BTW, via fp_class.h. Feel free to check
- * with me for the SGI manpages, SGI testing, etcetera, if you want to
- * try getting this to work with IRIX. - Allen <allens@cpan.org> */
+/* Feel free to check with me for the SGI manpages, SGI testing,
+ * etcetera, if you want to try getting this to work with IRIX.
+ *
+ * - Allen <allens@cpan.org> */
+/* fpclass(): SysV, at least Solaris and some versions of IRIX. */
#if !defined(Perl_fp_class) && (defined(HAS_FPCLASS)||defined(HAS_FPCLASSL))
+/* Solaris and IRIX have fpclass/fpclassl, but they are using
+ * an enum typedef, not cpp symbols, and Configure doesn't detect that.
+ * Define some symbols also as cpp symbols so we can detect them. */
+# if defined(__sun) || defined(__irix__) /* XXX Configure test instead */
+# define FP_PINF FP_PINF
+# define FP_QNAN FP_QNAN
+# endif
+# include <math.h>
# ifdef I_IEEFP
# include <ieeefp.h>
# endif
@@ -1946,134 +2180,221 @@ EXTERN_C long double modfl(long double, long double *);
# include <fp.h>
# endif
# if defined(USE_LONG_DOUBLE) && defined(HAS_FPCLASSL)
-# define Perl_fp_class() fpclassl(x)
+# define Perl_fp_class(x) fpclassl(x)
# else
-# define Perl_fp_class() fpclass(x)
+# define Perl_fp_class(x) fpclass(x)
# endif
-# define Perl_fp_class_snan(x) (Perl_fp_class(x)==FP_CLASS_SNAN)
-# define Perl_fp_class_qnan(x) (Perl_fp_class(x)==FP_CLASS_QNAN)
-# define Perl_fp_class_nan(x) (Perl_fp_class(x)==FP_CLASS_SNAN||Perl_fp_class(x)==FP_CLASS_QNAN)
-# define Perl_fp_class_ninf(x) (Perl_fp_class(x)==FP_CLASS_NINF)
-# define Perl_fp_class_pinf(x) (Perl_fp_class(x)==FP_CLASS_PINF)
-# define Perl_fp_class_inf(x) (Perl_fp_class(x)==FP_CLASS_NINF||Perl_fp_class(x)==FP_CLASS_PINF)
-# define Perl_fp_class_nnorm(x) (Perl_fp_class(x)==FP_CLASS_NNORM)
-# define Perl_fp_class_pnorm(x) (Perl_fp_class(x)==FP_CLASS_PNORM)
-# define Perl_fp_class_norm(x) (Perl_fp_class(x)==FP_CLASS_NNORM||Perl_fp_class(x)==FP_CLASS_PNORM)
-# define Perl_fp_class_ndenorm(x) (Perl_fp_class(x)==FP_CLASS_NDENORM)
-# define Perl_fp_class_pdenorm(x) (Perl_fp_class(x)==FP_CLASS_PDENORM)
-# define Perl_fp_class_denorm(x) (Perl_fp_class(x)==FP_CLASS_NDENORM||Perl_fp_class(x)==FP_CLASS_PDENORM)
-# define Perl_fp_class_nzero(x) (Perl_fp_class(x)==FP_CLASS_NZERO)
-# define Perl_fp_class_pzero(x) (Perl_fp_class(x)==FP_CLASS_PZERO)
-# define Perl_fp_class_zero(x) (Perl_fp_class(x)==FP_CLASS_NZERO||Perl_fp_class(x)==FP_CLASS_PZERO)
-#endif
-
-#if !defined(Perl_fp_class) && defined(HAS_FP_CLASS)
-# include <math.h>
-# if !defined(FP_SNAN) && defined(I_FP_CLASS)
-# include <fp_class.h>
+# if defined(FP_CLASS_PINF) && defined(FP_CLASS_SNAN)
+# define Perl_fp_class_snan(x) (Perl_fp_class(x)==FP_CLASS_SNAN)
+# define Perl_fp_class_qnan(x) (Perl_fp_class(x)==FP_CLASS_QNAN)
+# define Perl_fp_class_ninf(x) (Perl_fp_class(x)==FP_CLASS_NINF)
+# define Perl_fp_class_pinf(x) (Perl_fp_class(x)==FP_CLASS_PINF)
+# define Perl_fp_class_nnorm(x) (Perl_fp_class(x)==FP_CLASS_NNORM)
+# define Perl_fp_class_pnorm(x) (Perl_fp_class(x)==FP_CLASS_PNORM)
+# define Perl_fp_class_ndenorm(x) (Perl_fp_class(x)==FP_CLASS_NDENORM)
+# define Perl_fp_class_pdenorm(x) (Perl_fp_class(x)==FP_CLASS_PDENORM)
+# define Perl_fp_class_nzero(x) (Perl_fp_class(x)==FP_CLASS_NZERO)
+# define Perl_fp_class_pzero(x) (Perl_fp_class(x)==FP_CLASS_PZERO)
+# elif defined(FP_PINF) && defined(FP_QNAN)
+# define Perl_fp_class_snan(x) (Perl_fp_class(x)==FP_SNAN)
+# define Perl_fp_class_qnan(x) (Perl_fp_class(x)==FP_QNAN)
+# define Perl_fp_class_ninf(x) (Perl_fp_class(x)==FP_NINF)
+# define Perl_fp_class_pinf(x) (Perl_fp_class(x)==FP_PINF)
+# define Perl_fp_class_nnorm(x) (Perl_fp_class(x)==FP_NNORM)
+# define Perl_fp_class_pnorm(x) (Perl_fp_class(x)==FP_PNORM)
+# define Perl_fp_class_ndenorm(x) (Perl_fp_class(x)==FP_NDENORM)
+# define Perl_fp_class_pdenorm(x) (Perl_fp_class(x)==FP_PDENORM)
+# define Perl_fp_class_nzero(x) (Perl_fp_class(x)==FP_NZERO)
+# define Perl_fp_class_pzero(x) (Perl_fp_class(x)==FP_PZERO)
+# else
+# undef Perl_fp_class /* Unknown set of defines */
# endif
-# define Perl_fp_class(x) fp_class(x)
-# define Perl_fp_class_snan(x) (fp_class(x)==FP_SNAN)
-# define Perl_fp_class_qnan(x) (fp_class(x)==FP_QNAN)
-# define Perl_fp_class_nan(x) (fp_class(x)==FP_SNAN||fp_class(x)==FP_QNAN)
-# define Perl_fp_class_ninf(x) (fp_class(x)==FP_NEG_INF)
-# define Perl_fp_class_pinf(x) (fp_class(x)==FP_POS_INF)
-# define Perl_fp_class_inf(x) (fp_class(x)==FP_NEG_INF||fp_class(x)==FP_POS_INF)
-# define Perl_fp_class_nnorm(x) (fp_class(x)==FP_NEG_NORM)
-# define Perl_fp_class_pnorm(x) (fp_class(x)==FP_POS_NORM)
-# define Perl_fp_class_norm(x) (fp_class(x)==FP_NEG_NORM||fp_class(x)==FP_POS_NORM)
-# define Perl_fp_class_ndenorm(x) (fp_class(x)==FP_NEG_DENORM)
-# define Perl_fp_class_pdenorm(x) (fp_class(x)==FP_POS_DENORM)
-# define Perl_fp_class_denorm(x) (fp_class(x)==FP_NEG_DENORM||fp_class(x)==FP_POS_DENORM)
-# define Perl_fp_class_nzero(x) (fp_class(x)==FP_NEG_ZERO)
-# define Perl_fp_class_pzero(x) (fp_class(x)==FP_POS_ZERO)
-# define Perl_fp_class_zero(x) (fp_class(x)==FP_NEG_ZERO||fp_class(x)==FP_POS_ZERO)
#endif
-#if !defined(Perl_fp_class) && defined(HAS_FPCLASSIFY)
+/* fp_class(): Legacy: at least Tru64, some versions of IRIX. */
+#if !defined(Perl_fp_class) && (defined(HAS_FP_CLASS)||defined(HAS_FP_CLASSL))
# include <math.h>
-# define Perl_fp_class(x) fpclassify(x)
-# define Perl_fp_class_nan(x) (fp_classify(x)==FP_SNAN||fp_classify(x)==FP_QNAN)
-# define Perl_fp_class_inf(x) (fp_classify(x)==FP_INFINITE)
-# define Perl_fp_class_norm(x) (fp_classify(x)==FP_NORMAL)
-# define Perl_fp_class_denorm(x) (fp_classify(x)==FP_SUBNORMAL)
-# define Perl_fp_class_zero(x) (fp_classify(x)==FP_ZERO)
+# if !defined(FP_SNAN) && defined(I_FP_CLASS)
+# include <fp_class.h>
+# endif
+# if defined(FP_POS_INF) && defined(FP_QNAN)
+# ifdef __irix__ /* XXX Configure test instead */
+# ifdef USE_LONG_DOUBLE
+# define Perl_fp_class(x) fp_class_l(x)
+# else
+# define Perl_fp_class(x) fp_class_d(x)
+# endif
+# else
+# if defined(USE_LONG_DOUBLE) && defined(HAS_FP_CLASSL)
+# define Perl_fp_class(x) fp_classl(x)
+# else
+# define Perl_fp_class(x) fp_class(x)
+# endif
+# endif
+# if defined(FP_POS_INF) && defined(FP_QNAN)
+# define Perl_fp_class_snan(x) (Perl_fp_class(x)==FP_SNAN)
+# define Perl_fp_class_qnan(x) (Perl_fp_class(x)==FP_QNAN)
+# define Perl_fp_class_ninf(x) (Perl_fp_class(x)==FP_NEG_INF)
+# define Perl_fp_class_pinf(x) (Perl_fp_class(x)==FP_POS_INF)
+# define Perl_fp_class_nnorm(x) (Perl_fp_class(x)==FP_NEG_NORM)
+# define Perl_fp_class_pnorm(x) (Perl_fp_class(x)==FP_POS_NORM)
+# define Perl_fp_class_ndenorm(x) (Perl_fp_class(x)==FP_NEG_DENORM)
+# define Perl_fp_class_pdenorm(x) (Perl_fp_class(x)==FP_POS_DENORM)
+# define Perl_fp_class_nzero(x) (Perl_fp_class(x)==FP_NEG_ZERO)
+# define Perl_fp_class_pzero(x) (Perl_fp_class(x)==FP_POS_ZERO)
+# else
+# undef Perl_fp_class /* Unknown set of defines */
+# endif
+# endif
#endif
+/* class(), _class(): Legacy: AIX. */
#if !defined(Perl_fp_class) && defined(HAS_CLASS)
# include <math.h>
-# ifndef _cplusplus
-# define Perl_fp_class(x) class(x)
-# else
-# define Perl_fp_class(x) _class(x)
+# if defined(FP_PLUS_NORM) && defined(FP_PLUS_INF)
+# ifndef _cplusplus
+# define Perl_fp_class(x) class(x)
+# else
+# define Perl_fp_class(x) _class(x)
+# endif
+# if defined(FP_PLUS_INF) && defined(FP_NANQ)
+# define Perl_fp_class_snan(x) (Perl_fp_class(x)==FP_NANS)
+# define Perl_fp_class_qnan(x) (Perl_fp_class(x)==FP_NANQ)
+# define Perl_fp_class_ninf(x) (Perl_fp_class(x)==FP_MINUS_INF)
+# define Perl_fp_class_pinf(x) (Perl_fp_class(x)==FP_PLUS_INF)
+# define Perl_fp_class_nnorm(x) (Perl_fp_class(x)==FP_MINUS_NORM)
+# define Perl_fp_class_pnorm(x) (Perl_fp_class(x)==FP_PLUS_NORM)
+# define Perl_fp_class_ndenorm(x) (Perl_fp_class(x)==FP_MINUS_DENORM)
+# define Perl_fp_class_pdenorm(x) (Perl_fp_class(x)==FP_PLUS_DENORM)
+# define Perl_fp_class_nzero(x) (Perl_fp_class(x)==FP_MINUS_ZERO)
+# define Perl_fp_class_pzero(x) (Perl_fp_class(x)==FP_PLUS_ZERO)
+# else
+# undef Perl_fp_class /* Unknown set of defines */
+# endif
# endif
-# define Perl_fp_class_snan(x) (Perl_fp_class(x)==FP_NANS)
-# define Perl_fp_class_qnan(x) (Perl_fp_class(x)==FP_NANQ)
-# define Perl_fp_class_nan(x) (Perl_fp_class(x)==FP_SNAN||Perl_fp_class(x)==FP_QNAN)
-# define Perl_fp_class_ninf(x) (Perl_fp_class(x)==FP_MINUS_INF)
-# define Perl_fp_class_pinf(x) (Perl_fp_class(x)==FP_PLUS_INF)
-# define Perl_fp_class_inf(x) (Perl_fp_class(x)==FP_MINUS_INF||Perl_fp_class(x)==FP_PLUS_INF)
-# define Perl_fp_class_nnorm(x) (Perl_fp_class(x)==FP_MINUS_NORM)
-# define Perl_fp_class_pnorm(x) (Perl_fp_class(x)==FP_PLUS_NORM)
-# define Perl_fp_class_norm(x) (Perl_fp_class(x)==FP_MINUS_NORM||Perl_fp_class(x)==FP_PLUS_NORM)
-# define Perl_fp_class_ndenorm(x) (Perl_fp_class(x)==FP_MINUS_DENORM)
-# define Perl_fp_class_pdenorm(x) (Perl_fp_class(x)==FP_PLUS_DENORM)
-# define Perl_fp_class_denorm(x) (Perl_fp_class(x)==FP_MINUS_DENORM||Perl_fp_class(x)==FP_PLUS_DENORM)
-# define Perl_fp_class_nzero(x) (Perl_fp_class(x)==FP_MINUS_ZERO)
-# define Perl_fp_class_pzero(x) (Perl_fp_class(x)==FP_PLUS_ZERO)
-# define Perl_fp_class_zero(x) (Perl_fp_class(x)==FP_MINUS_ZERO||Perl_fp_class(x)==FP_PLUS_ZERO)
-#endif
-
-/* rumor has it that Win32 has _isnan() */
+#endif
-#ifndef Perl_isnan
-# ifdef HAS_ISNAN
-# define Perl_isnan(x) isnan((NV)x)
-# else
-# ifdef Perl_fp_class_nan
-# define Perl_isnan(x) Perl_fp_class_nan(x)
-# else
-# ifdef HAS_UNORDERED
-# define Perl_isnan(x) unordered((x), 0.0)
-# else
-# define Perl_isnan(x) ((x)!=(x))
-# endif
-# endif
-# endif
+/* Win32: _fpclass(), _isnan(), _finite(). */
+#ifdef WIN32
+# ifndef Perl_isnan
+# define Perl_isnan(x) _isnan(x)
+# endif
+# ifndef Perl_isfinite
+# define Perl_isfinite(x) _finite(x)
+# endif
+# ifndef Perl_fp_class_snan
+/* No simple way to #define Perl_fp_class because _fpclass()
+ * returns a set of bits. */
+# define Perl_fp_class_snan(x) (_fpclass(x) & _FPCLASS_SNAN)
+# define Perl_fp_class_qnan(x) (_fpclass(x) & _FPCLASS_QNAN)
+# define Perl_fp_class_nan(x) (_fpclass(x) & (_FPCLASS_SNAN|_FPCLASS_QNAN))
+# define Perl_fp_class_ninf(x) (_fpclass(x) & _FPCLASS_NINF))
+# define Perl_fp_class_pinf(x) (_fpclass(x) & _FPCLASS_PINF))
+# define Perl_fp_class_inf(x) (_fpclass(x) & (_FPCLASS_NINF|_FPCLASS_PINF))
+# define Perl_fp_class_nnorm(x) (_fpclass(x) & _FPCLASS_NN)
+# define Perl_fp_class_pnorm(x) (_fpclass(x) & _FPCLASS_PN)
+# define Perl_fp_class_norm(x) (_fpclass(x) & (_FPCLASS_NN|_FPCLASS_PN))
+# define Perl_fp_class_ndenorm(x) (_fpclass(x) & _FPCLASS_ND)
+# define Perl_fp_class_pdenorm(x) (_fpclass(x) & _FPCLASS_PD)
+# define Perl_fp_class_denorm(x) (_fpclass(x) & (_FPCLASS_ND|_FPCLASS_PD))
+# define Perl_fp_class_nzero(x) (_fpclass(x) & _FPCLASS_NZ)
+# define Perl_fp_class_pzero(x) (_fpclass(x) & _FPCLASS_PZ)
+# define Perl_fp_class_zero(x) (_fpclass(x) & (_FPCLASS_NZ|_FPCLASS_PZ))
+# endif
+#endif
+
+#if !defined(Perl_fp_class_inf) && \
+ defined(Perl_fp_class_pinf) && defined(Perl_fp_class_ninf)
+# define Perl_fp_class_inf(x) \
+ (Perl_fp_class_pinf(x) || Perl_fp_class_ninf(x))
+#endif
+
+#if !defined(Perl_fp_class_nan) && \
+ defined(Perl_fp_class_snan) && defined(Perl_fp_class_qnan)
+# define Perl_fp_class_nan(x) \
+ (Perl_fp_class_snan(x) || Perl_fp_class_qnan(x))
+#endif
+
+#if !defined(Perl_fp_class_zero) && \
+ defined(Perl_fp_class_pzero) && defined(Perl_fp_class_nzero)
+# define Perl_fp_class_zero(x) \
+ (Perl_fp_class_pzero(x) || Perl_fp_class_nzero(x))
+#endif
+
+#if !defined(Perl_fp_class_norm) && \
+ defined(Perl_fp_class_pnorm) && defined(Perl_fp_class_nnorm)
+# define Perl_fp_class_norm(x) \
+ (Perl_fp_class_pnorm(x) || Perl_fp_class_nnorm(x))
+#endif
+
+#if !defined(Perl_fp_class_denorm) && \
+ defined(Perl_fp_class_pdenorm) && defined(Perl_fp_class_ndenorm)
+# define Perl_fp_class_denorm(x) \
+ (Perl_fp_class_pdenorm(x) || Perl_fp_class_ndenorm(x))
#endif
#ifdef UNDER_CE
int isnan(double d);
#endif
-#ifndef Perl_isinf
-# ifdef HAS_ISINF
-# define Perl_isinf(x) isinf((NV)x)
+#ifndef Perl_isnan
+# ifdef Perl_fp_class_nan
+# define Perl_isnan(x) Perl_fp_class_nan(x)
# else
-# ifdef Perl_fp_class_inf
-# define Perl_isinf(x) Perl_fp_class_inf(x)
+# ifdef HAS_UNORDERED
+# define Perl_isnan(x) unordered((x), 0.0)
# else
-# define Perl_isinf(x) ((x)==NV_INF)
+# define Perl_isnan(x) ((x)!=(x))
# endif
# endif
#endif
+#ifndef Perl_isinf
+# ifdef Perl_fp_class_inf
+# define Perl_isinf(x) Perl_fp_class_inf(x)
+# endif
+#endif
+
#ifndef Perl_isfinite
-# ifdef HAS_FINITE
-# define Perl_isfinite(x) finite((NV)x)
+# if defined(HAS_ISFINITE) && !defined(isfinite)
+# define Perl_isfinite(x) isfinite((double)(x))
+# elif defined(HAS_FINITE)
+# define Perl_isfinite(x) finite((double)(x))
+# elif defined(Perl_fp_class_finite)
+# define Perl_isfinite(x) Perl_fp_class_finite(x)
# else
-# ifdef HAS_ISFINITE
-# define Perl_isfinite(x) isfinite(x)
-# else
-# ifdef Perl_fp_class_finite
-# define Perl_isfinite(x) Perl_fp_class_finite(x)
-# else
-# define Perl_isfinite(x) !(Perl_is_inf(x)||Perl_is_nan(x))
-# endif
-# endif
+/* For the infinities the multiplication returns nan,
+ * for the nan the multiplication also returns nan,
+ * for everything else (that is, finite) zero should be returned. */
+# define Perl_isfinite(x) (((x) * 0) == 0)
# endif
#endif
+#ifndef Perl_isinf
+# if defined(Perl_isfinite) && defined(Perl_isnan)
+# define Perl_isinf(x) !(Perl_isfinite(x)||Perl_isnan(x))
+# endif
+#endif
+
+/* We need Perl_isfinitel (ends with ell) (if available) even when
+ * not USE_LONG_DOUBLE because the printf code (sv_catpvfn_flags)
+ * needs that. */
+#if defined(HAS_LONG_DOUBLE) && !defined(Perl_isfinitel)
+/* If isfinite() is a macro and looks like we have C99,
+ * we assume it's the type-aware C99 isfinite(). */
+# if defined(HAS_ISFINITE) && defined(isfinite) && defined(HAS_C99)
+# define Perl_isfinitel(x) isfinite(x)
+# elif defined(HAS_ISFINITEL)
+# define Perl_isfinitel(x) isfinitel(x)
+# elif defined(HAS_FINITEL)
+# define Perl_isfinitel(x) finitel(x)
+# elif defined(HAS_INFL) && defined(HAS_NANL)
+# define Perl_isfinitel(x) !(isinfl(x)||isnanl(x))
+# else
+# define Perl_isfinitel(x) ((x) * 0 == 0) /* See Perl_isfinite. */
+# endif
+#endif
+
/* The default is to use Perl's own atof() implementation (in numeric.c).
* Usually that is the one to use but for some platforms (e.g. UNICOS)
* it is however best to use the native implementation of atof.
@@ -2278,14 +2599,10 @@ int isnan(double d);
typedef MEM_SIZE STRLEN;
-#ifdef PERL_MAD
-typedef struct token TOKEN;
-typedef struct madprop MADPROP;
-typedef struct nexttoken NEXTTOKE;
-#endif
typedef struct op OP;
typedef struct cop COP;
typedef struct unop UNOP;
+typedef struct unop_aux UNOP_AUX;
typedef struct binop BINOP;
typedef struct listop LISTOP;
typedef struct logop LOGOP;
@@ -2294,6 +2611,7 @@ typedef struct svop SVOP;
typedef struct padop PADOP;
typedef struct pvop PVOP;
typedef struct loop LOOP;
+typedef struct methop METHOP;
#ifdef PERL_CORE
typedef struct opslab OPSLAB;
@@ -2343,12 +2661,12 @@ typedef struct ptr_tbl_ent PTR_TBL_ENT_t;
typedef struct ptr_tbl PTR_TBL_t;
typedef struct clone_params CLONE_PARAMS;
-/* a pad or name pad is currently just an AV; but that might change,
+/* a pad is currently just an AV; but that might change,
* so hide the type. */
typedef struct padlist PADLIST;
typedef AV PAD;
-typedef AV PADNAMELIST;
-typedef SV PADNAME;
+typedef struct padnamelist PADNAMELIST;
+typedef struct padname PADNAME;
/* enable PERL_NEW_COPY_ON_WRITE by default */
#if !defined(PERL_OLD_COPY_ON_WRITE) && !defined(PERL_NEW_COPY_ON_WRITE) && !defined(PERL_NO_COW)
@@ -2365,7 +2683,12 @@ typedef SV PADNAME;
# define PERL_SAWAMPERSAND
#endif
+#if defined(PERL_DEBUG_READONLY_OPS) && !defined(USE_ITHREADS)
+# error PERL_DEBUG_READONLY_OPS only works with ithreads
+#endif
+
#include "handy.h"
+#include "charclass_invlists.h"
#if defined(USE_LARGE_FILES) && !defined(NO_64_BIT_RAWIO)
# if LSEEKSIZE == 8 && !defined(USE_64_BIT_RAWIO)
@@ -2586,11 +2909,50 @@ typedef SV PADNAME;
# define PERL_FPU_POST_EXEC }
#endif
+/* In Tru64 the cc -ieee enables the IEEE math but disables traps.
+ * We need to reenable the "invalid" trap because otherwise generation
+ * of NaN values leaves the IEEE fp flags in bad state, leaving any further
+ * fp ops behaving strangely (Inf + 1 resulting in zero, for example). */
+#ifdef __osf__
+# include <machine/fpu.h>
+# define PERL_SYS_FPU_INIT \
+ STMT_START { \
+ ieee_set_fp_control(IEEE_TRAP_ENABLE_INV); \
+ signal(SIGFPE, SIG_IGN); \
+ } STMT_END
+#endif
+/* In IRIX the default for Flush to Zero bit is true,
+ * which means that results going below the minimum of normal
+ * floating points go to zero, instead of going denormal/subnormal.
+ * This is unlike almost any other system running Perl, so let's clear it.
+ * [perl #123767] IRIX64 blead (ddce084a) opbasic/arith.t failure, originally
+ * [perl #120426] small numbers shouldn't round to zero if they have extra floating digits
+ *
+ * XXX The flush-to-zero behaviour should be a Configure scan.
+ * To change the behaviour usually requires some system-specific
+ * incantation, though, like the below. */
+#ifdef __sgi
+# include <sys/fpu.h>
+# define PERL_SYS_FPU_INIT \
+ STMT_START { \
+ union fpc_csr csr; \
+ csr.fc_word = get_fpc_csr(); \
+ csr.fc_struct.flush = 0; \
+ set_fpc_csr(csr.fc_word); \
+ } STMT_END
+#endif
+
+#ifndef PERL_SYS_FPU_INIT
+# define PERL_SYS_FPU_INIT NOOP
+#endif
+
#ifndef PERL_SYS_INIT3_BODY
# define PERL_SYS_INIT3_BODY(argvp,argcp,envp) PERL_SYS_INIT_BODY(argvp,argcp)
#endif
/*
+=head1 Miscellaneous Functions
+
=for apidoc Am|void|PERL_SYS_INIT|int *argc|char*** argv
Provides system-specific tune up of the C runtime environment necessary to
run Perl interpreters. This should be called only once, before creating
@@ -2705,9 +3067,6 @@ freeing any remaining Perl interpreters.
# else
# ifdef I_MACH_CTHREADS
# include <mach/cthreads.h>
-# if (defined(NeXT) || defined(__NeXT__)) && defined(PERL_POLLUTE_MALLOC)
-# define MUTEX_INIT_CALLS_MALLOC
-# endif
typedef cthread_t perl_os_thread;
typedef mutex_t perl_mutex;
typedef condition_t perl_cond;
@@ -3078,6 +3437,9 @@ typedef pthread_key_t perl_key;
#endif
#define UTF8fARG(u,l,p) (int)cBOOL(u), (UV)(l), (void*)(p)
+#define PNf UTF8f
+#define PNfARG(pn) (int)1, (UV)PadnameLEN(pn), (void *)PadnamePV(pn)
+
#ifdef PERL_CORE
/* not used; but needed for backward compatibility with XS code? - RMB */
# undef UVf
@@ -3138,6 +3500,13 @@ typedef pthread_key_t perl_key;
# define __attribute__warn_unused_result__
#endif
+#ifdef I_ASSERT
+# if !defined(DEBUGGING) && !defined(NDEBUG)
+# define NDEBUG 1
+# endif
+# include <assert.h>
+#endif
+
/* For functions that are marked as __attribute__noreturn__, it's not
appropriate to call return. In either case, include the lint directive.
*/
@@ -3165,6 +3534,40 @@ typedef pthread_key_t perl_key;
/* placeholder */
#endif
+/* STATIC_ASSERT_GLOBAL/STATIC_ASSERT_STMT are like assert(), but for compile
+ time invariants. That is, their argument must be a constant expression that
+ can be verified by the compiler. This expression can contain anything that's
+ known to the compiler, e.g. #define constants, enums, or sizeof (...). If
+ the expression evaluates to 0, compilation fails.
+ Because they generate no runtime code (i.e. their use is "free"), they're
+ always active, even under non-DEBUGGING builds.
+ STATIC_ASSERT_GLOBAL expands to a declaration and is suitable for use at
+ file scope (outside of any function).
+ STATIC_ASSERT_STMT expands to a statement and is suitable for use inside a
+ function.
+*/
+#if (defined(static_assert) || (defined(__cplusplus) && __cplusplus >= 201103L)) && (!defined(__IBMC__) || __IBMC__ >= 1210)
+/* static_assert is a macro defined in <assert.h> in C11 or a compiler
+ builtin in C++11.
+*/
+/* IBM XL C V11 does not support _Static_assert, no matter what <assert.h> says */
+# define STATIC_ASSERT_GLOBAL(COND) static_assert(COND, #COND)
+#else
+/* We use a bit-field instead of an array because gcc accepts
+ 'typedef char x[n]' where n is not a compile-time constant.
+ We want to enforce constantness.
+*/
+# define STATIC_ASSERT_2(COND, SUFFIX) \
+ typedef struct { \
+ unsigned int _static_assertion_failed_##SUFFIX : (COND) ? 1 : -1; \
+ } _static_assertion_failed_##SUFFIX PERL_UNUSED_DECL
+# define STATIC_ASSERT_1(COND, SUFFIX) STATIC_ASSERT_2(COND, SUFFIX)
+# define STATIC_ASSERT_GLOBAL(COND) STATIC_ASSERT_1(COND, __LINE__)
+#endif
+/* We need this wrapper even in C11 because 'case X: static_assert(...);' is an
+ error (static_assert is a declaration, and only statements can have labels).
+*/
+#define STATIC_ASSERT_STMT(COND) do { STATIC_ASSERT_GLOBAL(COND); } while (0)
#ifndef __has_builtin
# define __has_builtin(x) 0 /* not a clang style compiler */
@@ -3175,13 +3578,13 @@ typedef pthread_key_t perl_key;
expression, which allows the compiler to generate better machine code.
In a debug build, ASSUME(x) is a synonym for assert(x). ASSUME(0) means
the control path is unreachable. In a for loop, ASSUME can be used to hint
- that a loop will run atleast X times. ASSUME is based off MSVC's __assume
+ that a loop will run at least X times. ASSUME is based off MSVC's __assume
intrinsic function, see its documents for more details.
*/
#ifndef DEBUGGING
# if __has_builtin(__builtin_unreachable) \
- || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5 || __GNUC__ > 5) /* 4.5 -> */
+ || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5 || __GNUC__ > 4) /* 4.5 -> */
# define ASSUME(x) ((x) ? (void) 0 : __builtin_unreachable())
# elif defined(_MSC_VER)
# define ASSUME(x) __assume(x)
@@ -3313,13 +3716,6 @@ typedef struct crypt_data { /* straight from /usr/include/crypt.h */
#endif
#include "perly.h"
-#ifdef PERL_MAD
-struct nexttoken {
- YYSTYPE next_val; /* value of next token, if any */
- I32 next_type; /* type of next token */
- MADPROP *next_mad; /* everything else about that token */
-};
-#endif
/* macros to define bit-fields in structs. */
#ifndef PERL_BITFIELD8
@@ -3682,6 +4078,7 @@ Gid_t getegid (void);
# define DEBUG_Pv_TEST DEBUG_Pv_TEST_
# define PERL_DEB(a) a
+# define PERL_DEB2(a,b) a
# define PERL_DEBUG(a) if (PL_debug) a
# define DEBUG_p(a) if (DEBUG_p_TEST) a
# define DEBUG_s(a) if (DEBUG_s_TEST) a
@@ -3764,6 +4161,7 @@ Gid_t getegid (void);
# define DEBUG_Pv_TEST (0)
# define PERL_DEB(a)
+# define PERL_DEB2(a,b) b
# define PERL_DEBUG(a)
# define DEBUG_p(a)
# define DEBUG_s(a)
@@ -3803,19 +4201,17 @@ Gid_t getegid (void);
where, (long)PL_scopestack_ix, (long)PL_savestack_ix, \
__FILE__, __LINE__));
-#if defined(DEBUGGING) && defined(I_ASSERT)
-# include <assert.h>
-#endif
-
/* Keep the old croak based assert for those who want it, and as a fallback if
the platform is so heretically non-ANSI that it can't assert. */
-#define Perl_assert(what) PERL_DEB( \
+#define Perl_assert(what) PERL_DEB2( \
((what) ? ((void) 0) : \
(Perl_croak_nocontext("Assertion %s failed: file \"" __FILE__ \
"\", line %d", STRINGIFY(what), __LINE__), \
- (void) 0)))
+ (void) 0)), ((void)0))
+/* assert() gets defined if DEBUGGING (and I_ASSERT).
+ * If no DEBUGGING, the <assert.h> has not been included. */
#ifndef assert
# define assert(what) Perl_assert(what)
#endif
@@ -3877,6 +4273,10 @@ char *strcpy(), *strcat();
#ifdef I_MATH
# include <math.h>
+# ifdef __VMS
+ /* isfinite and others are here rather than in math.h as C99 stipulates */
+# include <fp.h>
+# endif
#else
START_EXTERN_C
double exp (double);
@@ -3893,8 +4293,19 @@ START_EXTERN_C
END_EXTERN_C
#endif
-#if !defined(NV_INF) && defined(USE_LONG_DOUBLE) && defined(LDBL_INFINITY)
-# define NV_INF LDBL_INFINITY
+/* If you are thinking of using HUGE_VAL for infinity, or using
+ * <math.h> functions to generate NV_INF (e.g. exp(1e9), log(-1.0)),
+ * stop. Neither will work portably: HUGE_VAL can be just DBL_MAX,
+ * and the math functions might be just generating DBL_MAX, or even
+ * zero. */
+
+#if !defined(NV_INF) && defined(USE_LONG_DOUBLE)
+# if !defined(NV_INF) && defined(LDBL_INFINITY)
+# define NV_INF LDBL_INFINITY
+# endif
+# if !defined(NV_INF) && defined(INFINITYL)
+# define NV_INF INFINITYL
+# endif
#endif
#if !defined(NV_INF) && defined(DBL_INFINITY)
# define NV_INF (NV)DBL_INFINITY
@@ -3905,23 +4316,43 @@ END_EXTERN_C
#if !defined(NV_INF) && defined(INF)
# define NV_INF (NV)INF
#endif
-#if !defined(NV_INF) && defined(USE_LONG_DOUBLE) && defined(HUGE_VALL)
-# define NV_INF (NV)HUGE_VALL
+#if !defined(NV_INF)
+# if INTSIZE == 4
+/* At this point we assume the IEEE 754 floating point (and of course,
+ * we also assume a floating point format that can encode an infinity).
+ * We will coerce an int32 (which will encode the infinity) into
+ * a 32-bit float, which will then be cast into NV.
+ *
+ * Note that we intentionally use a float and 32-bit int, instead of
+ * shifting a small integer into a full IV, and from that into a full
+ * NV, because:
+ *
+ * (1) an IV might not be wide enough to cover all the bits of an NV.
+ * (2) the exponent part (including the infinity and nan bits) of a NV
+ * might be wider than just 16 bits.
+ *
+ * Below the NV_NAN logic has similar __PL_nan_u fallback, the only
+ * difference being the int32 constant being coerced. */
+# define __PL_inf_float_int32 0x7F800000
+static const union { unsigned int __i; float __f; } __PL_inf_u =
+ { __PL_inf_float_int32 };
+# define NV_INF ((NV)(__PL_inf_u.__f))
+# endif
#endif
-#if !defined(NV_INF) && defined(HUGE_VAL)
-# define NV_INF (NV)HUGE_VAL
+#if !defined(NV_INF)
+# define NV_INF ((NV)1.0/0.0) /* Some compilers will warn. */
#endif
#if !defined(NV_NAN) && defined(USE_LONG_DOUBLE)
# if !defined(NV_NAN) && defined(LDBL_NAN)
# define NV_NAN LDBL_NAN
# endif
+# if !defined(NV_NAN) && defined(NANL)
+# define NV_NAN NANL
+# endif
# if !defined(NV_NAN) && defined(LDBL_QNAN)
# define NV_NAN LDBL_QNAN
# endif
-# if !defined(NV_NAN) && defined(LDBL_SNAN)
-# define NV_NAN LDBL_SNAN
-# endif
#endif
#if !defined(NV_NAN) && defined(DBL_NAN)
# define NV_NAN (NV)DBL_NAN
@@ -3929,29 +4360,37 @@ END_EXTERN_C
#if !defined(NV_NAN) && defined(DBL_QNAN)
# define NV_NAN (NV)DBL_QNAN
#endif
-#if !defined(NV_NAN) && defined(DBL_SNAN)
-# define NV_NAN (NV)DBL_SNAN
+#if !defined(NV_NAN) && defined(NAN)
+# define NV_NAN (NV)NAN
#endif
#if !defined(NV_NAN) && defined(QNAN)
# define NV_NAN (NV)QNAN
#endif
-#if !defined(NV_NAN) && defined(SNAN)
-# define NV_NAN (NV)SNAN
+#if !defined(NV_NAN) && defined(USE_LONG_DOUBLE) && defined(I_SUNMATH)
+# define NV_NAN (NV)quiet_nan()
#endif
-#if !defined(NV_NAN) && defined(NAN)
-# define NV_NAN (NV)NAN
+#if !defined(NV_NAN)
+# if INTSIZE == 4
+/* See the discussion near __PL_inf_u. */
+# define __PL_nan_float_int32 0x7FC00000
+static const union { unsigned int __i; float __f; } __PL_nan_u =
+ { __PL_nan_float_int32 };
+# define NV_NAN ((NV)(__PL_nan_u.__f))
+# endif
#endif
+#if !defined(NV_NAN)
+# define NV_NAN ((NV)0.0/0.0) /* Some compilers will warn. */
+#endif
+/* Do NOT try doing NV_NAN based on NV_INF and trying (NV_INF-NV_INF).
+ * Though IEEE-754-logically correct, some compilers (like Visual C 2003)
+ * falsely misoptimize that to zero (x-x is zero, right?) */
#ifndef __cplusplus
-# if defined(NeXT) || defined(__NeXT__) /* or whatever catches all NeXTs */
-char *crypt (); /* Maybe more hosts will need the unprototyped version */
-# else
-# if !defined(WIN32) && !defined(VMS)
+# if !defined(WIN32) && !defined(VMS)
#ifndef crypt
char *crypt (const char*, const char*);
#endif
-# endif /* !WIN32 */
-# endif /* !NeXT && !__NeXT__ */
+# endif /* !WIN32 */
# ifndef DONT_DECLARE_STD
# ifndef getenv
char *getenv (const char*);
@@ -4153,19 +4592,9 @@ typedef OP* (*PPADDR_t[]) (pTHX);
typedef bool (*destroyable_proc_t) (pTHX_ SV *sv);
typedef void (*despatch_signals_proc_t) (pTHX);
-/* NeXT has problems with crt0.o globals */
-#if defined(__DYNAMIC__) && \
- (defined(NeXT) || defined(__NeXT__) || defined(PERL_DARWIN))
-# if defined(NeXT) || defined(__NeXT)
-# include <mach-o/dyld.h>
-# define environ (*environ_pointer)
-EXT char *** environ_pointer;
-# else
-# if defined(PERL_DARWIN) && defined(PERL_CORE)
-# include <crt_externs.h> /* for the env array */
-# define environ (*_NSGetEnviron())
-# endif
-# endif
+#if defined(__DYNAMIC__) && defined(PERL_DARWIN) && defined(PERL_CORE)
+# include <crt_externs.h> /* for the env array */
+# define environ (*_NSGetEnviron())
#else
/* VMS and some other platforms don't use the environ array */
# ifdef USE_ENVIRON_ARRAY
@@ -4204,12 +4633,13 @@ EXTCONST char PL_warn_nl[]
INIT("Unsuccessful %s on filename containing newline");
EXTCONST char PL_no_wrongref[]
INIT("Can't use %s ref as %s ref");
-/* The core no longer needs these here. If you require the string constant,
+/* The core no longer needs this here. If you require the string constant,
please inline a copy into your own code. */
EXTCONST char PL_no_symref[] __attribute__deprecated__
INIT("Can't use string (\"%.32s\") as %s ref while \"strict refs\" in use");
-EXTCONST char PL_no_symref_sv[] __attribute__deprecated__
- INIT("Can't use string (\"%" SVf32 "\") as %s ref while \"strict refs\" in use");
+EXTCONST char PL_no_symref_sv[]
+ INIT("Can't use string (\"%" SVf32 "\"%s) as %s ref while \"strict refs\" in use");
+
EXTCONST char PL_no_usym[]
INIT("Can't use an undefined value as %s reference");
EXTCONST char PL_no_aelem[]
@@ -4229,7 +4659,7 @@ EXTCONST char PL_no_dir_func[]
EXTCONST char PL_no_func[]
INIT("The %s function is unimplemented");
EXTCONST char PL_no_myglob[]
- INIT("\"%s\" variable %s can't be in a package");
+ INIT("\"%s\" %se %s can't be in a package");
EXTCONST char PL_no_localize_ref[]
INIT("Can't localize through a reference");
EXTCONST char PL_memory_wrap[]
@@ -4651,9 +5081,6 @@ EXTCONST char PL_bincompat_options[] =
# ifdef PERL_IMPLICIT_SYS
" PERL_IMPLICIT_SYS"
# endif
-# ifdef PERL_MAD
- " PERL_MAD"
-# endif
# ifdef PERL_MICRO
" PERL_MICRO"
# endif
@@ -4699,12 +5126,18 @@ EXTCONST char PL_bincompat_options[] =
# ifdef USE_LOCALE_NUMERIC
" USE_LOCALE_NUMERIC"
# endif
+# ifdef USE_LOCALE_TIME
+ " USE_LOCALE_TIME"
+# endif
# ifdef USE_LONG_DOUBLE
" USE_LONG_DOUBLE"
# endif
# ifdef USE_PERLIO
" USE_PERLIO"
# endif
+# ifdef USE_QUADMATH
+ " USE_QUADMATH"
+# endif
# ifdef USE_REENTRANT_API
" USE_REENTRANT_API"
# endif
@@ -4796,6 +5229,7 @@ typedef enum {
XATTRBLOCK,
XATTRTERM,
XTERMBLOCK,
+ XBLOCKTERM,
XPOSTDEREF,
XTERMORDORDOR /* evil hack */
/* update exp_name[] in toke.c if adding to this enum */
@@ -4806,12 +5240,18 @@ typedef enum {
However, bitops store HINT_INTEGER in their op_private.
NOTE: The typical module using these has the bit value hard-coded, so don't
- blindly change the values of these */
+ blindly change the values of these.
+
+ If we run out of bits, the 2 locale ones could be combined. The PARTIAL one
+ is for "use locale 'FOO'" which excludes some categories. It requires going
+ to %^H to find out which are in and which are out. This could be extended
+ for the normal case of a plain HINT_LOCALE, so that %^H would be used for
+ any locale form. */
#define HINT_INTEGER 0x00000001 /* integer pragma */
#define HINT_STRICT_REFS 0x00000002 /* strict pragma */
#define HINT_LOCALE 0x00000004 /* locale pragma */
#define HINT_BYTES 0x00000008 /* bytes pragma */
-#define HINT_LOCALE_NOT_CHARS 0x00000010 /* locale ':not_characters' pragma */
+#define HINT_LOCALE_PARTIAL 0x00000010 /* locale, but a subset of categories */
#define HINT_EXPLICIT_STRICT_REFS 0x00000020 /* strict.pm */
#define HINT_EXPLICIT_STRICT_SUBS 0x00000040 /* strict.pm */
@@ -4844,8 +5284,8 @@ typedef enum {
#define HINT_FEATURE_MASK 0x1c000000 /* 3 bits for feature bundles */
- /* Note: Used for NATIVE_HINTS, currently
- defined by vms/vmsish.h:
+ /* Note: Used for HINT_M_VMSISH_*,
+ currently defined by vms/vmsish.h:
0x40000000
0x80000000
*/
@@ -4867,6 +5307,16 @@ typedef enum {
(SAWAMPERSAND_LEFT|SAWAMPERSAND_MIDDLE|SAWAMPERSAND_RIGHT)
#endif
+/* Used for debugvar magic */
+#define DBVARMG_SINGLE 0
+#define DBVARMG_TRACE 1
+#define DBVARMG_SIGNAL 2
+#define DBVARMG_COUNT 3
+
+#define PL_DBsingle_iv (PL_DBcontrol[DBVARMG_SINGLE])
+#define PL_DBtrace_iv (PL_DBcontrol[DBVARMG_TRACE])
+#define PL_DBsignal_iv (PL_DBcontrol[DBVARMG_SIGNAL])
+
/* Various states of the input record separator SV (rs) */
#define RsSNARF(sv) (! SvOK(sv))
#define RsSIMPLE(sv) (SvOK(sv) && (! SvPOK(sv) || SvCUR(sv)))
@@ -5066,12 +5516,6 @@ struct tempsym; /* defined in pp_pack.c */
#if !defined(PERL_FOR_X2P)
# include "embedvar.h"
#endif
-#ifndef PERL_MAD
-# undef PL_madskills
-# undef PL_xmlfp
-# define PL_madskills 0
-# define PL_xmlfp 0
-#endif
/* Now include all the 'global' variables
* If we don't have threads or multiple interpreters
@@ -5098,10 +5542,6 @@ END_EXTERN_C
In particular, need the relevant *ish file included already, as it may
define HAVE_INTERP_INTERN */
#include "embed.h"
-#ifndef PERL_MAD
-# undef op_getmad
-# define op_getmad(arg,pegop,slot) NOOP
-#endif
#ifndef PERL_GLOBAL_STRUCT
START_EXTERN_C
@@ -5116,6 +5556,26 @@ END_EXTERN_C
#undef PERLVARI
#undef PERLVARIC
+#if !defined(MULTIPLICITY)
+/* Set up PERLVAR macros for populating structs */
+# define PERLVAR(prefix,var,type) type prefix##var;
+/* 'var' is an array of length 'n' */
+# define PERLVARA(prefix,var,n,type) type prefix##var[n];
+/* initialize 'var' to init' */
+# define PERLVARI(prefix,var,type,init) type prefix##var;
+/* like PERLVARI, but make 'var' a const */
+# define PERLVARIC(prefix,var,type,init) type prefix##var;
+
+/* this is never instantiated, is it just used for sizeof(struct PerlHandShakeInterpreter) */
+struct PerlHandShakeInterpreter {
+# include "intrpvar.h"
+};
+# undef PERLVAR
+# undef PERLVARA
+# undef PERLVARI
+# undef PERLVARIC
+#endif
+
START_EXTERN_C
/* dummy variables that hold pointers to both runops functions, thus forcing
@@ -5126,14 +5586,7 @@ EXTCONST runops_proc_t PL_runops_std
EXTCONST runops_proc_t PL_runops_dbg
INIT(Perl_runops_debug);
-/* PERL_GLOBAL_STRUCT_PRIVATE wants to keep global data like the
- * magic vtables const, but this is incompatible with SWIG which
- * does want to modify the vtables. */
-#ifdef PERL_GLOBAL_STRUCT_PRIVATE
-# define EXT_MGVTBL EXTCONST MGVTBL
-#else
-# define EXT_MGVTBL EXT MGVTBL
-#endif
+#define EXT_MGVTBL EXTCONST MGVTBL
#define PERL_MAGIC_READONLY_ACCEPTABLE 0x40
#define PERL_MAGIC_VALUE_MAGIC 0x80
@@ -5183,6 +5636,25 @@ EXTCONST bool PL_valid_types_NV_set[];
#endif
+
+/* if these never got defined, they need defaults */
+#ifndef PERL_SET_CONTEXT
+# define PERL_SET_CONTEXT(i) PERL_SET_INTERP(i)
+#endif
+
+#ifndef PERL_GET_CONTEXT
+# define PERL_GET_CONTEXT PERL_GET_INTERP
+#endif
+
+#ifndef PERL_GET_THX
+# define PERL_GET_THX ((void*)NULL)
+#endif
+
+#ifndef PERL_SET_THX
+# define PERL_SET_THX(t) NOOP
+#endif
+
+
#ifndef PERL_NO_INLINE_FUNCTIONS
/* Static inline funcs that depend on includes and declarations above.
Some of these reference functions in the perl object files, and some
@@ -5282,152 +5754,349 @@ typedef struct am_table_short AMTS;
#define PERLDBf_SAVESRC_NOSUBS 0x800 /* Including evals that generate no subroutines */
#define PERLDBf_SAVESRC_INVALID 0x1000 /* Save source that did not compile */
-#define PERLDB_SUB (PL_perldb && (PL_perldb & PERLDBf_SUB))
-#define PERLDB_LINE (PL_perldb && (PL_perldb & PERLDBf_LINE))
-#define PERLDB_NOOPT (PL_perldb && (PL_perldb & PERLDBf_NOOPT))
-#define PERLDB_INTER (PL_perldb && (PL_perldb & PERLDBf_INTER))
-#define PERLDB_SUBLINE (PL_perldb && (PL_perldb & PERLDBf_SUBLINE))
-#define PERLDB_SINGLE (PL_perldb && (PL_perldb & PERLDBf_SINGLE))
-#define PERLDB_SUB_NN (PL_perldb && (PL_perldb & (PERLDBf_NONAME)))
-#define PERLDB_GOTO (PL_perldb && (PL_perldb & PERLDBf_GOTO))
-#define PERLDB_NAMEEVAL (PL_perldb && (PL_perldb & PERLDBf_NAMEEVAL))
-#define PERLDB_NAMEANON (PL_perldb && (PL_perldb & PERLDBf_NAMEANON))
-#define PERLDB_SAVESRC (PL_perldb && (PL_perldb & PERLDBf_SAVESRC))
-#define PERLDB_SAVESRC_NOSUBS (PL_perldb && (PL_perldb & PERLDBf_SAVESRC_NOSUBS))
-#define PERLDB_SAVESRC_INVALID (PL_perldb && (PL_perldb & PERLDBf_SAVESRC_INVALID))
+#define PERLDB_SUB (PL_perldb & PERLDBf_SUB)
+#define PERLDB_LINE (PL_perldb & PERLDBf_LINE)
+#define PERLDB_NOOPT (PL_perldb & PERLDBf_NOOPT)
+#define PERLDB_INTER (PL_perldb & PERLDBf_INTER)
+#define PERLDB_SUBLINE (PL_perldb & PERLDBf_SUBLINE)
+#define PERLDB_SINGLE (PL_perldb & PERLDBf_SINGLE)
+#define PERLDB_SUB_NN (PL_perldb & PERLDBf_NONAME)
+#define PERLDB_GOTO (PL_perldb & PERLDBf_GOTO)
+#define PERLDB_NAMEEVAL (PL_perldb & PERLDBf_NAMEEVAL)
+#define PERLDB_NAMEANON (PL_perldb & PERLDBf_NAMEANON)
+#define PERLDB_SAVESRC (PL_perldb & PERLDBf_SAVESRC)
+#define PERLDB_SAVESRC_NOSUBS (PL_perldb & PERLDBf_SAVESRC_NOSUBS)
+#define PERLDB_SAVESRC_INVALID (PL_perldb & PERLDBf_SAVESRC_INVALID)
+
+#ifdef USE_LOCALE
+/* These locale things are all subject to change */
+/* Returns TRUE if the plain locale pragma without a parameter is in effect
+ */
+# define IN_LOCALE_RUNTIME cBOOL(CopHINTS_get(PL_curcop) & HINT_LOCALE)
-/*
+/* Returns TRUE if either form of the locale pragma is in effect */
+# define IN_SOME_LOCALE_FORM_RUNTIME \
+ cBOOL(CopHINTS_get(PL_curcop) & (HINT_LOCALE|HINT_LOCALE_PARTIAL))
-=head1 Locale-related functions and macros
+# define IN_LOCALE_COMPILETIME cBOOL(PL_hints & HINT_LOCALE)
+# define IN_SOME_LOCALE_FORM_COMPILETIME \
+ cBOOL(PL_hints & (HINT_LOCALE|HINT_LOCALE_PARTIAL))
-=for apidoc sync_locale
+# define IN_LOCALE \
+ (IN_PERL_COMPILETIME ? IN_LOCALE_COMPILETIME : IN_LOCALE_RUNTIME)
+# define IN_SOME_LOCALE_FORM \
+ (IN_PERL_COMPILETIME ? IN_SOME_LOCALE_FORM_COMPILETIME \
+ : IN_SOME_LOCALE_FORM_RUNTIME)
-Changing the program's locale should be avoided by XS code. Nevertheless,
-certain non-Perl libraries called from XS, such as C<Gtk> do so. When this
-happens, Perl needs to be told that the locale has changed. Use this macro
-to do so, before returning to Perl code.
+# define IN_LC_ALL_COMPILETIME IN_LOCALE_COMPILETIME
+# define IN_LC_ALL_RUNTIME IN_LOCALE_RUNTIME
+
+# define IN_LC_PARTIAL_COMPILETIME cBOOL(PL_hints & HINT_LOCALE_PARTIAL)
+# define IN_LC_PARTIAL_RUNTIME \
+ cBOOL(CopHINTS_get(PL_curcop) & HINT_LOCALE_PARTIAL)
+
+# define IN_LC_COMPILETIME(category) \
+ (IN_LC_ALL_COMPILETIME || (IN_LC_PARTIAL_COMPILETIME \
+ && _is_in_locale_category(TRUE, (category))))
+# define IN_LC_RUNTIME(category) \
+ (IN_LC_ALL_RUNTIME || (IN_LC_PARTIAL_RUNTIME \
+ && _is_in_locale_category(FALSE, (category))))
+# define IN_LC(category) \
+ (IN_LC_COMPILETIME(category) || IN_LC_RUNTIME(category))
+
+# if defined (PERL_CORE) || defined (PERL_IN_XSUB_RE)
+
+ /* This internal macro should be called from places that operate under
+ * locale rules. It there is a problem with the current locale that
+ * hasn't been raised yet, it will output a warning this time. Because
+ * this will so rarely be true, there is no point to optimize for
+ * time; instead it makes sense to minimize space used and do all the
+ * work in the rarely called function */
+# ifdef USE_LOCALE_CTYPE
+# define _CHECK_AND_WARN_PROBLEMATIC_LOCALE \
+ STMT_START { \
+ if (UNLIKELY(PL_warn_locale)) { \
+ _warn_problematic_locale(); \
+ } \
+ } STMT_END
+# else
+# define _CHECK_AND_WARN_PROBLEMATIC_LOCALE
+# endif
-=cut
-*/
-/* Temporary for maint. Is a function in 5.21 */
-#define sync_locale() (new_ctype(setlocale(LC_CTYPE, NULL)), \
- new_collate(setlocale(LC_COLLATE, NULL)), \
- set_numeric_local(), \
- new_numeric(setlocale(LC_NUMERIC, NULL)))
+ /* These two internal macros are called when a warning should be raised,
+ * and will do so if enabled. The first takes a single code point
+ * argument; the 2nd, is a pointer to the first byte of the UTF-8 encoded
+ * string, and an end position which it won't try to read past */
+# define _CHECK_AND_OUTPUT_WIDE_LOCALE_CP_MSG(cp) \
+ STMT_START { \
+ if (! PL_in_utf8_CTYPE_locale && ckWARN(WARN_LOCALE)) { \
+ Perl_warner(aTHX_ packWARN(WARN_LOCALE), \
+ "Wide character (U+%"UVXf") in %s", \
+ (UV) cp, OP_DESC(PL_op)); \
+ } \
+ } STMT_END
+
+# define _CHECK_AND_OUTPUT_WIDE_LOCALE_UTF8_MSG(s, send) \
+ STMT_START { /* Check if to warn before doing the conversion work */\
+ if (! PL_in_utf8_CTYPE_locale && ckWARN(WARN_LOCALE)) { \
+ UV cp = utf8_to_uvchr_buf((U8 *) s, (U8 *) send, NULL); \
+ Perl_warner(aTHX_ packWARN(WARN_LOCALE), \
+ "Wide character (U+%"UVXf") in %s", \
+ (cp == 0) \
+ ? UNICODE_REPLACEMENT \
+ : (UV) cp, \
+ OP_DESC(PL_op)); \
+ } \
+ } STMT_END
+
+# endif /* PERL_CORE or PERL_IN_XSUB_RE */
+
+#else /* No locale usage */
+# define IN_LOCALE_RUNTIME 0
+# define IN_SOME_LOCALE_FORM_RUNTIME 0
+# define IN_LOCALE_COMPILETIME 0
+# define IN_SOME_LOCALE_FORM_COMPILETIME 0
+# define IN_LOCALE 0
+# define IN_SOME_LOCALE_FORM 0
+# define IN_LC_ALL_COMPILETIME 0
+# define IN_LC_ALL_RUNTIME 0
+# define IN_LC_PARTIAL_COMPILETIME 0
+# define IN_LC_PARTIAL_RUNTIME 0
+# define IN_LC_COMPILETIME(category) 0
+# define IN_LC_RUNTIME(category) 0
+# define IN_LC(category) 0
+
+# define _CHECK_AND_WARN_PROBLEMATIC_LOCALE
+# define _CHECK_AND_OUTPUT_WIDE_LOCALE_CP_MSG(a)
+# define _CHECK_AND_OUTPUT_WIDE_LOCALE_UTF8_MSG(a,b)
+#endif
#ifdef USE_LOCALE_NUMERIC
-/* Returns TRUE if the plain locale pragma without a parameter is in effect
- */
-#define IN_LOCALE_RUNTIME cBOOL(CopHINTS_get(PL_curcop) & HINT_LOCALE)
+/* These macros are for toggling between the underlying locale (UNDERLYING or
+ * LOCAL) and the C locale (STANDARD).
-/* Returns TRUE if either form of the locale pragma is in effect */
-#define IN_SOME_LOCALE_FORM_RUNTIME \
- cBOOL(CopHINTS_get(PL_curcop) & (HINT_LOCALE|HINT_LOCALE_NOT_CHARS))
+=head1 Locale-related functions and macros
-#define IN_LOCALE_COMPILETIME cBOOL(PL_hints & HINT_LOCALE)
-#define IN_SOME_LOCALE_FORM_COMPILETIME \
- cBOOL(PL_hints & (HINT_LOCALE|HINT_LOCALE_NOT_CHARS))
+=for apidoc Amn|void|DECLARATION_FOR_LC_NUMERIC_MANIPULATION
+
+This macro should be used as a statement. It declares a private variable
+(whose name begins with an underscore) that is needed by the other macros in
+this section. Failing to include this correctly should lead to a syntax error.
+For compatibility with C89 C compilers it should be placed in a block before
+any executable statements.
+
+=for apidoc Am|void|STORE_LC_NUMERIC_FORCE_TO_UNDERLYING
+
+This is used by XS code that that is C<LC_NUMERIC> locale-aware to force the
+locale for category C<LC_NUMERIC> to be what perl thinks is the current
+underlying locale. (The perl interpreter could be wrong about what the
+underlying locale actually is if some C or XS code has called the C library
+function L<setlocale(3)> behind its back; calling L</sync_locale> before calling
+this macro will update perl's records.)
+
+A call to L</DECLARATION_FOR_LC_NUMERIC_MANIPULATION> must have been made to
+declare at compile time a private variable used by this macro. This macro
+should be called as a single statement, not an expression, but with an empty
+argument list, like this:
+
+ {
+ DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
+ ...
+ STORE_LC_NUMERIC_FORCE_TO_UNDERLYING();
+ ...
+ RESTORE_LC_NUMERIC();
+ ...
+ }
+
+The private variable is used to save the current locale state, so
+that the requisite matching call to L</RESTORE_LC_NUMERIC> can restore it.
+
+=for apidoc Am|void|STORE_LC_NUMERIC_SET_TO_NEEDED
+
+This is used to help wrap XS or C code that that is C<LC_NUMERIC> locale-aware.
+This locale category is generally kept set to the C locale by Perl for
+backwards compatibility, and because most XS code that reads floating point
+values can cope only with the decimal radix character being a dot.
+
+This macro makes sure the current C<LC_NUMERIC> state is set properly, to be
+aware of locale if the call to the XS or C code from the Perl program is
+from within the scope of a S<C<use locale>>; or to ignore locale if the call is
+instead from outside such scope.
+
+This macro is the start of wrapping the C or XS code; the wrap ending is done
+by calling the L</RESTORE_LC_NUMERIC> macro after the operation. Otherwise
+the state can be changed that will adversely affect other XS code.
+
+A call to L</DECLARATION_FOR_LC_NUMERIC_MANIPULATION> must have been made to
+declare at compile time a private variable used by this macro. This macro
+should be called as a single statement, not an expression, but with an empty
+argument list, like this:
+
+ {
+ DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
+ ...
+ STORE_LC_NUMERIC_SET_TO_NEEDED();
+ ...
+ RESTORE_LC_NUMERIC();
+ ...
+ }
-#define IN_LOCALE \
- (IN_PERL_COMPILETIME ? IN_LOCALE_COMPILETIME : IN_LOCALE_RUNTIME)
-#define IN_SOME_LOCALE_FORM \
- (IN_PERL_COMPILETIME ? IN_SOME_LOCALE_FORM_COMPILETIME \
- : IN_SOME_LOCALE_FORM_RUNTIME)
+=for apidoc Am|void|RESTORE_LC_NUMERIC
-/* These macros are for toggling between the underlying locale (LOCAL) and the
- * C locale. */
-
-/* The first set makes sure that the locale is set to C unless within a 'use
- * locale's scope; otherwise to the default locale. A function pointer is
- * used, which can be declared separately by
- * DECLARATION_FOR_STORE_LC_NUMERIC_SET_TO_NEEDED, followed by the actual
- * setting (using STORE_LC_NUMERIC_SET_TO_NEEDED()), or the two can be combined
- * into one call DECLARE_STORE_LC_NUMERIC_SET_TO_NEEDED().
- * RESTORE_LC_NUMERIC() in all cases restores the locale to what it was before
- * these were called */
-
-#define DECLARATION_FOR_STORE_LC_NUMERIC_SET_TO_NEEDED \
- void (*_restore_LC_NUMERIC_function)(pTHX) = NULL;
-
-#define STORE_LC_NUMERIC_SET_TO_NEEDED() \
- if (IN_SOME_LOCALE_FORM) { \
- if (! PL_numeric_local) { \
- SET_NUMERIC_LOCAL(); \
- _restore_LC_NUMERIC_function = &Perl_set_numeric_standard; \
- } \
- } \
- else { \
- if (! PL_numeric_standard) { \
- SET_NUMERIC_STANDARD(); \
- _restore_LC_NUMERIC_function = &Perl_set_numeric_local; \
- } \
- }
+This is used in conjunction with one of the macros
+L</STORE_LC_NUMERIC_SET_TO_NEEDED>
+and
+L</STORE_LC_NUMERIC_FORCE_TO_UNDERLYING>
-#define DECLARE_STORE_LC_NUMERIC_SET_TO_NEEDED() \
- DECLARATION_FOR_STORE_LC_NUMERIC_SET_TO_NEEDED; \
- STORE_LC_NUMERIC_SET_TO_NEEDED();
+to properly restore the C<LC_NUMERIC> state.
+
+A call to L</DECLARATION_FOR_LC_NUMERIC_MANIPULATION> must have been made to
+declare at compile time a private variable used by this macro and the two
+C<STORE> ones. This macro should be called as a single statement, not an
+expression, but with an empty argument list, like this:
+
+ {
+ DECLARATION_FOR_LC_NUMERIC_MANIPULATION;
+ ...
+ RESTORE_LC_NUMERIC();
+ ...
+ }
-#define RESTORE_LC_NUMERIC() \
- if (_restore_LC_NUMERIC_function) { \
- _restore_LC_NUMERIC_function(aTHX); \
+=cut
+
+*/
+
+#define _NOT_IN_NUMERIC_STANDARD (! PL_numeric_standard)
+
+/* We can lock the category to stay in the C locale, making requests to the
+ * contrary be noops, in the dynamic scope by setting PL_numeric_standard to 2.
+ * */
+#define _NOT_IN_NUMERIC_UNDERLYING \
+ (! PL_numeric_local && PL_numeric_standard < 2)
+
+#define DECLARATION_FOR_LC_NUMERIC_MANIPULATION \
+ void (*_restore_LC_NUMERIC_function)(pTHX) = NULL
+
+#define STORE_LC_NUMERIC_SET_TO_NEEDED() \
+ if (IN_LC(LC_NUMERIC)) { \
+ if (_NOT_IN_NUMERIC_UNDERLYING) { \
+ set_numeric_local(); \
+ _restore_LC_NUMERIC_function = &Perl_set_numeric_standard; \
+ } \
+ } \
+ else { \
+ if (_NOT_IN_NUMERIC_STANDARD) { \
+ SET_NUMERIC_STANDARD(); \
+ _restore_LC_NUMERIC_function = &Perl_set_numeric_local; \
+ } \
+ }
+
+#define RESTORE_LC_NUMERIC() \
+ if (_restore_LC_NUMERIC_function) { \
+ _restore_LC_NUMERIC_function(aTHX); \
}
/* The next two macros set unconditionally. These should be rarely used, and
* only after being sure that this is what is needed */
-#define SET_NUMERIC_STANDARD() \
- set_numeric_standard();
+#define SET_NUMERIC_STANDARD() \
+ STMT_START { if (_NOT_IN_NUMERIC_STANDARD) set_numeric_standard(); \
+ } STMT_END
-#define SET_NUMERIC_LOCAL() \
- set_numeric_local();
+#define SET_NUMERIC_UNDERLYING() \
+ STMT_START { if (_NOT_IN_NUMERIC_UNDERLYING) \
+ set_numeric_local(); } STMT_END
/* The rest of these LC_NUMERIC macros toggle to one or the other state, with
* the RESTORE_foo ones called to switch back, but only if need be */
-#define STORE_NUMERIC_LOCAL_SET_STANDARD() \
- bool was_local = PL_numeric_local; \
- if (was_local) SET_NUMERIC_STANDARD();
+#define STORE_LC_NUMERIC_UNDERLYING_SET_STANDARD() \
+ bool _was_local = _NOT_IN_NUMERIC_STANDARD; \
+ if (_was_local) set_numeric_standard();
/* Doesn't change to underlying locale unless within the scope of some form of
* 'use locale'. This is the usual desired behavior. */
-#define STORE_NUMERIC_STANDARD_SET_LOCAL() \
- bool was_standard = PL_numeric_standard && IN_SOME_LOCALE_FORM; \
- if (was_standard) SET_NUMERIC_LOCAL();
+#define STORE_LC_NUMERIC_STANDARD_SET_UNDERLYING() \
+ bool _was_standard = _NOT_IN_NUMERIC_UNDERLYING \
+ && IN_LC(LC_NUMERIC); \
+ if (_was_standard) set_numeric_local();
/* Rarely, we want to change to the underlying locale even outside of 'use
* locale'. This is principally in the POSIX:: functions */
-#define STORE_NUMERIC_STANDARD_FORCE_LOCAL() \
- bool was_standard = PL_numeric_standard; \
- if (was_standard) SET_NUMERIC_LOCAL();
+#define STORE_LC_NUMERIC_FORCE_TO_UNDERLYING() \
+ if (_NOT_IN_NUMERIC_UNDERLYING) { \
+ set_numeric_local(); \
+ _restore_LC_NUMERIC_function = &Perl_set_numeric_standard; \
+ }
-#define RESTORE_NUMERIC_LOCAL() \
- if (was_local) SET_NUMERIC_LOCAL();
+/* Lock to the C locale until unlock is called */
+#define LOCK_LC_NUMERIC_STANDARD() \
+ (__ASSERT_(PL_numeric_standard) \
+ PL_numeric_standard = 2)
-#define RESTORE_NUMERIC_STANDARD() \
- if (was_standard) SET_NUMERIC_STANDARD();
+#define UNLOCK_LC_NUMERIC_STANDARD() \
+ (__ASSERT_(PL_numeric_standard == 2) \
+ PL_numeric_standard = 1)
-#define Atof my_atof
+#define RESTORE_LC_NUMERIC_UNDERLYING() \
+ if (_was_local) set_numeric_local();
+
+#define RESTORE_LC_NUMERIC_STANDARD() \
+ if (_restore_LC_NUMERIC_function) { \
+ _restore_LC_NUMERIC_function(aTHX); \
+ }
#else /* !USE_LOCALE_NUMERIC */
-#define SET_NUMERIC_STANDARD() /**/
-#define SET_NUMERIC_LOCAL() /**/
+#define SET_NUMERIC_STANDARD()
+#define SET_NUMERIC_UNDERLYING()
#define IS_NUMERIC_RADIX(a, b) (0)
-#define STORE_NUMERIC_LOCAL_SET_STANDARD() /**/
-#define STORE_NUMERIC_STANDARD_SET_LOCAL() /**/
-#define STORE_NUMERIC_STANDARD_FORCE_LOCAL()
-#define RESTORE_NUMERIC_LOCAL() /**/
-#define RESTORE_NUMERIC_STANDARD() /**/
-#define DECLARATION_FOR_STORE_LC_NUMERIC_SET_TO_NEEDED
+#define STORE_LC_NUMERIC_UNDERLYING_SET_STANDARD()
+#define STORE_LC_NUMERIC_STANDARD_SET_UNDERLYING()
+#define STORE_LC_NUMERIC_FORCE_TO_UNDERLYING()
+#define RESTORE_LC_NUMERIC_UNDERLYING()
+#define RESTORE_LC_NUMERIC_STANDARD()
+#define DECLARATION_FOR_LC_NUMERIC_MANIPULATION
#define STORE_LC_NUMERIC_SET_TO_NEEDED()
-#define DECLARE_STORE_LC_NUMERIC_SET_TO_NEEDED()
#define RESTORE_LC_NUMERIC()
+#define LOCK_LC_NUMERIC_STANDARD()
+#define UNLOCK_LC_NUMERIC_STANDARD()
+
+#endif /* !USE_LOCALE_NUMERIC */
#define Atof my_atof
-#define IN_LOCALE_RUNTIME 0
-#define IN_LOCALE_COMPILETIME 0
-#endif /* !USE_LOCALE_NUMERIC */
+/* Back-compat names */
+#define DECLARATION_FOR_STORE_LC_NUMERIC_SET_TO_NEEDED \
+ DECLARATION_FOR_LC_NUMERIC_MANIPULATION
+#define DECLARE_STORE_LC_NUMERIC_SET_TO_NEEDED() \
+ DECLARATION_FOR_STORE_LC_NUMERIC_SET_TO_NEEDED; \
+ STORE_LC_NUMERIC_SET_TO_NEEDED();
+#define LOCK_NUMERIC_STANDARD() LOCK_LC_NUMERIC_STANDARD()
+#define RESTORE_NUMERIC_LOCAL() RESTORE_LC_NUMERIC_UNDERLYING()
+#define RESTORE_NUMERIC_STANDARD() RESTORE_LC_NUMERIC_STANDARD()
+#define SET_NUMERIC_LOCAL() SET_NUMERIC_UNDERLYING()
+#define STORE_NUMERIC_LOCAL_SET_STANDARD() \
+ STORE_LC_NUMERIC_UNDERLYING_SET_STANDARD()
+#define STORE_NUMERIC_STANDARD_SET_LOCAL() \
+ STORE_LC_NUMERIC_STANDARD_SET_UNDERLYING()
+#define STORE_NUMERIC_STANDARD_FORCE_LOCAL() \
+ STORE_LC_NUMERIC_FORCE_TO_UNDERLYING()
+#define UNLOCK_NUMERIC_STANDARD() UNLOCK_LC_NUMERIC_STANDARD()
+
+
+
+#ifdef USE_QUADMATH
+# define Perl_strtod(s, e) strtoflt128(s, e)
+#elif defined(HAS_LONG_DOUBLE) && defined(USE_LONG_DOUBLE)
+# if defined(HAS_STRTOLD)
+# define Perl_strtod(s, e) strtold(s, e)
+# elif defined(HAS_STRTOD)
+# define Perl_strtod(s, e) (NV)strtod(s, e) /* Unavoidable loss. */
+# endif
+#elif defined(HAS_STRTOD)
+# define Perl_strtod(s, e) strtod(s, e)
+#endif
#if !defined(Strtol) && defined(USE_64_BIT_INT) && defined(IV_IS_QUAD) && \
(QUADKIND == QUAD_IS_LONG_LONG || QUADKIND == QUAD_IS___INT64)
@@ -5489,24 +6158,6 @@ to do so, before returning to Perl code.
# define Atoul(s) Strtoul(s, NULL, 10)
#endif
-
-/* if these never got defined, they need defaults */
-#ifndef PERL_SET_CONTEXT
-# define PERL_SET_CONTEXT(i) PERL_SET_INTERP(i)
-#endif
-
-#ifndef PERL_GET_CONTEXT
-# define PERL_GET_CONTEXT PERL_GET_INTERP
-#endif
-
-#ifndef PERL_GET_THX
-# define PERL_GET_THX ((void*)NULL)
-#endif
-
-#ifndef PERL_SET_THX
-# define PERL_SET_THX(t) NOOP
-#endif
-
#ifndef PERL_SCRIPT_MODE
#define PERL_SCRIPT_MODE "r"
#endif
@@ -5637,8 +6288,10 @@ to do so, before returning to Perl code.
/* Clones the per-interpreter data. */
# define MY_CXT_CLONE \
my_cxt_t *my_cxtp = (my_cxt_t*)SvPVX(newSV(sizeof(my_cxt_t)-1));\
- Copy(PL_my_cxt_list[MY_CXT_INDEX], my_cxtp, 1, my_cxt_t);\
- PL_my_cxt_list[MY_CXT_INDEX] = my_cxtp \
+ void * old_my_cxtp = PL_my_cxt_list[MY_CXT_INDEX]; \
+ PL_my_cxt_list[MY_CXT_INDEX] = my_cxtp; \
+ Copy(old_my_cxtp, my_cxtp, 1, my_cxt_t);
+
/* This macro must be used to access members of the my_cxt_t structure.
@@ -5706,7 +6359,7 @@ int flock(int fd, int op);
#endif
#if O_TEXT != O_BINARY
- /* If you have different O_TEXT and O_BINARY and you are a CLRF shop,
+ /* If you have different O_TEXT and O_BINARY and you are a CRLF shop,
* that is, you are somehow DOSish. */
# if defined(__HAIKU__) || defined(__VOS__) || defined(__CYGWIN__)
/* Haiku has O_TEXT != O_BINARY but O_TEXT and O_BINARY have no effect;
@@ -5734,10 +6387,11 @@ int flock(int fd, int op);
int). value returned in pointed-
to UV */
#define IS_NUMBER_GREATER_THAN_UV_MAX 0x02 /* pointed to UV undefined */
-#define IS_NUMBER_NOT_INT 0x04 /* saw . or E notation */
+#define IS_NUMBER_NOT_INT 0x04 /* saw . or E notation or infnan */
#define IS_NUMBER_NEG 0x08 /* leading minus sign */
#define IS_NUMBER_INFINITY 0x10 /* this is big */
#define IS_NUMBER_NAN 0x20 /* this is not */
+#define IS_NUMBER_TRAILING 0x40 /* number has trailing trash */
#define GROK_NUMERIC_RADIX(sp, send) grok_numeric_radix(sp, send)
@@ -5747,6 +6401,9 @@ int flock(int fd, int op);
#define PERL_SCAN_SILENT_ILLDIGIT 0x04 /* grok_??? not warn about illegal digits */
#define PERL_SCAN_SILENT_NON_PORTABLE 0x08 /* grok_??? not warn about very large
numbers which are <= UV_MAX */
+#define PERL_SCAN_TRAILING 0x10 /* grok_number_flags() allow trailing
+ and set IS_NUMBER_TRAILING */
+
/* Output flags: */
#define PERL_SCAN_GREATER_THAN_UV_MAX 0x02 /* should this merge with above? */
@@ -5864,31 +6521,100 @@ extern void moncontrol(int);
* passed straight through to _escape.
*/
-#define PERL_PV_ESCAPE_QUOTE 0x0001
+#define PERL_PV_ESCAPE_QUOTE 0x000001
#define PERL_PV_PRETTY_QUOTE PERL_PV_ESCAPE_QUOTE
-#define PERL_PV_PRETTY_ELLIPSES 0x0002
-#define PERL_PV_PRETTY_LTGT 0x0004
+#define PERL_PV_PRETTY_ELLIPSES 0x000002
+#define PERL_PV_PRETTY_LTGT 0x000004
+#define PERL_PV_PRETTY_EXACTSIZE 0x000008
-#define PERL_PV_ESCAPE_FIRSTCHAR 0x0008
+#define PERL_PV_ESCAPE_UNI 0x000100
+#define PERL_PV_ESCAPE_UNI_DETECT 0x000200
+#define PERL_PV_ESCAPE_NONASCII 0x000400
+#define PERL_PV_ESCAPE_FIRSTCHAR 0x000800
-#define PERL_PV_ESCAPE_UNI 0x0100
-#define PERL_PV_ESCAPE_UNI_DETECT 0x0200
-#define PERL_PV_ESCAPE_NONASCII 0x0400
+#define PERL_PV_ESCAPE_ALL 0x001000
+#define PERL_PV_ESCAPE_NOBACKSLASH 0x002000
+#define PERL_PV_ESCAPE_NOCLEAR 0x004000
+#define PERL_PV_PRETTY_NOCLEAR PERL_PV_ESCAPE_NOCLEAR
+#define PERL_PV_ESCAPE_RE 0x008000
-#define PERL_PV_ESCAPE_ALL 0x1000
-#define PERL_PV_ESCAPE_NOBACKSLASH 0x2000
-#define PERL_PV_ESCAPE_NOCLEAR 0x4000
-#define PERL_PV_ESCAPE_RE 0x8000
+#define PERL_PV_ESCAPE_DWIM 0x010000
-#define PERL_PV_ESCAPE_DWIM 0x10000
-
-#define PERL_PV_PRETTY_NOCLEAR PERL_PV_ESCAPE_NOCLEAR
/* used by pv_display in dump.c*/
#define PERL_PV_PRETTY_DUMP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_QUOTE
#define PERL_PV_PRETTY_REGPROP PERL_PV_PRETTY_ELLIPSES|PERL_PV_PRETTY_LTGT|PERL_PV_ESCAPE_RE|PERL_PV_ESCAPE_NONASCII
+#if DOUBLEKIND == DOUBLE_IS_IEEE_754_32_BIT_LITTLE_ENDIAN || \
+ DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_LITTLE_ENDIAN || \
+ DOUBLEKIND == DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN
+# define DOUBLE_LITTLE_ENDIAN
+#endif
+
+#if DOUBLEKIND == DOUBLE_IS_IEEE_754_32_BIT_BIG_ENDIAN || \
+ DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_BIG_ENDIAN || \
+ DOUBLEKIND == DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN
+# define DOUBLE_BIG_ENDIAN
+#endif
+
+#if DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_LE_BE || \
+ DOUBLEKIND == DOUBLE_IS_IEEE_754_64_BIT_MIXED_ENDIAN_BE_LE
+# define DOUBLE_MIX_ENDIAN
+#endif
+
+/* All the basic IEEE formats have the implicit bit,
+ * except for the 80-bit extended formats, which will undef this. */
+#define NV_IMPLICIT_BIT
+
+#ifdef LONG_DOUBLEKIND
+
+# if LONG_DOUBLEKIND == LONG_DOUBLE_IS_IEEE_754_128_BIT_LITTLE_ENDIAN || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN
+# define LONGDOUBLE_LITTLE_ENDIAN
+# endif
+
+# if LONG_DOUBLEKIND == LONG_DOUBLE_IS_IEEE_754_128_BIT_BIG_ENDIAN || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN
+# define LONGDOUBLE_BIG_ENDIAN
+# endif
+
+# if LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_LITTLE_ENDIAN || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_X86_80_BIT_BIG_ENDIAN
+# define LONGDOUBLE_X86_80_BIT
+# ifdef USE_LONG_DOUBLE
+# undef NV_IMPLICIT_BIT
+# endif
+# endif
+
+# if LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_LITTLE_ENDIAN || \
+ LONG_DOUBLEKIND == LONG_DOUBLE_IS_DOUBLEDOUBLE_128_BIT_BIG_ENDIAN
+# define LONGDOUBLE_DOUBLEDOUBLE
+# endif
+
+#endif /* LONG_DOUBLEKIND */
+
+#if NVSIZE == DOUBLESIZE
+# ifdef DOUBLE_LITTLE_ENDIAN
+# define NV_LITTLE_ENDIAN
+# endif
+# ifdef DOUBLE_BIG_ENDIAN
+# define NV_BIG_ENDIAN
+# endif
+# ifdef DOUBLE_MIX_ENDIAN
+# define NV_MIX_ENDIAN
+# endif
+#elif NVSIZE == LONG_DOUBLESIZE
+# ifdef LONGDOUBLE_LITTLE_ENDIAN
+# define NV_LITTLE_ENDIAN
+# endif
+# ifdef LONGDOUBLE_BIG_ENDIAN
+# define NV_BIG_ENDIAN
+# endif
+#endif
+
/*
(KEEP THIS LAST IN perl.h!)
@@ -5942,11 +6668,5 @@ extern void moncontrol(int);
#endif /* Include guard */
/*
- * Local variables:
- * c-indentation-style: bsd
- * c-basic-offset: 4
- * indent-tabs-mode: nil
- * End:
- *
* ex: set ts=8 sts=4 sw=4 et:
*/