5 #define SAVEPVN(p,n) ((p) ? savepvn(p,n) : NULL)
9 EXTERN_C const regexp_engine engine_plugin;
14 * Our struct which gets initiated and used as our object
15 * ($re). Since we can't count on the regexp structure provided by
16 * perl to be alive between comp/exec etc. we pull stuff from it and
17 * save it in our own structure.
19 * Besides, creating Perl accessors which directly muck with perl's
20 * own regexp structures in different phases of regex execution would
21 * be a little too evil.
23 typedef struct replug {
25 char flags[sizeof("ecgimsxp")];
33 AV * captures; /* Array of SV* that'll become $1, $2, ... */
34 } *re__engine__Plugin;
37 get_H_callback(const char* key)
48 XPUSHs(sv_2mortal(newSVpv(key, 0)));
51 call_pv("re::engine::Plugin::get_callback", G_SCALAR);
56 SvREFCNT_inc(callback);
58 if (!SvROK(callback)) { callback = NULL; }// croak("ret value not a ref"); }
67 /* just learn to use gdb you lazy bum! */
70 dump_r_info(const char* id, regexp *r)
73 warn("\textflags = %d", r->extflags);
74 warn("\tminlen = %d", r->minlen);
75 warn("\tminlenren = %d", r->minlenret);
76 warn("\tgofs = %d", r->gofs);
77 warn("\tnparens = %d", r->nparens);
78 warn("\tpprivate = %p", r->pprivate);
79 warn("\tsubbeg = %s", r->subbeg);
80 warn("\tsublen = %d", r->sublen);
81 warn("\tprecomp = %s", r->precomp);
82 warn("\tprelen = %d", r->prelen);
83 warn("\twrapped = %s", r->wrapped);
84 warn("\twraplen = %d", r->wraplen);
85 warn("\tseen_evals = %d", r->seen_evals);
86 warn("\trefcnt = %d", r->refcnt);
92 Plugin_comp(pTHX_ char *exp, char *xend, PMOP *pm)
99 * Allocate a new regexp struct, we must only write to the intflags,
100 * engine and private members and the others must be populated,
101 * internals expect the regex to have certain values least our code
107 /* Set up the regex to be handled by this plugin */
108 r->engine = &engine_plugin;
110 /* Store the initial flags */
111 r->intflags = pm->op_pmflags;
112 r->pprivate = NULL; /* this is set to our object below */
115 * Populate the regexp members for the engine
118 /* Ref count of the pattern */
121 /* Preserve a copy of the original pattern */
122 r->prelen = xend - exp;
123 r->precomp = SAVEPVN(exp, r->prelen);
125 /* these may be changed by accessors */
131 /* Store the flags as perl expects them */
132 r->extflags = pm->op_pmflags & RXf_PMf_COMPILETIME;
135 * Construct a new B<re::engine::Plugin> object that'll carry around
136 * our data inside C<< r->pprivate >>. The object is a blessed void*
137 * that points to our replug struct which holds any state we want to
140 re__engine__Plugin re;
141 Newz(0, re, 1, struct replug);
146 /* Bless into this package; TODO: make it subclassable */
147 const char * pkg = "re::engine::Plugin";
149 sv_setref_pv(obj, pkg, (void*)re);
151 /* Store our private object */
154 re->pattern = newSVpvn(SAVEPVN(exp, xend - exp), xend - exp);
155 SvREFCNT_inc(re->pattern);
157 /* Concat [ec]gimosxp (egimosxp & cgimosxp into) the flags string as
160 if (r->intflags & PMf_EVAL) { strcat(re->flags, "e"); }
161 if (r->intflags & PMf_CONTINUE) { strcat(re->flags, "c"); }
162 if (r->intflags & PMf_GLOBAL) { strcat(re->flags, "g"); }
163 if (r->intflags & PMf_FOLD) { strcat(re->flags, "i"); }
164 if (r->intflags & PMf_MULTILINE) { strcat(re->flags, "m"); }
165 if (r->intflags & PMf_ONCE) { strcat(re->flags, "o"); }
166 if (r->intflags & PMf_SINGLELINE) { strcat(re->flags, "s"); }
167 if (r->intflags & PMf_EXTENDED) { strcat(re->flags, "x"); }
168 if (((r->extflags & RXf_PMf_KEEPCOPY) == RXf_PMf_KEEPCOPY)) {
169 strcat(re->flags, "p");
173 * Call our callback function if one was defined, if not we've
174 * already set up all the stuff we're going to to need for
175 * subsequent exec and other calls
177 SV * callback = get_H_callback("comp");
185 XPUSHs(sv_2mortal(newSVpv(exp, xend - exp)));
189 call_sv(get_H_callback("comp"), G_DISCARD);
195 /* If any of the comp-time accessors were called we'll have to
196 * update the regexp struct with the new info.
198 if (re->minlen) r->minlen = re->minlen;
199 if (re->gofs) r->gofs = re->gofs;
200 if (re->gofs) r->gofs = re->gofs;
201 if (re->nparens) r->nparens = re->nparens;
203 int buffers = r->nparens;
205 //r->nparens = (buffers - 1);
206 Newxz(r->startp, buffers, I32);
207 Newxz(r->endp, buffers, I32);
209 /* return the regexp */
214 Plugin_exec(pTHX_ register regexp *r, char *stringarg, register char *strend,
215 char *strbeg, I32 minend, SV *sv, void *data, U32 flags)
224 /*Newx(ovector,r->nparens,int);*/
226 SV* callback = get_H_callback("exec");
238 count = call_sv(callback, G_ARRAY);
248 r->sublen = strend-strbeg;
249 r->subbeg = savepvn(strbeg,r->sublen);
267 Plugin_intuit(pTHX_ regexp *prog, SV *sv, char *strpos,
268 char *strend, U32 flags, re_scream_pos_data *data)
274 Plugin_checkstr(pTHX_ regexp *prog)
280 Plugin_free(pTHX_ struct regexp *r)
282 /*sv_2mortal(r->pprivate);*/
283 /*PerlMemShared_free(r->pprivate);*/
287 Plugin_dupe(pTHX_ const regexp *r, CLONE_PARAMS *param)
293 Plugin_numbered_buff_get(pTHX_ const REGEXP * const rx, I32 paren, SV* usesv)
299 Plugin_named_buff_get(pTHX_ const REGEXP * const rx, SV* namesv, U32 flags)
305 * The function pointers we're telling the regex engine to use
307 const regexp_engine engine_plugin = {
313 Plugin_numbered_buff_get,
314 Plugin_named_buff_get,
315 #if defined(USE_ITHREADS)
320 MODULE = re::engine::Plugin PACKAGE = re::engine::Plugin
323 pattern(re::engine::Plugin self, ...)
325 SvREFCNT_inc(self->pattern);
326 RETVAL = self->pattern;
331 flags(re::engine::Plugin self, ...)
333 RETVAL = self->flags;
338 stash(re::engine::Plugin self, ...)
343 self->stash = sv_mortalcopy(ST(1));
344 SvREFCNT_inc(self->stash);
346 SvREFCNT_inc(self->stash);
347 RETVAL = self->stash;
352 minlen(re::engine::Plugin self, ...)
355 self->minlen = (I32)SvIV(ST(1));
358 RETVAL = self->minlen ? newSViv(self->minlen) : &PL_sv_undef;
363 gofs(re::engine::Plugin self, ...)
366 self->gofs = (U32)SvIV(ST(1));
368 RETVAL = self->gofs ? newSVuv(self->gofs) : &PL_sv_undef;
373 nparens(re::engine::Plugin self, ...)
376 self->nparens = (U32)SvIV(ST(1));
378 RETVAL = self->gofs ? newSVuv(self->gofs) : &PL_sv_undef;
383 captures(re::engine::Plugin self, ...)
386 self->minlen = (I32)SvIV(ST(1));
388 XPUSHs(sv_2mortal(newSViv(5)));
389 XPUSHs(sv_2mortal(newSViv(10)));
394 XPUSHs(sv_2mortal(newSViv(PTR2IV(&engine_plugin))));