X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=blobdiff_plain;f=sv.h;h=b6e819fff651b62cfb82c628f8b37ee005b60419;hb=4ff843088efaf20f33954a488d457e0ee0278019;hp=5ebb337888e0df306c8f10a1e75f626bd225dc92;hpb=ed6116ce9b9d13712ea252ee248b0400653db7f9;p=p5sagit%2Fp5-mst-13.2.git diff --git a/sv.h b/sv.h index 5ebb337..b6e819f 100644 --- a/sv.h +++ b/sv.h @@ -1,144 +1,178 @@ -/* $RCSfile: sv.h,v $$Revision: 4.1 $$Date: 92/08/07 18:26:57 $ +/* sv.h * - * Copyright (c) 1991, Larry Wall + * Copyright (c) 1991-1999, Larry Wall * * You may distribute under the terms of either the GNU General Public * License or the Artistic License, as specified in the README file. * - * $Log: sv.h,v $ - * Revision 4.1 92/08/07 18:26:57 lwall - * - * Revision 4.0.1.4 92/06/08 15:41:45 lwall - * patch20: fixed confusion between a *var's real name and its effective name - * patch20: removed implicit int declarations on functions - * - * Revision 4.0.1.3 91/11/05 18:41:47 lwall - * patch11: random cleanup - * patch11: solitary subroutine references no longer trigger typo warnings - * - * Revision 4.0.1.2 91/06/07 11:58:33 lwall - * patch4: new copyright notice - * - * Revision 4.0.1.1 91/04/12 09:16:12 lwall - * patch1: you may now use "die" and "caller" in a signal handler - * - * Revision 4.0 91/03/20 01:40:04 lwall - * 4.0 baseline. - * */ +#ifdef sv_flags +#undef sv_flags /* Convex has this in for sigvec() */ +#endif + typedef enum { - SVt_NULL, - SVt_IV, - SVt_NV, - SVt_RV, - SVt_PV, - SVt_PVIV, - SVt_PVNV, - SVt_PVMG, - SVt_PVLV, - SVt_PVAV, - SVt_PVHV, - SVt_PVCV, - SVt_PVGV, - SVt_PVBM, - SVt_PVFM, + SVt_NULL, /* 0 */ + SVt_IV, /* 1 */ + SVt_NV, /* 2 */ + SVt_RV, /* 3 */ + SVt_PV, /* 4 */ + SVt_PVIV, /* 5 */ + SVt_PVNV, /* 6 */ + SVt_PVMG, /* 7 */ + SVt_PVBM, /* 8 */ + SVt_PVLV, /* 9 */ + SVt_PVAV, /* 10 */ + SVt_PVHV, /* 11 */ + SVt_PVCV, /* 12 */ + SVt_PVGV, /* 13 */ + SVt_PVFM, /* 14 */ + SVt_PVIO /* 15 */ } svtype; -/* Compensate for ANSI C misdesign... */ -#ifdef DEBUGGING -#define SVTYPE svtype -#else -#define SVTYPE U8 -#endif - /* Using C's structural equivalence to help emulate C++ inheritance here... */ struct sv { void* sv_any; /* pointer to something */ U32 sv_refcnt; /* how many references to us */ - SVTYPE sv_type; /* what sort of thing pointer points to */ - U8 sv_flags; /* extra flags, some depending on type */ - U8 sv_storage; /* storage class */ - U8 sv_private; /* extra value, depending on type */ + U32 sv_flags; /* what we are */ }; struct gv { XPVGV* sv_any; /* pointer to something */ U32 sv_refcnt; /* how many references to us */ - SVTYPE sv_type; /* what sort of thing pointer points to */ - U8 sv_flags; /* extra flags, some depending on type */ - U8 sv_storage; /* storage class */ - U8 sv_private; /* extra value, depending on type */ + U32 sv_flags; /* what we are */ }; struct cv { - XPVGV* sv_any; /* pointer to something */ + XPVCV* sv_any; /* pointer to something */ U32 sv_refcnt; /* how many references to us */ - SVTYPE sv_type; /* what sort of thing pointer points to */ - U8 sv_flags; /* extra flags, some depending on type */ - U8 sv_storage; /* storage class */ - U8 sv_private; /* extra value, depending on type */ + U32 sv_flags; /* what we are */ }; struct av { XPVAV* sv_any; /* pointer to something */ U32 sv_refcnt; /* how many references to us */ - SVTYPE sv_type; /* what sort of thing pointer points to */ - U8 sv_flags; /* extra flags, some depending on type */ - U8 sv_storage; /* storage class */ - U8 sv_private; /* extra value, depending on type */ + U32 sv_flags; /* what we are */ }; struct hv { XPVHV* sv_any; /* pointer to something */ U32 sv_refcnt; /* how many references to us */ - SVTYPE sv_type; /* what sort of thing pointer points to */ - U8 sv_flags; /* extra flags, some depending on type */ - U8 sv_storage; /* storage class */ - U8 sv_private; /* extra value, depending on type */ + U32 sv_flags; /* what we are */ +}; + +struct io { + XPVIO* sv_any; /* pointer to something */ + U32 sv_refcnt; /* how many references to us */ + U32 sv_flags; /* what we are */ }; #define SvANY(sv) (sv)->sv_any -#define SvTYPE(sv) (sv)->sv_type -#define SvREFCNT(sv) (sv)->sv_refcnt #define SvFLAGS(sv) (sv)->sv_flags -#define SvSTORAGE(sv) (sv)->sv_storage -#define SvPRIVATE(sv) (sv)->sv_private +#define SvREFCNT(sv) (sv)->sv_refcnt + +#ifdef USE_THREADS + +# ifdef EMULATE_ATOMIC_REFCOUNTS +# define ATOMIC_INC(count) STMT_START { \ + MUTEX_LOCK(&PL_svref_mutex); \ + ++count; \ + MUTEX_UNLOCK(&PL_svref_mutex); \ + } STMT_END +# define ATOMIC_DEC_AND_TEST(res,count) STMT_START { \ + MUTEX_LOCK(&PL_svref_mutex); \ + res = (--count == 0); \ + MUTEX_UNLOCK(&PL_svref_mutex); \ + } STMT_END +# else +# define ATOMIC_INC(count) atomic_inc(&count) +# define ATOMIC_DEC_AND_TEST(res,count) (res = atomic_dec_and_test(&count)) +# endif /* EMULATE_ATOMIC_REFCOUNTS */ +#else +# define ATOMIC_INC(count) (++count) +# define ATOMIC_DEC_AND_TEST(res, count) (res = (--count == 0)) +#endif /* USE_THREADS */ + +#ifdef __GNUC__ +# define SvREFCNT_inc(sv) \ + ({ \ + SV *nsv = (SV*)(sv); \ + if (nsv) \ + ATOMIC_INC(SvREFCNT(nsv)); \ + nsv; \ + }) +#else +# if defined(CRIPPLED_CC) || defined(USE_THREADS) +# define SvREFCNT_inc(sv) sv_newref((SV*)sv) +# else +# define SvREFCNT_inc(sv) \ + ((PL_Sv=(SV*)(sv)), (PL_Sv && ATOMIC_INC(SvREFCNT(PL_Sv))), (SV*)PL_Sv) +# endif +#endif + +#define SvREFCNT_dec(sv) sv_free((SV*)sv) + +#define SVTYPEMASK 0xff +#define SvTYPE(sv) ((sv)->sv_flags & SVTYPEMASK) #define SvUPGRADE(sv, mt) (SvTYPE(sv) >= mt || sv_upgrade(sv, mt)) -#define SVf_IOK 1 /* has valid integer value */ -#define SVf_NOK 2 /* has valid numeric value */ -#define SVf_POK 4 /* has valid pointer value */ -#define SVf_OOK 8 /* has valid offset value */ -#define SVf_ROK 16 /* has a valid reference pointer */ -#define SVf_OK 32 /* has defined value */ -#define SVf_MAGICAL 64 /* has special methods */ -#define SVf_THINKFIRST 128 /* may not be changed without thought */ - -#define SVs_PADBUSY 1 /* reserved for tmp or my already */ -#define SVs_PADTMP 2 /* in use as tmp */ -#define SVs_PADMY 4 /* in use a "my" variable */ -#define SVs_8 8 -#define SVs_16 16 -#define SVs_TEMP 32 /* string is stealable? */ -#define SVs_OBJECT 64 /* is "blessed" */ -#define SVs_READONLY 128 /* may not be modified */ - -#define SVp_IOK 1 /* has valid non-public integer value */ -#define SVp_NOK 2 /* has valid non-public numeric value */ -#define SVp_POK 4 /* has valid non-public pointer value */ -#define SVp_SCREAM 8 /* has been studied? */ -#define SVp_TAINTEDDIR 16 /* PATH component is a security risk */ - -#define SVpfm_COMPILED 128 - -#define SVpbm_VALID 128 -#define SVpbm_CASEFOLD 64 -#define SVpbm_TAIL 32 - -#define SVpgv_MULTI 128 +#define SVs_PADBUSY 0x00000100 /* reserved for tmp or my already */ +#define SVs_PADTMP 0x00000200 /* in use as tmp */ +#define SVs_PADMY 0x00000400 /* in use a "my" variable */ +#define SVs_TEMP 0x00000800 /* string is stealable? */ +#define SVs_OBJECT 0x00001000 /* is "blessed" */ +#define SVs_GMG 0x00002000 /* has magical get method */ +#define SVs_SMG 0x00004000 /* has magical set method */ +#define SVs_RMG 0x00008000 /* has random magical methods */ + +#define SVf_IOK 0x00010000 /* has valid public integer value */ +#define SVf_NOK 0x00020000 /* has valid public numeric value */ +#define SVf_POK 0x00040000 /* has valid public pointer value */ +#define SVf_ROK 0x00080000 /* has a valid reference pointer */ + +#define SVf_FAKE 0x00100000 /* glob or lexical is just a copy */ +#define SVf_OOK 0x00200000 /* has valid offset value */ +#define SVf_BREAK 0x00400000 /* refcnt is artificially low */ +#define SVf_READONLY 0x00800000 /* may not be modified */ + + +#define SVp_IOK 0x01000000 /* has valid non-public integer value */ +#define SVp_NOK 0x02000000 /* has valid non-public numeric value */ +#define SVp_POK 0x04000000 /* has valid non-public pointer value */ +#define SVp_SCREAM 0x08000000 /* has been studied? */ + +#define SVf_UTF8 0x20000000 /* SvPVX is UTF-8 encoded */ + +#define SVf_THINKFIRST (SVf_READONLY|SVf_ROK|SVf_FAKE|SVf_UTF8) + +#define SVf_OK (SVf_IOK|SVf_NOK|SVf_POK|SVf_ROK| \ + SVp_IOK|SVp_NOK|SVp_POK) + +#define SVf_AMAGIC 0x10000000 /* has magical overloaded methods */ + +#define PRIVSHIFT 8 + +/* Some private flags. */ + +#define SVpad_OUR 0x80000000 /* pad name is "our" instead of "my" */ + +#define SVpad_OUR 0x80000000 /* pad name is "our" instead of "my" */ + +#define SVf_IVisUV 0x80000000 /* use XPVUV instead of XPVIV */ + +#define SVpfm_COMPILED 0x80000000 /* FORMLINE is compiled */ + +#define SVpbm_VALID 0x80000000 +#define SVpbm_TAIL 0x40000000 + +#define SVrepl_EVAL 0x40000000 /* Replacement part of s///e */ + +#define SVphv_SHAREKEYS 0x20000000 /* keys live on shared string table */ +#define SVphv_LAZYDEL 0x40000000 /* entry in xhv_eiter must be deleted */ + +#define SVprv_WEAKREF 0x80000000 /* Weak reference */ struct xrv { SV * xrv_rv; /* pointer to another SV */ @@ -154,23 +188,31 @@ struct xpviv { char * xpv_pv; /* pointer to malloced string */ STRLEN xpv_cur; /* length of xpv_pv as a C string */ STRLEN xpv_len; /* allocated size */ - I32 xiv_iv; /* integer value or pv offset */ + IV xiv_iv; /* integer value or pv offset */ +}; + +struct xpvuv { + char * xpv_pv; /* pointer to malloced string */ + STRLEN xpv_cur; /* length of xpv_pv as a C string */ + STRLEN xpv_len; /* allocated size */ + UV xuv_uv; /* unsigned value or pv offset */ }; struct xpvnv { char * xpv_pv; /* pointer to malloced string */ STRLEN xpv_cur; /* length of xpv_pv as a C string */ STRLEN xpv_len; /* allocated size */ - I32 xiv_iv; /* integer value or pv offset */ - double xnv_nv; /* numeric value, if any */ + IV xiv_iv; /* integer value or pv offset */ + NV xnv_nv; /* numeric value, if any */ }; +/* These structure must match the beginning of struct xpvhv in hv.h. */ struct xpvmg { char * xpv_pv; /* pointer to malloced string */ STRLEN xpv_cur; /* length of xpv_pv as a C string */ STRLEN xpv_len; /* allocated size */ - I32 xiv_iv; /* integer value or pv offset */ - double xnv_nv; /* numeric value, if any */ + IV xiv_iv; /* integer value or pv offset */ + NV xnv_nv; /* numeric value, if any */ MAGIC* xmg_magic; /* linked list of magicalness */ HV* xmg_stash; /* class package */ }; @@ -179,10 +221,11 @@ struct xpvlv { char * xpv_pv; /* pointer to malloced string */ STRLEN xpv_cur; /* length of xpv_pv as a C string */ STRLEN xpv_len; /* allocated size */ - I32 xiv_iv; /* integer value or pv offset */ - double xnv_nv; /* numeric value, if any */ + IV xiv_iv; /* integer value or pv offset */ + NV xnv_nv; /* numeric value, if any */ MAGIC* xmg_magic; /* linked list of magicalness */ HV* xmg_stash; /* class package */ + STRLEN xlv_targoff; STRLEN xlv_targlen; SV* xlv_targ; @@ -193,149 +236,249 @@ struct xpvgv { char * xpv_pv; /* pointer to malloced string */ STRLEN xpv_cur; /* length of xpv_pv as a C string */ STRLEN xpv_len; /* allocated size */ - I32 xiv_iv; /* integer value or pv offset */ - double xnv_nv; /* numeric value, if any */ + IV xiv_iv; /* integer value or pv offset */ + NV xnv_nv; /* numeric value, if any */ MAGIC* xmg_magic; /* linked list of magicalness */ HV* xmg_stash; /* class package */ + GP* xgv_gp; char* xgv_name; STRLEN xgv_namelen; HV* xgv_stash; + U8 xgv_flags; }; struct xpvbm { char * xpv_pv; /* pointer to malloced string */ STRLEN xpv_cur; /* length of xpv_pv as a C string */ STRLEN xpv_len; /* allocated size */ - I32 xiv_iv; /* integer value or pv offset */ - double xnv_nv; /* numeric value, if any */ + IV xiv_iv; /* integer value or pv offset */ + NV xnv_nv; /* numeric value, if any */ MAGIC* xmg_magic; /* linked list of magicalness */ HV* xmg_stash; /* class package */ + I32 xbm_useful; /* is this constant pattern being useful? */ U16 xbm_previous; /* how many characters in string before rare? */ U8 xbm_rare; /* rarest character in string */ }; +/* This structure much match XPVCV in cv.h */ + +typedef U16 cv_flags_t; + struct xpvfm { char * xpv_pv; /* pointer to malloced string */ STRLEN xpv_cur; /* length of xpv_pv as a C string */ STRLEN xpv_len; /* allocated size */ - I32 xiv_iv; /* integer value or pv offset */ - double xnv_nv; /* numeric value, if any */ + IV xiv_iv; /* integer value or pv offset */ + NV xnv_nv; /* numeric value, if any */ MAGIC* xmg_magic; /* linked list of magicalness */ HV* xmg_stash; /* class package */ + HV * xcv_stash; OP * xcv_start; OP * xcv_root; - I32 (*xcv_usersub)(); - I32 xcv_userindex; - GV * xcv_filegv; - long xcv_depth; /* >= 2 indicates recursive call */ + void (*xcv_xsub)(pTHXo_ CV*); + ANY xcv_xsubany; + GV * xcv_gv; + char * xcv_file; + long xcv_depth; /* >= 2 indicates recursive call */ AV * xcv_padlist; - bool xcv_deleted; + CV * xcv_outside; +#ifdef USE_THREADS + perl_mutex *xcv_mutexp; /* protects xcv_owner */ + struct perl_thread *xcv_owner; /* current owner thread */ +#endif /* USE_THREADS */ + cv_flags_t xcv_flags; + I32 xfm_lines; }; +struct xpvio { + char * xpv_pv; /* pointer to malloced string */ + STRLEN xpv_cur; /* length of xpv_pv as a C string */ + STRLEN xpv_len; /* allocated size */ + IV xiv_iv; /* integer value or pv offset */ + NV xnv_nv; /* numeric value, if any */ + MAGIC* xmg_magic; /* linked list of magicalness */ + HV* xmg_stash; /* class package */ + + PerlIO * xio_ifp; /* ifp and ofp are normally the same */ + PerlIO * xio_ofp; /* but sockets need separate streams */ + DIR * xio_dirp; /* for opendir, readdir, etc */ + long xio_lines; /* $. */ + long xio_page; /* $% */ + long xio_page_len; /* $= */ + long xio_lines_left; /* $- */ + char * xio_top_name; /* $^ */ + GV * xio_top_gv; /* $^ */ + char * xio_fmt_name; /* $~ */ + GV * xio_fmt_gv; /* $~ */ + char * xio_bottom_name;/* $^B */ + GV * xio_bottom_gv; /* $^B */ + short xio_subprocess; /* -| or |- */ + char xio_type; + char xio_flags; +}; + +#define IOf_ARGV 1 /* this fp iterates over ARGV */ +#define IOf_START 2 /* check for null ARGV and substitute '-' */ +#define IOf_FLUSH 4 /* this fp wants a flush after write op */ +#define IOf_DIDTOP 8 /* just did top of form */ +#define IOf_UNTAINT 16 /* consider this fp (and its data) "safe" */ +#define IOf_NOLINE 32 /* slurped a pseudo-line from empty file */ +#define IOf_FAKE_DIRP 64 /* xio_dirp is fake (source filters kludge) */ + /* The following macros define implementation-independent predicates on SVs. */ #define SvNIOK(sv) (SvFLAGS(sv) & (SVf_IOK|SVf_NOK)) +#define SvNIOKp(sv) (SvFLAGS(sv) & (SVp_IOK|SVp_NOK)) +#define SvNIOK_off(sv) (SvFLAGS(sv) &= ~(SVf_IOK|SVf_NOK| \ + SVp_IOK|SVp_NOK|SVf_IVisUV)) #define SvOK(sv) (SvFLAGS(sv) & SVf_OK) -#define SvOK_on(sv) (SvFLAGS(sv) |= SVf_OK) -#define SvOK_off(sv) (SvFLAGS(sv) &= \ - ~(SVf_IOK|SVf_NOK|SVf_POK|SVf_OK), \ - SvOOK_off(sv)) - -#define SvOKp(sv) (SvPRIVATE(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) -#define SvIOKp(sv) (SvPRIVATE(sv) & SVp_IOK) -#define SvIOKp_on(sv) (SvOOK_off(sv), SvPRIVATE(sv) |= SVp_IOK) -#define SvNOKp(sv) (SvPRIVATE(sv) & SVp_NOK) -#define SvNOKp_on(sv) (SvPRIVATE(sv) |= SVp_NOK) -#define SvPOKp(sv) (SvPRIVATE(sv) & SVp_POK) -#define SvPOKp_on(sv) (SvPRIVATE(sv) |= SVp_POK) +#define SvOK_off(sv) (SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC| \ + SVf_IVisUV), \ + SvOOK_off(sv)) +#define SvOK_off_exc_UV(sv) (SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC), \ + SvOOK_off(sv)) + +#define SvOKp(sv) (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) +#define SvIOKp(sv) (SvFLAGS(sv) & SVp_IOK) +#define SvIOKp_on(sv) (SvOOK_off(sv), SvFLAGS(sv) |= SVp_IOK) +#define SvNOKp(sv) (SvFLAGS(sv) & SVp_NOK) +#define SvNOKp_on(sv) (SvFLAGS(sv) |= SVp_NOK) +#define SvPOKp(sv) (SvFLAGS(sv) & SVp_POK) +#define SvPOKp_on(sv) (SvFLAGS(sv) |= SVp_POK) #define SvIOK(sv) (SvFLAGS(sv) & SVf_IOK) -#define SvIOK_on(sv) (SvOOK_off(sv), SvFLAGS(sv) |= (SVf_IOK|SVf_OK)) -#define SvIOK_off(sv) (SvFLAGS(sv) &= ~SVf_IOK) -#define SvIOK_only(sv) (SvOK_off(sv), SvFLAGS(sv) |= (SVf_IOK|SVf_OK)) +#define SvIOK_on(sv) (SvOOK_off(sv), \ + SvFLAGS(sv) |= (SVf_IOK|SVp_IOK)) +#define SvIOK_off(sv) (SvFLAGS(sv) &= ~(SVf_IOK|SVp_IOK|SVf_IVisUV)) +#define SvIOK_only(sv) (SvOK_off(sv), \ + SvFLAGS(sv) |= (SVf_IOK|SVp_IOK)) +#define SvIOK_only_UV(sv) (SvOK_off_exc_UV(sv), \ + SvFLAGS(sv) |= (SVf_IOK|SVp_IOK)) + +#define SvIOK_UV(sv) ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV)) \ + == (SVf_IOK|SVf_IVisUV)) +#define SvIOK_notUV(sv) ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV)) \ + == SVf_IOK) + +#define SvIsUV(sv) (SvFLAGS(sv) & SVf_IVisUV) +#define SvIsUV_on(sv) (SvFLAGS(sv) |= SVf_IVisUV) +#define SvIsUV_off(sv) (SvFLAGS(sv) &= ~SVf_IVisUV) #define SvNOK(sv) (SvFLAGS(sv) & SVf_NOK) -#define SvNOK_on(sv) (SvFLAGS(sv) |= (SVf_NOK|SVf_OK)) -#define SvNOK_off(sv) (SvFLAGS(sv) &= ~SVf_NOK) -#define SvNOK_only(sv) (SvOK_off(sv), SvFLAGS(sv) |= (SVf_NOK|SVf_OK)) +#define SvNOK_on(sv) (SvFLAGS(sv) |= (SVf_NOK|SVp_NOK)) +#define SvNOK_off(sv) (SvFLAGS(sv) &= ~(SVf_NOK|SVp_NOK)) +#define SvNOK_only(sv) (SvOK_off(sv), \ + SvFLAGS(sv) |= (SVf_NOK|SVp_NOK)) + +#define SvUTF8(sv) (SvFLAGS(sv) & SVf_UTF8) +#define SvUTF8_on(sv) (SvFLAGS(sv) |= (SVf_UTF8)) +#define SvUTF8_off(sv) (SvFLAGS(sv) &= ~(SVf_UTF8)) #define SvPOK(sv) (SvFLAGS(sv) & SVf_POK) -#define SvPOK_on(sv) (SvFLAGS(sv) |= (SVf_POK|SVf_OK)) -#define SvPOK_off(sv) (SvFLAGS(sv) &= ~SVf_POK) -#define SvPOK_only(sv) (SvOK_off(sv), SvFLAGS(sv) |= (SVf_POK|SVf_OK)) +#define SvPOK_on(sv) (SvFLAGS(sv) |= (SVf_POK|SVp_POK)) +#define SvPOK_off(sv) (SvFLAGS(sv) &= ~(SVf_POK|SVp_POK)) +#define SvPOK_only(sv) (SvFLAGS(sv) &= ~(SVf_OK|SVf_AMAGIC|SVf_IVisUV), \ + SvFLAGS(sv) |= (SVf_POK|SVp_POK)) #define SvOOK(sv) (SvFLAGS(sv) & SVf_OOK) #define SvOOK_on(sv) (SvIOK_off(sv), SvFLAGS(sv) |= SVf_OOK) #define SvOOK_off(sv) (SvOOK(sv) && sv_backoff(sv)) +#define SvFAKE(sv) (SvFLAGS(sv) & SVf_FAKE) +#define SvFAKE_on(sv) (SvFLAGS(sv) |= SVf_FAKE) +#define SvFAKE_off(sv) (SvFLAGS(sv) &= ~SVf_FAKE) + #define SvROK(sv) (SvFLAGS(sv) & SVf_ROK) -#define SvROK_on(sv) (SvFLAGS(sv) |= SVf_ROK|SVf_THINKFIRST|SVf_OK) -#define SvROK_off(sv) (SvFLAGS(sv) &= ~SVf_ROK) +#define SvROK_on(sv) (SvFLAGS(sv) |= SVf_ROK) +#define SvROK_off(sv) (SvFLAGS(sv) &= ~(SVf_ROK|SVf_AMAGIC)) -#define SvMAGICAL(sv) (SvFLAGS(sv) & SVf_MAGICAL) -#define SvMAGICAL_on(sv) (SvFLAGS(sv) |= SVf_MAGICAL) -#define SvMAGICAL_off(sv) (SvFLAGS(sv) &= ~SVf_MAGICAL) +#define SvMAGICAL(sv) (SvFLAGS(sv) & (SVs_GMG|SVs_SMG|SVs_RMG)) +#define SvMAGICAL_on(sv) (SvFLAGS(sv) |= (SVs_GMG|SVs_SMG|SVs_RMG)) +#define SvMAGICAL_off(sv) (SvFLAGS(sv) &= ~(SVs_GMG|SVs_SMG|SVs_RMG)) -#define SvTHINKFIRST(sv) (SvFLAGS(sv) & SVf_THINKFIRST) -#define SvTHINKFIRST_on(sv) (SvFLAGS(sv) |= SVf_THINKFIRST) -#define SvTHINKFIRST_off(sv) (SvFLAGS(sv) &= ~SVf_THINKFIRST) +#define SvGMAGICAL(sv) (SvFLAGS(sv) & SVs_GMG) +#define SvGMAGICAL_on(sv) (SvFLAGS(sv) |= SVs_GMG) +#define SvGMAGICAL_off(sv) (SvFLAGS(sv) &= ~SVs_GMG) + +#define SvSMAGICAL(sv) (SvFLAGS(sv) & SVs_SMG) +#define SvSMAGICAL_on(sv) (SvFLAGS(sv) |= SVs_SMG) +#define SvSMAGICAL_off(sv) (SvFLAGS(sv) &= ~SVs_SMG) -#define SvPADBUSY(sv) (SvSTORAGE(sv) & SVs_PADBUSY) +#define SvRMAGICAL(sv) (SvFLAGS(sv) & SVs_RMG) +#define SvRMAGICAL_on(sv) (SvFLAGS(sv) |= SVs_RMG) +#define SvRMAGICAL_off(sv) (SvFLAGS(sv) &= ~SVs_RMG) -#define SvPADTMP(sv) (SvSTORAGE(sv) & SVs_PADTMP) -#define SvPADTMP_on(sv) (SvSTORAGE(sv) |= SVs_PADTMP|SVs_PADBUSY) -#define SvPADTMP_off(sv) (SvSTORAGE(sv) &= ~SVs_PADTMP) +#define SvAMAGIC(sv) (SvFLAGS(sv) & SVf_AMAGIC) +#define SvAMAGIC_on(sv) (SvFLAGS(sv) |= SVf_AMAGIC) +#define SvAMAGIC_off(sv) (SvFLAGS(sv) &= ~SVf_AMAGIC) -#define SvPADMY(sv) (SvSTORAGE(sv) & SVs_PADMY) -#define SvPADMY_on(sv) (SvSTORAGE(sv) |= SVs_PADMY|SVs_PADBUSY) +/* +#define Gv_AMG(stash) \ + (HV_AMAGICmb(stash) && \ + ((!HV_AMAGICbad(stash) && HV_AMAGIC(stash)) || Gv_AMupdate(stash))) +*/ +#define Gv_AMG(stash) (PL_amagic_generation && Gv_AMupdate(stash)) + +#define SvWEAKREF(sv) ((SvFLAGS(sv) & (SVf_ROK|SVprv_WEAKREF)) \ + == (SVf_ROK|SVprv_WEAKREF)) +#define SvWEAKREF_on(sv) (SvFLAGS(sv) |= (SVf_ROK|SVprv_WEAKREF)) +#define SvWEAKREF_off(sv) (SvFLAGS(sv) &= ~(SVf_ROK|SVprv_WEAKREF)) + +#define SvTHINKFIRST(sv) (SvFLAGS(sv) & SVf_THINKFIRST) -#define SvTEMP(sv) (SvSTORAGE(sv) & SVs_TEMP) -#define SvTEMP_on(sv) (SvSTORAGE(sv) |= SVs_TEMP) -#define SvTEMP_off(sv) (SvSTORAGE(sv) &= ~SVs_TEMP) +#define SvPADBUSY(sv) (SvFLAGS(sv) & SVs_PADBUSY) -#define SvOBJECT(sv) (SvSTORAGE(sv) & SVs_OBJECT) -#define SvOBJECT_on(sv) (SvSTORAGE(sv) |= SVs_OBJECT) -#define SvOBJECT_off(sv) (SvSTORAGE(sv) &= ~SVs_OBJECT) +#define SvPADTMP(sv) (SvFLAGS(sv) & SVs_PADTMP) +#define SvPADTMP_on(sv) (SvFLAGS(sv) |= SVs_PADTMP|SVs_PADBUSY) +#define SvPADTMP_off(sv) (SvFLAGS(sv) &= ~SVs_PADTMP) -#define SvREADONLY(sv) (SvSTORAGE(sv) & SVs_READONLY) -#define SvREADONLY_on(sv) (SvSTORAGE(sv) |= SVs_READONLY, \ - SvTHINKFIRST_on(sv)) -#define SvREADONLY_off(sv) (SvSTORAGE(sv) &= ~SVs_READONLY) +#define SvPADMY(sv) (SvFLAGS(sv) & SVs_PADMY) +#define SvPADMY_on(sv) (SvFLAGS(sv) |= SVs_PADMY|SVs_PADBUSY) -#define SvSCREAM(sv) (SvPRIVATE(sv) & SVp_SCREAM) -#define SvSCREAM_on(sv) (SvPRIVATE(sv) |= SVp_SCREAM) -#define SvSCREAM_off(sv) (SvPRIVATE(sv) &= ~SVp_SCREAM) +#define SvTEMP(sv) (SvFLAGS(sv) & SVs_TEMP) +#define SvTEMP_on(sv) (SvFLAGS(sv) |= SVs_TEMP) +#define SvTEMP_off(sv) (SvFLAGS(sv) &= ~SVs_TEMP) -#define SvCOMPILED(sv) (SvPRIVATE(sv) & SVpfm_COMPILED) -#define SvCOMPILED_on(sv) (SvPRIVATE(sv) |= SVpfm_COMPILED) -#define SvCOMPILED_off(sv) (SvPRIVATE(sv) &= ~SVpfm_COMPILED) +#define SvOBJECT(sv) (SvFLAGS(sv) & SVs_OBJECT) +#define SvOBJECT_on(sv) (SvFLAGS(sv) |= SVs_OBJECT) +#define SvOBJECT_off(sv) (SvFLAGS(sv) &= ~SVs_OBJECT) -#define SvTAIL(sv) (SvPRIVATE(sv) & SVpbm_TAIL) -#define SvTAIL_on(sv) (SvPRIVATE(sv) |= SVpbm_TAIL) -#define SvTAIL_off(sv) (SvPRIVATE(sv) &= ~SVpbm_TAIL) +#define SvREADONLY(sv) (SvFLAGS(sv) & SVf_READONLY) +#define SvREADONLY_on(sv) (SvFLAGS(sv) |= SVf_READONLY) +#define SvREADONLY_off(sv) (SvFLAGS(sv) &= ~SVf_READONLY) -#define SvCASEFOLD(sv) (SvPRIVATE(sv) & SVpbm_CASEFOLD) -#define SvCASEFOLD_on(sv) (SvPRIVATE(sv) |= SVpbm_CASEFOLD) -#define SvCASEFOLD_off(sv) (SvPRIVATE(sv) &= ~SVpbm_CASEFOLD) +#define SvSCREAM(sv) (SvFLAGS(sv) & SVp_SCREAM) +#define SvSCREAM_on(sv) (SvFLAGS(sv) |= SVp_SCREAM) +#define SvSCREAM_off(sv) (SvFLAGS(sv) &= ~SVp_SCREAM) -#define SvVALID(sv) (SvPRIVATE(sv) & SVpbm_VALID) -#define SvVALID_on(sv) (SvPRIVATE(sv) |= SVpbm_VALID) -#define SvVALID_off(sv) (SvPRIVATE(sv) &= ~SVpbm_VALID) +#define SvCOMPILED(sv) (SvFLAGS(sv) & SVpfm_COMPILED) +#define SvCOMPILED_on(sv) (SvFLAGS(sv) |= SVpfm_COMPILED) +#define SvCOMPILED_off(sv) (SvFLAGS(sv) &= ~SVpfm_COMPILED) -#define SvMULTI(sv) (SvPRIVATE(sv) & SVpgv_MULTI) -#define SvMULTI_on(sv) (SvPRIVATE(sv) |= SVpgv_MULTI) -#define SvMULTI_off(sv) (SvPRIVATE(sv) &= ~SVpgv_MULTI) +#define SvEVALED(sv) (SvFLAGS(sv) & SVrepl_EVAL) +#define SvEVALED_on(sv) (SvFLAGS(sv) |= SVrepl_EVAL) +#define SvEVALED_off(sv) (SvFLAGS(sv) &= ~SVrepl_EVAL) + +#define SvTAIL(sv) (SvFLAGS(sv) & SVpbm_TAIL) +#define SvTAIL_on(sv) (SvFLAGS(sv) |= SVpbm_TAIL) +#define SvTAIL_off(sv) (SvFLAGS(sv) &= ~SVpbm_TAIL) + +#define SvVALID(sv) (SvFLAGS(sv) & SVpbm_VALID) +#define SvVALID_on(sv) (SvFLAGS(sv) |= SVpbm_VALID) +#define SvVALID_off(sv) (SvFLAGS(sv) &= ~SVpbm_VALID) #define SvRV(sv) ((XRV*) SvANY(sv))->xrv_rv #define SvRVx(sv) SvRV(sv) #define SvIVX(sv) ((XPVIV*) SvANY(sv))->xiv_iv #define SvIVXx(sv) SvIVX(sv) +#define SvUVX(sv) ((XPVUV*) SvANY(sv))->xuv_uv +#define SvUVXx(sv) SvUVX(sv) #define SvNVX(sv) ((XPVNV*)SvANY(sv))->xnv_nv #define SvNVXx(sv) SvNVX(sv) #define SvPVX(sv) ((XPV*) SvANY(sv))->xpv_pv @@ -344,30 +487,28 @@ struct xpvfm { #define SvLEN(sv) ((XPV*) SvANY(sv))->xpv_len #define SvLENx(sv) SvLEN(sv) #define SvEND(sv)(((XPV*) SvANY(sv))->xpv_pv + ((XPV*)SvANY(sv))->xpv_cur) -#define SvENDx(sv) ((Sv = sv), SvEND(Sv)) +#define SvENDx(sv) ((PL_Sv = (sv)), SvEND(PL_Sv)) #define SvMAGIC(sv) ((XPVMG*) SvANY(sv))->xmg_magic #define SvSTASH(sv) ((XPVMG*) SvANY(sv))->xmg_stash #define SvIV_set(sv, val) \ - do { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \ - (((XPVIV*) SvANY(sv))->xiv_iv = val); } while (0) + STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \ + (((XPVIV*) SvANY(sv))->xiv_iv = val); } STMT_END #define SvNV_set(sv, val) \ - do { assert(SvTYPE(sv) == SVt_NV || SvTYPE(sv) >= SVt_PVNV); \ - (((XPVNV*) SvANY(sv))->xnv_nv = val); } while (0) + STMT_START { assert(SvTYPE(sv) == SVt_NV || SvTYPE(sv) >= SVt_PVNV); \ + (((XPVNV*) SvANY(sv))->xnv_nv = val); } STMT_END #define SvPV_set(sv, val) \ - do { assert(SvTYPE(sv) >= SVt_PV); \ - (((XPV*) SvANY(sv))->xpv_pv = val); } while (0) + STMT_START { assert(SvTYPE(sv) >= SVt_PV); \ + (((XPV*) SvANY(sv))->xpv_pv = val); } STMT_END #define SvCUR_set(sv, val) \ - do { assert(SvTYPE(sv) >= SVt_PV); \ - (((XPV*) SvANY(sv))->xpv_cur = val); } while (0) + STMT_START { assert(SvTYPE(sv) >= SVt_PV); \ + (((XPV*) SvANY(sv))->xpv_cur = val); } STMT_END #define SvLEN_set(sv, val) \ - do { assert(SvTYPE(sv) >= SVt_PV); \ - (((XPV*) SvANY(sv))->xpv_len = val); } while (0) + STMT_START { assert(SvTYPE(sv) >= SVt_PV); \ + (((XPV*) SvANY(sv))->xpv_len = val); } STMT_END #define SvEND_set(sv, val) \ - do { assert(SvTYPE(sv) >= SVt_PV); \ - (((XPV*) SvANY(sv))->xpv_cur = val - SvPVX(sv)); } while (0) - -#define SvCUROK(sv) (SvPOK(sv) ? SvCUR(sv) : 0) + STMT_START { assert(SvTYPE(sv) >= SVt_PV); \ + (((XPV*) SvANY(sv))->xpv_cur = val - SvPVX(sv)); } STMT_END #define BmRARE(sv) ((XPVBM*) SvANY(sv))->xbm_rare #define BmUSEFUL(sv) ((XPVBM*) SvANY(sv))->xbm_useful @@ -380,35 +521,165 @@ struct xpvfm { #define LvTARGOFF(sv) ((XPVLV*) SvANY(sv))->xlv_targoff #define LvTARGLEN(sv) ((XPVLV*) SvANY(sv))->xlv_targlen -#define SvTAINT(sv) if (tainting && tainted) sv_magic(sv, 0, 't', 0, 0) +#define IoIFP(sv) ((XPVIO*) SvANY(sv))->xio_ifp +#define IoOFP(sv) ((XPVIO*) SvANY(sv))->xio_ofp +#define IoDIRP(sv) ((XPVIO*) SvANY(sv))->xio_dirp +#define IoLINES(sv) ((XPVIO*) SvANY(sv))->xio_lines +#define IoPAGE(sv) ((XPVIO*) SvANY(sv))->xio_page +#define IoPAGE_LEN(sv) ((XPVIO*) SvANY(sv))->xio_page_len +#define IoLINES_LEFT(sv)((XPVIO*) SvANY(sv))->xio_lines_left +#define IoTOP_NAME(sv) ((XPVIO*) SvANY(sv))->xio_top_name +#define IoTOP_GV(sv) ((XPVIO*) SvANY(sv))->xio_top_gv +#define IoFMT_NAME(sv) ((XPVIO*) SvANY(sv))->xio_fmt_name +#define IoFMT_GV(sv) ((XPVIO*) SvANY(sv))->xio_fmt_gv +#define IoBOTTOM_NAME(sv)((XPVIO*) SvANY(sv))->xio_bottom_name +#define IoBOTTOM_GV(sv) ((XPVIO*) SvANY(sv))->xio_bottom_gv +#define IoSUBPROCESS(sv)((XPVIO*) SvANY(sv))->xio_subprocess +#define IoTYPE(sv) ((XPVIO*) SvANY(sv))->xio_type +#define IoFLAGS(sv) ((XPVIO*) SvANY(sv))->xio_flags + +#define SvTAINTED(sv) (SvMAGICAL(sv) && sv_tainted(sv)) +#define SvTAINTED_on(sv) STMT_START{ if(PL_tainting){sv_taint(sv);} }STMT_END +#define SvTAINTED_off(sv) STMT_START{ if(PL_tainting){sv_untaint(sv);} }STMT_END + +#define SvTAINT(sv) \ + STMT_START { \ + if (PL_tainting) { \ + dTHR; \ + if (PL_tainted) \ + SvTAINTED_on(sv); \ + } \ + } STMT_END + +#define SvPV_force(sv, lp) sv_pvn_force(sv, &lp) +#define SvPV(sv, lp) sv_pvn(sv, &lp) +#define SvPV_nolen(sv) sv_pv(sv) -#ifdef CRIPPLED_CC +#define SvPVutf8_force(sv, lp) sv_pvutf8n_force(sv, &lp) +#define SvPVutf8(sv, lp) sv_pvutf8n(sv, &lp) +#define SvPVutf8_nolen(sv) sv_pvutf8(sv) -double SvIV(); -double SvNV(); -#define SvPV(sv, lp) sv_pvn(sv, &lp) -char *sv_pvn(); -I32 SvTRUE(); +#define SvPVbyte_force(sv, lp) sv_pvbyte_force(sv, &lp) +#define SvPVbyte(sv, lp) sv_pvbyten(sv, &lp) +#define SvPVbyte_nolen(sv) sv_pvbyte(sv) -#define SvIVx(sv) SvIV(sv) -#define SvNVx(sv) SvNV(sv) #define SvPVx(sv, lp) sv_pvn(sv, &lp) -#define SvTRUEx(sv) SvTRUE(sv) +#define SvPVx_force(sv, lp) sv_pvn_force(sv, &lp) +#define SvPVutf8x(sv, lp) sv_pvutf8n(sv, &lp) +#define SvPVutf8x_force(sv, lp) sv_pvutf8n_force(sv, &lp) +#define SvPVbytex(sv, lp) sv_pvbyten(sv, &lp) +#define SvPVbytex_force(sv, lp) sv_pvbyten_force(sv, &lp) -#else /* !CRIPPLED_CC */ +#define SvIVx(sv) sv_iv(sv) +#define SvUVx(sv) sv_uv(sv) +#define SvNVx(sv) sv_nv(sv) +#define SvTRUEx(sv) sv_true(sv) + +#define SvIV(sv) SvIVx(sv) +#define SvNV(sv) SvNVx(sv) +#define SvUV(sv) SvUVx(sv) +#define SvTRUE(sv) SvTRUEx(sv) + +#ifndef CRIPPLED_CC +/* redefine some things to more efficient inlined versions */ + +/* Let us hope that bitmaps for UV and IV are the same */ +#undef SvIV #define SvIV(sv) (SvIOK(sv) ? SvIVX(sv) : sv_2iv(sv)) -#define SvNV(sv) (SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv)) +#undef SvUV +#define SvUV(sv) (SvIOK(sv) ? SvUVX(sv) : sv_2uv(sv)) -#define SvPV(sv, lp) (SvPOK(sv) ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv(sv, &lp)) +#undef SvNV +#define SvNV(sv) (SvNOK(sv) ? SvNVX(sv) : sv_2nv(sv)) -#define SvTRUE(sv) ( \ - SvPOK(sv) \ - ? ((Xpv = (XPV*)SvANY(sv)) && \ - (*Xpv->xpv_pv > '0' || \ - Xpv->xpv_cur > 1 || \ - (Xpv->xpv_cur && *Xpv->xpv_pv != '0')) \ +#undef SvPV +#define SvPV(sv, lp) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pv(sv, &lp)) + + +#undef SvPV_force +#define SvPV_force(sv, lp) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == SVf_POK \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvn_force(sv, &lp)) + +#undef SvPV_nolen +#define SvPV_nolen(sv) \ + ((SvFLAGS(sv) & (SVf_POK)) == SVf_POK \ + ? SvPVX(sv) : sv_2pv_nolen(sv)) + +#undef SvPVutf8 +#define SvPVutf8(sv, lp) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK|SVf_UTF8) \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvutf8(sv, &lp)) + +#undef SvPVutf8_force +#define SvPVutf8_force(sv, lp) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == (SVf_POK|SVf_UTF8) \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvutf8n_force(sv, &lp)) + +#undef SvPVutf8_nolen +#define SvPVutf8_nolen(sv) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK|SVf_UTF8)\ + ? SvPVX(sv) : sv_2pvutf8_nolen(sv)) + +#undef SvPVutf8 +#define SvPVutf8(sv, lp) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK|SVf_UTF8) \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvutf8(sv, &lp)) + +#undef SvPVutf8_force +#define SvPVutf8_force(sv, lp) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_THINKFIRST)) == (SVf_POK|SVf_UTF8) \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvutf8n_force(sv, &lp)) + +#undef SvPVutf8_nolen +#define SvPVutf8_nolen(sv) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK|SVf_UTF8)\ + ? SvPVX(sv) : sv_2pvutf8_nolen(sv)) + +#undef SvPVbyte +#define SvPVbyte(sv, lp) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK) \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_2pvbyte(sv, &lp)) + +#undef SvPVbyte_force +#define SvPVbyte_force(sv, lp) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8|SVf_THINKFIRST)) == (SVf_POK) \ + ? ((lp = SvCUR(sv)), SvPVX(sv)) : sv_pvbyte_force(sv, &lp)) + +#undef SvPVbyte_nolen +#define SvPVbyte_nolen(sv) \ + ((SvFLAGS(sv) & (SVf_POK|SVf_UTF8)) == (SVf_POK)\ + ? SvPVX(sv) : sv_2pvbyte_nolen(sv)) + + +#ifdef __GNUC__ +# undef SvIVx +# undef SvUVx +# undef SvNVx +# undef SvPVx +# undef SvPVutf8x +# undef SvPVbytex +# undef SvTRUE +# undef SvTRUEx +# define SvIVx(sv) ({SV *nsv = (SV*)(sv); SvIV(nsv); }) +# define SvUVx(sv) ({SV *nsv = (SV*)(sv); SvUV(nsv); }) +# define SvNVx(sv) ({SV *nsv = (SV*)(sv); SvNV(nsv); }) +# define SvPVx(sv, lp) ({SV *nsv = (sv); SvPV(nsv, lp); }) +# define SvPVutf8x(sv, lp) ({SV *nsv = (sv); SvPVutf8(nsv, lp); }) +# define SvPVbytex(sv, lp) ({SV *nsv = (sv); SvPVbyte(nsv, lp); }) +# define SvTRUE(sv) ( \ + !sv \ + ? 0 \ + : SvPOK(sv) \ + ? (({XPV *nxpv = (XPV*)SvANY(sv); \ + nxpv && \ + (*nxpv->xpv_pv > '0' || \ + nxpv->xpv_cur > 1 || \ + (nxpv->xpv_cur && *nxpv->xpv_pv != '0')); }) \ ? 1 \ : 0) \ : \ @@ -417,32 +688,93 @@ I32 SvTRUE(); : SvNOK(sv) \ ? SvNVX(sv) != 0.0 \ : sv_2bool(sv) ) +# define SvTRUEx(sv) ({SV *nsv = (sv); SvTRUE(nsv); }) +#else /* __GNUC__ */ +#ifndef USE_THREADS +/* These inlined macros use globals, which will require a thread + * declaration in user code, so we avoid them under threads */ + +# undef SvIVx +# undef SvUVx +# undef SvNVx +# undef SvPVx +# undef SvPVutf8x +# undef SvPVbytex +# undef SvTRUE +# undef SvTRUEx +# define SvIVx(sv) ((PL_Sv = (sv)), SvIV(PL_Sv)) +# define SvUVx(sv) ((PL_Sv = (sv)), SvUV(PL_Sv)) +# define SvNVx(sv) ((PL_Sv = (sv)), SvNV(PL_Sv)) +# define SvPVx(sv, lp) ((PL_Sv = (sv)), SvPV(PL_Sv, lp)) +# define SvPVutf8x(sv, lp) ((PL_Sv = (sv)), SvPVutf8(PL_Sv, lp)) +# define SvPVbytex(sv, lp) ((PL_Sv = (sv)), SvPVbyte(PL_Sv, lp)) +# define SvTRUE(sv) ( \ + !sv \ + ? 0 \ + : SvPOK(sv) \ + ? ((PL_Xpv = (XPV*)SvANY(sv)) && \ + (*PL_Xpv->xpv_pv > '0' || \ + PL_Xpv->xpv_cur > 1 || \ + (PL_Xpv->xpv_cur && *PL_Xpv->xpv_pv != '0')) \ + ? 1 \ + : 0) \ + : \ + SvIOK(sv) \ + ? SvIVX(sv) != 0 \ + : SvNOK(sv) \ + ? SvNVX(sv) != 0.0 \ + : sv_2bool(sv) ) +# define SvTRUEx(sv) ((PL_Sv = (sv)), SvTRUE(PL_Sv)) +#endif /* !USE_THREADS */ +#endif /* !__GNU__ */ +#endif /* !CRIPPLED_CC */ + +#define newRV_inc(sv) newRV(sv) + +/* the following macros update any magic values this sv is associated with */ + +#define SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END +#define SvSETMAGIC(x) STMT_START { if (SvSMAGICAL(x)) mg_set(x); } STMT_END + +#define SvSetSV_and(dst,src,finally) \ + STMT_START { \ + if ((dst) != (src)) { \ + sv_setsv(dst, src); \ + finally; \ + } \ + } STMT_END +#define SvSetSV_nosteal_and(dst,src,finally) \ + STMT_START { \ + if ((dst) != (src)) { \ + U32 tMpF = SvFLAGS(src) & SVs_TEMP; \ + SvTEMP_off(src); \ + sv_setsv(dst, src); \ + SvFLAGS(src) |= tMpF; \ + finally; \ + } \ + } STMT_END + +#define SvSetSV(dst,src) \ + SvSetSV_and(dst,src,/*nothing*/;) +#define SvSetSV_nosteal(dst,src) \ + SvSetSV_nosteal_and(dst,src,/*nothing*/;) + +#define SvSetMagicSV(dst,src) \ + SvSetSV_and(dst,src,SvSETMAGIC(dst)) +#define SvSetMagicSV_nosteal(dst,src) \ + SvSetSV_nosteal_and(dst,src,SvSETMAGIC(dst)) -#define SvIVx(sv) ((Sv = sv), SvIV(Sv)) -#define SvNVx(sv) ((Sv = sv), SvNV(Sv)) -#define SvPVx(sv, lp) ((Sv = sv), SvPV(Sv, lp)) -#define SvTRUEx(sv) ((Sv = sv), SvTRUE(Sv)) - -#endif /* CRIPPLED_CC */ - -/* the following macro updates any magic values this sv is associated with */ - -#define SvSETMAGIC(x) if (SvMAGICAL(x)) mg_set(x) +#ifdef DEBUGGING +#define SvPEEK(sv) sv_peek(sv) +#else +#define SvPEEK(sv) "" +#endif -#define SvSetSV(dst,src) if (dst != src) sv_setsv(dst,src) +#define SvIMMORTAL(sv) ((sv)==&PL_sv_undef || (sv)==&PL_sv_yes || (sv)==&PL_sv_no) -#define SvPEEK(sv) sv_peek(sv) +#define boolSV(b) ((b) ? &PL_sv_yes : &PL_sv_no) #define isGV(sv) (SvTYPE(sv) == SVt_PVGV) -#define GROWSTR(pp,lp,len) if (*(lp) < (len)) pv_grow(pp, lp, (len) * 3 / 2) - -#ifndef DOSISH -# define SvGROW(sv,len) if (SvLEN(sv) < (len)) sv_grow(sv,len) -# define Sv_Grow sv_grow -#else - /* extra parentheses intentionally NOT placed around "len"! */ -# define SvGROW(sv,len) if (SvLEN(sv) < (unsigned long)len) \ - sv_grow(sv,(unsigned long)len) -# define Sv_Grow(sv,len) sv_grow(sv,(unsigned long)(len)) -#endif /* DOSISH */ +#define SvGROW(sv,len) (SvLEN(sv) < (len) ? sv_grow(sv,len) : SvPVX(sv)) +#define Sv_Grow sv_grow