summaryrefslogtreecommitdiff
path: root/regexec.c
diff options
context:
space:
mode:
authorYves Orton <demerphq@gmail.com>2006-10-31 23:49:57 +0100
committerRafael Garcia-Suarez <rgarciasuarez@gmail.com>2006-11-01 17:05:03 +0000
commit5461259206276a3618e115d5d68776273bb41ca6 (patch)
tree62be0b5e283fa9c04597fe6ec054cc83064e0f87 /regexec.c
parenta983b08dc7c658d412bac21b8ceac00c24ae5c11 (diff)
downloadperl-5461259206276a3618e115d5d68776273bb41ca6.tar.gz
Add a commit verb to regex engine to allow fine tuning of backtracking control.
Message-ID: <9b18b3110610311349n5947cc8fsf0b2e6ddd9a7ee01@mail.gmail.com> p4raw-id: //depot/perl@29183
Diffstat (limited to 'regexec.c')
-rw-r--r--regexec.c24
1 files changed, 22 insertions, 2 deletions
diff --git a/regexec.c b/regexec.c
index 9f28e3eb3d..55a90d0d9b 100644
--- a/regexec.c
+++ b/regexec.c
@@ -2571,6 +2571,7 @@ S_regmatch(pTHX_ const regmatch_info *reginfo, regnode *prog)
regmatch_state *cur_eval = NULL; /* most recent EVAL_AB state */
struct regmatch_state *cur_curlyx = NULL; /* most recent curlyx */
U32 state_num;
+ bool no_final = 0; /* if true then we dont backtrack on failure */
/* these three flags are set by various ops to signal information to
* the very next op. They have a useful lifetime of exactly one loop
@@ -4614,6 +4615,12 @@ NULL
if (next == scan)
next = NULL;
break;
+ case COMMIT:
+ PUSH_STATE_GOTO(COMMIT_next,next);
+ /* NOTREACHED */
+ case COMMIT_next_fail:
+ no_final = 1;
+ /* FALLTHROUGH */
case OPFAIL:
sayNO;
default:
@@ -4672,7 +4679,13 @@ yes:
PL_regmatch_slab = PL_regmatch_slab->prev;
st = SLAB_LAST(PL_regmatch_slab);
}
- DEBUG_STATE_pp("pop (yes)");
+ DEBUG_STATE_r(
+ if (no_final) {
+ DEBUG_STATE_pp("pop (no final)");
+ } else {
+ DEBUG_STATE_pp("pop (yes)");
+ }
+ );
depth--;
}
#else
@@ -4690,7 +4703,7 @@ yes:
yes_state = st->u.yes.prev_yes_state;
PL_regmatch_state = st;
- state_num = st->resume_state;
+ state_num = st->resume_state + no_final;
goto reenter_switch;
}
@@ -4709,6 +4722,13 @@ no:
);
no_silent:
+ if (no_final) {
+ if (yes_state) {
+ goto yes;
+ } else {
+ goto final_exit;
+ }
+ }
if (depth) {
/* there's a previous state to backtrack to */
st--;