This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Perl_isinf and Perl_isfinite enhancements.
[perl5.git] / perl.h
diff --git a/perl.h b/perl.h
index 58dd2c1..bc4209f 100644 (file)
--- a/perl.h
+++ b/perl.h
 #  define PERL_UNUSED_VAR(x) ((void)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
  * semicolon being left alone on a line:
  * ;
  * which makes compilers mildly cranky.  Therefore at file level one
- * should use the #ifdef GCC_DIAG_PRAGMA guard around the GCC_DIAG_IGNORE
- * and GCC_DIAG_RESTORE.
- *
- * (An alternative solution would be not to use the semicolon, and then
- * the empty definition would be just empty, but that would make the code
- * look odd, and might mess up e.g. smart editors indenting the code.)
+ * 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(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
@@ -1545,12 +1544,14 @@ 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
+
 #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
@@ -1559,16 +1560,47 @@ EXTERN_C char *crypt(const char *, const char *);
 
 #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
@@ -1645,7 +1677,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))
@@ -1815,6 +1848,12 @@ typedef NVTYPE NV;
 #   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
@@ -1870,16 +1909,30 @@ EXTERN_C long double modfl(long double, long double *);
 #           define Perl_frexp(x,y) Perl_my_frexpl(x,y)
 #       endif
 #   endif
+#   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
 #   ifndef Perl_isnan
 #       ifdef HAS_ISNANL
 #           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)
+#           define Perl_isinf(x) isinfl(x)
 #       endif
 #   endif
+#   ifndef Perl_isfinite
+#     ifdef HAS_ISFINITEL
+#       define Perl_isfinite(x) isfinitel(x)
+#     elif defined(HAS_FINITEL)
+#       define Perl_isfinite(x) finitel(x)
+#     endif
+#   endif
 #else
 #   define NV_DIG DBL_DIG
 #   ifdef DBL_MANT_DIG
@@ -1891,6 +1944,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
@@ -1920,18 +1979,18 @@ EXTERN_C long double modfl(long double, long double *);
 #   define Perl_fmod fmod
 #   define Perl_modf(x,y) modf(x,y)
 #   define Perl_frexp(x,y) frexp(x,y)
+#   define Perl_ldexp(x,y) ldexp(x,y)
 #endif
 
-/* rumor has it that Win32 has _fpclass() */
-
-/* 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> */
+/* Solaris and IRIX have fpclass/fpclassl, but they are using
+ * an enum typedef, not cpp symbols, and Configure doesn't detect that.
+ * Define one symbol also as a cpp symbol so we can detect it. */
+#if defined(__sun) || defined(__irix__) /* XXX Configure test instead */
+# define FP_SNAN FP_SNAN
+#endif
 
 #if !defined(Perl_fp_class) && (defined(HAS_FPCLASS)||defined(HAS_FPCLASSL))
+#    include <math.h>
 #    ifdef I_IEEFP
 #        include <ieeefp.h>
 #    endif
@@ -1939,55 +1998,72 @@ 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
+#    ifdef 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_SNAN)
+#        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)
 #    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
 
+/* 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> */
+
 #if !defined(Perl_fp_class) && defined(HAS_FP_CLASS)
 #    include <math.h>
 #    if !defined(FP_SNAN) && defined(I_FP_CLASS)
 #        include <fp_class.h>
 #    endif
-#    define Perl_fp_class(x)           fp_class(x)
+#    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
+#        define Perl_fp_class(x)       fp_class(x)
+#    endif
 #    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)
 #    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_snan(x)      (fp_classify(x)==FP_SNAN)
+#    define Perl_fp_class_qnan(x)      (fp_classify(x)==FP_QNAN)
 #    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)
@@ -2002,26 +2078,75 @@ EXTERN_C long double modfl(long double, long double *);
 #    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() */
+#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
+#    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_QNAN|_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
 
 #ifndef Perl_isnan
 #   ifdef HAS_ISNAN
-#       define Perl_isnan(x) isnan((NV)x)
+#       define Perl_isnan(x) isnan((double)x)
 #   else
 #       ifdef Perl_fp_class_nan
 #           define Perl_isnan(x) Perl_fp_class_nan(x)
@@ -2039,31 +2164,24 @@ EXTERN_C long double modfl(long double, long double *);
 int isnan(double d);
 #endif
 
-#ifndef Perl_isinf
-#   ifdef HAS_ISINF
-#       define Perl_isinf(x) isinf((NV)x)
+#ifndef Perl_isfinite
+#   ifdef HAS_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)
+#   elif defined(Perl_is_inf) && defined(Perl_is_nan)
+#     define Perl_isfinite(x) !(Perl_is_inf(x)||Perl_is_nan(x))
 #   else
-#       ifdef Perl_fp_class_inf
-#           define Perl_isinf(x) Perl_fp_class_inf(x)
-#       else
-#           define Perl_isinf(x) ((x)==NV_INF)
-#       endif
+/* NaN*0 is NaN, [+-]Inf*0 is NaN, zero for anything else. */
+#     define Perl_isfinite(x) (((x) * 0) == 0)
 #   endif
 #endif
 
-#ifndef Perl_isfinite
-#   ifdef HAS_FINITE
-#       define Perl_isfinite(x) finite((NV)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
+#ifndef Perl_isinf
+#   if defined(Perl_isfinite) && defined(Perl_isnan)
+#       define Perl_isinf(x) !(Perl_isfinite(x)||Perl_isnan(x))
 #   endif
 #endif
 
@@ -4610,6 +4728,9 @@ EXTCONST char PL_bincompat_options[] =
 #  ifdef PERL_GLOBAL_STRUCT
                             " PERL_GLOBAL_STRUCT"
 #  endif
+#  ifdef PERL_GLOBAL_STRUCT_PRIVATE
+                            " PERL_GLOBAL_STRUCT_PRIVATE"
+#  endif
 #  ifdef PERL_IMPLICIT_CONTEXT
                             " PERL_IMPLICIT_CONTEXT"
 #  endif
@@ -4661,6 +4782,9 @@ 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
@@ -4758,6 +4882,7 @@ typedef enum {
     XATTRBLOCK,
     XATTRTERM,
     XTERMBLOCK,
+    XBLOCKTERM,
     XPOSTDEREF,
     XTERMORDORDOR /* evil hack */
     /* update exp_name[] in toke.c if adding to this enum */
@@ -5729,6 +5854,7 @@ int flock(int fd, int op);
 #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)
 
@@ -5738,6 +5864,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? */