6c82ba746503f5129fdd8a3eff44d067e1261f10
[p5sagit/p5-mst-13.2.git] / regexec.c
1 /*    regexec.c
2  */
3
4 /*
5  * "One Ring to rule them all, One Ring to find them..."
6  */
7
8 /* This file contains functions for executing a regular expression.  See
9  * also regcomp.c which funnily enough, contains functions for compiling
10  * a regular expression.
11  *
12  * This file is also copied at build time to ext/re/re_exec.c, where
13  * it's built with -DPERL_EXT_RE_BUILD -DPERL_EXT_RE_DEBUG -DPERL_EXT.
14  * This causes the main functions to be compiled under new names and with
15  * debugging support added, which makes "use re 'debug'" work.
16  */
17
18 /* NOTE: this is derived from Henry Spencer's regexp code, and should not
19  * confused with the original package (see point 3 below).  Thanks, Henry!
20  */
21
22 /* Additional note: this code is very heavily munged from Henry's version
23  * in places.  In some spots I've traded clarity for efficiency, so don't
24  * blame Henry for some of the lack of readability.
25  */
26
27 /* The names of the functions have been changed from regcomp and
28  * regexec to  pregcomp and pregexec in order to avoid conflicts
29  * with the POSIX routines of the same names.
30 */
31
32 #ifdef PERL_EXT_RE_BUILD
33 #include "re_top.h"
34 #endif
35
36 /*
37  * pregcomp and pregexec -- regsub and regerror are not used in perl
38  *
39  *      Copyright (c) 1986 by University of Toronto.
40  *      Written by Henry Spencer.  Not derived from licensed software.
41  *
42  *      Permission is granted to anyone to use this software for any
43  *      purpose on any computer system, and to redistribute it freely,
44  *      subject to the following restrictions:
45  *
46  *      1. The author is not responsible for the consequences of use of
47  *              this software, no matter how awful, even if they arise
48  *              from defects in it.
49  *
50  *      2. The origin of this software must not be misrepresented, either
51  *              by explicit claim or by omission.
52  *
53  *      3. Altered versions must be plainly marked as such, and must not
54  *              be misrepresented as being the original software.
55  *
56  ****    Alterations to Henry's code are...
57  ****
58  ****    Copyright (C) 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
59  ****    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007 by Larry Wall and others
60  ****
61  ****    You may distribute under the terms of either the GNU General Public
62  ****    License or the Artistic License, as specified in the README file.
63  *
64  * Beware that some of this code is subtly aware of the way operator
65  * precedence is structured in regular expressions.  Serious changes in
66  * regular-expression syntax might require a total rethink.
67  */
68 #include "EXTERN.h"
69 #define PERL_IN_REGEXEC_C
70 #include "perl.h"
71
72 #ifdef PERL_IN_XSUB_RE
73 #  include "re_comp.h"
74 #else
75 #  include "regcomp.h"
76 #endif
77
78 #define RF_tainted      1               /* tainted information used? */
79 #define RF_warned       2               /* warned about big count? */
80
81 #define RF_utf8         8               /* Pattern contains multibyte chars? */
82
83 #define UTF ((PL_reg_flags & RF_utf8) != 0)
84
85 #define RS_init         1               /* eval environment created */
86 #define RS_set          2               /* replsv value is set */
87
88 #ifndef STATIC
89 #define STATIC  static
90 #endif
91
92 #define REGINCLASS(prog,p,c)  (ANYOF_FLAGS(p) ? reginclass(prog,p,c,0,0) : ANYOF_BITMAP_TEST(p,*(c)))
93
94 /*
95  * Forwards.
96  */
97
98 #define CHR_SVLEN(sv) (do_utf8 ? sv_len_utf8(sv) : SvCUR(sv))
99 #define CHR_DIST(a,b) (PL_reg_match_utf8 ? utf8_distance(a,b) : a - b)
100
101 #define HOPc(pos,off) \
102         (char *)(PL_reg_match_utf8 \
103             ? reghop3((U8*)pos, off, (U8*)(off >= 0 ? PL_regeol : PL_bostr)) \
104             : (U8*)(pos + off))
105 #define HOPBACKc(pos, off) \
106         (char*)(PL_reg_match_utf8\
107             ? reghopmaybe3((U8*)pos, -off, (U8*)PL_bostr) \
108             : (pos - off >= PL_bostr)           \
109                 ? (U8*)pos - off                \
110                 : NULL)
111
112 #define HOP3(pos,off,lim) (PL_reg_match_utf8 ? reghop3((U8*)(pos), off, (U8*)(lim)) : (U8*)(pos + off))
113 #define HOP3c(pos,off,lim) ((char*)HOP3(pos,off,lim))
114
115 #define LOAD_UTF8_CHARCLASS(class,str) STMT_START { \
116     if (!CAT2(PL_utf8_,class)) { bool ok; ENTER; save_re_context(); ok=CAT2(is_utf8_,class)((const U8*)str); assert(ok); LEAVE; } } STMT_END
117 #define LOAD_UTF8_CHARCLASS_ALNUM() LOAD_UTF8_CHARCLASS(alnum,"a")
118 #define LOAD_UTF8_CHARCLASS_DIGIT() LOAD_UTF8_CHARCLASS(digit,"0")
119 #define LOAD_UTF8_CHARCLASS_SPACE() LOAD_UTF8_CHARCLASS(space," ")
120 #define LOAD_UTF8_CHARCLASS_MARK()  LOAD_UTF8_CHARCLASS(mark, "\xcd\x86")
121
122 /* TODO: Combine JUMPABLE and HAS_TEXT to cache OP(rn) */
123
124 /* for use after a quantifier and before an EXACT-like node -- japhy */
125 #define JUMPABLE(rn) ( \
126     OP(rn) == OPEN || OP(rn) == CLOSE || OP(rn) == EVAL || \
127     OP(rn) == SUSPEND || OP(rn) == IFMATCH || \
128     OP(rn) == PLUS || OP(rn) == MINMOD || \
129     OP(rn) == KEEPS || (PL_regkind[OP(rn)] == VERB) || \
130     (PL_regkind[OP(rn)] == CURLY && ARG1(rn) > 0) \
131 )
132 #define IS_EXACT(rn) (PL_regkind[OP(rn)] == EXACT)
133
134 #define HAS_TEXT(rn) ( IS_EXACT(rn) || PL_regkind[OP(rn)] == REF )
135
136 #if 0 
137 /* Currently these are only used when PL_regkind[OP(rn)] == EXACT so
138    we don't need this definition. */
139 #define IS_TEXT(rn)   ( OP(rn)==EXACT   || OP(rn)==REF   || OP(rn)==NREF   )
140 #define IS_TEXTF(rn)  ( OP(rn)==EXACTF  || OP(rn)==REFF  || OP(rn)==NREFF  )
141 #define IS_TEXTFL(rn) ( OP(rn)==EXACTFL || OP(rn)==REFFL || OP(rn)==NREFFL )
142
143 #else
144 /* ... so we use this as its faster. */
145 #define IS_TEXT(rn)   ( OP(rn)==EXACT   )
146 #define IS_TEXTF(rn)  ( OP(rn)==EXACTF  )
147 #define IS_TEXTFL(rn) ( OP(rn)==EXACTFL )
148
149 #endif
150
151 /*
152   Search for mandatory following text node; for lookahead, the text must
153   follow but for lookbehind (rn->flags != 0) we skip to the next step.
154 */
155 #define FIND_NEXT_IMPT(rn) STMT_START { \
156     while (JUMPABLE(rn)) { \
157         const OPCODE type = OP(rn); \
158         if (type == SUSPEND || PL_regkind[type] == CURLY) \
159             rn = NEXTOPER(NEXTOPER(rn)); \
160         else if (type == PLUS) \
161             rn = NEXTOPER(rn); \
162         else if (type == IFMATCH) \
163             rn = (rn->flags == 0) ? NEXTOPER(NEXTOPER(rn)) : rn + ARG(rn); \
164         else rn += NEXT_OFF(rn); \
165     } \
166 } STMT_END 
167
168
169 static void restore_pos(pTHX_ void *arg);
170
171 STATIC CHECKPOINT
172 S_regcppush(pTHX_ I32 parenfloor)
173 {
174     dVAR;
175     const int retval = PL_savestack_ix;
176 #define REGCP_PAREN_ELEMS 4
177     const int paren_elems_to_push = (PL_regsize - parenfloor) * REGCP_PAREN_ELEMS;
178     int p;
179     GET_RE_DEBUG_FLAGS_DECL;
180
181     if (paren_elems_to_push < 0)
182         Perl_croak(aTHX_ "panic: paren_elems_to_push < 0");
183
184 #define REGCP_OTHER_ELEMS 8
185     SSGROW(paren_elems_to_push + REGCP_OTHER_ELEMS);
186     
187     for (p = PL_regsize; p > parenfloor; p--) {
188 /* REGCP_PARENS_ELEMS are pushed per pairs of parentheses. */
189         SSPUSHINT(PL_regendp[p]);
190         SSPUSHINT(PL_regstartp[p]);
191         SSPUSHPTR(PL_reg_start_tmp[p]);
192         SSPUSHINT(p);
193         DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
194           "     saving \\%"UVuf" %"IVdf"(%"IVdf")..%"IVdf"\n",
195                       (UV)p, (IV)PL_regstartp[p],
196                       (IV)(PL_reg_start_tmp[p] - PL_bostr),
197                       (IV)PL_regendp[p]
198         ));
199     }
200 /* REGCP_OTHER_ELEMS are pushed in any case, parentheses or no. */
201     SSPUSHPTR(PL_regstartp);
202     SSPUSHPTR(PL_regendp);
203     SSPUSHINT(PL_regsize);
204     SSPUSHINT(*PL_reglastparen);
205     SSPUSHINT(*PL_reglastcloseparen);
206     SSPUSHPTR(PL_reginput);
207 #define REGCP_FRAME_ELEMS 2
208 /* REGCP_FRAME_ELEMS are part of the REGCP_OTHER_ELEMS and
209  * are needed for the regexp context stack bookkeeping. */
210     SSPUSHINT(paren_elems_to_push + REGCP_OTHER_ELEMS - REGCP_FRAME_ELEMS);
211     SSPUSHINT(SAVEt_REGCONTEXT); /* Magic cookie. */
212
213     return retval;
214 }
215
216 /* These are needed since we do not localize EVAL nodes: */
217 #define REGCP_SET(cp)                                           \
218     DEBUG_STATE_r(                                              \
219             PerlIO_printf(Perl_debug_log,                       \
220                 "  Setting an EVAL scope, savestack=%"IVdf"\n", \
221                 (IV)PL_savestack_ix));                          \
222     cp = PL_savestack_ix
223
224 #define REGCP_UNWIND(cp)                                        \
225     DEBUG_STATE_r(                                              \
226         if (cp != PL_savestack_ix)                              \
227             PerlIO_printf(Perl_debug_log,                       \
228                 "  Clearing an EVAL scope, savestack=%"IVdf"..%"IVdf"\n", \
229                 (IV)(cp), (IV)PL_savestack_ix));                \
230     regcpblow(cp)
231
232 STATIC char *
233 S_regcppop(pTHX_ const regexp *rex)
234 {
235     dVAR;
236     U32 i;
237     char *input;
238
239     GET_RE_DEBUG_FLAGS_DECL;
240
241     /* Pop REGCP_OTHER_ELEMS before the parentheses loop starts. */
242     i = SSPOPINT;
243     assert(i == SAVEt_REGCONTEXT); /* Check that the magic cookie is there. */
244     i = SSPOPINT; /* Parentheses elements to pop. */
245     input = (char *) SSPOPPTR;
246     *PL_reglastcloseparen = SSPOPINT;
247     *PL_reglastparen = SSPOPINT;
248     PL_regsize = SSPOPINT;
249     PL_regendp=(I32 *) SSPOPPTR;
250     PL_regstartp=(I32 *) SSPOPPTR;
251
252     
253     /* Now restore the parentheses context. */
254     for (i -= (REGCP_OTHER_ELEMS - REGCP_FRAME_ELEMS);
255          i > 0; i -= REGCP_PAREN_ELEMS) {
256         I32 tmps;
257         U32 paren = (U32)SSPOPINT;
258         PL_reg_start_tmp[paren] = (char *) SSPOPPTR;
259         PL_regstartp[paren] = SSPOPINT;
260         tmps = SSPOPINT;
261         if (paren <= *PL_reglastparen)
262             PL_regendp[paren] = tmps;
263         DEBUG_EXECUTE_r(
264             PerlIO_printf(Perl_debug_log,
265                           "     restoring \\%"UVuf" to %"IVdf"(%"IVdf")..%"IVdf"%s\n",
266                           (UV)paren, (IV)PL_regstartp[paren],
267                           (IV)(PL_reg_start_tmp[paren] - PL_bostr),
268                           (IV)PL_regendp[paren],
269                           (paren > *PL_reglastparen ? "(no)" : ""));
270         );
271     }
272     DEBUG_EXECUTE_r(
273         if (*PL_reglastparen + 1 <= rex->nparens) {
274             PerlIO_printf(Perl_debug_log,
275                           "     restoring \\%"IVdf"..\\%"IVdf" to undef\n",
276                           (IV)(*PL_reglastparen + 1), (IV)rex->nparens);
277         }
278     );
279 #if 1
280     /* It would seem that the similar code in regtry()
281      * already takes care of this, and in fact it is in
282      * a better location to since this code can #if 0-ed out
283      * but the code in regtry() is needed or otherwise tests
284      * requiring null fields (pat.t#187 and split.t#{13,14}
285      * (as of patchlevel 7877)  will fail.  Then again,
286      * this code seems to be necessary or otherwise
287      * building DynaLoader will fail:
288      * "Error: '*' not in typemap in DynaLoader.xs, line 164"
289      * --jhi */
290     for (i = *PL_reglastparen + 1; i <= rex->nparens; i++) {
291         if (i > PL_regsize)
292             PL_regstartp[i] = -1;
293         PL_regendp[i] = -1;
294     }
295 #endif
296     return input;
297 }
298
299 #define regcpblow(cp) LEAVE_SCOPE(cp)   /* Ignores regcppush()ed data. */
300
301 /*
302  * pregexec and friends
303  */
304
305 #ifndef PERL_IN_XSUB_RE
306 /*
307  - pregexec - match a regexp against a string
308  */
309 I32
310 Perl_pregexec(pTHX_ register regexp *prog, char *stringarg, register char *strend,
311          char *strbeg, I32 minend, SV *screamer, U32 nosave)
312 /* strend: pointer to null at end of string */
313 /* strbeg: real beginning of string */
314 /* minend: end of match must be >=minend after stringarg. */
315 /* nosave: For optimizations. */
316 {
317     return
318         regexec_flags(prog, stringarg, strend, strbeg, minend, screamer, NULL,
319                       nosave ? 0 : REXEC_COPY_STR);
320 }
321 #endif
322
323 /*
324  * Need to implement the following flags for reg_anch:
325  *
326  * USE_INTUIT_NOML              - Useful to call re_intuit_start() first
327  * USE_INTUIT_ML
328  * INTUIT_AUTORITATIVE_NOML     - Can trust a positive answer
329  * INTUIT_AUTORITATIVE_ML
330  * INTUIT_ONCE_NOML             - Intuit can match in one location only.
331  * INTUIT_ONCE_ML
332  *
333  * Another flag for this function: SECOND_TIME (so that float substrs
334  * with giant delta may be not rechecked).
335  */
336
337 /* Assumptions: if ANCH_GPOS, then strpos is anchored. XXXX Check GPOS logic */
338
339 /* If SCREAM, then SvPVX_const(sv) should be compatible with strpos and strend.
340    Otherwise, only SvCUR(sv) is used to get strbeg. */
341
342 /* XXXX We assume that strpos is strbeg unless sv. */
343
344 /* XXXX Some places assume that there is a fixed substring.
345         An update may be needed if optimizer marks as "INTUITable"
346         RExen without fixed substrings.  Similarly, it is assumed that
347         lengths of all the strings are no more than minlen, thus they
348         cannot come from lookahead.
349         (Or minlen should take into account lookahead.) 
350   NOTE: Some of this comment is not correct. minlen does now take account
351   of lookahead/behind. Further research is required. -- demerphq
352
353 */
354
355 /* A failure to find a constant substring means that there is no need to make
356    an expensive call to REx engine, thus we celebrate a failure.  Similarly,
357    finding a substring too deep into the string means that less calls to
358    regtry() should be needed.
359
360    REx compiler's optimizer found 4 possible hints:
361         a) Anchored substring;
362         b) Fixed substring;
363         c) Whether we are anchored (beginning-of-line or \G);
364         d) First node (of those at offset 0) which may distingush positions;
365    We use a)b)d) and multiline-part of c), and try to find a position in the
366    string which does not contradict any of them.
367  */
368
369 /* Most of decisions we do here should have been done at compile time.
370    The nodes of the REx which we used for the search should have been
371    deleted from the finite automaton. */
372
373 char *
374 Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos,
375                      char *strend, U32 flags, re_scream_pos_data *data)
376 {
377     dVAR;
378     register I32 start_shift = 0;
379     /* Should be nonnegative! */
380     register I32 end_shift   = 0;
381     register char *s;
382     register SV *check;
383     char *strbeg;
384     char *t;
385     const bool do_utf8 = (sv && SvUTF8(sv)) ? 1 : 0; /* if no sv we have to assume bytes */
386     I32 ml_anch;
387     register char *other_last = NULL;   /* other substr checked before this */
388     char *check_at = NULL;              /* check substr found at this pos */
389     const I32 multiline = prog->extflags & RXf_PMf_MULTILINE;
390     RXi_GET_DECL(prog,progi);
391 #ifdef DEBUGGING
392     const char * const i_strpos = strpos;
393 #endif
394
395     GET_RE_DEBUG_FLAGS_DECL;
396
397     RX_MATCH_UTF8_set(prog,do_utf8);
398
399     if (prog->extflags & RXf_UTF8) {
400         PL_reg_flags |= RF_utf8;
401     }
402     DEBUG_EXECUTE_r( 
403         debug_start_match(prog, do_utf8, strpos, strend, 
404             sv ? "Guessing start of match in sv for"
405                : "Guessing start of match in string for");
406               );
407
408     /* CHR_DIST() would be more correct here but it makes things slow. */
409     if (prog->minlen > strend - strpos) {
410         DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
411                               "String too short... [re_intuit_start]\n"));
412         goto fail;
413     }
414                 
415     strbeg = (sv && SvPOK(sv)) ? strend - SvCUR(sv) : strpos;
416     PL_regeol = strend;
417     if (do_utf8) {
418         if (!prog->check_utf8 && prog->check_substr)
419             to_utf8_substr(prog);
420         check = prog->check_utf8;
421     } else {
422         if (!prog->check_substr && prog->check_utf8)
423             to_byte_substr(prog);
424         check = prog->check_substr;
425     }
426     if (check == &PL_sv_undef) {
427         DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
428                 "Non-utf8 string cannot match utf8 check string\n"));
429         goto fail;
430     }
431     if (prog->extflags & RXf_ANCH) {    /* Match at beg-of-str or after \n */
432         ml_anch = !( (prog->extflags & RXf_ANCH_SINGLE)
433                      || ( (prog->extflags & RXf_ANCH_BOL)
434                           && !multiline ) );    /* Check after \n? */
435
436         if (!ml_anch) {
437           if ( !(prog->extflags & RXf_ANCH_GPOS) /* Checked by the caller */
438                 && !(prog->intflags & PREGf_IMPLICIT) /* not a real BOL */
439                /* SvCUR is not set on references: SvRV and SvPVX_const overlap */
440                && sv && !SvROK(sv)
441                && (strpos != strbeg)) {
442               DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "Not at start...\n"));
443               goto fail;
444           }
445           if (prog->check_offset_min == prog->check_offset_max &&
446               !(prog->extflags & RXf_CANY_SEEN)) {
447             /* Substring at constant offset from beg-of-str... */
448             I32 slen;
449
450             s = HOP3c(strpos, prog->check_offset_min, strend);
451             
452             if (SvTAIL(check)) {
453                 slen = SvCUR(check);    /* >= 1 */
454
455                 if ( strend - s > slen || strend - s < slen - 1
456                      || (strend - s == slen && strend[-1] != '\n')) {
457                     DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "String too long...\n"));
458                     goto fail_finish;
459                 }
460                 /* Now should match s[0..slen-2] */
461                 slen--;
462                 if (slen && (*SvPVX_const(check) != *s
463                              || (slen > 1
464                                  && memNE(SvPVX_const(check), s, slen)))) {
465                   report_neq:
466                     DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "String not equal...\n"));
467                     goto fail_finish;
468                 }
469             }
470             else if (*SvPVX_const(check) != *s
471                      || ((slen = SvCUR(check)) > 1
472                          && memNE(SvPVX_const(check), s, slen)))
473                 goto report_neq;
474             check_at = s;
475             goto success_at_start;
476           }
477         }
478         /* Match is anchored, but substr is not anchored wrt beg-of-str. */
479         s = strpos;
480         start_shift = prog->check_offset_min; /* okay to underestimate on CC */
481         end_shift = prog->check_end_shift;
482         
483         if (!ml_anch) {
484             const I32 end = prog->check_offset_max + CHR_SVLEN(check)
485                                          - (SvTAIL(check) != 0);
486             const I32 eshift = CHR_DIST((U8*)strend, (U8*)s) - end;
487
488             if (end_shift < eshift)
489                 end_shift = eshift;
490         }
491     }
492     else {                              /* Can match at random position */
493         ml_anch = 0;
494         s = strpos;
495         start_shift = prog->check_offset_min;  /* okay to underestimate on CC */
496         end_shift = prog->check_end_shift;
497         
498         /* end shift should be non negative here */
499     }
500
501 #ifdef QDEBUGGING       /* 7/99: reports of failure (with the older version) */
502     if (end_shift < 0)
503         Perl_croak(aTHX_ "panic: end_shift: %"IVdf" pattern:\n%s\n ",
504                    (IV)end_shift, prog->precomp);
505 #endif
506
507   restart:
508     /* Find a possible match in the region s..strend by looking for
509        the "check" substring in the region corrected by start/end_shift. */
510     
511     {
512         I32 srch_start_shift = start_shift;
513         I32 srch_end_shift = end_shift;
514         if (srch_start_shift < 0 && strbeg - s > srch_start_shift) {
515             srch_end_shift -= ((strbeg - s) - srch_start_shift); 
516             srch_start_shift = strbeg - s;
517         }
518     DEBUG_OPTIMISE_MORE_r({
519         PerlIO_printf(Perl_debug_log, "Check offset min: %"IVdf" Start shift: %"IVdf" End shift %"IVdf" Real End Shift: %"IVdf"\n",
520             (IV)prog->check_offset_min,
521             (IV)srch_start_shift,
522             (IV)srch_end_shift, 
523             (IV)prog->check_end_shift);
524     });       
525         
526     if (flags & REXEC_SCREAM) {
527         I32 p = -1;                     /* Internal iterator of scream. */
528         I32 * const pp = data ? data->scream_pos : &p;
529
530         if (PL_screamfirst[BmRARE(check)] >= 0
531             || ( BmRARE(check) == '\n'
532                  && (BmPREVIOUS(check) == SvCUR(check) - 1)
533                  && SvTAIL(check) ))
534             s = screaminstr(sv, check,
535                             srch_start_shift + (s - strbeg), srch_end_shift, pp, 0);
536         else
537             goto fail_finish;
538         /* we may be pointing at the wrong string */
539         if (s && RX_MATCH_COPIED(prog))
540             s = strbeg + (s - SvPVX_const(sv));
541         if (data)
542             *data->scream_olds = s;
543     }
544     else {
545         U8* start_point;
546         U8* end_point;
547         if (prog->extflags & RXf_CANY_SEEN) {
548             start_point= (U8*)(s + srch_start_shift);
549             end_point= (U8*)(strend - srch_end_shift);
550         } else {
551             start_point= HOP3(s, srch_start_shift, srch_start_shift < 0 ? strbeg : strend);
552             end_point= HOP3(strend, -srch_end_shift, strbeg);
553         }
554         DEBUG_OPTIMISE_MORE_r({
555             PerlIO_printf(Perl_debug_log, "fbm_instr len=%d str=<%.*s>\n", 
556                 (int)(end_point - start_point),
557                 (int)(end_point - start_point) > 20 ? 20 : (int)(end_point - start_point), 
558                 start_point);
559         });
560
561         s = fbm_instr( start_point, end_point,
562                       check, multiline ? FBMrf_MULTILINE : 0);
563     }
564     }
565     /* Update the count-of-usability, remove useless subpatterns,
566         unshift s.  */
567
568     DEBUG_EXECUTE_r({
569         RE_PV_QUOTED_DECL(quoted, do_utf8, PERL_DEBUG_PAD_ZERO(0), 
570             SvPVX_const(check), RE_SV_DUMPLEN(check), 30);
571         PerlIO_printf(Perl_debug_log, "%s %s substr %s%s%s",
572                           (s ? "Found" : "Did not find"),
573             (check == (do_utf8 ? prog->anchored_utf8 : prog->anchored_substr) 
574                 ? "anchored" : "floating"),
575             quoted,
576             RE_SV_TAIL(check),
577             (s ? " at offset " : "...\n") ); 
578     });
579
580     if (!s)
581         goto fail_finish;
582     /* Finish the diagnostic message */
583     DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "%ld...\n", (long)(s - i_strpos)) );
584
585     /* XXX dmq: first branch is for positive lookbehind...
586        Our check string is offset from the beginning of the pattern.
587        So we need to do any stclass tests offset forward from that 
588        point. I think. :-(
589      */
590     
591         
592     
593     check_at=s;
594      
595
596     /* Got a candidate.  Check MBOL anchoring, and the *other* substr.
597        Start with the other substr.
598        XXXX no SCREAM optimization yet - and a very coarse implementation
599        XXXX /ttx+/ results in anchored="ttx", floating="x".  floating will
600                 *always* match.  Probably should be marked during compile...
601        Probably it is right to do no SCREAM here...
602      */
603
604     if (do_utf8 ? (prog->float_utf8 && prog->anchored_utf8) 
605                 : (prog->float_substr && prog->anchored_substr)) 
606     {
607         /* Take into account the "other" substring. */
608         /* XXXX May be hopelessly wrong for UTF... */
609         if (!other_last)
610             other_last = strpos;
611         if (check == (do_utf8 ? prog->float_utf8 : prog->float_substr)) {
612           do_other_anchored:
613             {
614                 char * const last = HOP3c(s, -start_shift, strbeg);
615                 char *last1, *last2;
616                 char * const saved_s = s;
617                 SV* must;
618
619                 t = s - prog->check_offset_max;
620                 if (s - strpos > prog->check_offset_max  /* signed-corrected t > strpos */
621                     && (!do_utf8
622                         || ((t = (char*)reghopmaybe3((U8*)s, -(prog->check_offset_max), (U8*)strpos))
623                             && t > strpos)))
624                     NOOP;
625                 else
626                     t = strpos;
627                 t = HOP3c(t, prog->anchored_offset, strend);
628                 if (t < other_last)     /* These positions already checked */
629                     t = other_last;
630                 last2 = last1 = HOP3c(strend, -prog->minlen, strbeg);
631                 if (last < last1)
632                     last1 = last;
633                 /* XXXX It is not documented what units *_offsets are in.  
634                    We assume bytes, but this is clearly wrong. 
635                    Meaning this code needs to be carefully reviewed for errors.
636                    dmq.
637                   */
638  
639                 /* On end-of-str: see comment below. */
640                 must = do_utf8 ? prog->anchored_utf8 : prog->anchored_substr;
641                 if (must == &PL_sv_undef) {
642                     s = (char*)NULL;
643                     DEBUG_r(must = prog->anchored_utf8);        /* for debug */
644                 }
645                 else
646                     s = fbm_instr(
647                         (unsigned char*)t,
648                         HOP3(HOP3(last1, prog->anchored_offset, strend)
649                                 + SvCUR(must), -(SvTAIL(must)!=0), strbeg),
650                         must,
651                         multiline ? FBMrf_MULTILINE : 0
652                     );
653                 DEBUG_EXECUTE_r({
654                     RE_PV_QUOTED_DECL(quoted, do_utf8, PERL_DEBUG_PAD_ZERO(0), 
655                         SvPVX_const(must), RE_SV_DUMPLEN(must), 30);
656                     PerlIO_printf(Perl_debug_log, "%s anchored substr %s%s",
657                         (s ? "Found" : "Contradicts"),
658                         quoted, RE_SV_TAIL(must));
659                 });                 
660                 
661                             
662                 if (!s) {
663                     if (last1 >= last2) {
664                         DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
665                                                 ", giving up...\n"));
666                         goto fail_finish;
667                     }
668                     DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
669                         ", trying floating at offset %ld...\n",
670                         (long)(HOP3c(saved_s, 1, strend) - i_strpos)));
671                     other_last = HOP3c(last1, prog->anchored_offset+1, strend);
672                     s = HOP3c(last, 1, strend);
673                     goto restart;
674                 }
675                 else {
676                     DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, " at offset %ld...\n",
677                           (long)(s - i_strpos)));
678                     t = HOP3c(s, -prog->anchored_offset, strbeg);
679                     other_last = HOP3c(s, 1, strend);
680                     s = saved_s;
681                     if (t == strpos)
682                         goto try_at_start;
683                     goto try_at_offset;
684                 }
685             }
686         }
687         else {          /* Take into account the floating substring. */
688             char *last, *last1;
689             char * const saved_s = s;
690             SV* must;
691
692             t = HOP3c(s, -start_shift, strbeg);
693             last1 = last =
694                 HOP3c(strend, -prog->minlen + prog->float_min_offset, strbeg);
695             if (CHR_DIST((U8*)last, (U8*)t) > prog->float_max_offset)
696                 last = HOP3c(t, prog->float_max_offset, strend);
697             s = HOP3c(t, prog->float_min_offset, strend);
698             if (s < other_last)
699                 s = other_last;
700  /* XXXX It is not documented what units *_offsets are in.  Assume bytes.  */
701             must = do_utf8 ? prog->float_utf8 : prog->float_substr;
702             /* fbm_instr() takes into account exact value of end-of-str
703                if the check is SvTAIL(ed).  Since false positives are OK,
704                and end-of-str is not later than strend we are OK. */
705             if (must == &PL_sv_undef) {
706                 s = (char*)NULL;
707                 DEBUG_r(must = prog->float_utf8);       /* for debug message */
708             }
709             else
710                 s = fbm_instr((unsigned char*)s,
711                               (unsigned char*)last + SvCUR(must)
712                                   - (SvTAIL(must)!=0),
713                               must, multiline ? FBMrf_MULTILINE : 0);
714             DEBUG_EXECUTE_r({
715                 RE_PV_QUOTED_DECL(quoted, do_utf8, PERL_DEBUG_PAD_ZERO(0), 
716                     SvPVX_const(must), RE_SV_DUMPLEN(must), 30);
717                 PerlIO_printf(Perl_debug_log, "%s floating substr %s%s",
718                     (s ? "Found" : "Contradicts"),
719                     quoted, RE_SV_TAIL(must));
720             });
721             if (!s) {
722                 if (last1 == last) {
723                     DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
724                                             ", giving up...\n"));
725                     goto fail_finish;
726                 }
727                 DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
728                     ", trying anchored starting at offset %ld...\n",
729                     (long)(saved_s + 1 - i_strpos)));
730                 other_last = last;
731                 s = HOP3c(t, 1, strend);
732                 goto restart;
733             }
734             else {
735                 DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, " at offset %ld...\n",
736                       (long)(s - i_strpos)));
737                 other_last = s; /* Fix this later. --Hugo */
738                 s = saved_s;
739                 if (t == strpos)
740                     goto try_at_start;
741                 goto try_at_offset;
742             }
743         }
744     }
745
746     
747     t= (char*)HOP3( s, -prog->check_offset_max, (prog->check_offset_max<0) ? strend : strpos);
748         
749     DEBUG_OPTIMISE_MORE_r(
750         PerlIO_printf(Perl_debug_log, 
751             "Check offset min:%"IVdf" max:%"IVdf" S:%"IVdf" t:%"IVdf" D:%"IVdf" end:%"IVdf"\n",
752             (IV)prog->check_offset_min,
753             (IV)prog->check_offset_max,
754             (IV)(s-strpos),
755             (IV)(t-strpos),
756             (IV)(t-s),
757             (IV)(strend-strpos)
758         )
759     );
760
761     if (s - strpos > prog->check_offset_max  /* signed-corrected t > strpos */
762         && (!do_utf8
763             || ((t = (char*)reghopmaybe3((U8*)s, -prog->check_offset_max, (U8*) ((prog->check_offset_max<0) ? strend : strpos)))
764                  && t > strpos))) 
765     {
766         /* Fixed substring is found far enough so that the match
767            cannot start at strpos. */
768       try_at_offset:
769         if (ml_anch && t[-1] != '\n') {
770             /* Eventually fbm_*() should handle this, but often
771                anchored_offset is not 0, so this check will not be wasted. */
772             /* XXXX In the code below we prefer to look for "^" even in
773                presence of anchored substrings.  And we search even
774                beyond the found float position.  These pessimizations
775                are historical artefacts only.  */
776           find_anchor:
777             while (t < strend - prog->minlen) {
778                 if (*t == '\n') {
779                     if (t < check_at - prog->check_offset_min) {
780                         if (do_utf8 ? prog->anchored_utf8 : prog->anchored_substr) {
781                             /* Since we moved from the found position,
782                                we definitely contradict the found anchored
783                                substr.  Due to the above check we do not
784                                contradict "check" substr.
785                                Thus we can arrive here only if check substr
786                                is float.  Redo checking for "other"=="fixed".
787                              */
788                             strpos = t + 1;                     
789                             DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "Found /%s^%s/m at offset %ld, rescanning for anchored from offset %ld...\n",
790                                 PL_colors[0], PL_colors[1], (long)(strpos - i_strpos), (long)(strpos - i_strpos + prog->anchored_offset)));
791                             goto do_other_anchored;
792                         }
793                         /* We don't contradict the found floating substring. */
794                         /* XXXX Why not check for STCLASS? */
795                         s = t + 1;
796                         DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "Found /%s^%s/m at offset %ld...\n",
797                             PL_colors[0], PL_colors[1], (long)(s - i_strpos)));
798                         goto set_useful;
799                     }
800                     /* Position contradicts check-string */
801                     /* XXXX probably better to look for check-string
802                        than for "\n", so one should lower the limit for t? */
803                     DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "Found /%s^%s/m, restarting lookup for check-string at offset %ld...\n",
804                         PL_colors[0], PL_colors[1], (long)(t + 1 - i_strpos)));
805                     other_last = strpos = s = t + 1;
806                     goto restart;
807                 }
808                 t++;
809             }
810             DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "Did not find /%s^%s/m...\n",
811                         PL_colors[0], PL_colors[1]));
812             goto fail_finish;
813         }
814         else {
815             DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "Starting position does not contradict /%s^%s/m...\n",
816                         PL_colors[0], PL_colors[1]));
817         }
818         s = t;
819       set_useful:
820         ++BmUSEFUL(do_utf8 ? prog->check_utf8 : prog->check_substr);    /* hooray/5 */
821     }
822     else {
823         /* The found string does not prohibit matching at strpos,
824            - no optimization of calling REx engine can be performed,
825            unless it was an MBOL and we are not after MBOL,
826            or a future STCLASS check will fail this. */
827       try_at_start:
828         /* Even in this situation we may use MBOL flag if strpos is offset
829            wrt the start of the string. */
830         if (ml_anch && sv && !SvROK(sv) /* See prev comment on SvROK */
831             && (strpos != strbeg) && strpos[-1] != '\n'
832             /* May be due to an implicit anchor of m{.*foo}  */
833             && !(prog->intflags & PREGf_IMPLICIT))
834         {
835             t = strpos;
836             goto find_anchor;
837         }
838         DEBUG_EXECUTE_r( if (ml_anch)
839             PerlIO_printf(Perl_debug_log, "Position at offset %ld does not contradict /%s^%s/m...\n",
840                           (long)(strpos - i_strpos), PL_colors[0], PL_colors[1]);
841         );
842       success_at_start:
843         if (!(prog->intflags & PREGf_NAUGHTY)   /* XXXX If strpos moved? */
844             && (do_utf8 ? (
845                 prog->check_utf8                /* Could be deleted already */
846                 && --BmUSEFUL(prog->check_utf8) < 0
847                 && (prog->check_utf8 == prog->float_utf8)
848             ) : (
849                 prog->check_substr              /* Could be deleted already */
850                 && --BmUSEFUL(prog->check_substr) < 0
851                 && (prog->check_substr == prog->float_substr)
852             )))
853         {
854             /* If flags & SOMETHING - do not do it many times on the same match */
855             DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "... Disabling check substring...\n"));
856             SvREFCNT_dec(do_utf8 ? prog->check_utf8 : prog->check_substr);
857             if (do_utf8 ? prog->check_substr : prog->check_utf8)
858                 SvREFCNT_dec(do_utf8 ? prog->check_substr : prog->check_utf8);
859             prog->check_substr = prog->check_utf8 = NULL;       /* disable */
860             prog->float_substr = prog->float_utf8 = NULL;       /* clear */
861             check = NULL;                       /* abort */
862             s = strpos;
863             /* XXXX This is a remnant of the old implementation.  It
864                     looks wasteful, since now INTUIT can use many
865                     other heuristics. */
866             prog->extflags &= ~RXf_USE_INTUIT;
867         }
868         else
869             s = strpos;
870     }
871
872     /* Last resort... */
873     /* XXXX BmUSEFUL already changed, maybe multiple change is meaningful... */
874     /* trie stclasses are too expensive to use here, we are better off to
875        leave it to regmatch itself */
876     if (progi->regstclass && PL_regkind[OP(progi->regstclass)]!=TRIE) {
877         /* minlen == 0 is possible if regstclass is \b or \B,
878            and the fixed substr is ''$.
879            Since minlen is already taken into account, s+1 is before strend;
880            accidentally, minlen >= 1 guaranties no false positives at s + 1
881            even for \b or \B.  But (minlen? 1 : 0) below assumes that
882            regstclass does not come from lookahead...  */
883         /* If regstclass takes bytelength more than 1: If charlength==1, OK.
884            This leaves EXACTF only, which is dealt with in find_byclass().  */
885         const U8* const str = (U8*)STRING(progi->regstclass);
886         const int cl_l = (PL_regkind[OP(progi->regstclass)] == EXACT
887                     ? CHR_DIST(str+STR_LEN(progi->regstclass), str)
888                     : 1);
889         char * endpos;
890         if (prog->anchored_substr || prog->anchored_utf8 || ml_anch)
891             endpos= HOP3c(s, (prog->minlen ? cl_l : 0), strend);
892         else if (prog->float_substr || prog->float_utf8)
893             endpos= HOP3c(HOP3c(check_at, -start_shift, strbeg), cl_l, strend);
894         else 
895             endpos= strend;
896                     
897         DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "start_shift: %"IVdf" check_at: %"IVdf" s: %"IVdf" endpos: %"IVdf"\n",
898                                       (IV)start_shift, (IV)(check_at - strbeg), (IV)(s - strbeg), (IV)(endpos - strbeg)));
899         
900         t = s;
901         s = find_byclass(prog, progi->regstclass, s, endpos, NULL);
902         if (!s) {
903 #ifdef DEBUGGING
904             const char *what = NULL;
905 #endif
906             if (endpos == strend) {
907                 DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
908                                 "Could not match STCLASS...\n") );
909                 goto fail;
910             }
911             DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
912                                    "This position contradicts STCLASS...\n") );
913             if ((prog->extflags & RXf_ANCH) && !ml_anch)
914                 goto fail;
915             /* Contradict one of substrings */
916             if (prog->anchored_substr || prog->anchored_utf8) {
917                 if ((do_utf8 ? prog->anchored_utf8 : prog->anchored_substr) == check) {
918                     DEBUG_EXECUTE_r( what = "anchored" );
919                   hop_and_restart:
920                     s = HOP3c(t, 1, strend);
921                     if (s + start_shift + end_shift > strend) {
922                         /* XXXX Should be taken into account earlier? */
923                         DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
924                                                "Could not match STCLASS...\n") );
925                         goto fail;
926                     }
927                     if (!check)
928                         goto giveup;
929                     DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
930                                 "Looking for %s substr starting at offset %ld...\n",
931                                  what, (long)(s + start_shift - i_strpos)) );
932                     goto restart;
933                 }
934                 /* Have both, check_string is floating */
935                 if (t + start_shift >= check_at) /* Contradicts floating=check */
936                     goto retry_floating_check;
937                 /* Recheck anchored substring, but not floating... */
938                 s = check_at;
939                 if (!check)
940                     goto giveup;
941                 DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
942                           "Looking for anchored substr starting at offset %ld...\n",
943                           (long)(other_last - i_strpos)) );
944                 goto do_other_anchored;
945             }
946             /* Another way we could have checked stclass at the
947                current position only: */
948             if (ml_anch) {
949                 s = t = t + 1;
950                 if (!check)
951                     goto giveup;
952                 DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
953                           "Looking for /%s^%s/m starting at offset %ld...\n",
954                           PL_colors[0], PL_colors[1], (long)(t - i_strpos)) );
955                 goto try_at_offset;
956             }
957             if (!(do_utf8 ? prog->float_utf8 : prog->float_substr))     /* Could have been deleted */
958                 goto fail;
959             /* Check is floating subtring. */
960           retry_floating_check:
961             t = check_at - start_shift;
962             DEBUG_EXECUTE_r( what = "floating" );
963             goto hop_and_restart;
964         }
965         if (t != s) {
966             DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
967                         "By STCLASS: moving %ld --> %ld\n",
968                                   (long)(t - i_strpos), (long)(s - i_strpos))
969                    );
970         }
971         else {
972             DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
973                                   "Does not contradict STCLASS...\n"); 
974                    );
975         }
976     }
977   giveup:
978     DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "%s%s:%s match at offset %ld\n",
979                           PL_colors[4], (check ? "Guessed" : "Giving up"),
980                           PL_colors[5], (long)(s - i_strpos)) );
981     return s;
982
983   fail_finish:                          /* Substring not found */
984     if (prog->check_substr || prog->check_utf8)         /* could be removed already */
985         BmUSEFUL(do_utf8 ? prog->check_utf8 : prog->check_substr) += 5; /* hooray */
986   fail:
987     DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "%sMatch rejected by optimizer%s\n",
988                           PL_colors[4], PL_colors[5]));
989     return NULL;
990 }
991
992
993
994 #define REXEC_TRIE_READ_CHAR(trie_type, trie, widecharmap, uc, uscan, len,  \
995 uvc, charid, foldlen, foldbuf, uniflags) STMT_START {                       \
996     switch (trie_type) {                                                    \
997     case trie_utf8_fold:                                                    \
998         if ( foldlen>0 ) {                                                  \
999             uvc = utf8n_to_uvuni( uscan, UTF8_MAXLEN, &len, uniflags );     \
1000             foldlen -= len;                                                 \
1001             uscan += len;                                                   \
1002             len=0;                                                          \
1003         } else {                                                            \
1004             uvc = utf8n_to_uvuni( (U8*)uc, UTF8_MAXLEN, &len, uniflags );   \
1005             uvc = to_uni_fold( uvc, foldbuf, &foldlen );                    \
1006             foldlen -= UNISKIP( uvc );                                      \
1007             uscan = foldbuf + UNISKIP( uvc );                               \
1008         }                                                                   \
1009         break;                                                              \
1010     case trie_utf8:                                                         \
1011         uvc = utf8n_to_uvuni( (U8*)uc, UTF8_MAXLEN, &len, uniflags );       \
1012         break;                                                              \
1013     case trie_plain:                                                        \
1014         uvc = (UV)*uc;                                                      \
1015         len = 1;                                                            \
1016     }                                                                       \
1017                                                                             \
1018     if (uvc < 256) {                                                        \
1019         charid = trie->charmap[ uvc ];                                      \
1020     }                                                                       \
1021     else {                                                                  \
1022         charid = 0;                                                         \
1023         if (widecharmap) {                                                  \
1024             SV** const svpp = hv_fetch(widecharmap,                         \
1025                         (char*)&uvc, sizeof(UV), 0);                        \
1026             if (svpp)                                                       \
1027                 charid = (U16)SvIV(*svpp);                                  \
1028         }                                                                   \
1029     }                                                                       \
1030 } STMT_END
1031
1032 #define REXEC_FBC_EXACTISH_CHECK(CoNd)                  \
1033     if ( (CoNd)                                        \
1034          && (ln == len ||                              \
1035              ibcmp_utf8(s, NULL, 0,  do_utf8,          \
1036                         m, NULL, ln, (bool)UTF))       \
1037          && (!reginfo || regtry(reginfo, &s)) )         \
1038         goto got_it;                                   \
1039     else {                                             \
1040          U8 foldbuf[UTF8_MAXBYTES_CASE+1];             \
1041          uvchr_to_utf8(tmpbuf, c);                     \
1042          f = to_utf8_fold(tmpbuf, foldbuf, &foldlen);  \
1043          if ( f != c                                   \
1044               && (f == c1 || f == c2)                  \
1045               && (ln == foldlen ||                     \
1046                   !ibcmp_utf8((char *) foldbuf,        \
1047                               NULL, foldlen, do_utf8,  \
1048                               m,                       \
1049                               NULL, ln, (bool)UTF))    \
1050               && (!reginfo || regtry(reginfo, &s)) )    \
1051               goto got_it;                             \
1052     }                                                  \
1053     s += len
1054
1055 #define REXEC_FBC_EXACTISH_SCAN(CoNd)                     \
1056 STMT_START {                                              \
1057     while (s <= e) {                                      \
1058         if ( (CoNd)                                       \
1059              && (ln == 1 || !(OP(c) == EXACTF             \
1060                               ? ibcmp(s, m, ln)           \
1061                               : ibcmp_locale(s, m, ln)))  \
1062              && (!reginfo || regtry(reginfo, &s)) )        \
1063             goto got_it;                                  \
1064         s++;                                              \
1065     }                                                     \
1066 } STMT_END
1067
1068 #define REXEC_FBC_UTF8_SCAN(CoDe)                     \
1069 STMT_START {                                          \
1070     while (s + (uskip = UTF8SKIP(s)) <= strend) {     \
1071         CoDe                                          \
1072         s += uskip;                                   \
1073     }                                                 \
1074 } STMT_END
1075
1076 #define REXEC_FBC_SCAN(CoDe)                          \
1077 STMT_START {                                          \
1078     while (s < strend) {                              \
1079         CoDe                                          \
1080         s++;                                          \
1081     }                                                 \
1082 } STMT_END
1083
1084 #define REXEC_FBC_UTF8_CLASS_SCAN(CoNd)               \
1085 REXEC_FBC_UTF8_SCAN(                                  \
1086     if (CoNd) {                                       \
1087         if (tmp && (!reginfo || regtry(reginfo, &s)))  \
1088             goto got_it;                              \
1089         else                                          \
1090             tmp = doevery;                            \
1091     }                                                 \
1092     else                                              \
1093         tmp = 1;                                      \
1094 )
1095
1096 #define REXEC_FBC_CLASS_SCAN(CoNd)                    \
1097 REXEC_FBC_SCAN(                                       \
1098     if (CoNd) {                                       \
1099         if (tmp && (!reginfo || regtry(reginfo, &s)))  \
1100             goto got_it;                              \
1101         else                                          \
1102             tmp = doevery;                            \
1103     }                                                 \
1104     else                                              \
1105         tmp = 1;                                      \
1106 )
1107
1108 #define REXEC_FBC_TRYIT               \
1109 if ((!reginfo || regtry(reginfo, &s))) \
1110     goto got_it
1111
1112 #define REXEC_FBC_CSCAN_PRELOAD(UtFpReLoAd,CoNdUtF8,CoNd)      \
1113     if (do_utf8) {                                             \
1114         UtFpReLoAd;                                            \
1115         REXEC_FBC_UTF8_CLASS_SCAN(CoNdUtF8);                   \
1116     }                                                          \
1117     else {                                                     \
1118         REXEC_FBC_CLASS_SCAN(CoNd);                            \
1119     }                                                          \
1120     break
1121
1122 #define REXEC_FBC_CSCAN_TAINT(CoNdUtF8,CoNd)                   \
1123     PL_reg_flags |= RF_tainted;                                \
1124     if (do_utf8) {                                             \
1125         REXEC_FBC_UTF8_CLASS_SCAN(CoNdUtF8);                   \
1126     }                                                          \
1127     else {                                                     \
1128         REXEC_FBC_CLASS_SCAN(CoNd);                            \
1129     }                                                          \
1130     break
1131
1132 #define DUMP_EXEC_POS(li,s,doutf8) \
1133     dump_exec_pos(li,s,(PL_regeol),(PL_bostr),(PL_reg_starttry),doutf8)
1134
1135 /* We know what class REx starts with.  Try to find this position... */
1136 /* if reginfo is NULL, its a dryrun */
1137 /* annoyingly all the vars in this routine have different names from their counterparts
1138    in regmatch. /grrr */
1139
1140 STATIC char *
1141 S_find_byclass(pTHX_ regexp * prog, const regnode *c, char *s, 
1142     const char *strend, regmatch_info *reginfo)
1143 {
1144         dVAR;
1145         const I32 doevery = (prog->intflags & PREGf_SKIP) == 0;
1146         char *m;
1147         STRLEN ln;
1148         STRLEN lnc;
1149         register STRLEN uskip;
1150         unsigned int c1;
1151         unsigned int c2;
1152         char *e;
1153         register I32 tmp = 1;   /* Scratch variable? */
1154         register const bool do_utf8 = PL_reg_match_utf8;
1155         RXi_GET_DECL(prog,progi);
1156         
1157         /* We know what class it must start with. */
1158         switch (OP(c)) {
1159         case ANYOF:
1160             if (do_utf8) {
1161                  REXEC_FBC_UTF8_CLASS_SCAN((ANYOF_FLAGS(c) & ANYOF_UNICODE) ||
1162                           !UTF8_IS_INVARIANT((U8)s[0]) ?
1163                           reginclass(prog, c, (U8*)s, 0, do_utf8) :
1164                           REGINCLASS(prog, c, (U8*)s));
1165             }
1166             else {
1167                  while (s < strend) {
1168                       STRLEN skip = 1;
1169
1170                       if (REGINCLASS(prog, c, (U8*)s) ||
1171                           (ANYOF_FOLD_SHARP_S(c, s, strend) &&
1172                            /* The assignment of 2 is intentional:
1173                             * for the folded sharp s, the skip is 2. */
1174                            (skip = SHARP_S_SKIP))) {
1175                            if (tmp && (!reginfo || regtry(reginfo, &s)))
1176                                 goto got_it;
1177                            else
1178                                 tmp = doevery;
1179                       }
1180                       else 
1181                            tmp = 1;
1182                       s += skip;
1183                  }
1184             }
1185             break;
1186         case CANY:
1187             REXEC_FBC_SCAN(
1188                 if (tmp && (!reginfo || regtry(reginfo, &s)))
1189                     goto got_it;
1190                 else
1191                     tmp = doevery;
1192             );
1193             break;
1194         case EXACTF:
1195             m   = STRING(c);
1196             ln  = STR_LEN(c);   /* length to match in octets/bytes */
1197             lnc = (I32) ln;     /* length to match in characters */
1198             if (UTF) {
1199                 STRLEN ulen1, ulen2;
1200                 U8 *sm = (U8 *) m;
1201                 U8 tmpbuf1[UTF8_MAXBYTES_CASE+1];
1202                 U8 tmpbuf2[UTF8_MAXBYTES_CASE+1];
1203                 const U32 uniflags = UTF8_ALLOW_DEFAULT;
1204
1205                 to_utf8_lower((U8*)m, tmpbuf1, &ulen1);
1206                 to_utf8_upper((U8*)m, tmpbuf2, &ulen2);
1207
1208                 c1 = utf8n_to_uvchr(tmpbuf1, UTF8_MAXBYTES_CASE, 
1209                                     0, uniflags);
1210                 c2 = utf8n_to_uvchr(tmpbuf2, UTF8_MAXBYTES_CASE,
1211                                     0, uniflags);
1212                 lnc = 0;
1213                 while (sm < ((U8 *) m + ln)) {
1214                     lnc++;
1215                     sm += UTF8SKIP(sm);
1216                 }
1217             }
1218             else {
1219                 c1 = *(U8*)m;
1220                 c2 = PL_fold[c1];
1221             }
1222             goto do_exactf;
1223         case EXACTFL:
1224             m   = STRING(c);
1225             ln  = STR_LEN(c);
1226             lnc = (I32) ln;
1227             c1 = *(U8*)m;
1228             c2 = PL_fold_locale[c1];
1229           do_exactf:
1230             e = HOP3c(strend, -((I32)lnc), s);
1231
1232             if (!reginfo && e < s)
1233                 e = s;                  /* Due to minlen logic of intuit() */
1234
1235             /* The idea in the EXACTF* cases is to first find the
1236              * first character of the EXACTF* node and then, if
1237              * necessary, case-insensitively compare the full
1238              * text of the node.  The c1 and c2 are the first
1239              * characters (though in Unicode it gets a bit
1240              * more complicated because there are more cases
1241              * than just upper and lower: one needs to use
1242              * the so-called folding case for case-insensitive
1243              * matching (called "loose matching" in Unicode).
1244              * ibcmp_utf8() will do just that. */
1245
1246             if (do_utf8) {
1247                 UV c, f;
1248                 U8 tmpbuf [UTF8_MAXBYTES+1];
1249                 STRLEN len, foldlen;
1250                 const U32 uniflags = UTF8_ALLOW_DEFAULT;
1251                 if (c1 == c2) {
1252                     /* Upper and lower of 1st char are equal -
1253                      * probably not a "letter". */
1254                     while (s <= e) {
1255                         c = utf8n_to_uvchr((U8*)s, UTF8_MAXBYTES, &len,
1256                                            uniflags);
1257                         REXEC_FBC_EXACTISH_CHECK(c == c1);
1258                     }
1259                 }
1260                 else {
1261                     while (s <= e) {
1262                       c = utf8n_to_uvchr((U8*)s, UTF8_MAXBYTES, &len,
1263                                            uniflags);
1264
1265                         /* Handle some of the three Greek sigmas cases.
1266                          * Note that not all the possible combinations
1267                          * are handled here: some of them are handled
1268                          * by the standard folding rules, and some of
1269                          * them (the character class or ANYOF cases)
1270                          * are handled during compiletime in
1271                          * regexec.c:S_regclass(). */
1272                         if (c == (UV)UNICODE_GREEK_CAPITAL_LETTER_SIGMA ||
1273                             c == (UV)UNICODE_GREEK_SMALL_LETTER_FINAL_SIGMA)
1274                             c = (UV)UNICODE_GREEK_SMALL_LETTER_SIGMA;
1275
1276                         REXEC_FBC_EXACTISH_CHECK(c == c1 || c == c2);
1277                     }
1278                 }
1279             }
1280             else {
1281                 if (c1 == c2)
1282                     REXEC_FBC_EXACTISH_SCAN(*(U8*)s == c1);
1283                 else
1284                     REXEC_FBC_EXACTISH_SCAN(*(U8*)s == c1 || *(U8*)s == c2);
1285             }
1286             break;
1287         case BOUNDL:
1288             PL_reg_flags |= RF_tainted;
1289             /* FALL THROUGH */
1290         case BOUND:
1291             if (do_utf8) {
1292                 if (s == PL_bostr)
1293                     tmp = '\n';
1294                 else {
1295                     U8 * const r = reghop3((U8*)s, -1, (U8*)PL_bostr);
1296                     tmp = utf8n_to_uvchr(r, UTF8SKIP(r), 0, UTF8_ALLOW_DEFAULT);
1297                 }
1298                 tmp = ((OP(c) == BOUND ?
1299                         isALNUM_uni(tmp) : isALNUM_LC_uvchr(UNI_TO_NATIVE(tmp))) != 0);
1300                 LOAD_UTF8_CHARCLASS_ALNUM();
1301                 REXEC_FBC_UTF8_SCAN(
1302                     if (tmp == !(OP(c) == BOUND ?
1303                                  (bool)swash_fetch(PL_utf8_alnum, (U8*)s, do_utf8) :
1304                                  isALNUM_LC_utf8((U8*)s)))
1305                     {
1306                         tmp = !tmp;
1307                         REXEC_FBC_TRYIT;
1308                 }
1309                 );
1310             }
1311             else {
1312                 tmp = (s != PL_bostr) ? UCHARAT(s - 1) : '\n';
1313                 tmp = ((OP(c) == BOUND ? isALNUM(tmp) : isALNUM_LC(tmp)) != 0);
1314                 REXEC_FBC_SCAN(
1315                     if (tmp ==
1316                         !(OP(c) == BOUND ? isALNUM(*s) : isALNUM_LC(*s))) {
1317                         tmp = !tmp;
1318                         REXEC_FBC_TRYIT;
1319                 }
1320                 );
1321             }
1322             if ((!prog->minlen && tmp) && (!reginfo || regtry(reginfo, &s)))
1323                 goto got_it;
1324             break;
1325         case NBOUNDL:
1326             PL_reg_flags |= RF_tainted;
1327             /* FALL THROUGH */
1328         case NBOUND:
1329             if (do_utf8) {
1330                 if (s == PL_bostr)
1331                     tmp = '\n';
1332                 else {
1333                     U8 * const r = reghop3((U8*)s, -1, (U8*)PL_bostr);
1334                     tmp = utf8n_to_uvchr(r, UTF8SKIP(r), 0, UTF8_ALLOW_DEFAULT);
1335                 }
1336                 tmp = ((OP(c) == NBOUND ?
1337                         isALNUM_uni(tmp) : isALNUM_LC_uvchr(UNI_TO_NATIVE(tmp))) != 0);
1338                 LOAD_UTF8_CHARCLASS_ALNUM();
1339                 REXEC_FBC_UTF8_SCAN(
1340                     if (tmp == !(OP(c) == NBOUND ?
1341                                  (bool)swash_fetch(PL_utf8_alnum, (U8*)s, do_utf8) :
1342                                  isALNUM_LC_utf8((U8*)s)))
1343                         tmp = !tmp;
1344                     else REXEC_FBC_TRYIT;
1345                 );
1346             }
1347             else {
1348                 tmp = (s != PL_bostr) ? UCHARAT(s - 1) : '\n';
1349                 tmp = ((OP(c) == NBOUND ?
1350                         isALNUM(tmp) : isALNUM_LC(tmp)) != 0);
1351                 REXEC_FBC_SCAN(
1352                     if (tmp ==
1353                         !(OP(c) == NBOUND ? isALNUM(*s) : isALNUM_LC(*s)))
1354                         tmp = !tmp;
1355                     else REXEC_FBC_TRYIT;
1356                 );
1357             }
1358             if ((!prog->minlen && !tmp) && (!reginfo || regtry(reginfo, &s)))
1359                 goto got_it;
1360             break;
1361         case ALNUM:
1362             REXEC_FBC_CSCAN_PRELOAD(
1363                 LOAD_UTF8_CHARCLASS_ALNUM(),
1364                 swash_fetch(PL_utf8_alnum, (U8*)s, do_utf8),
1365                 isALNUM(*s)
1366             );
1367         case ALNUML:
1368             REXEC_FBC_CSCAN_TAINT(
1369                 isALNUM_LC_utf8((U8*)s),
1370                 isALNUM_LC(*s)
1371             );
1372         case NALNUM:
1373             REXEC_FBC_CSCAN_PRELOAD(
1374                 LOAD_UTF8_CHARCLASS_ALNUM(),
1375                 !swash_fetch(PL_utf8_alnum, (U8*)s, do_utf8),
1376                 !isALNUM(*s)
1377             );
1378         case NALNUML:
1379             REXEC_FBC_CSCAN_TAINT(
1380                 !isALNUM_LC_utf8((U8*)s),
1381                 !isALNUM_LC(*s)
1382             );
1383         case SPACE:
1384             REXEC_FBC_CSCAN_PRELOAD(
1385                 LOAD_UTF8_CHARCLASS_SPACE(),
1386                 *s == ' ' || swash_fetch(PL_utf8_space,(U8*)s, do_utf8),
1387                 isSPACE(*s)
1388             );
1389         case SPACEL:
1390             REXEC_FBC_CSCAN_TAINT(
1391                 *s == ' ' || isSPACE_LC_utf8((U8*)s),
1392                 isSPACE_LC(*s)
1393             );
1394         case NSPACE:
1395             REXEC_FBC_CSCAN_PRELOAD(
1396                 LOAD_UTF8_CHARCLASS_SPACE(),
1397                 !(*s == ' ' || swash_fetch(PL_utf8_space,(U8*)s, do_utf8)),
1398                 !isSPACE(*s)
1399             );
1400         case NSPACEL:
1401             REXEC_FBC_CSCAN_TAINT(
1402                 !(*s == ' ' || isSPACE_LC_utf8((U8*)s)),
1403                 !isSPACE_LC(*s)
1404             );
1405         case DIGIT:
1406             REXEC_FBC_CSCAN_PRELOAD(
1407                 LOAD_UTF8_CHARCLASS_DIGIT(),
1408                 swash_fetch(PL_utf8_digit,(U8*)s, do_utf8),
1409                 isDIGIT(*s)
1410             );
1411         case DIGITL:
1412             REXEC_FBC_CSCAN_TAINT(
1413                 isDIGIT_LC_utf8((U8*)s),
1414                 isDIGIT_LC(*s)
1415             );
1416         case NDIGIT:
1417             REXEC_FBC_CSCAN_PRELOAD(
1418                 LOAD_UTF8_CHARCLASS_DIGIT(),
1419                 !swash_fetch(PL_utf8_digit,(U8*)s, do_utf8),
1420                 !isDIGIT(*s)
1421             );
1422         case NDIGITL:
1423             REXEC_FBC_CSCAN_TAINT(
1424                 !isDIGIT_LC_utf8((U8*)s),
1425                 !isDIGIT_LC(*s)
1426             );
1427         case AHOCORASICKC:
1428         case AHOCORASICK: 
1429             {
1430                 const enum { trie_plain, trie_utf8, trie_utf8_fold }
1431                     trie_type = do_utf8 ?
1432                           (c->flags == EXACT ? trie_utf8 : trie_utf8_fold)
1433                         : trie_plain;
1434                 /* what trie are we using right now */
1435                 reg_ac_data *aho
1436                     = (reg_ac_data*)progi->data->data[ ARG( c ) ];
1437                 reg_trie_data *trie
1438                     = (reg_trie_data*)progi->data->data[ aho->trie ];
1439                 HV *widecharmap = (HV*) progi->data->data[ aho->trie + 1 ];
1440
1441                 const char *last_start = strend - trie->minlen;
1442 #ifdef DEBUGGING
1443                 const char *real_start = s;
1444 #endif
1445                 STRLEN maxlen = trie->maxlen;
1446                 SV *sv_points;
1447                 U8 **points; /* map of where we were in the input string
1448                                 when reading a given char. For ASCII this
1449                                 is unnecessary overhead as the relationship
1450                                 is always 1:1, but for unicode, especially
1451                                 case folded unicode this is not true. */
1452                 U8 foldbuf[ UTF8_MAXBYTES_CASE + 1 ];
1453                 U8 *bitmap=NULL;
1454
1455
1456                 GET_RE_DEBUG_FLAGS_DECL;
1457
1458                 /* We can't just allocate points here. We need to wrap it in
1459                  * an SV so it gets freed properly if there is a croak while
1460                  * running the match */
1461                 ENTER;
1462                 SAVETMPS;
1463                 sv_points=newSV(maxlen * sizeof(U8 *));
1464                 SvCUR_set(sv_points,
1465                     maxlen * sizeof(U8 *));
1466                 SvPOK_on(sv_points);
1467                 sv_2mortal(sv_points);
1468                 points=(U8**)SvPV_nolen(sv_points );
1469                 if ( trie_type != trie_utf8_fold 
1470                      && (trie->bitmap || OP(c)==AHOCORASICKC) ) 
1471                 {
1472                     if (trie->bitmap) 
1473                         bitmap=(U8*)trie->bitmap;
1474                     else
1475                         bitmap=(U8*)ANYOF_BITMAP(c);
1476                 }
1477                 /* this is the Aho-Corasick algorithm modified a touch
1478                    to include special handling for long "unknown char" 
1479                    sequences. The basic idea being that we use AC as long
1480                    as we are dealing with a possible matching char, when
1481                    we encounter an unknown char (and we have not encountered
1482                    an accepting state) we scan forward until we find a legal 
1483                    starting char. 
1484                    AC matching is basically that of trie matching, except
1485                    that when we encounter a failing transition, we fall back
1486                    to the current states "fail state", and try the current char 
1487                    again, a process we repeat until we reach the root state, 
1488                    state 1, or a legal transition. If we fail on the root state 
1489                    then we can either terminate if we have reached an accepting 
1490                    state previously, or restart the entire process from the beginning 
1491                    if we have not.
1492
1493                  */
1494                 while (s <= last_start) {
1495                     const U32 uniflags = UTF8_ALLOW_DEFAULT;
1496                     U8 *uc = (U8*)s;
1497                     U16 charid = 0;
1498                     U32 base = 1;
1499                     U32 state = 1;
1500                     UV uvc = 0;
1501                     STRLEN len = 0;
1502                     STRLEN foldlen = 0;
1503                     U8 *uscan = (U8*)NULL;
1504                     U8 *leftmost = NULL;
1505 #ifdef DEBUGGING                    
1506                     U32 accepted_word= 0;
1507 #endif
1508                     U32 pointpos = 0;
1509
1510                     while ( state && uc <= (U8*)strend ) {
1511                         int failed=0;
1512                         U32 word = aho->states[ state ].wordnum;
1513
1514                         if( state==1 ) {
1515                             if ( bitmap ) {
1516                                 DEBUG_TRIE_EXECUTE_r(
1517                                     if ( uc <= (U8*)last_start && !BITMAP_TEST(bitmap,*uc) ) {
1518                                         dump_exec_pos( (char *)uc, c, strend, real_start, 
1519                                             (char *)uc, do_utf8 );
1520                                         PerlIO_printf( Perl_debug_log,
1521                                             " Scanning for legal start char...\n");
1522                                     }
1523                                 );            
1524                                 while ( uc <= (U8*)last_start  && !BITMAP_TEST(bitmap,*uc) ) {
1525                                     uc++;
1526                                 }
1527                                 s= (char *)uc;
1528                             }
1529                             if (uc >(U8*)last_start) break;
1530                         }
1531                                             
1532                         if ( word ) {
1533                             U8 *lpos= points[ (pointpos - trie->wordlen[word-1] ) % maxlen ];
1534                             if (!leftmost || lpos < leftmost) {
1535                                 DEBUG_r(accepted_word=word);
1536                                 leftmost= lpos;
1537                             }
1538                             if (base==0) break;
1539                             
1540                         }
1541                         points[pointpos++ % maxlen]= uc;
1542                         REXEC_TRIE_READ_CHAR(trie_type, trie, widecharmap, uc,
1543                                              uscan, len, uvc, charid, foldlen,
1544                                              foldbuf, uniflags);
1545                         DEBUG_TRIE_EXECUTE_r({
1546                             dump_exec_pos( (char *)uc, c, strend, real_start, 
1547                                 s,   do_utf8 );
1548                             PerlIO_printf(Perl_debug_log,
1549                                 " Charid:%3u CP:%4"UVxf" ",
1550                                  charid, uvc);
1551                         });
1552
1553                         do {
1554 #ifdef DEBUGGING
1555                             word = aho->states[ state ].wordnum;
1556 #endif
1557                             base = aho->states[ state ].trans.base;
1558
1559                             DEBUG_TRIE_EXECUTE_r({
1560                                 if (failed) 
1561                                     dump_exec_pos( (char *)uc, c, strend, real_start, 
1562                                         s,   do_utf8 );
1563                                 PerlIO_printf( Perl_debug_log,
1564                                     "%sState: %4"UVxf", word=%"UVxf,
1565                                     failed ? " Fail transition to " : "",
1566                                     (UV)state, (UV)word);
1567                             });
1568                             if ( base ) {
1569                                 U32 tmp;
1570                                 if (charid &&
1571                                      (base + charid > trie->uniquecharcount )
1572                                      && (base + charid - 1 - trie->uniquecharcount
1573                                             < trie->lasttrans)
1574                                      && trie->trans[base + charid - 1 -
1575                                             trie->uniquecharcount].check == state
1576                                      && (tmp=trie->trans[base + charid - 1 -
1577                                         trie->uniquecharcount ].next))
1578                                 {
1579                                     DEBUG_TRIE_EXECUTE_r(
1580                                         PerlIO_printf( Perl_debug_log," - legal\n"));
1581                                     state = tmp;
1582                                     break;
1583                                 }
1584                                 else {
1585                                     DEBUG_TRIE_EXECUTE_r(
1586                                         PerlIO_printf( Perl_debug_log," - fail\n"));
1587                                     failed = 1;
1588                                     state = aho->fail[state];
1589                                 }
1590                             }
1591                             else {
1592                                 /* we must be accepting here */
1593                                 DEBUG_TRIE_EXECUTE_r(
1594                                         PerlIO_printf( Perl_debug_log," - accepting\n"));
1595                                 failed = 1;
1596                                 break;
1597                             }
1598                         } while(state);
1599                         uc += len;
1600                         if (failed) {
1601                             if (leftmost)
1602                                 break;
1603                             if (!state) state = 1;
1604                         }
1605                     }
1606                     if ( aho->states[ state ].wordnum ) {
1607                         U8 *lpos = points[ (pointpos - trie->wordlen[aho->states[ state ].wordnum-1]) % maxlen ];
1608                         if (!leftmost || lpos < leftmost) {
1609                             DEBUG_r(accepted_word=aho->states[ state ].wordnum);
1610                             leftmost = lpos;
1611                         }
1612                     }
1613                     if (leftmost) {
1614                         s = (char*)leftmost;
1615                         DEBUG_TRIE_EXECUTE_r({
1616                             PerlIO_printf( 
1617                                 Perl_debug_log,"Matches word #%"UVxf" at position %"IVdf". Trying full pattern...\n",
1618                                 (UV)accepted_word, (IV)(s - real_start)
1619                             );
1620                         });
1621                         if (!reginfo || regtry(reginfo, &s)) {
1622                             FREETMPS;
1623                             LEAVE;
1624                             goto got_it;
1625                         }
1626                         s = HOPc(s,1);
1627                         DEBUG_TRIE_EXECUTE_r({
1628                             PerlIO_printf( Perl_debug_log,"Pattern failed. Looking for new start point...\n");
1629                         });
1630                     } else {
1631                         DEBUG_TRIE_EXECUTE_r(
1632                             PerlIO_printf( Perl_debug_log,"No match.\n"));
1633                         break;
1634                     }
1635                 }
1636                 FREETMPS;
1637                 LEAVE;
1638             }
1639             break;
1640         default:
1641             Perl_croak(aTHX_ "panic: unknown regstclass %d", (int)OP(c));
1642             break;
1643         }
1644         return 0;
1645       got_it:
1646         return s;
1647 }
1648
1649 /*
1650  - regexec_flags - match a regexp against a string
1651  */
1652 I32
1653 Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char *strend,
1654               char *strbeg, I32 minend, SV *sv, void *data, U32 flags)
1655 /* strend: pointer to null at end of string */
1656 /* strbeg: real beginning of string */
1657 /* minend: end of match must be >=minend after stringarg. */
1658 /* data: May be used for some additional optimizations. 
1659          Currently its only used, with a U32 cast, for transmitting 
1660          the ganch offset when doing a /g match. This will change */
1661 /* nosave: For optimizations. */
1662 {
1663     dVAR;
1664     /*register*/ char *s;
1665     register regnode *c;
1666     /*register*/ char *startpos = stringarg;
1667     I32 minlen;         /* must match at least this many chars */
1668     I32 dontbother = 0; /* how many characters not to try at end */
1669     I32 end_shift = 0;                  /* Same for the end. */         /* CC */
1670     I32 scream_pos = -1;                /* Internal iterator of scream. */
1671     char *scream_olds = NULL;
1672     SV* const oreplsv = GvSV(PL_replgv);
1673     const bool do_utf8 = (bool)DO_UTF8(sv);
1674     I32 multiline;
1675     RXi_GET_DECL(prog,progi);
1676     regmatch_info reginfo;  /* create some info to pass to regtry etc */
1677
1678     GET_RE_DEBUG_FLAGS_DECL;
1679
1680     PERL_UNUSED_ARG(data);
1681
1682     /* Be paranoid... */
1683     if (prog == NULL || startpos == NULL) {
1684         Perl_croak(aTHX_ "NULL regexp parameter");
1685         return 0;
1686     }
1687
1688     multiline = prog->extflags & RXf_PMf_MULTILINE;
1689     reginfo.prog = prog;
1690
1691     RX_MATCH_UTF8_set(prog, do_utf8);
1692     DEBUG_EXECUTE_r( 
1693         debug_start_match(prog, do_utf8, startpos, strend, 
1694         "Matching");
1695     );
1696
1697     minlen = prog->minlen;
1698     
1699     if (strend - startpos < (minlen+(prog->check_offset_min<0?prog->check_offset_min:0))) {
1700         DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
1701                               "String too short [regexec_flags]...\n"));
1702         goto phooey;
1703     }
1704
1705     
1706     /* Check validity of program. */
1707     if (UCHARAT(progi->program) != REG_MAGIC) {
1708         Perl_croak(aTHX_ "corrupted regexp program");
1709     }
1710
1711     PL_reg_flags = 0;
1712     PL_reg_eval_set = 0;
1713     PL_reg_maxiter = 0;
1714
1715     if (prog->extflags & RXf_UTF8)
1716         PL_reg_flags |= RF_utf8;
1717
1718     /* Mark beginning of line for ^ and lookbehind. */
1719     reginfo.bol = startpos; /* XXX not used ??? */
1720     PL_bostr  = strbeg;
1721     reginfo.sv = sv;
1722
1723     /* Mark end of line for $ (and such) */
1724     PL_regeol = strend;
1725
1726     /* see how far we have to get to not match where we matched before */
1727     reginfo.till = startpos+minend;
1728
1729     /* If there is a "must appear" string, look for it. */
1730     s = startpos;
1731
1732     if (prog->extflags & RXf_GPOS_SEEN) { /* Need to set reginfo->ganch */
1733         MAGIC *mg;
1734
1735         if (flags & REXEC_IGNOREPOS)    /* Means: check only at start */
1736             reginfo.ganch = startpos + prog->gofs;
1737         else if (sv && SvTYPE(sv) >= SVt_PVMG
1738                   && SvMAGIC(sv)
1739                   && (mg = mg_find(sv, PERL_MAGIC_regex_global))
1740                   && mg->mg_len >= 0) {
1741             reginfo.ganch = strbeg + mg->mg_len;        /* Defined pos() */
1742             if (prog->extflags & RXf_ANCH_GPOS) {
1743                 if (s > reginfo.ganch)
1744                     goto phooey;
1745                 s = reginfo.ganch - prog->gofs;
1746             }
1747         }
1748         else if (data) {
1749             reginfo.ganch = strbeg + PTR2UV(data);
1750         } else                          /* pos() not defined */
1751             reginfo.ganch = strbeg;
1752     }
1753     if (PL_curpm && (PM_GETRE(PL_curpm) == prog)) {
1754         I32 *t;
1755         if (!progi->swap) {
1756         /* We have to be careful. If the previous successful match
1757            was from this regex we don't want a subsequent paritally
1758            successful match to clobber the old results. 
1759            So when we detect this possibility we add a swap buffer
1760            to the re, and switch the buffer each match. If we fail
1761            we switch it back, otherwise we leave it swapped.
1762         */
1763             Newxz(progi->swap, 1, regexp_paren_ofs);
1764             /* no need to copy these */
1765             Newxz(progi->swap->startp, prog->nparens + 1, I32);
1766             Newxz(progi->swap->endp, prog->nparens + 1, I32);
1767         }
1768         t = progi->swap->startp;
1769         progi->swap->startp = prog->startp;
1770         prog->startp = t;
1771         t = progi->swap->endp;
1772         progi->swap->endp = prog->endp;
1773         prog->endp = t;
1774     }
1775     if (!(flags & REXEC_CHECKED) && (prog->check_substr != NULL || prog->check_utf8 != NULL)) {
1776         re_scream_pos_data d;
1777
1778         d.scream_olds = &scream_olds;
1779         d.scream_pos = &scream_pos;
1780         s = re_intuit_start(prog, sv, s, strend, flags, &d);
1781         if (!s) {
1782             DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "Not present...\n"));
1783             goto phooey;        /* not present */
1784         }
1785     }
1786
1787
1788
1789     /* Simplest case:  anchored match need be tried only once. */
1790     /*  [unless only anchor is BOL and multiline is set] */
1791     if (prog->extflags & (RXf_ANCH & ~RXf_ANCH_GPOS)) {
1792         if (s == startpos && regtry(&reginfo, &startpos))
1793             goto got_it;
1794         else if (multiline || (prog->intflags & PREGf_IMPLICIT)
1795                  || (prog->extflags & RXf_ANCH_MBOL)) /* XXXX SBOL? */
1796         {
1797             char *end;
1798
1799             if (minlen)
1800                 dontbother = minlen - 1;
1801             end = HOP3c(strend, -dontbother, strbeg) - 1;
1802             /* for multiline we only have to try after newlines */
1803             if (prog->check_substr || prog->check_utf8) {
1804                 if (s == startpos)
1805                     goto after_try;
1806                 while (1) {
1807                     if (regtry(&reginfo, &s))
1808                         goto got_it;
1809                   after_try:
1810                     if (s >= end)
1811                         goto phooey;
1812                     if (prog->extflags & RXf_USE_INTUIT) {
1813                         s = re_intuit_start(prog, sv, s + 1, strend, flags, NULL);
1814                         if (!s)
1815                             goto phooey;
1816                     }
1817                     else
1818                         s++;
1819                 }               
1820             } else {
1821                 if (s > startpos)
1822                     s--;
1823                 while (s < end) {
1824                     if (*s++ == '\n') { /* don't need PL_utf8skip here */
1825                         if (regtry(&reginfo, &s))
1826                             goto got_it;
1827                     }
1828                 }               
1829             }
1830         }
1831         goto phooey;
1832     } else if (RXf_GPOS_CHECK == (prog->extflags & RXf_GPOS_CHECK)) 
1833     {
1834         /* the warning about reginfo.ganch being used without intialization
1835            is bogus -- we set it above, when prog->extflags & RXf_GPOS_SEEN 
1836            and we only enter this block when the same bit is set. */
1837         char *tmp_s = reginfo.ganch - prog->gofs;
1838         if (regtry(&reginfo, &tmp_s))
1839             goto got_it;
1840         goto phooey;
1841     }
1842
1843     /* Messy cases:  unanchored match. */
1844     if ((prog->anchored_substr || prog->anchored_utf8) && prog->intflags & PREGf_SKIP) {
1845         /* we have /x+whatever/ */
1846         /* it must be a one character string (XXXX Except UTF?) */
1847         char ch;
1848 #ifdef DEBUGGING
1849         int did_match = 0;
1850 #endif
1851         if (!(do_utf8 ? prog->anchored_utf8 : prog->anchored_substr))
1852             do_utf8 ? to_utf8_substr(prog) : to_byte_substr(prog);
1853         ch = SvPVX_const(do_utf8 ? prog->anchored_utf8 : prog->anchored_substr)[0];
1854
1855         if (do_utf8) {
1856             REXEC_FBC_SCAN(
1857                 if (*s == ch) {
1858                     DEBUG_EXECUTE_r( did_match = 1 );
1859                     if (regtry(&reginfo, &s)) goto got_it;
1860                     s += UTF8SKIP(s);
1861                     while (s < strend && *s == ch)
1862                         s += UTF8SKIP(s);
1863                 }
1864             );
1865         }
1866         else {
1867             REXEC_FBC_SCAN(
1868                 if (*s == ch) {
1869                     DEBUG_EXECUTE_r( did_match = 1 );
1870                     if (regtry(&reginfo, &s)) goto got_it;
1871                     s++;
1872                     while (s < strend && *s == ch)
1873                         s++;
1874                 }
1875             );
1876         }
1877         DEBUG_EXECUTE_r(if (!did_match)
1878                 PerlIO_printf(Perl_debug_log,
1879                                   "Did not find anchored character...\n")
1880                );
1881     }
1882     else if (prog->anchored_substr != NULL
1883               || prog->anchored_utf8 != NULL
1884               || ((prog->float_substr != NULL || prog->float_utf8 != NULL)
1885                   && prog->float_max_offset < strend - s)) {
1886         SV *must;
1887         I32 back_max;
1888         I32 back_min;
1889         char *last;
1890         char *last1;            /* Last position checked before */
1891 #ifdef DEBUGGING
1892         int did_match = 0;
1893 #endif
1894         if (prog->anchored_substr || prog->anchored_utf8) {
1895             if (!(do_utf8 ? prog->anchored_utf8 : prog->anchored_substr))
1896                 do_utf8 ? to_utf8_substr(prog) : to_byte_substr(prog);
1897             must = do_utf8 ? prog->anchored_utf8 : prog->anchored_substr;
1898             back_max = back_min = prog->anchored_offset;
1899         } else {
1900             if (!(do_utf8 ? prog->float_utf8 : prog->float_substr))
1901                 do_utf8 ? to_utf8_substr(prog) : to_byte_substr(prog);
1902             must = do_utf8 ? prog->float_utf8 : prog->float_substr;
1903             back_max = prog->float_max_offset;
1904             back_min = prog->float_min_offset;
1905         }
1906         
1907             
1908         if (must == &PL_sv_undef)
1909             /* could not downgrade utf8 check substring, so must fail */
1910             goto phooey;
1911
1912         if (back_min<0) {
1913             last = strend;
1914         } else {
1915             last = HOP3c(strend,        /* Cannot start after this */
1916                   -(I32)(CHR_SVLEN(must)
1917                          - (SvTAIL(must) != 0) + back_min), strbeg);
1918         }
1919         if (s > PL_bostr)
1920             last1 = HOPc(s, -1);
1921         else
1922             last1 = s - 1;      /* bogus */
1923
1924         /* XXXX check_substr already used to find "s", can optimize if
1925            check_substr==must. */
1926         scream_pos = -1;
1927         dontbother = end_shift;
1928         strend = HOPc(strend, -dontbother);
1929         while ( (s <= last) &&
1930                 ((flags & REXEC_SCREAM)
1931                  ? (s = screaminstr(sv, must, HOP3c(s, back_min, (back_min<0 ? strbeg : strend)) - strbeg,
1932                                     end_shift, &scream_pos, 0))
1933                  : (s = fbm_instr((unsigned char*)HOP3(s, back_min, (back_min<0 ? strbeg : strend)),
1934                                   (unsigned char*)strend, must,
1935                                   multiline ? FBMrf_MULTILINE : 0))) ) {
1936             /* we may be pointing at the wrong string */
1937             if ((flags & REXEC_SCREAM) && RX_MATCH_COPIED(prog))
1938                 s = strbeg + (s - SvPVX_const(sv));
1939             DEBUG_EXECUTE_r( did_match = 1 );
1940             if (HOPc(s, -back_max) > last1) {
1941                 last1 = HOPc(s, -back_min);
1942                 s = HOPc(s, -back_max);
1943             }
1944             else {
1945                 char * const t = (last1 >= PL_bostr) ? HOPc(last1, 1) : last1 + 1;
1946
1947                 last1 = HOPc(s, -back_min);
1948                 s = t;
1949             }
1950             if (do_utf8) {
1951                 while (s <= last1) {
1952                     if (regtry(&reginfo, &s))
1953                         goto got_it;
1954                     s += UTF8SKIP(s);
1955                 }
1956             }
1957             else {
1958                 while (s <= last1) {
1959                     if (regtry(&reginfo, &s))
1960                         goto got_it;
1961                     s++;
1962                 }
1963             }
1964         }
1965         DEBUG_EXECUTE_r(if (!did_match) {
1966             RE_PV_QUOTED_DECL(quoted, do_utf8, PERL_DEBUG_PAD_ZERO(0), 
1967                 SvPVX_const(must), RE_SV_DUMPLEN(must), 30);
1968             PerlIO_printf(Perl_debug_log, "Did not find %s substr %s%s...\n",
1969                               ((must == prog->anchored_substr || must == prog->anchored_utf8)
1970                                ? "anchored" : "floating"),
1971                 quoted, RE_SV_TAIL(must));
1972         });                 
1973         goto phooey;
1974     }
1975     else if ( (c = progi->regstclass) ) {
1976         if (minlen) {
1977             const OPCODE op = OP(progi->regstclass);
1978             /* don't bother with what can't match */
1979             if (PL_regkind[op] != EXACT && op != CANY && PL_regkind[op] != TRIE)
1980                 strend = HOPc(strend, -(minlen - 1));
1981         }
1982         DEBUG_EXECUTE_r({
1983             SV * const prop = sv_newmortal();
1984             regprop(prog, prop, c);
1985             {
1986                 RE_PV_QUOTED_DECL(quoted,UTF,PERL_DEBUG_PAD_ZERO(1),
1987                     s,strend-s,60);
1988                 PerlIO_printf(Perl_debug_log,
1989                     "Matching stclass %.*s against %s (%d chars)\n",
1990                     (int)SvCUR(prop), SvPVX_const(prop),
1991                      quoted, (int)(strend - s));
1992             }
1993         });
1994         if (find_byclass(prog, c, s, strend, &reginfo))
1995             goto got_it;
1996         DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "Contradicts stclass... [regexec_flags]\n"));
1997     }
1998     else {
1999         dontbother = 0;
2000         if (prog->float_substr != NULL || prog->float_utf8 != NULL) {
2001             /* Trim the end. */
2002             char *last;
2003             SV* float_real;
2004
2005             if (!(do_utf8 ? prog->float_utf8 : prog->float_substr))
2006                 do_utf8 ? to_utf8_substr(prog) : to_byte_substr(prog);
2007             float_real = do_utf8 ? prog->float_utf8 : prog->float_substr;
2008
2009             if (flags & REXEC_SCREAM) {
2010                 last = screaminstr(sv, float_real, s - strbeg,
2011                                    end_shift, &scream_pos, 1); /* last one */
2012                 if (!last)
2013                     last = scream_olds; /* Only one occurrence. */
2014                 /* we may be pointing at the wrong string */
2015                 else if (RX_MATCH_COPIED(prog))
2016                     s = strbeg + (s - SvPVX_const(sv));
2017             }
2018             else {
2019                 STRLEN len;
2020                 const char * const little = SvPV_const(float_real, len);
2021
2022                 if (SvTAIL(float_real)) {
2023                     if (memEQ(strend - len + 1, little, len - 1))
2024                         last = strend - len + 1;
2025                     else if (!multiline)
2026                         last = memEQ(strend - len, little, len)
2027                             ? strend - len : NULL;
2028                     else
2029                         goto find_last;
2030                 } else {
2031                   find_last:
2032                     if (len)
2033                         last = rninstr(s, strend, little, little + len);
2034                     else
2035                         last = strend;  /* matching "$" */
2036                 }
2037             }
2038             if (last == NULL) {
2039                 DEBUG_EXECUTE_r(
2040                     PerlIO_printf(Perl_debug_log,
2041                         "%sCan't trim the tail, match fails (should not happen)%s\n",
2042                         PL_colors[4], PL_colors[5]));
2043                 goto phooey; /* Should not happen! */
2044             }
2045             dontbother = strend - last + prog->float_min_offset;
2046         }
2047         if (minlen && (dontbother < minlen))
2048             dontbother = minlen - 1;
2049         strend -= dontbother;              /* this one's always in bytes! */
2050         /* We don't know much -- general case. */
2051         if (do_utf8) {
2052             for (;;) {
2053                 if (regtry(&reginfo, &s))
2054                     goto got_it;
2055                 if (s >= strend)
2056                     break;
2057                 s += UTF8SKIP(s);
2058             };
2059         }
2060         else {
2061             do {
2062                 if (regtry(&reginfo, &s))
2063                     goto got_it;
2064             } while (s++ < strend);
2065         }
2066     }
2067
2068     /* Failure. */
2069     goto phooey;
2070
2071 got_it:
2072     RX_MATCH_TAINTED_set(prog, PL_reg_flags & RF_tainted);
2073
2074     if (PL_reg_eval_set) {
2075         /* Preserve the current value of $^R */
2076         if (oreplsv != GvSV(PL_replgv))
2077             sv_setsv(oreplsv, GvSV(PL_replgv));/* So that when GvSV(replgv) is
2078                                                   restored, the value remains
2079                                                   the same. */
2080         restore_pos(aTHX_ prog);
2081     }
2082     if (prog->paren_names) 
2083         (void)hv_iterinit(prog->paren_names);
2084
2085     /* make sure $`, $&, $', and $digit will work later */
2086     if ( !(flags & REXEC_NOT_FIRST) ) {
2087         RX_MATCH_COPY_FREE(prog);
2088         if (flags & REXEC_COPY_STR) {
2089             const I32 i = PL_regeol - startpos + (stringarg - strbeg);
2090 #ifdef PERL_OLD_COPY_ON_WRITE
2091             if ((SvIsCOW(sv)
2092                  || (SvFLAGS(sv) & CAN_COW_MASK) == CAN_COW_FLAGS)) {
2093                 if (DEBUG_C_TEST) {
2094                     PerlIO_printf(Perl_debug_log,
2095                                   "Copy on write: regexp capture, type %d\n",
2096                                   (int) SvTYPE(sv));
2097                 }
2098                 prog->saved_copy = sv_setsv_cow(prog->saved_copy, sv);
2099                 prog->subbeg = (char *)SvPVX_const(prog->saved_copy);
2100                 assert (SvPOKp(prog->saved_copy));
2101             } else
2102 #endif
2103             {
2104                 RX_MATCH_COPIED_on(prog);
2105                 s = savepvn(strbeg, i);
2106                 prog->subbeg = s;
2107             }
2108             prog->sublen = i;
2109         }
2110         else {
2111             prog->subbeg = strbeg;
2112             prog->sublen = PL_regeol - strbeg;  /* strend may have been modified */
2113         }
2114     }
2115
2116     return 1;
2117
2118 phooey:
2119     DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "%sMatch failed%s\n",
2120                           PL_colors[4], PL_colors[5]));
2121     if (PL_reg_eval_set)
2122         restore_pos(aTHX_ prog);
2123     if (progi->swap) {
2124         /* we failed :-( roll it back */
2125         I32 *t;
2126         t = progi->swap->startp;
2127         progi->swap->startp = prog->startp;
2128         prog->startp = t;
2129         t = progi->swap->endp;
2130         progi->swap->endp = prog->endp;
2131         prog->endp = t;
2132     }
2133     return 0;
2134 }
2135
2136
2137
2138
2139 /*
2140  - regtry - try match at specific point
2141  */
2142 STATIC I32                      /* 0 failure, 1 success */
2143 S_regtry(pTHX_ regmatch_info *reginfo, char **startpos)
2144 {
2145     dVAR;
2146     register I32 *sp;
2147     register I32 *ep;
2148     CHECKPOINT lastcp;
2149     regexp *prog = reginfo->prog;
2150     RXi_GET_DECL(prog,progi);
2151     GET_RE_DEBUG_FLAGS_DECL;
2152     reginfo->cutpoint=NULL;
2153
2154     if ((prog->extflags & RXf_EVAL_SEEN) && !PL_reg_eval_set) {
2155         MAGIC *mg;
2156
2157         PL_reg_eval_set = RS_init;
2158         DEBUG_EXECUTE_r(DEBUG_s(
2159             PerlIO_printf(Perl_debug_log, "  setting stack tmpbase at %"IVdf"\n",
2160                           (IV)(PL_stack_sp - PL_stack_base));
2161             ));
2162         SAVESTACK_CXPOS();
2163         cxstack[cxstack_ix].blk_oldsp = PL_stack_sp - PL_stack_base;
2164         /* Otherwise OP_NEXTSTATE will free whatever on stack now.  */
2165         SAVETMPS;
2166         /* Apparently this is not needed, judging by wantarray. */
2167         /* SAVEI8(cxstack[cxstack_ix].blk_gimme);
2168            cxstack[cxstack_ix].blk_gimme = G_SCALAR; */
2169
2170         if (reginfo->sv) {
2171             /* Make $_ available to executed code. */
2172             if (reginfo->sv != DEFSV) {
2173                 SAVE_DEFSV;
2174                 DEFSV = reginfo->sv;
2175             }
2176         
2177             if (!(SvTYPE(reginfo->sv) >= SVt_PVMG && SvMAGIC(reginfo->sv)
2178                   && (mg = mg_find(reginfo->sv, PERL_MAGIC_regex_global)))) {
2179                 /* prepare for quick setting of pos */
2180 #ifdef PERL_OLD_COPY_ON_WRITE
2181                 if (SvIsCOW(reginfo->sv))
2182                     sv_force_normal_flags(reginfo->sv, 0);
2183 #endif
2184                 mg = sv_magicext(reginfo->sv, NULL, PERL_MAGIC_regex_global,
2185                                  &PL_vtbl_mglob, NULL, 0);
2186                 mg->mg_len = -1;
2187             }
2188             PL_reg_magic    = mg;
2189             PL_reg_oldpos   = mg->mg_len;
2190             SAVEDESTRUCTOR_X(restore_pos, prog);
2191         }
2192         if (!PL_reg_curpm) {
2193             Newxz(PL_reg_curpm, 1, PMOP);
2194 #ifdef USE_ITHREADS
2195             {
2196                 SV* const repointer = newSViv(0);
2197                 /* so we know which PL_regex_padav element is PL_reg_curpm */
2198                 SvFLAGS(repointer) |= SVf_BREAK;
2199                 av_push(PL_regex_padav,repointer);
2200                 PL_reg_curpm->op_pmoffset = av_len(PL_regex_padav);
2201                 PL_regex_pad = AvARRAY(PL_regex_padav);
2202             }
2203 #endif      
2204         }
2205         PM_SETRE(PL_reg_curpm, prog);
2206         PL_reg_oldcurpm = PL_curpm;
2207         PL_curpm = PL_reg_curpm;
2208         if (RX_MATCH_COPIED(prog)) {
2209             /*  Here is a serious problem: we cannot rewrite subbeg,
2210                 since it may be needed if this match fails.  Thus
2211                 $` inside (?{}) could fail... */
2212             PL_reg_oldsaved = prog->subbeg;
2213             PL_reg_oldsavedlen = prog->sublen;
2214 #ifdef PERL_OLD_COPY_ON_WRITE
2215             PL_nrs = prog->saved_copy;
2216 #endif
2217             RX_MATCH_COPIED_off(prog);
2218         }
2219         else
2220             PL_reg_oldsaved = NULL;
2221         prog->subbeg = PL_bostr;
2222         prog->sublen = PL_regeol - PL_bostr; /* strend may have been modified */
2223     }
2224     DEBUG_EXECUTE_r(PL_reg_starttry = *startpos);
2225     prog->startp[0] = *startpos - PL_bostr;
2226     PL_reginput = *startpos;
2227     PL_reglastparen = &prog->lastparen;
2228     PL_reglastcloseparen = &prog->lastcloseparen;
2229     prog->lastparen = 0;
2230     prog->lastcloseparen = 0;
2231     PL_regsize = 0;
2232     PL_regstartp = prog->startp;
2233     PL_regendp = prog->endp;
2234     if (PL_reg_start_tmpl <= prog->nparens) {
2235         PL_reg_start_tmpl = prog->nparens*3/2 + 3;
2236         if(PL_reg_start_tmp)
2237             Renew(PL_reg_start_tmp, PL_reg_start_tmpl, char*);
2238         else
2239             Newx(PL_reg_start_tmp, PL_reg_start_tmpl, char*);
2240     }
2241
2242     /* XXXX What this code is doing here?!!!  There should be no need
2243        to do this again and again, PL_reglastparen should take care of
2244        this!  --ilya*/
2245
2246     /* Tests pat.t#187 and split.t#{13,14} seem to depend on this code.
2247      * Actually, the code in regcppop() (which Ilya may be meaning by
2248      * PL_reglastparen), is not needed at all by the test suite
2249      * (op/regexp, op/pat, op/split), but that code is needed, oddly
2250      * enough, for building DynaLoader, or otherwise this
2251      * "Error: '*' not in typemap in DynaLoader.xs, line 164"
2252      * will happen.  Meanwhile, this code *is* needed for the
2253      * above-mentioned test suite tests to succeed.  The common theme
2254      * on those tests seems to be returning null fields from matches.
2255      * --jhi */
2256 #if 1
2257     sp = PL_regstartp;
2258     ep = PL_regendp;
2259     if (prog->nparens) {
2260         register I32 i;
2261         for (i = prog->nparens; i > (I32)*PL_reglastparen; i--) {
2262             *++sp = -1;
2263             *++ep = -1;
2264         }
2265     }
2266 #endif
2267     REGCP_SET(lastcp);
2268     if (regmatch(reginfo, progi->program + 1)) {
2269         PL_regendp[0] = PL_reginput - PL_bostr;
2270         return 1;
2271     }
2272     if (reginfo->cutpoint)
2273         *startpos= reginfo->cutpoint;
2274     REGCP_UNWIND(lastcp);
2275     return 0;
2276 }
2277
2278
2279 #define sayYES goto yes
2280 #define sayNO goto no
2281 #define sayNO_SILENT goto no_silent
2282
2283 /* we dont use STMT_START/END here because it leads to 
2284    "unreachable code" warnings, which are bogus, but distracting. */
2285 #define CACHEsayNO \
2286     if (ST.cache_mask) \
2287        PL_reg_poscache[ST.cache_offset] |= ST.cache_mask; \
2288     sayNO
2289
2290 /* this is used to determine how far from the left messages like
2291    'failed...' are printed. It should be set such that messages 
2292    are inline with the regop output that created them.
2293 */
2294 #define REPORT_CODE_OFF 32
2295
2296
2297 /* Make sure there is a test for this +1 options in re_tests */
2298 #define TRIE_INITAL_ACCEPT_BUFFLEN 4;
2299
2300 #define CHRTEST_UNINIT -1001 /* c1/c2 haven't been calculated yet */
2301 #define CHRTEST_VOID   -1000 /* the c1/c2 "next char" test should be skipped */
2302
2303 #define SLAB_FIRST(s) (&(s)->states[0])
2304 #define SLAB_LAST(s)  (&(s)->states[PERL_REGMATCH_SLAB_SLOTS-1])
2305
2306 /* grab a new slab and return the first slot in it */
2307
2308 STATIC regmatch_state *
2309 S_push_slab(pTHX)
2310 {
2311 #if PERL_VERSION < 9
2312     dMY_CXT;
2313 #endif
2314     regmatch_slab *s = PL_regmatch_slab->next;
2315     if (!s) {
2316         Newx(s, 1, regmatch_slab);
2317         s->prev = PL_regmatch_slab;
2318         s->next = NULL;
2319         PL_regmatch_slab->next = s;
2320     }
2321     PL_regmatch_slab = s;
2322     return SLAB_FIRST(s);
2323 }
2324
2325
2326 /* push a new state then goto it */
2327
2328 #define PUSH_STATE_GOTO(state, node) \
2329     scan = node; \
2330     st->resume_state = state; \
2331     goto push_state;
2332
2333 /* push a new state with success backtracking, then goto it */
2334
2335 #define PUSH_YES_STATE_GOTO(state, node) \
2336     scan = node; \
2337     st->resume_state = state; \
2338     goto push_yes_state;
2339
2340
2341
2342 /*
2343
2344 regmatch() - main matching routine
2345
2346 This is basically one big switch statement in a loop. We execute an op,
2347 set 'next' to point the next op, and continue. If we come to a point which
2348 we may need to backtrack to on failure such as (A|B|C), we push a
2349 backtrack state onto the backtrack stack. On failure, we pop the top
2350 state, and re-enter the loop at the state indicated. If there are no more
2351 states to pop, we return failure.
2352
2353 Sometimes we also need to backtrack on success; for example /A+/, where
2354 after successfully matching one A, we need to go back and try to
2355 match another one; similarly for lookahead assertions: if the assertion
2356 completes successfully, we backtrack to the state just before the assertion
2357 and then carry on.  In these cases, the pushed state is marked as
2358 'backtrack on success too'. This marking is in fact done by a chain of
2359 pointers, each pointing to the previous 'yes' state. On success, we pop to
2360 the nearest yes state, discarding any intermediate failure-only states.
2361 Sometimes a yes state is pushed just to force some cleanup code to be
2362 called at the end of a successful match or submatch; e.g. (??{$re}) uses
2363 it to free the inner regex.
2364
2365 Note that failure backtracking rewinds the cursor position, while
2366 success backtracking leaves it alone.
2367
2368 A pattern is complete when the END op is executed, while a subpattern
2369 such as (?=foo) is complete when the SUCCESS op is executed. Both of these
2370 ops trigger the "pop to last yes state if any, otherwise return true"
2371 behaviour.
2372
2373 A common convention in this function is to use A and B to refer to the two
2374 subpatterns (or to the first nodes thereof) in patterns like /A*B/: so A is
2375 the subpattern to be matched possibly multiple times, while B is the entire
2376 rest of the pattern. Variable and state names reflect this convention.
2377
2378 The states in the main switch are the union of ops and failure/success of
2379 substates associated with with that op.  For example, IFMATCH is the op
2380 that does lookahead assertions /(?=A)B/ and so the IFMATCH state means
2381 'execute IFMATCH'; while IFMATCH_A is a state saying that we have just
2382 successfully matched A and IFMATCH_A_fail is a state saying that we have
2383 just failed to match A. Resume states always come in pairs. The backtrack
2384 state we push is marked as 'IFMATCH_A', but when that is popped, we resume
2385 at IFMATCH_A or IFMATCH_A_fail, depending on whether we are backtracking
2386 on success or failure.
2387
2388 The struct that holds a backtracking state is actually a big union, with
2389 one variant for each major type of op. The variable st points to the
2390 top-most backtrack struct. To make the code clearer, within each
2391 block of code we #define ST to alias the relevant union.
2392
2393 Here's a concrete example of a (vastly oversimplified) IFMATCH
2394 implementation:
2395
2396     switch (state) {
2397     ....
2398
2399 #define ST st->u.ifmatch
2400
2401     case IFMATCH: // we are executing the IFMATCH op, (?=A)B
2402         ST.foo = ...; // some state we wish to save
2403         ...
2404         // push a yes backtrack state with a resume value of
2405         // IFMATCH_A/IFMATCH_A_fail, then continue execution at the
2406         // first node of A:
2407         PUSH_YES_STATE_GOTO(IFMATCH_A, A);
2408         // NOTREACHED
2409
2410     case IFMATCH_A: // we have successfully executed A; now continue with B
2411         next = B;
2412         bar = ST.foo; // do something with the preserved value
2413         break;
2414
2415     case IFMATCH_A_fail: // A failed, so the assertion failed
2416         ...;   // do some housekeeping, then ...
2417         sayNO; // propagate the failure
2418
2419 #undef ST
2420
2421     ...
2422     }
2423
2424 For any old-timers reading this who are familiar with the old recursive
2425 approach, the code above is equivalent to:
2426
2427     case IFMATCH: // we are executing the IFMATCH op, (?=A)B
2428     {
2429         int foo = ...
2430         ...
2431         if (regmatch(A)) {
2432             next = B;
2433             bar = foo;
2434             break;
2435         }
2436         ...;   // do some housekeeping, then ...
2437         sayNO; // propagate the failure
2438     }
2439
2440 The topmost backtrack state, pointed to by st, is usually free. If you
2441 want to claim it, populate any ST.foo fields in it with values you wish to
2442 save, then do one of
2443
2444         PUSH_STATE_GOTO(resume_state, node);
2445         PUSH_YES_STATE_GOTO(resume_state, node);
2446
2447 which sets that backtrack state's resume value to 'resume_state', pushes a
2448 new free entry to the top of the backtrack stack, then goes to 'node'.
2449 On backtracking, the free slot is popped, and the saved state becomes the
2450 new free state. An ST.foo field in this new top state can be temporarily
2451 accessed to retrieve values, but once the main loop is re-entered, it
2452 becomes available for reuse.
2453
2454 Note that the depth of the backtrack stack constantly increases during the
2455 left-to-right execution of the pattern, rather than going up and down with
2456 the pattern nesting. For example the stack is at its maximum at Z at the
2457 end of the pattern, rather than at X in the following:
2458
2459     /(((X)+)+)+....(Y)+....Z/
2460
2461 The only exceptions to this are lookahead/behind assertions and the cut,
2462 (?>A), which pop all the backtrack states associated with A before
2463 continuing.
2464  
2465 Bascktrack state structs are allocated in slabs of about 4K in size.
2466 PL_regmatch_state and st always point to the currently active state,
2467 and PL_regmatch_slab points to the slab currently containing
2468 PL_regmatch_state.  The first time regmatch() is called, the first slab is
2469 allocated, and is never freed until interpreter destruction. When the slab
2470 is full, a new one is allocated and chained to the end. At exit from
2471 regmatch(), slabs allocated since entry are freed.
2472
2473 */
2474  
2475
2476 #define DEBUG_STATE_pp(pp)                                  \
2477     DEBUG_STATE_r({                                         \
2478         DUMP_EXEC_POS(locinput, scan, do_utf8);             \
2479         PerlIO_printf(Perl_debug_log,                       \
2480             "    %*s"pp" %s%s%s%s%s\n",                     \
2481             depth*2, "",                                    \
2482             reg_name[st->resume_state],                     \
2483             ((st==yes_state||st==mark_state) ? "[" : ""),   \
2484             ((st==yes_state) ? "Y" : ""),                   \
2485             ((st==mark_state) ? "M" : ""),                  \
2486             ((st==yes_state||st==mark_state) ? "]" : "")    \
2487         );                                                  \
2488     });
2489
2490
2491 #define REG_NODE_NUM(x) ((x) ? (int)((x)-prog) : -1)
2492
2493 #ifdef DEBUGGING
2494
2495 STATIC void
2496 S_debug_start_match(pTHX_ const regexp *prog, const bool do_utf8, 
2497     const char *start, const char *end, const char *blurb)
2498 {
2499     const bool utf8_pat= prog->extflags & RXf_UTF8 ? 1 : 0;
2500     if (!PL_colorset)   
2501             reginitcolors();    
2502     {
2503         RE_PV_QUOTED_DECL(s0, utf8_pat, PERL_DEBUG_PAD_ZERO(0), 
2504             prog->precomp, prog->prelen, 60);   
2505         
2506         RE_PV_QUOTED_DECL(s1, do_utf8, PERL_DEBUG_PAD_ZERO(1), 
2507             start, end - start, 60); 
2508         
2509         PerlIO_printf(Perl_debug_log, 
2510             "%s%s REx%s %s against %s\n", 
2511                        PL_colors[4], blurb, PL_colors[5], s0, s1); 
2512         
2513         if (do_utf8||utf8_pat) 
2514             PerlIO_printf(Perl_debug_log, "UTF-8 %s%s%s...\n",
2515                 utf8_pat ? "pattern" : "",
2516                 utf8_pat && do_utf8 ? " and " : "",
2517                 do_utf8 ? "string" : ""
2518             ); 
2519     }
2520 }
2521
2522 STATIC void
2523 S_dump_exec_pos(pTHX_ const char *locinput, 
2524                       const regnode *scan, 
2525                       const char *loc_regeol, 
2526                       const char *loc_bostr, 
2527                       const char *loc_reg_starttry,
2528                       const bool do_utf8)
2529 {
2530     const int docolor = *PL_colors[0] || *PL_colors[2] || *PL_colors[4];
2531     const int taill = (docolor ? 10 : 7); /* 3 chars for "> <" */
2532     int l = (loc_regeol - locinput) > taill ? taill : (loc_regeol - locinput);
2533     /* The part of the string before starttry has one color
2534        (pref0_len chars), between starttry and current
2535        position another one (pref_len - pref0_len chars),
2536        after the current position the third one.
2537        We assume that pref0_len <= pref_len, otherwise we
2538        decrease pref0_len.  */
2539     int pref_len = (locinput - loc_bostr) > (5 + taill) - l
2540         ? (5 + taill) - l : locinput - loc_bostr;
2541     int pref0_len;
2542
2543     while (do_utf8 && UTF8_IS_CONTINUATION(*(U8*)(locinput - pref_len)))
2544         pref_len++;
2545     pref0_len = pref_len  - (locinput - loc_reg_starttry);
2546     if (l + pref_len < (5 + taill) && l < loc_regeol - locinput)
2547         l = ( loc_regeol - locinput > (5 + taill) - pref_len
2548               ? (5 + taill) - pref_len : loc_regeol - locinput);
2549     while (do_utf8 && UTF8_IS_CONTINUATION(*(U8*)(locinput + l)))
2550         l--;
2551     if (pref0_len < 0)
2552         pref0_len = 0;
2553     if (pref0_len > pref_len)
2554         pref0_len = pref_len;
2555     {
2556         const int is_uni = (do_utf8 && OP(scan) != CANY) ? 1 : 0;
2557
2558         RE_PV_COLOR_DECL(s0,len0,is_uni,PERL_DEBUG_PAD(0),
2559             (locinput - pref_len),pref0_len, 60, 4, 5);
2560         
2561         RE_PV_COLOR_DECL(s1,len1,is_uni,PERL_DEBUG_PAD(1),
2562                     (locinput - pref_len + pref0_len),
2563                     pref_len - pref0_len, 60, 2, 3);
2564         
2565         RE_PV_COLOR_DECL(s2,len2,is_uni,PERL_DEBUG_PAD(2),
2566                     locinput, loc_regeol - locinput, 10, 0, 1);
2567
2568         const STRLEN tlen=len0+len1+len2;
2569         PerlIO_printf(Perl_debug_log,
2570                     "%4"IVdf" <%.*s%.*s%s%.*s>%*s|",
2571                     (IV)(locinput - loc_bostr),
2572                     len0, s0,
2573                     len1, s1,
2574                     (docolor ? "" : "> <"),
2575                     len2, s2,
2576                     (int)(tlen > 19 ? 0 :  19 - tlen),
2577                     "");
2578     }
2579 }
2580
2581 #endif
2582
2583 /* reg_check_named_buff_matched()
2584  * Checks to see if a named buffer has matched. The data array of 
2585  * buffer numbers corresponding to the buffer is expected to reside
2586  * in the regexp->data->data array in the slot stored in the ARG() of
2587  * node involved. Note that this routine doesn't actually care about the
2588  * name, that information is not preserved from compilation to execution.
2589  * Returns the index of the leftmost defined buffer with the given name
2590  * or 0 if non of the buffers matched.
2591  */
2592 STATIC I32
2593 S_reg_check_named_buff_matched(pTHX_ const regexp *rex, const regnode *scan) {
2594     I32 n;
2595     RXi_GET_DECL(rex,rexi);
2596     SV *sv_dat=(SV*)rexi->data->data[ ARG( scan ) ];
2597     I32 *nums=(I32*)SvPVX(sv_dat);
2598     for ( n=0; n<SvIVX(sv_dat); n++ ) {
2599         if ((I32)*PL_reglastparen >= nums[n] &&
2600             PL_regendp[nums[n]] != -1)
2601         {
2602             return nums[n];
2603         }
2604     }
2605     return 0;
2606 }
2607
2608 STATIC I32                      /* 0 failure, 1 success */
2609 S_regmatch(pTHX_ regmatch_info *reginfo, regnode *prog)
2610 {
2611 #if PERL_VERSION < 9
2612     dMY_CXT;
2613 #endif
2614     dVAR;
2615     register const bool do_utf8 = PL_reg_match_utf8;
2616     const U32 uniflags = UTF8_ALLOW_DEFAULT;
2617
2618     regexp *rex = reginfo->prog;
2619     RXi_GET_DECL(rex,rexi);
2620     
2621     regmatch_slab  *orig_slab;
2622     regmatch_state *orig_state;
2623
2624     /* the current state. This is a cached copy of PL_regmatch_state */
2625     register regmatch_state *st;
2626
2627     /* cache heavy used fields of st in registers */
2628     register regnode *scan;
2629     register regnode *next;
2630     register U32 n = 0; /* general value; init to avoid compiler warning */
2631     register I32 ln = 0; /* len or last;  init to avoid compiler warning */
2632     register char *locinput = PL_reginput;
2633     register I32 nextchr;   /* is always set to UCHARAT(locinput) */
2634
2635     bool result = 0;        /* return value of S_regmatch */
2636     int depth = 0;          /* depth of backtrack stack */
2637     int nochange_depth = 0; /* depth of GOSUB recursion with nochange*/
2638     regmatch_state *yes_state = NULL; /* state to pop to on success of
2639                                                             subpattern */
2640     /* mark_state piggy backs on the yes_state logic so that when we unwind 
2641        the stack on success we can update the mark_state as we go */
2642     regmatch_state *mark_state = NULL; /* last mark state we have seen */
2643     
2644     regmatch_state *cur_eval = NULL; /* most recent EVAL_AB state */
2645     struct regmatch_state  *cur_curlyx = NULL; /* most recent curlyx */
2646     U32 state_num;
2647     bool no_final = 0;      /* prevent failure from backtracking? */
2648     bool do_cutgroup = 0;   /* no_final only until next branch/trie entry */
2649     char *startpoint = PL_reginput;
2650     SV *popmark = NULL;     /* are we looking for a mark? */
2651     SV *sv_commit = NULL;   /* last mark name seen in failure */
2652     SV *sv_yes_mark = NULL; /* last mark name we have seen 
2653                                during a successfull match */
2654     U32 lastopen = 0;       /* last open we saw */
2655     bool has_cutgroup = RX_HAS_CUTGROUP(rex) ? 1 : 0;   
2656                
2657     
2658     /* these three flags are set by various ops to signal information to
2659      * the very next op. They have a useful lifetime of exactly one loop
2660      * iteration, and are not preserved or restored by state pushes/pops
2661      */
2662     bool sw = 0;            /* the condition value in (?(cond)a|b) */
2663     bool minmod = 0;        /* the next "{n,m}" is a "{n,m}?" */
2664     int logical = 0;        /* the following EVAL is:
2665                                 0: (?{...})
2666                                 1: (?(?{...})X|Y)
2667                                 2: (??{...})
2668                                or the following IFMATCH/UNLESSM is:
2669                                 false: plain (?=foo)
2670                                 true:  used as a condition: (?(?=foo))
2671                             */
2672
2673 #ifdef DEBUGGING
2674     GET_RE_DEBUG_FLAGS_DECL;
2675 #endif
2676
2677     DEBUG_OPTIMISE_r( {    
2678             PerlIO_printf(Perl_debug_log,"regmatch start\n");
2679     });
2680     /* on first ever call to regmatch, allocate first slab */
2681     if (!PL_regmatch_slab) {
2682         Newx(PL_regmatch_slab, 1, regmatch_slab);
2683         PL_regmatch_slab->prev = NULL;
2684         PL_regmatch_slab->next = NULL;
2685         PL_regmatch_state = SLAB_FIRST(PL_regmatch_slab);
2686     }
2687
2688     /* remember current high-water mark for exit */
2689     /* XXX this should be done with SAVE* instead */
2690     orig_slab  = PL_regmatch_slab;
2691     orig_state = PL_regmatch_state;
2692
2693     /* grab next free state slot */
2694     st = ++PL_regmatch_state;
2695     if (st >  SLAB_LAST(PL_regmatch_slab))
2696         st = PL_regmatch_state = S_push_slab(aTHX);
2697
2698     /* Note that nextchr is a byte even in UTF */
2699     nextchr = UCHARAT(locinput);
2700     scan = prog;
2701     while (scan != NULL) {
2702
2703         DEBUG_EXECUTE_r( {
2704             SV * const prop = sv_newmortal();
2705             regnode *rnext=regnext(scan);
2706             DUMP_EXEC_POS( locinput, scan, do_utf8 );
2707             regprop(rex, prop, scan);
2708             
2709             PerlIO_printf(Perl_debug_log,
2710                     "%3"IVdf":%*s%s(%"IVdf")\n",
2711                     (IV)(scan - rexi->program), depth*2, "",
2712                     SvPVX_const(prop),
2713                     (PL_regkind[OP(scan)] == END || !rnext) ? 
2714                         0 : (IV)(rnext - rexi->program));
2715         });
2716
2717         next = scan + NEXT_OFF(scan);
2718         if (next == scan)
2719             next = NULL;
2720         state_num = OP(scan);
2721
2722       reenter_switch:
2723         switch (state_num) {
2724         case BOL:
2725             if (locinput == PL_bostr)
2726             {
2727                 /* reginfo->till = reginfo->bol; */
2728                 break;
2729             }
2730             sayNO;
2731         case MBOL:
2732             if (locinput == PL_bostr ||
2733                 ((nextchr || locinput < PL_regeol) && locinput[-1] == '\n'))
2734             {
2735                 break;
2736             }
2737             sayNO;
2738         case SBOL:
2739             if (locinput == PL_bostr)
2740                 break;
2741             sayNO;
2742         case GPOS:
2743             if (locinput == reginfo->ganch)
2744                 break;
2745             sayNO;
2746
2747         case KEEPS:
2748             /* update the startpoint */
2749             st->u.keeper.val = PL_regstartp[0];
2750             PL_reginput = locinput;
2751             PL_regstartp[0] = locinput - PL_bostr;
2752             PUSH_STATE_GOTO(KEEPS_next, next);
2753             /*NOT-REACHED*/
2754         case KEEPS_next_fail:
2755             /* rollback the start point change */
2756             PL_regstartp[0] = st->u.keeper.val;
2757             sayNO_SILENT;
2758             /*NOT-REACHED*/
2759         case EOL:
2760                 goto seol;
2761         case MEOL:
2762             if ((nextchr || locinput < PL_regeol) && nextchr != '\n')
2763                 sayNO;
2764             break;
2765         case SEOL:
2766           seol:
2767             if ((nextchr || locinput < PL_regeol) && nextchr != '\n')
2768                 sayNO;
2769             if (PL_regeol - locinput > 1)
2770                 sayNO;
2771             break;
2772         case EOS:
2773             if (PL_regeol != locinput)
2774                 sayNO;
2775             break;
2776         case SANY:
2777             if (!nextchr && locinput >= PL_regeol)
2778                 sayNO;
2779             if (do_utf8) {
2780                 locinput += PL_utf8skip[nextchr];
2781                 if (locinput > PL_regeol)
2782                     sayNO;
2783                 nextchr = UCHARAT(locinput);
2784             }
2785             else
2786                 nextchr = UCHARAT(++locinput);
2787             break;
2788         case CANY:
2789             if (!nextchr && locinput >= PL_regeol)
2790                 sayNO;
2791             nextchr = UCHARAT(++locinput);
2792             break;
2793         case REG_ANY:
2794             if ((!nextchr && locinput >= PL_regeol) || nextchr == '\n')
2795                 sayNO;
2796             if (do_utf8) {
2797                 locinput += PL_utf8skip[nextchr];
2798                 if (locinput > PL_regeol)
2799                     sayNO;
2800                 nextchr = UCHARAT(locinput);
2801             }
2802             else
2803                 nextchr = UCHARAT(++locinput);
2804             break;
2805
2806 #undef  ST
2807 #define ST st->u.trie
2808         case TRIEC:
2809             /* In this case the charclass data is available inline so
2810                we can fail fast without a lot of extra overhead. 
2811              */
2812             if (scan->flags == EXACT || !do_utf8) {
2813                 if(!ANYOF_BITMAP_TEST(scan, *locinput)) {
2814                     DEBUG_EXECUTE_r(
2815                         PerlIO_printf(Perl_debug_log,
2816                                   "%*s  %sfailed to match trie start class...%s\n",
2817                                   REPORT_CODE_OFF+depth*2, "", PL_colors[4], PL_colors[5])
2818                     );
2819                     sayNO_SILENT;
2820                     /* NOTREACHED */
2821                 }                       
2822             }
2823             /* FALL THROUGH */
2824         case TRIE:
2825             {
2826                 /* what type of TRIE am I? (utf8 makes this contextual) */
2827                 const enum { trie_plain, trie_utf8, trie_utf8_fold }
2828                     trie_type = do_utf8 ?
2829                           (scan->flags == EXACT ? trie_utf8 : trie_utf8_fold)
2830                         : trie_plain;
2831
2832                 /* what trie are we using right now */
2833                 reg_trie_data * const trie
2834                     = (reg_trie_data*)rexi->data->data[ ARG( scan ) ];
2835                 HV * widecharmap = (HV *)rexi->data->data[ ARG( scan ) + 1 ];
2836                 U32 state = trie->startstate;
2837
2838                 if (trie->bitmap && trie_type != trie_utf8_fold &&
2839                     !TRIE_BITMAP_TEST(trie,*locinput)
2840                 ) {
2841                     if (trie->states[ state ].wordnum) {
2842                          DEBUG_EXECUTE_r(
2843                             PerlIO_printf(Perl_debug_log,
2844                                           "%*s  %smatched empty string...%s\n",
2845                                           REPORT_CODE_OFF+depth*2, "", PL_colors[4], PL_colors[5])
2846                         );
2847                         break;
2848                     } else {
2849                         DEBUG_EXECUTE_r(
2850                             PerlIO_printf(Perl_debug_log,
2851                                           "%*s  %sfailed to match trie start class...%s\n",
2852                                           REPORT_CODE_OFF+depth*2, "", PL_colors[4], PL_colors[5])
2853                         );
2854                         sayNO_SILENT;
2855                    }
2856                 }
2857
2858             { 
2859                 U8 *uc = ( U8* )locinput;
2860
2861                 STRLEN len = 0;
2862                 STRLEN foldlen = 0;
2863                 U8 *uscan = (U8*)NULL;
2864                 STRLEN bufflen=0;
2865                 SV *sv_accept_buff = NULL;
2866                 U8 foldbuf[ UTF8_MAXBYTES_CASE + 1 ];
2867
2868                 ST.accepted = 0; /* how many accepting states we have seen */
2869                 ST.B = next;
2870                 ST.jump = trie->jump;
2871                 ST.me = scan;
2872                 
2873                 /*
2874                    traverse the TRIE keeping track of all accepting states
2875                    we transition through until we get to a failing node.
2876                 */
2877
2878                 while ( state && uc <= (U8*)PL_regeol ) {
2879                     U32 base = trie->states[ state ].trans.base;
2880                     UV uvc = 0;
2881                     U16 charid;
2882                     /* We use charid to hold the wordnum as we don't use it
2883                        for charid until after we have done the wordnum logic. 
2884                        We define an alias just so that the wordnum logic reads
2885                        more naturally. */
2886
2887 #define got_wordnum charid
2888                     got_wordnum = trie->states[ state ].wordnum;
2889
2890                     if ( got_wordnum ) {
2891                         if ( ! ST.accepted ) {
2892                             ENTER;
2893                             SAVETMPS;
2894                             bufflen = TRIE_INITAL_ACCEPT_BUFFLEN;
2895                             sv_accept_buff=newSV(bufflen *
2896                                             sizeof(reg_trie_accepted) - 1);
2897                             SvCUR_set(sv_accept_buff, 0);
2898                             SvPOK_on(sv_accept_buff);
2899                             sv_2mortal(sv_accept_buff);
2900                             SAVETMPS;
2901                             ST.accept_buff =
2902                                 (reg_trie_accepted*)SvPV_nolen(sv_accept_buff );
2903                         }
2904                         do {
2905                             if (ST.accepted >= bufflen) {
2906                                 bufflen *= 2;
2907                                 ST.accept_buff =(reg_trie_accepted*)
2908                                     SvGROW(sv_accept_buff,
2909                                         bufflen * sizeof(reg_trie_accepted));
2910                             }
2911                             SvCUR_set(sv_accept_buff,SvCUR(sv_accept_buff)
2912                                 + sizeof(reg_trie_accepted));
2913
2914
2915                             ST.accept_buff[ST.accepted].wordnum = got_wordnum;
2916                             ST.accept_buff[ST.accepted].endpos = uc;
2917                             ++ST.accepted;
2918                         } while (trie->nextword && (got_wordnum= trie->nextword[got_wordnum]));
2919                     }
2920 #undef got_wordnum 
2921
2922                     DEBUG_TRIE_EXECUTE_r({
2923                                 DUMP_EXEC_POS( (char *)uc, scan, do_utf8 );
2924                                 PerlIO_printf( Perl_debug_log,
2925                                     "%*s  %sState: %4"UVxf" Accepted: %4"UVxf" ",
2926                                     2+depth * 2, "", PL_colors[4],
2927                                     (UV)state, (UV)ST.accepted );
2928                     });
2929
2930                     if ( base ) {
2931                         REXEC_TRIE_READ_CHAR(trie_type, trie, widecharmap, uc,
2932                                              uscan, len, uvc, charid, foldlen,
2933                                              foldbuf, uniflags);
2934
2935                         if (charid &&
2936                              (base + charid > trie->uniquecharcount )
2937                              && (base + charid - 1 - trie->uniquecharcount
2938                                     < trie->lasttrans)
2939                              && trie->trans[base + charid - 1 -
2940                                     trie->uniquecharcount].check == state)
2941                         {
2942                             state = trie->trans[base + charid - 1 -
2943                                 trie->uniquecharcount ].next;
2944                         }
2945                         else {
2946                             state = 0;
2947                         }
2948                         uc += len;
2949
2950                     }
2951                     else {
2952                         state = 0;
2953                     }
2954                     DEBUG_TRIE_EXECUTE_r(
2955                         PerlIO_printf( Perl_debug_log,
2956                             "Charid:%3x CP:%4"UVxf" After State: %4"UVxf"%s\n",
2957                             charid, uvc, (UV)state, PL_colors[5] );
2958                     );
2959                 }
2960                 if (!ST.accepted )
2961                    sayNO;
2962
2963                 DEBUG_EXECUTE_r(
2964                     PerlIO_printf( Perl_debug_log,
2965                         "%*s  %sgot %"IVdf" possible matches%s\n",
2966                         REPORT_CODE_OFF + depth * 2, "",
2967                         PL_colors[4], (IV)ST.accepted, PL_colors[5] );
2968                 );
2969             }}
2970
2971             /* FALL THROUGH */
2972         case TRIE_next_fail: /* we failed - try next alterative */
2973             if (do_cutgroup) {
2974                 do_cutgroup = 0;
2975                 no_final = 0;
2976             }
2977             if ( ST.accepted == 1 ) {
2978                 /* only one choice left - just continue */
2979                 DEBUG_EXECUTE_r({
2980                     AV *const trie_words
2981                         = (AV *) rexi->data->data[ARG(ST.me)+TRIE_WORDS_OFFSET];
2982                     SV ** const tmp = av_fetch( trie_words, 
2983                         ST.accept_buff[ 0 ].wordnum-1, 0 );
2984                     SV *sv= tmp ? sv_newmortal() : NULL;
2985                     
2986                     PerlIO_printf( Perl_debug_log,
2987                         "%*s  %sonly one match left: #%d <%s>%s\n",
2988                         REPORT_CODE_OFF+depth*2, "", PL_colors[4],
2989                         ST.accept_buff[ 0 ].wordnum,
2990                         tmp ? pv_pretty(sv, SvPV_nolen_const(*tmp), SvCUR(*tmp), 0, 
2991                                 PL_colors[0], PL_colors[1],
2992                                 (SvUTF8(*tmp) ? PERL_PV_ESCAPE_UNI : 0)
2993                             ) 
2994                         : "not compiled under -Dr",
2995                         PL_colors[5] );
2996                 });
2997                 PL_reginput = (char *)ST.accept_buff[ 0 ].endpos;
2998                 /* in this case we free tmps/leave before we call regmatch
2999                    as we wont be using accept_buff again. */
3000                 
3001                 locinput = PL_reginput;
3002                 nextchr = UCHARAT(locinput);
3003                 if ( !ST.jump || !ST.jump[ST.accept_buff[0].wordnum]) 
3004                     scan = ST.B;
3005                 else
3006                     scan = ST.me + ST.jump[ST.accept_buff[0].wordnum];
3007                 if (!has_cutgroup) {
3008                     FREETMPS;
3009                     LEAVE;
3010                 } else {
3011                     ST.accepted--;
3012                     PUSH_YES_STATE_GOTO(TRIE_next, scan);
3013                 }
3014                 
3015                 continue; /* execute rest of RE */
3016             }
3017
3018             if (!ST.accepted-- ) {
3019                 DEBUG_EXECUTE_r({
3020                     PerlIO_printf( Perl_debug_log,
3021                         "%*s  %sTRIE failed...%s\n",
3022                         REPORT_CODE_OFF+depth*2, "", 
3023                         PL_colors[4],
3024                         PL_colors[5] );
3025                 });
3026                 FREETMPS;
3027                 LEAVE;
3028                 sayNO_SILENT;
3029             }
3030
3031             /*
3032                There are at least two accepting states left.  Presumably
3033                the number of accepting states is going to be low,
3034                typically two. So we simply scan through to find the one
3035                with lowest wordnum.  Once we find it, we swap the last
3036                state into its place and decrement the size. We then try to
3037                match the rest of the pattern at the point where the word
3038                ends. If we succeed, control just continues along the
3039                regex; if we fail we return here to try the next accepting
3040                state
3041              */
3042
3043             {
3044                 U32 best = 0;
3045                 U32 cur;
3046                 for( cur = 1 ; cur <= ST.accepted ; cur++ ) {
3047                     DEBUG_TRIE_EXECUTE_r(
3048                         PerlIO_printf( Perl_debug_log,
3049                             "%*s  %sgot %"IVdf" (%d) as best, looking at %"IVdf" (%d)%s\n",
3050                             REPORT_CODE_OFF + depth * 2, "", PL_colors[4],
3051                             (IV)best, ST.accept_buff[ best ].wordnum, (IV)cur,
3052                             ST.accept_buff[ cur ].wordnum, PL_colors[5] );
3053                     );
3054
3055                     if (ST.accept_buff[cur].wordnum <
3056                             ST.accept_buff[best].wordnum)
3057                         best = cur;
3058                 }
3059
3060                 DEBUG_EXECUTE_r({
3061                     AV *const trie_words
3062                         = (AV *) rexi->data->data[ARG(ST.me)+TRIE_WORDS_OFFSET];
3063                     SV ** const tmp = av_fetch( trie_words, 
3064                         ST.accept_buff[ best ].wordnum - 1, 0 );
3065                     regnode *nextop=(!ST.jump || !ST.jump[ST.accept_buff[best].wordnum]) ? 
3066                                     ST.B : 
3067                                     ST.me + ST.jump[ST.accept_buff[best].wordnum];    
3068                     SV *sv= tmp ? sv_newmortal() : NULL;
3069                     
3070                     PerlIO_printf( Perl_debug_log, 
3071                         "%*s  %strying alternation #%d <%s> at node #%d %s\n",
3072                         REPORT_CODE_OFF+depth*2, "", PL_colors[4],
3073                         ST.accept_buff[best].wordnum,
3074                         tmp ? pv_pretty(sv, SvPV_nolen_const(*tmp), SvCUR(*tmp), 0, 
3075                                 PL_colors[0], PL_colors[1],
3076                                 (SvUTF8(*tmp) ? PERL_PV_ESCAPE_UNI : 0)
3077                             ) : "not compiled under -Dr", 
3078                             REG_NODE_NUM(nextop),
3079                         PL_colors[5] );
3080                 });
3081
3082                 if ( best<ST.accepted ) {
3083                     reg_trie_accepted tmp = ST.accept_buff[ best ];
3084                     ST.accept_buff[ best ] = ST.accept_buff[ ST.accepted ];
3085                     ST.accept_buff[ ST.accepted ] = tmp;
3086                     best = ST.accepted;
3087                 }
3088                 PL_reginput = (char *)ST.accept_buff[ best ].endpos;
3089                 if ( !ST.jump || !ST.jump[ST.accept_buff[best].wordnum]) {
3090                     scan = ST.B;
3091                     /* NOTREACHED */
3092                 } else {
3093                     scan = ST.me + ST.jump[ST.accept_buff[best].wordnum];
3094                     /* NOTREACHED */
3095                 }
3096                 if (has_cutgroup) {
3097                     PUSH_YES_STATE_GOTO(TRIE_next, scan);    
3098                     /* NOTREACHED */
3099                 } else {
3100                     PUSH_STATE_GOTO(TRIE_next, scan);
3101                     /* NOTREACHED */
3102                 }
3103                 /* NOTREACHED */
3104             }
3105             /* NOTREACHED */
3106         case TRIE_next:
3107             FREETMPS;
3108             LEAVE;
3109             sayYES;
3110 #undef  ST
3111
3112         case EXACT: {
3113             char *s = STRING(scan);
3114             ln = STR_LEN(scan);
3115             if (do_utf8 != UTF) {
3116                 /* The target and the pattern have differing utf8ness. */
3117                 char *l = locinput;
3118                 const char * const e = s + ln;
3119
3120                 if (do_utf8) {
3121                     /* The target is utf8, the pattern is not utf8. */
3122                     while (s < e) {
3123                         STRLEN ulen;
3124                         if (l >= PL_regeol)
3125                              sayNO;
3126                         if (NATIVE_TO_UNI(*(U8*)s) !=
3127                             utf8n_to_uvuni((U8*)l, UTF8_MAXBYTES, &ulen,
3128                                             uniflags))
3129                              sayNO;
3130                         l += ulen;
3131                         s ++;
3132                     }
3133                 }
3134                 else {
3135                     /* The target is not utf8, the pattern is utf8. */
3136                     while (s < e) {
3137                         STRLEN ulen;
3138                         if (l >= PL_regeol)
3139                             sayNO;
3140                         if (NATIVE_TO_UNI(*((U8*)l)) !=
3141                             utf8n_to_uvuni((U8*)s, UTF8_MAXBYTES, &ulen,
3142                                            uniflags))
3143                             sayNO;
3144                         s += ulen;
3145                         l ++;
3146                     }
3147                 }
3148                 locinput = l;
3149                 nextchr = UCHARAT(locinput);
3150                 break;
3151             }
3152             /* The target and the pattern have the same utf8ness. */
3153             /* Inline the first character, for speed. */
3154             if (UCHARAT(s) != nextchr)
3155                 sayNO;
3156             if (PL_regeol - locinput < ln)
3157                 sayNO;
3158             if (ln > 1 && memNE(s, locinput, ln))
3159                 sayNO;
3160             locinput += ln;
3161             nextchr = UCHARAT(locinput);
3162             break;
3163             }
3164         case EXACTFL:
3165             PL_reg_flags |= RF_tainted;
3166             /* FALL THROUGH */
3167         case EXACTF: {
3168             char * const s = STRING(scan);
3169             ln = STR_LEN(scan);
3170
3171             if (do_utf8 || UTF) {
3172               /* Either target or the pattern are utf8. */
3173                 const char * const l = locinput;
3174                 char *e = PL_regeol;
3175
3176                 if (ibcmp_utf8(s, 0,  ln, (bool)UTF,
3177                                l, &e, 0,  do_utf8)) {
3178                      /* One more case for the sharp s:
3179                       * pack("U0U*", 0xDF) =~ /ss/i,
3180                       * the 0xC3 0x9F are the UTF-8
3181                       * byte sequence for the U+00DF. */
3182                      if (!(do_utf8 &&
3183                            toLOWER(s[0]) == 's' &&
3184                            ln >= 2 &&
3185                            toLOWER(s[1]) == 's' &&
3186                            (U8)l[0] == 0xC3 &&
3187                            e - l >= 2 &&
3188                            (U8)l[1] == 0x9F))
3189                           sayNO;
3190                 }
3191                 locinput = e;
3192                 nextchr = UCHARAT(locinput);
3193                 break;
3194             }
3195
3196             /* Neither the target and the pattern are utf8. */
3197
3198             /* Inline the first character, for speed. */
3199             if (UCHARAT(s) != nextchr &&
3200                 UCHARAT(s) != ((OP(scan) == EXACTF)
3201                                ? PL_fold : PL_fold_locale)[nextchr])
3202                 sayNO;
3203             if (PL_regeol - locinput < ln)
3204                 sayNO;
3205             if (ln > 1 && (OP(scan) == EXACTF
3206                            ? ibcmp(s, locinput, ln)
3207                            : ibcmp_locale(s, locinput, ln)))
3208                 sayNO;
3209             locinput += ln;
3210             nextchr = UCHARAT(locinput);
3211             break;
3212             }
3213         case ANYOF:
3214             if (do_utf8) {
3215                 STRLEN inclasslen = PL_regeol - locinput;
3216
3217                 if (!reginclass(rex, scan, (U8*)locinput, &inclasslen, do_utf8))
3218                     goto anyof_fail;
3219                 if (locinput >= PL_regeol)
3220                     sayNO;
3221                 locinput += inclasslen ? inclasslen : UTF8SKIP(locinput);
3222                 nextchr = UCHARAT(locinput);
3223                 break;
3224             }
3225             else {
3226                 if (nextchr < 0)
3227                     nextchr = UCHARAT(locinput);
3228                 if (!REGINCLASS(rex, scan, (U8*)locinput))
3229                     goto anyof_fail;
3230                 if (!nextchr && locinput >= PL_regeol)
3231                     sayNO;
3232                 nextchr = UCHARAT(++locinput);
3233                 break;
3234             }
3235         anyof_fail:
3236             /* If we might have the case of the German sharp s
3237              * in a casefolding Unicode character class. */
3238
3239             if (ANYOF_FOLD_SHARP_S(scan, locinput, PL_regeol)) {
3240                  locinput += SHARP_S_SKIP;
3241                  nextchr = UCHARAT(locinput);
3242             }
3243             else
3244                  sayNO;
3245             break;
3246         case ALNUML:
3247             PL_reg_flags |= RF_tainted;
3248             /* FALL THROUGH */
3249         case ALNUM:
3250             if (!nextchr)
3251                 sayNO;
3252             if (do_utf8) {
3253                 LOAD_UTF8_CHARCLASS_ALNUM();
3254                 if (!(OP(scan) == ALNUM
3255                       ? (bool)swash_fetch(PL_utf8_alnum, (U8*)locinput, do_utf8)
3256                       : isALNUM_LC_utf8((U8*)locinput)))
3257                 {
3258                     sayNO;
3259                 }
3260                 locinput += PL_utf8skip[nextchr];
3261                 nextchr = UCHARAT(locinput);
3262                 break;
3263             }
3264             if (!(OP(scan) == ALNUM
3265                   ? isALNUM(nextchr) : isALNUM_LC(nextchr)))
3266                 sayNO;
3267             nextchr = UCHARAT(++locinput);
3268             break;
3269         case NALNUML:
3270             PL_reg_flags |= RF_tainted;
3271             /* FALL THROUGH */
3272         case NALNUM:
3273             if (!nextchr && locinput >= PL_regeol)
3274                 sayNO;
3275             if (do_utf8) {
3276                 LOAD_UTF8_CHARCLASS_ALNUM();
3277                 if (OP(scan) == NALNUM
3278                     ? (bool)swash_fetch(PL_utf8_alnum, (U8*)locinput, do_utf8)
3279                     : isALNUM_LC_utf8((U8*)locinput))
3280                 {
3281                     sayNO;
3282                 }
3283                 locinput += PL_utf8skip[nextchr];
3284                 nextchr = UCHARAT(locinput);
3285                 break;
3286             }
3287             if (OP(scan) == NALNUM
3288                 ? isALNUM(nextchr) : isALNUM_LC(nextchr))
3289                 sayNO;
3290             nextchr = UCHARAT(++locinput);
3291             break;
3292         case BOUNDL:
3293         case NBOUNDL:
3294             PL_reg_flags |= RF_tainted;
3295             /* FALL THROUGH */
3296         case BOUND:
3297         case NBOUND:
3298             /* was last char in word? */
3299             if (do_utf8) {
3300                 if (locinput == PL_bostr)
3301                     ln = '\n';
3302                 else {
3303                     const U8 * const r = reghop3((U8*)locinput, -1, (U8*)PL_bostr);
3304                 
3305                     ln = utf8n_to_uvchr(r, UTF8SKIP(r), 0, uniflags);
3306                 }
3307                 if (OP(scan) == BOUND || OP(scan) == NBOUND) {
3308                     ln = isALNUM_uni(ln);
3309                     LOAD_UTF8_CHARCLASS_ALNUM();
3310                     n = swash_fetch(PL_utf8_alnum, (U8*)locinput, do_utf8);
3311                 }
3312                 else {
3313                     ln = isALNUM_LC_uvchr(UNI_TO_NATIVE(ln));
3314                     n = isALNUM_LC_utf8((U8*)locinput);
3315                 }
3316             }
3317             else {
3318                 ln = (locinput != PL_bostr) ?
3319                     UCHARAT(locinput - 1) : '\n';
3320                 if (OP(scan) == BOUND || OP(scan) == NBOUND) {
3321                     ln = isALNUM(ln);
3322                     n = isALNUM(nextchr);
3323                 }
3324                 else {
3325                     ln = isALNUM_LC(ln);
3326                     n = isALNUM_LC(nextchr);
3327                 }
3328             }
3329             if (((!ln) == (!n)) == (OP(scan) == BOUND ||
3330                                     OP(scan) == BOUNDL))
3331                     sayNO;
3332             break;
3333         case SPACEL:
3334             PL_reg_flags |= RF_tainted;
3335             /* FALL THROUGH */
3336         case SPACE:
3337             if (!nextchr)
3338                 sayNO;
3339             if (do_utf8) {
3340                 if (UTF8_IS_CONTINUED(nextchr)) {
3341                     LOAD_UTF8_CHARCLASS_SPACE();
3342                     if (!(OP(scan) == SPACE
3343                           ? (bool)swash_fetch(PL_utf8_space, (U8*)locinput, do_utf8)
3344                           : isSPACE_LC_utf8((U8*)locinput)))
3345                     {
3346                         sayNO;
3347                     }
3348                     locinput += PL_utf8skip[nextchr];
3349                     nextchr = UCHARAT(locinput);
3350                     break;
3351                 }
3352                 if (!(OP(scan) == SPACE
3353                       ? isSPACE(nextchr) : isSPACE_LC(nextchr)))
3354                     sayNO;
3355                 nextchr = UCHARAT(++locinput);
3356             }
3357             else {
3358                 if (!(OP(scan) == SPACE
3359                       ? isSPACE(nextchr) : isSPACE_LC(nextchr)))
3360                     sayNO;
3361                 nextchr = UCHARAT(++locinput);
3362             }
3363             break;
3364         case NSPACEL:
3365             PL_reg_flags |= RF_tainted;
3366             /* FALL THROUGH */
3367         case NSPACE:
3368             if (!nextchr && locinput >= PL_regeol)
3369                 sayNO;
3370             if (do_utf8) {
3371                 LOAD_UTF8_CHARCLASS_SPACE();
3372                 if (OP(scan) == NSPACE
3373                     ? (bool)swash_fetch(PL_utf8_space, (U8*)locinput, do_utf8)
3374                     : isSPACE_LC_utf8((U8*)locinput))
3375                 {
3376                     sayNO;
3377                 }
3378                 locinput += PL_utf8skip[nextchr];
3379                 nextchr = UCHARAT(locinput);
3380                 break;
3381             }
3382             if (OP(scan) == NSPACE
3383                 ? isSPACE(nextchr) : isSPACE_LC(nextchr))
3384                 sayNO;
3385             nextchr = UCHARAT(++locinput);
3386             break;
3387         case DIGITL:
3388             PL_reg_flags |= RF_tainted;
3389             /* FALL THROUGH */
3390         case DIGIT:
3391             if (!nextchr)
3392                 sayNO;
3393             if (do_utf8) {
3394                 LOAD_UTF8_CHARCLASS_DIGIT();
3395                 if (!(OP(scan) == DIGIT
3396                       ? (bool)swash_fetch(PL_utf8_digit, (U8*)locinput, do_utf8)
3397                       : isDIGIT_LC_utf8((U8*)locinput)))
3398                 {
3399                     sayNO;
3400                 }
3401                 locinput += PL_utf8skip[nextchr];
3402                 nextchr = UCHARAT(locinput);
3403                 break;
3404             }
3405             if (!(OP(scan) == DIGIT
3406                   ? isDIGIT(nextchr) : isDIGIT_LC(nextchr)))
3407                 sayNO;
3408             nextchr = UCHARAT(++locinput);
3409             break;
3410         case NDIGITL:
3411             PL_reg_flags |= RF_tainted;
3412             /* FALL THROUGH */
3413         case NDIGIT:
3414             if (!nextchr && locinput >= PL_regeol)
3415                 sayNO;
3416             if (do_utf8) {
3417                 LOAD_UTF8_CHARCLASS_DIGIT();
3418                 if (OP(scan) == NDIGIT
3419                     ? (bool)swash_fetch(PL_utf8_digit, (U8*)locinput, do_utf8)
3420                     : isDIGIT_LC_utf8((U8*)locinput))
3421                 {
3422                     sayNO;
3423                 }
3424                 locinput += PL_utf8skip[nextchr];
3425                 nextchr = UCHARAT(locinput);
3426                 break;
3427             }
3428             if (OP(scan) == NDIGIT
3429                 ? isDIGIT(nextchr) : isDIGIT_LC(nextchr))
3430                 sayNO;
3431             nextchr = UCHARAT(++locinput);
3432             break;
3433         case CLUMP:
3434             if (locinput >= PL_regeol)
3435                 sayNO;
3436             if  (do_utf8) {
3437                 LOAD_UTF8_CHARCLASS_MARK();
3438                 if (swash_fetch(PL_utf8_mark,(U8*)locinput, do_utf8))
3439                     sayNO;
3440                 locinput += PL_utf8skip[nextchr];
3441                 while (locinput < PL_regeol &&
3442                        swash_fetch(PL_utf8_mark,(U8*)locinput, do_utf8))
3443                     locinput += UTF8SKIP(locinput);
3444                 if (locinput > PL_regeol)
3445                     sayNO;
3446             } 
3447             else
3448                locinput++;
3449             nextchr = UCHARAT(locinput);
3450             break;
3451             
3452         case NREFFL:
3453         {
3454             char *s;
3455             char type;
3456             PL_reg_flags |= RF_tainted;
3457             /* FALL THROUGH */
3458         case NREF:
3459         case NREFF:
3460             type = OP(scan);
3461             n = reg_check_named_buff_matched(rex,scan);
3462
3463             if ( n ) {
3464                 type = REF + ( type - NREF );
3465                 goto do_ref;
3466             } else {
3467                 sayNO;
3468             }
3469             /* unreached */
3470         case REFFL:
3471             PL_reg_flags |= RF_tainted;
3472             /* FALL THROUGH */
3473         case REF:
3474         case REFF: 
3475             n = ARG(scan);  /* which paren pair */
3476             type = OP(scan);
3477           do_ref:  
3478             ln = PL_regstartp[n];
3479             PL_reg_leftiter = PL_reg_maxiter;           /* Void cache */
3480             if (*PL_reglastparen < n || ln == -1)
3481                 sayNO;                  /* Do not match unless seen CLOSEn. */
3482             if (ln == PL_regendp[n])
3483                 break;
3484
3485             s = PL_bostr + ln;
3486             if (do_utf8 && type != REF) {       /* REF can do byte comparison */
3487                 char *l = locinput;
3488                 const char *e = PL_bostr + PL_regendp[n];
3489                 /*
3490                  * Note that we can't do the "other character" lookup trick as
3491                  * in the 8-bit case (no pun intended) because in Unicode we
3492                  * have to map both upper and title case to lower case.
3493                  */
3494                 if (type == REFF) {
3495                     while (s < e) {
3496                         STRLEN ulen1, ulen2;
3497                         U8 tmpbuf1[UTF8_MAXBYTES_CASE+1];
3498                         U8 tmpbuf2[UTF8_MAXBYTES_CASE+1];
3499
3500                         if (l >= PL_regeol)
3501                             sayNO;
3502                         toLOWER_utf8((U8*)s, tmpbuf1, &ulen1);
3503                         toLOWER_utf8((U8*)l, tmpbuf2, &ulen2);
3504                         if (ulen1 != ulen2 || memNE((char *)tmpbuf1, (char *)tmpbuf2, ulen1))
3505                             sayNO;
3506                         s += ulen1;
3507                         l += ulen2;
3508                     }
3509                 }
3510                 locinput = l;
3511                 nextchr = UCHARAT(locinput);
3512                 break;
3513             }
3514
3515             /* Inline the first character, for speed. */
3516             if (UCHARAT(s) != nextchr &&
3517                 (type == REF ||
3518                  (UCHARAT(s) != (type == REFF
3519                                   ? PL_fold : PL_fold_locale)[nextchr])))
3520                 sayNO;
3521             ln = PL_regendp[n] - ln;
3522             if (locinput + ln > PL_regeol)
3523                 sayNO;
3524             if (ln > 1 && (type == REF
3525                            ? memNE(s, locinput, ln)
3526                            : (type == REFF
3527                               ? ibcmp(s, locinput, ln)
3528                               : ibcmp_locale(s, locinput, ln))))
3529                 sayNO;
3530             locinput += ln;
3531             nextchr = UCHARAT(locinput);
3532             break;
3533         }
3534         case NOTHING:
3535         case TAIL:
3536             break;
3537         case BACK:
3538             break;
3539
3540 #undef  ST
3541 #define ST st->u.eval
3542         {
3543             SV *ret;
3544             regexp *re;
3545             regexp_internal *rei;
3546             regnode *startpoint;
3547
3548         case GOSTART:
3549         case GOSUB: /*    /(...(?1))/      */
3550             if (cur_eval && cur_eval->locinput==locinput) {
3551                 if (cur_eval->u.eval.close_paren == (U32)ARG(scan)) 
3552                     Perl_croak(aTHX_ "Infinite recursion in regex");
3553                 if ( ++nochange_depth > MAX_RECURSE_EVAL_NOCHANGE_DEPTH ) 
3554                     Perl_croak(aTHX_ 
3555                         "Pattern subroutine nesting without pos change"
3556                         " exceeded limit in regex");
3557             } else {
3558                 nochange_depth = 0;
3559             }
3560             re = rex;
3561             rei = rexi;
3562             (void)ReREFCNT_inc(rex);
3563             if (OP(scan)==GOSUB) {
3564                 startpoint = scan + ARG2L(scan);
3565                 ST.close_paren = ARG(scan);
3566             } else {
3567                 startpoint = rei->program+1;
3568                 ST.close_paren = 0;
3569             }
3570             goto eval_recurse_doit;
3571             /* NOTREACHED */
3572         case EVAL:  /*   /(?{A})B/   /(??{A})B/  and /(?(?{A})X|Y)B/   */        
3573             if (cur_eval && cur_eval->locinput==locinput) {
3574                 if ( ++nochange_depth > MAX_RECURSE_EVAL_NOCHANGE_DEPTH ) 
3575                     Perl_croak(aTHX_ "EVAL without pos change exceeded limit in regex");
3576             } else {
3577                 nochange_depth = 0;
3578             }    
3579             {   regexp *ocurpm = PM_GETRE(PL_curpm);
3580                 char *osubbeg = rex->subbeg;
3581                 STRLEN osublen = rex->sublen;
3582             {
3583                 /* execute the code in the {...} */
3584                 dSP;
3585                 SV ** const before = SP;
3586                 OP_4tree * const oop = PL_op;
3587                 COP * const ocurcop = PL_curcop;
3588                 PAD *old_comppad;
3589
3590             
3591                 n = ARG(scan);
3592                 PL_op = (OP_4tree*)rexi->data->data[n];
3593                 DEBUG_STATE_r( PerlIO_printf(Perl_debug_log, 
3594                     "  re_eval 0x%"UVxf"\n", PTR2UV(PL_op)) );
3595                 PAD_SAVE_LOCAL(old_comppad, (PAD*)rexi->data->data[n + 2]);
3596                 PL_regendp[0] = PL_reg_magic->mg_len = locinput - PL_bostr;
3597
3598                 if (sv_yes_mark) {
3599                     SV *sv_mrk = get_sv("REGMARK", 1);
3600                     sv_setsv(sv_mrk, sv_yes_mark);
3601                 }
3602                 /* make sure that $1 and friends are available with nested eval */
3603                 PM_SETRE(PL_curpm,rex);
3604                 rex->subbeg = ocurpm->subbeg;
3605                 rex->sublen = ocurpm->sublen;
3606
3607                 CALLRUNOPS(aTHX);                       /* Scalar context. */
3608                 SPAGAIN;
3609                 if (SP == before)
3610                     ret = &PL_sv_undef;   /* protect against empty (?{}) blocks. */
3611                 else {
3612                     ret = POPs;
3613                     PUTBACK;
3614                 }
3615
3616                 PL_op = oop;
3617                 PAD_RESTORE_LOCAL(old_comppad);
3618                 PL_curcop = ocurcop;
3619
3620                 if (!logical) {
3621                     /* /(?{...})/ */
3622                     sv_setsv(save_scalar(PL_replgv), ret);
3623                     break;
3624                 }
3625             }
3626             if (logical == 2) { /* Postponed subexpression: /(??{...})/ */
3627                 logical = 0;
3628                 {
3629                     /* extract RE object from returned value; compiling if
3630                      * necessary */
3631
3632                     MAGIC *mg = NULL;
3633                     const SV *sv;
3634                     if(SvROK(ret) && SvSMAGICAL(sv = SvRV(ret)))
3635                         mg = mg_find(sv, PERL_MAGIC_qr);
3636                     else if (SvSMAGICAL(ret)) {
3637                         if (SvGMAGICAL(ret))
3638                             sv_unmagic(ret, PERL_MAGIC_qr);
3639                         else
3640                             mg = mg_find(ret, PERL_MAGIC_qr);
3641                     }
3642
3643                     if (mg) {
3644                         re = (regexp *)mg->mg_obj;
3645                         (void)ReREFCNT_inc(re);
3646                     }
3647                     else {
3648                         STRLEN len;
3649                         const char * const t = SvPV_const(ret, len);
3650                         PMOP pm;
3651                         const I32 osize = PL_regsize;
3652
3653                         Zero(&pm, 1, PMOP);
3654                         if (DO_UTF8(ret)) pm.op_pmdynflags |= PMdf_DYN_UTF8;
3655                         re = CALLREGCOMP((char*)t, (char*)t + len, &pm);
3656                         if (!(SvFLAGS(ret)
3657                               & (SVs_TEMP | SVs_PADTMP | SVf_READONLY
3658                                 | SVs_GMG)))
3659                             sv_magic(ret,(SV*)ReREFCNT_inc(re),
3660                                         PERL_MAGIC_qr,0,0);
3661                         PL_regsize = osize;
3662                     }
3663                 }
3664                 rei = RXi_GET(re);
3665
3666                 /* restore PL_curpm after the eval */
3667                 PM_SETRE(PL_curpm,ocurpm);
3668                 rex->sublen = osublen;
3669                 rex->subbeg = osubbeg;
3670
3671                 DEBUG_EXECUTE_r(
3672                     debug_start_match(re, do_utf8, locinput, PL_regeol, 
3673                         "Matching embedded");
3674                 );              
3675                 startpoint = rei->program + 1;
3676                 ST.close_paren = 0; /* only used for GOSUB */
3677                 /* borrowed from regtry */
3678                 if (PL_reg_start_tmpl <= re->nparens) {
3679                     PL_reg_start_tmpl = re->nparens*3/2 + 3;
3680                     if(PL_reg_start_tmp)
3681                         Renew(PL_reg_start_tmp, PL_reg_start_tmpl, char*);
3682                     else
3683                         Newx(PL_reg_start_tmp, PL_reg_start_tmpl, char*);
3684                 }
3685
3686
3687         eval_recurse_doit: /* Share code with GOSUB below this line */                          
3688                 /* run the pattern returned from (??{...}) */
3689                 ST.cp = regcppush(0);   /* Save *all* the positions. */
3690                 REGCP_SET(ST.lastcp);
3691                 
3692                 PL_regstartp = re->startp; /* essentially NOOP on GOSUB */
3693                 PL_regendp = re->endp;     /* essentially NOOP on GOSUB */
3694                 
3695                 *PL_reglastparen = 0;
3696                 *PL_reglastcloseparen = 0;
3697                 PL_reginput = locinput;
3698                 PL_regsize = 0;
3699
3700                 /* XXXX This is too dramatic a measure... */
3701                 PL_reg_maxiter = 0;
3702
3703                 ST.toggle_reg_flags = PL_reg_flags;
3704                 if (re->extflags & RXf_UTF8)
3705                     PL_reg_flags |= RF_utf8;
3706                 else
3707                     PL_reg_flags &= ~RF_utf8;
3708                 ST.toggle_reg_flags ^= PL_reg_flags; /* diff of old and new */
3709
3710                 ST.prev_rex = rex;
3711                 ST.prev_curlyx = cur_curlyx;
3712                 rex = re;
3713                 rexi = rei;
3714                 cur_curlyx = NULL;
3715                 ST.B = next;
3716                 ST.prev_eval = cur_eval;
3717                 cur_eval = st;
3718                 /* now continue from first node in postoned RE */
3719                 PUSH_YES_STATE_GOTO(EVAL_AB, startpoint);
3720                 /* NOTREACHED */
3721             }
3722             /* restore PL_curpm after the eval */
3723             PM_SETRE(PL_curpm,ocurpm);
3724             rex->sublen = osublen;
3725             rex->subbeg = osubbeg;
3726             }
3727             /* logical is 1,   /(?(?{...})X|Y)/ */
3728             sw = (bool)SvTRUE(ret);
3729             logical = 0;
3730             break;
3731         }
3732
3733         case EVAL_AB: /* cleanup after a successful (??{A})B */
3734             /* note: this is called twice; first after popping B, then A */
3735             PL_reg_flags ^= ST.toggle_reg_flags; 
3736             ReREFCNT_dec(rex);
3737             rex = ST.prev_rex;
3738             rexi = RXi_GET(rex);
3739             regcpblow(ST.cp);
3740             cur_eval = ST.prev_eval;
3741             cur_curlyx = ST.prev_curlyx;
3742             /* XXXX This is too dramatic a measure... */
3743             PL_reg_maxiter = 0;
3744             sayYES;
3745
3746
3747         case EVAL_AB_fail: /* unsuccessfully ran A or B in (??{A})B */
3748             /* note: this is called twice; first after popping B, then A */
3749             PL_reg_flags ^= ST.toggle_reg_flags; 
3750             ReREFCNT_dec(rex);
3751             rex = ST.prev_rex;
3752             rexi = RXi_GET(rex); 
3753             PL_reginput = locinput;
3754             REGCP_UNWIND(ST.lastcp);
3755             regcppop(rex);
3756             cur_eval = ST.prev_eval;
3757             cur_curlyx = ST.prev_curlyx;
3758             /* XXXX This is too dramatic a measure... */
3759             PL_reg_maxiter = 0;
3760             sayNO_SILENT;
3761 #undef ST
3762
3763         case OPEN:
3764             n = ARG(scan);  /* which paren pair */
3765             PL_reg_start_tmp[n] = locinput;
3766             if (n > PL_regsize)
3767                 PL_regsize = n;
3768             lastopen = n;
3769             break;
3770         case CLOSE:
3771             n = ARG(scan);  /* which paren pair */
3772             PL_regstartp[n] = PL_reg_start_tmp[n] - PL_bostr;
3773             PL_regendp[n] = locinput - PL_bostr;
3774             /*if (n > PL_regsize)
3775                 PL_regsize = n;*/
3776             if (n > *PL_reglastparen)
3777                 *PL_reglastparen = n;
3778             *PL_reglastcloseparen = n;
3779             if (cur_eval && cur_eval->u.eval.close_paren == n) {
3780                 goto fake_end;
3781             }    
3782             break;
3783         case ACCEPT:
3784             if (ARG(scan)){
3785                 regnode *cursor;
3786                 for (cursor=scan;
3787                      cursor && OP(cursor)!=END; 
3788                      cursor=regnext(cursor)) 
3789                 {
3790                     if ( OP(cursor)==CLOSE ){
3791                         n = ARG(cursor);
3792                         if ( n <= lastopen ) {
3793                             PL_regstartp[n] = PL_reg_start_tmp[n] - PL_bostr;
3794                             PL_regendp[n] = locinput - PL_bostr;
3795                             /*if (n > PL_regsize)
3796                             PL_regsize = n;*/
3797                             if (n > *PL_reglastparen)
3798                                 *PL_reglastparen = n;
3799                             *PL_reglastcloseparen = n;
3800                             if ( n == ARG(scan) || (cur_eval &&
3801                                 cur_eval->u.eval.close_paren == n))
3802                                 break;
3803                         }
3804                     }
3805                 }
3806             }
3807             goto fake_end;
3808             /*NOTREACHED*/          
3809         case GROUPP:
3810             n = ARG(scan);  /* which paren pair */
3811             sw = (bool)(*PL_reglastparen >= n && PL_regendp[n] != -1);
3812             break;
3813         case NGROUPP:
3814             /* reg_check_named_buff_matched returns 0 for no match */
3815             sw = (bool)(0 < reg_check_named_buff_matched(rex,scan));
3816             break;
3817         case INSUBP:
3818             n = ARG(scan);
3819             sw = (cur_eval && (!n || cur_eval->u.eval.close_paren == n));
3820             break;
3821         case DEFINEP:
3822             sw = 0;
3823             break;
3824         case IFTHEN:
3825             PL_reg_leftiter = PL_reg_maxiter;           /* Void cache */
3826             if (sw)
3827                 next = NEXTOPER(NEXTOPER(scan));
3828             else {
3829                 next = scan + ARG(scan);
3830                 if (OP(next) == IFTHEN) /* Fake one. */
3831                     next = NEXTOPER(NEXTOPER(next));
3832             }
3833             break;
3834         case LOGICAL:
3835             logical = scan->flags;
3836             break;
3837
3838 /*******************************************************************
3839
3840 The CURLYX/WHILEM pair of ops handle the most generic case of the /A*B/
3841 pattern, where A and B are subpatterns. (For simple A, CURLYM or
3842 STAR/PLUS/CURLY/CURLYN are used instead.)
3843
3844 A*B is compiled as <CURLYX><A><WHILEM><B>
3845
3846 On entry to the subpattern, CURLYX is called. This pushes a CURLYX
3847 state, which contains the current count, initialised to -1. It also sets
3848 cur_curlyx to point to this state, with any previous value saved in the
3849 state block.
3850
3851 CURLYX then jumps straight to the WHILEM op, rather than executing A,
3852 since the pattern may possibly match zero times (i.e. it's a while {} loop
3853 rather than a do {} while loop).
3854
3855 Each entry to WHILEM represents a successful match of A. The count in the
3856 CURLYX block is incremented, another WHILEM state is pushed, and execution
3857 passes to A or B depending on greediness and the current count.
3858
3859 For example, if matching against the string a1a2a3b (where the aN are
3860 substrings that match /A/), then the match progresses as follows: (the
3861 pushed states are interspersed with the bits of strings matched so far):
3862
3863     <CURLYX cnt=-1>
3864     <CURLYX cnt=0><WHILEM>
3865     <CURLYX cnt=1><WHILEM> a1 <WHILEM>
3866     <CURLYX cnt=2><WHILEM> a1 <WHILEM> a2 <WHILEM>
3867     <CURLYX cnt=3><WHILEM> a1 <WHILEM> a2 <WHILEM> a3 <WHILEM>
3868     <CURLYX cnt=3><WHILEM> a1 <WHILEM> a2 <WHILEM> a3 <WHILEM> b
3869
3870 (Contrast this with something like CURLYM, which maintains only a single
3871 backtrack state:
3872
3873     <CURLYM cnt=0> a1
3874     a1 <CURLYM cnt=1> a2
3875     a1 a2 <CURLYM cnt=2> a3
3876     a1 a2 a3 <CURLYM cnt=3> b
3877 )
3878
3879 Each WHILEM state block marks a point to backtrack to upon partial failure
3880 of A or B, and also contains some minor state data related to that
3881 iteration.  The CURLYX block, pointed to by cur_curlyx, contains the
3882 overall state, such as the count, and pointers to the A and B ops.
3883
3884 This is complicated slightly by nested CURLYX/WHILEM's. Since cur_curlyx
3885 must always point to the *current* CURLYX block, the rules are:
3886
3887 When executing CURLYX, save the old cur_curlyx in the CURLYX state block,
3888 and set cur_curlyx to point the new block.
3889
3890 When popping the CURLYX block after a successful or unsuccessful match,
3891 restore the previous cur_curlyx.
3892
3893 When WHILEM is about to execute B, save the current cur_curlyx, and set it
3894 to the outer one saved in the CURLYX block.
3895
3896 When popping the WHILEM block after a successful or unsuccessful B match,
3897 restore the previous cur_curlyx.
3898
3899 Here's an example for the pattern (AI* BI)*BO
3900 I and O refer to inner and outer, C and W refer to CURLYX and WHILEM:
3901
3902 cur_
3903 curlyx backtrack stack
3904 ------ ---------------
3905 NULL   
3906 CO     <CO prev=NULL> <WO>
3907 CI     <CO prev=NULL> <WO> <CI prev=CO> <WI> ai 
3908 CO     <CO prev=NULL> <WO> <CI prev=CO> <WI> ai <WI prev=CI> bi 
3909 NULL   <CO prev=NULL> <WO> <CI prev=CO> <WI> ai <WI prev=CI> bi <WO prev=CO> bo
3910
3911 At this point the pattern succeeds, and we work back down the stack to
3912 clean up, restoring as we go:
3913
3914 CO     <CO prev=NULL> <WO> <CI prev=CO> <WI> ai <WI prev=CI> bi 
3915 CI     <CO prev=NULL> <WO> <CI prev=CO> <WI> ai 
3916 CO     <CO prev=NULL> <WO>
3917 NULL   
3918
3919 *******************************************************************/
3920
3921 #define ST st->u.curlyx
3922
3923         case CURLYX:    /* start of /A*B/  (for complex A) */
3924         {
3925             /* No need to save/restore up to this paren */
3926             I32 parenfloor = scan->flags;
3927             
3928             assert(next); /* keep Coverity happy */
3929             if (OP(PREVOPER(next)) == NOTHING) /* LONGJMP */
3930                 next += ARG(next);
3931
3932             /* XXXX Probably it is better to teach regpush to support
3933                parenfloor > PL_regsize... */
3934             if (parenfloor > (I32)*PL_reglastparen)
3935                 parenfloor = *PL_reglastparen; /* Pessimization... */
3936
3937             ST.prev_curlyx= cur_curlyx;
3938             cur_curlyx = st;
3939             ST.cp = PL_savestack_ix;
3940
3941             /* these fields contain the state of the current curly.
3942              * they are accessed by subsequent WHILEMs */
3943             ST.parenfloor = parenfloor;
3944             ST.min = ARG1(scan);
3945             ST.max = ARG2(scan);
3946             ST.A = NEXTOPER(scan) + EXTRA_STEP_2ARGS;
3947             ST.B = next;
3948             ST.minmod = minmod;
3949             minmod = 0;
3950             ST.count = -1;      /* this will be updated by WHILEM */
3951             ST.lastloc = NULL;  /* this will be updated by WHILEM */
3952
3953             PL_reginput = locinput;
3954             PUSH_YES_STATE_GOTO(CURLYX_end, PREVOPER(next));
3955             /* NOTREACHED */
3956         }
3957
3958         case CURLYX_end: /* just finished matching all of A*B */
3959             if (PL_reg_eval_set){
3960                 SV *pres= GvSV(PL_replgv);
3961                 SvREFCNT_inc(pres);
3962                 regcpblow(ST.cp);
3963                 sv_setsv(GvSV(PL_replgv), pres);
3964                 SvREFCNT_dec(pres);
3965             } else {
3966                 regcpblow(ST.cp);
3967             }
3968             cur_curlyx = ST.prev_curlyx;
3969             sayYES;
3970             /* NOTREACHED */
3971
3972         case CURLYX_end_fail: /* just failed to match all of A*B */
3973             regcpblow(ST.cp);
3974             cur_curlyx = ST.prev_curlyx;
3975             sayNO;
3976             /* NOTREACHED */
3977
3978
3979 #undef ST
3980 #define ST st->u.whilem
3981
3982         case WHILEM:     /* just matched an A in /A*B/  (for complex A) */
3983         {
3984             /* see the discussion above about CURLYX/WHILEM */
3985             I32 n;
3986             assert(cur_curlyx); /* keep Coverity happy */
3987             n = ++cur_curlyx->u.curlyx.count; /* how many A's matched */
3988             ST.save_lastloc = cur_curlyx->u.curlyx.lastloc;
3989             ST.cache_offset = 0;
3990             ST.cache_mask = 0;
3991             
3992             PL_reginput = locinput;
3993
3994             DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
3995                   "%*s  whilem: matched %ld out of %ld..%ld\n",
3996                   REPORT_CODE_OFF+depth*2, "", (long)n,
3997                   (long)cur_curlyx->u.curlyx.min,
3998                   (long)cur_curlyx->u.curlyx.max)
3999             );
4000
4001             /* First just match a string of min A's. */
4002
4003             if (n < cur_curlyx->u.curlyx.min) {
4004                 cur_curlyx->u.curlyx.lastloc = locinput;
4005                 PUSH_STATE_GOTO(WHILEM_A_pre, cur_curlyx->u.curlyx.A);
4006                 /* NOTREACHED */
4007             }
4008
4009             /* If degenerate A matches "", assume A done. */
4010
4011             if (locinput == cur_curlyx->u.curlyx.lastloc) {
4012                 DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
4013                    "%*s  whilem: empty match detected, trying continuation...\n",
4014                    REPORT_CODE_OFF+depth*2, "")
4015                 );
4016                 goto do_whilem_B_max;
4017             }
4018
4019             /* super-linear cache processing */
4020
4021             if (scan->flags) {
4022
4023                 if (!PL_reg_maxiter) {
4024                     /* start the countdown: Postpone detection until we
4025                      * know the match is not *that* much linear. */
4026                     PL_reg_maxiter = (PL_regeol - PL_bostr + 1) * (scan->flags>>4);
4027                     /* possible overflow for long strings and many CURLYX's */
4028                     if (PL_reg_maxiter < 0)
4029                         PL_reg_maxiter = I32_MAX;
4030                     PL_reg_leftiter = PL_reg_maxiter;
4031                 }
4032
4033                 if (PL_reg_leftiter-- == 0) {
4034                     /* initialise cache */
4035                     const I32 size = (PL_reg_maxiter + 7)/8;
4036                     if (PL_reg_poscache) {
4037                         if ((I32)PL_reg_poscache_size < size) {
4038                             Renew(PL_reg_poscache, size, char);
4039                             PL_reg_poscache_size = size;
4040                         }
4041                         Zero(PL_reg_poscache, size, char);
4042                     }
4043                     else {
4044                         PL_reg_poscache_size = size;
4045                         Newxz(PL_reg_poscache, size, char);
4046                     }
4047                     DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
4048       "%swhilem: Detected a super-linear match, switching on caching%s...\n",
4049                               PL_colors[4], PL_colors[5])
4050                     );
4051                 }
4052
4053                 if (PL_reg_leftiter < 0) {
4054                     /* have we already failed at this position? */
4055                     I32 offset, mask;
4056                     offset  = (scan->flags & 0xf) - 1
4057                                 + (locinput - PL_bostr)  * (scan->flags>>4);
4058                     mask    = 1 << (offset % 8);
4059                     offset /= 8;
4060                     if (PL_reg_poscache[offset] & mask) {
4061                         DEBUG_EXECUTE_r( PerlIO_printf(Perl_debug_log,
4062                             "%*s  whilem: (cache) already tried at this position...\n",
4063                             REPORT_CODE_OFF+depth*2, "")
4064                         );
4065                         sayNO; /* cache records failure */
4066                     }
4067                     ST.cache_offset = offset;
4068                     ST.cache_mask   = mask;
4069                 }
4070             }
4071
4072             /* Prefer B over A for minimal matching. */
4073
4074             if (cur_curlyx->u.curlyx.minmod) {
4075                 ST.save_curlyx = cur_curlyx;
4076                 cur_curlyx = cur_curlyx->u.curlyx.prev_curlyx;
4077                 ST.cp = regcppush(ST.save_curlyx->u.curlyx.parenfloor);
4078                 REGCP_SET(ST.lastcp);
4079                 PUSH_YES_STATE_GOTO(WHILEM_B_min, ST.save_curlyx->u.curlyx.B);
4080                 /* NOTREACHED */
4081             }
4082
4083             /* Prefer A over B for maximal matching. */
4084
4085             if (n < cur_curlyx->u.curlyx.max) { /* More greed allowed? */
4086                 ST.cp = regcppush(cur_curlyx->u.curlyx.parenfloor);
4087                 cur_curlyx->u.curlyx.lastloc = locinput;
4088                 REGCP_SET(ST.lastcp);
4089                 PUSH_STATE_GOTO(WHILEM_A_max, cur_curlyx->u.curlyx.A);
4090                 /* NOTREACHED */
4091             }
4092             goto do_whilem_B_max;
4093         }
4094         /* NOTREACHED */
4095
4096         case WHILEM_B_min: /* just matched B in a minimal match */
4097         case WHILEM_B_max: /* just matched B in a maximal match */
4098             cur_curlyx = ST.save_curlyx;
4099             sayYES;
4100             /* NOTREACHED */
4101
4102         case WHILEM_B_max_fail: /* just failed to match B in a maximal match */
4103             cur_curlyx = ST.save_curlyx;
4104             cur_curlyx->u.curlyx.lastloc = ST.save_lastloc;
4105             cur_curlyx->u.curlyx.count--;
4106             CACHEsayNO;
4107             /* NOTREACHED */
4108
4109         case WHILEM_A_min_fail: /* just failed to match A in a minimal match */
4110             REGCP_UNWIND(ST.lastcp);
4111             regcppop(rex);
4112             /* FALL THROUGH */
4113         case WHILEM_A_pre_fail: /* just failed to match even minimal A */
4114             cur_curlyx->u.curlyx.lastloc = ST.save_lastloc;
4115             cur_curlyx->u.curlyx.count--;
4116             CACHEsayNO;
4117             /* NOTREACHED */
4118
4119         case WHILEM_A_max_fail: /* just failed to match A in a maximal match */
4120             REGCP_UNWIND(ST.lastcp);
4121             regcppop(rex);      /* Restore some previous $<digit>s? */
4122             PL_reginput = locinput;
4123             DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
4124                 "%*s  whilem: failed, trying continuation...\n",
4125                 REPORT_CODE_OFF+depth*2, "")
4126             );
4127           do_whilem_B_max:
4128             if (cur_curlyx->u.curlyx.count >= REG_INFTY
4129                 && ckWARN(WARN_REGEXP)
4130                 && !(PL_reg_flags & RF_warned))
4131             {
4132                 PL_reg_flags |= RF_warned;
4133                 Perl_warner(aTHX_ packWARN(WARN_REGEXP), "%s limit (%d) exceeded",
4134                      "Complex regular subexpression recursion",
4135                      REG_INFTY - 1);
4136             }
4137
4138             /* now try B */
4139             ST.save_curlyx = cur_curlyx;
4140             cur_curlyx = cur_curlyx->u.curlyx.prev_curlyx;
4141             PUSH_YES_STATE_GOTO(WHILEM_B_max, ST.save_curlyx->u.curlyx.B);
4142             /* NOTREACHED */
4143
4144         case WHILEM_B_min_fail: /* just failed to match B in a minimal match */
4145             cur_curlyx = ST.save_curlyx;
4146             REGCP_UNWIND(ST.lastcp);
4147             regcppop(rex);
4148
4149             if (cur_curlyx->u.curlyx.count >= cur_curlyx->u.curlyx.max) {
4150                 /* Maximum greed exceeded */
4151                 if (cur_curlyx->u.curlyx.count >= REG_INFTY
4152                     && ckWARN(WARN_REGEXP)
4153                     && !(PL_reg_flags & RF_warned))
4154                 {
4155                     PL_reg_flags |= RF_warned;
4156                     Perl_warner(aTHX_ packWARN(WARN_REGEXP),
4157                         "%s limit (%d) exceeded",
4158                         "Complex regular subexpression recursion",
4159                         REG_INFTY - 1);
4160                 }
4161                 cur_curlyx->u.curlyx.count--;
4162                 CACHEsayNO;
4163             }
4164
4165             DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
4166                 "%*s  trying longer...\n", REPORT_CODE_OFF+depth*2, "")
4167             );
4168             /* Try grabbing another A and see if it helps. */
4169             PL_reginput = locinput;
4170             cur_curlyx->u.curlyx.lastloc = locinput;
4171             ST.cp = regcppush(cur_curlyx->u.curlyx.parenfloor);
4172             REGCP_SET(ST.lastcp);
4173             PUSH_STATE_GOTO(WHILEM_A_min, ST.save_curlyx->u.curlyx.A);
4174             /* NOTREACHED */
4175
4176 #undef  ST
4177 #define ST st->u.branch
4178
4179         case BRANCHJ:       /*  /(...|A|...)/ with long next pointer */
4180             next = scan + ARG(scan);
4181             if (next == scan)
4182                 next = NULL;
4183             scan = NEXTOPER(scan);
4184             /* FALL THROUGH */
4185
4186         case BRANCH:        /*  /(...|A|...)/ */
4187             scan = NEXTOPER(scan); /* scan now points to inner node */
4188             if ((!next || (OP(next) != BRANCH && OP(next) != BRANCHJ)) 
4189                 && !has_cutgroup)
4190             {
4191                 /* last branch; skip state push and jump direct to node */
4192                 continue;
4193             }
4194             ST.lastparen = *PL_reglastparen;
4195             ST.next_branch = next;
4196             REGCP_SET(ST.cp);
4197             PL_reginput = locinput;
4198
4199             /* Now go into the branch */
4200             if (has_cutgroup) {
4201                 PUSH_YES_STATE_GOTO(BRANCH_next, scan);    
4202             } else {
4203                 PUSH_STATE_GOTO(BRANCH_next, scan);
4204             }
4205             /* NOTREACHED */
4206         case CUTGROUP:
4207             PL_reginput = locinput;
4208             sv_yes_mark = st->u.mark.mark_name = scan->flags ? NULL :
4209                 (SV*)rexi->data->data[ ARG( scan ) ];
4210             PUSH_STATE_GOTO(CUTGROUP_next,next);
4211             /* NOTREACHED */
4212         case CUTGROUP_next_fail:
4213             do_cutgroup = 1;
4214             no_final = 1;
4215             if (st->u.mark.mark_name)
4216                 sv_commit = st->u.mark.mark_name;
4217             sayNO;          
4218             /* NOTREACHED */
4219         case BRANCH_next:
4220             sayYES;
4221             /* NOTREACHED */
4222         case BRANCH_next_fail: /* that branch failed; try the next, if any */
4223             if (do_cutgroup) {
4224                 do_cutgroup = 0;
4225                 no_final = 0;
4226             }
4227             REGCP_UNWIND(ST.cp);
4228             for (n = *PL_reglastparen; n > ST.lastparen; n--)
4229                 PL_regendp[n] = -1;
4230             *PL_reglastparen = n;
4231             /*dmq: *PL_reglastcloseparen = n; */
4232             scan = ST.next_branch;
4233             /* no more branches? */
4234             if (!scan || (OP(scan) != BRANCH && OP(scan) != BRANCHJ)) {
4235                 DEBUG_EXECUTE_r({
4236                     PerlIO_printf( Perl_debug_log,
4237                         "%*s  %sBRANCH failed...%s\n",
4238                         REPORT_CODE_OFF+depth*2, "", 
4239                         PL_colors[4],
4240                         PL_colors[5] );
4241                 });
4242                 sayNO_SILENT;
4243             }
4244             continue; /* execute next BRANCH[J] op */
4245             /* NOTREACHED */
4246     
4247         case MINMOD:
4248             minmod = 1;
4249             break;
4250
4251 #undef  ST
4252 #define ST st->u.curlym
4253
4254         case CURLYM:    /* /A{m,n}B/ where A is fixed-length */
4255
4256             /* This is an optimisation of CURLYX that enables us to push
4257              * only a single backtracking state, no matter now many matches
4258              * there are in {m,n}. It relies on the pattern being constant
4259              * length, with no parens to influence future backrefs
4260              */
4261
4262             ST.me = scan;
4263             scan = NEXTOPER(scan) + NODE_STEP_REGNODE;
4264
4265             /* if paren positive, emulate an OPEN/CLOSE around A */
4266             if (ST.me->flags) {
4267                 U32 paren = ST.me->flags;
4268                 if (paren > PL_regsize)
4269                     PL_regsize = paren;
4270                 if (paren > *PL_reglastparen)
4271                     *PL_reglastparen = paren;
4272                 scan += NEXT_OFF(scan); /* Skip former OPEN. */
4273             }
4274             ST.A = scan;
4275             ST.B = next;
4276             ST.alen = 0;
4277             ST.count = 0;
4278             ST.minmod = minmod;
4279             minmod = 0;
4280             ST.c1 = CHRTEST_UNINIT;
4281             REGCP_SET(ST.cp);
4282
4283             if (!(ST.minmod ? ARG1(ST.me) : ARG2(ST.me))) /* min/max */
4284                 goto curlym_do_B;
4285
4286           curlym_do_A: /* execute the A in /A{m,n}B/  */
4287             PL_reginput = locinput;
4288             PUSH_YES_STATE_GOTO(CURLYM_A, ST.A); /* match A */
4289             /* NOTREACHED */
4290
4291         case CURLYM_A: /* we've just matched an A */
4292             locinput = st->locinput;
4293             nextchr = UCHARAT(locinput);
4294
4295             ST.count++;
4296             /* after first match, determine A's length: u.curlym.alen */
4297             if (ST.count == 1) {
4298                 if (PL_reg_match_utf8) {
4299                     char *s = locinput;
4300                     while (s < PL_reginput) {
4301                         ST.alen++;
4302                         s += UTF8SKIP(s);
4303                     }
4304                 }
4305                 else {
4306                     ST.alen = PL_reginput - locinput;
4307                 }
4308                 if (ST.alen == 0)
4309                     ST.count = ST.minmod ? ARG1(ST.me) : ARG2(ST.me);
4310             }
4311             DEBUG_EXECUTE_r(
4312                 PerlIO_printf(Perl_debug_log,
4313                           "%*s  CURLYM now matched %"IVdf" times, len=%"IVdf"...\n",
4314                           (int)(REPORT_CODE_OFF+(depth*2)), "",
4315                           (IV) ST.count, (IV)ST.alen)
4316             );
4317
4318             locinput = PL_reginput;
4319                         
4320             if (cur_eval && cur_eval->u.eval.close_paren && 
4321                 cur_eval->u.eval.close_paren == (U32)ST.me->flags) 
4322                 goto fake_end;
4323                 
4324             if ( ST.count < (ST.minmod ? ARG1(ST.me) : ARG2(ST.me)) )
4325                 goto curlym_do_A; /* try to match another A */
4326             goto curlym_do_B; /* try to match B */
4327
4328         case CURLYM_A_fail: /* just failed to match an A */
4329             REGCP_UNWIND(ST.cp);
4330
4331             if (ST.minmod || ST.count < ARG1(ST.me) /* min*/ 
4332                 || (cur_eval && cur_eval->u.eval.close_paren &&
4333                     cur_eval->u.eval.close_paren == (U32)ST.me->flags))
4334                 sayNO;
4335
4336           curlym_do_B: /* execute the B in /A{m,n}B/  */
4337             PL_reginput = locinput;
4338             if (ST.c1 == CHRTEST_UNINIT) {
4339                 /* calculate c1 and c2 for possible match of 1st char
4340                  * following curly */
4341                 ST.c1 = ST.c2 = CHRTEST_VOID;
4342                 if (HAS_TEXT(ST.B) || JUMPABLE(ST.B)) {
4343                     regnode *text_node = ST.B;
4344                     if (! HAS_TEXT(text_node))
4345                         FIND_NEXT_IMPT(text_node);
4346                     /* this used to be 
4347                         
4348                         (HAS_TEXT(text_node) && PL_regkind[OP(text_node)] == EXACT)
4349                         
4350                         But the former is redundant in light of the latter.
4351                         
4352                         if this changes back then the macro for 
4353                         IS_TEXT and friends need to change.
4354                      */
4355                     if (PL_regkind[OP(text_node)] == EXACT)
4356                     {
4357                         
4358                         ST.c1 = (U8)*STRING(text_node);
4359                         ST.c2 =
4360                             (IS_TEXTF(text_node))
4361                             ? PL_fold[ST.c1]
4362                             : (IS_TEXTFL(text_node))
4363                                 ? PL_fold_locale[ST.c1]
4364                                 : ST.c1;
4365                     }
4366                 }
4367             }
4368
4369             DEBUG_EXECUTE_r(
4370                 PerlIO_printf(Perl_debug_log,
4371                     "%*s  CURLYM trying tail with matches=%"IVdf"...\n",
4372                     (int)(REPORT_CODE_OFF+(depth*2)),
4373                     "", (IV)ST.count)
4374                 );
4375             if (ST.c1 != CHRTEST_VOID
4376                     && UCHARAT(PL_reginput) != ST.c1
4377                     && UCHARAT(PL_reginput) != ST.c2)
4378             {
4379                 /* simulate B failing */
4380                 state_num = CURLYM_B_fail;
4381                 goto reenter_switch;
4382             }
4383
4384             if (ST.me->flags) {
4385                 /* mark current A as captured */
4386                 I32 paren = ST.me->flags;
4387                 if (ST.count) {
4388                     PL_regstartp[paren]
4389                         = HOPc(PL_reginput, -ST.alen) - PL_bostr;
4390                     PL_regendp[paren] = PL_reginput - PL_bostr;
4391                     /*dmq: *PL_reglastcloseparen = paren; */
4392                 }
4393                 else
4394                     PL_regendp[paren] = -1;
4395                 if (cur_eval && cur_eval->u.eval.close_paren &&
4396                     cur_eval->u.eval.close_paren == (U32)ST.me->flags) 
4397                 {
4398                     if (ST.count) 
4399                         goto fake_end;
4400                     else
4401                         sayNO;
4402                 }
4403             }
4404             
4405             PUSH_STATE_GOTO(CURLYM_B, ST.B); /* match B */
4406             /* NOTREACHED */
4407
4408         case CURLYM_B_fail: /* just failed to match a B */
4409             REGCP_UNWIND(ST.cp);
4410             if (ST.minmod) {
4411                 if (ST.count == ARG2(ST.me) /* max */)
4412                     sayNO;
4413                 goto curlym_do_A; /* try to match a further A */
4414             }
4415             /* backtrack one A */
4416             if (ST.count == ARG1(ST.me) /* min */)
4417                 sayNO;
4418             ST.count--;
4419             locinput = HOPc(locinput, -ST.alen);
4420             goto curlym_do_B; /* try to match B */
4421
4422 #undef ST
4423 #define ST st->u.curly
4424
4425 #define CURLY_SETPAREN(paren, success) \
4426     if (paren) { \
4427         if (success) { \
4428             PL_regstartp[paren] = HOPc(locinput, -1) - PL_bostr; \
4429             PL_regendp[paren] = locinput - PL_bostr; \
4430             *PL_reglastcloseparen = paren; \
4431         } \
4432         else \
4433             PL_regendp[paren] = -1; \
4434     }
4435
4436         case STAR:              /*  /A*B/ where A is width 1 */
4437             ST.paren = 0;
4438             ST.min = 0;
4439             ST.max = REG_INFTY;
4440             scan = NEXTOPER(scan);
4441             goto repeat;
4442         case PLUS:              /*  /A+B/ where A is width 1 */
4443             ST.paren = 0;
4444             ST.min = 1;
4445             ST.max = REG_INFTY;
4446             scan = NEXTOPER(scan);
4447             goto repeat;
4448         case CURLYN:            /*  /(A){m,n}B/ where A is width 1 */
4449             ST.paren = scan->flags;     /* Which paren to set */
4450             if (ST.paren > PL_regsize)
4451                 PL_regsize = ST.paren;
4452             if (ST.paren > *PL_reglastparen)
4453                 *PL_reglastparen = ST.paren;
4454             ST.min = ARG1(scan);  /* min to match */
4455             ST.max = ARG2(scan);  /* max to match */
4456             if (cur_eval && cur_eval->u.eval.close_paren &&
4457                 cur_eval->u.eval.close_paren == (U32)ST.paren) {
4458                 ST.min=1;
4459                 ST.max=1;
4460             }
4461             scan = regnext(NEXTOPER(scan) + NODE_STEP_REGNODE);
4462             goto repeat;
4463         case CURLY:             /*  /A{m,n}B/ where A is width 1 */
4464             ST.paren = 0;
4465             ST.min = ARG1(scan);  /* min to match */
4466             ST.max = ARG2(scan);  /* max to match */
4467             scan = NEXTOPER(scan) + NODE_STEP_REGNODE;
4468           repeat:
4469             /*
4470             * Lookahead to avoid useless match attempts
4471             * when we know what character comes next.
4472             *
4473             * Used to only do .*x and .*?x, but now it allows
4474             * for )'s, ('s and (?{ ... })'s to be in the way
4475             * of the quantifier and the EXACT-like node.  -- japhy
4476             */
4477
4478             if (ST.min > ST.max) /* XXX make this a compile-time check? */
4479                 sayNO;
4480             if (HAS_TEXT(next) || JUMPABLE(next)) {
4481                 U8 *s;
4482                 regnode *text_node = next;
4483
4484                 if (! HAS_TEXT(text_node)) 
4485                     FIND_NEXT_IMPT(text_node);
4486
4487                 if (! HAS_TEXT(text_node))
4488                     ST.c1 = ST.c2 = CHRTEST_VOID;
4489                 else {
4490                     if ( PL_regkind[OP(text_node)] != EXACT ) {
4491                         ST.c1 = ST.c2 = CHRTEST_VOID;
4492                         goto assume_ok_easy;
4493                     }
4494                     else
4495                         s = (U8*)STRING(text_node);
4496                     
4497                     /*  Currently we only get here when 
4498                         
4499                         PL_rekind[OP(text_node)] == EXACT
4500                     
4501                         if this changes back then the macro for IS_TEXT and 
4502                         friends need to change. */
4503                     if (!UTF) {
4504                         ST.c2 = ST.c1 = *s;
4505                         if (IS_TEXTF(text_node))
4506                             ST.c2 = PL_fold[ST.c1];
4507                         else if (IS_TEXTFL(text_node))
4508                             ST.c2 = PL_fold_locale[ST.c1];
4509                     }
4510                     else { /* UTF */
4511                         if (IS_TEXTF(text_node)) {
4512                              STRLEN ulen1, ulen2;
4513                              U8 tmpbuf1[UTF8_MAXBYTES_CASE+1];
4514                              U8 tmpbuf2[UTF8_MAXBYTES_CASE+1];
4515
4516                              to_utf8_lower((U8*)s, tmpbuf1, &ulen1);
4517                              to_utf8_upper((U8*)s, tmpbuf2, &ulen2);
4518 #ifdef EBCDIC
4519                              ST.c1 = utf8n_to_uvchr(tmpbuf1, UTF8_MAXLEN, 0,
4520                                                     ckWARN(WARN_UTF8) ?
4521                                                     0 : UTF8_ALLOW_ANY);
4522                              ST.c2 = utf8n_to_uvchr(tmpbuf2, UTF8_MAXLEN, 0,
4523                                                     ckWARN(WARN_UTF8) ?
4524                                                     0 : UTF8_ALLOW_ANY);
4525 #else
4526                              ST.c1 = utf8n_to_uvuni(tmpbuf1, UTF8_MAXBYTES, 0,
4527                                                     uniflags);
4528                              ST.c2 = utf8n_to_uvuni(tmpbuf2, UTF8_MAXBYTES, 0,
4529                                                     uniflags);
4530 #endif
4531                         }
4532                         else {
4533                             ST.c2 = ST.c1 = utf8n_to_uvchr(s, UTF8_MAXBYTES, 0,
4534                                                      uniflags);
4535                         }
4536                     }
4537                 }
4538             }
4539             else
4540                 ST.c1 = ST.c2 = CHRTEST_VOID;
4541         assume_ok_easy:
4542
4543             ST.A = scan;
4544             ST.B = next;
4545             PL_reginput = locinput;
4546             if (minmod) {
4547                 minmod = 0;
4548                 if (ST.min && regrepeat(rex, ST.A, ST.min, depth) < ST.min)
4549                     sayNO;
4550                 ST.count = ST.min;
4551                 locinput = PL_reginput;
4552                 REGCP_SET(ST.cp);
4553                 if (ST.c1 == CHRTEST_VOID)
4554                     goto curly_try_B_min;
4555
4556                 ST.oldloc = locinput;
4557
4558                 /* set ST.maxpos to the furthest point along the
4559                  * string that could possibly match */
4560                 if  (ST.max == REG_INFTY) {
4561                     ST.maxpos = PL_regeol - 1;
4562                     if (do_utf8)
4563                         while (UTF8_IS_CONTINUATION(*(U8*)ST.maxpos))
4564                             ST.maxpos--;
4565                 }
4566                 else if (do_utf8) {
4567                     int m = ST.max - ST.min;
4568                     for (ST.maxpos = locinput;
4569                          m >0 && ST.maxpos + UTF8SKIP(ST.maxpos) <= PL_regeol; m--)
4570                         ST.maxpos += UTF8SKIP(ST.maxpos);
4571                 }
4572                 else {
4573                     ST.maxpos = locinput + ST.max - ST.min;
4574                     if (ST.maxpos >= PL_regeol)
4575                         ST.maxpos = PL_regeol - 1;
4576                 }
4577                 goto curly_try_B_min_known;
4578
4579             }
4580             else {
4581                 ST.count = regrepeat(rex, ST.A, ST.max, depth);
4582                 locinput = PL_reginput;
4583                 if (ST.count < ST.min)
4584                     sayNO;
4585                 if ((ST.count > ST.min)
4586                     && (PL_regkind[OP(ST.B)] == EOL) && (OP(ST.B) != MEOL))
4587                 {
4588                     /* A{m,n} must come at the end of the string, there's
4589                      * no point in backing off ... */
4590                     ST.min = ST.count;
4591                     /* ...except that $ and \Z can match before *and* after
4592                        newline at the end.  Consider "\n\n" =~ /\n+\Z\n/.
4593                        We may back off by one in this case. */
4594                     if (UCHARAT(PL_reginput - 1) == '\n' && OP(ST.B) != EOS)
4595                         ST.min--;
4596                 }
4597                 REGCP_SET(ST.cp);
4598                 goto curly_try_B_max;
4599             }
4600             /* NOTREACHED */
4601
4602
4603         case CURLY_B_min_known_fail:
4604             /* failed to find B in a non-greedy match where c1,c2 valid */
4605             if (ST.paren && ST.count)
4606                 PL_regendp[ST.paren] = -1;
4607
4608             PL_reginput = locinput;     /* Could be reset... */
4609             REGCP_UNWIND(ST.cp);
4610             /* Couldn't or didn't -- move forward. */
4611             ST.oldloc = locinput;
4612             if (do_utf8)
4613                 locinput += UTF8SKIP(locinput);
4614             else
4615                 locinput++;
4616             ST.count++;
4617           curly_try_B_min_known:
4618              /* find the next place where 'B' could work, then call B */
4619             {
4620                 int n;
4621                 if (do_utf8) {
4622                     n = (ST.oldloc == locinput) ? 0 : 1;
4623                     if (ST.c1 == ST.c2) {
4624                         STRLEN len;
4625                         /* set n to utf8_distance(oldloc, locinput) */
4626                         while (locinput <= ST.maxpos &&
4627                                utf8n_to_uvchr((U8*)locinput,
4628                                               UTF8_MAXBYTES, &len,
4629                                               uniflags) != (UV)ST.c1) {
4630                             locinput += len;
4631                             n++;
4632                         }
4633                     }
4634                     else {
4635                         /* set n to utf8_distance(oldloc, locinput) */
4636                         while (locinput <= ST.maxpos) {
4637                             STRLEN len;
4638                             const UV c = utf8n_to_uvchr((U8*)locinput,
4639                                                   UTF8_MAXBYTES, &len,
4640                                                   uniflags);
4641                             if (c == (UV)ST.c1 || c == (UV)ST.c2)
4642                                 break;
4643                             locinput += len;
4644                             n++;
4645                         }
4646                     }
4647                 }
4648                 else {
4649                     if (ST.c1 == ST.c2) {
4650                         while (locinput <= ST.maxpos &&
4651                                UCHARAT(locinput) != ST.c1)
4652                             locinput++;
4653                     }
4654                     else {
4655                         while (locinput <= ST.maxpos
4656                                && UCHARAT(locinput) != ST.c1
4657                                && UCHARAT(locinput) != ST.c2)
4658                             locinput++;
4659                     }
4660                     n = locinput - ST.oldloc;
4661                 }
4662                 if (locinput > ST.maxpos)
4663                     sayNO;
4664                 /* PL_reginput == oldloc now */
4665                 if (n) {
4666                     ST.count += n;
4667                     if (regrepeat(rex, ST.A, n, depth) < n)
4668                         sayNO;
4669                 }
4670                 PL_reginput = locinput;
4671                 CURLY_SETPAREN(ST.paren, ST.count);
4672                 if (cur_eval && cur_eval->u.eval.close_paren && 
4673                     cur_eval->u.eval.close_paren == (U32)ST.paren) {
4674                     goto fake_end;
4675                 }
4676                 PUSH_STATE_GOTO(CURLY_B_min_known, ST.B);
4677             }
4678             /* NOTREACHED */
4679
4680
4681         case CURLY_B_min_fail:
4682             /* failed to find B in a non-greedy match where c1,c2 invalid */
4683             if (ST.paren && ST.count)
4684                 PL_regendp[ST.paren] = -1;
4685
4686             REGCP_UNWIND(ST.cp);
4687             /* failed -- move forward one */
4688             PL_reginput = locinput;
4689             if (regrepeat(rex, ST.A, 1, depth)) {
4690                 ST.count++;
4691                 locinput = PL_reginput;
4692                 if (ST.count <= ST.max || (ST.max == REG_INFTY &&
4693                         ST.count > 0)) /* count overflow ? */
4694                 {
4695                   curly_try_B_min:
4696                     CURLY_SETPAREN(ST.paren, ST.count);
4697                     if (cur_eval && cur_eval->u.eval.close_paren &&
4698                         cur_eval->u.eval.close_paren == (U32)ST.paren) {
4699                         goto fake_end;
4700                     }
4701                     PUSH_STATE_GOTO(CURLY_B_min, ST.B);
4702                 }
4703             }
4704             sayNO;
4705             /* NOTREACHED */
4706
4707
4708         curly_try_B_max:
4709             /* a successful greedy match: now try to match B */
4710             if (cur_eval && cur_eval->u.eval.close_paren &&
4711                 cur_eval->u.eval.close_paren == (U32)ST.paren) {
4712                 goto fake_end;
4713             }
4714             {
4715                 UV c = 0;
4716                 if (ST.c1 != CHRTEST_VOID)
4717                     c = do_utf8 ? utf8n_to_uvchr((U8*)PL_reginput,
4718                                            UTF8_MAXBYTES, 0, uniflags)
4719                                 : (UV) UCHARAT(PL_reginput);
4720                 /* If it could work, try it. */
4721                 if (ST.c1 == CHRTEST_VOID || c == (UV)ST.c1 || c == (UV)ST.c2) {
4722                     CURLY_SETPAREN(ST.paren, ST.count);
4723                     PUSH_STATE_GOTO(CURLY_B_max, ST.B);
4724                     /* NOTREACHED */
4725                 }
4726             }
4727             /* FALL THROUGH */
4728         case CURLY_B_max_fail:
4729             /* failed to find B in a greedy match */
4730             if (ST.paren && ST.count)
4731                 PL_regendp[ST.paren] = -1;
4732
4733             REGCP_UNWIND(ST.cp);
4734             /*  back up. */
4735             if (--ST.count < ST.min)
4736                 sayNO;
4737             PL_reginput = locinput = HOPc(locinput, -1);
4738             goto curly_try_B_max;
4739
4740 #undef ST
4741
4742         case END:
4743             fake_end:
4744             if (cur_eval) {
4745                 /* we've just finished A in /(??{A})B/; now continue with B */
4746                 I32 tmpix;
4747
4748
4749                 st->u.eval.toggle_reg_flags
4750                             = cur_eval->u.eval.toggle_reg_flags;
4751                 PL_reg_flags ^= st->u.eval.toggle_reg_flags; 
4752
4753                 st->u.eval.prev_rex = rex;              /* inner */
4754                 rex  = cur_eval->u.eval.prev_rex;       /* outer */
4755                 rexi = RXi_GET(rex);
4756                 cur_curlyx = cur_eval->u.eval.prev_curlyx;
4757                 ReREFCNT_inc(rex);
4758                 st->u.eval.cp = regcppush(0);   /* Save *all* the positions. */
4759                 REGCP_SET(st->u.eval.lastcp);
4760                 PL_reginput = locinput;
4761
4762                 /* Restore parens of the outer rex without popping the
4763                  * savestack */
4764                 tmpix = PL_savestack_ix;
4765                 PL_savestack_ix = cur_eval->u.eval.lastcp;
4766                 regcppop(rex);
4767                 PL_savestack_ix = tmpix;
4768
4769                 st->u.eval.prev_eval = cur_eval;
4770                 cur_eval = cur_eval->u.eval.prev_eval;
4771                 DEBUG_EXECUTE_r(
4772                     PerlIO_printf(Perl_debug_log, "%*s  EVAL trying tail ... %"UVxf"\n",
4773                                       REPORT_CODE_OFF+depth*2, "",PTR2UV(cur_eval)););
4774                 PUSH_YES_STATE_GOTO(EVAL_AB,
4775                         st->u.eval.prev_eval->u.eval.B); /* match B */
4776             }
4777
4778             if (locinput < reginfo->till) {
4779                 DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log,
4780                                       "%sMatch possible, but length=%ld is smaller than requested=%ld, failing!%s\n",
4781                                       PL_colors[4],
4782                                       (long)(locinput - PL_reg_starttry),
4783                                       (long)(reginfo->till - PL_reg_starttry),
4784                                       PL_colors[5]));
4785                                               
4786                 sayNO_SILENT;           /* Cannot match: too short. */
4787             }
4788             PL_reginput = locinput;     /* put where regtry can find it */
4789             sayYES;                     /* Success! */
4790
4791         case SUCCEED: /* successful SUSPEND/UNLESSM/IFMATCH/CURLYM */
4792             DEBUG_EXECUTE_r(
4793             PerlIO_printf(Perl_debug_log,
4794                 "%*s  %ssubpattern success...%s\n",
4795                 REPORT_CODE_OFF+depth*2, "", PL_colors[4], PL_colors[5]));
4796             PL_reginput = locinput;     /* put where regtry can find it */
4797             sayYES;                     /* Success! */
4798
4799 #undef  ST
4800 #define ST st->u.ifmatch
4801
4802         case SUSPEND:   /* (?>A) */
4803             ST.wanted = 1;
4804             PL_reginput = locinput;
4805             goto do_ifmatch;    
4806
4807         case UNLESSM:   /* -ve lookaround: (?!A), or with flags, (?<!A) */
4808             ST.wanted = 0;
4809             goto ifmatch_trivial_fail_test;
4810
4811         case IFMATCH:   /* +ve lookaround: (?=A), or with flags, (?<=A) */
4812             ST.wanted = 1;
4813           ifmatch_trivial_fail_test:
4814             if (scan->flags) {
4815                 char * const s = HOPBACKc(locinput, scan->flags);
4816                 if (!s) {
4817                     /* trivial fail */
4818                     if (logical) {
4819                         logical = 0;
4820                         sw = 1 - (bool)ST.wanted;
4821                     }
4822                     else if (ST.wanted)
4823                         sayNO;
4824                     next = scan + ARG(scan);
4825                     if (next == scan)
4826                         next = NULL;
4827                     break;
4828                 }
4829                 PL_reginput = s;
4830             }
4831             else
4832                 PL_reginput = locinput;
4833
4834           do_ifmatch:
4835             ST.me = scan;
4836             ST.logical = logical;
4837             /* execute body of (?...A) */
4838             PUSH_YES_STATE_GOTO(IFMATCH_A, NEXTOPER(NEXTOPER(scan)));
4839             /* NOTREACHED */
4840
4841         case IFMATCH_A_fail: /* body of (?...A) failed */
4842             ST.wanted = !ST.wanted;
4843             /* FALL THROUGH */
4844
4845         case IFMATCH_A: /* body of (?...A) succeeded */
4846             if (ST.logical) {
4847                 sw = (bool)ST.wanted;
4848             }
4849             else if (!ST.wanted)
4850                 sayNO;
4851
4852             if (OP(ST.me) == SUSPEND)
4853                 locinput = PL_reginput;
4854             else {
4855                 locinput = PL_reginput = st->locinput;
4856                 nextchr = UCHARAT(locinput);
4857             }
4858             scan = ST.me + ARG(ST.me);
4859             if (scan == ST.me)
4860                 scan = NULL;
4861             continue; /* execute B */
4862
4863 #undef ST
4864
4865         case LONGJMP:
4866             next = scan + ARG(scan);
4867             if (next == scan)
4868                 next = NULL;
4869             break;
4870         case COMMIT:
4871             reginfo->cutpoint = PL_regeol;
4872             /* FALLTHROUGH */
4873         case PRUNE:
4874             PL_reginput = locinput;
4875             if (!scan->flags)
4876                 sv_yes_mark = sv_commit = (SV*)rexi->data->data[ ARG( scan ) ];
4877             PUSH_STATE_GOTO(COMMIT_next,next);
4878             /* NOTREACHED */
4879         case COMMIT_next_fail:
4880             no_final = 1;    
4881             /* FALLTHROUGH */       
4882         case OPFAIL:
4883             sayNO;
4884             /* NOTREACHED */
4885
4886 #define ST st->u.mark
4887         case MARKPOINT:
4888             ST.prev_mark = mark_state;
4889             ST.mark_name = sv_commit = sv_yes_mark 
4890                 = (SV*)rexi->data->data[ ARG( scan ) ];
4891             mark_state = st;
4892             ST.mark_loc = PL_reginput = locinput;
4893             PUSH_YES_STATE_GOTO(MARKPOINT_next,next);
4894             /* NOTREACHED */
4895         case MARKPOINT_next:
4896             mark_state = ST.prev_mark;
4897             sayYES;
4898             /* NOTREACHED */
4899         case MARKPOINT_next_fail:
4900             if (popmark && sv_eq(ST.mark_name,popmark)) 
4901             {
4902                 if (ST.mark_loc > startpoint)
4903                     reginfo->cutpoint = HOPBACKc(ST.mark_loc, 1);
4904                 popmark = NULL; /* we found our mark */
4905                 sv_commit = ST.mark_name;
4906
4907                 DEBUG_EXECUTE_r({
4908                         PerlIO_printf(Perl_debug_log,
4909                             "%*s  %ssetting cutpoint to mark:%"SVf"...%s\n",
4910                             REPORT_CODE_OFF+depth*2, "", 
4911                             PL_colors[4], SVfARG(sv_commit), PL_colors[5]);
4912                 });
4913             }
4914             mark_state = ST.prev_mark;
4915             sv_yes_mark = mark_state ? 
4916                 mark_state->u.mark.mark_name : NULL;
4917             sayNO;
4918             /* NOTREACHED */
4919         case SKIP:
4920             PL_reginput = locinput;
4921             if (scan->flags) {
4922                 /* (*SKIP) : if we fail we cut here*/
4923                 ST.mark_name = NULL;
4924                 ST.mark_loc = locinput;
4925                 PUSH_STATE_GOTO(SKIP_next,next);    
4926             } else {
4927                 /* (*SKIP:NAME) : if there is a (*MARK:NAME) fail where it was, 
4928                    otherwise do nothing.  Meaning we need to scan 
4929                  */
4930                 regmatch_state *cur = mark_state;
4931                 SV *find = (SV*)rexi->data->data[ ARG( scan ) ];
4932                 
4933                 while (cur) {
4934                     if ( sv_eq( cur->u.mark.mark_name, 
4935                                 find ) ) 
4936                     {
4937                         ST.mark_name = find;
4938                         PUSH_STATE_GOTO( SKIP_next, next );
4939                     }
4940                     cur = cur->u.mark.prev_mark;
4941                 }
4942             }    
4943             /* Didn't find our (*MARK:NAME) so ignore this (*SKIP:NAME) */
4944             break;    
4945         case SKIP_next_fail:
4946             if (ST.mark_name) {
4947                 /* (*CUT:NAME) - Set up to search for the name as we 
4948                    collapse the stack*/
4949                 popmark = ST.mark_name;    
4950             } else {
4951                 /* (*CUT) - No name, we cut here.*/
4952                 if (ST.mark_loc > startpoint)
4953                     reginfo->cutpoint = HOPBACKc(ST.mark_loc, 1);
4954                 /* but we set sv_commit to latest mark_name if there
4955                    is one so they can test to see how things lead to this
4956                    cut */    
4957                 if (mark_state) 
4958                     sv_commit=mark_state->u.mark.mark_name;                 
4959             } 
4960             no_final = 1; 
4961             sayNO;
4962             /* NOTREACHED */
4963 #undef ST
4964
4965         default:
4966             PerlIO_printf(Perl_error_log, "%"UVxf" %d\n",
4967                           PTR2UV(scan), OP(scan));
4968             Perl_croak(aTHX_ "regexp memory corruption");
4969             
4970         } /* end switch */ 
4971
4972         /* switch break jumps here */
4973         scan = next; /* prepare to execute the next op and ... */
4974         continue;    /* ... jump back to the top, reusing st */
4975         /* NOTREACHED */
4976
4977       push_yes_state:
4978         /* push a state that backtracks on success */
4979         st->u.yes.prev_yes_state = yes_state;
4980         yes_state = st;
4981         /* FALL THROUGH */
4982       push_state:
4983         /* push a new regex state, then continue at scan  */
4984         {
4985             regmatch_state *newst;
4986
4987             DEBUG_STACK_r({
4988                 regmatch_state *cur = st;
4989                 regmatch_state *curyes = yes_state;
4990                 int curd = depth;
4991                 regmatch_slab *slab = PL_regmatch_slab;
4992                 for (;curd > -1;cur--,curd--) {
4993                     if (cur < SLAB_FIRST(slab)) {
4994                         slab = slab->prev;
4995                         cur = SLAB_LAST(slab);
4996                     }
4997                     PerlIO_printf(Perl_error_log, "%*s#%-3d %-10s %s\n",
4998                         REPORT_CODE_OFF + 2 + depth * 2,"",
4999                         curd, reg_name[cur->resume_state],
5000                         (curyes == cur) ? "yes" : ""
5001                     );
5002                     if (curyes == cur)
5003                         curyes = cur->u.yes.prev_yes_state;
5004                 }
5005             } else 
5006                 DEBUG_STATE_pp("push")
5007             );
5008             depth++;
5009             st->locinput = locinput;
5010             newst = st+1; 
5011             if (newst >  SLAB_LAST(PL_regmatch_slab))
5012                 newst = S_push_slab(aTHX);
5013             PL_regmatch_state = newst;
5014
5015             locinput = PL_reginput;
5016             nextchr = UCHARAT(locinput);
5017             st = newst;
5018             continue;
5019             /* NOTREACHED */
5020         }
5021     }
5022
5023     /*
5024     * We get here only if there's trouble -- normally "case END" is
5025     * the terminating point.
5026     */
5027     Perl_croak(aTHX_ "corrupted regexp pointers");
5028     /*NOTREACHED*/
5029     sayNO;
5030
5031 yes:
5032     if (yes_state) {
5033         /* we have successfully completed a subexpression, but we must now
5034          * pop to the state marked by yes_state and continue from there */
5035         assert(st != yes_state);
5036 #ifdef DEBUGGING
5037         while (st != yes_state) {
5038             st--;
5039             if (st < SLAB_FIRST(PL_regmatch_slab)) {
5040                 PL_regmatch_slab = PL_regmatch_slab->prev;
5041                 st = SLAB_LAST(PL_regmatch_slab);
5042             }
5043             DEBUG_STATE_r({
5044                 if (no_final) {
5045                     DEBUG_STATE_pp("pop (no final)");        
5046                 } else {
5047                     DEBUG_STATE_pp("pop (yes)");
5048                 }
5049             });
5050             depth--;
5051         }
5052 #else
5053         while (yes_state < SLAB_FIRST(PL_regmatch_slab)
5054             || yes_state > SLAB_LAST(PL_regmatch_slab))
5055         {
5056             /* not in this slab, pop slab */
5057             depth -= (st - SLAB_FIRST(PL_regmatch_slab) + 1);
5058             PL_regmatch_slab = PL_regmatch_slab->prev;
5059             st = SLAB_LAST(PL_regmatch_slab);
5060         }
5061         depth -= (st - yes_state);
5062 #endif
5063         st = yes_state;
5064         yes_state = st->u.yes.prev_yes_state;
5065         PL_regmatch_state = st;
5066         
5067         if (no_final) {
5068             locinput= st->locinput;
5069             nextchr = UCHARAT(locinput);
5070         }
5071         state_num = st->resume_state + no_final;
5072         goto reenter_switch;
5073     }
5074
5075     DEBUG_EXECUTE_r(PerlIO_printf(Perl_debug_log, "%sMatch successful!%s\n",
5076                           PL_colors[4], PL_colors[5]));
5077
5078     result = 1;
5079     goto final_exit;
5080
5081 no:
5082     DEBUG_EXECUTE_r(
5083         PerlIO_printf(Perl_debug_log,
5084             "%*s  %sfailed...%s\n",
5085             REPORT_CODE_OFF+depth*2, "", 
5086             PL_colors[4], PL_colors[5])
5087         );
5088
5089 no_silent:
5090     if (no_final) {
5091         if (yes_state) {
5092             goto yes;
5093         } else {
5094             goto final_exit;
5095         }
5096     }    
5097     if (depth) {
5098         /* there's a previous state to backtrack to */
5099         st--;
5100         if (st < SLAB_FIRST(PL_regmatch_slab)) {
5101             PL_regmatch_slab = PL_regmatch_slab->prev;
5102             st = SLAB_LAST(PL_regmatch_slab);
5103         }
5104         PL_regmatch_state = st;
5105         locinput= st->locinput;
5106         nextchr = UCHARAT(locinput);
5107
5108         DEBUG_STATE_pp("pop");
5109         depth--;
5110         if (yes_state == st)
5111             yes_state = st->u.yes.prev_yes_state;
5112
5113         state_num = st->resume_state + 1; /* failure = success + 1 */
5114         goto reenter_switch;
5115     }
5116     result = 0;
5117
5118   final_exit:
5119     if (rex->intflags & PREGf_VERBARG_SEEN) {
5120         SV *sv_err = get_sv("REGERROR", 1);
5121         SV *sv_mrk = get_sv("REGMARK", 1);
5122         if (result) {
5123             sv_commit = &PL_sv_no;
5124             if (!sv_yes_mark) 
5125                 sv_yes_mark = &PL_sv_yes;
5126         } else {
5127             if (!sv_commit) 
5128                 sv_commit = &PL_sv_yes;
5129             sv_yes_mark = &PL_sv_no;
5130         }
5131         sv_setsv(sv_err, sv_commit);
5132         sv_setsv(sv_mrk, sv_yes_mark);
5133     }
5134     /* restore original high-water mark */
5135     PL_regmatch_slab  = orig_slab;
5136     PL_regmatch_state = orig_state;
5137
5138     /* free all slabs above current one */
5139     if (orig_slab->next) {
5140         regmatch_slab *sl = orig_slab->next;
5141         orig_slab->next = NULL;
5142         while (sl) {
5143             regmatch_slab * const osl = sl;
5144             sl = sl->next;
5145             Safefree(osl);
5146         }
5147     }
5148
5149     return result;
5150 }
5151
5152 /*
5153  - regrepeat - repeatedly match something simple, report how many
5154  */
5155 /*
5156  * [This routine now assumes that it will only match on things of length 1.
5157  * That was true before, but now we assume scan - reginput is the count,
5158  * rather than incrementing count on every character.  [Er, except utf8.]]
5159  */
5160 STATIC I32
5161 S_regrepeat(pTHX_ const regexp *prog, const regnode *p, I32 max, int depth)
5162 {
5163     dVAR;
5164     register char *scan;
5165     register I32 c;
5166     register char *loceol = PL_regeol;
5167     register I32 hardcount = 0;
5168     register bool do_utf8 = PL_reg_match_utf8;
5169
5170     scan = PL_reginput;
5171     if (max == REG_INFTY)
5172         max = I32_MAX;
5173     else if (max < loceol - scan)
5174         loceol = scan + max;
5175     switch (OP(p)) {
5176     case REG_ANY:
5177         if (do_utf8) {
5178             loceol = PL_regeol;
5179             while (scan < loceol && hardcount < max && *scan != '\n') {
5180                 scan += UTF8SKIP(scan);
5181                 hardcount++;
5182             }
5183         } else {
5184             while (scan < loceol && *scan != '\n')
5185                 scan++;
5186         }
5187         break;
5188     case SANY:
5189         if (do_utf8) {
5190             loceol = PL_regeol;
5191             while (scan < loceol && hardcount < max) {
5192                 scan += UTF8SKIP(scan);
5193                 hardcount++;
5194             }
5195         }
5196         else
5197             scan = loceol;
5198         break;
5199     case CANY:
5200         scan = loceol;
5201         break;
5202     case EXACT:         /* length of string is 1 */
5203         c = (U8)*STRING(p);
5204         while (scan < loceol && UCHARAT(scan) == c)
5205             scan++;
5206         break;
5207     case EXACTF:        /* length of string is 1 */
5208         c = (U8)*STRING(p);
5209         while (scan < loceol &&
5210                (UCHARAT(scan) == c || UCHARAT(scan) == PL_fold[c]))
5211             scan++;
5212         break;
5213     case EXACTFL:       /* length of string is 1 */
5214         PL_reg_flags |= RF_tainted;
5215         c = (U8)*STRING(p);
5216         while (scan < loceol &&
5217                (UCHARAT(scan) == c || UCHARAT(scan) == PL_fold_locale[c]))
5218             scan++;
5219         break;
5220     case ANYOF:
5221         if (do_utf8) {
5222             loceol = PL_regeol;
5223             while (hardcount < max && scan < loceol &&
5224                    reginclass(prog, p, (U8*)scan, 0, do_utf8)) {
5225                 scan += UTF8SKIP(scan);
5226                 hardcount++;
5227             }
5228         } else {
5229             while (scan < loceol && REGINCLASS(prog, p, (U8*)scan))
5230                 scan++;
5231         }
5232         break;
5233     case ALNUM:
5234         if (do_utf8) {
5235             loceol = PL_regeol;
5236             LOAD_UTF8_CHARCLASS_ALNUM();
5237             while (hardcount < max && scan < loceol &&
5238                    swash_fetch(PL_utf8_alnum, (U8*)scan, do_utf8)) {
5239                 scan += UTF8SKIP(scan);
5240                 hardcount++;
5241             }
5242         } else {
5243             while (scan < loceol && isALNUM(*scan))
5244                 scan++;
5245         }
5246         break;
5247     case ALNUML:
5248         PL_reg_flags |= RF_tainted;
5249         if (do_utf8) {
5250             loceol = PL_regeol;
5251             while (hardcount < max && scan < loceol &&
5252                    isALNUM_LC_utf8((U8*)scan)) {
5253                 scan += UTF8SKIP(scan);
5254                 hardcount++;
5255             }
5256         } else {
5257             while (scan < loceol && isALNUM_LC(*scan))
5258                 scan++;
5259         }
5260         break;
5261     case NALNUM:
5262         if (do_utf8) {
5263             loceol = PL_regeol;
5264             LOAD_UTF8_CHARCLASS_ALNUM();
5265             while (hardcount < max && scan < loceol &&
5266                    !swash_fetch(PL_utf8_alnum, (U8*)scan, do_utf8)) {
5267                 scan += UTF8SKIP(scan);
5268                 hardcount++;
5269             }
5270         } else {
5271             while (scan < loceol && !isALNUM(*scan))
5272                 scan++;
5273         }
5274         break;
5275     case NALNUML:
5276         PL_reg_flags |= RF_tainted;
5277         if (do_utf8) {
5278             loceol = PL_regeol;
5279             while (hardcount < max && scan < loceol &&
5280                    !isALNUM_LC_utf8((U8*)scan)) {
5281                 scan += UTF8SKIP(scan);
5282                 hardcount++;
5283             }
5284         } else {
5285             while (scan < loceol && !isALNUM_LC(*scan))
5286                 scan++;
5287         }
5288         break;
5289     case SPACE:
5290         if (do_utf8) {
5291             loceol = PL_regeol;
5292             LOAD_UTF8_CHARCLASS_SPACE();
5293             while (hardcount < max && scan < loceol &&
5294                    (*scan == ' ' ||
5295                     swash_fetch(PL_utf8_space,(U8*)scan, do_utf8))) {
5296                 scan += UTF8SKIP(scan);
5297                 hardcount++;
5298             }
5299         } else {
5300             while (scan < loceol && isSPACE(*scan))
5301                 scan++;
5302         }
5303         break;
5304     case SPACEL:
5305         PL_reg_flags |= RF_tainted;
5306         if (do_utf8) {
5307             loceol = PL_regeol;
5308             while (hardcount < max && scan < loceol &&
5309                    (*scan == ' ' || isSPACE_LC_utf8((U8*)scan))) {
5310                 scan += UTF8SKIP(scan);
5311                 hardcount++;
5312             }
5313         } else {
5314             while (scan < loceol && isSPACE_LC(*scan))
5315                 scan++;
5316         }
5317         break;
5318     case NSPACE:
5319         if (do_utf8) {
5320             loceol = PL_regeol;
5321             LOAD_UTF8_CHARCLASS_SPACE();
5322             while (hardcount < max && scan < loceol &&
5323                    !(*scan == ' ' ||
5324                      swash_fetch(PL_utf8_space,(U8*)scan, do_utf8))) {
5325                 scan += UTF8SKIP(scan);
5326                 hardcount++;
5327             }
5328         } else {
5329             while (scan < loceol && !isSPACE(*scan))
5330                 scan++;
5331             break;
5332         }
5333     case NSPACEL:
5334         PL_reg_flags |= RF_tainted;
5335         if (do_utf8) {
5336             loceol = PL_regeol;
5337             while (hardcount < max && scan < loceol &&
5338                    !(*scan == ' ' || isSPACE_LC_utf8((U8*)scan))) {
5339                 scan += UTF8SKIP(scan);
5340                 hardcount++;
5341             }
5342         } else {
5343             while (scan < loceol && !isSPACE_LC(*scan))
5344                 scan++;
5345         }
5346         break;
5347     case DIGIT:
5348         if (do_utf8) {
5349             loceol = PL_regeol;
5350             LOAD_UTF8_CHARCLASS_DIGIT();
5351             while (hardcount < max && scan < loceol &&
5352                    swash_fetch(PL_utf8_digit, (U8*)scan, do_utf8)) {
5353                 scan += UTF8SKIP(scan);
5354                 hardcount++;
5355             }
5356         } else {
5357             while (scan < loceol && isDIGIT(*scan))
5358                 scan++;
5359         }
5360         break;
5361     case NDIGIT:
5362         if (do_utf8) {
5363             loceol = PL_regeol;
5364             LOAD_UTF8_CHARCLASS_DIGIT();
5365             while (hardcount < max && scan < loceol &&
5366                    !swash_fetch(PL_utf8_digit, (U8*)scan, do_utf8)) {
5367                 scan += UTF8SKIP(scan);
5368                 hardcount++;
5369             }
5370         } else {
5371             while (scan < loceol && !isDIGIT(*scan))
5372                 scan++;
5373         }
5374         break;
5375     default:            /* Called on something of 0 width. */
5376         break;          /* So match right here or not at all. */
5377     }
5378
5379     if (hardcount)
5380         c = hardcount;
5381     else
5382         c = scan - PL_reginput;
5383     PL_reginput = scan;
5384
5385     DEBUG_r({
5386         GET_RE_DEBUG_FLAGS_DECL;
5387         DEBUG_EXECUTE_r({
5388             SV * const prop = sv_newmortal();
5389             regprop(prog, prop, p);
5390             PerlIO_printf(Perl_debug_log,
5391                         "%*s  %s can match %"IVdf" times out of %"IVdf"...\n",
5392                         REPORT_CODE_OFF + depth*2, "", SvPVX_const(prop),(IV)c,(IV)max);
5393         });
5394     });
5395
5396     return(c);
5397 }
5398
5399
5400 #if !defined(PERL_IN_XSUB_RE) || defined(PLUGGABLE_RE_EXTENSION)
5401 /*
5402 - regclass_swash - prepare the utf8 swash
5403 */
5404
5405 SV *
5406 Perl_regclass_swash(pTHX_ const regexp *prog, register const regnode* node, bool doinit, SV** listsvp, SV **altsvp)
5407 {
5408     dVAR;
5409     SV *sw  = NULL;
5410     SV *si  = NULL;
5411     SV *alt = NULL;
5412     RXi_GET_DECL(prog,progi);
5413     const struct reg_data * const data = prog ? progi->data : NULL;
5414
5415     if (data && data->count) {
5416         const U32 n = ARG(node);
5417
5418         if (data->what[n] == 's') {
5419             SV * const rv = (SV*)data->data[n];
5420             AV * const av = (AV*)SvRV((SV*)rv);
5421             SV **const ary = AvARRAY(av);
5422             SV **a, **b;
5423         
5424             /* See the end of regcomp.c:S_regclass() for
5425              * documentation of these array elements. */
5426
5427             si = *ary;
5428             a  = SvROK(ary[1]) ? &ary[1] : 0;
5429             b  = SvTYPE(ary[2]) == SVt_PVAV ? &ary[2] : 0;
5430
5431             if (a)
5432                 sw = *a;
5433             else if (si && doinit) {
5434                 sw = swash_init("utf8", "", si, 1, 0);
5435                 (void)av_store(av, 1, sw);
5436             }
5437             if (b)
5438                 alt = *b;
5439         }
5440     }
5441         
5442     if (listsvp)
5443         *listsvp = si;
5444     if (altsvp)
5445         *altsvp  = alt;
5446
5447     return sw;
5448 }
5449 #endif
5450
5451 /*
5452  - reginclass - determine if a character falls into a character class
5453  
5454   The n is the ANYOF regnode, the p is the target string, lenp
5455   is pointer to the maximum length of how far to go in the p
5456   (if the lenp is zero, UTF8SKIP(p) is used),
5457   do_utf8 tells whether the target string is in UTF-8.
5458
5459  */
5460
5461 STATIC bool
5462 S_reginclass(pTHX_ const regexp *prog, register const regnode *n, register const U8* p, STRLEN* lenp, register bool do_utf8)
5463 {
5464     dVAR;
5465     const char flags = ANYOF_FLAGS(n);
5466     bool match = FALSE;
5467     UV c = *p;
5468     STRLEN len = 0;
5469     STRLEN plen;
5470
5471     if (do_utf8 && !UTF8_IS_INVARIANT(c)) {
5472         c = utf8n_to_uvchr(p, UTF8_MAXBYTES, &len,
5473                 (UTF8_ALLOW_DEFAULT & UTF8_ALLOW_ANYUV) | UTF8_CHECK_ONLY);
5474                 /* see [perl #37836] for UTF8_ALLOW_ANYUV */
5475         if (len == (STRLEN)-1) 
5476             Perl_croak(aTHX_ "Malformed UTF-8 character (fatal)");
5477     }
5478
5479     plen = lenp ? *lenp : UNISKIP(NATIVE_TO_UNI(c));
5480     if (do_utf8 || (flags & ANYOF_UNICODE)) {
5481         if (lenp)
5482             *lenp = 0;
5483         if (do_utf8 && !ANYOF_RUNTIME(n)) {
5484             if (len != (STRLEN)-1 && c < 256 && ANYOF_BITMAP_TEST(n, c))
5485                 match = TRUE;
5486         }
5487         if (!match && do_utf8 && (flags & ANYOF_UNICODE_ALL) && c >= 256)
5488             match = TRUE;
5489         if (!match) {
5490             AV *av;
5491             SV * const sw = regclass_swash(prog, n, TRUE, 0, (SV**)&av);
5492         
5493             if (sw) {
5494                 if (swash_fetch(sw, p, do_utf8))
5495                     match = TRUE;
5496                 else if (flags & ANYOF_FOLD) {
5497                     if (!match && lenp && av) {
5498                         I32 i;
5499                         for (i = 0; i <= av_len(av); i++) {
5500                             SV* const sv = *av_fetch(av, i, FALSE);
5501                             STRLEN len;
5502                             const char * const s = SvPV_const(sv, len);
5503                         
5504                             if (len <= plen && memEQ(s, (char*)p, len)) {
5505                                 *lenp = len;
5506                                 match = TRUE;
5507                                 break;
5508                             }
5509                         }
5510                     }
5511                     if (!match) {
5512                         U8 tmpbuf[UTF8_MAXBYTES_CASE+1];
5513                         STRLEN tmplen;
5514
5515                         to_utf8_fold(p, tmpbuf, &tmplen);
5516                         if (swash_fetch(sw, tmpbuf, do_utf8))
5517                             match = TRUE;
5518                     }
5519                 }
5520             }
5521         }
5522         if (match && lenp && *lenp == 0)
5523             *lenp = UNISKIP(NATIVE_TO_UNI(c));
5524     }
5525     if (!match && c < 256) {
5526         if (ANYOF_BITMAP_TEST(n, c))
5527             match = TRUE;
5528         else if (flags & ANYOF_FOLD) {
5529             U8 f;
5530
5531             if (flags & ANYOF_LOCALE) {
5532                 PL_reg_flags |= RF_tainted;
5533                 f = PL_fold_locale[c];
5534             }
5535             else
5536                 f = PL_fold[c];
5537             if (f != c && ANYOF_BITMAP_TEST(n, f))
5538                 match = TRUE;
5539         }
5540         
5541         if (!match && (flags & ANYOF_CLASS)) {
5542             PL_reg_flags |= RF_tainted;
5543             if (
5544                 (ANYOF_CLASS_TEST(n, ANYOF_ALNUM)   &&  isALNUM_LC(c))  ||
5545                 (ANYOF_CLASS_TEST(n, ANYOF_NALNUM)  && !isALNUM_LC(c))  ||
5546                 (ANYOF_CLASS_TEST(n, ANYOF_SPACE)   &&  isSPACE_LC(c))  ||
5547                 (ANYOF_CLASS_TEST(n, ANYOF_NSPACE)  && !isSPACE_LC(c))  ||
5548                 (ANYOF_CLASS_TEST(n, ANYOF_DIGIT)   &&  isDIGIT_LC(c))  ||
5549                 (ANYOF_CLASS_TEST(n, ANYOF_NDIGIT)  && !isDIGIT_LC(c))  ||
5550                 (ANYOF_CLASS_TEST(n, ANYOF_ALNUMC)  &&  isALNUMC_LC(c)) ||
5551                 (ANYOF_CLASS_TEST(n, ANYOF_NALNUMC) && !isALNUMC_LC(c)) ||
5552                 (ANYOF_CLASS_TEST(n, ANYOF_ALPHA)   &&  isALPHA_LC(c))  ||
5553                 (ANYOF_CLASS_TEST(n, ANYOF_NALPHA)  && !isALPHA_LC(c))  ||
5554                 (ANYOF_CLASS_TEST(n, ANYOF_ASCII)   &&  isASCII(c))     ||
5555                 (ANYOF_CLASS_TEST(n, ANYOF_NASCII)  && !isASCII(c))     ||
5556                 (ANYOF_CLASS_TEST(n, ANYOF_CNTRL)   &&  isCNTRL_LC(c))  ||
5557                 (ANYOF_CLASS_TEST(n, ANYOF_NCNTRL)  && !isCNTRL_LC(c))  ||
5558                 (ANYOF_CLASS_TEST(n, ANYOF_GRAPH)   &&  isGRAPH_LC(c))  ||
5559                 (ANYOF_CLASS_TEST(n, ANYOF_NGRAPH)  && !isGRAPH_LC(c))  ||
5560                 (ANYOF_CLASS_TEST(n, ANYOF_LOWER)   &&  isLOWER_LC(c))  ||
5561                 (ANYOF_CLASS_TEST(n, ANYOF_NLOWER)  && !isLOWER_LC(c))  ||
5562                 (ANYOF_CLASS_TEST(n, ANYOF_PRINT)   &&  isPRINT_LC(c))  ||
5563                 (ANYOF_CLASS_TEST(n, ANYOF_NPRINT)  && !isPRINT_LC(c))  ||
5564                 (ANYOF_CLASS_TEST(n, ANYOF_PUNCT)   &&  isPUNCT_LC(c))  ||
5565                 (ANYOF_CLASS_TEST(n, ANYOF_NPUNCT)  && !isPUNCT_LC(c))  ||
5566                 (ANYOF_CLASS_TEST(n, ANYOF_UPPER)   &&  isUPPER_LC(c))  ||
5567                 (ANYOF_CLASS_TEST(n, ANYOF_NUPPER)  && !isUPPER_LC(c))  ||
5568                 (ANYOF_CLASS_TEST(n, ANYOF_XDIGIT)  &&  isXDIGIT(c))    ||
5569                 (ANYOF_CLASS_TEST(n, ANYOF_NXDIGIT) && !isXDIGIT(c))    ||
5570                 (ANYOF_CLASS_TEST(n, ANYOF_PSXSPC)  &&  isPSXSPC(c))    ||
5571                 (ANYOF_CLASS_TEST(n, ANYOF_NPSXSPC) && !isPSXSPC(c))    ||
5572                 (ANYOF_CLASS_TEST(n, ANYOF_BLANK)   &&  isBLANK(c))     ||
5573                 (ANYOF_CLASS_TEST(n, ANYOF_NBLANK)  && !isBLANK(c))
5574                 ) /* How's that for a conditional? */
5575             {
5576                 match = TRUE;
5577             }
5578         }
5579     }
5580
5581     return (flags & ANYOF_INVERT) ? !match : match;
5582 }
5583
5584 STATIC U8 *
5585 S_reghop3(U8 *s, I32 off, const U8* lim)
5586 {
5587     dVAR;
5588     if (off >= 0) {
5589         while (off-- && s < lim) {
5590             /* XXX could check well-formedness here */
5591             s += UTF8SKIP(s);
5592         }
5593     }
5594     else {
5595         while (off++ && s > lim) {
5596             s--;
5597             if (UTF8_IS_CONTINUED(*s)) {
5598                 while (s > lim && UTF8_IS_CONTINUATION(*s))
5599                     s--;
5600             }
5601             /* XXX could check well-formedness here */
5602         }
5603     }
5604     return s;
5605 }
5606
5607 #ifdef XXX_dmq
5608 /* there are a bunch of places where we use two reghop3's that should
5609    be replaced with this routine. but since thats not done yet 
5610    we ifdef it out - dmq
5611 */
5612 STATIC U8 *
5613 S_reghop4(U8 *s, I32 off, const U8* llim, const U8* rlim)
5614 {
5615     dVAR;
5616     if (off >= 0) {
5617         while (off-- && s < rlim) {
5618             /* XXX could check well-formedness here */
5619             s += UTF8SKIP(s);
5620         }
5621     }
5622     else {
5623         while (off++ && s > llim) {
5624             s--;
5625             if (UTF8_IS_CONTINUED(*s)) {
5626                 while (s > llim && UTF8_IS_CONTINUATION(*s))
5627                     s--;
5628             }
5629             /* XXX could check well-formedness here */
5630         }
5631     }
5632     return s;
5633 }
5634 #endif
5635
5636 STATIC U8 *
5637 S_reghopmaybe3(U8* s, I32 off, const U8* lim)
5638 {
5639     dVAR;
5640     if (off >= 0) {
5641         while (off-- && s < lim) {
5642             /* XXX could check well-formedness here */
5643             s += UTF8SKIP(s);
5644         }
5645         if (off >= 0)
5646             return NULL;
5647     }
5648     else {
5649         while (off++ && s > lim) {
5650             s--;
5651             if (UTF8_IS_CONTINUED(*s)) {
5652                 while (s > lim && UTF8_IS_CONTINUATION(*s))
5653                     s--;
5654             }
5655             /* XXX could check well-formedness here */
5656         }
5657         if (off <= 0)
5658             return NULL;
5659     }
5660     return s;
5661 }
5662
5663 static void
5664 restore_pos(pTHX_ void *arg)
5665 {
5666     dVAR;
5667     regexp * const rex = (regexp *)arg;
5668     if (PL_reg_eval_set) {
5669         if (PL_reg_oldsaved) {
5670             rex->subbeg = PL_reg_oldsaved;
5671             rex->sublen = PL_reg_oldsavedlen;
5672 #ifdef PERL_OLD_COPY_ON_WRITE
5673             rex->saved_copy = PL_nrs;
5674 #endif
5675             RX_MATCH_COPIED_on(rex);
5676         }
5677         PL_reg_magic->mg_len = PL_reg_oldpos;
5678         PL_reg_eval_set = 0;
5679         PL_curpm = PL_reg_oldcurpm;
5680     }   
5681 }
5682
5683 STATIC void
5684 S_to_utf8_substr(pTHX_ register regexp *prog)
5685 {
5686     int i = 1;
5687     do {
5688         if (prog->substrs->data[i].substr
5689             && !prog->substrs->data[i].utf8_substr) {
5690             SV* const sv = newSVsv(prog->substrs->data[i].substr);
5691             prog->substrs->data[i].utf8_substr = sv;
5692             sv_utf8_upgrade(sv);
5693             if (SvVALID(prog->substrs->data[i].substr))
5694                 fbm_compile(sv, 0);
5695             if (SvTAIL(prog->substrs->data[i].substr))
5696                 SvTAIL_on(sv);
5697             if (prog->substrs->data[i].substr == prog->check_substr)
5698                 prog->check_utf8 = sv;
5699         }
5700     } while (i--);
5701 }
5702
5703 STATIC void
5704 S_to_byte_substr(pTHX_ register regexp *prog)
5705 {
5706     dVAR;
5707     int i = 1;
5708     do {
5709         if (prog->substrs->data[i].utf8_substr
5710             && !prog->substrs->data[i].substr) {
5711             SV* sv = newSVsv(prog->substrs->data[i].utf8_substr);
5712             if (sv_utf8_downgrade(sv, TRUE)) {
5713                 if (SvVALID(prog->substrs->data[i].utf8_substr))
5714                     fbm_compile(sv, 0);
5715                 if (SvTAIL(prog->substrs->data[i].utf8_substr))
5716                     SvTAIL_on(sv);
5717             } else {
5718                 SvREFCNT_dec(sv);
5719                 sv = &PL_sv_undef;
5720             }
5721             prog->substrs->data[i].substr = sv;
5722             if (prog->substrs->data[i].utf8_substr == prog->check_utf8)
5723                 prog->check_substr = sv;
5724         }
5725     } while (i--);
5726 }
5727
5728 /*
5729  * Local variables:
5730  * c-indentation-style: bsd
5731  * c-basic-offset: 4
5732  * indent-tabs-mode: t
5733  * End:
5734  *
5735  * ex: set ts=8 sts=4 sw=4 noet:
5736  */