X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/3c813ed0ab90d1f1f16ca848d265616ae5315536..095b19d150eee57ee8501177d6950002977ef74c:/sv.h diff --git a/sv.h b/sv.h index 7f79c01..056d43b 100644 --- a/sv.h +++ b/sv.h @@ -302,12 +302,12 @@ perform the upgrade if necessary. See C. #define SVp_IOK 0x00001000 /* has valid non-public integer value */ #define SVp_NOK 0x00002000 /* has valid non-public numeric value */ #define SVp_POK 0x00004000 /* has valid non-public pointer value */ -#define SVp_SCREAM 0x00008000 /* has been studied? */ +#define SVp_SCREAM 0x00008000 /* method name is DOES */ #define SVphv_CLONEABLE SVp_SCREAM /* PVHV (stashes) clone its objects */ #define SVpgv_GP SVp_SCREAM /* GV has a valid GP */ #define SVprv_PCS_IMPORTED SVp_SCREAM /* RV is a proxy for a constant subroutine in another package. Set the - CvIMPORTED_CV_ON() if it needs to be + GvIMPORTED_CV_on() if it needs to be expanded to a real GV */ /* 0x00010000 *** FREE SLOT */ #define SVs_PADTMP 0x00020000 /* in use as tmp; only if ! SVs_PADMY */ @@ -348,7 +348,7 @@ perform the upgrade if necessary. See C. -#define SVf_THINKFIRST (SVf_READONLY|SVf_ROK|SVf_FAKE) +#define SVf_THINKFIRST (SVf_READONLY|SVf_ROK|SVf_FAKE|SVs_RMG) #define SVf_OK (SVf_IOK|SVf_NOK|SVf_POK|SVf_ROK| \ SVp_IOK|SVp_NOK|SVp_POK|SVpgv_GP) @@ -378,7 +378,7 @@ perform the upgrade if necessary. See C. SVf_POK, SVp_POK also set: 0x00004400 Normal - 0x0000C400 Studied (SvSCREAM) + 0x0000C400 method name for DOES (SvSCREAM) 0x40004400 FBM compiled (SvVALID) 0x4000C400 pad name. @@ -494,8 +494,6 @@ struct xpvgv { union _xnvu xnv_u; }; -/* This structure must match XPVCV in cv.h */ - typedef U16 cv_flags_t; #define _XPVCV_COMMON \ @@ -517,6 +515,8 @@ typedef U16 cv_flags_t; * sub */ \ cv_flags_t xcv_flags +/* This structure must match XPVCV in cv.h */ + struct xpvfm { _XPV_HEAD; _XPVCV_COMMON; @@ -879,22 +879,58 @@ in gv.h: */ #define SvRMAGICAL_on(sv) (SvFLAGS(sv) |= SVs_RMG) #define SvRMAGICAL_off(sv) (SvFLAGS(sv) &= ~SVs_RMG) -#define SvAMAGIC(sv) (SvROK(sv) && (SvFLAGS(SvRV(sv)) & SVf_AMAGIC)) +#define SvAMAGIC(sv) (SvROK(sv) && SvOBJECT(SvRV(sv)) && \ + HvAMAGIC(SvSTASH(SvRV(sv)))) #if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) # define SvAMAGIC_on(sv) ({ SV * const kloink = sv; \ assert(SvROK(kloink)); \ - SvFLAGS(SvRV(kloink)) |= SVf_AMAGIC; \ + if (SvOBJECT(SvRV(kloink))) \ + HvAMAGIC_on(SvSTASH(SvRV(kloink))); \ }) # define SvAMAGIC_off(sv) ({ SV * const kloink = sv; \ - if(SvROK(kloink)) \ - SvFLAGS(SvRV(kloink)) &= ~SVf_AMAGIC;\ + if(SvROK(kloink) \ + && SvOBJECT(SvRV(kloink))) \ + HvAMAGIC_off(SvSTASH(SvRV(kloink))); \ }) #else -# define SvAMAGIC_on(sv) (SvFLAGS(SvRV(sv)) |= SVf_AMAGIC) +# define SvAMAGIC_on(sv) \ + SvOBJECT(SvRV(sv)) && (SvFLAGS(SvSTASH(SvRV(sv))) |= SVf_AMAGIC) # define SvAMAGIC_off(sv) \ - (SvROK(sv) && (SvFLAGS(SvRV(sv)) &= ~SVf_AMAGIC)) + (SvROK(sv) && SvOBJECT(SvRV(sv)) \ + && (SvFLAGS(SvSTASH(SvRV(sv))) &= ~SVf_AMAGIC)) #endif +/* To be used on the stashes themselves: */ +#define HvAMAGIC(hv) (SvFLAGS(hv) & SVf_AMAGIC) +#define HvAMAGIC_on(hv) (SvFLAGS(hv) |= SVf_AMAGIC) +#define HvAMAGIC_off(hv) (SvFLAGS(hv) &=~ SVf_AMAGIC) + + +#define SvPOK_nog(sv) ((SvFLAGS(sv) & (SVf_POK|SVs_GMG)) == SVf_POK) +#define SvIOK_nog(sv) ((SvFLAGS(sv) & (SVf_IOK|SVs_GMG)) == SVf_IOK) +#define SvUOK_nog(sv) ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV|SVs_GMG)) == (SVf_IOK|SVf_IVisUV)) +#define SvNOK_nog(sv) ((SvFLAGS(sv) & (SVf_NOK|SVs_GMG)) == SVf_NOK) +#define SvNIOK_nog(sv) (SvNIOK(sv) && !(SvFLAGS(sv) & SVs_GMG)) + +#define SvPOK_nogthink(sv) ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST|SVs_GMG)) == SVf_POK) +#define SvIOK_nogthink(sv) ((SvFLAGS(sv) & (SVf_IOK|SVf_THINKFIRST|SVs_GMG)) == SVf_IOK) +#define SvUOK_nogthink(sv) ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV|SVf_THINKFIRST|SVs_GMG)) == (SVf_IOK|SVf_IVisUV)) +#define SvNOK_nogthink(sv) ((SvFLAGS(sv) & (SVf_NOK|SVf_THINKFIRST|SVs_GMG)) == SVf_NOK) +#define SvNIOK_nogthink(sv) (SvNIOK(sv) && !(SvFLAGS(sv) & (SVf_THINKFIRST|SVs_GMG))) + +#define SvPOK_utf8_nog(sv) ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVs_GMG)) == (SVf_POK|SVf_UTF8)) +#define SvPOK_utf8_nogthink(sv) ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_THINKFIRST|SVs_GMG)) == (SVf_POK|SVf_UTF8)) + +#define SvPOK_byte_nog(sv) ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVs_GMG)) == SVf_POK) +#define SvPOK_byte_nogthink(sv) ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_THINKFIRST|SVs_GMG)) == SVf_POK) + +#define SvPOK_pure_nogthink(sv) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_IOK|SVf_NOK|SVf_ROK|SVpgv_GP|SVf_THINKFIRST|SVs_GMG)) == SVf_POK) +#define SvPOK_utf8_pure_nogthink(sv) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_IOK|SVf_NOK|SVf_ROK|SVpgv_GP|SVf_THINKFIRST|SVs_GMG)) == (SVf_POK|SVf_UTF8)) +#define SvPOK_byte_pure_nogthink(sv) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_IOK|SVf_NOK|SVf_ROK|SVpgv_GP|SVf_THINKFIRST|SVs_GMG)) == SVf_POK) + /* =for apidoc Am|U32|SvGAMAGIC|SV* sv @@ -911,7 +947,10 @@ the scalar's value cannot change unless written to. #define SvGAMAGIC(sv) (SvGMAGICAL(sv) || SvAMAGIC(sv)) -#define Gv_AMG(stash) (PL_amagic_generation && Gv_AMupdate(stash, FALSE)) +#define Gv_AMG(stash) \ + (HvNAME(stash) && Gv_AMupdate(stash,FALSE) \ + ? 1 \ + : (HvAMAGIC_off(stash), 0)) #define SvWEAKREF(sv) ((SvFLAGS(sv) & (SVf_ROK|SVprv_WEAKREF)) \ == (SVf_ROK|SVprv_WEAKREF)) @@ -923,6 +962,30 @@ the scalar's value cannot change unless written to. #define SvPCS_IMPORTED_on(sv) (SvFLAGS(sv) |= (SVf_ROK|SVprv_PCS_IMPORTED)) #define SvPCS_IMPORTED_off(sv) (SvFLAGS(sv) &= ~(SVf_ROK|SVprv_PCS_IMPORTED)) +/* +=for apidoc m|U32|SvTHINKFIRST|SV *sv + +A quick flag check to see whether an sv should be passed to sv_force_normal +to be "downgraded" before SvIVX or SvPVX can be modified directly. + +For example, if your scalar is a reference and you want to modify the SvIVX +slot, you can't just do SvROK_off, as that will leak the referent. + +This is used internally by various sv-modifying functions, such as +sv_setsv, sv_setiv and sv_pvn_force. + +One case that this does not handle is a gv without SvFAKE set. After + + if (SvTHINKFIRST(gv)) sv_force_normal(gv); + +it will still be a gv. + +SvTHINKFIRST sometimes produces false positives. In those cases +sv_force_normal does nothing. + +=cut +*/ + #define SvTHINKFIRST(sv) (SvFLAGS(sv) & SVf_THINKFIRST) #define SvPADMY(sv) (SvFLAGS(sv) & SVs_PADMY) @@ -1195,8 +1258,9 @@ the scalar's value cannot change unless written to. STMT_START {if (!SvIOKp(sv) && (SvNOK(sv) || SvPOK(sv))) \ (void) SvIV(sv); } STMT_END #define SvIV_please_nomg(sv) \ - STMT_START {if (!SvIOKp(sv) && (SvNOK(sv) || SvPOK(sv))) \ - (void) SvIV_nomg(sv); } STMT_END + (!SvIOKp(sv) && (SvNOK(sv) || SvPOK(sv)) \ + ? (SvIV_nomg(sv), SvIOK(sv)) \ + : SvIOK(sv)) #define SvIV_set(sv, val) \ STMT_START { \ assert(PL_valid_types_IV_set[SvTYPE(sv) & SVt_MASK]); \ @@ -1402,14 +1466,14 @@ attention to precisely which outputs are influenced by which inputs. /* =for apidoc Am|char*|SvPV_force|SV* sv|STRLEN len -Like C but will force the SV into containing just a string -(C). You want force if you are going to update the C -directly. +Like C but will force the SV into containing a string (C), and +only a (C), by hook or by crook. You want force if you are +going to update the C directly. Processes get magic. =for apidoc Am|char*|SvPV_force_nomg|SV* sv|STRLEN len -Like C but will force the SV into containing just a string -(C). You want force if you are going to update the C -directly. Doesn't process magic. +Like C but will force the SV into containing a string (C), and +only a (C), by hook or by crook. You want force if you are +going to update the C directly. Doesn't process get magic. =for apidoc Am|char*|SvPV|SV* sv|STRLEN len Returns a pointer to the string in the SV, or a stringified form of @@ -1549,9 +1613,9 @@ Like sv_utf8_upgrade, but doesn't do magic on C. */ /* Let us hope that bitmaps for UV and IV are the same */ -#define SvIV(sv) (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) -#define SvUV(sv) (SvIOK(sv) ? SvUVX(sv) : sv_2uv(sv)) -#define SvNV(sv) (SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv)) +#define SvIV(sv) (SvIOK_nog(sv) ? SvIVX(sv) : sv_2iv(sv)) +#define SvUV(sv) (SvUOK_nog(sv) ? SvUVX(sv) : sv_2uv(sv)) +#define SvNV(sv) (SvNOK_nog(sv) ? SvNVX(sv) : sv_2nv(sv)) #define SvIV_nomg(sv) (SvIOK(sv) ? SvIVX(sv) : sv_2iv_flags(sv, 0)) #define SvUV_nomg(sv) (SvIOK(sv) ? SvUVX(sv) : sv_2uv_flags(sv, 0)) @@ -1559,23 +1623,23 @@ Like sv_utf8_upgrade, but doesn't do magic on C. /* ----*/ -#define SvPV(sv, lp) SvPV_flags(sv, lp, SV_GMAGIC) -#define SvPV_const(sv, lp) SvPV_flags_const(sv, lp, SV_GMAGIC) +#define SvPV(sv, lp) SvPV_flags(sv, lp, SV_GMAGIC) +#define SvPV_const(sv, lp) SvPV_flags_const(sv, lp, SV_GMAGIC) #define SvPV_mutable(sv, lp) SvPV_flags_mutable(sv, lp, SV_GMAGIC) #define SvPV_flags(sv, lp, flags) \ - ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + (SvPOK_nog(sv) \ ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv_flags(sv, &lp, flags)) #define SvPV_flags_const(sv, lp, flags) \ - ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + (SvPOK_nog(sv) \ ? ((lp = SvCUR(sv)), SvPVX_const(sv)) : \ (const char*) sv_2pv_flags(sv, &lp, flags|SV_CONST_RETURN)) #define SvPV_flags_const_nolen(sv, flags) \ - ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + (SvPOK_nog(sv) \ ? SvPVX_const(sv) : \ (const char*) sv_2pv_flags(sv, 0, flags|SV_CONST_RETURN)) #define SvPV_flags_mutable(sv, lp, flags) \ - ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + (SvPOK_nog(sv) \ ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) : \ sv_2pv_flags(sv, &lp, flags|SV_MUTABLE_RETURN)) @@ -1587,26 +1651,28 @@ Like sv_utf8_upgrade, but doesn't do magic on C. #define SvPV_force_nomg_nolen(sv) SvPV_force_flags_nolen(sv, 0) #define SvPV_force_flags(sv, lp, flags) \ - ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ - ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force_flags(sv, &lp, flags)) + (SvPOK_pure_nogthink(sv) \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force_flags(sv, &lp, flags)) + #define SvPV_force_flags_nolen(sv, flags) \ - ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ - ? SvPVX(sv) : sv_pvn_force_flags(sv, 0, flags)) + (SvPOK_pure_nogthink(sv) \ + ? SvPVX(sv) : sv_pvn_force_flags(sv, 0, flags)) + #define SvPV_force_flags_mutable(sv, lp, flags) \ - ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ - ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) \ + (SvPOK_pure_nogthink(sv) \ + ? ((lp = SvCUR(sv)), SvPVX_mutable(sv)) \ : sv_pvn_force_flags(sv, &lp, flags|SV_MUTABLE_RETURN)) #define SvPV_nolen(sv) \ - ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + (SvPOK_nog(sv) \ ? SvPVX(sv) : sv_2pv_flags(sv, 0, SV_GMAGIC)) #define SvPV_nomg_nolen(sv) \ - ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + (SvPOK_nog(sv) \ ? SvPVX(sv) : sv_2pv_flags(sv, 0, 0)) #define SvPV_nolen_const(sv) \ - ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + (SvPOK_nog(sv) \ ? SvPVX_const(sv) : sv_2pv_flags(sv, 0, SV_GMAGIC|SV_CONST_RETURN)) #define SvPV_nomg(sv, lp) SvPV_flags(sv, lp, 0) @@ -1616,33 +1682,31 @@ Like sv_utf8_upgrade, but doesn't do magic on C. /* ----*/ #define SvPVutf8(sv, lp) \ - ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK|SVf_UTF8) \ + (SvPOK_utf8_nog(sv) \ ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvutf8(sv, &lp)) #define SvPVutf8_force(sv, lp) \ - ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_THINKFIRST)) == (SVf_POK|SVf_UTF8) \ + (SvPOK_utf8_pure_nogthink(sv) \ ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvutf8n_force(sv, &lp)) - #define SvPVutf8_nolen(sv) \ - ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK|SVf_UTF8)\ + (SvPOK_utf8_nog(sv) \ ? SvPVX(sv) : sv_2pvutf8(sv, 0)) /* ----*/ #define SvPVbyte(sv, lp) \ - ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \ + (SvPOK_byte_nog(sv) \ ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte(sv, &lp)) #define SvPVbyte_force(sv, lp) \ - ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_THINKFIRST)) == (SVf_POK) \ + (SvPOK_byte_pure_nogthink(sv) \ ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvbyten_force(sv, &lp)) #define SvPVbyte_nolen(sv) \ - ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK)\ + (SvPOK_byte_nog(sv) \ ? SvPVX(sv) : sv_2pvbyte(sv, 0)) - /* define FOOx(): idempotent versions of FOO(). If possible, use a local * var to evaluate the arg once; failing that, use a global if possible; @@ -1653,6 +1717,17 @@ Like sv_utf8_upgrade, but doesn't do magic on C. #define SvPVutf8x_force(sv, lp) sv_pvutf8n_force(sv, &lp) #define SvPVbytex_force(sv, lp) sv_pvbyten_force(sv, &lp) +#define SvTRUE(sv) ((sv) && (SvGMAGICAL(sv) ? sv_2bool(sv) : SvTRUE_common(sv, sv_2bool_nomg(sv)))) +#define SvTRUE_nomg(sv) ((sv) && ( SvTRUE_common(sv, sv_2bool_nomg(sv)))) +#define SvTRUE_common(sv,fallback) ( \ + !SvOK(sv) \ + ? 0 \ + : (SvFLAGS(sv) & (SVf_POK|SVf_IOK|SVf_NOK)) \ + ? ( (SvPOK(sv) && SvPVXtrue(sv)) \ + || (SvIOK(sv) && SvIVX(sv) != 0) \ + || (SvNOK(sv) && SvNVX(sv) != 0.0)) \ + : (fallback)) + #if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN) # define SvIVx(sv) ({SV *_sv = MUTABLE_SV(sv); SvIV(_sv); }) @@ -1665,39 +1740,13 @@ Like sv_utf8_upgrade, but doesn't do magic on C. # define SvPVutf8x(sv, lp) ({SV *_sv = (sv); SvPVutf8(_sv, lp); }) # define SvPVbytex(sv, lp) ({SV *_sv = (sv); SvPVbyte(_sv, lp); }) # define SvPVbytex_nolen(sv) ({SV *_sv = (sv); SvPVbyte_nolen(_sv); }) -# define SvTRUE(sv) ( \ - !sv \ - ? 0 \ - : SvPOK(sv) \ - ? (({XPV *nxpv = (XPV*)SvANY(sv); \ - nxpv && \ - (nxpv->xpv_cur > 1 || \ - (nxpv->xpv_cur && *(sv)->sv_u.svu_pv != '0')); }) \ - ? 1 \ - : 0) \ - : \ - SvIOK(sv) \ - ? SvIVX(sv) != 0 \ - : SvNOK(sv) \ - ? SvNVX(sv) != 0.0 \ - : sv_2bool(sv) ) -# define SvTRUE_nomg(sv) ( \ - !sv \ - ? 0 \ - : SvPOK(sv) \ - ? (({XPV *nxpv = (XPV*)SvANY(sv); \ - nxpv && \ - (nxpv->xpv_cur > 1 || \ - (nxpv->xpv_cur && *(sv)->sv_u.svu_pv != '0')); }) \ - ? 1 \ - : 0) \ - : \ - SvIOK(sv) \ - ? SvIVX(sv) != 0 \ - : SvNOK(sv) \ - ? SvNVX(sv) != 0.0 \ - : sv_2bool_flags(sv,0) ) -# define SvTRUEx(sv) ({SV *_sv = (sv); SvTRUE(_sv); }) +# define SvTRUEx(sv) ({SV *_sv = (sv); SvTRUE(_sv); }) +# define SvTRUEx_nomg(sv) ({SV *_sv = (sv); SvTRUE_nomg(_sv); }) +# define SvPVXtrue(sv) \ + ({XPV *nxpv; \ + (nxpv = (XPV*)SvANY(sv)) \ + && (nxpv->xpv_cur > 1 \ + || (nxpv->xpv_cur && *(sv)->sv_u.svu_pv != '0'));}) #else /* __GNUC__ */ @@ -1714,37 +1763,12 @@ Like sv_utf8_upgrade, but doesn't do magic on C. # define SvPVutf8x(sv, lp) ((PL_Sv = (sv)), SvPVutf8(PL_Sv, lp)) # define SvPVbytex(sv, lp) ((PL_Sv = (sv)), SvPVbyte(PL_Sv, lp)) # define SvPVbytex_nolen(sv) ((PL_Sv = (sv)), SvPVbyte_nolen(PL_Sv)) -# define SvTRUE(sv) ( \ - !sv \ - ? 0 \ - : SvPOK(sv) \ - ? ((PL_Xpv = (XPV*)SvANY(PL_Sv = (sv))) && \ - (PL_Xpv->xpv_cur > 1 || \ - (PL_Xpv->xpv_cur && *PL_Sv->sv_u.svu_pv != '0')) \ - ? 1 \ - : 0) \ - : \ - SvIOK(sv) \ - ? SvIVX(sv) != 0 \ - : SvNOK(sv) \ - ? SvNVX(sv) != 0.0 \ - : sv_2bool(sv) ) -# define SvTRUE_nomg(sv) ( \ - !sv \ - ? 0 \ - : SvPOK(sv) \ - ? ((PL_Xpv = (XPV*)SvANY(PL_Sv = (sv))) && \ - (PL_Xpv->xpv_cur > 1 || \ - (PL_Xpv->xpv_cur && *PL_Sv->sv_u.svu_pv != '0')) \ - ? 1 \ - : 0) \ - : \ - SvIOK(sv) \ - ? SvIVX(sv) != 0 \ - : SvNOK(sv) \ - ? SvNVX(sv) != 0.0 \ - : sv_2bool_flags(sv,0) ) -# define SvTRUEx(sv) ((PL_Sv = (sv)), SvTRUE(PL_Sv)) +# define SvTRUEx(sv) ((PL_Sv = (sv)), SvTRUE(PL_Sv)) +# define SvTRUEx_nomg(sv) ((PL_Sv = (sv)), SvTRUE_nomg(PL_Sv)) +# define SvPVXtrue(sv) \ + ((PL_Xpv = (XPV*)SvANY(PL_Sv = (sv))) \ + && (PL_Xpv->xpv_cur > 1 \ + || (PL_Xpv->xpv_cur && *PL_Sv->sv_u.svu_pv != '0'))) #endif /* __GNU__ */ #define SvIsCOW(sv) ((SvFLAGS(sv) & (SVf_FAKE | SVf_READONLY)) == \ @@ -1854,8 +1878,9 @@ mg.c:1024: warning: left-hand operand of comma expression has no effect #define sv_catsv_nomg(dsv, ssv) sv_catsv_flags(dsv, ssv, 0) #define sv_catsv_mg(dsv, ssv) sv_catsv_flags(dsv, ssv, SV_GMAGIC|SV_SMAGIC) #define sv_catpvn(dsv, sstr, slen) sv_catpvn_flags(dsv, sstr, slen, SV_GMAGIC) -#define sv_catpvn_mg(sv, sstr, slen) \ - sv_catpvn_flags(sv, sstr, slen, SV_GMAGIC|SV_SMAGIC); +#define sv_catpvn_mg(sv, sstr, slen) sv_catpvn_flags(sv, sstr, slen, SV_GMAGIC|SV_SMAGIC); +#define sv_copypv(dsv, ssv) sv_copypv_flags(dsv, ssv, SV_GMAGIC) +#define sv_copypv_nomg(dsv, ssv) sv_copypv_flags(dsv, ssv, 0) #define sv_2pv(sv, lp) sv_2pv_flags(sv, lp, SV_GMAGIC) #define sv_2pv_nolen(sv) sv_2pv(sv, 0) #define sv_2pvbyte_nolen(sv) sv_2pvbyte(sv, 0) @@ -1871,12 +1896,13 @@ mg.c:1024: warning: left-hand operand of comma expression has no effect #define sv_cmp_locale(sv1, sv2) sv_cmp_locale_flags(sv1, sv2, SV_GMAGIC) #define sv_collxfrm(sv, nxp) sv_cmp_flags(sv, nxp, SV_GMAGIC) #define sv_2bool(sv) sv_2bool_flags(sv, SV_GMAGIC) +#define sv_2bool_nomg(sv) sv_2bool_flags(sv, 0) #define sv_insert(bigstr, offset, len, little, littlelen) \ Perl_sv_insert_flags(aTHX_ (bigstr),(offset), (len), (little), \ (littlelen), SV_GMAGIC) /* Should be named SvCatPVN_utf8_upgrade? */ -#define sv_catpvn_utf8_upgrade(dsv, sstr, slen, nsv) \ +#define sv_catpvn_nomg_utf8_upgrade(dsv, sstr, slen, nsv) \ STMT_START { \ if (!(nsv)) \ nsv = newSVpvn_flags(sstr, slen, SVs_TEMP); \ @@ -1884,7 +1910,7 @@ mg.c:1024: warning: left-hand operand of comma expression has no effect sv_setpvn(nsv, sstr, slen); \ SvUTF8_off(nsv); \ sv_utf8_upgrade(nsv); \ - sv_catsv(dsv, nsv); \ + sv_catsv_nomg(dsv, nsv); \ } STMT_END /* @@ -1904,11 +1930,14 @@ incremented. =head1 Magical Functions =for apidoc Am|void|SvGETMAGIC|SV* sv -Invokes C on an SV if it has 'get' magic. This macro evaluates its +Invokes C on an SV if it has 'get' magic. For example, this +will call C on a tied variable. This macro evaluates its argument more than once. =for apidoc Am|void|SvSETMAGIC|SV* sv -Invokes C on an SV if it has 'set' magic. This macro evaluates its +Invokes C on an SV if it has 'set' magic. This is necessary +after modifying a scalar, in case it is a magical variable like C<$|> +or a tied variable (it calls C). This macro evaluates its argument more than once. =for apidoc Am|void|SvSetSV|SV* dsb|SV* ssv @@ -2071,23 +2100,23 @@ Evaluates I more than once. Sets I to 0 if C is false. # define SvOOK_offset(sv, offset) STMT_START { \ assert(sizeof(offset) == sizeof(STRLEN)); \ if (SvOOK(sv)) { \ - const U8 *crash = (U8*)SvPVX_const(sv); \ - offset = *--crash; \ - if (!offset) { \ - crash -= sizeof(STRLEN); \ - Copy(crash, (U8 *)&offset, sizeof(STRLEN), U8); \ + const U8 *_crash = (U8*)SvPVX_const(sv); \ + (offset) = *--_crash; \ + if (!(offset)) { \ + _crash -= sizeof(STRLEN); \ + Copy(_crash, (U8 *)&(offset), sizeof(STRLEN), U8); \ } \ { \ /* Validate the preceding buffer's sentinels to \ verify that no-one is using it. */ \ - const U8 *const bonk = (U8 *) SvPVX_const(sv) - offset; \ - while (crash > bonk) { \ - --crash; \ - assert (*crash == (U8)PTR2UV(crash)); \ + const U8 *const _bonk = (U8*)SvPVX_const(sv) - (offset);\ + while (_crash > _bonk) { \ + --_crash; \ + assert (*_crash == (U8)PTR2UV(_crash)); \ } \ } \ } else { \ - offset = 0; \ + (offset) = 0; \ } \ } STMT_END #else @@ -2095,13 +2124,13 @@ Evaluates I more than once. Sets I to 0 if C is false. # define SvOOK_offset(sv, offset) STMT_START { \ assert(sizeof(offset) == sizeof(STRLEN)); \ if (SvOOK(sv)) { \ - offset = ((U8*)SvPVX_const(sv))[-1]; \ - if (!offset) { \ + (offset) = ((U8*)SvPVX_const(sv))[-1]; \ + if (!(offset)) { \ Copy(SvPVX_const(sv) - 1 - sizeof(STRLEN), \ - (U8 *)&offset, sizeof(STRLEN), U8); \ + (U8*)&(offset), sizeof(STRLEN), U8); \ } \ } else { \ - offset = 0; \ + (offset) = 0; \ } \ } STMT_END #endif @@ -2112,8 +2141,8 @@ Evaluates I more than once. Sets I to 0 if C is false. * Local variables: * c-indentation-style: bsd * c-basic-offset: 4 - * indent-tabs-mode: t + * indent-tabs-mode: nil * End: * - * ex: set ts=8 sts=4 sw=4 noet: + * ex: set ts=8 sts=4 sw=4 et: */