This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Bump $XS::Typemap::VERSION after previous commit.
[perl5.git] / handy.h
diff --git a/handy.h b/handy.h
index 0b63b56..178d975 100644 (file)
--- a/handy.h
+++ b/handy.h
 #ifdef NULL
 #undef NULL
 #endif
-#ifndef I286
 #  define NULL 0
-#else
-#  define NULL 0L
-#endif
 #endif
 
 #ifndef PERL_CORE
@@ -105,7 +101,7 @@ Null SV pointer. (No longer available when C<PERL_CORE> is defined.)
 #endif /* NeXT || __NeXT__ */
 
 #ifndef HAS_BOOL
-# if defined(UTS) || defined(VMS)
+# if defined(VMS)
 #  define bool int
 # else
 #  define bool char
@@ -127,7 +123,7 @@ Null SV pointer. (No longer available when C<PERL_CORE> is defined.)
 #if (defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) || (defined(__SUNPRO_C)) /* C99 or close enough. */
 #  define FUNCTION__ __func__
 #else
-#  if (defined(_MSC_VER) && _MSC_VER < 1300) || /* Pre-MSVC 7.0 has neither __func__ nor __FUNCTION and no good workarounds, either. */ \
+#  if (defined(_MSC_VER) && _MSC_VER < 1300) || /* MSVC6 has neither __func__ nor __FUNCTION and no good workarounds, either. */ \
       (defined(__DECC_VER)) /* Tru64 or VMS, and strict C89 being used, but not modern enough cc (in Tur64, -c99 not known, only -std1). */
 #    define FUNCTION__ ""
 #  else
@@ -195,13 +191,13 @@ typedef U64TYPE U64;
 #       define PeRl_INT64_C(c) CAT2(c,LL)
 #       define PeRl_UINT64_C(c)        CAT2(c,ULL)
 #   else
-#       if LONGSIZE == 8 && QUADKIND == QUAD_IS_LONG
-#           define PeRl_INT64_C(c)     CAT2(c,L)
-#           define PeRl_UINT64_C(c)    CAT2(c,UL)
+#       if QUADKIND == QUAD_IS___INT64
+#           define PeRl_INT64_C(c)     CAT2(c,I64)
+#           define PeRl_UINT64_C(c)    CAT2(c,UI64)
 #       else
-#           if defined(_WIN64) && defined(_MSC_VER)
-#               define PeRl_INT64_C(c) CAT2(c,I64)
-#               define PeRl_UINT64_C(c)        CAT2(c,UI64)
+#           if LONGSIZE == 8 && QUADKIND == QUAD_IS_LONG
+#               define PeRl_INT64_C(c) CAT2(c,L)
+#               define PeRl_UINT64_C(c)        CAT2(c,UL)
 #           else
 #               define PeRl_INT64_C(c) ((I64TYPE)(c))
 #               define PeRl_UINT64_C(c)        ((U64TYPE)(c))
@@ -550,6 +546,10 @@ Returns a boolean indicating whether the specified character is a hexadecimal
 digit, [0-9A-Fa-f].  Variants C<isXDIGIT_A()> and C<isXDIGIT_L1()> are
 identical to C<isXDIGIT()>.
 
+=for apidoc Am|U8|READ_XDIGIT|char str*
+Returns the value of a hex digit and advances the string pointer.
+Behaviour is only well defined when isXDIGIT(*str) is true.
+
 =head1 Character case changing
 
 =for apidoc Am|char|toUPPER|char ch
@@ -599,61 +599,45 @@ patched there.  The file as of this writing is cpan/Devel-PPPort/parts/inc/misc
  * digits */
 #define isOCTAL_A(c)  cBOOL(FITS_IN_8_BITS(c) && (0xF8 & (c)) == '0')
 
-
 /* ASCII range only */
 #ifdef H_PERL       /* If have access to perl.h, lookup in its table */
