This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
regex: Use #define for number of bits in ANYOF
authorKarl Williamson <khw@cpan.org>
Mon, 30 Jun 2014 21:03:14 +0000 (15:03 -0600)
committerKarl Williamson <khw@cpan.org>
Thu, 21 Aug 2014 20:49:46 +0000 (14:49 -0600)
ANYOF nodes (for bracketed character classes) currently are for code
points 0-255.  This is the first step in the eventual making that size
configurable.  This also renames a static function, as the domain may
not necessarily be 'latin1'

embed.fnc
embed.h
proto.h
regcomp.c
regcomp.h
regexec.c

index 97d0d99..f77140e 100644 (file)
--- a/embed.fnc
+++ b/embed.fnc
@@ -2189,7 +2189,7 @@ Es        |const regnode*|dumpuntil|NN const regexp *r|NN const regnode *start \
                                |NULLOK const regnode *plast \
                                |NN SV* sv|I32 indent|U32 depth
 Es     |void   |put_byte       |NN SV* sv|int c
-Es     |bool   |put_latin1_charclass_innards|NN SV* sv|NN char* bitmap
+Es     |bool   |put_charclass_bitmap_innards|NN SV* sv|NN char* bitmap
 Es     |void   |put_range      |NN SV* sv|UV start|UV end
 Es     |void   |dump_trie      |NN const struct _reg_trie_data *trie\
                                |NULLOK HV* widecharmap|NN AV *revcharmap\
diff --git a/embed.h b/embed.h
index be519f2..4b94b89 100644 (file)
--- a/embed.h
+++ b/embed.h
 #define dump_trie_interim_table(a,b,c,d,e)     S_dump_trie_interim_table(aTHX_ a,b,c,d,e)
 #define dumpuntil(a,b,c,d,e,f,g,h)     S_dumpuntil(aTHX_ a,b,c,d,e,f,g,h)
 #define put_byte(a,b)          S_put_byte(aTHX_ a,b)
-#define put_latin1_charclass_innards(a,b)      S_put_latin1_charclass_innards(aTHX_ a,b)
+#define put_charclass_bitmap_innards(a,b)      S_put_charclass_bitmap_innards(aTHX_ a,b)
 #define put_range(a,b,c)       S_put_range(aTHX_ a,b,c)
 #define regdump_extflags(a,b)  S_regdump_extflags(aTHX_ a,b)
 #define regdump_intflags(a,b)  S_regdump_intflags(aTHX_ a,b)
diff --git a/proto.h b/proto.h
index df4b9e2..2f7ba5f 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -5386,10 +5386,10 @@ STATIC void     S_put_byte(pTHX_ SV* sv, int c)
 #define PERL_ARGS_ASSERT_PUT_BYTE      \
        assert(sv)
 
-STATIC bool    S_put_latin1_charclass_innards(pTHX_ SV* sv, char* bitmap)
+STATIC bool    S_put_charclass_bitmap_innards(pTHX_ SV* sv, char* bitmap)
                        __attribute__nonnull__(pTHX_1)
                        __attribute__nonnull__(pTHX_2);
-#define PERL_ARGS_ASSERT_PUT_LATIN1_CHARCLASS_INNARDS  \
+#define PERL_ARGS_ASSERT_PUT_CHARCLASS_BITMAP_INNARDS  \
        assert(sv); assert(bitmap)
 
 STATIC void    S_put_range(pTHX_ SV* sv, UV start, UV end)
index 96fa3aa..98f012b 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -1048,15 +1048,16 @@ S_get_ANYOF_cp_list_for_ssc(pTHX_ const RExC_state_t *pRExC_state,
         }
     }
 
