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 c90a876..178d975 100644 (file)
--- a/handy.h
+++ b/handy.h
@@ -1,7 +1,7 @@
 /*    handy.h
  *
  *    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1999, 2000,
- *    2001, 2002, 2004, 2005, 2006, 2007, 2008 by Larry Wall and others
+ *    2001, 2002, 2004, 2005, 2006, 2007, 2008, 2012 by Larry Wall and others
  *
  *    You may distribute under the terms of either the GNU General Public
  *    License or the Artistic License, as specified in the README file.
 #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
@@ -191,25 +187,29 @@ typedef U64TYPE U64;
 #endif /* PERL_CORE */
 
 #if defined(HAS_QUAD) && defined(USE_64_BIT_INT)
-#   ifndef UINT64_C /* usually from <inttypes.h> */
-#       if defined(HAS_LONG_LONG) && QUADKIND == QUAD_IS_LONG_LONG
-#           define INT64_C(c)  CAT2(c,LL)
-#           define UINT64_C(c) CAT2(c,ULL)
+#   if defined(HAS_LONG_LONG) && QUADKIND == QUAD_IS_LONG_LONG
+#       define PeRl_INT64_C(c) CAT2(c,LL)
+#       define PeRl_UINT64_C(c)        CAT2(c,ULL)
+#   else
+#       if QUADKIND == QUAD_IS___INT64
+#           define PeRl_INT64_C(c)     CAT2(c,I64)
+#           define PeRl_UINT64_C(c)    CAT2(c,UI64)
 #       else
 #           if LONGSIZE == 8 && QUADKIND == QUAD_IS_LONG
-#               define INT64_C(c)      CAT2(c,L)
-#               define UINT64_C(c)     CAT2(c,UL)
+#               define PeRl_INT64_C(c) CAT2(c,L)
+#               define PeRl_UINT64_C(c)        CAT2(c,UL)
 #           else
-#               if defined(_WIN64) && defined(_MSC_VER)
-#                   define INT64_C(c)  CAT2(c,I64)
-#                   define UINT64_C(c) CAT2(c,UI64)
-#               else
-#                   define INT64_C(c)  ((I64TYPE)(c))
-#                   define UINT64_C(c) ((U64TYPE)(c))
-#               endif
+#               define PeRl_INT64_C(c) ((I64TYPE)(c))
+#               define PeRl_UINT64_C(c)        ((U64TYPE)(c))
 #           endif
 #       endif
 #   endif
+#   ifndef UINT64_C
+#   define UINT64_C(c) PeRl_UINT64_C(c)
+#   endif
+#   ifndef INT64_C
+#   define INT64_C(c) PeRl_INT64_C(c)
+#   endif
 #endif
 
 #if defined(UINT8_MAX) && defined(INT16_MAX) && defined(INT32_MAX)
@@ -546,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
@@ -590,49 +594,50 @@ patched there.  The file as of this writing is cpan/Devel-PPPort/parts/inc/misc
 #define isASCII_A(c)  isASCII(c)
 #define isASCII_L1(c)  isASCII(c)
 
+/* The lower 3 bits in both the ASCII and EBCDIC representations of '0' are 0,
+ * and the 8 possible permutations of those bits exactly comprise the 8 octal
+ * 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_ALNUMC_A         (1<<0)
-#  define _CC_ALNUMC_L1        (1<<1)
-#  define _CC_ALPHA_A          (1<<2)
-#  define _CC_ALPHA_L1         (1<<3)
-#  define _CC_BLANK_A          (1<<4)
-#  define _CC_BLANK_L1         (1<<5)
-#  define _CC_CHARNAME_CONT    (1<<6)
-#  define _CC_CNTRL_A          (1<<7)
-#  define _CC_CNTRL_L1         (1<<8)
-#  define _CC_DIGIT_A          (1<<9)
-#  define _CC_GRAPH_A          (1<<10)
-#  define _CC_GRAPH_L1         (1<<11)
-#  define _CC_IDFIRST_A        (1<<12)
-#  define _CC_IDFIRST_L1       (1<<13)
-#  define _CC_LOWER_A          (1<<14)
-#  define _CC_LOWER_L1         (1<<15)
-#  define _CC_OCTAL_A          (1<<16)
-#  define _CC_PRINT_A          (1<<17)
-#  define _CC_PRINT_L1         (1<<18)
-#  define _CC_PSXSPC_A         (1<<19)
-#  define _CC_PSXSPC_L1        (1<<20)
-#  define _CC_PUNCT_A          (1<<21)
-#  define _CC_PUNCT_L1         (1<<22)
-#  define _CC_SPACE_A          (1<<23)
-#  define _CC_SPACE_L1         (1<<24)
-#  define _CC_UPPER_A          (1<<25)
-#  define _CC_UPPER_L1         (1<<26)
-#  define _CC_WORDCHAR_A       (1<<27)
-#  define _CC_WORDCHAR_L1      (1<<28)
-#  define _CC_XDIGIT_A         (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 occupy a single range like OCTAL_A, DIGIT_A,
- * UPPER_A, and LOWER_A.
- */
+
+/* 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[] = {
@@ -643,28 +648,47 @@ EXTCONST  U32 PL_charclass[] = {
 EXTCONST U32 PL_charclass[];
 #  endif
 
-#   define isALNUMC_A(c) cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_ALNUMC_A))
-#   define isALPHA_A(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_ALPHA_A))
-#   define isBLANK_A(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_BLANK_A))
-#   define isCNTRL_A(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_CNTRL_A))
-#   define isDIGIT_A(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_DIGIT_A))
-#   define isGRAPH_A(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_GRAPH_A))
-#   define isIDFIRST_A(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_IDFIRST_A))
-#   define isLOWER_A(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_LOWER_A))
-#   define isOCTAL_A(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_OCTAL_A))
-#   define isPRINT_A(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_PRINT_A))
-#   define isPSXSPC_A(c) cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_PSXSPC_A))
-#   define isPUNCT_A(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_PUNCT_A))
-#   define isSPACE_A(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_SPACE_A))
-#   define isUPPER_A(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_UPPER_A))
-#   define isWORDCHAR_A(c) cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_WORDCHAR_A))
-#   define isXDIGIT_A(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(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 _isQUOTEMETA(c) cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_QUOTEMETA))
+#   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. */
-#   define isOCTAL_A(c)  ((c) <= '7' && (c) >= '0')
 #   ifdef EBCDIC
 #       define isALNUMC_A(c)   (isASCII(c) && isALNUMC(c))
 #       define isALPHA_A(c)    (isASCII(c) && isALPHA(c))
