X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=universal.c;h=99a3dd9eb16aeb44bac5f7133fb83b10311b67e8;hb=4cbc76b1bf09108493ca657fbc5ed7ed7b09fdbc;hp=fd96ce73c991373430b27d521697452c069e63cc;hpb=a3b680e6b77dd7f88268fad8b1dbdf4f641dd836;p=p5sagit%2Fp5-mst-13.2.git diff --git a/universal.c b/universal.c index fd96ce7..99a3dd9 100644 --- a/universal.c +++ b/universal.c @@ -40,13 +40,16 @@ S_isa_lookup(pTHX_ HV *stash, const char *name, HV* name_stash, GV** gvp; HV* hv = Nullhv; SV* subgen = Nullsv; + const char *hvname; /* A stash/class can go by many names (ie. User == main::User), so we compare the stash itself just in case */ if (name_stash && (stash == name_stash)) return &PL_sv_yes; - if (strEQ(HvNAME(stash), name)) + hvname = HvNAME_get(stash); + + if (strEQ(hvname, name)) return &PL_sv_yes; if (strEQ(name, "UNIVERSAL")) @@ -54,7 +57,7 @@ S_isa_lookup(pTHX_ HV *stash, const char *name, HV* name_stash, if (level > 100) Perl_croak(aTHX_ "Recursive inheritance detected in package '%s'", - HvNAME(stash)); + hvname); gvp = (GV**)hv_fetch(stash, "::ISA::CACHE::", 14, FALSE); @@ -66,13 +69,13 @@ S_isa_lookup(pTHX_ HV *stash, const char *name, HV* name_stash, SV** svp = (SV**)hv_fetch(hv, name, len, FALSE); if (svp && (sv = *svp) != (SV*)&PL_sv_undef) { DEBUG_o( Perl_deb(aTHX_ "Using cached ISA %s for package %s\n", - name, HvNAME(stash)) ); + name, hvname) ); return sv; } } else { DEBUG_o( Perl_deb(aTHX_ "ISA Cache in package %s is stale\n", - HvNAME(stash)) ); + hvname) ); hv_clear(hv); sv_setiv(subgen, PL_sub_generation); } @@ -106,8 +109,8 @@ S_isa_lookup(pTHX_ HV *stash, const char *name, HV* name_stash, if (!basestash) { if (ckWARN(WARN_MISC)) Perl_warner(aTHX_ packWARN(WARN_SYNTAX), - "Can't locate package %"SVf" for @%s::ISA", - sv, HvNAME(stash)); + "Can't locate package %"SVf" for @%s::ISA", + sv, hvname); continue; } if (&PL_sv_yes == isa_lookup(basestash, name, name_stash, @@ -171,9 +174,14 @@ PERL_XS_EXPORT_C void XS_UNIVERSAL_VERSION(pTHX_ CV *cv); XS(XS_version_new); XS(XS_version_stringify); XS(XS_version_numify); +XS(XS_version_normal); XS(XS_version_vcmp); XS(XS_version_boolean); +#ifdef HASATTRIBUTE_NORETURN +XS(XS_version_noop) __attribute__noreturn__; +#else XS(XS_version_noop); +#endif XS(XS_version_is_alpha); XS(XS_version_qv); XS(XS_utf8_is_utf8); @@ -211,6 +219,7 @@ Perl_boot_core_UNIVERSAL(pTHX) newXS("version::stringify", XS_version_stringify, file); newXS("version::(0+", XS_version_numify, file); newXS("version::numify", XS_version_numify, file); + newXS("version::normal", XS_version_normal, file); newXS("version::(cmp", XS_version_vcmp, file); newXS("version::(<=>", XS_version_vcmp, file); newXS("version::vcmp", XS_version_vcmp, file); @@ -247,7 +256,6 @@ XS(XS_UNIVERSAL_isa) dXSARGS; SV *sv; const char *name; - STRLEN n_a; if (items != 2) Perl_croak(aTHX_ "Usage: UNIVERSAL::isa(reference, kind)"); @@ -261,7 +269,7 @@ XS(XS_UNIVERSAL_isa) || (SvGMAGICAL(sv) && SvPOKp(sv) && SvCUR(sv)))) XSRETURN_UNDEF; - name = (const char *)SvPV(ST(1),n_a); + name = SvPV_nolen_const(ST(1)); ST(0) = boolSV(sv_derived_from(sv, name)); XSRETURN(1); @@ -274,7 +282,6 @@ XS(XS_UNIVERSAL_can) const char *name; SV *rv; HV *pkg = NULL; - STRLEN n_a; if (items != 2) Perl_croak(aTHX_ "Usage: UNIVERSAL::can(object-ref, method)"); @@ -288,7 +295,7 @@ XS(XS_UNIVERSAL_can) || (SvGMAGICAL(sv) && SvPOKp(sv) && SvCUR(sv)))) XSRETURN_UNDEF; - name = (const char *)SvPV(ST(1),n_a); + name = SvPV_nolen_const(ST(1)); rv = &PL_sv_undef; if (SvROK(sv)) { @@ -348,15 +355,15 @@ XS(XS_UNIVERSAL_VERSION) SV *req = ST(1); if (undef) { - if (pkg) + if (pkg) { + const char *name = HvNAME_get(pkg); Perl_croak(aTHX_ - "%s does not define $%s::VERSION--version check failed", - HvNAME(pkg), HvNAME(pkg)); - else { - STRLEN n_a; + "%s does not define $%s::VERSION--version check failed", + name, name); + } else { Perl_croak(aTHX_ "%s defines neither package nor VERSION--version check failed", - SvPVx(ST(0),n_a) ); + SvPVx_nolen_const(ST(0)) ); } } @@ -370,7 +377,7 @@ XS(XS_UNIVERSAL_VERSION) if ( vcmp( req, sv ) > 0 ) Perl_croak(aTHX_ "%s version %"SVf" (%"SVf") required--" - "this is only version %"SVf" (%"SVf")", HvNAME(pkg), + "this is only version %"SVf" (%"SVf")", HvNAME_get(pkg), vnumify(req),vnormal(req),vnumify(sv),vnormal(sv)); } @@ -390,13 +397,33 @@ XS(XS_version_new) Perl_croak(aTHX_ "Usage: version::new(class, version)"); SP -= items; { - const char *classname = SvPV_nolen(ST(0)); SV *vs = ST(1); SV *rv; - if (items == 3 ) - { - vs = sv_newmortal(); - Perl_sv_setpvf(aTHX_ vs,"v%s",SvPV_nolen(ST(2))); + const char *classname; + + /* get the class if called as an object method */ + if ( sv_isobject(ST(0)) ) { + classname = HvNAME(SvSTASH(SvRV(ST(0)))); + } + else { + classname = (char *)SvPV_nolen(ST(0)); + } + + if ( items == 1 ) { + /* no parameter provided */ + if ( sv_isobject(ST(0)) ) { + /* copy existing object */ + vs = ST(0); + } + else { + /* create empty object */ + vs = sv_newmortal(); + sv_setpv(vs,""); + } + } + else if ( items == 3 ) { + vs = sv_newmortal(); + Perl_sv_setpvf(aTHX_ vs,"v%s",SvPV_nolen_const(ST(2))); } rv = new_version(vs); @@ -416,11 +443,10 @@ XS(XS_version_stringify) Perl_croak(aTHX_ "Usage: version::stringify(lobj, ...)"); SP -= items; { - SV * lobj; + SV * lobj = Nullsv; if (sv_derived_from(ST(0), "version")) { - SV *tmp = SvRV(ST(0)); - lobj = tmp; + lobj = SvRV(ST(0)); } else Perl_croak(aTHX_ "lobj is not of type version"); @@ -439,11 +465,10 @@ XS(XS_version_numify) Perl_croak(aTHX_ "Usage: version::numify(lobj, ...)"); SP -= items; { - SV * lobj; + SV * lobj = Nullsv; if (sv_derived_from(ST(0), "version")) { - SV *tmp = SvRV(ST(0)); - lobj = tmp; + lobj = SvRV(ST(0)); } else Perl_croak(aTHX_ "lobj is not of type version"); @@ -455,6 +480,28 @@ XS(XS_version_numify) } } +XS(XS_version_normal) +{ + dXSARGS; + if (items < 1) + Perl_croak(aTHX_ "Usage: version::normal(lobj, ...)"); + SP -= items; + { + SV * lobj = Nullsv; + + if (sv_derived_from(ST(0), "version")) { + lobj = SvRV(ST(0)); + } + else + Perl_croak(aTHX_ "lobj is not of type version"); + + PUSHs(sv_2mortal(vnormal(lobj))); + + PUTBACK; + return; + } +} + XS(XS_version_vcmp) { dXSARGS; @@ -462,11 +509,10 @@ XS(XS_version_vcmp) Perl_croak(aTHX_ "Usage: version::vcmp(lobj, ...)"); SP -= items; { - SV * lobj; + SV * lobj = Nullsv; if (sv_derived_from(ST(0), "version")) { - SV *tmp = SvRV(ST(0)); - lobj = tmp; + lobj = SvRV(ST(0)); } else Perl_croak(aTHX_ "lobj is not of type version"); @@ -507,12 +553,10 @@ XS(XS_version_boolean) Perl_croak(aTHX_ "Usage: version::boolean(lobj, ...)"); SP -= items; { - SV * lobj; + SV * lobj = Nullsv; if (sv_derived_from(ST(0), "version")) { - /* XXX If tmp serves a purpose, explain it. */ - SV *tmp = SvRV(ST(0)); - lobj = tmp; + lobj = SvRV(ST(0)); } else Perl_croak(aTHX_ "lobj is not of type version"); @@ -530,25 +574,16 @@ XS(XS_version_boolean) XS(XS_version_noop) { - dXSARGS; - if (items < 1) - Perl_croak(aTHX_ "Usage: version::noop(lobj, ...)"); - { - SV * lobj; - - if (sv_derived_from(ST(0), "version")) { - SV *tmp = SvRV(ST(0)); - lobj = tmp; - } - else - Perl_croak(aTHX_ "lobj is not of type version"); - - { - Perl_croak(aTHX_ "operation not supported with version object"); - } - - } - XSRETURN_EMPTY; + dXSARGS; + if (items < 1) + Perl_croak(aTHX_ "Usage: version::noop(lobj, ...)"); + if (sv_derived_from(ST(0), "version")) + Perl_croak(aTHX_ "operation not supported with version object"); + else + Perl_croak(aTHX_ "lobj is not of type version"); +#ifndef HASATTRIBUTE_NORETURN + XSRETURN_EMPTY; +#endif } XS(XS_version_is_alpha) @@ -558,19 +593,14 @@ XS(XS_version_is_alpha) Perl_croak(aTHX_ "Usage: version::is_alpha(lobj)"); SP -= items; { - SV *lobj; + SV * lobj = Nullsv; - if (sv_derived_from(ST(0), "version")) { - /* XXX If tmp serves a purpose, explain it. */ - SV *tmp = SvRV(ST(0)); - lobj = tmp; - } + if (sv_derived_from(ST(0), "version")) + lobj = ST(0); else Perl_croak(aTHX_ "lobj is not of type version"); { - const I32 len = av_len((AV *)lobj); - const I32 digit = SvIVX(*av_fetch((AV *)lobj, len, 0)); - if ( digit < 0 ) + if ( hv_exists((HV*)SvRV(lobj), "alpha", 5 ) ) XSRETURN_YES; else XSRETURN_NO; @@ -643,7 +673,7 @@ XS(XS_utf8_valid) SV * sv = ST(0); { STRLEN len; - const char *s = SvPV(sv,len); + const char *s = SvPV_const(sv,len); if (!SvUTF8(sv) || is_utf8_string((const U8*)s,len)) XSRETURN_YES; else @@ -789,6 +819,7 @@ XS(XS_Internals_hv_clear_placehold) XS(XS_Regexp_DESTROY) { + LINT_UNUSED_ARG(cv) } XS(XS_PerlIO_get_layers) @@ -811,7 +842,7 @@ XS(XS_PerlIO_get_layers) SV **varp = svp; SV **valp = svp + 1; STRLEN klen; - const char *key = SvPV(*varp, klen); + const char *key = SvPV_const(*varp, klen); switch (*key) { case 'i': @@ -877,9 +908,9 @@ XS(XS_PerlIO_get_layers) if (details) { XPUSHs(namok ? - newSVpv(SvPVX(*namsvp), 0) : &PL_sv_undef); + newSVpv(SvPVX_const(*namsvp), 0) : &PL_sv_undef); XPUSHs(argok ? - newSVpv(SvPVX(*argsvp), 0) : &PL_sv_undef); + newSVpv(SvPVX_const(*argsvp), 0) : &PL_sv_undef); if (flgok) XPUSHi(SvIVX(*flgsvp)); else @@ -921,6 +952,8 @@ XS(XS_Internals_hash_seed) /* Using dXSARGS would also have dITEM and dSP, * which define 2 unused local variables. */ dAXMARK; + LINT_UNUSED_ARG(cv) + PERL_UNUSED_VAR(mark); XSRETURN_UV(PERL_HASH_SEED); } @@ -929,6 +962,8 @@ XS(XS_Internals_rehash_seed) /* Using dXSARGS would also have dITEM and dSP, * which define 2 unused local variables. */ dAXMARK; + LINT_UNUSED_ARG(cv) + PERL_UNUSED_VAR(mark); XSRETURN_UV(PL_rehash_seed); }