/* universal.c
*
* Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
- * 2005, 2006, 2007 by Larry Wall and others
+ * 2005, 2006, 2007, 2008 by Larry Wall and others
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
*/
/*
- * "The roots of those mountains must be roots indeed; there must be
- * great secrets buried there which have not been discovered since the
- * beginning." --Gandalf, relating Gollum's story
+ * '"The roots of those mountains must be roots indeed; there must be
+ * great secrets buried there which have not been discovered since the
+ * beginning."' --Gandalf, relating Gollum's history
+ *
+ * [p.54 of _The Lord of the Rings_, I/ii: "The Shadow of the Past"]
*/
/* This file contains the code that implements the functions in Perl's
#include "perliol.h" /* For the PERLIO_F_XXX */
#endif
+static HV *
+S_get_isa_hash(pTHX_ HV *const stash)
+{
+ dVAR;
+ struct mro_meta *const meta = HvMROMETA(stash);
+
+ PERL_ARGS_ASSERT_GET_ISA_HASH;
+
+ if (!meta->isa) {
+ AV *const isa = mro_get_linear_isa(stash);
+ if (!meta->isa) {
+ HV *const isa_hash = newHV();
+ /* Linearisation didn't build it for us, so do it here. */
+ SV *const *svp = AvARRAY(isa);
+ SV *const *const svp_end = svp + AvFILLp(isa) + 1;
+ const HEK *const canon_name = HvNAME_HEK(stash);
+
+ while (svp < svp_end) {
+ (void) hv_store_ent(isa_hash, *svp++, &PL_sv_undef, 0);
+ }
+
+ (void) hv_common(isa_hash, NULL, HEK_KEY(canon_name),
+ HEK_LEN(canon_name), HEK_FLAGS(canon_name),
+ HV_FETCH_ISSTORE, &PL_sv_undef,
+ HEK_HASH(canon_name));
+ (void) hv_store(isa_hash, "UNIVERSAL", 9, &PL_sv_undef, 0);
+
+ SvREADONLY_on(isa_hash);
+
+ meta->isa = isa_hash;
+ }
+ }
+ return meta->isa;
+}
+
/*
* Contributed by Graham Barr <Graham.Barr@tiuk.ti.com>
* The main guts of traverse_isa was actually copied from gv_fetchmeth
*/
STATIC bool
-S_isa_lookup(pTHX_ HV *stash, const char * const name, const HV* const name_stash)
+S_isa_lookup(pTHX_ HV *stash, const char * const name)
{
dVAR;
- AV* stash_linear_isa;
- SV** svp;
- const char *hvname;
- I32 items;
-
- /* 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))
- return TRUE;
+ const struct mro_meta *const meta = HvMROMETA(stash);
+ HV *const isa = meta->isa ? meta->isa : S_get_isa_hash(aTHX_ stash);
+ STRLEN len = strlen(name);
+ const HV *our_stash;
- hvname = HvNAME_get(stash);
+ PERL_ARGS_ASSERT_ISA_LOOKUP;
- if (strEQ(hvname, name))
+ if (hv_common(isa, NULL, name, len, 0 /* No "UTF-8" flag possible with only
+ a char * argument*/,
+ HV_FETCH_ISEXISTS, NULL, 0)) {
+ /* Direct name lookup worked. */
return TRUE;
+ }
- if (strEQ(name, "UNIVERSAL"))
- return TRUE;
+ /* A stash/class can go by many names (ie. User == main::User), so
+ we use the name in the stash itself, which is canonical. */
+ our_stash = gv_stashpvn(name, len, 0);
- stash_linear_isa = mro_get_linear_isa(stash);
- svp = AvARRAY(stash_linear_isa) + 1;
- items = AvFILLp(stash_linear_isa);
- while (items--) {
- SV* const basename_sv = *svp++;
- HV* const basestash = gv_stashsv(basename_sv, 0);
- if (!basestash) {
- if (ckWARN(WARN_SYNTAX))
- Perl_warner(aTHX_ packWARN(WARN_SYNTAX),
- "Can't locate package %"SVf" for the parents of %s",
- SVfARG(basename_sv), hvname);
- continue;
- }
- if(name_stash == basestash || strEQ(name, SvPVX(basename_sv)))
+ if (our_stash) {
+ HEK *const canon_name = HvNAME_HEK(our_stash);
+
+ if (hv_common(isa, NULL, HEK_KEY(canon_name), HEK_LEN(canon_name),
+ HEK_FLAGS(canon_name),
+ HV_FETCH_ISEXISTS, NULL, HEK_HASH(canon_name))) {
return TRUE;
+ }
}
return FALSE;
dVAR;
HV *stash;
+ PERL_ARGS_ASSERT_SV_DERIVED_FROM;
+
SvGETMAGIC(sv);
if (SvROK(sv)) {
stash = gv_stashsv(sv, 0);
}
- if (stash) {
- HV * const name_stash = gv_stashpv(name, 0);
- return isa_lookup(stash, name, name_stash);
- }
- else
- return FALSE;
-
+ return stash ? isa_lookup(stash, name) : FALSE;
}
/*
const char *classname;
bool does_it;
SV *methodname;
-
dSP;
+
+ PERL_ARGS_ASSERT_SV_DOES;
+
ENTER;
SAVETMPS;
#endif
XS(XS_version_is_alpha);
XS(XS_version_qv);
+XS(XS_version_is_qv);
XS(XS_utf8_is_utf8);
XS(XS_utf8_valid);
XS(XS_utf8_encode);
XS(XS_Internals_SvREFCNT);
XS(XS_Internals_hv_clear_placehold);
XS(XS_PerlIO_get_layers);
-XS(XS_Regexp_DESTROY);
XS(XS_Internals_hash_seed);
XS(XS_Internals_rehash_seed);
XS(XS_Internals_HvREHASH);
-XS(XS_Internals_inc_sub_generation);
XS(XS_re_is_regexp);
XS(XS_re_regname);
XS(XS_re_regnames);
/* Make it findable via fetchmethod */
newXS("version::()", XS_version_noop, file);
newXS("version::new", XS_version_new, file);
+ newXS("version::parse", XS_version_new, file);
newXS("version::(\"\"", XS_version_stringify, file);
newXS("version::stringify", XS_version_stringify, file);
newXS("version::(0+", XS_version_numify, file);
newXS("version::noop", XS_version_noop, file);
newXS("version::is_alpha", XS_version_is_alpha, file);
newXS("version::qv", XS_version_qv, file);
+ newXS("version::declare", XS_version_qv, file);
+ newXS("version::is_qv", XS_version_is_qv, file);
}
newXS("utf8::is_utf8", XS_utf8_is_utf8, file);
newXS("utf8::valid", XS_utf8_valid, file);
XS_Internals_hv_clear_placehold, file, "\\%");
newXSproto("PerlIO::get_layers",
XS_PerlIO_get_layers, file, "*;@");
- newXS("Regexp::DESTROY", XS_Regexp_DESTROY, file);
+ /* Providing a Regexp::DESTROY fixes #21347. See test in t/op/ref.t */
+ CvFILE(newCONSTSUB(get_hv("Regexp::", GV_ADD), "DESTROY", NULL))
+ = (char *)file;
newXSproto("Internals::hash_seed",XS_Internals_hash_seed, file, "");
newXSproto("Internals::rehash_seed",XS_Internals_rehash_seed, file, "");
newXSproto("Internals::HvREHASH", XS_Internals_HvREHASH, file, "\\%");
newXS("Tie::Hash::NamedCapture::flags", XS_Tie_Hash_NamedCapture_flags, file);
}
+/*
+=for apidoc croak_xs_usage
+
+A specialised variant of C<croak()> for emitting the usage message for xsubs
+
+ croak_xs_usage(cv, "eee_yow");
+
+works out the package name and subroutine name from C<cv>, and then calls
+C<croak()>. Hence if C<cv> is C<&ouch::awk>, it would call C<croak> as:
+
+ Perl_croak(aTHX_ "Usage %s::%s(%s)", "ouch" "awk", "eee_yow");
+
+=cut
+*/
+
+void
+Perl_croak_xs_usage(pTHX_ const CV *const cv, const char *const params)
+{
+ const GV *const gv = CvGV(cv);
+
+ PERL_ARGS_ASSERT_CROAK_XS_USAGE;
+
+ if (gv) {
+ const char *const gvname = GvNAME(gv);
+ const HV *const stash = GvSTASH(gv);
+ const char *const hvname = stash ? HvNAME_get(stash) : NULL;
+
+ if (hvname)
+ Perl_croak(aTHX_ "Usage: %s::%s(%s)", hvname, gvname, params);
+ else
+ Perl_croak(aTHX_ "Usage: %s(%s)", gvname, params);
+ } else {
+ /* Pants. I don't think that it should be possible to get here. */
+ Perl_croak(aTHX_ "Usage: CODE(0x%"UVxf")(%s)", PTR2UV(cv), params);
+ }
+}
XS(XS_UNIVERSAL_isa)
{
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items != 2)
- Perl_croak(aTHX_ "Usage: UNIVERSAL::isa(reference, kind)");
+ croak_xs_usage(cv, "reference, kind");
else {
SV * const sv = ST(0);
const char *name;
const char *name;
SV *rv;
HV *pkg = NULL;
- PERL_UNUSED_ARG(cv);
if (items != 2)
- Perl_croak(aTHX_ "Usage: UNIVERSAL::can(object-ref, method)");
+ croak_xs_usage(cv, "object-ref, method");
sv = ST(0);
rv = &PL_sv_undef;
if (SvROK(sv)) {
- sv = (SV*)SvRV(sv);
+ sv = MUTABLE_SV(SvRV(sv));
if (SvOBJECT(sv))
pkg = SvSTASH(sv);
}
if (pkg) {
GV * const gv = gv_fetchmethod_autoload(pkg, name, FALSE);
if (gv && isGV(gv))
- rv = sv_2mortal(newRV((SV*)GvCV(gv)));
+ rv = sv_2mortal(newRV(MUTABLE_SV(GvCV(gv))));
}
ST(0) = rv;
PERL_UNUSED_ARG(cv);
if (SvROK(ST(0))) {
- sv = (SV*)SvRV(ST(0));
+ sv = MUTABLE_SV(SvRV(ST(0)));
if (!SvOBJECT(sv))
Perl_croak(aTHX_ "Cannot find version of an unblessed reference");
pkg = SvSTASH(sv);
undef = NULL;
}
else {
- sv = (SV*)&PL_sv_undef;
+ sv = &PL_sv_undef;
undef = "(undef)";
}
}
if ( vcmp( req, sv ) > 0 ) {
- if ( hv_exists((HV*)SvRV(req), "qv", 2 ) ) {
+ if ( hv_exists(MUTABLE_HV(SvRV(req)), "qv", 2 ) ) {
Perl_croak(aTHX_ "%s version %"SVf" required--"
"this is only version %"SVf"", HvNAME_get(pkg),
SVfARG(vnormal(req)),
{
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items > 3)
- Perl_croak(aTHX_ "Usage: version::new(class, version)");
+ croak_xs_usage(cv, "class, version");
SP -= items;
{
SV *vs = ST(1);
if ( items == 1 || vs == &PL_sv_undef ) { /* no param or explicit undef */
/* create empty object */
vs = sv_newmortal();
- sv_setpvn(vs,"",0);
+ sv_setpvs(vs,"");
}
else if ( items == 3 ) {
vs = sv_newmortal();
{
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items < 1)
- Perl_croak(aTHX_ "Usage: version::stringify(lobj, ...)");
+ croak_xs_usage(cv, "lobj, ...");
SP -= items;
{
SV * lobj;
{
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items < 1)
- Perl_croak(aTHX_ "Usage: version::numify(lobj, ...)");
+ croak_xs_usage(cv, "lobj, ...");
SP -= items;
{
SV * lobj;
{
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items < 1)
- Perl_croak(aTHX_ "Usage: version::normal(lobj, ...)");
+ croak_xs_usage(cv, "lobj, ...");
SP -= items;
{
SV * lobj;
{
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items < 1)
- Perl_croak(aTHX_ "Usage: version::vcmp(lobj, ...)");
+ croak_xs_usage(cv, "lobj, ...");
SP -= items;
{
SV * lobj;
{
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items < 1)
- Perl_croak(aTHX_ "Usage: version::boolean(lobj, ...)");
+ croak_xs_usage(cv, "lobj, ...");
SP -= items;
if (sv_derived_from(ST(0), "version")) {
SV * const lobj = SvRV(ST(0));
{
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items < 1)
- Perl_croak(aTHX_ "Usage: version::noop(lobj, ...)");
+ croak_xs_usage(cv, "lobj, ...");
if (sv_derived_from(ST(0), "version"))
Perl_croak(aTHX_ "operation not supported with version object");
else
{
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items != 1)
- Perl_croak(aTHX_ "Usage: version::is_alpha(lobj)");
+ croak_xs_usage(cv, "lobj");
SP -= items;
if (sv_derived_from(ST(0), "version")) {
SV * const lobj = ST(0);
- if ( hv_exists((HV*)SvRV(lobj), "alpha", 5 ) )
+ if ( hv_exists(MUTABLE_HV(SvRV(lobj)), "alpha", 5 ) )
XSRETURN_YES;
else
XSRETURN_NO;
dVAR;
dXSARGS;
PERL_UNUSED_ARG(cv);
- if (items != 1)
- Perl_croak(aTHX_ "Usage: version::qv(ver)");
SP -= items;
{
- SV * ver = ST(0);
- if ( !SvVOK(ver) ) { /* only need to do with if not already v-string */
- SV * const rv = sv_newmortal();
+ SV * ver = ST(0);
+ SV * rv;
+ const char * classname = "";
+ if ( items == 2 && (ST(1)) != &PL_sv_undef ) {
+ /* getting called as object or class method */
+ ver = ST(1);
+ classname =
+ sv_isobject(ST(0)) /* class called as an object method */
+ ? HvNAME_get(SvSTASH(SvRV(ST(0))))
+ : (char *)SvPV_nolen(ST(0));
+ }
+ if ( !SvVOK(ver) ) { /* not already a v-string */
+ rv = sv_newmortal();
sv_setsv(rv,ver); /* make a duplicate */
upg_version(rv, TRUE);
- PUSHs(rv);
+ } else {
+ rv = sv_2mortal(new_version(ver));
}
- else
- {
- mPUSHs(new_version(ver));
+ if ( items == 2 && strcmp(classname,"version") ) { /* inherited new() */
+ sv_bless(rv, gv_stashpv(classname, GV_ADD));
}
+ PUSHs(rv);
+ }
+ PUTBACK;
+ return;
+}
+XS(XS_version_is_qv)
+{
+ dVAR;
+ dXSARGS;
+ if (items != 1)
+ croak_xs_usage(cv, "lobj");
+ SP -= items;
+ if (sv_derived_from(ST(0), "version")) {
+ SV * const lobj = ST(0);
+ if ( hv_exists(MUTABLE_HV(SvRV(lobj)), "qv", 2 ) )
+ XSRETURN_YES;
+ else
+ XSRETURN_NO;
PUTBACK;
return;
}
+ else
+ Perl_croak(aTHX_ "lobj is not of type version");
}
XS(XS_utf8_is_utf8)
{
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items != 1)
- Perl_croak(aTHX_ "Usage: utf8::is_utf8(sv)");
+ croak_xs_usage(cv, "sv");
else {
const SV * const sv = ST(0);
if (SvUTF8(sv))
{
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items != 1)
- Perl_croak(aTHX_ "Usage: utf8::valid(sv)");
+ croak_xs_usage(cv, "sv");
else {
SV * const sv = ST(0);
STRLEN len;
{
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items != 1)
- Perl_croak(aTHX_ "Usage: utf8::encode(sv)");
+ croak_xs_usage(cv, "sv");
sv_utf8_encode(ST(0));
XSRETURN_EMPTY;
}
{
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items != 1)
- Perl_croak(aTHX_ "Usage: utf8::decode(sv)");
+ croak_xs_usage(cv, "sv");
else {
SV * const sv = ST(0);
const bool RETVAL = sv_utf8_decode(sv);
{
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items != 1)
- Perl_croak(aTHX_ "Usage: utf8::upgrade(sv)");
+ croak_xs_usage(cv, "sv");
else {
SV * const sv = ST(0);
STRLEN RETVAL;
{
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items < 1 || items > 2)
- Perl_croak(aTHX_ "Usage: utf8::downgrade(sv, failok=0)");
+ croak_xs_usage(cv, "sv, failok=0");
else {
SV * const sv = ST(0);
const bool failok = (items < 2) ? 0 : (int)SvIV(ST(1));
dVAR;
dXSARGS;
const UV uv = SvUV(ST(0));
- PERL_UNUSED_ARG(cv);
if (items > 1)
- Perl_croak(aTHX_ "Usage: utf8::native_to_unicode(sv)");
+ croak_xs_usage(cv, "sv");
ST(0) = sv_2mortal(newSViv(NATIVE_TO_UNI(uv)));
XSRETURN(1);
dVAR;
dXSARGS;
const UV uv = SvUV(ST(0));
- PERL_UNUSED_ARG(cv);
if (items > 1)
- Perl_croak(aTHX_ "Usage: utf8::unicode_to_native(sv)");
+ croak_xs_usage(cv, "sv");
ST(0) = sv_2mortal(newSViv(UNI_TO_NATIVE(uv)));
XSRETURN(1);
{
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items != 1)
- Perl_croak(aTHX_ "Usage: UNIVERSAL::hv_clear_placeholders(hv)");
+ croak_xs_usage(cv, "hv");
else {
- HV * const hv = (HV *) SvRV(ST(0));
+ HV * const hv = MUTABLE_HV(SvRV(ST(0)));
hv_clear_placeholders(hv);
XSRETURN(0);
}
}
-XS(XS_Regexp_DESTROY)
-{
- PERL_UNUSED_CONTEXT;
- PERL_UNUSED_ARG(cv);
-}
-
XS(XS_PerlIO_get_layers)
{
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items < 1 || items % 2 == 0)
- Perl_croak(aTHX_ "Usage: PerlIO_get_layers(filehandle[,args])");
+ croak_xs_usage(cv, "filehandle[,args]");
#ifdef USE_PERLIO
{
SV * sv;
}
sv = POPs;
- gv = (GV*)sv;
+ gv = MUTABLE_GV(sv);
if (!isGV(sv)) {
if (SvROK(sv) && isGV(SvRV(sv)))
- gv = (GV*)SvRV(sv);
+ gv = MUTABLE_GV(SvRV(sv));
else if (SvPOKp(sv))
gv = gv_fetchsv(sv, 0, SVt_PVIO);
}
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
- ? sv_2mortal(newSVpvn(SvPVX_const(*namsvp), SvCUR(*namsvp)))
+ ? sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp))
: &PL_sv_undef);
XPUSHs(argok
- ? sv_2mortal(newSVpvn(SvPVX_const(*argsvp), SvCUR(*argsvp)))
+ ? newSVpvn_flags(SvPVX_const(*argsvp),
+ SvCUR(*argsvp),
+ (SvUTF8(*argsvp) ? SVf_UTF8 : 0)
+ | SVs_TEMP)
+ : &PL_sv_undef);
+ XPUSHs(flgok
+ ? sv_2mortal(SvREFCNT_inc_simple_NN(*flgsvp))
: &PL_sv_undef);
- if (flgok)
- mXPUSHi(SvIVX(*flgsvp));
- else
- XPUSHs(&PL_sv_undef);
nitem += 3;
}
else {
SVfARG(*namsvp),
SVfARG(*argsvp))));
else if (namok)
- XPUSHs(sv_2mortal(Perl_newSVpvf(aTHX_ "%"SVf,
- SVfARG(*namsvp))));
+ XPUSHs(sv_2mortal(SvREFCNT_inc_simple_NN(*namsvp)));
else
XPUSHs(&PL_sv_undef);
nitem++;
dXSARGS;
PERL_UNUSED_ARG(cv);
if (SvROK(ST(0))) {
- const HV * const hv = (HV *) SvRV(ST(0));
+ const HV * const hv = (const HV *) SvRV(ST(0));
if (items == 1 && SvTYPE(hv) == SVt_PVHV) {
if (HvREHASH(hv))
XSRETURN_YES;
PERL_UNUSED_VAR(cv);
if (items != 1)
- Perl_croak(aTHX_ "Usage: %s(%s)", "re::is_regexp", "sv");
+ croak_xs_usage(cv, "sv");
SP -= items;
SV * ret;
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items != 0)
- Perl_croak(aTHX_ "Usage: %s(%s)", "re::regnames_count", "");
+ croak_xs_usage(cv, "");
SP -= items;
SPAGAIN;
if (ret) {
- XPUSHs(ret);
+ mXPUSHs(ret);
PUTBACK;
return;
} else {
REGEXP * rx;
U32 flags;
SV * ret;
- PERL_UNUSED_ARG(cv);
if (items < 1 || items > 2)
- Perl_croak(aTHX_ "Usage: %s(%s)", "re::regname", "name[, all ]");
+ croak_xs_usage(cv, "name[, all ]");
SP -= items;
ret = CALLREG_NAMED_BUFF_FETCH(rx, ST(0), (flags | RXapif_REGNAME));
if (ret) {
- if (SvROK(ret))
- XPUSHs(ret);
- else
- XPUSHs(SvREFCNT_inc(ret));
+ mXPUSHs(ret);
XSRETURN(1);
}
XSRETURN_UNDEF;
I32 length;
I32 i;
SV **entry;
- PERL_UNUSED_ARG(cv);
if (items > 1)
- Perl_croak(aTHX_ "Usage: %s(%s)", "re::regnames", "[all]");
+ croak_xs_usage(cv, "[all]");
rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
if (!ret)
XSRETURN_UNDEF;
- av = (AV*)SvRV(ret);
+ av = MUTABLE_AV(SvRV(ret));
length = av_len(av);
for (i = 0; i <= length; i++) {
if (!entry)
Perl_croak(aTHX_ "NULL array element in re::regnames()");
- XPUSHs(*entry);
+ mXPUSHs(SvREFCNT_inc_simple_NN(*entry));
}
+
+ SvREFCNT_dec(ret);
+
PUTBACK;
return;
}
dVAR;
dXSARGS;
REGEXP *re;
- PERL_UNUSED_ARG(cv);
if (items != 1)
- Perl_croak(aTHX_ "Usage: %s(%s)", "re::regexp_pattern", "sv");
+ croak_xs_usage(cv, "sv");
SP -= items;
match_flags >>= 1;
}
- pattern = sv_2mortal(newSVpvn(RX_PRECOMP(re),RX_PRELEN(re)));
- if (RX_UTF8(re))
- SvUTF8_on(pattern);
+ 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(sv_2mortal(newSVpvn(reflags,left)));
+ 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));
+ pattern = sv_2mortal(newSVsv(MUTABLE_SV(re)));
#else
- pattern = sv_2mortal(newSVpvn(RX_WRAPPED(re),RX_WRAPLEN(re)));
- if (RX_UTF8(re))
- SvUTF8_on(pattern);
+ pattern = newSVpvn_flags(RX_WRAPPED(re), RX_WRAPLEN(re),
+ (RX_UTF8(re) ? SVf_UTF8 : 0) | SVs_TEMP);
#endif
XPUSHs(pattern);
XSRETURN(1);
REGEXP * rx;
U32 flags;
SV * ret;
- PERL_UNUSED_ARG(cv);
if (items != 2)
- Perl_croak(aTHX_ "Usage: Tie::Hash::NamedCapture::STORE($key, $flags)");
+ croak_xs_usage(cv, "$key, $flags");
rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
SP -= items;
- flags = (U32)INT2PTR(IV,SvIV(SvRV((SV*)ST(0))));
+ flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
ret = CALLREG_NAMED_BUFF_FETCH(rx, ST(1), flags);
SPAGAIN;
if (ret) {
- if (SvROK(ret))
- XPUSHs(ret);
- else
- XPUSHs(SvREFCNT_inc(ret));
+ mXPUSHs(ret);
PUTBACK;
return;
}
dXSARGS;
REGEXP * rx;
U32 flags;
- PERL_UNUSED_ARG(cv);
if (items != 3)
- Perl_croak(aTHX_ "Usage: Tie::Hash::NamedCapture::STORE($key, $value, $flags)");
+ croak_xs_usage(cv, "$key, $value, $flags");
rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
if (!rx) {
if (!PL_localizing)
- Perl_croak(aTHX_ PL_no_modify);
+ Perl_croak(aTHX_ "%s", PL_no_modify);
else
XSRETURN_UNDEF;
}
SP -= items;
- flags = (U32)INT2PTR(IV,SvIV(SvRV((SV*)ST(0))));
+ flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
CALLREG_NAMED_BUFF_STORE(rx,ST(1), ST(2), flags);
}
dXSARGS;
REGEXP * rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
U32 flags;
- PERL_UNUSED_ARG(cv);
if (items != 2)
- Perl_croak(aTHX_ "Usage: Tie::Hash::NamedCapture::DELETE($key, $flags)");
+ croak_xs_usage(cv, "$key, $flags");
if (!rx)
- Perl_croak(aTHX_ PL_no_modify);
+ Perl_croak(aTHX_ "%s", PL_no_modify);
SP -= items;
- flags = (U32)INT2PTR(IV,SvIV(SvRV((SV*)ST(0))));
+ flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
CALLREG_NAMED_BUFF_DELETE(rx, ST(1), flags);
}
dXSARGS;
REGEXP * rx;
U32 flags;
- PERL_UNUSED_ARG(cv);
if (items != 1)
- Perl_croak(aTHX_ "Usage: Tie::Hash::NamedCapture::CLEAR($flags)");
+ croak_xs_usage(cv, "$flags");
rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
if (!rx)
- Perl_croak(aTHX_ PL_no_modify);
+ Perl_croak(aTHX_ "%s", PL_no_modify);
SP -= items;
- flags = (U32)INT2PTR(IV,SvIV(SvRV((SV*)ST(0))));
+ flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
CALLREG_NAMED_BUFF_CLEAR(rx, flags);
}
REGEXP * rx;
U32 flags;
SV * ret;
- PERL_UNUSED_ARG(cv);
if (items != 2)
- Perl_croak(aTHX_ "Usage: Tie::Hash::NamedCapture::EXISTS($key, $flags)");
+ croak_xs_usage(cv, "$key, $flags");
rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
SP -= items;
- flags = (U32)INT2PTR(IV,SvIV(SvRV((SV*)ST(0))));
+ flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
ret = CALLREG_NAMED_BUFF_EXISTS(rx, ST(1), flags);
SPAGAIN;
REGEXP * rx;
U32 flags;
SV * ret;
- PERL_UNUSED_ARG(cv);
if (items != 1)
- Perl_croak(aTHX_ "Usage: Tie::Hash::NamedCapture::FIRSTKEY()");
+ croak_xs_usage(cv, "");
rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
SP -= items;
- flags = (U32)INT2PTR(IV,SvIV(SvRV((SV*)ST(0))));
+ flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
ret = CALLREG_NAMED_BUFF_FIRSTKEY(rx, flags);
SPAGAIN;
if (ret) {
- XPUSHs(SvREFCNT_inc(ret));
+ mXPUSHs(ret);
PUTBACK;
} else {
XSRETURN_UNDEF;
REGEXP * rx;
U32 flags;
SV * ret;
- PERL_UNUSED_ARG(cv);
if (items != 2)
- Perl_croak(aTHX_ "Usage: Tie::Hash::NamedCapture::NEXTKEY($lastkey)");
+ croak_xs_usage(cv, "$lastkey");
rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
SP -= items;
- flags = (U32)INT2PTR(IV,SvIV(SvRV((SV*)ST(0))));
+ flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
ret = CALLREG_NAMED_BUFF_NEXTKEY(rx, ST(1), flags);
SPAGAIN;
if (ret) {
- XPUSHs(ret);
+ mXPUSHs(ret);
} else {
XSRETURN_UNDEF;
}
REGEXP * rx;
U32 flags;
SV * ret;
- PERL_UNUSED_ARG(cv);
if (items != 1)
- Perl_croak(aTHX_ "Usage: Tie::Hash::NamedCapture::SCALAR()");
+ croak_xs_usage(cv, "");
rx = PL_curpm ? PM_GETRE(PL_curpm) : NULL;
SP -= items;
- flags = (U32)INT2PTR(IV,SvIV(SvRV((SV*)ST(0))));
+ flags = (U32)INT2PTR(IV,SvIV(SvRV(MUTABLE_SV(ST(0)))));
ret = CALLREG_NAMED_BUFF_SCALAR(rx, flags);
SPAGAIN;
if (ret) {
- XPUSHs(ret);
+ mXPUSHs(ret);
PUTBACK;
return;
} else {
{
dVAR;
dXSARGS;
- PERL_UNUSED_ARG(cv);
if (items != 0)
- Perl_croak(aTHX_ "Usage: Tie::Hash::NamedCapture::flags()");
+ croak_xs_usage(cv, "");
mXPUSHu(RXapif_ONE);
mXPUSHu(RXapif_ALL);