-    /* An ANYOF node contains a bitmap for the first 256 code points, and an
-     * inversion list for the others, but if there are code points that should
-     * match only conditionally on the target string being UTF-8, those are
-     * placed in the inversion list, and not the bitmap.  Since there are
-     * circumstances under which they could match, they are included in the
-     * SSC.  But if the ANYOF node is to be inverted, we have to exclude them
-     * here, so that when we invert below, the end result actually does include
-     * them.  (Think about "\xe0" =~ /[^\xc0]/di;).  We have to do this here
-     * before we add the unconditionally matched code points */
+    /* An ANYOF node contains a bitmap for the first NUM_ANYOF_CODE_POINTS
+     * code points, and an inversion list for the others, but if there are code
+     * points that should match only conditionally on the target string being
+     * UTF-8, those are placed in the inversion list, and not the bitmap.
+     * Since there are circumstances under which they could match, they are
+     * included in the SSC.  But if the ANYOF node is to be inverted, we have
+     * to exclude them here, so that when we invert below, the end result
+     * actually does include them.  (Think about "\xe0" =~ /[^\xc0]/di;).  We
+     * have to do this here before we add the unconditionally matched code
+     * points */
     if (ANYOF_FLAGS(node) & ANYOF_INVERT) {
         _invlist_intersection_complement_2nd(invlist,
                                              PL_UpperLatin1,
@@ -1064,7 +1065,7 @@ S_get_ANYOF_cp_list_for_ssc(pTHX_ const RExC_state_t *pRExC_state,
     }
 
     /* Add in the points from the bit map */
-    for (i = 0; i < 256; i++) {
+    for (i = 0; i < NUM_ANYOF_CODE_POINTS; i++) {
         if (ANYOF_BITMAP_TEST(node, i)) {
             invlist = add_cp_to_invlist(invlist, i);
             new_node_has_latin1 = TRUE;
@@ -1428,7 +1429,8 @@ S_ssc_finalize(pTHX_ RExC_state_t *pRExC_state, regnode_ssc *ssc)
 {
     /* The inversion list in the SSC is marked mortal; now we need a more
      * permanent copy, which is stored the same way that is done in a regular
-     * ANYOF node, with the first 256 code points in a bit map */
+     * ANYOF node, with the first NUM_ANYOF_CODE_POINTS code points in a bit
+     * map */
 
     SV* invlist = invlist_clone(ssc->invlist);
 
@@ -12470,14 +12472,16 @@ S_populate_ANYOF_from_invlist(pTHX_ regnode *node, SV** invlist_ptr)
             }
 
            /* Quit if are above what we should change */
-           if (start > 255) {
+           if (start >= NUM_ANYOF_CODE_POINTS) {
                break;
            }
 
            change_invlist = TRUE;
 
            /* Set all the bits in the range, up to the max that we are doing */
-           high = (end < 255) ? end : 255;
+           high = (end < NUM_ANYOF_CODE_POINTS - 1)
+                   ? end
+                   : NUM_ANYOF_CODE_POINTS - 1;
            for (i = start; i <= (int) high; i++) {
                if (! ANYOF_BITMAP_TEST(node, i)) {
                    ANYOF_BITMAP_SET(node, i);
@@ -13289,11 +13293,11 @@ S_regclass(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth,
      * ignored in the recursion by means of a flag:
      * <RExC_in_multi_char_class>.)
      *
-     * ANYOF nodes contain a bit map for the first 256 characters, with the
-     * corresponding bit set if that character is in the list.  For characters
-     * above 255, a range list or swash is used.  There are extra bits for \w,
-     * etc. in locale ANYOFs, as what these match is not determinable at
-     * compile time
+     * ANYOF nodes contain a bit map for the first NUM_ANYOF_CODE_POINTS
+     * characters, with the corresponding bit set if that character is in the
+     * list.  For characters above this, a range list or swash is used.  There
+     * are extra bits for \w, etc. in locale ANYOFs, as what these match is not
+     * determinable at compile time
      *
      * Returns NULL, setting *flagp to RESTART_UTF8 if the sizing scan needs
      * to be restarted.  This can only happen if ret_invlist is non-NULL.
@@ -15723,7 +15727,7 @@ Perl_regprop(pTHX_ const regexp *prog, SV *sv, const regnode *o, const regmatch_
         );
         if ( IS_ANYOF_TRIE(op) || trie->bitmap ) {
             sv_catpvs(sv, "[");
-            (void) put_latin1_charclass_innards(sv, IS_ANYOF_TRIE(op)
+            (void) put_charclass_bitmap_innards(sv, IS_ANYOF_TRIE(op)
                                                    ? ANYOF_BITMAP(o)
                                                    : TRIE_BITMAP(trie));
             sv_catpvs(sv, "]");
@@ -15799,8 +15803,9 @@ Perl_regprop(pTHX_ const regexp *prog, SV *sv, const regnode *o, const regmatch_
        if (flags & ANYOF_INVERT)
            sv_catpvs(sv, "^");
 
-       /* output what the standard cp 0-255 bitmap matches */
-        do_sep = put_latin1_charclass_innards(sv, ANYOF_BITMAP(o));
+        /* output what the standard cp 0-NUM_ANYOF_CODE_POINTS-1 bitmap matches
+         * */
+        do_sep = put_charclass_bitmap_innards(sv, ANYOF_BITMAP(o));
 
         /* output any special charclass tests (used entirely under use
          * locale) * */
@@ -16570,8 +16575,7 @@ S_put_range(pTHX_ SV *sv, UV start, UV end)
 
     /* Appends to 'sv' a displayable version of the range of code points from
      * 'start' to 'end'.  It assumes that only ASCII printables are displayable
-     * as-is (though some of these will be escaped by put_byte()).  For the
-     * time being, this subroutine only works for latin1 (< 256) code points */
+     * as-is (though some of these will be escaped by put_byte()). */
 
     assert(start <= end);
 
@@ -16665,13 +16669,15 @@ S_put_range(pTHX_ SV *sv, UV start, UV end)
          * hex. */
         Perl_sv_catpvf(aTHX_ sv, "\\x{%02" UVXf "}-\\x{%02" UVXf "}",
                        start,
-                       (end < 256) ? end : 255);
+                       (end < NUM_ANYOF_CODE_POINTS)
+                       ? end
+                       : NUM_ANYOF_CODE_POINTS - 1);
         break;
     }
 }
 
 STATIC bool
-S_put_latin1_charclass_innards(pTHX_ SV *sv, char *bitmap)
+S_put_charclass_bitmap_innards(pTHX_ SV *sv, char *bitmap)
 {
     /* Appends to 'sv' a displayable version of the innards of the bracketed
      * character class whose bitmap is 'bitmap';  Returns 'TRUE' if it actually
@@ -16680,15 +16686,15 @@ S_put_latin1_charclass_innards(pTHX_ SV *sv, char *bitmap)
     int i;
     bool has_output_anything = FALSE;
 
-    PERL_ARGS_ASSERT_PUT_LATIN1_CHARCLASS_INNARDS;
+    PERL_ARGS_ASSERT_PUT_CHARCLASS_BITMAP_INNARDS;
 
-    for (i = 0; i < 256; i++) {
+    for (i = 0; i < NUM_ANYOF_CODE_POINTS; i++) {
         if (BITMAP_TEST((U8 *) bitmap,i)) {
 
             /* The character at index i should be output.  Find the next
              * character that should NOT be output */
             int j;
-            for (j = i + 1; j < 256; j++) {
+            for (j = i + 1; j < NUM_ANYOF_CODE_POINTS; j++) {
                 if (! BITMAP_TEST((U8 *) bitmap, j)) {
                     break;
                 }
index 3bb1a53..68646f1 100644 (file)
--- a/regcomp.h
+++ b/regcomp.h
@@ -184,8 +184,9 @@ struct regnode_2 {
     U16 arg2;
 };
 
+#define NUM_ANYOF_CODE_POINTS   256
 
-#define ANYOF_BITMAP_SIZE      (256 / 8)   /* 8 bits/Byte */
+#define ANYOF_BITMAP_SIZE      (NUM_ANYOF_CODE_POINTS / 8)   /* 8 bits/Byte */
 
 /* Note that these form structs which are supersets of the next smaller one, by
  * appending fields.  Alignment problems can occur if one of those optional
@@ -551,9 +552,13 @@ struct regnode_ssc {
        memset (ANYOF_BITMAP(p), 255, ANYOF_BITMAP_SIZE)
 #define ANYOF_BITMAP_CLEARALL(p)       \
        Zero (ANYOF_BITMAP(p), ANYOF_BITMAP_SIZE)
-/* Check that all 256 bits are all set.  Used in S_cl_is_anything()  */
-#define ANYOF_BITMAP_TESTALLSET(p)     /* Assumes sizeof(p) == 32 */     \
+#if ANYOF_BITMAP_SIZE == 32
+/* Check that all 256 bits are all set. */
+#   define ANYOF_BITMAP_TESTALLSET(p)  /* Assumes sizeof(p) == 32 */     \
        memEQ (ANYOF_BITMAP(p), "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377", ANYOF_BITMAP_SIZE)
+#else
+#   error Need to fix this if raise bitmap size.  (As of this writing this macro is unused in the core)
+#endif
 
 #define ANYOF_SKIP             ((ANYOF_SIZE - 1)/sizeof(regnode))
 #define ANYOF_POSIXL_SKIP      ((ANYOF_POSIXL_SIZE - 1)/sizeof(regnode))
index 33fb5da..b2cdda2 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -7787,7 +7787,7 @@ S_reginclass(pTHX_ regexp * const prog, const regnode * const n, const U8* const
     }
 
     /* If this character is potentially in the bitmap, check it */
-    if (c < 256) {
+    if (c < NUM_ANYOF_CODE_POINTS) {
        if (ANYOF_BITMAP_TEST(n, c))
            match = TRUE;
        else if (flags & ANYOF_NON_UTF8_NON_ASCII_ALL