inline, then delete, S_regrepeat_hard()
Dave Mitchell [Fri, 17 Mar 2006 15:58:45 +0000 (15:58 +0000)]
p4raw-id: //depot/perl@27534

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

index 719cf5c..7dbdd58 100644 (file)
--- a/embed.fnc
+++ b/embed.fnc
@@ -1303,7 +1303,6 @@ Es        |I32    |make_trie      |NN struct RExC_state_t* state|NN regnode *startbranch \
 #if defined(PERL_IN_REGEXEC_C) || defined(PERL_DECL_PROT)
 ERs    |I32    |regmatch       |NN regnode *prog
 ERs    |I32    |regrepeat      |NN const regnode *p|I32 max
-ERs    |I32    |regrepeat_hard |NN regnode *p|I32 max|NN I32 *lp
 ERs    |I32    |regtry         |NN regexp *prog|NN char *startpos
 ERs    |bool   |reginclass     |NN const regnode *n|NN const U8 *p|NULLOK STRLEN *lenp\
                                |bool do_utf8sv_is_utf8
diff --git a/embed.h b/embed.h
index 9b19829..eb21c52 100644 (file)
--- a/embed.h
+++ b/embed.h
 #if defined(PERL_CORE) || defined(PERL_EXT)
 #define regmatch               S_regmatch
 #define regrepeat              S_regrepeat
-#define regrepeat_hard         S_regrepeat_hard
 #define regtry                 S_regtry
 #define reginclass             S_reginclass
 #define regcppush              S_regcppush
 #if defined(PERL_CORE) || defined(PERL_EXT)
 #define regmatch(a)            S_regmatch(aTHX_ a)
 #define regrepeat(a,b)         S_regrepeat(aTHX_ a,b)
-#define regrepeat_hard(a,b,c)  S_regrepeat_hard(aTHX_ a,b,c)
 #define regtry(a,b)            S_regtry(aTHX_ a,b)
 #define reginclass(a,b,c,d)    S_reginclass(aTHX_ a,b,c,d)
 #define regcppush(a)           S_regcppush(aTHX_ a)
diff --git a/proto.h b/proto.h
index fd42b8c..1e42b7f 100644 (file)
--- a/proto.h
+++ b/proto.h
@@ -3597,11 +3597,6 @@ STATIC I32       S_regrepeat(pTHX_ const regnode *p, I32 max)
                        __attribute__warn_unused_result__
                        __attribute__nonnull__(pTHX_1);
 
-STATIC I32     S_regrepeat_hard(pTHX_ regnode *p, I32 max, I32 *lp)
-                       __attribute__warn_unused_result__
-                       __attribute__nonnull__(pTHX_1)
-                       __attribute__nonnull__(pTHX_3);
-
 STATIC I32     S_regtry(pTHX_ regexp *prog, char *startpos)
                        __attribute__warn_unused_result__
                        __attribute__nonnull__(pTHX_1)
index e802282..2b7fdfa 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -2130,12 +2130,9 @@ S_regtry(pTHX_ regexp *prog, char *startpos)
            if (!(SvTYPE(PL_reg_sv) >= SVt_PVMG && SvMAGIC(PL_reg_sv)
                  && (mg = mg_find(PL_reg_sv, PERL_MAGIC_regex_global)))) {
                /* prepare for quick setting of pos */
-#ifdef PERL_OLD_COPY_ON_WRITE
-               if (SvIsCOW(sv))
-                   sv_force_normal_flags(sv, 0);
-#endif
-               mg = sv_magicext(PL_reg_sv, (SV*)0, PERL_MAGIC_regex_global,
-                                &PL_vtbl_mglob, NULL, 0);
+               sv_magic(PL_reg_sv, (SV*)0,
+                       PERL_MAGIC_regex_global, NULL, 0);
+               mg = mg_find(PL_reg_sv, PERL_MAGIC_regex_global);
                mg->mg_len = -1;
            }
            PL_reg_magic    = mg;
