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