const char *hvname;
I32 items;
+ PERL_ARGS_ASSERT_ISA_LOOKUP;
+
/* A stash/class can go by many names (ie. User == main::User), so
we compare the stash itself just in case */
if (name_stash && ((const HV *)stash == name_stash))
*/
bool
-Perl_sv_derived_from(pTHX_ SV *sv, const char *name)
+Perl_sv_derived_from(pTHX_ SV *sv, const char *const name)
{
dVAR;
HV *stash;
+ PERL_ARGS_ASSERT_SV_DERIVED_FROM;
+
SvGETMAGIC(sv);
if (SvROK(sv)) {
#include "XSUB.h"
bool
-Perl_sv_does(pTHX_ SV *sv, const char *name)
+Perl_sv_does(pTHX_ SV *sv, const char *const name)
{
const char *classname;
bool does_it;
SV *methodname;
-
dSP;
+
+ PERL_ARGS_ASSERT_SV_DOES;
+
ENTER;
SAVETMPS;
PUSHMARK(SP);
XPUSHs(sv);
- XPUSHs(sv_2mortal(newSVpv(name, 0)));
+ mXPUSHs(newSVpv(name, 0));
PUTBACK;
- methodname = sv_2mortal(newSVpvs("isa"));
+ methodname = newSVpvs_flags("isa", SVs_TEMP);
/* ugly hack: use the SvSCREAM flag so S_method_common
* can figure out we're calling DOES() and not isa(),
* and report eventual errors correctly. --rgs */
XS(XS_re_regname);
XS(XS_re_regnames);
XS(XS_re_regnames_count);
+XS(XS_re_regexp_pattern);
XS(XS_Tie_Hash_NamedCapture_FETCH);
XS(XS_Tie_Hash_NamedCapture_STORE);
XS(XS_Tie_Hash_NamedCapture_DELETE);
newXSproto("re::regname", XS_re_regname, file, ";$$");
newXSproto("re::regnames", XS_re_regnames, file, ";$");
newXSproto("re::regnames_count", XS_re_regnames_count, file, "");
+ newXSproto("re::regexp_pattern", XS_re_regexp_pattern, file, "$");
newXS("Tie::Hash::NamedCapture::FETCH", XS_Tie_Hash_NamedCapture_FETCH, file);
newXS("Tie::Hash::NamedCapture::STORE", XS_Tie_Hash_NamedCapture_STORE, file);
newXS("Tie::Hash::NamedCapture::DELETE", XS_Tie_Hash_NamedCapture_DELETE, file);
if ( strcmp(classname,"version") != 0 ) /* inherited new() */
sv_bless(rv, gv_stashpv(classname, GV_ADD));
- PUSHs(sv_2mortal(rv));
+ mPUSHs(rv);
PUTBACK;
return;
}
else
Perl_croak(aTHX_ "lobj is not of type version");
- PUSHs(sv_2mortal(vstringify(lobj)));
+ mPUSHs(vstringify(lobj));
PUTBACK;
return;
else
Perl_croak(aTHX_ "lobj is not of type version");
- PUSHs(sv_2mortal(vnumify(lobj)));
+ mPUSHs(vnumify(lobj));
PUTBACK;
return;
else
Perl_croak(aTHX_ "lobj is not of type version");
- PUSHs(sv_2mortal(vnormal(lobj)));
+ mPUSHs(vnormal(lobj));
PUTBACK;
return;
rs = newSViv(vcmp(lobj,rvs));
}
- PUSHs(sv_2mortal(rs));
+ mPUSHs(rs);
}
PUTBACK;
if (sv_derived_from(ST(0), "version")) {
SV * const lobj = SvRV(ST(0));
SV * const rs = newSViv( vcmp(lobj,new_version(newSVpvs("0"))) );
- PUSHs(sv_2mortal(rs));
+ mPUSHs(rs);
PUTBACK;
return;
}
}
else
{
- PUSHs(sv_2mortal(new_version(ver)));
+ mPUSHs(new_version(ver));
}
PUTBACK;
}
if (gv && (io = GvIO(gv))) {
- dTARGET;
AV* const av = PerlIO_get_layers(aTHX_ input ?
IoIFP(io) : IoOFP(io));
I32 i;
const bool flgok = flgsvp && *flgsvp && SvIOK(*flgsvp);
if (details) {
+ /* Indents of 5? Yuck. */
+ /* We know that PerlIO_get_layers creates a new SV for
+ the name and flags, so we can just take a reference
+ and "steal" it when we free the AV below. */
XPUSHs(namok
- ? newSVpvn(SvPVX_const(*namsvp), SvCUR(*namsvp))
+ ? sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp))
: &PL_sv_undef);
XPUSHs(argok
- ? newSVpvn(SvPVX_const(*argsvp), SvCUR(*argsvp))
+ ? newSVpvn_flags(SvPVX_const(*argsvp),
+ SvCUR(*argsvp),
+ (SvUTF8(*argsvp) ? SVf_UTF8 : 0)
+ | SVs_TEMP)
+ : &PL_sv_undef);
+ XPUSHs(namok
+ ? sv_2mortal(SvREFCNT_inc_simple_NN(*flgsvp))
: &PL_sv_undef);
- if (flgok)
- XPUSHi(SvIVX(*flgsvp));
- else
- XPUSHs(&PL_sv_undef);
nitem += 3;
}
else {
if (namok && argok)
- XPUSHs(Perl_newSVpvf(aTHX_ "%"SVf"(%"SVf")",
+ XPUSHs(sv_2mortal(Perl_newSVpvf(aTHX_ "%"SVf"(%"SVf")",
SVfARG(*namsvp),
- SVfARG(*argsvp)));
+ SVfARG(*argsvp))));
else if (namok)
- XPUSHs(Perl_newSVpvf(aTHX_ "%"SVf,
- SVfARG(*namsvp)));
+ XPUSHs(sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp)));
else
XPUSHs(&PL_sv_undef);
nitem++;
const IV flags = SvIVX(*flgsvp);
if (flags & PERLIO_F_UTF8) {
- XPUSHs(newSVpvs("utf8"));
+ XPUSHs(newSVpvs_flags("utf8", SVs_TEMP));
nitem++;
}
}
return;
}
+XS(XS_re_regexp_pattern)
+{
+ dVAR;
+ dXSARGS;
+ REGEXP *re;
+ PERL_UNUSED_ARG(cv);
+
+ if (items != 1)
+ Perl_croak(aTHX_ "Usage: %s(%s)", "re::regexp_pattern", "sv");
+
+ SP -= items;
+
+ /*
+ Checks if a reference is a regex or not. If the parameter is
+ not a ref, or is not the result of a qr// then returns false
+ in scalar context and an empty list in list context.
+ Otherwise in list context it returns the pattern and the
+ modifiers, in scalar context it returns the pattern just as it
+ would if the qr// was stringified normally, regardless as
+ to the class of the variable and any strigification overloads
+ on the object.
+ */
+
+ if ((re = SvRX(ST(0)))) /* assign deliberate */
+ {
+ /* Housten, we have a regex! */
+ SV *pattern;
+ STRLEN left = 0;
+ char reflags[6];
+
+ if ( GIMME_V == G_ARRAY ) {
+ /*
+ we are in list context so stringify
+ the modifiers that apply. We ignore "negative
+ modifiers" in this scenario.
+ */
+
+ const char *fptr = INT_PAT_MODS;
+ char ch;
+ U16 match_flags = (U16)((RX_EXTFLAGS(re) & PMf_COMPILETIME)
+ >> RXf_PMf_STD_PMMOD_SHIFT);
+
+ while((ch = *fptr++)) {
+ if(match_flags & 1) {
+ reflags[left++] = ch;
+ }
+ match_flags >>= 1;
+ }
+
+ pattern = newSVpvn_flags(RX_PRECOMP(re),RX_PRELEN(re),
+ (RX_UTF8(re) ? SVf_UTF8 : 0) | SVs_TEMP);
+
+ /* return the pattern and the modifiers */
+ XPUSHs(pattern);
+ XPUSHs(newSVpvn_flags(reflags, left, SVs_TEMP));
+ XSRETURN(2);
+ } else {
+ /* Scalar, so use the string that Perl would return */
+ /* return the pattern in (?msix:..) format */
+#if PERL_VERSION >= 11
+ pattern = sv_2mortal(newSVsv((SV*)re));
+#else
+ pattern = newSVpvn_flags(RX_WRAPPED(re), RX_WRAPLEN(re),
+ (RX_UTF8(re) ? SVf_UTF8 : 0) | SVs_TEMP);
+#endif
+ XPUSHs(pattern);
+ XSRETURN(1);
+ }
+ } else {
+ /* It ain't a regexp folks */
+ if ( GIMME_V == G_ARRAY ) {
+ /* return the empty list */
+ XSRETURN_UNDEF;
+ } else {
+ /* Because of the (?:..) wrapping involved in a
+ stringified pattern it is impossible to get a
+ result for a real regexp that would evaluate to
+ false. Therefore we can return PL_sv_no to signify
+ that the object is not a regex, this means that one
+ can say
+
+ if (regex($might_be_a_regex) eq '(?:foo)') { }
+
+ and not worry about undefined values.
+ */
+ XSRETURN_NO;
+ }
+ }
+ /* NOT-REACHED */
+}
+
XS(XS_Tie_Hash_NamedCapture_FETCH)
{
dVAR;
if (items != 0)
Perl_croak(aTHX_ "Usage: Tie::Hash::NamedCapture::flags()");
- XPUSHs(sv_2mortal(newSVuv(RXapif_ONE)));
- XPUSHs(sv_2mortal(newSVuv(RXapif_ALL)));
+ mXPUSHu(RXapif_ONE);
+ mXPUSHu(RXapif_ALL);
PUTBACK;
return;
}