@@ -3716,8 +3713,9 @@ S_regmatch(pTHX_ regnode *prog)
        case CURLYM:
        {
            I32 l = 0;
+           I32 matches = 0;
            CHECKPOINT lastcp;
-           I32 count;
+           I32 maxwanted;
        
            /* We suppose that the next guy does not need
               backtracking: in particular, it is of constant non-zero length,
@@ -3735,14 +3733,38 @@ S_regmatch(pTHX_ regnode *prog)
            if (paren)
                scan += NEXT_OFF(scan); /* Skip former OPEN. */
            PL_reginput = locinput;
-           count = minmod ? ln : n;
-           if (count)
-               count = regrepeat_hard(scan, count, &l);
+           maxwanted = minmod ? ln : n;
+           if (maxwanted) {
+               while (PL_reginput < PL_regeol && matches < maxwanted) {
+                   if (!regmatch(scan))
+                       break;
+                   /* on first match, determine length, l */
+                   if (!matches++) {
+                       if (PL_reg_match_utf8) {
+                           char *s = locinput;
+                           while (s < PL_reginput) {
+                               l++;
+                               s += UTF8SKIP(s);
+                           }
+                       }
+                       else {
+                           l = PL_reginput - locinput;
+                       }
+                       if (l == 0) {
+                           matches = maxwanted;
+                           break;
+                       }
+                   }
+                   locinput = PL_reginput;
+               }
+           }
+
+           PL_reginput = locinput;
+
            if (minmod) {
                minmod = 0;
-               if (ln && count < ln)
+               if (ln && matches < ln)
                    sayNO;
-               locinput = PL_reginput;
                if (HAS_TEXT(next) || JUMPABLE(next)) {
                    regnode *text_node = next;
 
@@ -3797,15 +3819,13 @@ S_regmatch(pTHX_ regnode *prog)
                }
            }
            else {
-               n = count;
-               locinput = PL_reginput;
                DEBUG_EXECUTE_r(
                    PerlIO_printf(Perl_debug_log,
                                  "%*s  matched %"IVdf" times, len=%"IVdf"...\n",
                                  (int)(REPORT_CODE_OFF+PL_regindent*2), "",
-                                 (IV) n, (IV)l)
+                                 (IV) matches, (IV)l)
                    );
-               if (n >= ln) {
+               if (matches >= ln) {
                    if (HAS_TEXT(next) || JUMPABLE(next)) {
                        regnode *text_node = next;
 
@@ -3832,19 +3852,20 @@ S_regmatch(pTHX_ regnode *prog)
                }
            assume_ok_REG:
                REGCP_SET(lastcp);
-               while (n >= ln) {
+               while (matches >= ln) {
                    /* If it could work, try it. */
                    if (c1 == -1000 ||
                        UCHARAT(PL_reginput) == c1 ||
                        UCHARAT(PL_reginput) == c2)
                    {
                        DEBUG_EXECUTE_r(
-                               PerlIO_printf(Perl_debug_log,
-                                             "%*s  trying tail with n=%"IVdf"...\n",
-                                             (int)(REPORT_CODE_OFF+PL_regindent*2), "", (IV)n)
+                           PerlIO_printf(Perl_debug_log,
+                               "%*s  trying tail with matches=%"IVdf"...\n",
+                               (int)(REPORT_CODE_OFF+PL_regindent*2),
+                               "", (IV)matches)
                            );
                        if (paren) {
-                           if (n) {
+                           if (matches) {
                                PL_regstartp[paren] = HOPc(PL_reginput, -l) - PL_bostr;
                                PL_regendp[paren] = PL_reginput - PL_bostr;
                            }
@@ -3856,7 +3877,7 @@ S_regmatch(pTHX_ regnode *prog)
                        REGCP_UNWIND(lastcp);
                    }
                    /* Couldn't or didn't -- back up. */
-                   n--;
+                   matches--;
                    locinput = HOPc(locinput, -l);
                    PL_reginput = locinput;
                }
@@ -4598,58 +4619,6 @@ S_regrepeat(pTHX_ const regnode *p, I32 max)
     return(c);
 }
 
-/*
- - regrepeat_hard - repeatedly match something, report total lenth and length
- *
- * The repeater is supposed to have constant non-zero length.
- */
-
-STATIC I32
-S_regrepeat_hard(pTHX_ regnode *p, I32 max, I32 *lp)
-{
-    dVAR;
-    register char *scan = NULL;
-    register char *start;
-    register char *loceol = PL_regeol;
-    I32 l = 0;
-    I32 count = 0, res = 1;
-
-    if (!max)
-       return 0;
-
-    start = PL_reginput;
-    if (PL_reg_match_utf8) {
-       while (PL_reginput < loceol && (scan = PL_reginput, res = regmatch(p))) {
-           if (!count++) {
-               l = 0;
-               while (start < PL_reginput) {
-                   l++;
-                   start += UTF8SKIP(start);
-               }
-               *lp = l;
-               if (l == 0)
-                   return max;
-           }
-           if (count == max)
-               return count;
-       }
-    }
-    else {
-       while (PL_reginput < loceol && (scan = PL_reginput, res = regmatch(p))) {
-           if (!count++) {
-               *lp = l = PL_reginput - start;
-               if (max != REG_INFTY && l*max < loceol - scan)
-                   loceol = scan + l*max;
-               if (l == 0)
-                   return max;
-           }
-       }
-    }
-    if (!res)
-       PL_reginput = scan;
-
-    return count;
-}
 
 /*
 - regclass_swash - prepare the utf8 swash