-/* Bits for PL_charclass[].  These use names used in l1_char_class_tab.h but
- * their actual definitions are here.  If that has a name not used here, it
- * won't compile. */
-#  define _CC_WORDCHAR_A       (1<<0)
-#  define _CC_SPACE_A          (1<<1)
-#  define _CC_DIGIT_A          (1<<2)
-#  define _CC_ALNUMC_A         (1<<3)
-#  define _CC_ALPHA_A          (1<<4)
-#  define _CC_ASCII            (1<<5)
-#  define _CC_CNTRL_A          (1<<6)
-#  define _CC_GRAPH_A          (1<<7)
-#  define _CC_LOWER_A          (1<<8)
-#  define _CC_PRINT_A          (1<<9)
-#  define _CC_PUNCT_A          (1<<10)
-#  define _CC_UPPER_A          (1<<11)
-#  define _CC_XDIGIT_A         (1<<12)
-#  define _CC_PSXSPC_A         (1<<13)
-#  define _CC_BLANK_A          (1<<14)
-
-#  define _CC_WORDCHAR_L1      (1<<15)
-#  define _CC_SPACE_L1         (1<<16)
-#  define _CC_ALNUMC_L1        (1<<17)
-#  define _CC_ALPHA_L1         (1<<18)
-#  define _CC_CNTRL_L1         (1<<19)
-#  define _CC_GRAPH_L1         (1<<20)
-#  define _CC_LOWER_L1         (1<<21)
-#  define _CC_PRINT_L1         (1<<22)
-#  define _CC_PUNCT_L1         (1<<23)
-#  define _CC_UPPER_L1         (1<<24)
-#  define _CC_PSXSPC_L1        (1<<25)
-#  define _CC_BLANK_L1         (1<<26)
-#  define _CC_IDFIRST_A        (1<<27)
-#  define _CC_IDFIRST_L1       (1<<28)
-#  define _CC_CHARNAME_CONT    (1<<29)
-#  define _CC_NONLATIN1_FOLD   (1<<30)
-#  define _CC_QUOTEMETA        (1U<<31)        /* 1U keeps Solaris from griping */
-/* Unused: None
- * If more are needed, can give up some of the above.  The first ones to go
- * would be those that require just two tests to verify; either there are two
- * code points, like BLANK_A, or it occupies a single range like DIGIT_A,
- * UPPER_A, and LOWER_A.  Also consider the ones that can be replaced with two
- * tests and an additional mask, so
- *
- * #define isCNTRL_A  cBOOL(FITS_IN_8_BITS(c)                             \
- *                         && (( ! (~0x1F & NATIVE_TO_UNI(c)]))          \
- *                              || UNLIKELY(NATIVE_TO_UNI(c) == 0x7f)))
- *
- * This takes advantage of the contiguous block of these with the first one's
- * representation having the lower order bits all zero;, except the DELETE must
- * be tested specially.  A similar pattern can be used for for isCNTRL_L1,
- * isPRINT_A, and isPRINT_L1
- */
+
+/* Character class numbers.  For internal core Perl use only.  These are used
+ * in PL_charclass[] and the ones up through the one that corresponds to
+ * <_HIGHEST_REGCOMP_DOT_H_SYNC> are used by regcomp.h.  These use names used
+ * in l1_char_class_tab.h but their actual definitions are here.  If that has a
+ * name not used here, it won't compile. */
+#  define _CC_WORDCHAR           0
+#  define _CC_SPACE              1
+#  define _CC_DIGIT              2
+#  define _CC_ALNUMC             3
+#  define _CC_ALPHA              4
+#  define _CC_ASCII              5
+#  define _CC_CNTRL              6
+#  define _CC_GRAPH              7
+#  define _CC_LOWER              8
+#  define _CC_PRINT              9
+#  define _CC_PUNCT             10
+#  define _CC_UPPER             11
+#  define _CC_XDIGIT            12
+#  define _CC_PSXSPC            13
+#  define _CC_BLANK             14
+#  define _CC_VERTSPACE         15
+#  define _HIGHEST_REGCOMP_DOT_H_SYNC _CC_VERTSPACE
+
+#  define _CC_IDFIRST           16
+#  define _CC_CHARNAME_CONT     17
+#  define _CC_NONLATIN1_FOLD    18
+#  define _CC_QUOTEMETA         19
+#  define _CC_NON_FINAL_FOLD    20
+#  define _CC_IS_IN_SOME_FOLD   21
+/* Unused: 22-31
+ * If more bits are needed, one could add a second word for non-64bit
+ * QUAD_IS_INT systems, using some #ifdefs to distinguish between having a 2nd
+ * word or not.  The IS_IN_SOME_FOLD bit is the most easily expendable, as it
+ * is used only for optimization (as of this writing), and differs in the
+ * Latin1 range from the ALPHA bit only in two relatively unimportant
+ * characters: the masculine and feminine ordinal indicators */
 
 #  ifdef DOINIT
 EXTCONST  U32 PL_charclass[] = {
@@ -664,27 +648,46 @@ EXTCONST  U32 PL_charclass[] = {
 EXTCONST U32 PL_charclass[];
 #  endif
 
-#   define _generic_isCC(c, bit) cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & (bit)))
-
-#   define isALNUMC_A(c) _generic_isCC(c, _CC_ALNUMC_A)
-#   define isALPHA_A(c)  _generic_isCC(c, _CC_ALPHA_A)
-#   define isBLANK_A(c)  _generic_isCC(c, _CC_BLANK_A)
-#   define isCNTRL_A(c)  _generic_isCC(c, _CC_CNTRL_A)
-#   define isDIGIT_A(c)  _generic_isCC(c, _CC_DIGIT_A)
-#   define isGRAPH_A(c)  _generic_isCC(c, _CC_GRAPH_A)
-#   define isIDFIRST_A(c)  _generic_isCC(c, _CC_IDFIRST_A)
-#   define isLOWER_A(c)  _generic_isCC(c, _CC_LOWER_A)
-#   define isPRINT_A(c)  _generic_isCC(c, _CC_PRINT_A)
-#   define isPSXSPC_A(c) _generic_isCC(c, _CC_PSXSPC_A)
-#   define isPUNCT_A(c)  _generic_isCC(c, _CC_PUNCT_A)
-#   define isSPACE_A(c)  _generic_isCC(c, _CC_SPACE_A)
-#   define isUPPER_A(c)  _generic_isCC(c, _CC_UPPER_A)
-#   define isWORDCHAR_A(c) _generic_isCC(c, _CC_WORDCHAR_A)
-#   define isXDIGIT_A(c)  _generic_isCC(c, _CC_XDIGIT_A)
+    /* The 1U keeps Solaris from griping when shifting sets the uppermost bit */
+#   define _CC_mask(classnum) (1U << (classnum))
+#   define _generic_isCC(c, classnum) cBOOL(FITS_IN_8_BITS(c) \
+                            && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_mask(classnum)))
+
+    /* The mask for the _A versions of the macros; it just adds in the bit for
+     * ASCII. */
+#   define _CC_mask_A(classnum) (_CC_mask(classnum) | _CC_mask(_CC_ASCII))
+
+    /* The _A version makes sure that both the desired bit and the ASCII bit
+     * are present */
+#   define _generic_isCC_A(c, classnum) (FITS_IN_8_BITS(c) \
+        && ((PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_mask_A(classnum)) \
+                                == _CC_mask_A(classnum)))
+
+#   define isALNUMC_A(c) _generic_isCC_A(c, _CC_ALNUMC)
+#   define isALPHA_A(c)  _generic_isCC_A(c, _CC_ALPHA)
+#   define isBLANK_A(c)  _generic_isCC_A(c, _CC_BLANK)
+#   define isCNTRL_A(c)  _generic_isCC_A(c, _CC_CNTRL)
+#   define isDIGIT_A(c)  _generic_isCC(c, _CC_DIGIT)
+#   define isGRAPH_A(c)  _generic_isCC_A(c, _CC_GRAPH)
+#   define isLOWER_A(c)  _generic_isCC_A(c, _CC_LOWER)
+#   define isPRINT_A(c)  _generic_isCC_A(c, _CC_PRINT)
+#   define isPSXSPC_A(c) _generic_isCC_A(c, _CC_PSXSPC)
+#   define isPUNCT_A(c)  _generic_isCC_A(c, _CC_PUNCT)
+#   define isSPACE_A(c)  _generic_isCC_A(c, _CC_SPACE)
+#   define isUPPER_A(c)  _generic_isCC_A(c, _CC_UPPER)
+#   define isWORDCHAR_A(c) _generic_isCC_A(c, _CC_WORDCHAR)
+#   define isXDIGIT_A(c)  _generic_isCC(c, _CC_XDIGIT)
+#   define isIDFIRST_A(c) _generic_isCC_A(c, ( _CC_IDFIRST))
+
     /* Either participates in a fold with a character above 255, or is a
      * multi-char fold */
