📄 sv.h
字号:
(SvFLAGS(thwacke) & SVpbm_VALID); \ })# define SvVALID_on(sv) ({ SV *const thwacke = (SV *) (sv); \ assert(!isGV_with_GP(thwacke)); \ (SvFLAGS(thwacke) |= SVpbm_VALID); \ })# define SvVALID_off(sv) ({ SV *const thwacke = (SV *) (sv); \ assert(!isGV_with_GP(thwacke)); \ (SvFLAGS(thwacke) &= ~SVpbm_VALID); \ })# define SvTAIL(sv) ({ SV *const _svi = (SV *) (sv); \ assert(SvTYPE(_svi) != SVt_PVAV); \ assert(SvTYPE(_svi) != SVt_PVHV); \ (SvFLAGS(sv) & (SVpbm_TAIL|SVpbm_VALID)) \ == (SVpbm_TAIL|SVpbm_VALID); \ })#else# define SvVALID(sv) (SvFLAGS(sv) & SVpbm_VALID)# define SvVALID_on(sv) (SvFLAGS(sv) |= SVpbm_VALID)# define SvVALID_off(sv) (SvFLAGS(sv) &= ~SVpbm_VALID)# define SvTAIL(sv) ((SvFLAGS(sv) & (SVpbm_TAIL|SVpbm_VALID)) \ == (SVpbm_TAIL|SVpbm_VALID))#endif#define SvTAIL_on(sv) (SvFLAGS(sv) |= SVpbm_TAIL)#define SvTAIL_off(sv) (SvFLAGS(sv) &= ~SVpbm_TAIL)#ifdef USE_ITHREADS/* The following uses the FAKE flag to show that a regex pointer is infact its own offset in the regexpad for ithreads */#define SvREPADTMP(sv) (SvFLAGS(sv) & SVf_FAKE)#define SvREPADTMP_on(sv) (SvFLAGS(sv) |= SVf_FAKE)#define SvREPADTMP_off(sv) (SvFLAGS(sv) &= ~SVf_FAKE)#endif#define SvPAD_TYPED(sv) \ ((SvFLAGS(sv) & (SVpad_NAME|SVpad_TYPED)) == (SVpad_NAME|SVpad_TYPED))#define SvPAD_OUR(sv) \ ((SvFLAGS(sv) & (SVpad_NAME|SVpad_OUR)) == (SVpad_NAME|SVpad_OUR))#define SvPAD_STATE(sv) \ ((SvFLAGS(sv) & (SVpad_NAME|SVpad_STATE)) == (SVpad_NAME|SVpad_STATE))#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)# define SvPAD_TYPED_on(sv) ({ \ SV *const whap = (SV *) (sv); \ assert(SvTYPE(whap) == SVt_PVMG); \ (SvFLAGS(whap) |= SVpad_NAME|SVpad_TYPED); \ })#define SvPAD_OUR_on(sv) ({ \ SV *const whap = (SV *) (sv); \ assert(SvTYPE(whap) == SVt_PVMG); \ (SvFLAGS(whap) |= SVpad_NAME|SVpad_OUR); \ })#define SvPAD_STATE_on(sv) ({ \ SV *const whap = (SV *) (sv); \ assert(SvTYPE(whap) == SVt_PVNV || SvTYPE(whap) == SVt_PVMG); \ (SvFLAGS(whap) |= SVpad_NAME|SVpad_STATE); \ })#else# define SvPAD_TYPED_on(sv) (SvFLAGS(sv) |= SVpad_NAME|SVpad_TYPED)# define SvPAD_OUR_on(sv) (SvFLAGS(sv) |= SVpad_NAME|SVpad_OUR)# define SvPAD_STATE_on(sv) (SvFLAGS(sv) |= SVpad_NAME|SVpad_STATE)#endif#define SvOURSTASH(sv) \ (SvPAD_OUR(sv) ? ((XPVMG*) SvANY(sv))->xmg_u.xmg_ourstash : NULL)#define SvOURSTASH_set(sv, st) \ STMT_START { \ assert(SvTYPE(sv) == SVt_PVMG); \ ((XPVMG*) SvANY(sv))->xmg_u.xmg_ourstash = st; \ } STMT_END#ifdef PERL_DEBUG_COW#else#endif#define SvRVx(sv) SvRV(sv)#ifdef PERL_DEBUG_COW/* Need -0.0 for SvNVX to preserve IEEE FP "negative zero" because +0.0 + -0.0 => +0.0 but -0.0 + -0.0 => -0.0 */# define SvIVX(sv) (0 + ((XPVIV*) SvANY(sv))->xiv_iv)# define SvUVX(sv) (0 + ((XPVUV*) SvANY(sv))->xuv_uv)# define SvNVX(sv) (-0.0 + ((XPVNV*) SvANY(sv))->xnv_u.xnv_nv)# define SvRV(sv) (0 + (sv)->sv_u.svu_rv)/* Don't test the core XS code yet. */# if defined (PERL_CORE) && PERL_DEBUG_COW > 1# define SvPVX(sv) (0 + (assert(!SvREADONLY(sv)), (sv)->sv_u.svu_pv))# else# define SvPVX(sv) SvPVX_mutable(sv)# endif# define SvCUR(sv) (0 + ((XPV*) SvANY(sv))->xpv_cur)# define SvLEN(sv) (0 + ((XPV*) SvANY(sv))->xpv_len)# define SvEND(sv) ((sv)->sv_u.svu_pv + ((XPV*)SvANY(sv))->xpv_cur)# ifdef DEBUGGING# define SvMAGIC(sv) (0 + *(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*) SvANY(sv))->xmg_u.xmg_magic))# define SvSTASH(sv) (0 + *(assert(SvTYPE(sv) >= SVt_PVMG), &((XPVMG*) SvANY(sv))->xmg_stash))# else# define SvMAGIC(sv) (0 + ((XPVMG*) SvANY(sv))->xmg_u.xmg_magic)# define SvSTASH(sv) (0 + ((XPVMG*) SvANY(sv))->xmg_stash)# endif#else# define SvLEN(sv) ((XPV*) SvANY(sv))->xpv_len# define SvEND(sv) ((sv)->sv_u.svu_pv + ((XPV*)SvANY(sv))->xpv_cur)# if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)/* These get expanded inside other macros that already use a variable _sv */# define SvPVX(sv) \ (*({ SV *const _svi = (SV *) (sv); \ assert(SvTYPE(_svi) >= SVt_PV); \ assert(SvTYPE(_svi) != SVt_PVAV); \ assert(SvTYPE(_svi) != SVt_PVHV); \ assert(!isGV_with_GP(_svi)); \ &((_svi)->sv_u.svu_pv); \ }))# define SvCUR(sv) \ (*({ SV *const _svi = (SV *) (sv); \ assert(SvTYPE(_svi) >= SVt_PV); \ assert(SvTYPE(_svi) != SVt_PVAV); \ assert(SvTYPE(_svi) != SVt_PVHV); \ assert(!isGV_with_GP(_svi)); \ &(((XPV*) SvANY(_svi))->xpv_cur); \ }))# define SvIVX(sv) \ (*({ SV *const _svi = (SV *) (sv); \ assert(SvTYPE(_svi) == SVt_IV || SvTYPE(_svi) >= SVt_PVIV); \ assert(SvTYPE(_svi) != SVt_PVAV); \ assert(SvTYPE(_svi) != SVt_PVHV); \ assert(SvTYPE(_svi) != SVt_PVCV); \ assert(!isGV_with_GP(_svi)); \ &(((XPVIV*) SvANY(_svi))->xiv_iv); \ }))# define SvUVX(sv) \ (*({ SV *const _svi = (SV *) (sv); \ assert(SvTYPE(_svi) == SVt_IV || SvTYPE(_svi) >= SVt_PVIV); \ assert(SvTYPE(_svi) != SVt_PVAV); \ assert(SvTYPE(_svi) != SVt_PVHV); \ assert(SvTYPE(_svi) != SVt_PVCV); \ assert(!isGV_with_GP(_svi)); \ &(((XPVUV*) SvANY(_svi))->xuv_uv); \ }))# define SvNVX(sv) \ (*({ SV *const _svi = (SV *) (sv); \ assert(SvTYPE(_svi) == SVt_NV || SvTYPE(_svi) >= SVt_PVNV); \ assert(SvTYPE(_svi) != SVt_PVAV); \ assert(SvTYPE(_svi) != SVt_PVHV); \ assert(SvTYPE(_svi) != SVt_PVCV); \ assert(SvTYPE(_svi) != SVt_PVFM); \ assert(!isGV_with_GP(_svi)); \ &(((XPVNV*) SvANY(_svi))->xnv_u.xnv_nv); \ }))# define SvRV(sv) \ (*({ SV *const _svi = (SV *) (sv); \ assert(SvTYPE(_svi) >= SVt_RV); \ assert(SvTYPE(_svi) != SVt_PVAV); \ assert(SvTYPE(_svi) != SVt_PVHV); \ assert(SvTYPE(_svi) != SVt_PVCV); \ assert(SvTYPE(_svi) != SVt_PVFM); \ assert(!isGV_with_GP(_svi)); \ &((_svi)->sv_u.svu_rv); \ }))# define SvMAGIC(sv) \ (*({ SV *const _svi = (SV *) (sv); \ assert(SvTYPE(_svi) >= SVt_PVMG); \ if(SvTYPE(_svi) == SVt_PVMG) \ assert(!SvPAD_OUR(_svi)); \ &(((XPVMG*) SvANY(_svi))->xmg_u.xmg_magic); \ }))# define SvSTASH(sv) \ (*({ SV *const _svi = (SV *) (sv); \ assert(SvTYPE(_svi) >= SVt_PVMG); \ &(((XPVMG*) SvANY(_svi))->xmg_stash); \ }))# else# define SvPVX(sv) ((sv)->sv_u.svu_pv)# define SvCUR(sv) ((XPV*) SvANY(sv))->xpv_cur# define SvIVX(sv) ((XPVIV*) SvANY(sv))->xiv_iv# define SvUVX(sv) ((XPVUV*) SvANY(sv))->xuv_uv# define SvNVX(sv) ((XPVNV*) SvANY(sv))->xnv_u.xnv_nv# define SvRV(sv) ((sv)->sv_u.svu_rv)# define SvMAGIC(sv) ((XPVMG*) SvANY(sv))->xmg_u.xmg_magic# define SvSTASH(sv) ((XPVMG*) SvANY(sv))->xmg_stash# endif#endif#ifndef PERL_POISON/* Given that these two are new, there can't be any existing code using them * as LVALUEs */# define SvPVX_mutable(sv) (0 + (sv)->sv_u.svu_pv)# define SvPVX_const(sv) ((const char*)(0 + (sv)->sv_u.svu_pv))#else/* Except for the poison code, which uses & to scribble over the pointer after free() is called. */# define SvPVX_mutable(sv) ((sv)->sv_u.svu_pv)# define SvPVX_const(sv) ((const char*)((sv)->sv_u.svu_pv))#endif#define SvIVXx(sv) SvIVX(sv)#define SvUVXx(sv) SvUVX(sv)#define SvNVXx(sv) SvNVX(sv)#define SvPVXx(sv) SvPVX(sv)#define SvLENx(sv) SvLEN(sv)#define SvENDx(sv) ((PL_Sv = (sv)), SvEND(PL_Sv))/* Ask a scalar nicely to try to become an IV, if possible. Not guaranteed to stay returning void *//* Macro won't actually call sv_2iv if already IOK */#define SvIV_please(sv) \ STMT_START {if (!SvIOKp(sv) && (SvNOK(sv) || SvPOK(sv))) \ (void) SvIV(sv); } STMT_END#define SvIV_set(sv, val) \ STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \ assert(SvTYPE(sv) != SVt_PVAV); \ assert(SvTYPE(sv) != SVt_PVHV); \ assert(SvTYPE(sv) != SVt_PVCV); \ assert(!isGV_with_GP(sv)); \ (((XPVIV*) SvANY(sv))->xiv_iv = (val)); } STMT_END#define SvNV_set(sv, val) \ STMT_START { assert(SvTYPE(sv) == SVt_NV || SvTYPE(sv) >= SVt_PVNV); \ assert(SvTYPE(sv) != SVt_PVAV); assert(SvTYPE(sv) != SVt_PVHV); \ assert(SvTYPE(sv) != SVt_PVCV); assert(SvTYPE(sv) != SVt_PVFM); \ assert(!isGV_with_GP(sv)); \ (((XPVNV*)SvANY(sv))->xnv_u.xnv_nv = (val)); } STMT_END#define SvPV_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_PV); \ assert(SvTYPE(sv) != SVt_PVAV); \ assert(SvTYPE(sv) != SVt_PVHV); \ assert(!isGV_with_GP(sv)); \ ((sv)->sv_u.svu_pv = (val)); } STMT_END#define SvUV_set(sv, val) \ STMT_START { assert(SvTYPE(sv) == SVt_IV || SvTYPE(sv) >= SVt_PVIV); \ assert(SvTYPE(sv) != SVt_PVAV); \ assert(SvTYPE(sv) != SVt_PVHV); \ assert(SvTYPE(sv) != SVt_PVCV); \ assert(!isGV_with_GP(sv)); \ (((XPVUV*)SvANY(sv))->xuv_uv = (val)); } STMT_END#define SvRV_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_RV); \ assert(SvTYPE(sv) != SVt_PVAV); \ assert(SvTYPE(sv) != SVt_PVHV); \ assert(SvTYPE(sv) != SVt_PVCV); \ assert(SvTYPE(sv) != SVt_PVFM); \ assert(!isGV_with_GP(sv)); \ ((sv)->sv_u.svu_rv = (val)); } STMT_END#define SvMAGIC_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \ (((XPVMG*)SvANY(sv))->xmg_u.xmg_magic = (val)); } STMT_END#define SvSTASH_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_PVMG); \ (((XPVMG*) SvANY(sv))->xmg_stash = (val)); } STMT_END#define SvCUR_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_PV); \ assert(SvTYPE(sv) != SVt_PVAV); \ assert(SvTYPE(sv) != SVt_PVHV); \ assert(!isGV_with_GP(sv)); \ (((XPV*) SvANY(sv))->xpv_cur = (val)); } STMT_END#define SvLEN_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_PV); \ assert(SvTYPE(sv) != SVt_PVAV); \ assert(SvTYPE(sv) != SVt_PVHV); \ assert(!isGV_with_GP(sv)); \ (((XPV*) SvANY(sv))->xpv_len = (val)); } STMT_END#define SvEND_set(sv, val) \ STMT_START { assert(SvTYPE(sv) >= SVt_PV); \ (SvCUR(sv) = (val) - SvPVX(sv)); } STMT_END#define SvPV_renew(sv,n) \ STMT_START { SvLEN_set(sv, n); \ SvPV_set((sv), (MEM_WRAP_CHECK_(n,char) \ (char*)saferealloc((Malloc_t)SvPVX(sv), \ (MEM_SIZE)((n))))); \ } STMT_END#define SvPV_shrink_to_cur(sv) STMT_START { \ const STRLEN _lEnGtH = SvCUR(sv) + 1; \ SvPV_renew(sv, _lEnGtH); \ } STMT_END#define SvPV_free(sv) \ STMT_START { \ assert(SvTYPE(sv) >= SVt_PV); \ if (SvLEN(sv)) { \ if(SvOOK(sv)) { \ SvPV_set(sv, SvPVX_mutable(sv) - SvIVX(sv)); \ SvFLAGS(sv) &= ~SVf_OOK; \ } \ Safefree(SvPVX(sv)); \ } \ } STMT_END#define PERL_FBM_TABLE_OFFSET 1 /* Number of bytes between EOS and table *//* SvPOKp not SvPOK in the assertion because the string can be tainted! eg perl -T -e '/$^X/'*/#if defined (DEBUGGING) && defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)# define BmFLAGS(sv) \ (*({ SV *const uggh = (SV *) (sv); \ assert(SvTYPE(uggh) == SVt_PVGV); \ assert(SvVALID(uggh)); \ &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_flags); \ }))# define BmRARE(sv) \ (*({ SV *const uggh = (SV *) (sv); \ assert(SvTYPE(uggh) == SVt_PVGV); \ assert(SvVALID(uggh)); \ &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_rare); \ }))# define BmUSEFUL(sv) \ (*({ SV *const uggh = (SV *) (sv); \ assert(SvTYPE(uggh) == SVt_PVGV); \ assert(SvVALID(uggh)); \ assert(!SvIOK(uggh)); \ &(((XPVGV*) SvANY(uggh))->xiv_u.xivu_i32); \ }))# define BmPREVIOUS(sv) \ (*({ SV *const uggh = (SV *) (sv); \ assert(SvTYPE(uggh) == SVt_PVGV); \ assert(SvVALID(uggh)); \ &(((XPVGV*) SvANY(uggh))->xnv_u.xbm_s.xbm_previous); \ }))#else# define BmFLAGS(sv) ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_flags# define BmRARE(sv) ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_rare# define BmUSEFUL(sv) ((XPVGV*) SvANY(sv))->xiv_u.xivu_i32# define BmPREVIOUS(sv) ((XPVGV*) SvANY(sv))->xnv_u.xbm_s.xbm_previous#endif#define FmLINES(sv) ((XPVFM*) SvANY(sv))->xfm_lines#define LvTYPE(sv) ((XPVLV*) SvANY(sv))->xlv_type#define LvTARG(sv) ((XPVLV*) SvANY(sv))->xlv_targ#define LvTARGOFF(sv) ((XPVLV*) SvANY(sv))->xlv_targoff#define LvTARGLEN(sv) ((XPVLV*) SvANY(sv))->xlv_targlen#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 IoANY(sv) ((XPVIO*) SvANY(sv))->xio_any#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 IoTYPE(sv) ((XPVIO*) SvANY(sv))->xio_type#define IoFLAGS(sv) ((XPVIO*) SvANY(sv))->xio_flags/* IoTYPE(sv) is a single character telling the type of I/O connection. */#define IoTYPE_RDONLY '<'#define IoTYPE_WRONLY '>'#define IoTYPE_RDWR '+'#define IoTYPE_APPEND 'a'#define IoTYPE_PIPE '|'#define IoTYPE_STD '-' /* stdin or stdout */#define IoTYPE_SOCKET 's'#define IoTYPE_CLOSED ' '#define IoTYPE_IMPLICIT 'I' /* stdin or stdout or stderr */#define IoTYPE_NUMERIC '#' /* fdopen *//*=for apidoc Am|bool|SvTAINTED|SV* svChecks to see if an SV is tainted. Returns TRUE if it is, FALSE ifnot.=for apidoc Am|void|SvTAINTED_on|SV* svMarks an SV as tainted if tainting is enabled.=for apidoc Am|void|SvTAINTED_off|SV* svUntaints an SV. Be I<very> careful with this routine, as it short-circuits
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -