diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2013-11-23 21:20:30 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2013-11-23 21:20:30 (GMT) |
commit | 32eddc1bbc47479a3639b9191ffc82a52903c5f4 (patch) | |
tree | 8ce67ed6f7d6db96277f4e6d07457f2b159fb362 /Modules/sre_lib.h | |
parent | 3ed82c55a85665a33b821064c1911b4aa09301d9 (diff) | |
download | cpython-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.h | 28 |
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; |