Re: [PATCH for _66] Makefile.SH problem on dos/djgpp
[p5sagit/p5-mst-13.2.git] / regexec.c
index 32c9c75..dd51bc1 100644 (file)
--- a/regexec.c
+++ b/regexec.c
 #include "perl.h"
 #include "regcomp.h"
 
-static char *  reginput;       /* String-input pointer. */
-static char *  regbol;         /* Beginning of input, for ^ check. */
-static char *  regeol;         /* End of input, for $ check. */
-static char ** regstartp;      /* Pointer to startp array. */
-static char ** regendp;        /* Ditto for endp. */
-static U32 *   reglastparen;   /* Similarly for lastparen. */
-static char *  regtill;        /* How far we are required to go. */
-static char    regprev;        /* char before regbol, \n if none */
-
-static char *  regprecomp;     /* uncompiled string. */
-static I32             regnpar;        /* () count. */
-static I32             regsize;        /* Largest OPEN seens. */
-static char ** reg_start_tmp;
-static U32 reg_start_tmpl;
-static struct reg_data *data;
-static char *bostr;
-
-static U32 reg_flags;                  /* tainted/warned */
-static I32 reg_eval_set;
-
 #define RF_tainted     1               /* tainted information used? */
 #define RF_warned      2               /* warned about big count? */
-#define RF_evaled      4               /* Did an EVAL? */
+#define RF_evaled      4               /* Did an EVAL with setting? */
+
+#define RS_init                1               /* eval environment created */
+#define RS_set         2               /* replsv value is set */
 
 #ifndef STATIC
 #define        STATIC  static
 #endif
 
-#ifdef DEBUGGING
-static I32     regnarrate = 0;
-static regnode* regprogram = 0;
-#endif
-
-/* Current curly descriptor */
-typedef struct curcur CURCUR;
-struct curcur {
-    int                parenfloor;     /* how far back to strip paren data */
-    int                cur;            /* how many instances of scan we've matched */
-    int                min;            /* the minimal number of scans to match */
-    int                max;            /* the maximal number of scans to match */
-    int                minmod;         /* whether to work our way up or down */
-    regnode *  scan;           /* the thing to match */
-    regnode *  next;           /* what has to match after it */
-    char *     lastloc;        /* where we started matching this scan */
-    CURCUR *   oldcc;          /* current curly before we started this one */
-};
-
-static CURCUR* regcc;
-
 #ifndef PERL_OBJECT
 typedef I32 CHECKPOINT;
 
@@ -115,10 +77,12 @@ static I32 regmatch _((regnode *prog));
 static I32 regrepeat _((regnode *p, I32 max));
 static I32 regrepeat_hard _((regnode *p, I32 max, I32 *lp));
 static I32 regtry _((regexp *prog, char *startpos));
+
 static bool reginclass _((char *p, I32 c));
 static CHECKPOINT regcppush _((I32 parenfloor));
 static char * regcppop _((void));
 #endif
+#define REGINCLASS(p,c)  (*(p) ? reginclass(p,c) : ANYOF_TEST(p,c))
 
 STATIC CHECKPOINT
 regcppush(I32 parenfloor)
