X-Git-Url: http://git.vpit.fr/?p=perl%2Fmodules%2Fre-engine-Plugin.git;a=blobdiff_plain;f=Plugin.xs;h=3abd900c12e2a74beaa3d6795028307c44fe0160;hp=483d294f371cf789fa1daabc5816f935fd07a94f;hb=bc365867d2883a69972ef82adf4b19d0680e43aa;hpb=990ba6fd714681b2a6d50ac5153d654bfea0ccdd diff --git a/Plugin.xs b/Plugin.xs index 483d294..3abd900 100644 --- a/Plugin.xs +++ b/Plugin.xs @@ -1,3 +1,7 @@ +/* This file is part of the re::engine::Plugin Perl module. + * See http://search.cpan.org/dist/re-engine-Plugin/ */ + +#define PERL_NO_GET_CONTEXT #include "EXTERN.h" #include "perl.h" #include "XSUB.h" @@ -267,6 +271,10 @@ Plugin_comp(pTHX_ SV * const pattern, U32 flags) re__engine__Plugin re; const rep_hint_t *h; + h = rep_hint(); + if (!h) /* This looks like a pragma leak. Apply the default behaviour */ + return re_compile(pattern, flags); + /* exp/xend version of the pattern & length */ STRLEN plen; char* exp = SvPV((SV*)pattern, plen); @@ -307,13 +315,22 @@ Plugin_comp(pTHX_ SV * const pattern, U32 flags) re->pattern = (SV*)pattern; SvREFCNT_inc(re->pattern); - /* - * Call our callback function if one was defined, if not we've + /* 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->cb_num_capture_buff_FETCH = NULL; + re->cb_num_capture_buff_STORE = NULL; + re->cb_num_capture_buff_LENGTH = NULL; + + /* 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 - */ - h = rep_hint(); - if (h && h->comp) { + * subsequent exec and other calls */ + if (h->comp) { ENTER; SAVETMPS; @@ -345,11 +362,9 @@ Plugin_exec(pTHX_ REGEXP * const RX, char *stringarg, char *strend, dSP; I32 matched; struct regexp *rx = rxREGEXP(RX); - const rep_hint_t *h; GET_SELF_FROM_PPRIVATE(rx->pprivate); - h = rep_hint(); - if (h && h->exec) { + if (self->cb_exec) { /* Store the current str for ->str */ self->str = (SV*)sv; SvREFCNT_inc(self->str); @@ -362,7 +377,7 @@ Plugin_exec(pTHX_ REGEXP * const RX, char *stringarg, char *strend, XPUSHs(sv); PUTBACK; - call_sv(h->exec, G_SCALAR); + call_sv(self->cb_exec, G_SCALAR); SPAGAIN; @@ -406,11 +421,24 @@ Plugin_checkstr(pTHX_ REGEXP * const RX) void Plugin_free(pTHX_ REGEXP * const RX) { - PERL_UNUSED_ARG(RX); + struct regexp *rx = rxREGEXP(RX); + GET_SELF_FROM_PPRIVATE(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; - GET_SELF_FROM_PPRIVATE(rx->pprivate); callback = self->cb_free; @@ -740,10 +768,20 @@ PPCODE: } } +void +_exec(re::engine::Plugin self, ...) +PPCODE: + if (items > 1) { + SvREFCNT_dec(self->cb_exec); + self->cb_exec = ST(1); + SvREFCNT_inc(self->cb_exec); + } + void _num_capture_buff_FETCH(re::engine::Plugin self, ...) PPCODE: if (items > 1) { + SvREFCNT_dec(self->cb_num_capture_buff_FETCH); self->cb_num_capture_buff_FETCH = ST(1); SvREFCNT_inc(self->cb_num_capture_buff_FETCH); } @@ -752,6 +790,7 @@ void _num_capture_buff_STORE(re::engine::Plugin self, ...) PPCODE: if (items > 1) { + SvREFCNT_dec(self->cb_num_capture_buff_STORE); self->cb_num_capture_buff_STORE = ST(1); SvREFCNT_inc(self->cb_num_capture_buff_STORE); } @@ -760,6 +799,7 @@ void _num_capture_buff_LENGTH(re::engine::Plugin self, ...) PPCODE: if (items > 1) { + SvREFCNT_dec(self->cb_num_capture_buff_LENGTH); self->cb_num_capture_buff_LENGTH = ST(1); SvREFCNT_inc(self->cb_num_capture_buff_LENGTH); }