This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
malloc.c: Fix compiler warnings/error
[perl5.git] / handy.h
diff --git a/handy.h b/handy.h
index 0f1e940..e5062e6 100644 (file)
--- a/handy.h
+++ b/handy.h
@@ -478,6 +478,13 @@ Like L</memNE>, but the second string is a literal enclosed in double quotes,
 C<l1> gives the number of bytes in C<s1>.
 Returns zero if non-equal, or zero if non-equal.
 
+=for apidoc Am|bool|memCHRs|"list"|char c
+Returns the position of the first occurence of the byte C<c> in the literal
+string C<"list">, or NULL if C<c> doesn't appear in C<"list">.  All bytes are
+treated as unsigned char.  Thus this macro can be used to determine if C<c> is
+in a set of particular characters.  Unlike L<strchr(3)>, it works even if C<c>
+is C<NUL> (and the set doesn't include C<NUL>).
+
 =cut
 
 New macros should use the following conventions for their names (which are
@@ -569,6 +576,8 @@ based on the underlying C library functions):
 #define memGT(s1,s2,l) (memcmp(s1,s2,l) > 0)
 #define memGE(s1,s2,l) (memcmp(s1,s2,l) >= 0)
 
+#define memCHRs(s1,c) ((const char *) memchr("" s1 "" , c, sizeof(s1)-1))
+
 /*
  * Character classes.
  *
@@ -1356,7 +1365,9 @@ or casts
 #  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 */
@@ -1486,8 +1497,11 @@ END_EXTERN_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)
-#   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
@@ -1540,7 +1554,7 @@ END_EXTERN_C
                           ||  (c) == '\f' || (c) == '\n' || (c) == '\r'     \
                           ||  (c) == '\t' || (c) == '\v'                    \
                           || inRANGE((c), 1, 3)     /* SOH, STX, ETX */     \
-                          ||  (c) == 7    /* U+7F DEL */                    \
+                          ||  (c) == 7F   /* U+7F DEL */                    \
                           || inRANGE((c), 0x0E, 0x13) /* SO SI DLE          \
                                                          DC[1-3] */         \
                           ||  (c) == 0x18 /* U+18 CAN */                    \
@@ -2089,7 +2103,7 @@ END_EXTERN_C
 
 /* To prevent S_scan_word in toke.c from hanging, we have to make sure that
  * IDFIRST is an alnum.  See
- * https://rt.perl.org/rt3/Ticket/Display.html?id=74022 for more detail than you
+ * https://github.com/Perl/perl5/issues/10275 for more detail than you
  * ever wanted to know about.  (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 */
@@ -2281,17 +2295,22 @@ typedef U32 line_t;
        } \
        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