Ap |void |pregfree |NULLOK REGEXP* r
Ap |void |pregfree2 |NN REGEXP *rx
: FIXME - is anything in re using this now?
-EXp |REGEXP*|reg_temp_copy |NN REGEXP* r
+EXp |REGEXP*|reg_temp_copy |NULLOK REGEXP* ret_x|NN REGEXP* rx
Ap |void |regfree_internal|NN REGEXP *const rx
#if defined(USE_ITHREADS)
Ap |void* |regdupe_internal|NN REGEXP * const r|NN CLONE_PARAMS* param
#define pregfree(a) Perl_pregfree(aTHX_ a)
#define pregfree2(a) Perl_pregfree2(aTHX_ a)
#if defined(PERL_CORE) || defined(PERL_EXT)
-#define reg_temp_copy(a) Perl_reg_temp_copy(aTHX_ a)
+#define reg_temp_copy(a,b) Perl_reg_temp_copy(aTHX_ a,b)
#endif
#define regfree_internal(a) Perl_regfree_internal(aTHX_ a)
#if defined(USE_ITHREADS)
re = (REGEXP*) sv;
}
if (re) {
- re = reg_temp_copy(re);
+ re = reg_temp_copy(NULL, re);
ReREFCNT_dec(PM_GETRE(pm));
PM_SETRE(pm, re);
}
#define PERL_ARGS_ASSERT_PREGFREE2 \
assert(rx)
-PERL_CALLCONV REGEXP* Perl_reg_temp_copy(pTHX_ REGEXP* r)
- __attribute__nonnull__(pTHX_1);
+PERL_CALLCONV REGEXP* Perl_reg_temp_copy(pTHX_ REGEXP* ret_x, REGEXP* rx)
+ __attribute__nonnull__(pTHX_2);
#define PERL_ARGS_ASSERT_REG_TEMP_COPY \
- assert(r)
+ assert(rx)
PERL_CALLCONV void Perl_regfree_internal(pTHX_ REGEXP *const rx)
__attribute__nonnull__(pTHX_1);
REGEXP *
-Perl_reg_temp_copy (pTHX_ REGEXP *rx)
+Perl_reg_temp_copy (pTHX_ REGEXP *ret_x, REGEXP *rx)
{
- REGEXP *ret_x = (REGEXP*) newSV_type(SVt_REGEXP);
- struct regexp *ret = (struct regexp *)SvANY(ret_x);
+ struct regexp *ret;
struct regexp *const r = (struct regexp *)SvANY(rx);
register const I32 npar = r->nparens+1;
PERL_ARGS_ASSERT_REG_TEMP_COPY;
+ if (!ret_x)
+ ret_x = (REGEXP*) newSV_type(SVt_REGEXP);
+ ret = (struct regexp *)SvANY(ret_x);
+
(void)ReREFCNT_inc(rx);
/* We can take advantage of the existing "copied buffer" mechanism in SVs
by pointing directly at the buffer, but flagging that the allocated
assert(rx);
}
if (rx) {
- rx = reg_temp_copy(rx);
+ rx = reg_temp_copy(NULL, rx);
}
else {
U32 pm_flags = 0;
}
/* Fall through */
#endif
- case SVt_REGEXP:
case SVt_PV:
if (dtype < SVt_PV)
sv_upgrade(dstr, SVt_PV);
}
break;
+ case SVt_REGEXP:
+ if (dtype < SVt_REGEXP)
+ sv_upgrade(dstr, SVt_REGEXP);
+ break;
+
/* case SVt_BIND: */
case SVt_PVLV:
case SVt_PVGV:
}
}
}
+ else if (dtype == SVt_REGEXP && stype == SVt_REGEXP) {
+ reg_temp_copy((REGEXP*)dstr, (REGEXP*)sstr);
+ }
else if (sflags & SVp_POK) {
bool isSwipe = 0;
require 'test.pl';
use strict qw(refs subs);
+use re ();
-plan(189);
+plan(196);
# Test glob operations.
is ($$subrefref->("GOOD"), "good");
sub mysub2 { lc shift }
+# Test REGEXP assignment
+
+{
+ my $x = qr/x/;
+ my $str = "$x"; # regex stringification may change
+
+ my $y = $$x;
+ is ($y, $str, "bare REGEXP stringifies correctly");
+ ok (eval { "x" =~ $y }, "bare REGEXP matches correctly");
+
+ my $z = \$y;
+ ok (re::is_regexp($z), "new ref to REXEXP passes is_regexp");
+ is ($z, $str, "new ref to REGEXP stringifies correctly");
+ ok (eval { "x" =~ $z }, "new ref to REGEXP matches correctly");
+}
+{
+ my ($x, $str);
+ {
+ my $y = qr/x/;
+ $str = "$y";
+ $x = $$y;
+ }
+ is ($x, $str, "REGEXP keeps a ref to its mother_re");
+ ok (eval { "x" =~ $x }, "REGEXP with mother_re still matches");
+}
+
# Test the ref operator.
sub PVBM () { 'foo' }