@@ -702,21 +726,23 @@ EXTCONST U32 PL_charclass[];
 
 /* Latin1 definitions */
 #ifdef H_PERL
-#   define isALNUMC_L1(c) cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_ALNUMC_L1))
-#   define isALPHA_L1(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_ALPHA_L1))
-#   define isBLANK_L1(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(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) cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_CHARNAME_CONT))
-#   define isCNTRL_L1(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_CNTRL_L1))
-#   define isGRAPH_L1(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_GRAPH_L1))
-#   define isIDFIRST_L1(c) cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_IDFIRST_L1))
-#   define isLOWER_L1(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_LOWER_L1))
-#   define isPRINT_L1(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_PRINT_L1))
-#   define isPSXSPC_L1(c) cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_PSXSPC_L1))
-#   define isPUNCT_L1(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_PUNCT_L1))
-#   define isSPACE_L1(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_SPACE_L1))
-#   define isUPPER_L1(c)  cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_UPPER_L1))
-#   define isWORDCHAR_L1(c) cBOOL(FITS_IN_8_BITS(c) && (PL_charclass[(U8) NATIVE_TO_UNI(c)] & _CC_WORDCHAR_L1))
+#   define isCHARNAME_CONT(c) _generic_isCC(c, _CC_CHARNAME_CONT)
+
+#   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
@@ -765,7 +791,7 @@ EXTCONST U32 PL_charclass[];
 #   define toLOWER(c)  tolower(c)
 #   define toUPPER(c)  toupper(c)
 #else /* Not EBCDIC: ASCII-only matching */
-#   define isALNUMC(c)  isALNUMC_A(c)
+#   define isALNUMC(c)  isALNUMC_A(c)  /* Mnemonic: "C's alnum" = alpha + digit */
 #   define isALPHA(c)   isALPHA_A(c)
 #   define isBLANK(c)   isBLANK_A(c)
 #   define isCNTRL(c)   isCNTRL_A(c)
@@ -887,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 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 isBLANK_uni(c)         isBLANK(c) /* could be wrong */
-
 #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))
@@ -936,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
@@ -960,42 +996,38 @@ 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 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 isBLANK_utf8(c)                isBLANK(c) /* could be wrong */
+#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))
+#define isBLANK_LC_utf8(p)     isBLANK_LC_uvchr(valid_utf8_to_uvchr(p,  0))
 #define isSPACE_LC_utf8(p)     isSPACE_LC_uvchr(valid_utf8_to_uvchr(p,  0))
 #define isDIGIT_LC_utf8(p)     isDIGIT_LC_uvchr(valid_utf8_to_uvchr(p,  0))
 #define isUPPER_LC_utf8(p)     isUPPER_LC_uvchr(valid_utf8_to_uvchr(p,  0))
@@ -1007,15 +1039,16 @@ EXTCONST U32 PL_charclass[];
 #define isPUNCT_LC_utf8(p)     isPUNCT_LC_uvchr(valid_utf8_to_uvchr(p,  0))
 
 #define isPSXSPC_LC_utf8(c)    (isSPACE_LC_utf8(c) ||(c) == '\f')
-#define isBLANK_LC_utf8(c)     isBLANK(c) /* could be wrong */
 
 /* 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) \
@@ -1030,6 +1063,8 @@ typedef U32 line_t;
        } \
        return a;
 
+#define READ_XDIGIT(s) (isALPHA(*(s)) ? ((*(s)++ + 9) & 0xf) : (*(s)++ & 0xf))
+
 /*
 =head1 Memory Management
 
@@ -1089,7 +1124,7 @@ destination, C<nitems> is the number of items, and C<type> is the type.
 Like C<Zero> but returns dest. Useful for encouraging compilers to tail-call
 optimise.
 
-=for apidoc Am|void|StructCopy|type src|type dest|type
+=for apidoc Am|void|StructCopy|type *src|type *dest|type
 This is an architecture-independent macro to copy one structure to another.
 
 =for apidoc Am|void|PoisonWith|void* dest|int nitems|type|U8 byte
@@ -1122,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)
@@ -1303,8 +1338,8 @@ void Perl_mem_log_del_sv(const SV *sv, const char *filename, const int linenumbe
  * Local variables:
  * c-indentation-style: bsd
  * c-basic-offset: 4
- * indent-tabs-mode: t
+ * indent-tabs-mode: nil
  * End:
  *
- * ex: set ts=8 sts=4 sw=4 noet:
+ * ex: set ts=8 sts=4 sw=4 et:
  */