#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
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)
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;
else
s = fbm_instr((unsigned char*)s + start_shift,
(unsigned char*)strend - end_shift,
- prog->check_substr);
+ prog->check_substr, 0);
if (!s) {
++BmUSEFUL(prog->check_substr); /* hooray */
goto phooey; /* not present */
? (s = screaminstr(screamer, must, s + back_min - strbeg,
end_shift, &scream_pos, 0))
: (s = fbm_instr((unsigned char*)s + back_min,
- (unsigned char*)strend, must))) ) {
+ (unsigned char*)strend, must, 0))) ) {
if (s - back_max > last1) {
last1 = s - back_min;
s = s - back_max;
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
strend += dontbother; /* uncheat */
prog->subbeg = strbeg;
prog->subend = strend;
- RX_MATCH_TAINTED_SET(prog, reg_flags & RF_tainted);
+ RX_MATCH_TAINTED_set(prog, reg_flags & RF_tainted);
/* make sure $`, $&, $', and $digit will work later */
if (strbeg != prog->subbase) { /* second+ //g match. */
}
}
}
+ /* 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:
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;
}
}
REGCP_SET;
- if (regmatch(prog->program + 1) && reginput >= regtill) {
+ if (regmatch(prog->program + 1)) {
prog->startp[0] = startpos;
prog->endp[0] = reginput;
return 1;
SvPVX(prop));
} );
-#ifdef REGALIGN
next = scan + NEXT_OFF(scan);
if (next == scan)
next = NULL;
-#else
- next = regnext(scan);
-#endif
switch (OP(scan)) {
case BOL:
- if (locinput == regbol
+ if (locinput == bostr
? regprev == '\n'
: (multiline &&
(nextchr || locinput < regeol) && locinput[-1] == '\n') )
}
sayNO;
case MBOL:
- if (locinput == regbol
+ if (locinput == bostr
? regprev == '\n'
: ((nextchr || locinput < regeol) && locinput[-1] == '\n') )
{
if (regeol - locinput > 1)
sayNO;
break;
+ case EOS:
+ if (regeol != locinput)
+ sayNO;
+ break;
case SANY:
if (!nextchr && locinput >= regeol)
sayNO;
s = (char *) OPERAND(scan);
if (nextchr < 0)
nextchr = UCHARAT(locinput);
- if (!reginclass(s, nextchr))
+ if (!REGINCLASS(s, nextchr))
sayNO;
if (!nextchr && locinput >= regeol)
sayNO;
op = (OP_4tree*)regdata->data[n];
DEBUG_r( PerlIO_printf(Perl_debug_log, " re_eval 0x%x\n", op) );
curpad = AvARRAY((AV*)regdata->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; */
- }
CALLRUNOPS(); /* Scalar context. */
SPAGAIN;
if (logical) {
logical = 0;
sw = SvTRUE(ret);
- }
+ } else
+ sv_setsv(save_scalar(replgv), ret);
op = oop;
curpad = ocurpad;
curcop = ocurcop;
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);
break;
case CURLYM:
{
- I32 l;
+ I32 l = 0;
CHECKPOINT lastcp;
/* We suppose that the next guy does not need
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)
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;
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. */
} 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 ||
*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;
}
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:
scan++;
break;
case ANYOF:
- while (scan < loceol && reginclass(opnd, *scan))
+ while (scan < loceol && REGINCLASS(opnd, *scan))
scan++;
break;
case ALNUM:
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;
}
else
cf = fold[c];
- if (p[1 + (cf >> 3)] & (1 << (cf & 7)))
+ if (ANYOF_TEST(p, cf))
match = TRUE;
}
}
}
- return match ^ ((flags & ANYOF_INVERT) != 0);
+ return (flags & ANYOF_INVERT) ? !match : match;
}