#include #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "Exception.h" SV *Exception_new(char *type) { I32 retval; SV *exc = (SV *)0; dSP; ENTER; SAVETMPS; PUSHMARK(sp); XPUSHs(sv_2mortal(newSVpv(type,0))); PUTBACK; retval = perl_call_method("new",G_SCALAR | G_EVAL); SPAGAIN; if (retval == 1 && !SvTRUE(GvSV(errgv))) { exc = POPs; SvREFCNT_inc(exc); } PUTBACK; FREETMPS; LEAVE; return exc; } ECODE Exception_throw(SV *exc,char **argv) { if (SvROK(exc)) { dSP; PUSHMARK(sp); XPUSHs(exc); if (argv != (char **)0) while (*argv != 0) { XPUSHs(sv_2mortal(newSVpv(*argv,0))); argv++; } PUTBACK; sv_2mortal(exc); perl_call_method("throw",G_DISCARD); return E_ERROR; /* shouldn't happen */ } return E_NOEXCEPTION; } ECODE Exception_setField(SV *exc,char *key,char *val) { if (SvROK(exc) && SvTYPE(SvRV(exc)) == SVt_PVHV) { HV *hash = (HV *)SvRV(exc); hv_store(hash,key,strlen(key),newSVpv(val,0),0); return E_OK; } else return E_NOEXCEPTION; } char *Exception_getField(SV *exc,char *key) { if (SvROK(exc) && SvTYPE(SvRV(exc)) == SVt_PVHV) { HV *hash = (HV *)SvRV(exc); SV **sv_ptr = hv_fetch(hash,key,strlen(key),0); if (sv_ptr == (SV **)0 || !SvPOK(*sv_ptr)) return (char *)0; return SvPV(*sv_ptr, na); } else return (char *)0; } ECODE Exception_throwMessage(char *type,char *mess) { SV *exc = Exception_new(type); if (exc != 0 && SvROK(exc) && sv_isa(exc,type)) { dSP; Exception_setField(exc,"Message",mess); PUSHMARK(sp); XPUSHs(exc); PUTBACK; sv_2mortal(exc); perl_call_method("throw",G_DISCARD); return E_ERROR; /* shouldn't happen */ } return E_NOEXCEPTION; }