strict-w-proof the ?DBM_File, from Paul Marquess.
[p5sagit/p5-mst-13.2.git] / regexec.c
index 0c29b78..5d9e8ac 100644 (file)
--- a/regexec.c
+++ b/regexec.c
@@ -130,21 +130,29 @@ STATIC CHECKPOINT
 S_regcppush(pTHX_ I32 parenfloor)
 {
     int retval = PL_savestack_ix;
-    int i = (PL_regsize - parenfloor) * 4;
+#define REGCP_PAREN_ELEMS 4
+    int paren_elems_to_push = (PL_regsize - parenfloor) * REGCP_PAREN_ELEMS;
     int p;
 
-    SSCHECK(i + 5);
+#define REGCP_OTHER_ELEMS 5
+    SSCHECK(paren_elems_to_push + REGCP_OTHER_ELEMS);
     for (p = PL_regsize; p > parenfloor; p--) {
+/* REGCP_PARENS_ELEMS are pushed per pairs of parentheses. */
        SSPUSHINT(PL_regendp[p]);
        SSPUSHINT(PL_regstartp[p]);
        SSPUSHPTR(PL_reg_start_tmp[p]);
        SSPUSHINT(p);
     }
+/* REGCP_OTHER_ELEMS are pushed in any case, parentheses or no. */
     SSPUSHINT(PL_regsize);
     SSPUSHINT(*PL_reglastparen);
     SSPUSHPTR(PL_reginput);
-    SSPUSHINT(i + 3);
-    SSPUSHINT(SAVEt_REGCONTEXT);
+#define REGCP_FRAME_ELEMS 2
+/* REGCP_FRAME_ELEMS are part of the REGCP_OTHER_ELEMS and
+ * are needed for the regexp context stack bookkeeping. */
+    SSPUSHINT(paren_elems_to_push + REGCP_OTHER_ELEMS - REGCP_FRAME_ELEMS);
+    SSPUSHINT(SAVEt_REGCONTEXT); /* Magic cookie. */
+
     return retval;
 }
 
@@ -161,16 +169,22 @@ S_regcppush(pTHX_ I32 parenfloor)
 STATIC char *
 S_regcppop(pTHX)
 {
-    I32 i = SSPOPINT;
+    I32 i;
     U32 paren = 0;
     char *input;
     I32 tmps;
-    assert(i == SAVEt_REGCONTEXT);
+
+    /* Pop REGCP_OTHER_ELEMS before the parentheses loop starts. */
     i = SSPOPINT;
+    assert(i == SAVEt_REGCONTEXT); /* Check that the magic cookie is there. */
+    i = SSPOPINT; /* Parentheses elements to pop. */
     input = (char *) SSPOPPTR;
     *PL_reglastparen = SSPOPINT;
     PL_regsize = SSPOPINT;
-    for (i -= 3; i > 0; i -= 4) {
+
+    /* Now restore the parentheses context. */
+    for (i -= (REGCP_OTHER_ELEMS - REGCP_FRAME_ELEMS);
+        i > 0; i -= REGCP_PAREN_ELEMS) {
        paren = (U32)SSPOPINT;
        PL_reg_start_tmp[paren] = (char *) SSPOPPTR;
        PL_regstartp[paren] = SSPOPINT;
@@ -384,7 +398,8 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos,
              DEBUG_r(PerlIO_printf(Perl_debug_log, "Not at start...\n"));
              goto fail;
          }
-         if (prog->check_offset_min == prog->check_offset_max) {
+         if (prog->check_offset_min == prog->check_offset_max &&
+             !(prog->reganch & ROPT_SANY_SEEN)) {
            /* Substring at constant offset from beg-of-str... */
            I32 slen;
 
@@ -460,6 +475,10 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos,
        if (data)
            *data->scream_olds = s;
     }
+    else if (prog->reganch & ROPT_SANY_SEEN)
+       s = fbm_instr((U8*)(s + start_shift),
+                     (U8*)(strend - end_shift),
+                     check, PL_multiline ? FBMrf_MULTILINE : 0);
     else
        s = fbm_instr(HOP3(s, start_shift, strend),
                      HOP3(strend, -end_shift, strbeg),
@@ -595,14 +614,14 @@ Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos,
                    DEBUG_r(PerlIO_printf(Perl_debug_log,
                        ", trying anchored starting at offset %ld...\n",
                        (long)(s1 + 1 - i_strpos)));
-                   other_last = last + 1;
+                   other_last = last;
                    s = HOP3c(t, 1, strend);
                    goto restart;
                }
                else {
                    DEBUG_r(PerlIO_printf(Perl_debug_log, " at offset %ld...\n",
                          (long)(s - i_strpos)));
-                   other_last = s + 1;
+                   other_last = s; /* Fix this later. --Hugo */
                    s = s1;
                    if (t == strpos)
                        goto try_at_start;
@@ -1393,7 +1412,8 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char *
 
     minlen = prog->minlen;
     if (do_utf8) {
-      if (utf8_distance((U8*)strend, (U8*)startpos) < minlen) goto phooey;
+      if (!(prog->reganch & ROPT_SANY_SEEN))
+        if (utf8_distance((U8*)strend, (U8*)startpos) < minlen) goto phooey;
     }
     else {
       if (strend - startpos < minlen) goto phooey;
@@ -1460,7 +1480,8 @@ Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char *
            PL_reg_ganch = strbeg;
     }
 
-    if (!(flags & REXEC_CHECKED) && prog->check_substr != Nullsv) {
+    if (do_utf8 == (UTF!=0) &&
+       !(flags & REXEC_CHECKED) && prog->check_substr != Nullsv) {
        re_scream_pos_data d;
 
        d.scream_olds = &scream_olds;
@@ -2060,13 +2081,6 @@ S_regmatch(pTHX_ regnode *prog)
                sayNO;
            break;
        case SANY:
-           if (do_utf8) {
-               locinput += PL_utf8skip[nextchr];
-               if (locinput > PL_regeol)
-                   sayNO;
-               nextchr = UCHARAT(locinput);
-               break;
-           }
            if (!nextchr && locinput >= PL_regeol)
                sayNO;
            nextchr = UCHARAT(++locinput);
@@ -2273,7 +2287,7 @@ S_regmatch(pTHX_ regnode *prog)
            if (!nextchr)
                sayNO;
            if (do_utf8) {
-               if (nextchr & 0x80) {
+               if (UTF8_IS_CONTINUED(nextchr)) {
                    if (!(OP(scan) == SPACE
                          ? swash_fetch(PL_utf8_space, (U8*)locinput)
                          : isSPACE_LC_utf8((U8*)locinput)))
@@ -3548,15 +3562,7 @@ S_regrepeat(pTHX_ regnode *p, I32 max)
        }
        break;
     case SANY:
-       if (do_utf8) {
-           loceol = PL_regeol;
-           while (hardcount < max && scan < loceol) {
-               scan += UTF8SKIP(scan);
-               hardcount++;
-           }
-       } else {
-           scan = loceol;
-       }
+       scan = loceol;
        break;
     case EXACT:                /* length of string is 1 */
        c = (U8)*STRING(p);