summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFacundo Batista <facundobatista@gmail.com>2008-01-08 21:10:12 (GMT)
committerFacundo Batista <facundobatista@gmail.com>2008-01-08 21:10:12 (GMT)
commit4473d225a8b0d4977bde569892a3c76640fb123a (patch)
treee147845a886b8b00121bb5e76cbfbb9c174b2700
parent8d10167236c2247bab706780262fbbef38de0099 (diff)
downloadcpython-4473d225a8b0d4977bde569892a3c76640fb123a.zip
cpython-4473d225a8b0d4977bde569892a3c76640fb123a.tar.gz
cpython-4473d225a8b0d4977bde569892a3c76640fb123a.tar.bz2
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.
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/_sre.c8
2 files changed, 11 insertions, 0 deletions
diff --git a/Misc/NEWS b/Misc/NEWS
index c77ce62..dc1817f 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -348,6 +348,9 @@ Core and builtins
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
on Parser objects to set the character data buffer size.
diff --git a/Modules/_sre.c b/Modules/_sre.c
index 3827aa1..d79d5a7 100644
--- a/Modules/_sre.c
+++ b/Modules/_sre.c
@@ -99,6 +99,7 @@ static char copyright[] =
#define SRE_ERROR_STATE -2 /* illegal state */
#define SRE_ERROR_RECURSION_LIMIT -3 /* runaway recursion */
#define SRE_ERROR_MEMORY -9 /* out of memory */
+#define SRE_ERROR_INTERRUPTED -10 /* signal handler raised exception */
#if defined(VERBOSE)
#define TRACE(v) printf v
@@ -809,6 +810,7 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern)
Py_ssize_t alloc_pos, ctx_pos = -1;
Py_ssize_t i, ret = 0;
Py_ssize_t jump;
+ unsigned int sigcount=0;
SRE_MATCH_CONTEXT* ctx;
SRE_MATCH_CONTEXT* nextctx;
@@ -837,6 +839,9 @@ entrance:
}
for (;;) {
+ ++sigcount;
+ if ((0 == (sigcount & 0xfff)) && PyErr_CheckSignals())
+ RETURN_ERROR(SRE_ERROR_INTERRUPTED);
switch (*ctx->pattern++) {
@@ -1834,6 +1839,9 @@ pattern_error(int status)
case SRE_ERROR_MEMORY:
PyErr_NoMemory();
break;
+ case SRE_ERROR_INTERRUPTED:
+ /* An exception has already been raised, so let it fly */
+ break;
default:
/* other error codes indicate compiler/engine bugs */
PyErr_SetString(