-#   define _HAS_NONLATIN1_FOLD_CLOSURE_ONLY_FOR_USE_BY_REGCOMP_DOT_C_AND_REGEXEC_DOT_C(c) ((! cBOOL(FITS_IN_8_BITS(c))) || (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_NONLATIN1_FOLD))
+#   define _HAS_NONLATIN1_FOLD_CLOSURE_ONLY_FOR_USE_BY_REGCOMP_DOT_C_AND_REGEXEC_DOT_C(c) ((! cBOOL(FITS_IN_8_BITS(c))) || (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_mask(_CC_NONLATIN1_FOLD)))
+
 #   define _isQUOTEMETA(c) _generic_isCC(c, _CC_QUOTEMETA)
+#   define _IS_NON_FINAL_FOLD_ONLY_FOR_USE_BY_REGCOMP_DOT_C(c) \
+                                            _generic_isCC(c, _CC_NON_FINAL_FOLD)
+#   define _IS_IN_SOME_FOLD_ONLY_FOR_USE_BY_REGCOMP_DOT_C(c) \
+                                            _generic_isCC(c, _CC_IS_IN_SOME_FOLD)
 #else   /* No perl.h. */
 #   ifdef EBCDIC
 #       define isALNUMC_A(c)   (isASCII(c) && isALNUMC(c))
