X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=sv.c;h=2a4c581f6ff157f16f2c8fc20244adc233b04819;hb=601cee3b44d5dc2533c9ca9da3e2820c4464c2af;hp=3293a91faa3bdc4da4eeb12fcee6d28fc1fb1cba;hpb=76f68e9bb86f29e34e2aeb5c177571288f05b7ca;p=p5sagit%2Fp5-mst-13.2.git diff --git a/sv.c b/sv.c index 3293a91..2a4c581 100644 --- a/sv.c +++ b/sv.c @@ -6,7 +6,16 @@ * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. * - * "I wonder what the Entish is for 'yes' and 'no'," he thought. + */ + +/* + * 'I wonder what the Entish is for "yes" and "no",' he thought. + * --Pippin + * + * [p.480 of _The Lord of the Rings_, III/iv: "Treebeard"] + */ + +/* * * * This file contains the code that creates, manipulates and destroys @@ -195,7 +204,7 @@ Perl_offer_nice_chunk(pTHX_ void *const chunk, const U32 chunk_size) #ifdef PERL_POISON # define SvARENA_CHAIN(sv) ((sv)->sv_u.svu_rv) -# define SvARENA_CHAIN_SET(sv,val) (sv)->sv_u.svu_rv = (SV *)(val) +# define SvARENA_CHAIN_SET(sv,val) (sv)->sv_u.svu_rv = MUTABLE_SV((val)) /* Whilst I'd love to do this, it seems that things like to check on unreferenced scalars # define POSION_SV_HEAD(sv) PoisonNew(sv, 1, struct STRUCT_SV) @@ -233,7 +242,7 @@ Perl_offer_nice_chunk(pTHX_ void *const chunk, const U32 chunk_size) #define uproot_SV(p) \ STMT_START { \ (p) = PL_sv_root; \ - PL_sv_root = (SV*)SvARENA_CHAIN(p); \ + PL_sv_root = MUTABLE_SV(SvARENA_CHAIN(p)); \ ++PL_sv_count; \ } STMT_END @@ -334,7 +343,7 @@ S_del_sv(pTHX_ SV *p) if (DEBUG_D_TEST) { SV* sva; bool ok = 0; - for (sva = PL_sv_arenaroot; sva; sva = (SV *) SvANY(sva)) { + for (sva = PL_sv_arenaroot; sva; sva = MUTABLE_SV(SvANY(sva))) { const SV * const sv = sva + 1; const SV * const svend = &sva[SvREFCNT(sva)]; if (p >= sv && p < svend) { @@ -371,11 +380,11 @@ and split it into a list of free SVs. =cut */ -void -Perl_sv_add_arena(pTHX_ char *const ptr, const U32 size, const U32 flags) +static void +S_sv_add_arena(pTHX_ char *const ptr, const U32 size, const U32 flags) { dVAR; - SV* const sva = (SV*)ptr; + SV *const sva = MUTABLE_SV(ptr); register SV* sv; register SV* svend; @@ -420,7 +429,7 @@ S_visit(pTHX_ SVFUNC_t f, const U32 flags, const U32 mask) PERL_ARGS_ASSERT_VISIT; - for (sva = PL_sv_arenaroot; sva; sva = (SV*)SvANY(sva)) { + for (sva = PL_sv_arenaroot; sva; sva = MUTABLE_SV(SvANY(sva))) { register const SV * const svend = &sva[SvREFCNT(sva)]; register SV* sv; for (sv = sva + 1; sv < svend; ++sv) { @@ -550,7 +559,7 @@ static void do_clean_all(pTHX_ SV *const sv) { dVAR; - if (sv == (SV*) PL_fdpid || sv == (SV *)PL_strtab) { + if (sv == (const SV *) PL_fdpid || sv == (const SV *)PL_strtab) { /* don't clean pid table and strtab */ return; } @@ -637,9 +646,9 @@ Perl_sv_free_arenas(pTHX) contiguity of the fake ones with the corresponding real ones.) */ for (sva = PL_sv_arenaroot; sva; sva = svanext) { - svanext = (SV*) SvANY(sva); + svanext = MUTABLE_SV(SvANY(sva)); while (svanext && SvFAKE(svanext)) - svanext = (SV*) SvANY(svanext); + svanext = MUTABLE_SV(SvANY(svanext)); if (!SvFAKE(sva)) Safefree(sva); @@ -917,7 +926,7 @@ struct xpv { #define copy_length(type, last_member) \ STRUCT_OFFSET(type, last_member) \ - + sizeof (((type*)SvANY((SV*)0))->last_member) + + sizeof (((type*)SvANY((const SV *)0))->last_member) static const struct body_details bodies_by_type[] = { { sizeof(HE), 0, 0, SVt_NULL, @@ -2264,7 +2273,7 @@ S_sv_2iuv_common(pTHX_ SV *const sv) } else { if (isGV_with_GP(sv)) - return glob_2number((GV *)sv); + return glob_2number(MUTABLE_GV(sv)); if (!(SvFLAGS(sv) & SVs_PADTMP)) { if (!PL_localizing && ckWARN(WARN_UNINITIALIZED)) @@ -2635,7 +2644,7 @@ Perl_sv_2nv(pTHX_ register SV *const sv) } else { if (isGV_with_GP(sv)) { - glob_2number((GV *)sv); + glob_2number(MUTABLE_GV(sv)); return 0.0; } @@ -2831,13 +2840,13 @@ Perl_sv_2pv_flags(pTHX_ register SV *const sv, STRLEN *const lp, const I32 flags STRLEN len; char *retval; char *buffer; - const SV *const referent = (SV*)SvRV(sv); + SV *const referent = SvRV(sv); if (!referent) { len = 7; retval = buffer = savepvn("NULLREF", len); } else if (SvTYPE(referent) == SVt_REGEXP) { - const REGEXP * const re = (REGEXP *)referent; + REGEXP * const re = (REGEXP *)MUTABLE_PTR(referent); I32 seen_evals = 0; assert(re); @@ -2978,7 +2987,7 @@ Perl_sv_2pv_flags(pTHX_ register SV *const sv, STRLEN *const lp, const I32 flags } else { if (isGV_with_GP(sv)) - return glob_2pv((GV *)sv, lp); + return glob_2pv(MUTABLE_GV(sv), lp); if (lp) *lp = 0; @@ -3291,7 +3300,7 @@ Perl_sv_utf8_encode(pTHX_ register SV *const sv) sv_force_normal_flags(sv, 0); } if (SvREADONLY(sv)) { - Perl_croak(aTHX_ PL_no_modify); + Perl_croak(aTHX_ "%s", PL_no_modify); } (void) sv_utf8_upgrade(sv); SvUTF8_off(sv); @@ -3402,18 +3411,18 @@ S_glob_assign_glob(pTHX_ SV *const dstr, SV *const sstr, const int dtype) } GvSTASH(dstr) = GvSTASH(sstr); if (GvSTASH(dstr)) - Perl_sv_add_backref(aTHX_ (SV*)GvSTASH(dstr), dstr); - gv_name_set((GV *)dstr, name, len, GV_ADD); + Perl_sv_add_backref(aTHX_ MUTABLE_SV(GvSTASH(dstr)), dstr); + gv_name_set(MUTABLE_GV(dstr), name, len, GV_ADD); SvFAKE_on(dstr); /* can coerce to non-glob */ } #ifdef GV_UNIQUE_CHECK - if (GvUNIQUE((GV*)dstr)) { - Perl_croak(aTHX_ PL_no_modify); + if (GvUNIQUE((const GV *)dstr)) { + Perl_croak(aTHX_ "%s", PL_no_modify); } #endif - if(GvGP((GV*)sstr)) { + if(GvGP(MUTABLE_GV(sstr))) { /* If source has method cache entry, clear it */ if(GvCVGEN(sstr)) { SvREFCNT_dec(GvCV(sstr)); @@ -3422,20 +3431,20 @@ S_glob_assign_glob(pTHX_ SV *const dstr, SV *const sstr, const int dtype) } /* If source has a real method, then a method is going to change */ - else if(GvCV((GV*)sstr)) { + else if(GvCV((const GV *)sstr)) { mro_changes = 1; } } /* If dest already had a real method, that's a change as well */ - if(!mro_changes && GvGP((GV*)dstr) && GvCVu((GV*)dstr)) { + if(!mro_changes && GvGP(MUTABLE_GV(dstr)) && GvCVu((const GV *)dstr)) { mro_changes = 1; } - if(strEQ(GvNAME((GV*)dstr),"ISA")) + if(strEQ(GvNAME((const GV *)dstr),"ISA")) mro_changes = 2; - gp_free((GV*)dstr); + gp_free(MUTABLE_GV(dstr)); isGV_with_GP_off(dstr); (void)SvOK_off(dstr); isGV_with_GP_on(dstr); @@ -3467,15 +3476,15 @@ S_glob_assign_ref(pTHX_ SV *const dstr, SV *const sstr) PERL_ARGS_ASSERT_GLOB_ASSIGN_REF; #ifdef GV_UNIQUE_CHECK - if (GvUNIQUE((GV*)dstr)) { - Perl_croak(aTHX_ PL_no_modify); + if (GvUNIQUE((const GV *)dstr)) { + Perl_croak(aTHX_ "%s", PL_no_modify); } #endif if (intro) { GvINTRO_off(dstr); /* one-shot flag */ GvLINE(dstr) = CopLINE(PL_curcop); - GvEGV(dstr) = (GV*)dstr; + GvEGV(dstr) = MUTABLE_GV(dstr); } GvMULTI_on(dstr); switch (stype) { @@ -3516,7 +3525,7 @@ S_glob_assign_ref(pTHX_ SV *const dstr, SV *const sstr) if (stype == SVt_PVCV && (*location != sref || GvCVGEN(dstr))) { CV* const cv = MUTABLE_CV(*location); if (cv) { - if (!GvCVGEN((GV*)dstr) && + if (!GvCVGEN((const GV *)dstr) && (CvROOT(cv) || CvXSUB(cv))) { /* Redefining a sub - warning is mandatory if @@ -3543,12 +3552,12 @@ S_glob_assign_ref(pTHX_ SV *const dstr, SV *const sstr) (CvCONST(cv) ? "Constant subroutine %s::%s redefined" : "Subroutine %s::%s redefined"), - HvNAME_get(GvSTASH((GV*)dstr)), - GvENAME((GV*)dstr)); + HvNAME_get(GvSTASH((const GV *)dstr)), + GvENAME(MUTABLE_GV(dstr))); } } if (!intro) - cv_ckproto_len(cv, (GV*)dstr, + cv_ckproto_len(cv, (const GV *)dstr, SvPOK(sref) ? SvPVX_const(sref) : NULL, SvPOK(sref) ? SvCUR(sref) : 0); } @@ -3796,9 +3805,9 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV* sstr, const I32 flags) } else { GV *gv = gv_fetchsv(sstr, GV_ADD, SVt_PVGV); - if (dstr != (SV*)gv) { + if (dstr != (const SV *)gv) { if (GvGP(dstr)) - gp_free((GV*)dstr); + gp_free(MUTABLE_GV(dstr)); GvGP(dstr) = gp_ref(GvGP(gv)); } } @@ -3987,7 +3996,7 @@ Perl_sv_setsv_flags(pTHX_ SV *dstr, register SV* sstr, const I32 flags) /* FAKE globs can get coerced, so need to turn this off temporarily if it is on. */ SvFAKE_off(sstr); - gv_efullname3(dstr, (GV *)sstr, "*"); + gv_efullname3(dstr, MUTABLE_GV(sstr), "*"); SvFLAGS(sstr) |= wasfake; } else @@ -4375,7 +4384,7 @@ Perl_sv_force_normal_flags(pTHX_ register SV *const sv, const U32 flags) } } else if (IN_PERL_RUNTIME) - Perl_croak(aTHX_ PL_no_modify); + Perl_croak(aTHX_ "%s", PL_no_modify); /* At this point I believe that I can drop the global SV mutex. */ } #else @@ -4393,7 +4402,7 @@ Perl_sv_force_normal_flags(pTHX_ register SV *const sv, const U32 flags) unshare_hek(SvSHARED_HEK_FROM_PV(pvx)); } else if (IN_PERL_RUNTIME) - Perl_croak(aTHX_ PL_no_modify); + Perl_croak(aTHX_ "%s", PL_no_modify); } #endif if (SvROK(sv)) @@ -4736,7 +4745,7 @@ Perl_sv_magicext(pTHX_ SV *const sv, SV *const obj, const int how, */ if (how == PERL_MAGIC_tiedscalar && SvTYPE(sv) == SVt_PVIO && - obj && SvROK(obj) && GvIO(SvRV(obj)) == (IO*)sv) + obj && SvROK(obj) && GvIO(SvRV(obj)) == (const IO *)sv) { sv_rvweaken(obj); } @@ -4746,9 +4755,13 @@ Perl_sv_magicext(pTHX_ SV *const sv, SV *const obj, const int how, if (name) { if (namlen > 0) mg->mg_ptr = savepvn(name, namlen); - else if (namlen == HEf_SVKEY) - mg->mg_ptr = (char*)SvREFCNT_inc_simple_NN((SV*)name); - else + else if (namlen == HEf_SVKEY) { + /* Yes, this is casting away const. This is only for the case of + HEf_SVKEY. I think we need to document this abberation of the + constness of the API, rather than making name non-const, as + that change propagating outwards a long way. */ + mg->mg_ptr = (char*)SvREFCNT_inc_simple_NN((SV *)name); + } else mg->mg_ptr = (char *) name; } mg->mg_virtual = (MGVTBL *) vtable; @@ -4802,7 +4815,7 @@ Perl_sv_magic(pTHX_ register SV *const sv, SV *const obj, const int how, && how != PERL_MAGIC_backref ) { - Perl_croak(aTHX_ PL_no_modify); + Perl_croak(aTHX_ "%s", PL_no_modify); } } if (SvMAGICAL(sv) || (how == PERL_MAGIC_taint && SvTYPE(sv) >= SVt_PVMG)) { @@ -4983,7 +4996,7 @@ Perl_sv_unmagic(pTHX_ SV *const sv, const int type) if (mg->mg_len > 0) Safefree(mg->mg_ptr); else if (mg->mg_len == HEf_SVKEY) - SvREFCNT_dec((SV*)mg->mg_ptr); + SvREFCNT_dec(MUTABLE_SV(mg->mg_ptr)); else if (mg->mg_type == PERL_MAGIC_utf8) Safefree(mg->mg_ptr); } @@ -5100,7 +5113,7 @@ Perl_sv_add_backref(pTHX_ SV *const tsv, SV *const sv) else { av = newAV(); AvREAL_off(av); - sv_magic(tsv, (SV*)av, PERL_MAGIC_backref, NULL, 0); + sv_magic(tsv, MUTABLE_SV(av), PERL_MAGIC_backref, NULL, 0); /* av now has a refcnt of 2; see discussion above */ } } @@ -5445,7 +5458,7 @@ Perl_sv_clear(pTHX_ register SV *const sv) PUSHMARK(SP); PUSHs(tmpref); PUTBACK; - call_sv((SV*)destructor, G_DISCARD|G_EVAL|G_KEEPERR|G_VOID); + call_sv(MUTABLE_SV(destructor), G_DISCARD|G_EVAL|G_KEEPERR|G_VOID); POPSTACK; @@ -5494,7 +5507,7 @@ Perl_sv_clear(pTHX_ register SV *const sv) IoIFP(sv) != PerlIO_stdout() && IoIFP(sv) != PerlIO_stderr()) { - io_close((IO*)sv, FALSE); + io_close(MUTABLE_IO(sv), FALSE); } if (IoDIRP(sv) && !(IoFLAGS(sv) & IOf_FAKE_DIRP)) PerlDir_close(IoDIRP(sv)); @@ -5535,20 +5548,21 @@ Perl_sv_clear(pTHX_ register SV *const sv) SvREFCNT_dec(LvTARG(sv)); case SVt_PVGV: if (isGV_with_GP(sv)) { - if(GvCVu((GV*)sv) && (stash = GvSTASH((GV*)sv)) && HvNAME_get(stash)) + if(GvCVu((const GV *)sv) && (stash = GvSTASH(MUTABLE_GV(sv))) + && HvNAME_get(stash)) mro_method_changed_in(stash); - gp_free((GV*)sv); + gp_free(MUTABLE_GV(sv)); if (GvNAME_HEK(sv)) unshare_hek(GvNAME_HEK(sv)); /* If we're in a stash, we don't own a reference to it. However it does have a back reference to us, which needs to be cleared. */ if (!SvVALID(sv) && (stash = GvSTASH(sv))) - sv_del_backref((SV*)stash, sv); + sv_del_backref(MUTABLE_SV(stash), sv); } /* FIXME. There are probably more unreferenced pointers to SVs in the interpreter struct that we should check and tidy in a similar fashion to this: */ - if ((GV*)sv == PL_last_in_gv) + if ((const GV *)sv == PL_last_in_gv) PL_last_in_gv = NULL; case SVt_PVMG: case SVt_PVNV: @@ -7019,7 +7033,7 @@ Perl_sv_inc(pTHX_ register SV *const sv) sv_force_normal_flags(sv, 0); if (SvREADONLY(sv)) { if (IN_PERL_RUNTIME) - Perl_croak(aTHX_ PL_no_modify); + Perl_croak(aTHX_ "%s", PL_no_modify); } if (SvROK(sv)) { IV i; @@ -7182,7 +7196,7 @@ Perl_sv_dec(pTHX_ register SV *const sv) sv_force_normal_flags(sv, 0); if (SvREADONLY(sv)) { if (IN_PERL_RUNTIME) - Perl_croak(aTHX_ PL_no_modify); + Perl_croak(aTHX_ "%s", PL_no_modify); } if (SvROK(sv)) { IV i; @@ -7787,7 +7801,7 @@ Perl_sv_reset(pTHX_ register const char *s, HV *const stash) return; if (!*s) { /* reset ?? searches */ - MAGIC * const mg = mg_find((SV *)stash, PERL_MAGIC_symtab); + MAGIC * const mg = mg_find((const SV *)stash, PERL_MAGIC_symtab); if (mg) { const U32 count = mg->mg_len / sizeof(PMOP**); PMOP **pmp = (PMOP**) mg->mg_ptr; @@ -7832,7 +7846,7 @@ Perl_sv_reset(pTHX_ register const char *s, HV *const stash) if (!todo[(U8)*HeKEY(entry)]) continue; - gv = (GV*)HeVAL(entry); + gv = MUTABLE_GV(HeVAL(entry)); sv = GvSV(gv); if (sv) { if (SvTHINKFIRST(sv)) { @@ -7889,11 +7903,11 @@ Perl_sv_2io(pTHX_ SV *const sv) switch (SvTYPE(sv)) { case SVt_PVIO: - io = (IO*)sv; + io = MUTABLE_IO(sv); break; case SVt_PVGV: if (isGV_with_GP(sv)) { - gv = (GV*)sv; + gv = MUTABLE_GV(sv); io = GvIO(gv); if (!io) Perl_croak(aTHX_ "Bad filehandle: %s", GvNAME(gv)); @@ -7953,7 +7967,7 @@ Perl_sv_2cv(pTHX_ SV *sv, HV **const st, GV **const gvp, const I32 lref) return NULL; case SVt_PVGV: if (isGV_with_GP(sv)) { - gv = (GV*)sv; + gv = MUTABLE_GV(sv); *gvp = gv; *st = GvESTASH(gv); goto fix_gv; @@ -7974,13 +7988,13 @@ Perl_sv_2cv(pTHX_ SV *sv, HV **const st, GV **const gvp, const I32 lref) return cv; } else if(isGV_with_GP(sv)) - gv = (GV*)sv; + gv = MUTABLE_GV(sv); else Perl_croak(aTHX_ "Not a subroutine reference"); } else if (isGV_with_GP(sv)) { SvGETMAGIC(sv); - gv = (GV*)sv; + gv = MUTABLE_GV(sv); } else gv = gv_fetchsv(sv, lref, SVt_PVCV); /* Calls get magic */ @@ -8234,7 +8248,7 @@ Perl_sv_isobject(pTHX_ SV *sv) SvGETMAGIC(sv); if (!SvROK(sv)) return 0; - sv = (SV*)SvRV(sv); + sv = SvRV(sv); if (!SvOBJECT(sv)) return 0; return 1; @@ -8262,7 +8276,7 @@ Perl_sv_isa(pTHX_ SV *sv, const char *const name) SvGETMAGIC(sv); if (!SvROK(sv)) return 0; - sv = (SV*)SvRV(sv); + sv = SvRV(sv); if (!SvOBJECT(sv)) return 0; hvname = HvNAME_get(SvSTASH(sv)); @@ -8468,7 +8482,7 @@ Perl_sv_bless(pTHX_ SV *const sv, HV *const stash) if (SvIsCOW(tmpRef)) sv_force_normal_flags(tmpRef, 0); if (SvREADONLY(tmpRef)) - Perl_croak(aTHX_ PL_no_modify); + Perl_croak(aTHX_ "%s", PL_no_modify); if (SvOBJECT(tmpRef)) { if (SvTYPE(tmpRef) != SVt_PVIO) --PL_sv_objcount; @@ -8510,15 +8524,16 @@ S_sv_unglob(pTHX_ SV *const sv) assert(SvTYPE(sv) == SVt_PVGV); SvFAKE_off(sv); - gv_efullname3(temp, (GV *) sv, "*"); + gv_efullname3(temp, MUTABLE_GV(sv), "*"); if (GvGP(sv)) { - if(GvCVu((GV*)sv) && (stash = GvSTASH((GV*)sv)) && HvNAME_get(stash)) + if(GvCVu((const GV *)sv) && (stash = GvSTASH(MUTABLE_GV(sv))) + && HvNAME_get(stash)) mro_method_changed_in(stash); - gp_free((GV*)sv); + gp_free(MUTABLE_GV(sv)); } if (GvSTASH(sv)) { - sv_del_backref((SV*)GvSTASH(sv), sv); + sv_del_backref(MUTABLE_SV(GvSTASH(sv)), sv); GvSTASH(sv) = NULL; } GvMULTI_off(sv); @@ -9032,7 +9047,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen, } if (args && patlen == 3 && pat[0] == '%' && pat[1] == '-' && pat[2] == 'p') { - argsv = (SV*)va_arg(*args, void*); + argsv = MUTABLE_SV(va_arg(*args, void*)); sv_catsv(sv, argsv); return; } @@ -9107,6 +9122,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen, STRLEN esignlen = 0; const char *eptr = NULL; + const char *fmtstart; STRLEN elen = 0; SV *vecsv = NULL; const U8 *vecstr = NULL; @@ -9147,6 +9163,8 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen, if (q++ >= patend) break; + fmtstart = q; + /* We allow format specification elements in this order: \d+\$ explicit format parameter index @@ -9189,7 +9207,7 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen, precis = n; has_precis = TRUE; } - argsv = (SV*)va_arg(*args, void*); + argsv = MUTABLE_SV(va_arg(*args, void*)); eptr = SvPV_const(argsv, elen); if (DO_UTF8(argsv)) is_utf8 = TRUE; @@ -9542,8 +9560,11 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen, case 'l': iv = va_arg(*args, long); break; case 'V': iv = va_arg(*args, IV); break; default: iv = va_arg(*args, int); break; + case 'q': #ifdef HAS_QUAD - case 'q': iv = va_arg(*args, Quad_t); break; + iv = va_arg(*args, Quad_t); break; +#else + goto unknown; #endif } } @@ -9554,8 +9575,11 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen, case 'l': iv = (long)tiv; break; case 'V': default: iv = tiv; break; + case 'q': #ifdef HAS_QUAD - case 'q': iv = (Quad_t)tiv; break; + iv = (Quad_t)tiv; break; +#else + goto unknown; #endif } } @@ -9627,8 +9651,11 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen, case 'l': uv = va_arg(*args, unsigned long); break; case 'V': uv = va_arg(*args, UV); break; default: uv = va_arg(*args, unsigned); break; + case 'q': #ifdef HAS_QUAD - case 'q': uv = va_arg(*args, Uquad_t); break; + uv = va_arg(*args, Uquad_t); break; +#else + goto unknown; #endif } } @@ -9639,8 +9666,11 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen, case 'l': uv = (unsigned long)tuv; break; case 'V': default: uv = tuv; break; + case 'q': #ifdef HAS_QUAD - case 'q': uv = (Uquad_t)tuv; break; + uv = (Uquad_t)tuv; break; +#else + goto unknown; #endif } } @@ -9926,8 +9956,11 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen, default: *(va_arg(*args, int*)) = i; break; case 'l': *(va_arg(*args, long*)) = i; break; case 'V': *(va_arg(*args, IV*)) = i; break; + case 'q': #ifdef HAS_QUAD - case 'q': *(va_arg(*args, Quad_t*)) = i; break; + *(va_arg(*args, Quad_t*)) = i; break; +#else + goto unknown; #endif } } @@ -9946,16 +9979,22 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen, SV * const msg = sv_newmortal(); Perl_sv_setpvf(aTHX_ msg, "Invalid conversion in %sprintf: ", (PL_op->op_type == OP_PRTF) ? "" : "s"); - if (c) { - if (isPRINT(c)) - Perl_sv_catpvf(aTHX_ msg, - "\"%%%c\"", c & 0xFF); - else - Perl_sv_catpvf(aTHX_ msg, - "\"%%\\%03"UVof"\"", - (UV)c & 0xFF); - } else + if (fmtstart < patend) { + const char * const fmtend = q < patend ? q : patend; + const char * f; + sv_catpvs(msg, "\"%"); + for (f = fmtstart; f < fmtend; f++) { + if (isPRINT(*f)) { + sv_catpvn(msg, f, 1); + } else { + Perl_sv_catpvf(aTHX_ msg, + "\\%03"UVof, (UV)*f & 0xFF); + } + } + sv_catpvs(msg, "\""); + } else { sv_catpvs(msg, "end of string"); + } Perl_warner(aTHX_ packWARN(WARN_PRINTF), "%"SVf, SVfARG(msg)); /* yes, this is reentrant */ } @@ -9997,13 +10036,13 @@ Perl_sv_vcatpvfn(pTHX_ SV *const sv, const char *const pat, const STRLEN patlen, have = esignlen + zeros + elen; if (have < zeros) - Perl_croak_nocontext(PL_memory_wrap); + Perl_croak_nocontext("%s", PL_memory_wrap); need = (have > width ? have : width); gap = need - have; if (need >= (((STRLEN)~0) - SvCUR(sv) - dotstrlen - 1)) - Perl_croak_nocontext(PL_memory_wrap); + Perl_croak_nocontext("%s", PL_memory_wrap); SvGROW(sv, SvCUR(sv) + need + dotstrlen + 1); p = SvEND(sv); if (esignlen && fill == '0') { @@ -10088,12 +10127,12 @@ ptr_table_* functions. #define av_dup_inc(s,t) MUTABLE_AV(SvREFCNT_inc(sv_dup((const SV *)s,t))) #define hv_dup(s,t) MUTABLE_HV(sv_dup((const SV *)s,t)) #define hv_dup_inc(s,t) MUTABLE_HV(SvREFCNT_inc(sv_dup((const SV *)s,t))) -#define cv_dup(s,t) MUTABLE_CV(sv_dup((SV*)s,t)) +#define cv_dup(s,t) MUTABLE_CV(sv_dup((const SV *)s,t)) #define cv_dup_inc(s,t) MUTABLE_CV(SvREFCNT_inc(sv_dup((const SV *)s,t))) -#define io_dup(s,t) (IO*)sv_dup((SV*)s,t) -#define io_dup_inc(s,t) (IO*)SvREFCNT_inc(sv_dup((const SV *)s,t)) -#define gv_dup(s,t) (GV*)sv_dup((SV*)s,t) -#define gv_dup_inc(s,t) (GV*)SvREFCNT_inc(sv_dup((const SV *)s,t)) +#define io_dup(s,t) MUTABLE_IO(sv_dup((const SV *)s,t)) +#define io_dup_inc(s,t) MUTABLE_IO(SvREFCNT_inc(sv_dup((const SV *)s,t))) +#define gv_dup(s,t) MUTABLE_GV(sv_dup((const SV *)s,t)) +#define gv_dup_inc(s,t) MUTABLE_GV(SvREFCNT_inc(sv_dup((const SV *)s,t))) #define SAVEPV(p) ((p) ? savepv(p) : NULL) #define SAVEPVN(p,n) ((p) ? savepvn(p,n) : NULL) @@ -10317,7 +10356,7 @@ Perl_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *const param) nmg->mg_flags = mg->mg_flags; /* FIXME for plugins if (mg->mg_type == PERL_MAGIC_qr) { - nmg->mg_obj = (SV*)CALLREGDUPE((REGEXP*)mg->mg_obj, param); + nmg->mg_obj = MUTABLE_SV(CALLREGDUPE((REGEXP*)mg->mg_obj, param)); } else */ @@ -10349,7 +10388,7 @@ Perl_mg_dup(pTHX_ MAGIC *mg, CLONE_PARAMS *const param) } } else if (mg->mg_len == HEf_SVKEY) - nmg->mg_ptr = (char*)sv_dup_inc((SV*)mg->mg_ptr, param); + nmg->mg_ptr = (char*)sv_dup_inc((const SV *)mg->mg_ptr, param); } if ((mg->mg_flags & MGf_DUP) && mg->mg_virtual && mg->mg_virtual->svt_dup) { CALL_FPTR(nmg->mg_virtual->svt_dup)(aTHX_ nmg, param); @@ -10523,8 +10562,8 @@ Perl_rvpv_dup(pTHX_ SV *const dstr, const SV *const sstr, CLONE_PARAMS *const pa if (SvROK(sstr)) { SvRV_set(dstr, SvWEAKREF(sstr) - ? sv_dup(SvRV(sstr), param) - : sv_dup_inc(SvRV(sstr), param)); + ? sv_dup(SvRV_const(sstr), param) + : sv_dup_inc(SvRV_const(sstr), param)); } else if (SvPVX_const(sstr)) { @@ -10552,7 +10591,7 @@ Perl_rvpv_dup(pTHX_ SV *const dstr, const SV *const sstr, CLONE_PARAMS *const pa } else { /* Some other special case - random pointer */ - SvPV_set(dstr, SvPVX(sstr)); + SvPV_set(dstr, (char *) SvPVX_const(sstr)); } } } @@ -10581,7 +10620,7 @@ Perl_sv_dup(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) return NULL; } /* look for it in the table first */ - dstr = (SV*)ptr_table_fetch(PL_ptr_table, sstr); + dstr = MUTABLE_SV(ptr_table_fetch(PL_ptr_table, sstr)); if (dstr) return dstr; @@ -10592,7 +10631,7 @@ Perl_sv_dup(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) const HEK * const hvname = HvNAME_HEK(sstr); if (hvname) /** don't clone stashes if they already exist **/ - return (SV*)gv_stashpvn(HEK_KEY(hvname), HEK_LEN(hvname), 0); + return MUTABLE_SV(gv_stashpvn(HEK_KEY(hvname), HEK_LEN(hvname), 0)); } } @@ -10657,7 +10696,7 @@ Perl_sv_dup(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) break; case SVt_PVGV: - if (GvUNIQUE((GV*)sstr)) { + if (GvUNIQUE((const GV *)sstr)) { NOOP; /* Do sharing here, and fall through */ } case SVt_PVIO: @@ -10730,7 +10769,7 @@ Perl_sv_dup(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) if (LvTYPE(dstr) == 't') /* for tie: unrefcnted fake (SV**) */ LvTARG(dstr) = dstr; else if (LvTYPE(dstr) == 'T') /* for tie: fake HE */ - LvTARG(dstr) = (SV*)he_dup((HE*)LvTARG(dstr), 0, param); + LvTARG(dstr) = MUTABLE_SV(he_dup((HE*)LvTARG(dstr), 0, param)); else LvTARG(dstr) = sv_dup_inc(LvTARG(dstr), param); case SVt_PVGV: @@ -10841,7 +10880,7 @@ Perl_sv_dup(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) daux->xhv_backreferences = saux->xhv_backreferences ? MUTABLE_AV(SvREFCNT_inc( - sv_dup_inc((SV*)saux->xhv_backreferences, param))) + sv_dup_inc((const SV *)saux->xhv_backreferences, param))) : 0; daux->xhv_mro_meta = saux->xhv_mro_meta @@ -10870,7 +10909,7 @@ Perl_sv_dup(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) if (CvCONST(dstr) && CvISXSUB(dstr)) { CvXSUBANY(dstr).any_ptr = GvUNIQUE(CvGV(dstr)) ? SvREFCNT_inc(CvXSUBANY(dstr).any_ptr) : - sv_dup_inc((SV *)CvXSUBANY(dstr).any_ptr, param); + sv_dup_inc((const SV *)CvXSUBANY(dstr).any_ptr, param); } /* don't dup if copying back - CvGV isn't refcounted, so the * duped GV may never be freed. A bit of a hack! DAPM */ @@ -10961,7 +11000,8 @@ Perl_cx_dup(pTHX_ PERL_CONTEXT *cxs, I32 ix, I32 max, CLONE_PARAMS* param) ncx->blk_loop.oldcomppad); } else { ncx->blk_loop.oldcomppad - = (PAD*)gv_dup((GV*)ncx->blk_loop.oldcomppad, param); + = (PAD*)gv_dup((const GV *)ncx->blk_loop.oldcomppad, + param); } break; case CXt_FORMAT: @@ -11072,7 +11112,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) const I32 max = proto_perl->Isavestack_max; I32 ix = proto_perl->Isavestack_ix; ANY *nss; - SV *sv; + const SV *sv; const GV *gv; const AV *av; const HV *hv; @@ -11095,17 +11135,17 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) TOPINT(nss,ix) = type; switch (type) { case SAVEt_HELEM: /* hash element */ - sv = (SV*)POPPTR(ss,ix); + sv = (const SV *)POPPTR(ss,ix); TOPPTR(nss,ix) = sv_dup_inc(sv, param); /* fall through */ case SAVEt_ITEM: /* normal string */ case SAVEt_SV: /* scalar reference */ - sv = (SV*)POPPTR(ss,ix); + sv = (const SV *)POPPTR(ss,ix); TOPPTR(nss,ix) = sv_dup_inc(sv, param); /* fall through */ case SAVEt_FREESV: case SAVEt_MORTALIZESV: - sv = (SV*)POPPTR(ss,ix); + sv = (const SV *)POPPTR(ss,ix); TOPPTR(nss,ix) = sv_dup_inc(sv, param); break; case SAVEt_SHARED_PVREF: /* char* in shared space */ @@ -11116,19 +11156,19 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) break; case SAVEt_GENERIC_SVREF: /* generic sv */ case SAVEt_SVREF: /* scalar reference */ - sv = (SV*)POPPTR(ss,ix); + sv = (const SV *)POPPTR(ss,ix); TOPPTR(nss,ix) = sv_dup_inc(sv, param); ptr = POPPTR(ss,ix); TOPPTR(nss,ix) = svp_dup_inc((SV**)ptr, proto_perl);/* XXXXX */ break; case SAVEt_HV: /* hash reference */ case SAVEt_AV: /* array reference */ - sv = (SV*) POPPTR(ss,ix); + sv = (const SV *) POPPTR(ss,ix); TOPPTR(nss,ix) = sv_dup_inc(sv, param); /* fall through */ case SAVEt_COMPPAD: case SAVEt_NSTAB: - sv = (SV*) POPPTR(ss,ix); + sv = (const SV *) POPPTR(ss,ix); TOPPTR(nss,ix) = sv_dup(sv, param); break; case SAVEt_INT: /* int reference */ @@ -11165,7 +11205,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) case SAVEt_SPTR: /* SV* reference */ ptr = POPPTR(ss,ix); TOPPTR(nss,ix) = any_dup(ptr, proto_perl); - sv = (SV*)POPPTR(ss,ix); + sv = (const SV *)POPPTR(ss,ix); TOPPTR(nss,ix) = sv_dup(sv, param); break; case SAVEt_VPTR: /* random* reference */ @@ -11185,7 +11225,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) gp = (GP*)POPPTR(ss,ix); TOPPTR(nss,ix) = gp = gp_dup(gp, param); (void)GpREFCNT_inc(gp); - gv = (GV*)POPPTR(ss,ix); + gv = (const GV *)POPPTR(ss,ix); TOPPTR(nss,ix) = gv_dup_inc(gv, param); break; case SAVEt_FREEOP: @@ -11251,7 +11291,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) ix -= i; break; case SAVEt_AELEM: /* array element */ - sv = (SV*)POPPTR(ss,ix); + sv = (const SV *)POPPTR(ss,ix); TOPPTR(nss,ix) = sv_dup_inc(sv, param); i = POPINT(ss,ix); TOPINT(nss,ix) = i; @@ -11263,8 +11303,6 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) TOPPTR(nss,ix) = ptr; break; case SAVEt_HINTS: - i = POPINT(ss,ix); - TOPINT(nss,ix) = i; ptr = POPPTR(ss,ix); if (ptr) { HINTS_REFCNT_LOCK; @@ -11272,6 +11310,8 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) HINTS_REFCNT_UNLOCK; } TOPPTR(nss,ix) = ptr; + i = POPINT(ss,ix); + TOPINT(nss,ix) = i; if (i & HINT_LOCALIZE_HH) { hv = (const HV *)POPPTR(ss,ix); TOPPTR(nss,ix) = hv_dup_inc(hv, param); @@ -11282,7 +11322,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) TOPLONG(nss,ix) = longval; ptr = POPPTR(ss,ix); TOPPTR(nss,ix) = any_dup(ptr, proto_perl); - sv = (SV*)POPPTR(ss,ix); + sv = (const SV *)POPPTR(ss,ix); TOPPTR(nss,ix) = sv_dup_inc(sv, param); break; case SAVEt_BOOL: @@ -11296,7 +11336,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param) TOPINT(nss,ix) = i; i = POPINT(ss,ix); TOPINT(nss,ix) = i; - sv = (SV*)POPPTR(ss,ix); + sv = (const SV *)POPPTR(ss,ix); TOPPTR(nss,ix) = sv_dup(sv, param); break; case SAVEt_RE_STATE: @@ -11398,7 +11438,7 @@ do_mark_cloneable_stash(pTHX_ SV *const sv) PUSHMARK(SP); mXPUSHs(newSVhek(hvname)); PUTBACK; - call_sv((SV*)GvCV(cloner), G_SCALAR); + call_sv(MUTABLE_SV(GvCV(cloner)), G_SCALAR); SPAGAIN; status = POPu; PUTBACK; @@ -11721,6 +11761,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PL_regex_pad = AvARRAY(PL_regex_padav); /* shortcuts to various I/O objects */ + PL_ofsgv = gv_dup(proto_perl->Iofsgv, param); PL_stdingv = gv_dup(proto_perl->Istdingv, param); PL_stderrgv = gv_dup(proto_perl->Istderrgv, param); PL_defgv = gv_dup(proto_perl->Idefgv, param); @@ -12037,8 +12078,8 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, * orphaned */ for (i = 0; i<= proto_perl->Itmps_ix; i++) { - SV * const nsv = (SV*)ptr_table_fetch(PL_ptr_table, - proto_perl->Itmps_stack[i]); + SV * const nsv = MUTABLE_SV(ptr_table_fetch(PL_ptr_table, + proto_perl->Itmps_stack[i])); if (nsv && !SvREFCNT(nsv)) { EXTEND_MORTAL(1); PL_tmps_stack[++PL_tmps_ix] = SvREFCNT_inc_simple(nsv); @@ -12067,7 +12108,6 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PL_curpm = proto_perl->Icurpm; /* XXX No PMOP ref count */ PL_rs = sv_dup_inc(proto_perl->Irs, param); PL_last_in_gv = gv_dup(proto_perl->Ilast_in_gv, param); - PL_ofs_sv = sv_dup_inc(proto_perl->Iofs_sv, param); PL_defoutgv = gv_dup_inc(proto_perl->Idefoutgv, param); PL_chopset = proto_perl->Ichopset; /* XXX never deallocated */ PL_toptarget = sv_dup_inc(proto_perl->Itoptarget, param); @@ -12140,7 +12180,7 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, PUSHMARK(SP); mXPUSHs(newSVhek(HvNAME_HEK(stash))); PUTBACK; - call_sv((SV*)GvCV(cloner), G_DISCARD); + call_sv(MUTABLE_SV(GvCV(cloner)), G_DISCARD); FREETMPS; LEAVE; } @@ -12472,7 +12512,7 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv, gv = cGVOPx_gv(cUNOPx(obase)->op_first); if (!gv) break; - sv = hash ? (SV*)GvHV(gv): (SV*)GvAV(gv); + sv = hash ? MUTABLE_SV(GvHV(gv)): MUTABLE_SV(GvAV(gv)); } else /* @{expr}, %{expr} */ return find_uninit_var(cUNOPx(obase)->op_first, @@ -12570,7 +12610,8 @@ S_find_uninit_var(pTHX_ const OP *const obase, const SV *const uninit_sv, gv = cGVOPx_gv(cUNOPo->op_first); if (!gv) break; - sv = o->op_type == OP_RV2HV ? (SV*)GvHV(gv) : (SV*)GvAV(gv); + sv = o->op_type + == OP_RV2HV ? MUTABLE_SV(GvHV(gv)) : MUTABLE_SV(GvAV(gv)); } if (!sv) break; @@ -12830,7 +12871,7 @@ Print appropriate "Use of uninitialized variable" warning */ void -Perl_report_uninit(pTHX_ SV* uninit_sv) +Perl_report_uninit(pTHX_ const SV *uninit_sv) { dVAR; if (PL_op) {