diff options
author | David Mitchell <davem@iabyn.com> | 2012-07-26 15:35:39 +0100 |
---|---|---|
committer | David Mitchell <davem@iabyn.com> | 2012-09-08 15:42:06 +0100 |
commit | 2c7b5d7698f52b86acffe19a7ec15e85c99337fe (patch) | |
tree | 5ebca5ec9ae16235bc7d69b64bbd2bfbabcee1f9 /mg.c | |
parent | ac0ba89f3ee4e5469c43dc0a34b548a9aa415f98 (diff) | |
download | perl-2c7b5d7698f52b86acffe19a7ec15e85c99337fe.tar.gz |
Separate handling of ${^PREMATCH} from $` etc
Currently the handling of getting the value, length etc of ${^PREMATCH}
etc is identical to that of $` etc.
Handle them separately, by adding RX_BUFF_IDX_CARET_PREMATCH etc
constants to the existing RX_BUFF_IDX_PREMATCH set.
This allows, when retrieving them, to always return undef if the current
match didn't use //p. Previously the result depended on stuff such
as whether the (non-//p) pattern included captures or not.
The documentation for ${^PREMATCH} etc states that it's only guaranteed to
return a defined value when the last pattern was //p.
As well as making things more consistent, this is a necessary
prerequisite for the following commit, which may not always copy the
whole string during a non-//p match.
Diffstat (limited to 'mg.c')
-rw-r--r-- | mg.c | 66 |
1 files changed, 30 insertions, 36 deletions
@@ -913,9 +913,12 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) if (nextchar == '\0') { /* ^P */ sv_setiv(sv, (IV)PL_perldb); } else if (strEQ(remaining, "REMATCH")) { /* $^PREMATCH */ - goto do_prematch_fetch; + + paren = RX_BUFF_IDX_CARET_PREMATCH; + goto do_numbuf_fetch; } else if (strEQ(remaining, "OSTMATCH")) { /* $^POSTMATCH */ - goto do_postmatch_fetch; + paren = RX_BUFF_IDX_CARET_POSTMATCH; + goto do_numbuf_fetch; } break; case '\023': /* ^S */ @@ -978,55 +981,46 @@ Perl_magic_get(pTHX_ SV *sv, MAGIC *mg) break; case '\015': /* $^MATCH */ if (strEQ(remaining, "ATCH")) { + paren = RX_BUFF_IDX_CARET_FULLMATCH; + goto do_numbuf_fetch; + } + case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '&': - if (PL_curpm && (rx = PM_GETRE(PL_curpm))) { - /* - * Pre-threads, this was paren = atoi(GvENAME((const GV *)mg->mg_obj)); - * XXX Does the new way break anything? - */ - paren = atoi(mg->mg_ptr); /* $& is in [0] */ - CALLREG_NUMBUF_FETCH(rx,paren,sv); - break; - } - sv_setsv(sv,&PL_sv_undef); - } + /* + * Pre-threads, this was paren = atoi(GvENAME((const GV *)mg->mg_obj)); + * XXX Does the new way break anything? + */ + paren = atoi(mg->mg_ptr); /* $& is in [0] */ + do_numbuf_fetch: + if (PL_curpm && (rx = PM_GETRE(PL_curpm))) { + CALLREG_NUMBUF_FETCH(rx,paren,sv); + break; + } + sv_setsv(sv,&PL_sv_undef); break; case '+': if (PL_curpm && (rx = PM_GETRE(PL_curpm))) { - if (RX_LASTPAREN(rx)) { - CALLREG_NUMBUF_FETCH(rx,RX_LASTPAREN(rx),sv); - break; - } + paren = RX_LASTPAREN(rx); + if (paren) + goto do_numbuf_fetch; } sv_setsv(sv,&PL_sv_undef); break; case '\016': /* ^N */ if (PL_curpm && (rx = PM_GETRE(PL_curpm))) { - if (RX_LASTCLOSEPAREN(rx)) { - CALLREG_NUMBUF_FETCH(rx,RX_LASTCLOSEPAREN(rx),sv); - break; - } - + paren = RX_LASTCLOSEPAREN(rx); + if (paren) + goto do_numbuf_fetch; } sv_setsv(sv,&PL_sv_undef); break; case '`': - do_prematch_fetch: - if (PL_curpm && (rx = PM_GETRE(PL_curpm))) { - CALLREG_NUMBUF_FETCH(rx,-2,sv); - break; - } - sv_setsv(sv,&PL_sv_undef); - break; + paren = RX_BUFF_IDX_PREMATCH; + goto do_numbuf_fetch; case '\'': - do_postmatch_fetch: - if (PL_curpm && (rx = PM_GETRE(PL_curpm))) { - CALLREG_NUMBUF_FETCH(rx,-1,sv); - break; - } - sv_setsv(sv,&PL_sv_undef); - break; + paren = RX_BUFF_IDX_POSTMATCH; + goto do_numbuf_fetch; case '.': if (GvIO(PL_last_in_gv)) { sv_setiv(sv, (IV)IoLINES(GvIOp(PL_last_in_gv))); |