@@ -723,21 +726,23 @@ EXTCONST U32 PL_charclass[];
 
 /* Latin1 definitions */
 #ifdef H_PERL
-#   define isALNUMC_L1(c) _generic_isCC(c, _CC_ALNUMC_L1)
-#   define isALPHA_L1(c)  _generic_isCC(c, _CC_ALPHA_L1)
-#   define isBLANK_L1(c)  _generic_isCC(c, _CC_BLANK_L1)
+#   define isALNUMC_L1(c) _generic_isCC(c, _CC_ALNUMC)
+#   define isALPHA_L1(c)  _generic_isCC(c, _CC_ALPHA)
+#   define isBLANK_L1(c)  _generic_isCC(c, _CC_BLANK)
+
 /*  continuation character for legal NAME in \N{NAME} */
 #   define isCHARNAME_CONT(c) _generic_isCC(c, _CC_CHARNAME_CONT)
-#   define isCNTRL_L1(c)  _generic_isCC(c, _CC_CNTRL_L1)
-#   define isGRAPH_L1(c)  _generic_isCC(c, _CC_GRAPH_L1)
-#   define isIDFIRST_L1(c) _generic_isCC(c, _CC_IDFIRST_L1)
-#   define isLOWER_L1(c)  _generic_isCC(c, _CC_LOWER_L1)
-#   define isPRINT_L1(c)  _generic_isCC(c, _CC_PRINT_L1)
-#   define isPSXSPC_L1(c) _generic_isCC(c, _CC_PSXSPC_L1)
-#   define isPUNCT_L1(c)  _generic_isCC(c, _CC_PUNCT_L1)
-#   define isSPACE_L1(c)  _generic_isCC(c, _CC_SPACE_L1)
-#   define isUPPER_L1(c)  _generic_isCC(c, _CC_UPPER_L1)
-#   define isWORDCHAR_L1(c) _generic_isCC(c, _CC_WORDCHAR_L1)
+
+#   define isCNTRL_L1(c)  _generic_isCC(c, _CC_CNTRL)
+#   define isGRAPH_L1(c)  _generic_isCC(c, _CC_GRAPH)
+#   define isLOWER_L1(c)  _generic_isCC(c, _CC_LOWER)
+#   define isPRINT_L1(c)  _generic_isCC(c, _CC_PRINT)
+#   define isPSXSPC_L1(c) _generic_isCC(c, _CC_PSXSPC)
+#   define isPUNCT_L1(c)  _generic_isCC(c, _CC_PUNCT)
+#   define isSPACE_L1(c)  _generic_isCC(c, _CC_SPACE)
+#   define isUPPER_L1(c)  _generic_isCC(c, _CC_UPPER)
+#   define isWORDCHAR_L1(c) _generic_isCC(c, _CC_WORDCHAR)
+#   define isIDFIRST_L1(c) _generic_isCC(c, _CC_IDFIRST)
 #else /* No access to perl.h.  Only a few provided here, just in case needed
        * for backwards compatibility */
     /* ALPHAU includes Unicode semantics for latin1 characters.  It has an extra
@@ -908,40 +913,46 @@ EXTCONST U32 PL_charclass[];
 
 #define isPSXSPC_LC(c)         (isSPACE_LC(c) || (c) == '\v')
 
-/* For use in the macros just below.  If the input is Latin1, use the Latin1
- * (_L1) version of the macro; otherwise use the function.  Won't compile if
- * 'c' isn't unsigned, as won't match function prototype. The macros do bounds
- * checking, so have duplicate checks here, so could create versions of the
- * macros that don't, but experiments show that gcc optimizes them out anyway.
- */
-#define generic_uni(macro, function, c) ((c) < 256               \
-                                         ? CAT2(macro, _L1)(c)   \
-                                         : function(c))
+/* For internal core Perl use only.  If the input is Latin1, use the Latin1
+ * macro; otherwise use the function.  Won't compile if 'c' isn't unsigned, as
+ * won't match function prototype. The macros do bounds checking, so have
+ * duplicate checks here, so could create versions of the macros that don't,
+ * but experiments show that gcc optimizes them out anyway. */
+
 /* Note that all ignore 'use bytes' */
