- dSP;
- register regexp *r;
- int count;
-
- /*
- * Allocate a new regexp struct, we must only write to the intflags,
- * engine and private members and the others must be populated,
- * internals expect the regex to have certain values least our code
- * blow up
- */
-
- Newxz(r,1,regexp);
-
- /* Set up the regex to be handled by this plugin */
- r->engine = &engine_plugin;
-
- /* Store the initial flags */
- r->intflags = pm->op_pmflags;
- r->pprivate = NULL; /* this is set to our object below */
-
- /*
- * Populate the regexp members for the engine
- */
-
- /* Ref count of the pattern */
- r->refcnt = 1;
-
- /* Preserve a copy of the original pattern */
- r->prelen = xend - exp;
- r->precomp = SAVEPVN(exp, r->prelen);
-
- /* these may be changed by accessors */
- r->minlen = 0;
- r->minlenret = 0;
- r->gofs = 0;
- r->nparens = 0;
-
- /* Store the flags as perl expects them */
- r->extflags = pm->op_pmflags & RXf_PMf_COMPILETIME;
-
- /*
- * Construct a new B<re::engine::Plugin> object that'll carry around
- * our data inside C<< r->pprivate >>. The object is a blessed void*
- * that points to our replug struct which holds any state we want to
- * keep.
- */
- re__engine__Plugin re;
- Newz(0, re, 1, struct replug);
-
- SV *obj = newSV(0);
- SvREFCNT_inc(obj);
-
- /* Bless into this package; TODO: make it subclassable */
- const char * pkg = "re::engine::Plugin";
- /* bless it */
- sv_setref_pv(obj, pkg, (void*)re);
-
- /* Store our private object */
- r->pprivate = obj;
-
- re->pattern = newSVpvn(SAVEPVN(exp, xend - exp), xend - exp);
- SvREFCNT_inc(re->pattern);
-
- /* Concat [ec]gimosxp (egimosxp & cgimosxp into) the flags string as
- * appropriate
- */
- if (r->intflags & PMf_EVAL) { strcat(re->flags, "e"); }
- if (r->intflags & PMf_CONTINUE) { strcat(re->flags, "c"); }
- if (r->intflags & PMf_GLOBAL) { strcat(re->flags, "g"); }
- if (r->intflags & PMf_FOLD) { strcat(re->flags, "i"); }
- if (r->intflags & PMf_MULTILINE) { strcat(re->flags, "m"); }
- if (r->intflags & PMf_ONCE) { strcat(re->flags, "o"); }
- if (r->intflags & PMf_SINGLELINE) { strcat(re->flags, "s"); }
- if (r->intflags & PMf_EXTENDED) { strcat(re->flags, "x"); }
- if (((r->extflags & RXf_PMf_KEEPCOPY) == RXf_PMf_KEEPCOPY)) {
- strcat(re->flags, "p");
- }
-
- /*
- * 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
- */
- SV * callback = get_H_callback("comp");
-
- if (callback) {
- ENTER;
- SAVETMPS;
-
- PUSHMARK(SP);
- XPUSHs(obj);
- XPUSHs(sv_2mortal(newSVpv(exp, xend - exp)));
-
- PUTBACK;
-
- call_sv(get_H_callback("comp"), G_DISCARD);
-
- FREETMPS;
- LEAVE;
- }
-
- /* If any of the comp-time accessors were called we'll have to
- * update the regexp struct with the new info.
- */
- if (re->minlen) r->minlen = re->minlen;
- if (re->gofs) r->gofs = re->gofs;
- if (re->gofs) r->gofs = re->gofs;
- if (re->nparens) r->nparens = re->nparens;
-
- int buffers = r->nparens;
-
- //r->nparens = (buffers - 1);
- Newxz(r->startp, buffers, I32);
- Newxz(r->endp, buffers, I32);
-
- /* return the regexp */
- return r;