summaryrefslogtreecommitdiffstats
path: root/Modules
diff options
context:
space:
mode:
Diffstat (limited to 'Modules')
-rw-r--r--Modules/_sre.c61
1 files changed, 38 insertions, 23 deletions
diff --git a/Modules/_sre.c b/Modules/_sre.c
index be59112..3183a6e 100644
--- a/Modules/_sre.c
+++ b/Modules/_sre.c
@@ -337,19 +337,6 @@ mark_restore(SRE_STATE* state, int lo, int hi)
return 0;
}
-static void
-lastmark_restore(SRE_STATE *state, int lastmark)
-{
- if (state->lastmark > lastmark) {
- memset(
- state->mark + lastmark + 1, 0,
- (state->lastmark - lastmark) * sizeof(void*)
- );
- state->lastmark = lastmark;
- state->lastindex = (lastmark == 0) ? -1 : (lastmark-1)/2+1;
- }
-}
-
/* generate 8-bit version */
#define SRE_CHAR unsigned char
@@ -690,6 +677,22 @@ SRE_INFO(SRE_STATE* state, SRE_CODE* pattern)
}
#endif
+/* macros to preserve lastmark in case of backtracking */
+#define LASTMARK_SAVE() \
+ do { \
+ lastmark = state->lastmark; \
+ lastindex = state->lastindex; \
+ } while (0)
+#define LASTMARK_RESTORE() \
+ do { \
+ if (state->lastmark > lastmark) { \
+ memset(state->mark + lastmark + 1, 0, \
+ (state->lastmark - lastmark) * sizeof(void*)); \
+ state->lastmark = lastmark; \
+ state->lastindex = lastindex; \
+ } \
+ } while (0)
+
LOCAL(int)
SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
{
@@ -700,7 +703,7 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
SRE_CHAR* ptr = state->ptr;
int i, count;
SRE_REPEAT* rp;
- int lastmark;
+ int lastmark, lastindex;
SRE_CODE chr;
SRE_REPEAT rep; /* FIXME: <fl> allocate in STATE instead */
@@ -927,7 +930,7 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
/* alternation */
/* <BRANCH> <0=skip> code <JUMP> ... <NULL> */
TRACE(("|%p|%p|BRANCH\n", pattern, ptr));
- lastmark = state->lastmark;
+ LASTMARK_SAVE();
for (; pattern[0]; pattern += pattern[0]) {
if (pattern[1] == SRE_OP_LITERAL &&
(ptr >= end || (SRE_CODE) *ptr != pattern[2]))
@@ -939,7 +942,7 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
i = SRE_MATCH(state, pattern + 1, level + 1);
if (i)
return i;
- lastmark_restore(state, lastmark);
+ LASTMARK_RESTORE();
}
return 0;
@@ -979,8 +982,11 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
/* tail is empty. we're finished */
state->ptr = ptr;
return 1;
+ }
+
+ LASTMARK_SAVE();
- } else if (pattern[pattern[0]] == SRE_OP_LITERAL) {
+ if (pattern[pattern[0]] == SRE_OP_LITERAL) {
/* tail starts with a literal. skip positions where
the rest of the pattern cannot possibly match */
chr = pattern[pattern[0]+1];
@@ -998,11 +1004,11 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
return i;
ptr--;
count--;
+ LASTMARK_RESTORE();
}
} else {
/* general case */
- lastmark = state->lastmark;
while (count >= (int) pattern[1]) {
state->ptr = ptr;
i = SRE_MATCH(state, pattern + pattern[0], level + 1);
@@ -1010,7 +1016,7 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
return i;
ptr--;
count--;
- lastmark_restore(state, lastmark);
+ LASTMARK_RESTORE();
}
}
return 0;
@@ -1055,7 +1061,7 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
/* general case */
int matchmax = ((int)pattern[2] == 65535);
int c;
- lastmark = state->lastmark;
+ LASTMARK_SAVE();
while (matchmax || count <= (int) pattern[2]) {
state->ptr = ptr;
i = SRE_MATCH(state, pattern + pattern[0], level + 1);
@@ -1065,13 +1071,13 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
c = SRE_COUNT(state, pattern+3, 1, level+1);
if (c < 0)
return c;
+ LASTMARK_RESTORE();
if (c == 0)
break;
assert(c == 1);
ptr++;
count++;
}
- lastmark_restore(state, lastmark);
}
return 0;
@@ -1113,6 +1119,8 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
TRACE(("|%p|%p|MAX_UNTIL %d\n", pattern, ptr, count));
+ LASTMARK_SAVE();
+
if (count < rp->pattern[1]) {
/* not enough matches */
rp->count = count;
@@ -1122,6 +1130,7 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
return i;
rp->count = count - 1;
state->ptr = ptr;
+ LASTMARK_RESTORE();
return 0;
}
@@ -1129,7 +1138,6 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
/* we may have enough matches, but if we can
match another item, do so */
rp->count = count;
- lastmark = state->lastmark;
i = mark_save(state, 0, lastmark);
if (i < 0)
return i;
@@ -1138,7 +1146,7 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
if (i)
return i;
i = mark_restore(state, 0, lastmark);
- state->lastmark = lastmark;
+ LASTMARK_RESTORE();
if (i < 0)
return i;
rp->count = count - 1;
@@ -1182,6 +1190,8 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
return 0;
}
+ LASTMARK_SAVE();
+
/* see if the tail matches */
state->repeat = rp->prev;
i = SRE_MATCH(state, pattern, level + 1);
@@ -1191,6 +1201,8 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern, int level)
state->ptr = ptr;
state->repeat = rp;
+ LASTMARK_RESTORE();
+
if (count >= rp->pattern[2] && rp->pattern[2] != 65535)
return 0;
@@ -3084,3 +3096,6 @@ PyMODINIT_FUNC init_sre(void)
}
#endif /* !defined(SRE_RECURSIVE) */
+
+/* vim:ts=4:sw=4:et
+*/