|
Packit |
7d6a7d |
################################################################################
|
|
Packit |
7d6a7d |
##
|
|
Packit |
7d6a7d |
## Version 3.x, Copyright (C) 2004-2013, Marcus Holland-Moritz.
|
|
Packit |
7d6a7d |
## Version 2.x, Copyright (C) 2001, Paul Marquess.
|
|
Packit |
7d6a7d |
## Version 1.x, Copyright (C) 1999, Kenneth Albanowski.
|
|
Packit |
7d6a7d |
##
|
|
Packit |
7d6a7d |
## This program is free software; you can redistribute it and/or
|
|
Packit |
7d6a7d |
## modify it under the same terms as Perl itself.
|
|
Packit |
7d6a7d |
##
|
|
Packit |
7d6a7d |
################################################################################
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
=provides
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
mg_findext
|
|
Packit |
7d6a7d |
sv_unmagicext
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
__UNDEFINED__
|
|
Packit |
7d6a7d |
/sv_\w+_mg/
|
|
Packit |
7d6a7d |
sv_magic_portable
|
|
Packit |
7d6a7d |
MUTABLE_PTR
|
|
Packit |
7d6a7d |
MUTABLE_SV
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
=implementation
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
__UNDEFINED__ SvGETMAGIC(x) STMT_START { if (SvGMAGICAL(x)) mg_get(x); } STMT_END
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
/* Some random bits for sv_unmagicext. These should probably be pulled in for
|
|
Packit |
7d6a7d |
real and organized at some point */
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
__UNDEFINED__ HEf_SVKEY -2
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#ifndef MUTABLE_PTR
|
|
Packit |
7d6a7d |
#if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
|
|
Packit |
7d6a7d |
# define MUTABLE_PTR(p) ({ void *_p = (p); _p; })
|
|
Packit |
7d6a7d |
#else
|
|
Packit |
7d6a7d |
# define MUTABLE_PTR(p) ((void *) (p))
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
__UNDEFINED__ MUTABLE_SV(p) ((SV *)MUTABLE_PTR(p))
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
/* end of random bits */
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_sv '\0'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_overload 'A'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_overload_elem 'a'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_overload_table 'c'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_bm 'B'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_regdata 'D'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_regdatum 'd'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_env 'E'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_envelem 'e'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_fm 'f'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_regex_global 'g'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_isa 'I'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_isaelem 'i'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_nkeys 'k'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_dbfile 'L'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_dbline 'l'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_mutex 'm'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_shared 'N'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_shared_scalar 'n'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_collxfrm 'o'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_tied 'P'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_tiedelem 'p'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_tiedscalar 'q'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_qr 'r'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_sig 'S'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_sigelem 's'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_taint 't'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_uvar 'U'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_uvar_elem 'u'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_vstring 'V'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_vec 'v'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_utf8 'w'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_substr 'x'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_defelem 'y'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_glob '*'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_arylen '#'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_pos '.'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_backref '<'
|
|
Packit |
7d6a7d |
__UNDEFINED__ PERL_MAGIC_ext '~'
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
/* That's the best we can do... */
|
|
Packit |
7d6a7d |
__UNDEFINED__ sv_catpvn_nomg sv_catpvn
|
|
Packit |
7d6a7d |
__UNDEFINED__ sv_catsv_nomg sv_catsv
|
|
Packit |
7d6a7d |
__UNDEFINED__ sv_setsv_nomg sv_setsv
|
|
Packit |
7d6a7d |
__UNDEFINED__ sv_pvn_nomg sv_pvn
|
|
Packit |
7d6a7d |
__UNDEFINED__ SvIV_nomg SvIV
|
|
Packit |
7d6a7d |
__UNDEFINED__ SvUV_nomg SvUV
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#ifndef sv_catpv_mg
|
|
Packit |
7d6a7d |
# define sv_catpv_mg(sv, ptr) \
|
|
Packit |
7d6a7d |
STMT_START { \
|
|
Packit |
7d6a7d |
SV *TeMpSv = sv; \
|
|
Packit |
7d6a7d |
sv_catpv(TeMpSv,ptr); \
|
|
Packit |
7d6a7d |
SvSETMAGIC(TeMpSv); \
|
|
Packit |
7d6a7d |
} STMT_END
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#ifndef sv_catpvn_mg
|
|
Packit |
7d6a7d |
# define sv_catpvn_mg(sv, ptr, len) \
|
|
Packit |
7d6a7d |
STMT_START { \
|
|
Packit |
7d6a7d |
SV *TeMpSv = sv; \
|
|
Packit |
7d6a7d |
sv_catpvn(TeMpSv,ptr,len); \
|
|
Packit |
7d6a7d |
SvSETMAGIC(TeMpSv); \
|
|
Packit |
7d6a7d |
} STMT_END
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#ifndef sv_catsv_mg
|
|
Packit |
7d6a7d |
# define sv_catsv_mg(dsv, ssv) \
|
|
Packit |
7d6a7d |
STMT_START { \
|
|
Packit |
7d6a7d |
SV *TeMpSv = dsv; \
|
|
Packit |
7d6a7d |
sv_catsv(TeMpSv,ssv); \
|
|
Packit |
7d6a7d |
SvSETMAGIC(TeMpSv); \
|
|
Packit |
7d6a7d |
} STMT_END
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#ifndef sv_setiv_mg
|
|
Packit |
7d6a7d |
# define sv_setiv_mg(sv, i) \
|
|
Packit |
7d6a7d |
STMT_START { \
|
|
Packit |
7d6a7d |
SV *TeMpSv = sv; \
|
|
Packit |
7d6a7d |
sv_setiv(TeMpSv,i); \
|
|
Packit |
7d6a7d |
SvSETMAGIC(TeMpSv); \
|
|
Packit |
7d6a7d |
} STMT_END
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#ifndef sv_setnv_mg
|
|
Packit |
7d6a7d |
# define sv_setnv_mg(sv, num) \
|
|
Packit |
7d6a7d |
STMT_START { \
|
|
Packit |
7d6a7d |
SV *TeMpSv = sv; \
|
|
Packit |
7d6a7d |
sv_setnv(TeMpSv,num); \
|
|
Packit |
7d6a7d |
SvSETMAGIC(TeMpSv); \
|
|
Packit |
7d6a7d |
} STMT_END
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#ifndef sv_setpv_mg
|
|
Packit |
7d6a7d |
# define sv_setpv_mg(sv, ptr) \
|
|
Packit |
7d6a7d |
STMT_START { \
|
|
Packit |
7d6a7d |
SV *TeMpSv = sv; \
|
|
Packit |
7d6a7d |
sv_setpv(TeMpSv,ptr); \
|
|
Packit |
7d6a7d |
SvSETMAGIC(TeMpSv); \
|
|
Packit |
7d6a7d |
} STMT_END
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#ifndef sv_setpvn_mg
|
|
Packit |
7d6a7d |
# define sv_setpvn_mg(sv, ptr, len) \
|
|
Packit |
7d6a7d |
STMT_START { \
|
|
Packit |
7d6a7d |
SV *TeMpSv = sv; \
|
|
Packit |
7d6a7d |
sv_setpvn(TeMpSv,ptr,len); \
|
|
Packit |
7d6a7d |
SvSETMAGIC(TeMpSv); \
|
|
Packit |
7d6a7d |
} STMT_END
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#ifndef sv_setsv_mg
|
|
Packit |
7d6a7d |
# define sv_setsv_mg(dsv, ssv) \
|
|
Packit |
7d6a7d |
STMT_START { \
|
|
Packit |
7d6a7d |
SV *TeMpSv = dsv; \
|
|
Packit |
7d6a7d |
sv_setsv(TeMpSv,ssv); \
|
|
Packit |
7d6a7d |
SvSETMAGIC(TeMpSv); \
|
|
Packit |
7d6a7d |
} STMT_END
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#ifndef sv_setuv_mg
|
|
Packit |
7d6a7d |
# define sv_setuv_mg(sv, i) \
|
|
Packit |
7d6a7d |
STMT_START { \
|
|
Packit |
7d6a7d |
SV *TeMpSv = sv; \
|
|
Packit |
7d6a7d |
sv_setuv(TeMpSv,i); \
|
|
Packit |
7d6a7d |
SvSETMAGIC(TeMpSv); \
|
|
Packit |
7d6a7d |
} STMT_END
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#ifndef sv_usepvn_mg
|
|
Packit |
7d6a7d |
# define sv_usepvn_mg(sv, ptr, len) \
|
|
Packit |
7d6a7d |
STMT_START { \
|
|
Packit |
7d6a7d |
SV *TeMpSv = sv; \
|
|
Packit |
7d6a7d |
sv_usepvn(TeMpSv,ptr,len); \
|
|
Packit |
7d6a7d |
SvSETMAGIC(TeMpSv); \
|
|
Packit |
7d6a7d |
} STMT_END
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
__UNDEFINED__ SvVSTRING_mg(sv) (SvMAGICAL(sv) ? mg_find(sv, PERL_MAGIC_vstring) : NULL)
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
/* Hint: sv_magic_portable
|
|
Packit |
7d6a7d |
* This is a compatibility function that is only available with
|
|
Packit |
7d6a7d |
* Devel::PPPort. It is NOT in the perl core.
|
|
Packit |
7d6a7d |
* Its purpose is to mimic the 5.8.0 behaviour of sv_magic() when
|
|
Packit |
7d6a7d |
* it is being passed a name pointer with namlen == 0. In that
|
|
Packit |
7d6a7d |
* case, perl 5.8.0 and later store the pointer, not a copy of it.
|
|
Packit |
7d6a7d |
* The compatibility can be provided back to perl 5.004. With
|
|
Packit |
7d6a7d |
* earlier versions, the code will not compile.
|
|
Packit |
7d6a7d |
*/
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#if { VERSION < 5.004 }
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
/* code that uses sv_magic_portable will not compile */
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#elif { VERSION < 5.8.0 }
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
# define sv_magic_portable(sv, obj, how, name, namlen) \
|
|
Packit |
7d6a7d |
STMT_START { \
|
|
Packit |
7d6a7d |
SV *SvMp_sv = (sv); \
|
|
Packit |
7d6a7d |
char *SvMp_name = (char *) (name); \
|
|
Packit |
7d6a7d |
I32 SvMp_namlen = (namlen); \
|
|
Packit |
7d6a7d |
if (SvMp_name && SvMp_namlen == 0) \
|
|
Packit |
7d6a7d |
{ \
|
|
Packit |
7d6a7d |
MAGIC *mg; \
|
|
Packit |
7d6a7d |
sv_magic(SvMp_sv, obj, how, 0, 0); \
|
|
Packit |
7d6a7d |
mg = SvMAGIC(SvMp_sv); \
|
|
Packit |
7d6a7d |
mg->mg_len = -42; /* XXX: this is the tricky part */ \
|
|
Packit |
7d6a7d |
mg->mg_ptr = SvMp_name; \
|
|
Packit |
7d6a7d |
} \
|
|
Packit |
7d6a7d |
else \
|
|
Packit |
7d6a7d |
{ \
|
|
Packit |
7d6a7d |
sv_magic(SvMp_sv, obj, how, SvMp_name, SvMp_namlen); \
|
|
Packit |
7d6a7d |
} \
|
|
Packit |
7d6a7d |
} STMT_END
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#else
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
# define sv_magic_portable(a, b, c, d, e) sv_magic(a, b, c, d, e)
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#if !defined(mg_findext)
|
|
Packit |
7d6a7d |
#if { NEED mg_findext }
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
MAGIC *
|
|
Packit |
7d6a7d |
mg_findext(SV * sv, int type, const MGVTBL *vtbl) {
|
|
Packit |
7d6a7d |
if (sv) {
|
|
Packit |
7d6a7d |
MAGIC *mg;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#ifdef AvPAD_NAMELIST
|
|
Packit |
7d6a7d |
assert(!(SvTYPE(sv) == SVt_PVAV && AvPAD_NAMELIST(sv)));
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
for (mg = SvMAGIC (sv); mg; mg = mg->mg_moremagic) {
|
|
Packit |
7d6a7d |
if (mg->mg_type == type && mg->mg_virtual == vtbl)
|
|
Packit |
7d6a7d |
return mg;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
return NULL;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#if !defined(sv_unmagicext)
|
|
Packit |
7d6a7d |
#if { NEED sv_unmagicext }
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
int
|
|
Packit |
7d6a7d |
sv_unmagicext(pTHX_ SV *const sv, const int type, MGVTBL *vtbl)
|
|
Packit |
7d6a7d |
{
|
|
Packit |
7d6a7d |
MAGIC* mg;
|
|
Packit |
7d6a7d |
MAGIC** mgp;
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
if (SvTYPE(sv) < SVt_PVMG || !SvMAGIC(sv))
|
|
Packit |
7d6a7d |
return 0;
|
|
Packit |
7d6a7d |
mgp = &(SvMAGIC(sv));
|
|
Packit |
7d6a7d |
for (mg = *mgp; mg; mg = *mgp) {
|
|
Packit |
7d6a7d |
const MGVTBL* const virt = mg->mg_virtual;
|
|
Packit |
7d6a7d |
if (mg->mg_type == type && virt == vtbl) {
|
|
Packit |
7d6a7d |
*mgp = mg->mg_moremagic;
|
|
Packit |
7d6a7d |
if (virt && virt->svt_free)
|
|
Packit |
7d6a7d |
virt->svt_free(aTHX_ sv, mg);
|
|
Packit |
7d6a7d |
if (mg->mg_ptr && mg->mg_type != PERL_MAGIC_regex_global) {
|
|
Packit |
7d6a7d |
if (mg->mg_len > 0)
|
|
Packit |
7d6a7d |
Safefree(mg->mg_ptr);
|
|
Packit |
7d6a7d |
else if (mg->mg_len == HEf_SVKEY) /* Questionable on older perls... */
|
|
Packit |
7d6a7d |
SvREFCNT_dec(MUTABLE_SV(mg->mg_ptr));
|
|
Packit |
7d6a7d |
else if (mg->mg_type == PERL_MAGIC_utf8)
|
|
Packit |
7d6a7d |
Safefree(mg->mg_ptr);
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
if (mg->mg_flags & MGf_REFCOUNTED)
|
|
Packit |
7d6a7d |
SvREFCNT_dec(mg->mg_obj);
|
|
Packit |
7d6a7d |
Safefree(mg);
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
else
|
|
Packit |
7d6a7d |
mgp = &mg->mg_moremagic;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
if (SvMAGIC(sv)) {
|
|
Packit |
7d6a7d |
if (SvMAGICAL(sv)) /* if we're under save_magic, wait for restore_magic; */
|
|
Packit |
7d6a7d |
mg_magical(sv); /* else fix the flags now */
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
else {
|
|
Packit |
7d6a7d |
SvMAGICAL_off(sv);
|
|
Packit |
7d6a7d |
SvFLAGS(sv) |= (SvFLAGS(sv) & (SVp_IOK|SVp_NOK|SVp_POK)) >> PRIVSHIFT;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
return 0;
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
=xsinit
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#define NEED_mg_findext
|
|
Packit |
7d6a7d |
#define NEED_sv_unmagicext
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
#ifndef STATIC
|
|
Packit |
7d6a7d |
#define STATIC static
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
STATIC MGVTBL null_mg_vtbl = {
|
|
Packit |
7d6a7d |
NULL, /* get */
|
|
Packit |
7d6a7d |
NULL, /* set */
|
|
Packit |
7d6a7d |
NULL, /* len */
|
|
Packit |
7d6a7d |
NULL, /* clear */
|
|
Packit |
7d6a7d |
NULL, /* free */
|
|
Packit |
7d6a7d |
#if MGf_COPY
|
|
Packit |
7d6a7d |
NULL, /* copy */
|
|
Packit |
7d6a7d |
#endif /* MGf_COPY */
|
|
Packit |
7d6a7d |
#if MGf_DUP
|
|
Packit |
7d6a7d |
NULL, /* dup */
|
|
Packit |
7d6a7d |
#endif /* MGf_DUP */
|
|
Packit |
7d6a7d |
#if MGf_LOCAL
|
|
Packit |
7d6a7d |
NULL, /* local */
|
|
Packit |
7d6a7d |
#endif /* MGf_LOCAL */
|
|
Packit |
7d6a7d |
};
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
STATIC MGVTBL other_mg_vtbl = {
|
|
Packit |
7d6a7d |
NULL, /* get */
|
|
Packit |
7d6a7d |
NULL, /* set */
|
|
Packit |
7d6a7d |
NULL, /* len */
|
|
Packit |
7d6a7d |
NULL, /* clear */
|
|
Packit |
7d6a7d |
NULL, /* free */
|
|
Packit |
7d6a7d |
#if MGf_COPY
|
|
Packit |
7d6a7d |
NULL, /* copy */
|
|
Packit |
7d6a7d |
#endif /* MGf_COPY */
|
|
Packit |
7d6a7d |
#if MGf_DUP
|
|
Packit |
7d6a7d |
NULL, /* dup */
|
|
Packit |
7d6a7d |
#endif /* MGf_DUP */
|
|
Packit |
7d6a7d |
#if MGf_LOCAL
|
|
Packit |
7d6a7d |
NULL, /* local */
|
|
Packit |
7d6a7d |
#endif /* MGf_LOCAL */
|
|
Packit |
7d6a7d |
};
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
=xsubs
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
SV *
|
|
Packit |
7d6a7d |
new_with_other_mg(package, ...)
|
|
Packit |
7d6a7d |
SV *package
|
|
Packit |
7d6a7d |
PREINIT:
|
|
Packit |
7d6a7d |
HV *self;
|
|
Packit |
7d6a7d |
HV *stash;
|
|
Packit |
7d6a7d |
SV *self_ref;
|
|
Packit |
7d6a7d |
const char *data = "hello\0";
|
|
Packit |
7d6a7d |
MAGIC *mg;
|
|
Packit |
7d6a7d |
CODE:
|
|
Packit |
7d6a7d |
self = newHV();
|
|
Packit |
7d6a7d |
stash = gv_stashpv(SvPV_nolen(package), 0);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
self_ref = newRV_noinc((SV*)self);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sv_magic((SV*)self, NULL, PERL_MAGIC_ext, data, strlen(data));
|
|
Packit |
7d6a7d |
mg = mg_find((SV*)self, PERL_MAGIC_ext);
|
|
Packit |
7d6a7d |
if (mg)
|
|
Packit |
7d6a7d |
mg->mg_virtual = &other_mg_vtbl;
|
|
Packit |
7d6a7d |
else
|
|
Packit |
7d6a7d |
croak("No mg!");
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
RETVAL = sv_bless(self_ref, stash);
|
|
Packit |
7d6a7d |
OUTPUT:
|
|
Packit |
7d6a7d |
RETVAL
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
SV *
|
|
Packit |
7d6a7d |
new_with_mg(package, ...)
|
|
Packit |
7d6a7d |
SV *package
|
|
Packit |
7d6a7d |
PREINIT:
|
|
Packit |
7d6a7d |
HV *self;
|
|
Packit |
7d6a7d |
HV *stash;
|
|
Packit |
7d6a7d |
SV *self_ref;
|
|
Packit |
7d6a7d |
const char *data = "hello\0";
|
|
Packit |
7d6a7d |
MAGIC *mg;
|
|
Packit |
7d6a7d |
CODE:
|
|
Packit |
7d6a7d |
self = newHV();
|
|
Packit |
7d6a7d |
stash = gv_stashpv(SvPV_nolen(package), 0);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
self_ref = newRV_noinc((SV*)self);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sv_magic((SV*)self, NULL, PERL_MAGIC_ext, data, strlen(data));
|
|
Packit |
7d6a7d |
mg = mg_find((SV*)self, PERL_MAGIC_ext);
|
|
Packit |
7d6a7d |
if (mg)
|
|
Packit |
7d6a7d |
mg->mg_virtual = &null_mg_vtbl;
|
|
Packit |
7d6a7d |
else
|
|
Packit |
7d6a7d |
croak("No mg!");
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
RETVAL = sv_bless(self_ref, stash);
|
|
Packit |
7d6a7d |
OUTPUT:
|
|
Packit |
7d6a7d |
RETVAL
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
void
|
|
Packit |
7d6a7d |
remove_null_magic(self)
|
|
Packit |
7d6a7d |
SV *self
|
|
Packit |
7d6a7d |
PREINIT:
|
|
Packit |
7d6a7d |
HV *obj;
|
|
Packit |
7d6a7d |
PPCODE:
|
|
Packit |
7d6a7d |
obj = (HV*) SvRV(self);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sv_unmagicext((SV*)obj, PERL_MAGIC_ext, &null_mg_vtbl);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
void
|
|
Packit |
7d6a7d |
remove_other_magic(self)
|
|
Packit |
7d6a7d |
SV *self
|
|
Packit |
7d6a7d |
PREINIT:
|
|
Packit |
7d6a7d |
HV *obj;
|
|
Packit |
7d6a7d |
PPCODE:
|
|
Packit |
7d6a7d |
obj = (HV*) SvRV(self);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
sv_unmagicext((SV*)obj, PERL_MAGIC_ext, &other_mg_vtbl);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
void
|
|
Packit |
7d6a7d |
as_string(self)
|
|
Packit |
7d6a7d |
SV *self
|
|
Packit |
7d6a7d |
PREINIT:
|
|
Packit |
7d6a7d |
HV *obj;
|
|
Packit |
7d6a7d |
MAGIC *mg;
|
|
Packit |
7d6a7d |
PPCODE:
|
|
Packit |
7d6a7d |
obj = (HV*) SvRV(self);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
if ((mg = mg_findext((SV*)obj, PERL_MAGIC_ext, &null_mg_vtbl))) {
|
|
Packit |
7d6a7d |
XPUSHs(sv_2mortal(newSVpv(mg->mg_ptr, strlen(mg->mg_ptr))));
|
|
Packit |
7d6a7d |
} else {
|
|
Packit |
7d6a7d |
XPUSHs(sv_2mortal(newSVpvs("Sorry, your princess is in another castle.")));
|
|
Packit |
7d6a7d |
}
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
void
|
|
Packit |
7d6a7d |
sv_catpv_mg(sv, string)
|
|
Packit |
7d6a7d |
SV *sv;
|
|
Packit |
7d6a7d |
char *string;
|
|
Packit |
7d6a7d |
CODE:
|
|
Packit |
7d6a7d |
sv_catpv_mg(sv, string);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
void
|
|
Packit |
7d6a7d |
sv_catpvn_mg(sv, sv2)
|
|
Packit |
7d6a7d |
SV *sv;
|
|
Packit |
7d6a7d |
SV *sv2;
|
|
Packit |
7d6a7d |
PREINIT:
|
|
Packit |
7d6a7d |
char *str;
|
|
Packit |
7d6a7d |
STRLEN len;
|
|
Packit |
7d6a7d |
CODE:
|
|
Packit |
7d6a7d |
str = SvPV(sv2, len);
|
|
Packit |
7d6a7d |
sv_catpvn_mg(sv, str, len);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
void
|
|
Packit |
7d6a7d |
sv_catsv_mg(sv, sv2)
|
|
Packit |
7d6a7d |
SV *sv;
|
|
Packit |
7d6a7d |
SV *sv2;
|
|
Packit |
7d6a7d |
CODE:
|
|
Packit |
7d6a7d |
sv_catsv_mg(sv, sv2);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
void
|
|
Packit |
7d6a7d |
sv_setiv_mg(sv, iv)
|
|
Packit |
7d6a7d |
SV *sv;
|
|
Packit |
7d6a7d |
IV iv;
|
|
Packit |
7d6a7d |
CODE:
|
|
Packit |
7d6a7d |
sv_setiv_mg(sv, iv);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
void
|
|
Packit |
7d6a7d |
sv_setnv_mg(sv, nv)
|
|
Packit |
7d6a7d |
SV *sv;
|
|
Packit |
7d6a7d |
NV nv;
|
|
Packit |
7d6a7d |
CODE:
|
|
Packit |
7d6a7d |
sv_setnv_mg(sv, nv);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
void
|
|
Packit |
7d6a7d |
sv_setpv_mg(sv, pv)
|
|
Packit |
7d6a7d |
SV *sv;
|
|
Packit |
7d6a7d |
char *pv;
|
|
Packit |
7d6a7d |
CODE:
|
|
Packit |
7d6a7d |
sv_setpv_mg(sv, pv);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
void
|
|
Packit |
7d6a7d |
sv_setpvn_mg(sv, sv2)
|
|
Packit |
7d6a7d |
SV *sv;
|
|
Packit |
7d6a7d |
SV *sv2;
|
|
Packit |
7d6a7d |
PREINIT:
|
|
Packit |
7d6a7d |
char *str;
|
|
Packit |
7d6a7d |
STRLEN len;
|
|
Packit |
7d6a7d |
CODE:
|
|
Packit |
7d6a7d |
str = SvPV(sv2, len);
|
|
Packit |
7d6a7d |
sv_setpvn_mg(sv, str, len);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
void
|
|
Packit |
7d6a7d |
sv_setsv_mg(sv, sv2)
|
|
Packit |
7d6a7d |
SV *sv;
|
|
Packit |
7d6a7d |
SV *sv2;
|
|
Packit |
7d6a7d |
CODE:
|
|
Packit |
7d6a7d |
sv_setsv_mg(sv, sv2);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
void
|
|
Packit |
7d6a7d |
sv_setuv_mg(sv, uv)
|
|
Packit |
7d6a7d |
SV *sv;
|
|
Packit |
7d6a7d |
UV uv;
|
|
Packit |
7d6a7d |
CODE:
|
|
Packit |
7d6a7d |
sv_setuv_mg(sv, uv);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
void
|
|
Packit |
7d6a7d |
sv_usepvn_mg(sv, sv2)
|
|
Packit |
7d6a7d |
SV *sv;
|
|
Packit |
7d6a7d |
SV *sv2;
|
|
Packit |
7d6a7d |
PREINIT:
|
|
Packit |
7d6a7d |
char *str, *copy;
|
|
Packit |
7d6a7d |
STRLEN len;
|
|
Packit |
7d6a7d |
CODE:
|
|
Packit |
7d6a7d |
str = SvPV(sv2, len);
|
|
Packit |
7d6a7d |
New(42, copy, len+1, char);
|
|
Packit |
7d6a7d |
Copy(str, copy, len+1, char);
|
|
Packit |
7d6a7d |
sv_usepvn_mg(sv, copy, len);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
int
|
|
Packit |
7d6a7d |
SvVSTRING_mg(sv)
|
|
Packit |
7d6a7d |
SV *sv;
|
|
Packit |
7d6a7d |
CODE:
|
|
Packit |
7d6a7d |
RETVAL = SvVSTRING_mg(sv) != NULL;
|
|
Packit |
7d6a7d |
OUTPUT:
|
|
Packit |
7d6a7d |
RETVAL
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
int
|
|
Packit |
7d6a7d |
sv_magic_portable(sv)
|
|
Packit |
7d6a7d |
SV *sv
|
|
Packit |
7d6a7d |
PREINIT:
|
|
Packit |
7d6a7d |
MAGIC *mg;
|
|
Packit |
7d6a7d |
const char *foo = "foo";
|
|
Packit |
7d6a7d |
CODE:
|
|
Packit |
7d6a7d |
#if { VERSION >= 5.004 }
|
|
Packit |
7d6a7d |
sv_magic_portable(sv, 0, '~', foo, 0);
|
|
Packit |
7d6a7d |
mg = mg_find(sv, '~');
|
|
Packit |
7d6a7d |
if (!mg)
|
|
Packit |
7d6a7d |
croak("No mg!");
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
RETVAL = mg->mg_ptr == foo;
|
|
Packit |
7d6a7d |
#else
|
|
Packit |
7d6a7d |
sv_magic(sv, 0, '~', (char *) foo, strlen(foo));
|
|
Packit |
7d6a7d |
mg = mg_find(sv, '~');
|
|
Packit |
7d6a7d |
RETVAL = strEQ(mg->mg_ptr, foo);
|
|
Packit |
7d6a7d |
#endif
|
|
Packit |
7d6a7d |
sv_unmagic(sv, '~');
|
|
Packit |
7d6a7d |
OUTPUT:
|
|
Packit |
7d6a7d |
RETVAL
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
=tests plan => 23
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
# Find proper magic
|
|
Packit |
7d6a7d |
ok(my $obj1 = Devel::PPPort->new_with_mg());
|
|
Packit |
7d6a7d |
ok(Devel::PPPort::as_string($obj1), 'hello');
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
# Find with no magic
|
|
Packit |
7d6a7d |
my $obj = bless {}, 'Fake::Class';
|
|
Packit |
7d6a7d |
ok(Devel::PPPort::as_string($obj), "Sorry, your princess is in another castle.");
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
# Find with other magic (not the magic we are looking for)
|
|
Packit |
7d6a7d |
ok($obj = Devel::PPPort->new_with_other_mg());
|
|
Packit |
7d6a7d |
ok(Devel::PPPort::as_string($obj), "Sorry, your princess is in another castle.");
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
# Okay, attempt to remove magic that isn't there
|
|
Packit |
7d6a7d |
Devel::PPPort::remove_other_magic($obj1);
|
|
Packit |
7d6a7d |
ok(Devel::PPPort::as_string($obj1), 'hello');
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
# Remove magic that IS there
|
|
Packit |
7d6a7d |
Devel::PPPort::remove_null_magic($obj1);
|
|
Packit |
7d6a7d |
ok(Devel::PPPort::as_string($obj1), "Sorry, your princess is in another castle.");
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
# Removing when no magic present
|
|
Packit |
7d6a7d |
Devel::PPPort::remove_null_magic($obj1);
|
|
Packit |
7d6a7d |
ok(Devel::PPPort::as_string($obj1), "Sorry, your princess is in another castle.");
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
use Tie::Hash;
|
|
Packit |
7d6a7d |
my %h;
|
|
Packit |
7d6a7d |
tie %h, 'Tie::StdHash';
|
|
Packit |
7d6a7d |
$h{foo} = 'foo';
|
|
Packit |
7d6a7d |
$h{bar} = '';
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
&Devel::PPPort::sv_catpv_mg($h{foo}, 'bar');
|
|
Packit |
7d6a7d |
ok($h{foo}, 'foobar');
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
&Devel::PPPort::sv_catpvn_mg($h{bar}, 'baz');
|
|
Packit |
7d6a7d |
ok($h{bar}, 'baz');
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
&Devel::PPPort::sv_catsv_mg($h{foo}, '42');
|
|
Packit |
7d6a7d |
ok($h{foo}, 'foobar42');
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
&Devel::PPPort::sv_setiv_mg($h{bar}, 42);
|
|
Packit |
7d6a7d |
ok($h{bar}, 42);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
&Devel::PPPort::sv_setnv_mg($h{PI}, 3.14159);
|
|
Packit |
7d6a7d |
ok(abs($h{PI} - 3.14159) < 0.01);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
&Devel::PPPort::sv_setpv_mg($h{mhx}, 'mhx');
|
|
Packit |
7d6a7d |
ok($h{mhx}, 'mhx');
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
&Devel::PPPort::sv_setpvn_mg($h{mhx}, 'Marcus');
|
|
Packit |
7d6a7d |
ok($h{mhx}, 'Marcus');
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
&Devel::PPPort::sv_setsv_mg($h{sv}, 'SV');
|
|
Packit |
7d6a7d |
ok($h{sv}, 'SV');
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
&Devel::PPPort::sv_setuv_mg($h{sv}, 4711);
|
|
Packit |
7d6a7d |
ok($h{sv}, 4711);
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
&Devel::PPPort::sv_usepvn_mg($h{sv}, 'Perl');
|
|
Packit |
7d6a7d |
ok($h{sv}, 'Perl');
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
# v1 is treated as a bareword in older perls...
|
|
Packit |
7d6a7d |
my $ver = do { local $SIG{'__WARN__'} = sub {}; eval qq[v1.2.0] };
|
|
Packit |
7d6a7d |
ok($] < 5.009 || $@ eq '');
|
|
Packit |
7d6a7d |
ok($] < 5.009 || Devel::PPPort::SvVSTRING_mg($ver));
|
|
Packit |
7d6a7d |
ok(!Devel::PPPort::SvVSTRING_mg(4711));
|
|
Packit |
7d6a7d |
|
|
Packit |
7d6a7d |
my $foo = 'bar';
|
|
Packit |
7d6a7d |
ok(Devel::PPPort::sv_magic_portable($foo));
|
|
Packit |
7d6a7d |
ok($foo eq 'bar');
|