regcomp.c: Extract code into separate function
authorKarl Williamson <public@khwilliamson.com>
Mon, 22 Jul 2013 03:13:38 +0000 (21:13 -0600)
committerKarl Williamson <public@khwilliamson.com>
Tue, 24 Sep 2013 17:36:11 +0000 (11:36 -0600)
This is in preparation for it to be called from more than one place, in
a future commit.

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

index 3f7040b..87f1994 100644 (file)
--- a/embed.fnc
+++ b/embed.fnc
@@ -2046,6 +2046,7 @@ Es        |bool   |reg_skipcomment|NN struct RExC_state_t *pRExC_state
 Es     |void   |scan_commit    |NN const struct RExC_state_t *pRExC_state \
                                |NN struct scan_data_t *data \
                                |NN SSize_t *minlenp|int is_inf
+Es     |void   |populate_ANYOF_from_invlist|NN regnode *node|NN SV** invlist_ptr
 Esn    |void   |cl_anything    |NN const struct RExC_state_t *pRExC_state \
                                |NN struct regnode_charclass_class *cl
 EsRn   |int    |cl_is_anything |NN const struct regnode_charclass_class *cl
diff --git a/embed.h b/embed.h
index eade4a4..d3e014a 100644 (file)
--- a/embed.h
+++ b/embed.h
 #define make_trie_failtable(a,b,c,d)   S_make_trie_failtable(aTHX_ a,b,c,d)
 #define nextchar(a)            S_nextchar(aTHX_ a)
 #define parse_lparen_question_flags(a) S_parse_lparen_question_flags(aTHX_ a)
+#define populate_ANYOF_from_invlist(a,b)       S_populate_ANYOF_from_invlist(aTHX_ a,b)
 #define reg(a,b,c,d)           S_reg(aTHX_ a,b,c,d)
 #define reg_node(a,b)          S_reg_node(aTHX_ a,b)
 #define reg_recode(a,b)                S_reg_recode(aTHX_ a,b)
diff --git a/proto.h b/proto.h
index 3a2d46a..93b1601 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -6721,6 +6721,12 @@ STATIC void      S_parse_lparen_question_flags(pTHX_ struct RExC_state_t *pRExC_state
 #define PERL_ARGS_ASSERT_PARSE_LPAREN_QUESTION_FLAGS   \
        assert(pRExC_state)
 
+STATIC void    S_populate_ANYOF_from_invlist(pTHX_ regnode *node, SV** invlist_ptr)
+                       __attribute__nonnull__(pTHX_1)
+                       __attribute__nonnull__(pTHX_2);
+#define PERL_ARGS_ASSERT_POPULATE_ANYOF_FROM_INVLIST   \
+       assert(node); assert(invlist_ptr)
+
 PERL_STATIC_NO_RET void        S_re_croak2(pTHX_ bool utf8, const char* pat1, const char* pat2, ...)
                        __attribute__noreturn__
                        __attribute__nonnull__(pTHX_2)
index f5064a9..2441a69 100644 (file)
--- a/regcomp.c
+++ b/regcomp.c
@@ -11476,6 +11476,69 @@ S_regpatws( RExC_state_t *pRExC_state, char *p , const bool recognize_comment )
     return p;
 }
 
