X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2Fre-engine-Plugin.git;a=blobdiff_plain;f=Plugin.xs;h=6036d87fff2bf36dfea4aa33fa3a6bbe9fdd4243;hp=10a01ae68abc7a8b54dcc6b896eaf333a3e8f9ea;hb=182fcce5112d0394e1678a80b3f17b3581918f7e;hpb=5432eb59f83cbde4b5f7444bd849ef3bac4c2365 diff --git a/Plugin.xs b/Plugin.xs index 10a01ae..6036d87 100644 --- a/Plugin.xs +++ b/Plugin.xs @@ -18,6 +18,7 @@ typedef struct { SV *comp; SV *exec; + SV *free; } xsh_hints_user_t; static SV *rep_validate_callback(SV *code) { @@ -34,6 +35,7 @@ static SV *rep_validate_callback(SV *code) { static void xsh_hints_user_init(pTHX_ xsh_hints_user_t *hv, xsh_hints_user_t *v) { hv->comp = rep_validate_callback(v->comp); hv->exec = rep_validate_callback(v->exec); + hv->free = rep_validate_callback(v->free); return; } @@ -43,6 +45,7 @@ static void xsh_hints_user_init(pTHX_ xsh_hints_user_t *hv, xsh_hints_user_t *v) static void xsh_hints_user_clone(pTHX_ xsh_hints_user_t *nv, xsh_hints_user_t *ov, CLONE_PARAMS *params) { nv->comp = xsh_dup_inc(ov->comp, params); nv->exec = xsh_dup_inc(ov->exec, params); + nv->free = xsh_dup_inc(ov->free, params); return; } @@ -52,6 +55,7 @@ static void xsh_hints_user_clone(pTHX_ xsh_hints_user_t *nv, xsh_hints_user_t *o static void xsh_hints_user_deinit(pTHX_ xsh_hints_user_t *hv) { SvREFCNT_dec(hv->comp); SvREFCNT_dec(hv->exec); + SvREFCNT_dec(hv->free); return; } @@ -75,10 +79,6 @@ static void xsh_hints_user_deinit(pTHX_ xsh_hints_user_t *hv) { /* --- Custom regexp engine ------------------------------------------------ */ -#define GET_SELF_FROM_PPRIVATE(pprivate) \ - re__engine__Plugin self; \ - SELF_FROM_PPRIVATE(self,pprivate); - /* re__engine__Plugin self; SELF_FROM_PPRIVATE(self,rx->pprivate) */ #define SELF_FROM_PPRIVATE(self, pprivate) \ if (sv_isobject(pprivate)) { \ @@ -192,17 +192,13 @@ Plugin_comp(pTHX_ SV * const pattern, U32 flags) Plugin_comp(pTHX_ const SV * const pattern, const U32 flags) #endif { - dSP; - struct regexp *rx; - REGEXP *RX; - - re__engine__Plugin re; const xsh_hints_user_t *h; - + REGEXP *RX; + struct regexp *rx; + re__engine__Plugin re; + char *pbuf; STRLEN plen; - char *pbuf; - - SV *obj; + SV *obj; h = rep_hint(); if (!h) /* This looks like a pragma leak. Apply the default behaviour */ @@ -213,9 +209,8 @@ Plugin_comp(pTHX_ const SV * const pattern, const U32 flags) /* Our blessed object */ obj = newSV(0); - SvREFCNT_inc_simple_void_NN(obj); - Newxz(re, 1, struct replug); - sv_setref_pv(obj, "re::engine::Plugin", (void *) re); + Newx(re, 1, struct replug); + sv_setref_pv(obj, XSH_PACKAGE, (void *) re); newREGEXP(RX); rx = rxREGEXP(RX); @@ -246,12 +241,17 @@ Plugin_comp(pTHX_ const SV * const pattern, const U32 flags) re->pattern = (SV *) pattern; SvREFCNT_inc_simple_void(re->pattern); - /* If there's an exec callback, store it into the private object so that it - * will be the one to be called, even if the engine changes in between */ - if (h->exec) { - re->cb_exec = h->exec; - SvREFCNT_inc_simple_void_NN(h->exec); - } + re->str = NULL; + re->stash = NULL; + + /* Store the default exec callback (which may be NULL) into the regexp + * object. */ + re->cb_exec = h->exec; + SvREFCNT_inc_simple_void(h->exec); + + /* Same goes for the free callback. */ + re->cb_free = h->free; + SvREFCNT_inc_simple_void(h->free); re->cb_num_capture_buff_FETCH = NULL; re->cb_num_capture_buff_STORE = NULL; @@ -260,6 +260,8 @@ Plugin_comp(pTHX_ const SV * const pattern, const U32 flags) /* Call our callback function if one was defined, if not we've already set up * all the stuff we're going to to need for subsequent exec and other calls */ if (h->comp) { + dSP; + ENTER; SAVETMPS; @@ -285,14 +287,16 @@ Plugin_exec(pTHX_ REGEXP * const RX, char *stringarg, char *strend, char *strbeg, REP_ENG_EXEC_MINEND_TYPE minend, SV *sv, void *data, U32 flags) { - dSP; + struct regexp *rx; + re__engine__Plugin self; I32 matched; - struct regexp *rx = rxREGEXP(RX); - GET_SELF_FROM_PPRIVATE(rx->pprivate); + rx = rxREGEXP(RX); + SELF_FROM_PPRIVATE(self, rx->pprivate); if (self->cb_exec) { SV *ret; + dSP; /* Store the current str for ->str */ SvREFCNT_dec(self->str); @@ -360,8 +364,9 @@ Plugin_checkstr(pTHX_ REGEXP * const RX) void Plugin_free(pTHX_ REGEXP * const RX) { - struct regexp *rx; + struct regexp *rx; re__engine__Plugin self; + SV *callback; if (PL_dirty) return; @@ -369,25 +374,11 @@ Plugin_free(pTHX_ REGEXP * const RX) rx = rxREGEXP(RX); SELF_FROM_PPRIVATE(self, rx->pprivate); - SvREFCNT_dec(self->pattern); - SvREFCNT_dec(self->str); - - SvREFCNT_dec(self->cb_exec); - - SvREFCNT_dec(self->cb_num_capture_buff_FETCH); - SvREFCNT_dec(self->cb_num_capture_buff_STORE); - SvREFCNT_dec(self->cb_num_capture_buff_LENGTH); - - self->rx = NULL; - Safefree(self); - -/* - dSP; - SV *callback; - callback = self->cb_free; if (callback) { + dSP; + ENTER; SAVETMPS; @@ -401,8 +392,24 @@ Plugin_free(pTHX_ REGEXP * const RX) FREETMPS; LEAVE; } + + SvREFCNT_dec(self->pattern); + SvREFCNT_dec(self->str); + SvREFCNT_dec(self->stash); + + SvREFCNT_dec(self->cb_exec); + + SvREFCNT_dec(self->cb_num_capture_buff_FETCH); + SvREFCNT_dec(self->cb_num_capture_buff_STORE); + SvREFCNT_dec(self->cb_num_capture_buff_LENGTH); + + self->rx = NULL; + + Safefree(self); + + SvREFCNT_dec(rx->pprivate); + return; -*/ } void * @@ -420,22 +427,25 @@ void Plugin_numbered_buff_FETCH(pTHX_ REGEXP * const RX, const I32 paren, SV * const sv) { - dSP; - I32 items; + struct regexp *rx; + re__engine__Plugin self; SV *callback; - struct regexp *rx = rxREGEXP(RX); - GET_SELF_FROM_PPRIVATE(rx->pprivate); + rx = rxREGEXP(RX); + SELF_FROM_PPRIVATE(self, rx->pprivate); callback = self->cb_num_capture_buff_FETCH; if (callback) { + I32 items; + dSP; + ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(rx->pprivate); - XPUSHs(sv_2mortal(newSViv(paren))); + mXPUSHi(paren); PUTBACK; items = call_sv(callback, G_SCALAR); @@ -461,21 +471,24 @@ void Plugin_numbered_buff_STORE(pTHX_ REGEXP * const RX, const I32 paren, SV const * const value) { - dSP; + struct regexp *rx; + re__engine__Plugin self; SV *callback; - struct regexp *rx = rxREGEXP(RX); - GET_SELF_FROM_PPRIVATE(rx->pprivate); + rx = rxREGEXP(RX); + SELF_FROM_PPRIVATE(self, rx->pprivate); callback = self->cb_num_capture_buff_STORE; if (callback) { + dSP; + ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(rx->pprivate); - XPUSHs(sv_2mortal(newSViv(paren))); + mXPUSHi(paren); XPUSHs((SV *) value); PUTBACK; @@ -491,23 +504,25 @@ I32 Plugin_numbered_buff_LENGTH(pTHX_ REGEXP * const RX, const SV * const sv, const I32 paren) { - dSP; + struct regexp *rx; + re__engine__Plugin self; SV *callback; - struct regexp *rx = rxREGEXP(RX); - GET_SELF_FROM_PPRIVATE(rx->pprivate); + rx = rxREGEXP(RX); + SELF_FROM_PPRIVATE(self, rx->pprivate); callback = self->cb_num_capture_buff_LENGTH; if (callback) { IV ret; + dSP; ENTER; SAVETMPS; PUSHMARK(SP); XPUSHs(rx->pprivate); - XPUSHs(sv_2mortal(newSViv(paren))); + mXPUSHi(paren); PUTBACK; call_sv(callback, G_SCALAR); @@ -546,7 +561,7 @@ Plugin_package(pTHX_ REGEXP * const RX) { PERL_UNUSED_ARG(RX); - return newSVpvs("re::engine::Plugin"); + return newSVpvs(XSH_PACKAGE); } static void xsh_user_global_setup(pTHX) { @@ -584,11 +599,13 @@ void pattern(re::engine::Plugin self, ...) PPCODE: XPUSHs(self->pattern); + XSRETURN(1); void str(re::engine::Plugin self, ...) PPCODE: XPUSHs(self->str); + XSRETURN(1); void mod(re::engine::Plugin self) @@ -626,6 +643,7 @@ PPCODE: XSRETURN_EMPTY; } else { XPUSHs(self->stash); + XSRETURN(1); } void @@ -634,12 +652,11 @@ PPCODE: if (items > 1) { self->rx->minlen = (I32)SvIV(ST(1)); XSRETURN_EMPTY; + } else if (self->rx->minlen) { + mXPUSHi(self->rx->minlen); + XSRETURN(1); } else { - if (self->rx->minlen) { - XPUSHs(sv_2mortal(newSViv(self->rx->minlen))); - } else { - XPUSHs(sv_2mortal(&PL_sv_undef)); - } + XSRETURN_UNDEF; } void @@ -648,12 +665,11 @@ PPCODE: if (items > 1) { self->rx->gofs = (U32)SvIV(ST(1)); XSRETURN_EMPTY; + } else if (self->rx->gofs) { + mXPUSHu(self->rx->gofs); + XSRETURN(1); } else { - if (self->rx->gofs) { - XPUSHs(sv_2mortal(newSVuv(self->rx->gofs))); - } else { - XPUSHs(sv_2mortal(&PL_sv_undef)); - } + XSRETURN_UNDEF; } void @@ -662,12 +678,11 @@ PPCODE: if (items > 1) { self->rx->nparens = (U32)SvIV(ST(1)); XSRETURN_EMPTY; + } else if (self->rx->nparens) { + mXPUSHu(self->rx->nparens); + XSRETURN(1); } else { - if (self->rx->nparens) { - XPUSHs(sv_2mortal(newSVuv(self->rx->nparens))); - } else { - XPUSHs(sv_2mortal(&PL_sv_undef)); - } + XSRETURN_UNDEF; } void @@ -678,6 +693,17 @@ PPCODE: self->cb_exec = ST(1); SvREFCNT_inc_simple_void(self->cb_exec); } + XSRETURN(0); + +void +_free(re::engine::Plugin self, ...) +PPCODE: + if (items > 1) { + SvREFCNT_dec(self->cb_free); + self->cb_free = ST(1); + SvREFCNT_inc_simple_void(self->cb_free); + } + XSRETURN(0); void _num_capture_buff_FETCH(re::engine::Plugin self, ...) @@ -687,6 +713,7 @@ PPCODE: self->cb_num_capture_buff_FETCH = ST(1); SvREFCNT_inc_simple_void(self->cb_num_capture_buff_FETCH); } + XSRETURN(0); void _num_capture_buff_STORE(re::engine::Plugin self, ...) @@ -696,6 +723,7 @@ PPCODE: self->cb_num_capture_buff_STORE = ST(1); SvREFCNT_inc_simple_void(self->cb_num_capture_buff_STORE); } + XSRETURN(0); void _num_capture_buff_LENGTH(re::engine::Plugin self, ...) @@ -705,14 +733,16 @@ PPCODE: self->cb_num_capture_buff_LENGTH = ST(1); SvREFCNT_inc_simple_void(self->cb_num_capture_buff_LENGTH); } + XSRETURN(0); SV * -_tag(SV *comp, SV *exec) +_tag(SV *comp, SV *exec, SV *free) PREINIT: xsh_hints_user_t arg; CODE: arg.comp = comp; arg.exec = exec; + arg.free = free; RETVAL = xsh_hints_tag(&arg); OUTPUT: RETVAL @@ -720,4 +750,5 @@ OUTPUT: void ENGINE() PPCODE: - XPUSHs(sv_2mortal(newSViv(PTR2IV(&engine_plugin)))); + mXPUSHi(PTR2IV(&engine_plugin)); + XSRETURN(1);