Blame parts/inc/magic

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');