+#define _generic_uni(classnum, function, c) ((c) < 256                    \
+                                             ? _generic_isCC(c, classnum) \
+                                             : function(c))
+
+#define isWORDCHAR_uni(c)       _generic_uni(_CC_WORDCHAR, is_uni_alnum, c)
+#define isALNUM_uni(c)          isWORDCHAR_uni(c)
+#define isBLANK_uni(c)          _generic_uni(_CC_BLANK, is_HORIZWS_cp_high, c)
+#define isIDFIRST_uni(c)        _generic_uni(_CC_IDFIRST, is_uni_idfirst, c)
+#define isALPHA_uni(c)          _generic_uni(_CC_ALPHA, is_uni_alpha, c)
+#define isSPACE_uni(c)          _generic_uni(_CC_SPACE, is_XPERLSPACE_cp_high, c)
+#define isVERTWS_uni(c)         _generic_uni(_CC_VERTSPACE, is_VERTWS_cp_high, c)
+#define isDIGIT_uni(c)          _generic_uni(_CC_DIGIT, is_uni_digit, c)
+#define isUPPER_uni(c)          _generic_uni(_CC_UPPER, is_uni_upper, c)
+#define isLOWER_uni(c)          _generic_uni(_CC_LOWER, is_uni_lower, c)
+#define isASCII_uni(c)          isASCII(c)
 
-#define isALNUM_uni(c)         generic_uni(isWORDCHAR, is_uni_alnum, c)
-#define isBLANK_uni(c)         generic_uni(isBLANK, is_uni_blank, c)
-#define isIDFIRST_uni(c)        generic_uni(isIDFIRST, is_uni_idfirst, c)
-#define isALPHA_uni(c)         generic_uni(isALPHA, is_uni_alpha, c)
-#define isSPACE_uni(c)         generic_uni(isSPACE, is_uni_space, c)
-#define isDIGIT_uni(c)         generic_uni(isDIGIT, is_uni_digit, c)
-#define isUPPER_uni(c)         generic_uni(isUPPER, is_uni_upper, c)
-#define isLOWER_uni(c)         generic_uni(isLOWER, is_uni_lower, c)
-#define isASCII_uni(c)         isASCII(c)
 /* All controls are in Latin1 */
-#define isCNTRL_uni(c)         ((c) < 256 && isCNTRL_L1(c))
-#define isGRAPH_uni(c)         generic_uni(isGRAPH, is_uni_graph, c)
-#define isPRINT_uni(c)         generic_uni(isPRINT, is_uni_print, c)
-#define isPUNCT_uni(c)         generic_uni(isPUNCT, is_uni_punct, c)
-#define isXDIGIT_uni(c)                generic_uni(isXDIGIT, is_uni_xdigit, c)
+#define isCNTRL_uni(c)          isCNTRL_L1(c)
+
+#define isGRAPH_uni(c)          _generic_uni(_CC_GRAPH, is_uni_graph, c)
+#define isPRINT_uni(c)          _generic_uni(_CC_PRINT, is_uni_print, c)
+#define isPUNCT_uni(c)          _generic_uni(_CC_PUNCT, is_uni_punct, c)
+#define isXDIGIT_uni(c)         _generic_uni(_CC_XDIGIT, is_XDIGIT_cp_high, c)
+
+/* Posix and regular space differ only in U+000B, which is in Latin1 */
+#define isPSXSPC_uni(c)         _generic_uni(_CC_PSXSPC,                \
+                                             is_XPERLSPACE_cp_high, c)
+
 #define toUPPER_uni(c,s,l)     to_uni_upper(c,s,l)
 #define toTITLE_uni(c,s,l)     to_uni_title(c,s,l)
 #define toLOWER_uni(c,s,l)     to_uni_lower(c,s,l)
 #define toFOLD_uni(c,s,l)      to_uni_fold(c,s,l)
 
