Commit ec69dfd2 authored by Facundo Batista's avatar Facundo Batista

Issue 846388. Adds a call to PyErr_CheckSignals to

SRE_MATCH so that signal handlers can be invoked during
long regular expression matches.  It also adds a new
error return value indicating that an exception
occurred in a signal handler during the match, allowing
exceptions in the signal handler to propagate up to the
main loop.  Thanks Josh Hoyt and Ralf Schmitt.
parent d668143d
...@@ -348,6 +348,9 @@ Core and builtins ...@@ -348,6 +348,9 @@ Core and builtins
Library Library
------- -------
- Issue #846388. re.match is interruptible now, which is particularly
good for long regular expression matches.
- pyexpat, patch #1137: allow setting buffer_size attribute - pyexpat, patch #1137: allow setting buffer_size attribute
on Parser objects to set the character data buffer size. on Parser objects to set the character data buffer size.
......
...@@ -99,6 +99,7 @@ static char copyright[] = ...@@ -99,6 +99,7 @@ static char copyright[] =
#define SRE_ERROR_STATE -2 /* illegal state */ #define SRE_ERROR_STATE -2 /* illegal state */
#define SRE_ERROR_RECURSION_LIMIT -3 /* runaway recursion */ #define SRE_ERROR_RECURSION_LIMIT -3 /* runaway recursion */
#define SRE_ERROR_MEMORY -9 /* out of memory */ #define SRE_ERROR_MEMORY -9 /* out of memory */
#define SRE_ERROR_INTERRUPTED -10 /* signal handler raised exception */
#if defined(VERBOSE) #if defined(VERBOSE)
#define TRACE(v) printf v #define TRACE(v) printf v
...@@ -809,6 +810,7 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern) ...@@ -809,6 +810,7 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern)
Py_ssize_t alloc_pos, ctx_pos = -1; Py_ssize_t alloc_pos, ctx_pos = -1;
Py_ssize_t i, ret = 0; Py_ssize_t i, ret = 0;
Py_ssize_t jump; Py_ssize_t jump;
unsigned int sigcount=0;
SRE_MATCH_CONTEXT* ctx; SRE_MATCH_CONTEXT* ctx;
SRE_MATCH_CONTEXT* nextctx; SRE_MATCH_CONTEXT* nextctx;
...@@ -837,6 +839,9 @@ entrance: ...@@ -837,6 +839,9 @@ entrance:
} }
for (;;) { for (;;) {
++sigcount;
if ((0 == (sigcount & 0xfff)) && PyErr_CheckSignals())
RETURN_ERROR(SRE_ERROR_INTERRUPTED);
switch (*ctx->pattern++) { switch (*ctx->pattern++) {
...@@ -1834,6 +1839,9 @@ pattern_error(int status) ...@@ -1834,6 +1839,9 @@ pattern_error(int status)
case SRE_ERROR_MEMORY: case SRE_ERROR_MEMORY:
PyErr_NoMemory(); PyErr_NoMemory();
break; break;
case SRE_ERROR_INTERRUPTED:
/* An exception has already been raised, so let it fly */
break;
default: default:
/* other error codes indicate compiler/engine bugs */ /* other error codes indicate compiler/engine bugs */
PyErr_SetString( PyErr_SetString(
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment