summaryrefslogtreecommitdiffstats
path: root/Modules/sre_lib.h
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2013-11-23 21:20:30 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2013-11-23 21:20:30 (GMT)
commit32eddc1bbc47479a3639b9191ffc82a52903c5f4 (patch)
tree8ce67ed6f7d6db96277f4e6d07457f2b159fb362 /Modules/sre_lib.h
parent3ed82c55a85665a33b821064c1911b4aa09301d9 (diff)
downloadcpython-32eddc1bbc47479a3639b9191ffc82a52903c5f4.zip
cpython-32eddc1bbc47479a3639b9191ffc82a52903c5f4.tar.gz
cpython-32eddc1bbc47479a3639b9191ffc82a52903c5f4.tar.bz2
Issue #16203: Add re.fullmatch() function and regex.fullmatch() method,
which anchor the pattern at both ends of the string to match. Original patch by Matthew Barnett.
Diffstat (limited to 'Modules/sre_lib.h')
-rw-r--r--Modules/sre_lib.h28
1 files changed, 21 insertions, 7 deletions
diff --git a/Modules/sre_lib.h b/Modules/sre_lib.h
index 214c22a..df86697 100644
--- a/Modules/sre_lib.h
+++ b/Modules/sre_lib.h
@@ -454,17 +454,24 @@ do { \
#define JUMP_ASSERT 12
#define JUMP_ASSERT_NOT 13
-#define DO_JUMP(jumpvalue, jumplabel, nextpattern) \
+#define DO_JUMPX(jumpvalue, jumplabel, nextpattern, matchall) \
DATA_ALLOC(SRE(match_context), nextctx); \
nextctx->last_ctx_pos = ctx_pos; \
nextctx->jump = jumpvalue; \
nextctx->pattern = nextpattern; \
+ nextctx->match_all = matchall; \
ctx_pos = alloc_pos; \
ctx = nextctx; \
goto entrance; \
jumplabel: \
while (0) /* gcc doesn't like labels at end of scopes */ \
+#define DO_JUMP(jumpvalue, jumplabel, nextpattern) \
+ DO_JUMPX(jumpvalue, jumplabel, nextpattern, ctx->match_all)
+
+#define DO_JUMP0(jumpvalue, jumplabel, nextpattern) \
+ DO_JUMPX(jumpvalue, jumplabel, nextpattern, 0)
+
typedef struct {
Py_ssize_t last_ctx_pos;
Py_ssize_t jump;
@@ -477,6 +484,7 @@ typedef struct {
SRE_CODE chr;
SRE_REPEAT* rep;
} u;
+ int match_all;
} SRE(match_context);
/* check if string matches the given pattern. returns <0 for
@@ -499,6 +507,7 @@ SRE(match)(SRE_STATE* state, SRE_CODE* pattern)
ctx->last_ctx_pos = -1;
ctx->jump = JUMP_NONE;
ctx->pattern = pattern;
+ ctx->match_all = state->match_all;
ctx_pos = alloc_pos;
entrance:
@@ -571,8 +580,11 @@ entrance:
case SRE_OP_SUCCESS:
/* end of pattern */
TRACE(("|%p|%p|SUCCESS\n", ctx->pattern, ctx->ptr));
- state->ptr = ctx->ptr;
- RETURN_SUCCESS;
+ if (!ctx->match_all || ctx->ptr == state->end) {
+ state->ptr = ctx->ptr;
+ RETURN_SUCCESS;
+ }
+ RETURN_FAILURE;
case SRE_OP_AT:
/* match at given position */
@@ -726,7 +738,8 @@ entrance:
if (ctx->count < (Py_ssize_t) ctx->pattern[1])
RETURN_FAILURE;
- if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS) {
+ if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS &&
+ (!ctx->match_all || ctx->ptr == state->end)) {
/* tail is empty. we're finished */
state->ptr = ctx->ptr;
RETURN_SUCCESS;
@@ -810,7 +823,8 @@ entrance:
ctx->ptr += ctx->count;
}
- if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS) {
+ if (ctx->pattern[ctx->pattern[0]] == SRE_OP_SUCCESS &&
+ (!ctx->match_all || ctx->ptr == state->end)) {
/* tail is empty. we're finished */
state->ptr = ctx->ptr;
RETURN_SUCCESS;
@@ -1082,7 +1096,7 @@ entrance:
state->ptr = ctx->ptr - ctx->pattern[1];
if (state->ptr < state->beginning)
RETURN_FAILURE;
- DO_JUMP(JUMP_ASSERT, jump_assert, ctx->pattern+2);
+ DO_JUMP0(JUMP_ASSERT, jump_assert, ctx->pattern+2);
RETURN_ON_FAILURE(ret);
ctx->pattern += ctx->pattern[0];
break;
@@ -1094,7 +1108,7 @@ entrance:
ctx->ptr, ctx->pattern[1]));
state->ptr = ctx->ptr - ctx->pattern[1];
if (state->ptr >= state->beginning) {
- DO_JUMP(JUMP_ASSERT_NOT, jump_assert_not, ctx->pattern+2);
+ DO_JUMP0(JUMP_ASSERT_NOT, jump_assert_not, ctx->pattern+2);
if (ret) {
RETURN_ON_ERROR(ret);
RETURN_FAILURE;