@@ -233,6 +197,7 @@ regexec_flags(register regexp *prog, char *stringarg, register char *strend, cha
     I32 end_shift = 0;                 /* Same for the end. */
     I32 scream_pos = -1;               /* Internal iterator of scream. */
     char *scream_olds;
+    SV* oreplsv = GvSV(replgv);
 
     cc.cur = 0;
     cc.oldcc = 0;
@@ -424,7 +389,7 @@ regexec_flags(register regexp *prog, char *stringarg, register char *strend, cha
        case ANYOF:
            Class = (char *) OPERAND(c);
            while (s < strend) {
-               if (reginclass(Class, *s)) {
+               if (REGINCLASS(Class, *s)) {
                    if (tmp && regtry(prog, s))
                        goto got_it;
                    else
@@ -671,6 +636,12 @@ got_it:
            }
        }
     }
+    /* Preserve the current value of $^R */
+    if (oreplsv != GvSV(replgv)) {
+       sv_setsv(oreplsv, GvSV(replgv));/* So that when GvSV(replgv) is
+                                          restored, the value remains
+                                          the same. */
+    }
     return 1;
 
 phooey:
@@ -689,6 +660,19 @@ regtry(regexp *prog, char *startpos)
     register char **ep;
     CHECKPOINT lastcp;
 
+    if ((prog->reganch & ROPT_EVAL_SEEN) && !reg_eval_set) {
+       reg_eval_set = RS_init;
+       DEBUG_r(DEBUG_s(
+           PerlIO_printf(Perl_debug_log, "  setting stack tmpbase at %i\n", stack_sp - stack_base);
+           ));
+       SAVEINT(cxstack[cxstack_ix].blk_oldsp);
+       cxstack[cxstack_ix].blk_oldsp = stack_sp - stack_base;
+       /* Otherwise OP_NEXTSTATE will free whatever on stack now.  */
+       SAVETMPS;
+       /* Apparently this is not needed, judging by wantarray. */
+       /* SAVEINT(cxstack[cxstack_ix].blk_gimme);
+          cxstack[cxstack_ix].blk_gimme = G_SCALAR; */
+    }
     reginput = startpos;
     regstartp = prog->startp;
     regendp = prog->endp;
@@ -705,7 +689,7 @@ regtry(regexp *prog, char *startpos)
 
     sp = prog->startp;
     ep = prog->endp;
-    data = prog->data;
+    regdata = prog->data;
     if (prog->nparens) {
        for (i = prog->nparens; i >= 0; i--) {
            *sp++ = NULL;
@@ -713,7 +697,7 @@ regtry(regexp *prog, char *startpos)
        }
     }
     REGCP_SET;
-    if (regmatch(prog->program + 1) && reginput >= regtill) {
+    if (regmatch(prog->program + 1)) {
        prog->startp[0] = startpos;
        prog->endp[0] = reginput;
        return 1;
@@ -751,7 +735,6 @@ regmatch(regnode *prog)
     register I32 c1, c2, paren;        /* case fold search, parenth */
     int minmod = 0, sw = 0, logical = 0;
 #ifdef DEBUGGING
-    static int regindent = 0;
     regindent++;
 #endif
 
@@ -793,13 +776,9 @@ regmatch(regnode *prog)
                          SvPVX(prop));
        } );
 
-#ifdef REGALIGN
        next = scan + NEXT_OFF(scan);
        if (next == scan)
            next = NULL;
-#else
-       next = regnext(scan);
-#endif
 
        switch (OP(scan)) {
        case BOL:
@@ -892,7 +871,7 @@ regmatch(regnode *prog)
            s = (char *) OPERAND(scan);
            if (nextchr < 0)
                nextchr = UCHARAT(locinput);
-           if (!reginclass(s, nextchr))
+           if (!REGINCLASS(s, nextchr))
                sayNO;
            if (!nextchr && locinput >= regeol)
                sayNO;
@@ -981,7 +960,7 @@ regmatch(regnode *prog)
            n = ARG(scan);  /* which paren pair */
            s = regstartp[n];
            if (*reglastparen < n || !s)
-               break;                  /* Zero length always matches */
+               sayNO;                  /* Do not match unless seen CLOSEn. */
            if (s == regendp[n])
                break;
            /* Inline the first character, for speed. */
@@ -1017,25 +996,9 @@ regmatch(regnode *prog)
            SV *ret;
            
            n = ARG(scan);
-           op = (OP_4tree*)data->data[n];
+           op = (OP_4tree*)regdata->data[n];
            DEBUG_r( PerlIO_printf(Perl_debug_log, "  re_eval 0x%x\n", op) );
-           curpad = AvARRAY((AV*)data->data[n + 1]);
-           if (!reg_eval_set) {
-               /* Preserve whatever is on stack now, otherwise
-                  OP_NEXTSTATE will overwrite it. */
-               SAVEINT(reg_eval_set);  /* Protect against unwinding. */
-               reg_eval_set = 1;
-               DEBUG_r(DEBUG_s(
-                   PerlIO_printf(Perl_debug_log, "  setting stack tmpbase at %i\n", stack_sp - stack_base);
-                   ));
-               SAVEINT(cxstack[cxstack_ix].blk_oldsp);
-               cxstack[cxstack_ix].blk_oldsp = stack_sp - stack_base;
-               /* Otherwise OP_NEXTSTATE will free whatever on stack now.  */
-               SAVETMPS;
-               /* Apparently this is not needed, judging by wantarray. */
-               /* SAVEINT(cxstack[cxstack_ix].blk_gimme);
-                  cxstack[cxstack_ix].blk_gimme = G_SCALAR; */
-           }
+           curpad = AvARRAY((AV*)regdata->data[n + 1]);
 
            CALLRUNOPS();                       /* Scalar context. */
            SPAGAIN;
@@ -1045,7 +1008,8 @@ regmatch(regnode *prog)
            if (logical) {
                logical = 0;
                sw = SvTRUE(ret);
-           }
+           } else
+               sv_setsv(save_scalar(replgv), ret);
            op = oop;
            curpad = ocurpad;
            curcop = ocurcop;
@@ -1274,15 +1238,11 @@ regmatch(regnode *prog)
                            regendp[n] = 0;
                        *reglastparen = n;
                        scan = next;
-#ifdef REGALIGN
                        /*SUPPRESS 560*/
                        if (n = (c1 == BRANCH ? NEXT_OFF(next) : ARG(next)))
                            next += n;
                        else
                            next = NULL;
-#else
-                       next = regnext(next);
-#endif
                        inner = NEXTOPER(scan);
                        if (c1 == BRANCHJ) {
                            inner = NEXTOPER(inner);
@@ -1298,7 +1258,7 @@ regmatch(regnode *prog)
            break;
        case CURLYM:
        {
-           I32 l;
+           I32 l = 0;
            CHECKPOINT lastcp;
            
            /* We suppose that the next guy does not need
@@ -1306,7 +1266,6 @@ regmatch(regnode *prog)
               and has no parenths to influence future backrefs. */
            ln = ARG1(scan);  /* min to match */
            n  = ARG2(scan);  /* max to match */
-#ifdef REGALIGN_STRUCT
            paren = scan->flags;
            if (paren) {
                if (paren > regsize)
@@ -1314,8 +1273,7 @@ regmatch(regnode *prog)
                if (paren > *reglastparen)
                    *reglastparen = paren;
            }
-#endif 
-           scan = NEXTOPER(scan) + 4/sizeof(regnode);
+           scan = NEXTOPER(scan) + NODE_STEP_REGNODE;
            if (paren)
                scan += NEXT_OFF(scan); /* Skip former OPEN. */
            reginput = locinput;
@@ -1323,7 +1281,7 @@ regmatch(regnode *prog)
                minmod = 0;
                if (ln && regrepeat_hard(scan, ln, &l) < ln)
                    sayNO;
-               if (l == 0 && n >= ln
+               if (ln && l == 0 && n >= ln
                    /* In fact, this is tricky.  If paren, then the
                       fact that we did/didnot match may influence
                       future execution. */
@@ -1341,6 +1299,7 @@ regmatch(regnode *prog)
                } else
                    c1 = c2 = -1000;
                REGCP_SET;
+               /* This may be improved if l == 0.  */
                while (n >= ln || (n == REG_INFTY && ln > 0 && l)) { /* ln overflow ? */
                    /* If it could work, try it. */
                    if (c1 == -1000 ||
@@ -1429,13 +1388,13 @@ regmatch(regnode *prog)
                *reglastparen = paren;
            ln = ARG1(scan);  /* min to match */
            n  = ARG2(scan);  /* max to match */
-            scan = regnext(NEXTOPER(scan) + 4/sizeof(regnode));
+            scan = regnext(NEXTOPER(scan) + NODE_STEP_REGNODE);
            goto repeat;
        case CURLY:
            paren = 0;
            ln = ARG1(scan);  /* min to match */
            n  = ARG2(scan);  /* max to match */
-           scan = NEXTOPER(scan) + 4/sizeof(regnode);
+           scan = NEXTOPER(scan) + NODE_STEP_REGNODE;
            goto repeat;
        case STAR:
            ln = 0;
@@ -1545,8 +1504,11 @@ regmatch(regnode *prog)
            }
            sayNO;
            break;
-       case SUCCEED:
        case END:
+           if (locinput < regtill)
+               sayNO;                  /* Cannot match: too short. */
+           /* Fall through */
+       case SUCCEED:
            reginput = locinput;        /* put where regtry can find it */
            sayYES;                     /* Success! */
        case SUSPEND:
@@ -1665,7 +1627,7 @@ regrepeat(regnode *p, I32 max)
            scan++;
        break;
     case ANYOF:
-       while (scan < loceol && reginclass(opnd, *scan))
+       while (scan < loceol && REGINCLASS(opnd, *scan))
            scan++;
        break;
     case ALNUM:
@@ -1776,7 +1738,7 @@ reginclass(register char *p, register I32 c)
     bool match = FALSE;
 
     c &= 0xFF;
-    if (p[1 + (c >> 3)] & (1 << (c & 7)))
+    if (ANYOF_TEST(p, c))
        match = TRUE;
     else if (flags & ANYOF_FOLD) {
        I32 cf;
@@ -1786,7 +1748,7 @@ reginclass(register char *p, register I32 c)
        }
        else
            cf = fold[c];
-       if (p[1 + (cf >> 3)] & (1 << (cf & 7)))
+       if (ANYOF_TEST(p, cf))
            match = TRUE;
     }
 
@@ -1802,7 +1764,7 @@ reginclass(register char *p, register I32 c)
        }
     }
 
-    return match ^ ((flags & ANYOF_INVERT) != 0);
+    return (flags & ANYOF_INVERT) ? !match : match;
 }