-/* Posix and regular space differ only in U+000B, which is in Latin1 */
-#define isPSXSPC_uni(c)                ((c) < 256 ? isPSXSPC_L1(c) : isSPACE_uni(c))
-
 #define isALNUM_LC_uvchr(c)    (c < 256 ? isALNUM_LC(c) : is_uni_alnum_lc(c))
 #define isIDFIRST_LC_uvchr(c)  (c < 256 ? isIDFIRST_LC(c) : is_uni_idfirst_lc(c))
 #define isALPHA_LC_uvchr(c)    (c < 256 ? isALPHA_LC(c) : is_uni_alpha_lc(c))
@@ -957,23 +968,27 @@ EXTCONST U32 PL_charclass[];
 #define isPSXSPC_LC_uni(c)     (isSPACE_LC_uni(c) ||(c) == '\f')
 #define isBLANK_LC_uni(c)      isBLANK(c) /* could be wrong */
 
-/* For use in the macros just below.  If the input is ASCII, use the ASCII (_A)
- * version of the macro; if the input is in the upper Latin1 range, use the
- * Latin1 (_L1) version of the macro, after converting from utf8; otherwise use
- * the function.  This relies on the fact that ASCII characters have the same
- * representation whether utf8 or not */
-#define generic_utf8(macro, function, p) (isASCII(*(p))                        \
-                                         ? CAT2(CAT2(macro,_),A)(*(p))               \
-                                         : (UTF8_IS_DOWNGRADEABLE_START(*(p))) \
-                                           ? CAT2(macro, _L1)                  \
-                                             (TWO_BYTE_UTF8_TO_UNI(*(p),       \
-                                                                   *((p)+1)))  \
-                                           : function(p))
-
-/* Note that all assume that the utf8 has been validated, and ignore 'use
+/* For internal core Perl use only.  If the input is in the Latin1 range, use
+ * the Latin1 macro 'classnum' on 'p' which is a pointer to a UTF-8 string.
+ * Otherwise use the value given by the 'utf8' parameter.  This relies on the
+ * fact that ASCII characters have the same representation whether utf8 or not.
+ * Note that it assumes that the utf8 has been validated, and ignores 'use
  * bytes' */
+#define _generic_utf8_utf8(classnum, p, utf8) (UTF8_IS_INVARIANT(*(p))         \
+                                         ? _generic_isCC(*(p), classnum)       \
+                                         : (UTF8_IS_DOWNGRADEABLE_START(*(p))) \
+                                           ? _generic_isCC(                    \
+                                                   TWO_BYTE_UTF8_TO_UNI(*(p),  \
+                                                                   *((p)+1 )), \
+                                                   classnum)                   \
+                                           : utf8)
+/* Like the above, but calls 'function(p)' to get the utf8 value */
+#define _generic_utf8(classnum, function, p)  \
+                                    _generic_utf8_utf8(classnum, p, function(p))
+
+#define isWORDCHAR_utf8(p)      _generic_utf8(_CC_WORDCHAR, is_utf8_alnum, p)
+#define isALNUM_utf8(p)         isWORDCHAR_utf8(p)  /* back compat */
 
-#define isALNUM_utf8(p)                generic_utf8(isWORDCHAR, is_utf8_alnum, p)
 /* To prevent S_scan_word in toke.c from hanging, we have to make sure that
  * IDFIRST is an alnum.  See
  * http://rt.perl.org/rt3/Ticket/Display.html?id=74022 for more detail than you
@@ -981,38 +996,34 @@ EXTCONST U32 PL_charclass[];
  * isIDFIRST_uni() which it hasn't so far.  (In the ASCII range, there isn't a
  * difference.) This used to be not the XID version, but we decided to go with
  * the more modern Unicode definition */
