# define _CC_QUOTEMETA 20
# define _CC_NON_FINAL_FOLD 21
# define _CC_IS_IN_SOME_FOLD 22
-# define _CC_MNEMONIC_CNTRL 23
+# define _CC_BINDIGIT 23
+# define _CC_OCTDIGIT 24
+# define _CC_MNEMONIC_CNTRL 25
/* This next group is only used on EBCDIC platforms, so theoretically could be
* shared with something entirely different that's only on ASCII platforms */
_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)
-# define _IS_MNEMONIC_CNTRL_ONLY_FOR_USE_BY_REGCOMP_DOT_C(c) \
- _generic_isCC(c, _CC_MNEMONIC_CNTRL)
+
+/* is c a control character for which we have a mnemonic? */
+# if defined(PERL_CORE) || defined(PERL_EXT)
+# define isMNEMONIC_CNTRL(c) _generic_isCC(c, _CC_MNEMONIC_CNTRL)
+# endif
#else /* else we don't have perl.h H_PERL */
/* If we don't have perl.h, we are compiling a utility program. Below we
} \
return a;
-/* Converts a character known to represent a hexadecimal digit (0-9, A-F, or
- * a-f) to its numeric value. READ_XDIGIT's argument is a string pointer,
- * which is advanced. The input is validated only by an assert() in DEBUGGING
- * builds. In both ASCII and EBCDIC the last 4 bits of the digits are 0-9; and
- * the last 4 bits of A-F and a-f are 1-6, so adding 9 yields 10-15 */
-#define XDIGIT_VALUE(c) (__ASSERT_(isXDIGIT(c)) (0xf & (isDIGIT(c) \
- ? (c) \
- : ((c) + 9))))
-#define READ_XDIGIT(s) (__ASSERT_(isXDIGIT(*s)) (0xf & (isDIGIT(*(s)) \
- ? (*(s)++) \
- : (*(s)++ + 9))))
+/* Converts a character KNOWN to represent a hexadecimal digit (0-9, A-F, or
+ * a-f) to its numeric value without using any branches. The input is
+ * validated only by an assert() in DEBUGGING builds.
+ *
+ * It works by right shifting and isolating the bit that is 0 for the digits,
+ * and 1 for at least the alphas A-F, a-f. The bit is shifted to the ones
+ * position, and then to the eights position. Both are added together to form
+ * 0 if the input is '0'-'9' and to form 9 if alpha. This is added to the
+ * final four bits of the input to form the correct value. */
+#define XDIGIT_VALUE(c) (__ASSERT_(isXDIGIT(c)) \
+ ((NATIVE_TO_LATIN1(c) >> 6) & 1) /* 1 if alpha; 0 if not */ \
+ + ((NATIVE_TO_LATIN1(c) >> 3) & 8) /* 8 if alpha; 0 if not */ \
+ + ((c) & 0xF)) /* 0-9 if input valid hex digit */
+
+/* The argument is a string pointer, which is advanced. */
+#define READ_XDIGIT(s) ((s)++, XDIGIT_VALUE(*((s) - 1)))
/* Converts a character known to represent an octal digit (0-7) to its numeric
* value. The input is validated only by an assert() in DEBUGGING builds. In