summaryrefslogtreecommitdiff
path: root/mg.c
diff options
context:
space:
mode:
authorYves Orton <demerphq@gmail.com>2016-10-31 22:44:31 +0100
committerYves Orton <demerphq@gmail.com>2016-11-01 13:29:48 +0100
commit27deb0cf05ad74bec9ea0da3d1b6405346a66401 (patch)
treef40af34d9d18411571c3159c6cc104729969e672 /mg.c
parentb634eb441c2bbbdbcd8dbcbbc4097658c7439a1f (diff)
downloadperl-27deb0cf05ad74bec9ea0da3d1b6405346a66401.tar.gz
new feature @{^CAPTURE} (and %{^CAPTURE} and %{^CAPTURE_ALL})
@{^CAPTURE} exposes the capture buffers of the last match as an array. So $1 is ${^CAPTURE}[0]. %{^CAPTURE} is the equivalent to %+ (ie named captures) %{^CAPTURE_ALL} is the equivalent to %- (ie all named captures).
Diffstat (limited to 'mg.c')
-rw-r--r--mg.c37
1 files changed, 25 insertions, 12 deletions
diff --git a/mg.c b/mg.c
index 238d84771c..a0ee39d234 100644
--- a/mg.c
+++ b/mg.c
@@ -471,9 +471,7 @@ Perl_mg_copy(pTHX_ SV *sv, SV *nsv, const char *key, I32 klen)
sv_magic(nsv,
(type == PERL_MAGIC_tied)
? SvTIED_obj(sv, mg)
- : (type == PERL_MAGIC_regdata && mg->mg_obj)
- ? sv
- : mg->mg_obj,
+ : mg->mg_obj,
toLOWER(type), key, klen);
count++;
}
@@ -619,12 +617,13 @@ Perl_magic_regdata_cnt(pTHX_ SV *sv, MAGIC *mg)
PERL_ARGS_ASSERT_MAGIC_REGDATA_CNT;
if (PL_curpm) {
- const REGEXP * const rx = PM_GETRE(PL_curpm);
+ REGEXP * const rx = PM_GETRE(PL_curpm);
if (rx) {
- if (mg->mg_obj) { /* @+ */
+ UV uv= (UV)mg->mg_obj;
+ if (uv == '+') { /* @+ */
/* return the number possible */
return RX_NPARENS(rx);
- } else { /* @- */
+ } else { /* @- @^CAPTURE @{^CAPTURE} */
I32 paren = RX_LASTPAREN(rx);
/* return the last filled */
@@ -632,8 +631,14 @@ Perl_magic_regdata_cnt(pTHX_ SV *sv, MAGIC *mg)
&& (RX_OFFS(rx)[paren].start == -1
|| RX_OFFS(rx)[paren].end == -1) )
paren--;
- return (U32)paren;
- }
+ if (uv == '-') {
+ /* @- */
+ return (U32)paren;
+ } else {
+ /* @^CAPTURE @{^CAPTURE} */
+ return paren >= 0 ? (U32)(paren-1) : (U32)-1;
+ }
+ }
}
}
@@ -648,9 +653,12 @@ Perl_magic_regdatum_get(pTHX_ SV *sv, MAGIC *mg)
PERL_ARGS_ASSERT_MAGIC_REGDATUM_GET;
if (PL_curpm) {
- const REGEXP * const rx = PM_GETRE(PL_curpm);
+ REGEXP * const rx = PM_GETRE(PL_curpm);
if (rx) {
- const I32 paren = mg->mg_len;
+ const UV uv= (UV)mg->mg_obj;
+ /* @{^CAPTURE} does not contain $&, so we need to increment by 1 */
+ const I32 paren = mg->mg_len
+ + (uv == '\003' ? 1 : 0);
SSize_t s;
SSize_t t;
if (paren < 0)
@@ -660,10 +668,15 @@ Perl_magic_regdatum_get(pTHX_ SV *sv, MAGIC *mg)
(t = RX_OFFS(rx)[paren].end) != -1)
{
SSize_t i;
- if (mg->mg_obj) /* @+ */
+
+ if (uv == '+') /* @+ */
i = t;
- else /* @- */
+ else if (uv == '-') /* @- */
i = s;
+ else { /* @^CAPTURE @{^CAPTURE} */
+ CALLREG_NUMBUF_FETCH(rx,paren,sv);
+ return 0;
+ }
if (RX_MATCH_UTF8(rx)) {
const char * const b = RX_SUBBEG(rx);