regnode *next;
U32 n = 0; /* general value; init to avoid compiler warning */
I32 ln = 0; /* len or last; init to avoid compiler warning */
- char *reginput = startpos;
- char *locinput = reginput;
+ char *locinput = startpos;
char *pushinput; /* where to continue after a PUSH */
I32 nextchr; /* is always set to UCHARAT(locinput) */
U32 state_num;
bool no_final = 0; /* prevent failure from backtracking? */
bool do_cutgroup = 0; /* no_final only until next branch/trie entry */
- char *startpoint = reginput;
+ char *startpoint = locinput;
SV *popmark = NULL; /* are we looking for a mark? */
SV *sv_commit = NULL; /* last mark name seen in failure */
SV *sv_yes_mark = NULL; /* last mark name we have seen
case KEEPS:
/* update the startpoint */
st->u.keeper.val = rex->offs[0].start;
- reginput = locinput;
rex->offs[0].start = locinput - PL_bostr;
PUSH_STATE_GOTO(KEEPS_next, next, locinput);
/*NOT-REACHED*/
re->lastparen = 0;
re->lastcloseparen = 0;
- reginput = locinput;
PL_regsize = 0;
/* XXXX This is too dramatic a measure... */
rex = (struct regexp *)SvANY(rex_sv);
rexi = RXi_GET(rex);
- reginput = locinput;
REGCP_UNWIND(ST.lastcp);
regcppop(rex);
cur_eval = ST.prev_eval;
ST.cache_offset = 0;
ST.cache_mask = 0;
- reginput = locinput;
DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
"%*s whilem: matched %ld out of %d..%d\n",
case WHILEM_A_max_fail: /* just failed to match A in a maximal match */
REGCP_UNWIND(ST.lastcp);
regcppop(rex); /* Restore some previous $<digit>s? */
- reginput = locinput;
DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
"%*s whilem: failed, trying continuation...\n",
REPORT_CODE_OFF+depth*2, "")
"%*s trying longer...\n", REPORT_CODE_OFF+depth*2, "")
);
/* Try grabbing another A and see if it helps. */
- reginput = locinput;
cur_curlyx->u.curlyx.lastloc = locinput;
ST.cp = regcppush(rex, cur_curlyx->u.curlyx.parenfloor);
REGCP_SET(ST.lastcp);
assert(0); /* NOTREACHED */
case CURLYM_A: /* we've just matched an A */
- locinput = st->locinput;
- nextchr = UCHARAT(locinput);
-
ST.count++;
/* after first match, determine A's length: u.curlym.alen */
if (ST.count == 1) {
if (PL_reg_match_utf8) {
- char *s = locinput;
- while (s < reginput) {
+ char *s = st->locinput;
+ while (s < locinput) {
ST.alen++;
s += UTF8SKIP(s);
}
}
else {
- ST.alen = reginput - locinput;
+ ST.alen = locinput - st->locinput;
}
if (ST.alen == 0)
ST.count = ST.minmod ? ARG1(ST.me) : ARG2(ST.me);
(IV) ST.count, (IV)ST.alen)
);
- locinput = reginput;
-
if (cur_eval && cur_eval->u.eval.close_paren &&
cur_eval->u.eval.close_paren == (U32)ST.me->flags)
goto fake_end;
sayNO;
curlym_do_B: /* execute the B in /A{m,n}B/ */
- reginput = locinput;
if (ST.c1 == CHRTEST_UNINIT) {
/* calculate c1 and c2 for possible match of 1st char
* following curly */
"", (IV)ST.count)
);
if (ST.c1 != CHRTEST_VOID
- && UCHARAT(reginput) != ST.c1
- && UCHARAT(reginput) != ST.c2)
+ && nextchr != ST.c1
+ && nextchr != ST.c2)
{
/* simulate B failing */
DEBUG_OPTIMISE_r(
I32 paren = ST.me->flags;
if (ST.count) {
rex->offs[paren].start
- = HOPc(reginput, -ST.alen) - PL_bostr;
- rex->offs[paren].end = reginput - PL_bostr;
+ = HOPc(locinput, -ST.alen) - PL_bostr;
+ rex->offs[paren].end = locinput - PL_bostr;
if ((U32)paren > rex->lastparen)
rex->lastparen = paren;
rex->lastcloseparen = paren;
sayNO;
ST.count--;
locinput = HOPc(locinput, -ST.alen);
+ nextchr = UCHARAT(locinput);
goto curlym_do_B; /* try to match B */
#undef ST
ST.A = scan;
ST.B = next;
- reginput = locinput;
if (minmod) {
- /* avoid taking address of reginput, so it can remain
- * a register var */
- char *ri = reginput;
+ char *li = locinput;
minmod = 0;
- if (ST.min && regrepeat(rex, &ri, ST.A, ST.min, depth) < ST.min)
+ if (ST.min && regrepeat(rex, &li, ST.A, ST.min, depth) < ST.min)
sayNO;
- reginput = ri;
+ locinput = li;
+ nextchr = UCHARAT(locinput);
ST.count = ST.min;
- locinput = reginput;
REGCP_SET(ST.cp);
if (ST.c1 == CHRTEST_VOID)
goto curly_try_B_min;
}
else {
- char *ri = reginput;
- ST.count = regrepeat(rex, &ri, ST.A, ST.max, depth);
- reginput = ri;
- locinput = reginput;
+ /* avoid taking address of locinput, so it can remain
+ * a register var */
+ char *li = locinput;
+ ST.count = regrepeat(rex, &li, ST.A, ST.max, depth);
if (ST.count < ST.min)
sayNO;
+ locinput = li;
+ nextchr = UCHARAT(locinput);
if ((ST.count > ST.min)
&& (PL_regkind[OP(ST.B)] == EOL) && (OP(ST.B) != MEOL))
{
/* ...except that $ and \Z can match before *and* after
newline at the end. Consider "\n\n" =~ /\n+\Z\n/.
We may back off by one in this case. */
- if (UCHARAT(reginput - 1) == '\n' && OP(ST.B) != EOS)
+ if (UCHARAT(locinput - 1) == '\n' && OP(ST.B) != EOS)
ST.min--;
}
REGCP_SET(ST.cp);
case CURLY_B_min_known_fail:
/* failed to find B in a non-greedy match where c1,c2 valid */
- reginput = locinput; /* Could be reset... */
REGCP_UNWIND(ST.cp);
if (ST.paren) {
UNWIND_PAREN(ST.lastparen, ST.lastcloseparen);
}
if (locinput > ST.maxpos)
sayNO;
- /* reginput == oldloc now */
if (n) {
- char *ri = reginput;
+ /* In /a{m,n}b/, ST.oldloc is at "a" x m, locinput is
+ * at b; check that everything between oldloc and
+ * locinput matches */
+ char *li = ST.oldloc;
ST.count += n;
- if (regrepeat(rex, &ri, ST.A, n, depth) < n)
+ if (regrepeat(rex, &li, ST.A, n, depth) < n)
sayNO;
- reginput = ri;
+ assert(n == REG_INFTY || locinput == li);
}
- reginput = locinput;
CURLY_SETPAREN(ST.paren, ST.count);
if (cur_eval && cur_eval->u.eval.close_paren &&
cur_eval->u.eval.close_paren == (U32)ST.paren) {
UNWIND_PAREN(ST.lastparen, ST.lastcloseparen);
}
/* failed -- move forward one */
- reginput = locinput;
{
- char *ri = reginput;
- if (!regrepeat(rex, &ri, ST.A, 1, depth)) {
+ char *li = locinput;
+ if (!regrepeat(rex, &li, ST.A, 1, depth)) {
sayNO;
}
- reginput = ri;
+ locinput = li;
}
{
ST.count++;
- locinput = reginput;
if (ST.count <= ST.max || (ST.max == REG_INFTY &&
ST.count > 0)) /* count overflow ? */
{
{
UV c = 0;
if (ST.c1 != CHRTEST_VOID)
- c = utf8_target ? utf8n_to_uvchr((U8*)reginput,
+ c = utf8_target ? utf8n_to_uvchr((U8*)locinput,
UTF8_MAXBYTES, 0, uniflags)
- : (UV) UCHARAT(reginput);
+ : (UV) UCHARAT(locinput);
/* If it could work, try it. */
if (ST.c1 == CHRTEST_VOID || c == (UV)ST.c1 || c == (UV)ST.c2) {
CURLY_SETPAREN(ST.paren, ST.count);
/* back up. */
if (--ST.count < ST.min)
sayNO;
- reginput = locinput = HOPc(locinput, -1);
+ locinput = HOPc(locinput, -1);
goto curly_try_B_max;
#undef ST
cur_curlyx = cur_eval->u.eval.prev_curlyx;
REGCP_SET(st->u.eval.lastcp);
- reginput = locinput;
/* Restore parens of the outer rex without popping the
* savestack */
sayNO_SILENT; /* Cannot match: too short. */
}
- reginput = locinput; /* put where regtry can find it */
sayYES; /* Success! */
case SUCCEED: /* successful SUSPEND/UNLESSM/IFMATCH/CURLYM */
PerlIO_printf(Perl_debug_log,
"%*s %ssubpattern success...%s\n",
REPORT_CODE_OFF+depth*2, "", PL_colors[4], PL_colors[5]));
- reginput = locinput; /* put where regtry can find it */
sayYES; /* Success! */
#undef ST
#define ST st->u.ifmatch
+ {
+ char *newstart;
+
case SUSPEND: /* (?>A) */
ST.wanted = 1;
- reginput = locinput;
+ newstart = locinput;
goto do_ifmatch;
case UNLESSM: /* -ve lookaround: (?!A), or with flags, (?<!A) */
next = NULL;
break;
}
- reginput = s;
+ newstart = s;
}
else
- reginput = locinput;
+ newstart = locinput;
do_ifmatch:
ST.me = scan;
logical = 0; /* XXX: reset state of logical once it has been saved into ST */
/* execute body of (?...A) */
- PUSH_YES_STATE_GOTO(IFMATCH_A, NEXTOPER(NEXTOPER(scan)), reginput);
+ PUSH_YES_STATE_GOTO(IFMATCH_A, NEXTOPER(NEXTOPER(scan)), newstart);
assert(0); /* NOTREACHED */
+ }
case IFMATCH_A_fail: /* body of (?...A) failed */
ST.wanted = !ST.wanted;
else if (!ST.wanted)
sayNO;
- if (OP(ST.me) == SUSPEND)
- locinput = reginput;
- else {
- locinput = reginput = st->locinput;
+ if (OP(ST.me) != SUSPEND) {
+ /* restore old position except for (?>...) */
+ locinput = st->locinput;
nextchr = UCHARAT(locinput);
}
scan = ST.me + ARG(ST.me);
reginfo->cutpoint = PL_regeol;
/* FALLTHROUGH */
case PRUNE:
- reginput = locinput;
if (!scan->flags)
sv_yes_mark = sv_commit = MUTABLE_SV(rexi->data->data[ ARG( scan ) ]);
PUSH_STATE_GOTO(COMMIT_next, next, locinput);
sayNO;
assert(0); /* NOTREACHED */
case SKIP:
- reginput = locinput;
if (scan->flags) {
/* (*SKIP) : if we fail we cut here*/
ST.mark_name = NULL;
/* clean up; in particular, free all slabs above current one */
LEAVE_SCOPE(oldsave);
- assert(!result || reginput - PL_bostr >= 0);
- return result ? reginput - PL_bostr : -1;
+ assert(!result || locinput - PL_bostr >= 0);
+ return result ? locinput - PL_bostr : -1;
}
/*
- regrepeat - repeatedly match something simple, report how many
- */
-/*
- * [This routine now assumes that it will only match on things of length 1.
- * That was true before, but now we assume scan - reginput is the count,
- * rather than incrementing count on every character. [Er, except utf8.]]
+ *
+ * startposp - pointer a pointer to the start position. This is updated
+ * to point to the byte following the highest successful
+ * match.
+ * p - the regnode to be repeatedly matched against.
+ * max - maximum number of characters to match.
+ * depth - (for debugging) backtracking depth.
*/
STATIC I32
S_regrepeat(pTHX_ const regexp *prog, char **startposp, const regnode *p, I32 max, int depth)