+STATIC void
+S_populate_ANYOF_from_invlist(pTHX_ regnode *node, SV** invlist_ptr)
+{
+    /* Uses the inversion list '*invlist_ptr' to populate the ANYOF 'node'.  It
+     * sets up the bitmap and any flags, removing those code points from the
+     * inversion list, setting it to NULL should it become completely empty */
+
+    PERL_ARGS_ASSERT_POPULATE_ANYOF_FROM_INVLIST;
+    assert(PL_regkind[OP(node)] == ANYOF);
+
+    ANYOF_BITMAP_ZERO(node);
+    if (*invlist_ptr) {
+
+       /* This gets set if we actually need to modify things */
+       bool change_invlist = FALSE;
+
+       UV start, end;
+
+       /* Start looking through *invlist_ptr */
+       invlist_iterinit(*invlist_ptr);
+       while (invlist_iternext(*invlist_ptr, &start, &end)) {
+           UV high;
+           int i;
+
+            if (end == UV_MAX && start <= 256) {
+                ANYOF_FLAGS(node) |= ANYOF_UNICODE_ALL;
+            }
+
+           /* Quit if are above what we should change */
+           if (start > 255) {
+               break;
+           }
+
+           change_invlist = TRUE;
+
+           /* Set all the bits in the range, up to the max that we are doing */
+           high = (end < 255) ? end : 255;
+           for (i = start; i <= (int) high; i++) {
+               if (! ANYOF_BITMAP_TEST(node, i)) {
+                   ANYOF_BITMAP_SET(node, i);
+               }
+           }
+       }
+       invlist_iterfinish(*invlist_ptr);
+
+        /* Done with loop; remove any code points that are in the bitmap from
+         * *invlist_ptr; similarly for code points above latin1 if we have a flag
+         * to match all of them anyways */
+       if (change_invlist) {
+           _invlist_subtract(*invlist_ptr, PL_Latin1, invlist_ptr);
+       }
+        if (ANYOF_FLAGS(node) & ANYOF_UNICODE_ALL) {
+           _invlist_intersection(*invlist_ptr, PL_Latin1, invlist_ptr);
+       }
+
+       /* If have completely emptied it, remove it completely */
+       if (_invlist_len(*invlist_ptr) == 0) {
+           SvREFCNT_dec_NN(*invlist_ptr);
+           *invlist_ptr = NULL;
+       }
+    }
+}
+
 /* Parse POSIX character classes: [[:foo:]], [[=foo=]], [[.foo.]].
    Character classes ([:foo:]) can also be negated ([:^foo:]).
    Returns a named class id (ANYOF_XXX) if successful, -1 otherwise.
@@ -13946,57 +14009,8 @@ parseit:
      * for things that belong in the bitmap, put them there, and delete from
      * <cp_list>.  While we are at it, see if everything above 255 is in the
      * list, and if so, set a flag to speed up execution */
-    ANYOF_BITMAP_ZERO(ret);
-    if (cp_list) {
-
-       /* This gets set if we actually need to modify things */
-       bool change_invlist = FALSE;
-
-       UV start, end;
-
-       /* Start looking through <cp_list> */
-       invlist_iterinit(cp_list);
-       while (invlist_iternext(cp_list, &start, &end)) {
-           UV high;
-           int i;
-
-            if (end == UV_MAX && start <= 256) {
-                ANYOF_FLAGS(ret) |= ANYOF_UNICODE_ALL;
-            }
-
-           /* Quit if are above what we should change */
-           if (start > 255) {
-               break;
-           }
 
-           change_invlist = TRUE;
-
-           /* Set all the bits in the range, up to the max that we are doing */
-           high = (end < 255) ? end : 255;
-           for (i = start; i <= (int) high; i++) {
-               if (! ANYOF_BITMAP_TEST(ret, i)) {
-                   ANYOF_BITMAP_SET(ret, i);
-               }
-           }
-       }
-       invlist_iterfinish(cp_list);
-
-        /* Done with loop; remove any code points that are in the bitmap from
-         * <cp_list>; similarly for code points above latin1 if we have a flag
-         * to match all of them anyways */
-       if (change_invlist) {
-           _invlist_subtract(cp_list, PL_Latin1, &cp_list);
-       }
-        if (ANYOF_FLAGS(ret) & ANYOF_UNICODE_ALL) {
-           _invlist_intersection(cp_list, PL_Latin1, &cp_list);
-       }
-
-       /* If have completely emptied it, remove it completely */
-       if (_invlist_len(cp_list) == 0) {
-           SvREFCNT_dec_NN(cp_list);
-           cp_list = NULL;
-       }
-    }
+    populate_ANYOF_from_invlist(ret, &cp_list);
 
     if (invert) {
         ANYOF_FLAGS(ret) |= ANYOF_INVERT;