+/* Specify the widest unsigned type on the platform. Use U64TYPE because U64
+ * is known only in the perl core, and this macro can be called from outside
+ * that */
+#ifdef HAS_QUAD
+# define WIDEST_UTYPE U64TYPE
+#else
+# define WIDEST_UTYPE U32
+#endif
+
+/* FITS_IN_8_BITS(c) returns true if c doesn't have a bit set other than in
+ * the lower 8. It is designed to be hopefully bomb-proof, making sure that no
+ * bits of information are lost even on a 64-bit machine, but to get the
+ * compiler to optimize it out if possible. This is because Configure makes
+ * sure that the machine has an 8-bit byte, so if c is stored in a byte, the
+ * sizeof() guarantees that this evaluates to a constant true at compile time.
+ */
+#define FITS_IN_8_BITS(c) ((sizeof(c) == 1) || !(((WIDEST_UTYPE)(c)) & ~0xFF))
+
+#ifdef EBCDIC
+# define isASCII(c) (FITS_IN_8_BITS(c) && (NATIVE_TO_UNI((U8) (c)) < 128))
+#else
+# define isASCII(c) ((WIDEST_UTYPE)(c) < 128)
+#endif
+
+#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 */
+
+/* Character class numbers. 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 _HIGHEST_REGCOMP_DOT_H_SYNC _CC_BLANK
+
+# define _CC_IDFIRST 15
+# define _CC_CHARNAME_CONT 16
+# define _CC_NONLATIN1_FOLD 17
+# define _CC_QUOTEMETA 18
+# define _CC_NON_FINAL_FOLD 19
+/* Unused: 20-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. */
+
+# ifdef DOINIT
+EXTCONST U32 PL_charclass[] = {
+# include "l1_char_class_tab.h"
+};
+
+# else /* ! DOINIT */
+EXTCONST U32 PL_charclass[];
+# endif
+
+ /* 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_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)
+#else /* No perl.h. */
+# ifdef EBCDIC
+# define isALNUMC_A(c) (isASCII(c) && isALNUMC(c))
+# define isALPHA_A(c) (isASCII(c) && isALPHA(c))
+# define isBLANK_A(c) (isASCII(c) && isBLANK(c))
+# define isCNTRL_A(c) (isASCII(c) && isCNTRL(c))
+# define isDIGIT_A(c) (isASCII(c) && isDIGIT(c))
+# define isGRAPH_A(c) (isASCII(c) && isGRAPH(c))
+# define isIDFIRST_A(c) (isASCII(c) && isIDFIRST(c))
+# define isLOWER_A(c) (isASCII(c) && isLOWER(c))
+# define isPRINT_A(c) (isASCII(c) && isPRINT(c))
+# define isPSXSPC_A(c) (isASCII(c) && isPSXSPC(c))
+# define isPUNCT_A(c) (isASCII(c) && isPUNCT(c))
+# define isSPACE_A(c) (isASCII(c) && isSPACE(c))
+# define isUPPER_A(c) (isASCII(c) && isUPPER(c))
+# define isWORDCHAR_A(c) (isASCII(c) && isWORDCHAR(c))
+# define isXDIGIT_A(c) (isASCII(c) && isXDIGIT(c))
+# else /* ASCII platform, no perl.h */
+# define isALNUMC_A(c) (isALPHA_A(c) || isDIGIT_A(c))
+# define isALPHA_A(c) (isUPPER_A(c) || isLOWER_A(c))
+# define isBLANK_A(c) ((c) == ' ' || (c) == '\t')
+# define isCNTRL_A(c) (FITS_IN_8_BITS(c) && ((U8) (c) < ' ' || (c) == 127))
+# define isDIGIT_A(c) ((c) <= '9' && (c) >= '0')
+# define isGRAPH_A(c) (isWORDCHAR_A(c) || isPUNCT_A(c))
+# define isIDFIRST_A(c) (isALPHA_A(c) || (c) == '_')
+# define isLOWER_A(c) ((c) >= 'a' && (c) <= 'z')
+# define isPRINT_A(c) (((c) >= 32 && (c) < 127))
+# define isPSXSPC_A(c) (isSPACE_A(c) || (c) == '\v')
+# define isPUNCT_A(c) (((c) >= 33 && (c) <= 47) || ((c) >= 58 && (c) <= 64) || ((c) >= 91 && (c) <= 96) || ((c) >= 123 && (c) <= 126))
+# define isSPACE_A(c) ((c) == ' ' || (c) == '\t' || (c) == '\n' || (c) =='\r' || (c) == '\f')
+# define isUPPER_A(c) ((c) <= 'Z' && (c) >= 'A')
+# define isWORDCHAR_A(c) (isALPHA_A(c) || isDIGIT_A(c) || (c) == '_')
+# define isXDIGIT_A(c) (isDIGIT_A(c) || ((c) >= 'a' && (c) <= 'f') || ((c) <= 'F' && (c) >= 'A'))
+# endif
+#endif /* ASCII range definitions */
+
+/* Latin1 definitions */
+#ifdef H_PERL
+# 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)
+# 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
+ * >= AA test to speed up ASCII-only tests at the expense of the others */
+# define isALPHA_L1(c) (isALPHA(c) || (NATIVE_TO_UNI((U8) c) >= 0xAA \
+ && ((NATIVE_TO_UNI((U8) c) >= 0xC0 \
+ && NATIVE_TO_UNI((U8) c) != 0xD7 && NATIVE_TO_UNI((U8) c) != 0xF7) \
+ || NATIVE_TO_UNI((U8) c) == 0xAA \
+ || NATIVE_TO_UNI((U8) c) == 0xB5 \
+ || NATIVE_TO_UNI((U8) c) == 0xBA)))
+# define isCHARNAME_CONT(c) (isALNUM_L1(c) || (c) == ' ' || (c) == '-' || (c) == '(' || (c) == ')' || (c) == ':' || NATIVE_TO_UNI((U8) c) == 0xA0)
+#endif
+
+/* Macros for backwards compatibility and for completeness when the ASCII and
+ * Latin1 values are identical */
+#define isALNUM(c) isWORDCHAR(c)
+#define isALNUMU(c) isWORDCHAR_L1(c)
+#define isALPHAU(c) isALPHA_L1(c)
+#define isDIGIT_L1(c) isDIGIT_A(c)
+#define isOCTAL(c) isOCTAL_A(c)
+#define isOCTAL_L1(c) isOCTAL_A(c)
+#define isXDIGIT_L1(c) isXDIGIT_A(c)
+
+/* Macros that differ between EBCDIC and ASCII. Where C89 defines a function,
+ * that is used in the EBCDIC form, because in EBCDIC we do not do locales:
+ * therefore can use native functions. For those where C89 doesn't define a
+ * function, use our function, assuming that the EBCDIC code page is isomorphic
+ * with Latin1, which the three currently recognized by Perl are. Some libc's
+ * have an isblank(), but it's not guaranteed. */