-#define isIDFIRST_utf8(p)       (isASCII(*(p))                                  \
-                                ? isIDFIRST_A(*(p))                             \
-                                : (UTF8_IS_DOWNGRADEABLE_START(*(p)))           \
-                                  ? isIDFIRST_L1(TWO_BYTE_UTF8_TO_UNI(*(p),     \
-                                                                      *((p)+1)))\
-                                  : Perl__is_utf8__perl_idstart(aTHX_ p))
-#define isIDCONT_utf8(p)       generic_utf8(isWORDCHAR, is_utf8_xidcont, p)
-#define isALPHA_utf8(p)                generic_utf8(isALPHA, is_utf8_alpha, p)
-#define isBLANK_utf8(p)                generic_utf8(isBLANK, is_utf8_blank, p)
-#define isSPACE_utf8(p)                generic_utf8(isSPACE, is_utf8_space, p)
-#define isDIGIT_utf8(p)                generic_utf8(isDIGIT, is_utf8_digit, p)
-#define isUPPER_utf8(p)                generic_utf8(isUPPER, is_utf8_upper, p)
-#define isLOWER_utf8(p)                generic_utf8(isLOWER, is_utf8_lower, p)
+#define isIDFIRST_utf8(p)       _generic_utf8(_CC_IDFIRST,               \
+                                              _is_utf8__perl_idstart, p)
+
+#define isIDCONT_utf8(p)        _generic_utf8(_CC_WORDCHAR, is_utf8_xidcont, p)
+#define isALPHA_utf8(p)         _generic_utf8(_CC_ALPHA, is_utf8_alpha, p)
+#define isBLANK_utf8(p)         _generic_utf8(_CC_BLANK, is_HORIZWS_high, p)
+#define isSPACE_utf8(p)         _generic_utf8(_CC_SPACE, is_XPERLSPACE_high, p)
+#define isVERTWS_utf8(p)        _generic_utf8(_CC_VERTSPACE, is_VERTWS_high, p)
+#define isDIGIT_utf8(p)         _generic_utf8(_CC_DIGIT, is_utf8_digit, p)
+#define isUPPER_utf8(p)         _generic_utf8(_CC_UPPER, is_utf8_upper, p)
+#define isLOWER_utf8(p)         _generic_utf8(_CC_LOWER, is_utf8_lower, p)
+
 /* Because ASCII is invariant under utf8, the non-utf8 macro works */
-#define isASCII_utf8(p)                isASCII(*p)
-#define isCNTRL_utf8(p)                generic_utf8(isCNTRL, is_utf8_cntrl, p)
-#define isGRAPH_utf8(p)                generic_utf8(isGRAPH, is_utf8_graph, p)
-#define isPRINT_utf8(p)                generic_utf8(isPRINT, is_utf8_print, p)
-#define isPUNCT_utf8(p)                generic_utf8(isPUNCT, is_utf8_punct, p)
-#define isXDIGIT_utf8(p)       generic_utf8(isXDIGIT, is_utf8_xdigit, p)
+#define isASCII_utf8(p)         isASCII(*p)
+
+#define isCNTRL_utf8(p)         _generic_utf8_utf8(_CC_CNTRL, p, 0)
+#define isGRAPH_utf8(p)         _generic_utf8(_CC_GRAPH, is_utf8_graph, p)
+#define isPRINT_utf8(p)         _generic_utf8(_CC_PRINT, is_utf8_print, p)
+#define isPUNCT_utf8(p)         _generic_utf8(_CC_PUNCT, is_utf8_punct, p)
+#define isXDIGIT_utf8(p)        _generic_utf8(_CC_XDIGIT, is_XDIGIT_high, p)
 #define toUPPER_utf8(p,s,l)    to_utf8_upper(p,s,l)
 #define toTITLE_utf8(p,s,l)    to_utf8_title(p,s,l)
 #define toLOWER_utf8(p,s,l)    to_utf8_lower(p,s,l)
 
 /* Posix and regular space differ only in U+000B, which is in ASCII (and hence
  * Latin1 */
