]> git.vpit.fr Git - perl/modules/re-engine-Plugin.git/blobdiff - Plugin.xs
This is 0.12
[perl/modules/re-engine-Plugin.git] / Plugin.xs
index da33ce2ff9050a130fe6f6d79d58d8b3b6262814..d75c0869a22602177a49fbb1568341eba5ddee82 100644 (file)
--- 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;
 }
@@ -188,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 */
@@ -209,7 +209,7 @@ Plugin_comp(pTHX_ const SV * const pattern, const U32 flags)
 
  /* Our blessed object */
  obj = newSV(0);
Newxz(re, 1, struct replug);
XSH_LOCAL_ALLOC(re, 1, struct replug);
  sv_setref_pv(obj, XSH_PACKAGE, (void *) re);
 
  newREGEXP(RX);
@@ -241,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;
@@ -255,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;
 
@@ -280,7 +287,7 @@ Plugin_exec(pTHX_ REGEXP * const RX, char *stringarg, char *strend,
             char *strbeg, REP_ENG_EXEC_MINEND_TYPE minend,
             SV *sv, void *data, U32 flags)
 {
- struct regexp *rx;
+ struct regexp     *rx;
  re__engine__Plugin self;
  I32 matched;
 
@@ -357,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;
@@ -366,29 +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->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);
-
-/*
- dSP;
- SV *callback;
-
  callback = self->cb_free;
 
  if (callback) {
+  dSP;
+
   ENTER;
   SAVETMPS;
 
@@ -402,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;
+
+ XSH_LOCAL_FREE(self, 1, struct replug);
+
+ SvREFCNT_dec(rx->pprivate);
+
  return;
-*/
 }
 
 void *
@@ -421,7 +427,7 @@ void
 Plugin_numbered_buff_FETCH(pTHX_ REGEXP * const RX, const I32 paren,
                            SV * const sv)
 {
- struct regexp *rx;
+ struct regexp     *rx;
  re__engine__Plugin self;
  SV *callback;
 
@@ -439,7 +445,7 @@ Plugin_numbered_buff_FETCH(pTHX_ REGEXP * const RX, const I32 paren,
 
   PUSHMARK(SP);
   XPUSHs(rx->pprivate);
-  XPUSHs(sv_2mortal(newSViv(paren)));
+  mXPUSHi(paren);
   PUTBACK;
 
   items = call_sv(callback, G_SCALAR);
@@ -465,7 +471,7 @@ void
 Plugin_numbered_buff_STORE(pTHX_ REGEXP * const RX, const I32 paren,
                            SV const * const value)
 {
- struct regexp *rx;
+ struct regexp     *rx;
  re__engine__Plugin self;
  SV *callback;
 
@@ -482,7 +488,7 @@ Plugin_numbered_buff_STORE(pTHX_ REGEXP * const RX, const I32 paren,
 
   PUSHMARK(SP);
   XPUSHs(rx->pprivate);
-  XPUSHs(sv_2mortal(newSViv(paren)));
+  mXPUSHi(paren);
   XPUSHs((SV *) value);
   PUTBACK;
 
@@ -498,7 +504,7 @@ I32
 Plugin_numbered_buff_LENGTH(pTHX_ REGEXP * const RX, const SV * const sv,
                             const I32 paren)
 {
- struct regexp *rx;
+ struct regexp     *rx;
  re__engine__Plugin self;
  SV *callback;
 
@@ -516,7 +522,7 @@ Plugin_numbered_buff_LENGTH(pTHX_ REGEXP * const RX, const SV * const sv,
 
   PUSHMARK(SP);
   XPUSHs(rx->pprivate);
-  XPUSHs(sv_2mortal(newSViv(paren)));
+  mXPUSHi(paren);
   PUTBACK;
 
   call_sv(callback, G_SCALAR);
@@ -646,13 +652,11 @@ PPCODE:
  if (items > 1) {
   self->rx->minlen = (I32)SvIV(ST(1));
   XSRETURN_EMPTY;
- } else {
-  if (self->rx->minlen) {
-   XPUSHs(sv_2mortal(newSViv(self->rx->minlen)));
-  } else {
-   XPUSHs(sv_2mortal(&PL_sv_undef));
-  }
+ } else if (self->rx->minlen) {
+  mXPUSHi(self->rx->minlen);
   XSRETURN(1);
+ } else {
+  XSRETURN_UNDEF;
  }
 
 void
@@ -661,13 +665,11 @@ PPCODE:
  if (items > 1) {
   self->rx->gofs = (U32)SvIV(ST(1));
   XSRETURN_EMPTY;
- } else {
-  if (self->rx->gofs) {
-   XPUSHs(sv_2mortal(newSVuv(self->rx->gofs)));
-  } else {
-   XPUSHs(sv_2mortal(&PL_sv_undef));
-  }
+ } else if (self->rx->gofs) {
+  mXPUSHu(self->rx->gofs);
   XSRETURN(1);
+ } else {
+  XSRETURN_UNDEF;
  }
 
 void
@@ -676,13 +678,11 @@ PPCODE:
  if (items > 1) {
   self->rx->nparens = (U32)SvIV(ST(1));
   XSRETURN_EMPTY;
- } else {
-  if (self->rx->nparens) {
-   XPUSHs(sv_2mortal(newSVuv(self->rx->nparens)));
-  } else {
-   XPUSHs(sv_2mortal(&PL_sv_undef));
-  }
+ } else if (self->rx->nparens) {
+  mXPUSHu(self->rx->nparens);
   XSRETURN(1);
+ } else {
+  XSRETURN_UNDEF;
  }
 
 void
@@ -695,6 +695,16 @@ PPCODE:
  }
  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, ...)
 PPCODE:
@@ -726,12 +736,13 @@ PPCODE:
  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
@@ -739,5 +750,5 @@ OUTPUT:
 void
 ENGINE()
 PPCODE:
XPUSHs(sv_2mortal(newSViv(PTR2IV(&engine_plugin))));
mXPUSHi(PTR2IV(&engine_plugin));
  XSRETURN(1);