-#define isPSXSPC_utf8(p)       ((isASCII(*(p)))                               \
-                                ? isPSXSPC_A(*(p))                             \
-                                : (UTF8_IS_DOWNGRADEABLE_START(*(p))           \
-                                 ? isPSXSPC_L1(TWO_BYTE_UTF8_TO_UNI(*(p),     \
-                                                                     *((p)+1)))\
-                                  : isSPACE_utf8(p)))
+#define isPSXSPC_utf8(p)        _generic_utf8(_CC_PSXSPC, is_XPERLSPACE_high, p)
+
 #define isALNUM_LC_utf8(p)     isALNUM_LC_uvchr(valid_utf8_to_uvchr(p,  0))
 #define isIDFIRST_LC_utf8(p)   isIDFIRST_LC_uvchr(valid_utf8_to_uvchr(p,  0))
 #define isALPHA_LC_utf8(p)     isALPHA_LC_uvchr(valid_utf8_to_uvchr(p,  0))
@@ -1030,12 +1041,14 @@ EXTCONST U32 PL_charclass[];
 #define isPSXSPC_LC_utf8(c)    (isSPACE_LC_utf8(c) ||(c) == '\f')
 
 /* This conversion works both ways, strangely enough. On EBCDIC platforms,
- * CTRL-@ is 0, CTRL-A is 1, etc, just like on ASCII */
+ * CTRL-@ is 0, CTRL-A is 1, etc, just like on ASCII, except that they don't
+ * necessarily mean the same characters, e.g. CTRL-D is 4 on both systems, but
+ * that is EOT on ASCII;  ST on EBCDIC */
 #  define toCTRL(c)    (toUPPER(NATIVE_TO_UNI(c)) ^ 64)
 
 /* Line numbers are unsigned, 32 bits. */
 typedef U32 line_t;
-#define NOLINE ((line_t) 4294967295UL)
+#define NOLINE ((line_t) 4294967295UL)  /* = FFFFFFFF */
 
 /* Helpful alias for version prescan */
 #define is_LAX_VERSION(a,b) \
@@ -1050,6 +1063,8 @@ typedef U32 line_t;
        } \
        return a;
 
+#define READ_XDIGIT(s) (isALPHA(*(s)) ? ((*(s)++ + 9) & 0xf) : (*(s)++ & 0xf))
+
 /*
 =head1 Memory Management
 
@@ -1142,13 +1157,13 @@ PoisonWith(0xEF) for catching access to freed memory.
  * overly eager compilers that will bleat about e.g.
  * (U16)n > (size_t)~0/sizeof(U16) always being false. */
 #ifdef PERL_MALLOC_WRAP
-#define MEM_WRAP_CHECK(n,t) MEM_WRAP_CHECK_1(n,t,PL_memory_wrap)
+#define MEM_WRAP_CHECK(n,t) \
+       (void)(sizeof(t) > 1 && ((MEM_SIZE)(n)+0.0) > MEM_SIZE_MAX/sizeof(t) && (croak_memory_wrap(),0))
 #define MEM_WRAP_CHECK_1(n,t,a) \
        (void)(sizeof(t) > 1 && ((MEM_SIZE)(n)+0.0) > MEM_SIZE_MAX/sizeof(t) && (Perl_croak_nocontext("%s",(a)),0))
 #define MEM_WRAP_CHECK_(n,t) MEM_WRAP_CHECK(n,t),
 
-#define PERL_STRLEN_ROUNDUP(n) ((void)(((n) > MEM_SIZE_MAX - 2 * PERL_STRLEN_ROUNDUP_QUANTUM) ? (Perl_croak_nocontext("%s",PL_memory_wrap),0):0),((n-1+PERL_STRLEN_ROUNDUP_QUANTUM)&~((MEM_SIZE)PERL_STRLEN_ROUNDUP_QUANTUM-1)))
-
+#define PERL_STRLEN_ROUNDUP(n) ((void)(((n) > MEM_SIZE_MAX - 2 * PERL_STRLEN_ROUNDUP_QUANTUM) ? (croak_memory_wrap(),0):0),((n-1+PERL_STRLEN_ROUNDUP_QUANTUM)&~((MEM_SIZE)PERL_STRLEN_ROUNDUP_QUANTUM-1)))
 #else
 
 #define MEM_WRAP_CHECK(n,t)