f6ed3287ef63c57ba4623677b4f8b7d6487ebaff
[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 /* NOTE: this is derived from Henry Spencer's regexp code, and should not
9  * confused with the original package (see point 3 below).  Thanks, Henry!
10  */
11
12 /* Additional note: this code is very heavily munged from Henry's version
13  * in places.  In some spots I've traded clarity for efficiency, so don't
14  * blame Henry for some of the lack of readability.
15  */
16
17 /* The names of the functions have been changed from regcomp and
18  * regexec to  pregcomp and pregexec in order to avoid conflicts
19  * with the POSIX routines of the same names.
20 */
21
22 #ifdef PERL_EXT_RE_BUILD
23 /* need to replace pregcomp et al, so enable that */
24 #  ifndef PERL_IN_XSUB_RE
25 #    define PERL_IN_XSUB_RE
26 #  endif
27 /* need access to debugger hooks */
28 #  if defined(PERL_EXT_RE_DEBUG) && !defined(DEBUGGING)
29 #    define DEBUGGING
30 #  endif
31 #endif
32
33 #ifdef PERL_IN_XSUB_RE
34 /* We *really* need to overwrite these symbols: */
35 #  define Perl_regexec_flags my_regexec
36 #  define Perl_regdump my_regdump
37 #  define Perl_regprop my_regprop
38 #  define Perl_re_intuit_start my_re_intuit_start
39 /* *These* symbols are masked to allow static link. */
40 #  define Perl_pregexec my_pregexec
41 #  define Perl_reginitcolors my_reginitcolors 
42
43 #  define PERL_NO_GET_CONTEXT
44 #endif 
45
46 /*SUPPRESS 112*/
47 /*
48  * pregcomp and pregexec -- regsub and regerror are not used in perl
49  *
50  *      Copyright (c) 1986 by University of Toronto.
51  *      Written by Henry Spencer.  Not derived from licensed software.
52  *
53  *      Permission is granted to anyone to use this software for any
54  *      purpose on any computer system, and to redistribute it freely,
55  *      subject to the following restrictions:
56  *
57  *      1. The author is not responsible for the consequences of use of
58  *              this software, no matter how awful, even if they arise
59  *              from defects in it.
60  *
61  *      2. The origin of this software must not be misrepresented, either
62  *              by explicit claim or by omission.
63  *
64  *      3. Altered versions must be plainly marked as such, and must not
65  *              be misrepresented as being the original software.
66  *
67  ****    Alterations to Henry's code are...
68  ****
69  ****    Copyright (c) 1991-1999, Larry Wall
70  ****
71  ****    You may distribute under the terms of either the GNU General Public
72  ****    License or the Artistic License, as specified in the README file.
73  *
74  * Beware that some of this code is subtly aware of the way operator
75  * precedence is structured in regular expressions.  Serious changes in
76  * regular-expression syntax might require a total rethink.
77  */
78 #include "EXTERN.h"
79 #define PERL_IN_REGEXEC_C
80 #include "perl.h"
81
82 #ifdef PERL_IN_XSUB_RE
83 #  if defined(PERL_CAPI) || defined(PERL_OBJECT)
84 #    include "XSUB.h"
85 #  endif
86 #endif
87
88 #include "regcomp.h"
89
90 #define RF_tainted      1               /* tainted information used? */
91 #define RF_warned       2               /* warned about big count? */
92 #define RF_evaled       4               /* Did an EVAL with setting? */
93 #define RF_utf8         8               /* String contains multibyte chars? */
94
95 #define UTF (PL_reg_flags & RF_utf8)
96
97 #define RS_init         1               /* eval environment created */
98 #define RS_set          2               /* replsv value is set */
99
100 #ifndef STATIC
101 #define STATIC  static
102 #endif
103
104 /*
105  * Forwards.
106  */
107
108 #define REGINCLASS(p,c)  (ANYOF_FLAGS(p) ? reginclass(p,c) : ANYOF_BITMAP_TEST(p,c))
109 #define REGINCLASSUTF8(f,p)  (ARG1(f) ? reginclassutf8(f,p) : swash_fetch((SV*)PL_regdata->data[ARG2(f)],p))
110
111 #define CHR_SVLEN(sv) (UTF ? sv_len_utf8(sv) : SvCUR(sv))
112 #define CHR_DIST(a,b) (UTF ? utf8_distance(a,b) : a - b)
113
114 #define reghop_c(pos,off) ((char*)reghop((U8*)pos, off))
115 #define reghopmaybe_c(pos,off) ((char*)reghopmaybe((U8*)pos, off))
116 #define HOP(pos,off) (UTF ? reghop((U8*)pos, off) : (U8*)(pos + off))
117 #define HOPMAYBE(pos,off) (UTF ? reghopmaybe((U8*)pos, off) : (U8*)(pos + off))
118 #define HOPc(pos,off) ((char*)HOP(pos,off))
119 #define HOPMAYBEc(pos,off) ((char*)HOPMAYBE(pos,off))
120
121 static void restore_pos(pTHXo_ void *arg);
122
123
124 STATIC CHECKPOINT
125 S_regcppush(pTHX_ I32 parenfloor)
126 {
127     dTHR;
128     int retval = PL_savestack_ix;
129     int i = (PL_regsize - parenfloor) * 4;
130     int p;
131
132     SSCHECK(i + 5);
133     for (p = PL_regsize; p > parenfloor; p--) {
134         SSPUSHINT(PL_regendp[p]);
135         SSPUSHINT(PL_regstartp[p]);
136         SSPUSHPTR(PL_reg_start_tmp[p]);
137         SSPUSHINT(p);
138     }
139     SSPUSHINT(PL_regsize);
140     SSPUSHINT(*PL_reglastparen);
141     SSPUSHPTR(PL_reginput);
142     SSPUSHINT(i + 3);
143     SSPUSHINT(SAVEt_REGCONTEXT);
144     return retval;
145 }
146
147 /* These are needed since we do not localize EVAL nodes: */
148 #  define REGCP_SET  DEBUG_r(PerlIO_printf(Perl_debug_log,              \
149                              "  Setting an EVAL scope, savestack=%i\n", \
150                              PL_savestack_ix)); lastcp = PL_savestack_ix
151
152 #  define REGCP_UNWIND  DEBUG_r(lastcp != PL_savestack_ix ?             \
153                                 PerlIO_printf(Perl_debug_log,           \
154                                 "  Clearing an EVAL scope, savestack=%i..%i\n", \
155                                 lastcp, PL_savestack_ix) : 0); regcpblow(lastcp)
156
157 STATIC char *
158 S_regcppop(pTHX)
159 {
160     dTHR;
161     I32 i = SSPOPINT;
162     U32 paren = 0;
163     char *input;
164     I32 tmps;
165     assert(i == SAVEt_REGCONTEXT);
166     i = SSPOPINT;
167     input = (char *) SSPOPPTR;
168     *PL_reglastparen = SSPOPINT;
169     PL_regsize = SSPOPINT;
170     for (i -= 3; i > 0; i -= 4) {
171         paren = (U32)SSPOPINT;
172         PL_reg_start_tmp[paren] = (char *) SSPOPPTR;
173         PL_regstartp[paren] = SSPOPINT;
174         tmps = SSPOPINT;
175         if (paren <= *PL_reglastparen)
176             PL_regendp[paren] = tmps;
177         DEBUG_r(
178             PerlIO_printf(Perl_debug_log,
179                           "     restoring \\%d to %d(%d)..%d%s\n",
180                           paren, PL_regstartp[paren], 
181                           PL_reg_start_tmp[paren] - PL_bostr,
182                           PL_regendp[paren], 
183                           (paren > *PL_reglastparen ? "(no)" : ""));
184         );
185     }
186     DEBUG_r(
187         if (*PL_reglastparen + 1 <= PL_regnpar) {
188             PerlIO_printf(Perl_debug_log,
189                           "     restoring \\%d..\\%d to undef\n",
190                           *PL_reglastparen + 1, PL_regnpar);
191         }
192     );
193     for (paren = *PL_reglastparen + 1; paren <= PL_regnpar; paren++) {
194         if (paren > PL_regsize)
195             PL_regstartp[paren] = -1;
196         PL_regendp[paren] = -1;
197     }
198     return input;
199 }
200
201 STATIC char *
202 S_regcp_set_to(pTHX_ I32 ss)
203 {
204     dTHR;
205     I32 tmp = PL_savestack_ix;
206
207     PL_savestack_ix = ss;
208     regcppop();
209     PL_savestack_ix = tmp;
210     return Nullch;
211 }
212
213 typedef struct re_cc_state
214 {
215     I32 ss;
216     regnode *node;
217     struct re_cc_state *prev;
218     CURCUR *cc;
219     regexp *re;
220 } re_cc_state;
221
222 #define regcpblow(cp) LEAVE_SCOPE(cp)
223
224 /*
225  * pregexec and friends
226  */
227
228 /*
229  - pregexec - match a regexp against a string
230  */
231 I32
232 Perl_pregexec(pTHX_ register regexp *prog, char *stringarg, register char *strend,
233          char *strbeg, I32 minend, SV *screamer, U32 nosave)
234 /* strend: pointer to null at end of string */
235 /* strbeg: real beginning of string */
236 /* minend: end of match must be >=minend after stringarg. */
237 /* nosave: For optimizations. */
238 {
239     return
240         regexec_flags(prog, stringarg, strend, strbeg, minend, screamer, NULL, 
241                       nosave ? 0 : REXEC_COPY_STR);
242 }
243
244 STATIC void
245 S_cache_re(pTHX_ regexp *prog)
246 {
247     dTHR;
248     PL_regprecomp = prog->precomp;              /* Needed for FAIL. */
249 #ifdef DEBUGGING
250     PL_regprogram = prog->program;
251 #endif
252     PL_regnpar = prog->nparens;
253     PL_regdata = prog->data;    
254     PL_reg_re = prog;    
255 }
256
257 /* 
258  * Need to implement the following flags for reg_anch:
259  *
260  * USE_INTUIT_NOML              - Useful to call re_intuit_start() first
261  * USE_INTUIT_ML
262  * INTUIT_AUTORITATIVE_NOML     - Can trust a positive answer
263  * INTUIT_AUTORITATIVE_ML
264  * INTUIT_ONCE_NOML             - Intuit can match in one location only.
265  * INTUIT_ONCE_ML
266  *
267  * Another flag for this function: SECOND_TIME (so that float substrs
268  * with giant delta may be not rechecked).
269  */
270
271 /* Assumptions: if ANCH_GPOS, then strpos is anchored. XXXX Check GPOS logic */
272
273 /* If SCREAM, then sv should be compatible with strpos and strend.
274    Otherwise, only SvCUR(sv) is used to get strbeg. */
275
276 /* XXXX We assume that strpos is strbeg unless sv. */
277
278 char *
279 Perl_re_intuit_start(pTHX_ regexp *prog, SV *sv, char *strpos,
280                      char *strend, U32 flags, re_scream_pos_data *data)
281 {
282     I32 start_shift;
283     /* Should be nonnegative! */
284     I32 end_shift;
285     char *s;
286     char *t;
287     I32 ml_anch;
288
289     DEBUG_r( if (!PL_colorset) reginitcolors() );
290     DEBUG_r(PerlIO_printf(Perl_debug_log,
291                       "%sGuessing start of match:%s `%s%.60s%s%s' against `%s%.*s%s%s'\n",
292                       PL_colors[4],PL_colors[5],PL_colors[0],
293                       prog->precomp,
294                       PL_colors[1],
295                       (strlen(prog->precomp) > 60 ? "..." : ""),
296                       PL_colors[0],
297                       (strend - strpos > 60 ? 60 : strend - strpos),
298                       strpos, PL_colors[1],
299                       (strend - strpos > 60 ? "..." : ""))
300         );
301
302     if (prog->minlen > strend - strpos)
303         goto fail;
304
305     /* XXXX Move further down? */
306     start_shift = prog->check_offset_min;       /* okay to underestimate on CC */
307     /* Should be nonnegative! */
308     end_shift = prog->minlen - start_shift -
309         CHR_SVLEN(prog->check_substr) + (SvTAIL(prog->check_substr) != 0);
310
311     if (prog->reganch & ROPT_ANCH) {
312         ml_anch = !( (prog->reganch & ROPT_ANCH_SINGLE)
313                      || ( (prog->reganch & ROPT_ANCH_BOL)
314                           && !PL_multiline ) );
315
316         if ((prog->check_offset_min == prog->check_offset_max) && !ml_anch) {
317             /* Anchored... */
318             I32 slen;
319
320             if ( !(prog->reganch & ROPT_ANCH_GPOS) /* Checked by the caller */
321                  && (sv && (strpos + SvCUR(sv) != strend)) )
322                 goto fail;
323
324             PL_regeol = strend;                 /* Used in HOP() */
325             s = (char*)HOP((U8*)strpos, prog->check_offset_min);
326             if (SvTAIL(prog->check_substr)) {
327                 slen = SvCUR(prog->check_substr);       /* >= 1 */
328
329                 if ( strend - s > slen || strend - s < slen - 1 ) {
330                     s = Nullch;
331                     goto finish;
332                 }
333                 if ( strend - s == slen && strend[-1] != '\n') {
334                     s = Nullch;
335                     goto finish;
336                 }
337                 /* Now should match s[0..slen-2] */
338                 slen--;
339                 if (slen && (*SvPVX(prog->check_substr) != *s
340                              || (slen > 1
341                                  && memNE(SvPVX(prog->check_substr), s, slen))))
342                     s = Nullch;
343             }
344             else if (*SvPVX(prog->check_substr) != *s
345                      || ((slen = SvCUR(prog->check_substr)) > 1
346                          && memNE(SvPVX(prog->check_substr), s, slen)))
347                     s = Nullch;
348             else
349                     s = strpos;
350             goto finish;
351         }
352         s = strpos;
353         if (!ml_anch && (s + prog->check_offset_max < strend - prog->minlen))
354             end_shift += strend - s - prog->minlen - prog->check_offset_max;
355     }
356     else {
357         ml_anch = 0;
358         s = strpos;
359     }
360
361   restart:
362     if (end_shift < 0)
363         end_shift = 0; /* can happen when strend == strpos */
364     if (flags & REXEC_SCREAM) {
365         SV *c = prog->check_substr;
366         char *strbeg = SvPVX(sv);       /* XXXX Assume PV_force() on SCREAM! */
367         I32 p = -1;                     /* Internal iterator of scream. */
368         I32 *pp = data ? data->scream_pos : &p;
369
370         if (PL_screamfirst[BmRARE(c)] >= 0
371             || ( BmRARE(c) == '\n'
372                  && (BmPREVIOUS(c) == SvCUR(c) - 1)
373                  && SvTAIL(c) ))
374             s = screaminstr(sv, prog->check_substr, 
375                             start_shift + (strpos - strbeg), end_shift, pp, 0);
376         else
377             s = Nullch;
378         if (data)
379             *data->scream_olds = s;
380     }
381     else
382         s = fbm_instr((unsigned char*)s + start_shift,
383                       (unsigned char*)strend - end_shift,
384                       prog->check_substr, PL_multiline ? FBMrf_MULTILINE : 0);
385
386     /* Update the count-of-usability, remove useless subpatterns,
387         unshift s.  */
388   finish:
389     if (!s) {
390         ++BmUSEFUL(prog->check_substr); /* hooray */
391         goto fail;                      /* not present */
392     }
393     else if (s - strpos > prog->check_offset_max &&
394              ((prog->reganch & ROPT_UTF8)
395               ? ((t = reghopmaybe_c(s, -(prog->check_offset_max)))
396                  && t >= strpos)
397               : (t = s - prog->check_offset_max) != 0) ) {
398         if (ml_anch && t[-1] != '\n') {
399           find_anchor:
400             while (t < strend - end_shift - prog->minlen) {
401                 if (*t == '\n') {
402                     if (t < s - prog->check_offset_min) {
403                         s = t + 1;
404                         goto set_useful;
405                     }
406                     s = t + 1;
407                     goto restart;
408                 }
409                 t++;
410             }
411             s = Nullch;
412             goto finish;
413         }
414         s = t;
415       set_useful:
416         ++BmUSEFUL(prog->check_substr); /* hooray/2 */
417     }
418     else {
419         if (ml_anch && sv 
420             && (strpos + SvCUR(sv) != strend) && strpos[-1] != '\n') {
421             t = strpos;
422             goto find_anchor;
423         }
424         if (!(prog->reganch & ROPT_NAUGHTY)
425             && --BmUSEFUL(prog->check_substr) < 0
426             && prog->check_substr == prog->float_substr) { /* boo */
427             /* If flags & SOMETHING - do not do it many times on the same match */
428             SvREFCNT_dec(prog->check_substr);
429             prog->check_substr = Nullsv;        /* disable */
430             prog->float_substr = Nullsv;        /* clear */
431             s = strpos;
432             prog->reganch &= ~RE_USE_INTUIT;
433         }
434         else
435             s = strpos;
436     }
437
438     DEBUG_r(PerlIO_printf(Perl_debug_log, "%sFound%s at offset %ld\n",
439                           PL_colors[4],PL_colors[5], (long)(s - strpos)) );
440     return s;
441   fail:
442     DEBUG_r(PerlIO_printf(Perl_debug_log, "%sNot found...%s\n",
443                           PL_colors[4],PL_colors[5]));
444     return Nullch;
445 }
446
447 /*
448  - regexec_flags - match a regexp against a string
449  */
450 I32
451 Perl_regexec_flags(pTHX_ register regexp *prog, char *stringarg, register char *strend,
452               char *strbeg, I32 minend, SV *sv, void *data, U32 flags)
453 /* strend: pointer to null at end of string */
454 /* strbeg: real beginning of string */
455 /* minend: end of match must be >=minend after stringarg. */
456 /* data: May be used for some additional optimizations. */
457 /* nosave: For optimizations. */
458 {
459     dTHR;
460     register char *s;
461     register regnode *c;
462     register char *startpos = stringarg;
463     register I32 tmp;
464     I32 minlen;         /* must match at least this many chars */
465     I32 dontbother = 0; /* how many characters not to try at end */
466     CURCUR cc;
467     I32 start_shift = 0;                /* Offset of the start to find
468                                          constant substr. */            /* CC */
469     I32 end_shift = 0;                  /* Same for the end. */         /* CC */
470     I32 scream_pos = -1;                /* Internal iterator of scream. */
471     char *scream_olds;
472     SV* oreplsv = GvSV(PL_replgv);
473
474     cc.cur = 0;
475     cc.oldcc = 0;
476     PL_regcc = &cc;
477
478     cache_re(prog);
479 #ifdef DEBUGGING
480     PL_regnarrate = PL_debug & 512;
481 #endif
482
483     /* Be paranoid... */
484     if (prog == NULL || startpos == NULL) {
485         Perl_croak(aTHX_ "NULL regexp parameter");
486         return 0;
487     }
488
489     minlen = prog->minlen;
490     if (strend - startpos < minlen) goto phooey;
491
492     if (startpos == strbeg)     /* is ^ valid at stringarg? */
493         PL_regprev = '\n';
494     else {
495         PL_regprev = (U32)stringarg[-1];
496         if (!PL_multiline && PL_regprev == '\n')
497             PL_regprev = '\0';          /* force ^ to NOT match */
498     }
499
500     /* Check validity of program. */
501     if (UCHARAT(prog->program) != REG_MAGIC) {
502         Perl_croak(aTHX_ "corrupted regexp program");
503     }
504
505     PL_reg_flags = 0;
506     PL_reg_eval_set = 0;
507
508     if (prog->reganch & ROPT_UTF8)
509         PL_reg_flags |= RF_utf8;
510
511     /* Mark beginning of line for ^ and lookbehind. */
512     PL_regbol = startpos;
513     PL_bostr  = strbeg;
514     PL_reg_sv = sv;
515
516     /* Mark end of line for $ (and such) */
517     PL_regeol = strend;
518
519     /* see how far we have to get to not match where we matched before */
520     PL_regtill = startpos+minend;
521
522     /* We start without call_cc context.  */
523     PL_reg_call_cc = 0;
524
525     /* If there is a "must appear" string, look for it. */
526     s = startpos;
527
528     if (prog->reganch & ROPT_GPOS_SEEN) {
529         MAGIC *mg;
530
531         if (!(flags & REXEC_IGNOREPOS) && sv && SvTYPE(sv) >= SVt_PVMG
532             && SvMAGIC(sv) && (mg = mg_find(sv, 'g')) && mg->mg_len >= 0)
533             PL_reg_ganch = strbeg + mg->mg_len;
534         else
535             PL_reg_ganch = startpos;
536         if (prog->reganch & ROPT_ANCH_GPOS) {
537             if (s > PL_reg_ganch)
538                 goto phooey;
539             s = PL_reg_ganch;
540         }
541     }
542
543     if (!(flags & REXEC_CHECKED) && prog->check_substr != Nullsv) {
544         re_scream_pos_data d;
545
546         d.scream_olds = &scream_olds;
547         d.scream_pos = &scream_pos;
548         s = re_intuit_start(prog, sv, s, strend, flags, &d);
549         if (!s)
550             goto phooey;        /* not present */
551     }
552
553     DEBUG_r( if (!PL_colorset) reginitcolors() );
554     DEBUG_r(PerlIO_printf(Perl_debug_log,
555                       "%sMatching%s `%s%.60s%s%s' against `%s%.*s%s%s'\n",
556                       PL_colors[4],PL_colors[5],PL_colors[0],
557                       prog->precomp,
558                       PL_colors[1],
559                       (strlen(prog->precomp) > 60 ? "..." : ""),
560                       PL_colors[0],
561                       (strend - startpos > 60 ? 60 : strend - startpos),
562                       startpos, PL_colors[1],
563                       (strend - startpos > 60 ? "..." : ""))
564         );
565
566     /* Simplest case:  anchored match need be tried only once. */
567     /*  [unless only anchor is BOL and multiline is set] */
568     if (prog->reganch & (ROPT_ANCH & ~ROPT_ANCH_GPOS)) {
569         if (s == startpos && regtry(prog, startpos))
570             goto got_it;
571         else if (PL_multiline || (prog->reganch & ROPT_IMPLICIT)
572                  || (prog->reganch & ROPT_ANCH_MBOL)) /* XXXX SBOL? */
573         {
574             char *end;
575
576             if (minlen)
577                 dontbother = minlen - 1;
578             end = HOPc(strend, -dontbother) - 1;
579             /* for multiline we only have to try after newlines */
580             if (prog->check_substr) {
581                 while (1) {
582                     if (regtry(prog, s))
583                         goto got_it;
584                     if (s >= end)
585                         goto phooey;
586                     s = re_intuit_start(prog, sv, s + 1, strend, flags, NULL);
587                     if (!s)
588                         goto phooey;
589                 }               
590             } else {
591                 if (s > startpos)
592                     s--;
593                 while (s < end) {
594                     if (*s++ == '\n') { /* don't need PL_utf8skip here */
595                         if (regtry(prog, s))
596                             goto got_it;
597                     }
598                 }               
599             }
600         }
601         goto phooey;
602     } else if (prog->reganch & ROPT_ANCH_GPOS) {
603         if (regtry(prog, PL_reg_ganch))
604             goto got_it;
605         goto phooey;
606     }
607
608     /* Messy cases:  unanchored match. */
609     if (prog->anchored_substr && prog->reganch & ROPT_SKIP) { 
610         /* we have /x+whatever/ */
611         /* it must be a one character string (XXXX Except UTF?) */
612         char ch = SvPVX(prog->anchored_substr)[0];
613         if (UTF) {
614             while (s < strend) {
615                 if (*s == ch) {
616                     if (regtry(prog, s)) goto got_it;
617                     s += UTF8SKIP(s);
618                     while (s < strend && *s == ch)
619                         s += UTF8SKIP(s);
620                 }
621                 s += UTF8SKIP(s);
622             }
623         }
624         else {
625             while (s < strend) {
626                 if (*s == ch) {
627                     if (regtry(prog, s)) goto got_it;
628                     s++;
629                     while (s < strend && *s == ch)
630                         s++;
631                 }
632                 s++;
633             }
634         }
635     }
636     /*SUPPRESS 560*/
637     else if (prog->anchored_substr != Nullsv
638              || (prog->float_substr != Nullsv 
639                  && prog->float_max_offset < strend - s)) {
640         SV *must = prog->anchored_substr 
641             ? prog->anchored_substr : prog->float_substr;
642         I32 back_max = 
643             prog->anchored_substr ? prog->anchored_offset : prog->float_max_offset;
644         I32 back_min = 
645             prog->anchored_substr ? prog->anchored_offset : prog->float_min_offset;
646         I32 delta = back_max - back_min;
647         char *last = HOPc(strend,       /* Cannot start after this */
648                           -(I32)(CHR_SVLEN(must)
649                                  - (SvTAIL(must) != 0) + back_min));
650         char *last1;            /* Last position checked before */
651
652         if (s > PL_bostr)
653             last1 = HOPc(s, -1);
654         else
655             last1 = s - 1;      /* bogus */
656
657         /* XXXX check_substr already used to find `s', can optimize if
658            check_substr==must. */
659         scream_pos = -1;
660         dontbother = end_shift;
661         strend = HOPc(strend, -dontbother);
662         while ( (s <= last) &&
663                 ((flags & REXEC_SCREAM) 
664                  ? (s = screaminstr(sv, must, HOPc(s, back_min) - strbeg,
665                                     end_shift, &scream_pos, 0))
666                  : (s = fbm_instr((unsigned char*)HOP(s, back_min),
667                                   (unsigned char*)strend, must, 
668                                   PL_multiline ? FBMrf_MULTILINE : 0))) ) {
669             if (HOPc(s, -back_max) > last1) {
670                 last1 = HOPc(s, -back_min);
671                 s = HOPc(s, -back_max);
672             }
673             else {
674                 char *t = (last1 >= PL_bostr) ? HOPc(last1, 1) : last1 + 1;
675
676                 last1 = HOPc(s, -back_min);
677                 s = t;          
678             }
679             if (UTF) {
680                 while (s <= last1) {
681                     if (regtry(prog, s))
682                         goto got_it;
683                     s += UTF8SKIP(s);
684                 }
685             }
686             else {
687                 while (s <= last1) {
688                     if (regtry(prog, s))
689                         goto got_it;
690                     s++;
691                 }
692             }
693         }
694         goto phooey;
695     }
696     else if (c = prog->regstclass) {
697         I32 doevery = (prog->reganch & ROPT_SKIP) == 0;
698         char *cc;
699
700         if (minlen)
701             dontbother = minlen - 1;
702         strend = HOPc(strend, -dontbother);     /* don't bother with what can't match */
703         tmp = 1;
704         /* We know what class it must start with. */
705         switch (OP(c)) {
706         case ANYOFUTF8:
707             cc = (char *) OPERAND(c);
708             while (s < strend) {
709                 if (REGINCLASSUTF8(c, (U8*)s)) {
710                     if (tmp && regtry(prog, s))
711                         goto got_it;
712                     else
713                         tmp = doevery;
714                 }
715                 else
716                     tmp = 1;
717                 s += UTF8SKIP(s);
718             }
719             break;
720         case ANYOF:
721             cc = (char *) OPERAND(c);
722             while (s < strend) {
723                 if (REGINCLASS(cc, *s)) {
724                     if (tmp && regtry(prog, s))
725                         goto got_it;
726                     else
727                         tmp = doevery;
728                 }
729                 else
730                     tmp = 1;
731                 s++;
732             }
733             break;
734         case BOUNDL:
735             PL_reg_flags |= RF_tainted;
736             /* FALL THROUGH */
737         case BOUND:
738             if (minlen) {
739                 dontbother++;
740                 strend -= 1;
741             }
742             tmp = (s != startpos) ? UCHARAT(s - 1) : PL_regprev;
743             tmp = ((OP(c) == BOUND ? isALNUM(tmp) : isALNUM_LC(tmp)) != 0);
744             while (s < strend) {
745                 if (tmp == !(OP(c) == BOUND ? isALNUM(*s) : isALNUM_LC(*s))) {
746                     tmp = !tmp;
747                     if (regtry(prog, s))
748                         goto got_it;
749                 }
750                 s++;
751             }
752             if ((minlen || tmp) && regtry(prog,s))
753                 goto got_it;
754             break;
755         case BOUNDLUTF8:
756             PL_reg_flags |= RF_tainted;
757             /* FALL THROUGH */
758         case BOUNDUTF8:
759             if (minlen) {
760                 dontbother++;
761                 strend = reghop_c(strend, -1);
762             }
763             tmp = (I32)(s != startpos) ? utf8_to_uv(reghop((U8*)s, -1), 0) : PL_regprev;
764             tmp = ((OP(c) == BOUND ? isALNUM_uni(tmp) : isALNUM_LC_uni(tmp)) != 0);
765             while (s < strend) {
766                 if (tmp == !(OP(c) == BOUND ?
767                              swash_fetch(PL_utf8_alnum, (U8*)s) :
768                              isALNUM_LC_utf8((U8*)s)))
769                 {
770                     tmp = !tmp;
771                     if (regtry(prog, s))
772                         goto got_it;
773                 }
774                 s += UTF8SKIP(s);
775             }
776             if ((minlen || tmp) && regtry(prog,s))
777                 goto got_it;
778             break;
779         case NBOUNDL:
780             PL_reg_flags |= RF_tainted;
781             /* FALL THROUGH */
782         case NBOUND:
783             if (minlen) {
784                 dontbother++;
785                 strend -= 1;
786             }
787             tmp = (s != startpos) ? UCHARAT(s - 1) : PL_regprev;
788             tmp = ((OP(c) == NBOUND ? isALNUM(tmp) : isALNUM_LC(tmp)) != 0);
789             while (s < strend) {
790                 if (tmp == !(OP(c) == NBOUND ? isALNUM(*s) : isALNUM_LC(*s)))
791                     tmp = !tmp;
792                 else if (regtry(prog, s))
793                     goto got_it;
794                 s++;
795             }
796             if ((minlen || !tmp) && regtry(prog,s))
797                 goto got_it;
798             break;
799         case NBOUNDLUTF8:
800             PL_reg_flags |= RF_tainted;
801             /* FALL THROUGH */
802         case NBOUNDUTF8:
803             if (minlen) {
804                 dontbother++;
805                 strend = reghop_c(strend, -1);
806             }
807             tmp = (I32)(s != startpos) ? utf8_to_uv(reghop((U8*)s, -1), 0) : PL_regprev;
808             tmp = ((OP(c) == NBOUND ? isALNUM_uni(tmp) : isALNUM_LC_uni(tmp)) != 0);
809             while (s < strend) {
810                 if (tmp == !(OP(c) == NBOUND ?
811                              swash_fetch(PL_utf8_alnum, (U8*)s) :
812                              isALNUM_LC_utf8((U8*)s)))
813                     tmp = !tmp;
814                 else if (regtry(prog, s))
815                     goto got_it;
816                 s += UTF8SKIP(s);
817             }
818             if ((minlen || !tmp) && regtry(prog,s))
819                 goto got_it;
820             break;
821         case ALNUM:
822             while (s < strend) {
823                 if (isALNUM(*s)) {
824                     if (tmp && regtry(prog, s))
825                         goto got_it;
826                     else
827                         tmp = doevery;
828                 }
829                 else
830                     tmp = 1;
831                 s++;
832             }
833             break;
834         case ALNUMUTF8:
835             while (s < strend) {
836                 if (swash_fetch(PL_utf8_alnum, (U8*)s)) {
837                     if (tmp && regtry(prog, s))
838                         goto got_it;
839                     else
840                         tmp = doevery;
841                 }
842                 else
843                     tmp = 1;
844                 s += UTF8SKIP(s);
845             }
846             break;
847         case ALNUML:
848             PL_reg_flags |= RF_tainted;
849             while (s < strend) {
850                 if (isALNUM_LC(*s)) {
851                     if (tmp && regtry(prog, s))
852                         goto got_it;
853                     else
854                         tmp = doevery;
855                 }
856                 else
857                     tmp = 1;
858                 s++;
859             }
860             break;
861         case ALNUMLUTF8:
862             PL_reg_flags |= RF_tainted;
863             while (s < strend) {
864                 if (isALNUM_LC_utf8((U8*)s)) {
865                     if (tmp && regtry(prog, s))
866                         goto got_it;
867                     else
868                         tmp = doevery;
869                 }
870                 else
871                     tmp = 1;
872                 s += UTF8SKIP(s);
873             }
874             break;
875         case NALNUM:
876             while (s < strend) {
877                 if (!isALNUM(*s)) {
878                     if (tmp && regtry(prog, s))
879                         goto got_it;
880                     else
881                         tmp = doevery;
882                 }
883                 else
884                     tmp = 1;
885                 s++;
886             }
887             break;
888         case NALNUMUTF8:
889             while (s < strend) {
890                 if (!swash_fetch(PL_utf8_alnum, (U8*)s)) {
891                     if (tmp && regtry(prog, s))
892                         goto got_it;
893                     else
894                         tmp = doevery;
895                 }
896                 else
897                     tmp = 1;
898                 s += UTF8SKIP(s);
899             }
900             break;
901         case NALNUML:
902             PL_reg_flags |= RF_tainted;
903             while (s < strend) {
904                 if (!isALNUM_LC(*s)) {
905                     if (tmp && regtry(prog, s))
906                         goto got_it;
907                     else
908                         tmp = doevery;
909                 }
910                 else
911                     tmp = 1;
912                 s++;
913             }
914             break;
915         case NALNUMLUTF8:
916             PL_reg_flags |= RF_tainted;
917             while (s < strend) {
918                 if (!isALNUM_LC_utf8((U8*)s)) {
919                     if (tmp && regtry(prog, s))
920                         goto got_it;
921                     else
922                         tmp = doevery;
923                 }
924                 else
925                     tmp = 1;
926                 s += UTF8SKIP(s);
927             }
928             break;
929         case SPACE:
930             while (s < strend) {
931                 if (isSPACE(*s)) {
932                     if (tmp && regtry(prog, s))
933                         goto got_it;
934                     else
935                         tmp = doevery;
936                 }
937                 else
938                     tmp = 1;
939                 s++;
940             }
941             break;
942         case SPACEUTF8:
943             while (s < strend) {
944                 if (*s == ' ' || swash_fetch(PL_utf8_space,(U8*)s)) {
945                     if (tmp && regtry(prog, s))
946                         goto got_it;
947                     else
948                         tmp = doevery;
949                 }
950                 else
951                     tmp = 1;
952                 s += UTF8SKIP(s);
953             }
954             break;
955         case SPACEL:
956             PL_reg_flags |= RF_tainted;
957             while (s < strend) {
958                 if (isSPACE_LC(*s)) {
959                     if (tmp && regtry(prog, s))
960                         goto got_it;
961                     else
962                         tmp = doevery;
963                 }
964                 else
965                     tmp = 1;
966                 s++;
967             }
968             break;
969         case SPACELUTF8:
970             PL_reg_flags |= RF_tainted;
971             while (s < strend) {
972                 if (*s == ' ' || isSPACE_LC_utf8((U8*)s)) {
973                     if (tmp && regtry(prog, s))
974                         goto got_it;
975                     else
976                         tmp = doevery;
977                 }
978                 else
979                     tmp = 1;
980                 s += UTF8SKIP(s);
981             }
982             break;
983         case NSPACE:
984             while (s < strend) {
985                 if (!isSPACE(*s)) {
986                     if (tmp && regtry(prog, s))
987                         goto got_it;
988                     else
989                         tmp = doevery;
990                 }
991                 else
992                     tmp = 1;
993                 s++;
994             }
995             break;
996         case NSPACEUTF8:
997             while (s < strend) {
998                 if (!(*s == ' ' || swash_fetch(PL_utf8_space,(U8*)s))) {
999                     if (tmp && regtry(prog, s))
1000                         goto got_it;
1001                     else
1002                         tmp = doevery;
1003                 }
1004                 else
1005                     tmp = 1;
1006                 s += UTF8SKIP(s);
1007             }
1008             break;
1009         case NSPACEL:
1010             PL_reg_flags |= RF_tainted;
1011             while (s < strend) {
1012                 if (!isSPACE_LC(*s)) {
1013                     if (tmp && regtry(prog, s))
1014                         goto got_it;
1015                     else
1016                         tmp = doevery;
1017                 }
1018                 else
1019                     tmp = 1;
1020                 s++;
1021             }
1022             break;
1023         case NSPACELUTF8:
1024             PL_reg_flags |= RF_tainted;
1025             while (s < strend) {
1026                 if (!(*s == ' ' || isSPACE_LC_utf8((U8*)s))) {
1027                     if (tmp && regtry(prog, s))
1028                         goto got_it;
1029                     else
1030                         tmp = doevery;
1031                 }
1032                 else
1033                     tmp = 1;
1034                 s += UTF8SKIP(s);
1035             }
1036             break;
1037         case DIGIT:
1038             while (s < strend) {
1039                 if (isDIGIT(*s)) {
1040                     if (tmp && regtry(prog, s))
1041                         goto got_it;
1042                     else
1043                         tmp = doevery;
1044                 }
1045                 else
1046                     tmp = 1;
1047                 s++;
1048             }
1049             break;
1050         case DIGITUTF8:
1051             while (s < strend) {
1052                 if (swash_fetch(PL_utf8_digit,(U8*)s)) {
1053                     if (tmp && regtry(prog, s))
1054                         goto got_it;
1055                     else
1056                         tmp = doevery;
1057                 }
1058                 else
1059                     tmp = 1;
1060                 s += UTF8SKIP(s);
1061             }
1062             break;
1063         case DIGITL:
1064             PL_reg_flags |= RF_tainted;
1065             while (s < strend) {
1066                 if (isDIGIT_LC(*s)) {
1067                     if (tmp && regtry(prog, s))
1068                         goto got_it;
1069                     else
1070                         tmp = doevery;
1071                 }
1072                 else
1073                     tmp = 1;
1074                 s++;
1075             }
1076             break;
1077         case DIGITLUTF8:
1078             PL_reg_flags |= RF_tainted;
1079             while (s < strend) {
1080                 if (isDIGIT_LC_utf8((U8*)s)) {
1081                     if (tmp && regtry(prog, s))
1082                         goto got_it;
1083                     else
1084                         tmp = doevery;
1085                 }
1086                 else
1087                     tmp = 1;
1088                 s += UTF8SKIP(s);
1089             }
1090             break;
1091         case NDIGIT:
1092             while (s < strend) {
1093                 if (!isDIGIT(*s)) {
1094                     if (tmp && regtry(prog, s))
1095                         goto got_it;
1096                     else
1097                         tmp = doevery;
1098                 }
1099                 else
1100                     tmp = 1;
1101                 s++;
1102             }
1103             break;
1104         case NDIGITUTF8:
1105             while (s < strend) {
1106                 if (!swash_fetch(PL_utf8_digit,(U8*)s)) {
1107                     if (tmp && regtry(prog, s))
1108                         goto got_it;
1109                     else
1110                         tmp = doevery;
1111                 }
1112                 else
1113                     tmp = 1;
1114                 s += UTF8SKIP(s);
1115             }
1116             break;
1117         case NDIGITL:
1118             PL_reg_flags |= RF_tainted;
1119             while (s < strend) {
1120                 if (!isDIGIT_LC(*s)) {
1121                     if (tmp && regtry(prog, s))
1122                         goto got_it;
1123                     else
1124                         tmp = doevery;
1125                 }
1126                 else
1127                     tmp = 1;
1128                 s++;
1129             }
1130             break;
1131         case NDIGITLUTF8:
1132             PL_reg_flags |= RF_tainted;
1133             while (s < strend) {
1134                 if (!isDIGIT_LC_utf8((U8*)s)) {
1135                     if (tmp && regtry(prog, s))
1136                         goto got_it;
1137                     else
1138                         tmp = doevery;
1139                 }
1140                 else
1141                     tmp = 1;
1142                 s += UTF8SKIP(s);
1143             }
1144             break;
1145         }
1146     }
1147     else {
1148         dontbother = 0;
1149         if (prog->float_substr != Nullsv) {     /* Trim the end. */
1150             char *last;
1151             I32 oldpos = scream_pos;
1152
1153             if (flags & REXEC_SCREAM) {
1154                 last = screaminstr(sv, prog->float_substr, s - strbeg,
1155                                    end_shift, &scream_pos, 1); /* last one */
1156                 if (!last)
1157                     last = scream_olds; /* Only one occurence. */
1158             }
1159             else {
1160                 STRLEN len;
1161                 char *little = SvPV(prog->float_substr, len);
1162
1163                 if (SvTAIL(prog->float_substr)) {
1164                     if (memEQ(strend - len + 1, little, len - 1))
1165                         last = strend - len + 1;
1166                     else if (!PL_multiline)
1167                         last = memEQ(strend - len, little, len) 
1168                             ? strend - len : Nullch;
1169                     else
1170                         goto find_last;
1171                 } else {
1172                   find_last:
1173                     if (len) 
1174                         last = rninstr(s, strend, little, little + len);
1175                     else
1176                         last = strend;  /* matching `$' */
1177                 }
1178             }
1179             if (last == NULL) goto phooey; /* Should not happen! */
1180             dontbother = strend - last + prog->float_min_offset;
1181         }
1182         if (minlen && (dontbother < minlen))
1183             dontbother = minlen - 1;
1184         strend -= dontbother;              /* this one's always in bytes! */
1185         /* We don't know much -- general case. */
1186         if (UTF) {
1187             for (;;) {
1188                 if (regtry(prog, s))
1189                     goto got_it;
1190                 if (s >= strend)
1191                     break;
1192                 s += UTF8SKIP(s);
1193             };
1194         }
1195         else {
1196             do {
1197                 if (regtry(prog, s))
1198                     goto got_it;
1199             } while (s++ < strend);
1200         }
1201     }
1202
1203     /* Failure. */
1204     goto phooey;
1205
1206 got_it:
1207     RX_MATCH_TAINTED_set(prog, PL_reg_flags & RF_tainted);
1208
1209     if (PL_reg_eval_set) {
1210         /* Preserve the current value of $^R */
1211         if (oreplsv != GvSV(PL_replgv))
1212             sv_setsv(oreplsv, GvSV(PL_replgv));/* So that when GvSV(replgv) is
1213                                                   restored, the value remains
1214                                                   the same. */
1215         restore_pos(aTHXo_ 0);
1216     }
1217
1218     /* make sure $`, $&, $', and $digit will work later */
1219     if ( !(flags & REXEC_NOT_FIRST) ) {
1220         if (RX_MATCH_COPIED(prog)) {
1221             Safefree(prog->subbeg);
1222             RX_MATCH_COPIED_off(prog);
1223         }
1224         if (flags & REXEC_COPY_STR) {
1225             I32 i = PL_regeol - startpos + (stringarg - strbeg);
1226
1227             s = savepvn(strbeg, i);
1228             prog->subbeg = s;
1229             prog->sublen = i;
1230             RX_MATCH_COPIED_on(prog);
1231         }
1232         else {
1233             prog->subbeg = strbeg;
1234             prog->sublen = PL_regeol - strbeg;  /* strend may have been modified */
1235         }
1236     }
1237     
1238     return 1;
1239
1240 phooey:
1241     if (PL_reg_eval_set)
1242         restore_pos(aTHXo_ 0);
1243     return 0;
1244 }
1245
1246 /*
1247  - regtry - try match at specific point
1248  */
1249 STATIC I32                      /* 0 failure, 1 success */
1250 S_regtry(pTHX_ regexp *prog, char *startpos)
1251 {
1252     dTHR;
1253     register I32 i;
1254     register I32 *sp;
1255     register I32 *ep;
1256     CHECKPOINT lastcp;
1257
1258     if ((prog->reganch & ROPT_EVAL_SEEN) && !PL_reg_eval_set) {
1259         MAGIC *mg;
1260
1261         PL_reg_eval_set = RS_init;
1262         DEBUG_r(DEBUG_s(
1263             PerlIO_printf(Perl_debug_log, "  setting stack tmpbase at %i\n",
1264                           PL_stack_sp - PL_stack_base);
1265             ));
1266         SAVEINT(cxstack[cxstack_ix].blk_oldsp);
1267         cxstack[cxstack_ix].blk_oldsp = PL_stack_sp - PL_stack_base;
1268         /* Otherwise OP_NEXTSTATE will free whatever on stack now.  */
1269         SAVETMPS;
1270         /* Apparently this is not needed, judging by wantarray. */
1271         /* SAVEINT(cxstack[cxstack_ix].blk_gimme);
1272            cxstack[cxstack_ix].blk_gimme = G_SCALAR; */
1273
1274         if (PL_reg_sv) {
1275             /* Make $_ available to executed code. */
1276             if (PL_reg_sv != DEFSV) {
1277                 /* SAVE_DEFSV does *not* suffice here for USE_THREADS */
1278                 SAVESPTR(DEFSV);
1279                 DEFSV = PL_reg_sv;
1280             }
1281         
1282             if (!(SvTYPE(PL_reg_sv) >= SVt_PVMG && SvMAGIC(PL_reg_sv) 
1283                   && (mg = mg_find(PL_reg_sv, 'g')))) {
1284                 /* prepare for quick setting of pos */
1285                 sv_magic(PL_reg_sv, (SV*)0, 'g', Nullch, 0);
1286                 mg = mg_find(PL_reg_sv, 'g');
1287                 mg->mg_len = -1;
1288             }
1289             PL_reg_magic    = mg;
1290             PL_reg_oldpos   = mg->mg_len;
1291             SAVEDESTRUCTOR(restore_pos, 0);
1292         }
1293         if (!PL_reg_curpm)
1294             New(22,PL_reg_curpm, 1, PMOP);
1295         PL_reg_curpm->op_pmregexp = prog;
1296         PL_reg_oldcurpm = PL_curpm;
1297         PL_curpm = PL_reg_curpm;
1298         if (RX_MATCH_COPIED(prog)) {
1299             /*  Here is a serious problem: we cannot rewrite subbeg,
1300                 since it may be needed if this match fails.  Thus
1301                 $` inside (?{}) could fail... */
1302             PL_reg_oldsaved = prog->subbeg;
1303             PL_reg_oldsavedlen = prog->sublen;
1304             RX_MATCH_COPIED_off(prog);
1305         }
1306         else
1307             PL_reg_oldsaved = Nullch;
1308         prog->subbeg = PL_bostr;
1309         prog->sublen = PL_regeol - PL_bostr; /* strend may have been modified */
1310     }
1311     prog->startp[0] = startpos - PL_bostr;
1312     PL_reginput = startpos;
1313     PL_regstartp = prog->startp;
1314     PL_regendp = prog->endp;
1315     PL_reglastparen = &prog->lastparen;
1316     prog->lastparen = 0;
1317     PL_regsize = 0;
1318     DEBUG_r(PL_reg_starttry = startpos);
1319     if (PL_reg_start_tmpl <= prog->nparens) {
1320         PL_reg_start_tmpl = prog->nparens*3/2 + 3;
1321         if(PL_reg_start_tmp)
1322             Renew(PL_reg_start_tmp, PL_reg_start_tmpl, char*);
1323         else
1324             New(22,PL_reg_start_tmp, PL_reg_start_tmpl, char*);
1325     }
1326
1327     /* XXXX What this code is doing here?!!!  There should be no need
1328        to do this again and again, PL_reglastparen should take care of
1329        this!  */
1330     sp = prog->startp;
1331     ep = prog->endp;
1332     if (prog->nparens) {
1333         for (i = prog->nparens; i >= 1; i--) {
1334             *++sp = -1;
1335             *++ep = -1;
1336         }
1337     }
1338     REGCP_SET;
1339     if (regmatch(prog->program + 1)) {
1340         prog->endp[0] = PL_reginput - PL_bostr;
1341         return 1;
1342     }
1343     REGCP_UNWIND;
1344     return 0;
1345 }
1346
1347 /*
1348  - regmatch - main matching routine
1349  *
1350  * Conceptually the strategy is simple:  check to see whether the current
1351  * node matches, call self recursively to see whether the rest matches,
1352  * and then act accordingly.  In practice we make some effort to avoid
1353  * recursion, in particular by going through "ordinary" nodes (that don't
1354  * need to know whether the rest of the match failed) by a loop instead of
1355  * by recursion.
1356  */
1357 /* [lwall] I've hoisted the register declarations to the outer block in order to
1358  * maybe save a little bit of pushing and popping on the stack.  It also takes
1359  * advantage of machines that use a register save mask on subroutine entry.
1360  */
1361 STATIC I32                      /* 0 failure, 1 success */
1362 S_regmatch(pTHX_ regnode *prog)
1363 {
1364     dTHR;
1365     register regnode *scan;     /* Current node. */
1366     regnode *next;              /* Next node. */
1367     regnode *inner;             /* Next node in internal branch. */
1368     register I32 nextchr;       /* renamed nextchr - nextchar colides with
1369                                    function of same name */
1370     register I32 n;             /* no or next */
1371     register I32 ln;            /* len or last */
1372     register char *s;           /* operand or save */
1373     register char *locinput = PL_reginput;
1374     register I32 c1, c2, paren; /* case fold search, parenth */
1375     int minmod = 0, sw = 0, logical = 0;
1376 #ifdef DEBUGGING
1377     PL_regindent++;
1378 #endif
1379
1380     /* Note that nextchr is a byte even in UTF */
1381     nextchr = UCHARAT(locinput);
1382     scan = prog;
1383     while (scan != NULL) {
1384 #define sayNO_L (logical ? (logical = 0, sw = 0, goto cont) : sayNO)
1385 #ifdef DEBUGGING
1386 #  define sayYES goto yes
1387 #  define sayNO goto no
1388 #  define saySAME(x) if (x) goto yes; else goto no
1389 #  define REPORT_CODE_OFF 24
1390 #else
1391 #  define sayYES return 1
1392 #  define sayNO return 0
1393 #  define saySAME(x) return x
1394 #endif
1395         DEBUG_r( {
1396             SV *prop = sv_newmortal();
1397             int docolor = *PL_colors[0];
1398             int taill = (docolor ? 10 : 7); /* 3 chars for "> <" */
1399             int l = (PL_regeol - locinput > taill ? taill : PL_regeol - locinput);
1400             /* The part of the string before starttry has one color
1401                (pref0_len chars), between starttry and current
1402                position another one (pref_len - pref0_len chars),
1403                after the current position the third one.
1404                We assume that pref0_len <= pref_len, otherwise we
1405                decrease pref0_len.  */
1406             int pref_len = (locinput - PL_bostr > (5 + taill) - l 
1407                             ? (5 + taill) - l : locinput - PL_bostr);
1408             int pref0_len = pref_len  - (locinput - PL_reg_starttry);
1409
1410             if (l + pref_len < (5 + taill) && l < PL_regeol - locinput)
1411                 l = ( PL_regeol - locinput > (5 + taill) - pref_len 
1412                       ? (5 + taill) - pref_len : PL_regeol - locinput);
1413             if (pref0_len < 0)
1414                 pref0_len = 0;
1415             if (pref0_len > pref_len)
1416                 pref0_len = pref_len;
1417             regprop(prop, scan);
1418             PerlIO_printf(Perl_debug_log, 
1419                           "%4i <%s%.*s%s%s%.*s%s%s%s%.*s%s>%*s|%3d:%*s%s\n",
1420                           locinput - PL_bostr, 
1421                           PL_colors[4], pref0_len, 
1422                           locinput - pref_len, PL_colors[5],
1423                           PL_colors[2], pref_len - pref0_len, 
1424                           locinput - pref_len + pref0_len, PL_colors[3],
1425                           (docolor ? "" : "> <"),
1426                           PL_colors[0], l, locinput, PL_colors[1],
1427                           15 - l - pref_len + 1,
1428                           "",
1429                           scan - PL_regprogram, PL_regindent*2, "",
1430                           SvPVX(prop));
1431         } );
1432
1433         next = scan + NEXT_OFF(scan);
1434         if (next == scan)
1435             next = NULL;
1436
1437         switch (OP(scan)) {
1438         case BOL:
1439             if (locinput == PL_bostr
1440                 ? PL_regprev == '\n'
1441                 : (PL_multiline && 
1442                    (nextchr || locinput < PL_regeol) && locinput[-1] == '\n') )
1443             {
1444                 /* regtill = regbol; */
1445                 break;
1446             }
1447             sayNO;
1448         case MBOL:
1449             if (locinput == PL_bostr
1450                 ? PL_regprev == '\n'
1451                 : ((nextchr || locinput < PL_regeol) && locinput[-1] == '\n') )
1452             {
1453                 break;
1454             }
1455             sayNO;
1456         case SBOL:
1457             if (locinput == PL_regbol && PL_regprev == '\n')
1458                 break;
1459             sayNO;
1460         case GPOS:
1461             if (locinput == PL_reg_ganch)
1462                 break;
1463             sayNO;
1464         case EOL:
1465             if (PL_multiline)
1466                 goto meol;
1467             else
1468                 goto seol;
1469         case MEOL:
1470           meol:
1471             if ((nextchr || locinput < PL_regeol) && nextchr != '\n')
1472                 sayNO;
1473             break;
1474         case SEOL:
1475           seol:
1476             if ((nextchr || locinput < PL_regeol) && nextchr != '\n')
1477                 sayNO;
1478             if (PL_regeol - locinput > 1)
1479                 sayNO;
1480             break;
1481         case EOS:
1482             if (PL_regeol != locinput)
1483                 sayNO;
1484             break;
1485         case SANYUTF8:
1486             if (nextchr & 0x80) {
1487                 locinput += PL_utf8skip[nextchr];
1488                 if (locinput > PL_regeol)
1489                     sayNO;
1490                 nextchr = UCHARAT(locinput);
1491                 break;
1492             }
1493             if (!nextchr && locinput >= PL_regeol)
1494                 sayNO;
1495             nextchr = UCHARAT(++locinput);
1496             break;
1497         case SANY:
1498             if (!nextchr && locinput >= PL_regeol)
1499                 sayNO;
1500             nextchr = UCHARAT(++locinput);
1501             break;
1502         case ANYUTF8:
1503             if (nextchr & 0x80) {
1504                 locinput += PL_utf8skip[nextchr];
1505                 if (locinput > PL_regeol)
1506                     sayNO;
1507                 nextchr = UCHARAT(locinput);
1508                 break;
1509             }
1510             if (!nextchr && locinput >= PL_regeol || nextchr == '\n')
1511                 sayNO;
1512             nextchr = UCHARAT(++locinput);
1513             break;
1514         case REG_ANY:
1515             if (!nextchr && locinput >= PL_regeol || nextchr == '\n')
1516                 sayNO;
1517             nextchr = UCHARAT(++locinput);
1518             break;
1519         case EXACT:
1520             s = (char *) OPERAND(scan);
1521             ln = UCHARAT(s++);
1522             /* Inline the first character, for speed. */
1523             if (UCHARAT(s) != nextchr)
1524                 sayNO;
1525             if (PL_regeol - locinput < ln)
1526                 sayNO;
1527             if (ln > 1 && memNE(s, locinput, ln))
1528                 sayNO;
1529             locinput += ln;
1530             nextchr = UCHARAT(locinput);
1531             break;
1532         case EXACTFL:
1533             PL_reg_flags |= RF_tainted;
1534             /* FALL THROUGH */
1535         case EXACTF:
1536             s = (char *) OPERAND(scan);
1537             ln = UCHARAT(s++);
1538
1539             if (UTF) {
1540                 char *l = locinput;
1541                 char *e = s + ln;
1542                 c1 = OP(scan) == EXACTF;
1543                 while (s < e) {
1544                     if (l >= PL_regeol)
1545                         sayNO;
1546                     if (utf8_to_uv((U8*)s, 0) != (c1 ?
1547                                                   toLOWER_utf8((U8*)l) :
1548                                                   toLOWER_LC_utf8((U8*)l)))
1549                     {
1550                         sayNO;
1551                     }
1552                     s += UTF8SKIP(s);
1553                     l += UTF8SKIP(l);
1554                 }
1555                 locinput = l;
1556                 nextchr = UCHARAT(locinput);
1557                 break;
1558             }
1559
1560             /* Inline the first character, for speed. */
1561             if (UCHARAT(s) != nextchr &&
1562                 UCHARAT(s) != ((OP(scan) == EXACTF)
1563                                ? PL_fold : PL_fold_locale)[nextchr])
1564                 sayNO;
1565             if (PL_regeol - locinput < ln)
1566                 sayNO;
1567             if (ln > 1 && (OP(scan) == EXACTF
1568                            ? ibcmp(s, locinput, ln)
1569                            : ibcmp_locale(s, locinput, ln)))
1570                 sayNO;
1571             locinput += ln;
1572             nextchr = UCHARAT(locinput);
1573             break;
1574         case ANYOFUTF8:
1575             s = (char *) OPERAND(scan);
1576             if (!REGINCLASSUTF8(scan, (U8*)locinput))
1577                 sayNO;
1578             if (locinput >= PL_regeol)
1579                 sayNO;
1580             locinput += PL_utf8skip[nextchr];
1581             nextchr = UCHARAT(locinput);
1582             break;
1583         case ANYOF:
1584             s = (char *) OPERAND(scan);
1585             if (nextchr < 0)
1586                 nextchr = UCHARAT(locinput);
1587             if (!REGINCLASS(s, nextchr))
1588                 sayNO;
1589             if (!nextchr && locinput >= PL_regeol)
1590                 sayNO;
1591             nextchr = UCHARAT(++locinput);
1592             break;
1593         case ALNUML:
1594             PL_reg_flags |= RF_tainted;
1595             /* FALL THROUGH */
1596         case ALNUM:
1597             if (!nextchr)
1598                 sayNO;
1599             if (!(OP(scan) == ALNUM
1600                   ? isALNUM(nextchr) : isALNUM_LC(nextchr)))
1601                 sayNO;
1602             nextchr = UCHARAT(++locinput);
1603             break;
1604         case ALNUMLUTF8:
1605             PL_reg_flags |= RF_tainted;
1606             /* FALL THROUGH */
1607         case ALNUMUTF8:
1608             if (!nextchr)
1609                 sayNO;
1610             if (nextchr & 0x80) {
1611                 if (!(OP(scan) == ALNUMUTF8
1612                       ? swash_fetch(PL_utf8_alnum, (U8*)locinput)
1613                       : isALNUM_LC_utf8((U8*)locinput)))
1614                 {
1615                     sayNO;
1616                 }
1617                 locinput += PL_utf8skip[nextchr];
1618                 nextchr = UCHARAT(locinput);
1619                 break;
1620             }
1621             if (!(OP(scan) == ALNUMUTF8
1622                   ? isALNUM(nextchr) : isALNUM_LC(nextchr)))
1623                 sayNO;
1624             nextchr = UCHARAT(++locinput);
1625             break;
1626         case NALNUML:
1627             PL_reg_flags |= RF_tainted;
1628             /* FALL THROUGH */
1629         case NALNUM:
1630             if (!nextchr && locinput >= PL_regeol)
1631                 sayNO;
1632             if (OP(scan) == NALNUM
1633                 ? isALNUM(nextchr) : isALNUM_LC(nextchr))
1634                 sayNO;
1635             nextchr = UCHARAT(++locinput);
1636             break;
1637         case NALNUMLUTF8:
1638             PL_reg_flags |= RF_tainted;
1639             /* FALL THROUGH */
1640         case NALNUMUTF8:
1641             if (!nextchr && locinput >= PL_regeol)
1642                 sayNO;
1643             if (nextchr & 0x80) {
1644                 if (OP(scan) == NALNUMUTF8
1645                     ? swash_fetch(PL_utf8_alnum, (U8*)locinput)
1646                     : isALNUM_LC_utf8((U8*)locinput))
1647                 {
1648                     sayNO;
1649                 }
1650                 locinput += PL_utf8skip[nextchr];
1651                 nextchr = UCHARAT(locinput);
1652                 break;
1653             }
1654             if (OP(scan) == NALNUMUTF8
1655                 ? isALNUM(nextchr) : isALNUM_LC(nextchr))
1656                 sayNO;
1657             nextchr = UCHARAT(++locinput);
1658             break;
1659         case BOUNDL:
1660         case NBOUNDL:
1661             PL_reg_flags |= RF_tainted;
1662             /* FALL THROUGH */
1663         case BOUND:
1664         case NBOUND:
1665             /* was last char in word? */
1666             ln = (locinput != PL_regbol) ? UCHARAT(locinput - 1) : PL_regprev;
1667             if (OP(scan) == BOUND || OP(scan) == NBOUND) {
1668                 ln = isALNUM(ln);
1669                 n = isALNUM(nextchr);
1670             }
1671             else {
1672                 ln = isALNUM_LC(ln);
1673                 n = isALNUM_LC(nextchr);
1674             }
1675             if (((!ln) == (!n)) == (OP(scan) == BOUND || OP(scan) == BOUNDL))
1676                 sayNO;
1677             break;
1678         case BOUNDLUTF8:
1679         case NBOUNDLUTF8:
1680             PL_reg_flags |= RF_tainted;
1681             /* FALL THROUGH */
1682         case BOUNDUTF8:
1683         case NBOUNDUTF8:
1684             /* was last char in word? */
1685             ln = (locinput != PL_regbol)
1686                 ? utf8_to_uv(reghop((U8*)locinput, -1), 0) : PL_regprev;
1687             if (OP(scan) == BOUNDUTF8 || OP(scan) == NBOUNDUTF8) {
1688                 ln = isALNUM_uni(ln);
1689                 n = swash_fetch(PL_utf8_alnum, (U8*)locinput);
1690             }
1691             else {
1692                 ln = isALNUM_LC_uni(ln);
1693                 n = isALNUM_LC_utf8((U8*)locinput);
1694             }
1695             if (((!ln) == (!n)) == (OP(scan) == BOUNDUTF8 || OP(scan) == BOUNDLUTF8))
1696                 sayNO;
1697             break;
1698         case SPACEL:
1699             PL_reg_flags |= RF_tainted;
1700             /* FALL THROUGH */
1701         case SPACE:
1702             if (!nextchr && locinput >= PL_regeol)
1703                 sayNO;
1704             if (!(OP(scan) == SPACE
1705                   ? isSPACE(nextchr) : isSPACE_LC(nextchr)))
1706                 sayNO;
1707             nextchr = UCHARAT(++locinput);
1708             break;
1709         case SPACELUTF8:
1710             PL_reg_flags |= RF_tainted;
1711             /* FALL THROUGH */
1712         case SPACEUTF8:
1713             if (!nextchr && locinput >= PL_regeol)
1714                 sayNO;
1715             if (nextchr & 0x80) {
1716                 if (!(OP(scan) == SPACEUTF8
1717                       ? swash_fetch(PL_utf8_space,(U8*)locinput)
1718                       : isSPACE_LC_utf8((U8*)locinput)))
1719                 {
1720                     sayNO;
1721                 }
1722                 locinput += PL_utf8skip[nextchr];
1723                 nextchr = UCHARAT(locinput);
1724                 break;
1725             }
1726             if (!(OP(scan) == SPACEUTF8
1727                   ? isSPACE(nextchr) : isSPACE_LC(nextchr)))
1728                 sayNO;
1729             nextchr = UCHARAT(++locinput);
1730             break;
1731         case NSPACEL:
1732             PL_reg_flags |= RF_tainted;
1733             /* FALL THROUGH */
1734         case NSPACE:
1735             if (!nextchr)
1736                 sayNO;
1737             if (OP(scan) == SPACE
1738                 ? isSPACE(nextchr) : isSPACE_LC(nextchr))
1739                 sayNO;
1740             nextchr = UCHARAT(++locinput);
1741             break;
1742         case NSPACELUTF8:
1743             PL_reg_flags |= RF_tainted;
1744             /* FALL THROUGH */
1745         case NSPACEUTF8:
1746             if (!nextchr)
1747                 sayNO;
1748             if (nextchr & 0x80) {
1749                 if (OP(scan) == NSPACEUTF8
1750                     ? swash_fetch(PL_utf8_space,(U8*)locinput)
1751                     : isSPACE_LC_utf8((U8*)locinput))
1752                 {
1753                     sayNO;
1754                 }
1755                 locinput += PL_utf8skip[nextchr];
1756                 nextchr = UCHARAT(locinput);
1757                 break;
1758             }
1759             if (OP(scan) == NSPACEUTF8
1760                 ? isSPACE(nextchr) : isSPACE_LC(nextchr))
1761                 sayNO;
1762             nextchr = UCHARAT(++locinput);
1763             break;
1764         case DIGITL:
1765             PL_reg_flags |= RF_tainted;
1766             /* FALL THROUGH */
1767         case DIGIT:
1768             if (!nextchr && locinput >= PL_regeol)
1769                 sayNO;
1770             if (!(OP(scan) == DIGIT
1771                   ? isDIGIT(nextchr) : isDIGIT_LC(nextchr)))
1772                 sayNO;
1773             nextchr = UCHARAT(++locinput);
1774             break;
1775         case DIGITLUTF8:
1776             PL_reg_flags |= RF_tainted;
1777             /* FALL THROUGH */
1778         case DIGITUTF8:
1779             if (!nextchr)
1780                 sayNO;
1781             if (nextchr & 0x80) {
1782                 if (OP(scan) == NDIGITUTF8
1783                     ? swash_fetch(PL_utf8_digit,(U8*)locinput)
1784                     : isDIGIT_LC_utf8((U8*)locinput))
1785                 {
1786                     sayNO;
1787                 }
1788                 locinput += PL_utf8skip[nextchr];
1789                 nextchr = UCHARAT(locinput);
1790                 break;
1791             }
1792             if (!isDIGIT(nextchr))
1793                 sayNO;
1794             nextchr = UCHARAT(++locinput);
1795             break;
1796         case NDIGITL:
1797             PL_reg_flags |= RF_tainted;
1798             /* FALL THROUGH */
1799         case NDIGIT:
1800             if (!nextchr)
1801                 sayNO;
1802             if (OP(scan) == DIGIT
1803                 ? isDIGIT(nextchr) : isDIGIT_LC(nextchr))
1804                 sayNO;
1805             nextchr = UCHARAT(++locinput);
1806             break;
1807         case NDIGITLUTF8:
1808             PL_reg_flags |= RF_tainted;
1809             /* FALL THROUGH */
1810         case NDIGITUTF8:
1811             if (!nextchr && locinput >= PL_regeol)
1812                 sayNO;
1813             if (nextchr & 0x80) {
1814                 if (swash_fetch(PL_utf8_digit,(U8*)locinput))
1815                     sayNO;
1816                 locinput += PL_utf8skip[nextchr];
1817                 nextchr = UCHARAT(locinput);
1818                 break;
1819             }
1820             if (isDIGIT(nextchr))
1821                 sayNO;
1822             nextchr = UCHARAT(++locinput);
1823             break;
1824         case CLUMP:
1825             if (locinput >= PL_regeol || swash_fetch(PL_utf8_mark,(U8*)locinput))
1826                 sayNO;
1827             locinput += PL_utf8skip[nextchr];
1828             while (locinput < PL_regeol && swash_fetch(PL_utf8_mark,(U8*)locinput))
1829                 locinput += UTF8SKIP(locinput);
1830             if (locinput > PL_regeol)
1831                 sayNO;
1832             nextchr = UCHARAT(locinput);
1833             break;
1834         case REFFL:
1835             PL_reg_flags |= RF_tainted;
1836             /* FALL THROUGH */
1837         case REF:
1838         case REFF:
1839             n = ARG(scan);  /* which paren pair */
1840             ln = PL_regstartp[n];
1841             if (*PL_reglastparen < n || ln == -1)
1842                 sayNO;                  /* Do not match unless seen CLOSEn. */
1843             if (ln == PL_regendp[n])
1844                 break;
1845
1846             s = PL_bostr + ln;
1847             if (UTF && OP(scan) != REF) {       /* REF can do byte comparison */
1848                 char *l = locinput;
1849                 char *e = PL_bostr + PL_regendp[n];
1850                 /*
1851                  * Note that we can't do the "other character" lookup trick as
1852                  * in the 8-bit case (no pun intended) because in Unicode we
1853                  * have to map both upper and title case to lower case.
1854                  */
1855                 if (OP(scan) == REFF) {
1856                     while (s < e) {
1857                         if (l >= PL_regeol)
1858                             sayNO;
1859                         if (toLOWER_utf8((U8*)s) != toLOWER_utf8((U8*)l))
1860                             sayNO;
1861                         s += UTF8SKIP(s);
1862                         l += UTF8SKIP(l);
1863                     }
1864                 }
1865                 else {
1866                     while (s < e) {
1867                         if (l >= PL_regeol)
1868                             sayNO;
1869                         if (toLOWER_LC_utf8((U8*)s) != toLOWER_LC_utf8((U8*)l))
1870                             sayNO;
1871                         s += UTF8SKIP(s);
1872                         l += UTF8SKIP(l);
1873                     }
1874                 }
1875                 locinput = l;
1876                 nextchr = UCHARAT(locinput);
1877                 break;
1878             }
1879
1880             /* Inline the first character, for speed. */
1881             if (UCHARAT(s) != nextchr &&
1882                 (OP(scan) == REF ||
1883                  (UCHARAT(s) != ((OP(scan) == REFF
1884                                   ? PL_fold : PL_fold_locale)[nextchr]))))
1885                 sayNO;
1886             ln = PL_regendp[n] - ln;
1887             if (locinput + ln > PL_regeol)
1888                 sayNO;
1889             if (ln > 1 && (OP(scan) == REF
1890                            ? memNE(s, locinput, ln)
1891                            : (OP(scan) == REFF
1892                               ? ibcmp(s, locinput, ln)
1893                               : ibcmp_locale(s, locinput, ln))))
1894                 sayNO;
1895             locinput += ln;
1896             nextchr = UCHARAT(locinput);
1897             break;
1898
1899         case NOTHING:
1900         case TAIL:
1901             break;
1902         case BACK:
1903             break;
1904         case EVAL:
1905         {
1906             dSP;
1907             OP_4tree *oop = PL_op;
1908             COP *ocurcop = PL_curcop;
1909             SV **ocurpad = PL_curpad;
1910             SV *ret;
1911             
1912             n = ARG(scan);
1913             PL_op = (OP_4tree*)PL_regdata->data[n];
1914             DEBUG_r( PerlIO_printf(Perl_debug_log, "  re_eval 0x%x\n", PL_op) );
1915             PL_curpad = AvARRAY((AV*)PL_regdata->data[n + 2]);
1916             PL_regendp[0] = PL_reg_magic->mg_len = locinput - PL_bostr;
1917
1918             CALLRUNOPS(aTHX);                   /* Scalar context. */
1919             SPAGAIN;
1920             ret = POPs;
1921             PUTBACK;
1922             
1923             PL_op = oop;
1924             PL_curpad = ocurpad;
1925             PL_curcop = ocurcop;
1926             if (logical) {
1927                 if (logical == 2) {     /* Postponed subexpression. */
1928                     regexp *re;
1929                     MAGIC *mg = Null(MAGIC*);
1930                     re_cc_state state;
1931                     CURCUR cctmp;
1932                     CHECKPOINT cp, lastcp;
1933
1934                     if(SvROK(ret) || SvRMAGICAL(ret)) {
1935                         SV *sv = SvROK(ret) ? SvRV(ret) : ret;
1936
1937                         if(SvMAGICAL(sv))
1938                             mg = mg_find(sv, 'r');
1939                     }
1940                     if (mg) {
1941                         re = (regexp *)mg->mg_obj;
1942                         (void)ReREFCNT_inc(re);
1943                     }
1944                     else {
1945                         STRLEN len;
1946                         char *t = SvPV(ret, len);
1947                         PMOP pm;
1948                         char *oprecomp = PL_regprecomp;
1949                         I32 osize = PL_regsize;
1950                         I32 onpar = PL_regnpar;
1951
1952                         pm.op_pmflags = 0;
1953                         re = CALLREGCOMP(aTHX_ t, t + len, &pm);
1954                         if (!(SvFLAGS(ret) 
1955                               & (SVs_TEMP | SVs_PADTMP | SVf_READONLY)))
1956                             sv_magic(ret,(SV*)ReREFCNT_inc(re),'r',0,0);
1957                         PL_regprecomp = oprecomp;
1958                         PL_regsize = osize;
1959                         PL_regnpar = onpar;
1960                     }
1961                     DEBUG_r(
1962                         PerlIO_printf(Perl_debug_log, 
1963                                       "Entering embedded `%s%.60s%s%s'\n",
1964                                       PL_colors[0],
1965                                       re->precomp,
1966                                       PL_colors[1],
1967                                       (strlen(re->precomp) > 60 ? "..." : ""))
1968                         );
1969                     state.node = next;
1970                     state.prev = PL_reg_call_cc;
1971                     state.cc = PL_regcc;
1972                     state.re = PL_reg_re;
1973
1974                     cctmp.cur = 0;
1975                     cctmp.oldcc = 0;
1976                     PL_regcc = &cctmp;
1977                     
1978                     cp = regcppush(0);  /* Save *all* the positions. */
1979                     REGCP_SET;
1980                     cache_re(re);
1981                     state.ss = PL_savestack_ix;
1982                     *PL_reglastparen = 0;
1983                     PL_reg_call_cc = &state;
1984                     PL_reginput = locinput;
1985                     if (regmatch(re->program + 1)) {
1986                         ReREFCNT_dec(re);
1987                         regcpblow(cp);
1988                         sayYES;
1989                     }
1990                     DEBUG_r(
1991                         PerlIO_printf(Perl_debug_log,
1992                                       "%*s  failed...\n",
1993                                       REPORT_CODE_OFF+PL_regindent*2, "")
1994                         );
1995                     ReREFCNT_dec(re);
1996                     REGCP_UNWIND;
1997                     regcppop();
1998                     PL_reg_call_cc = state.prev;
1999                     PL_regcc = state.cc;
2000                     PL_reg_re = state.re;
2001                     cache_re(PL_reg_re);
2002                     sayNO;
2003                 }
2004                 sw = SvTRUE(ret);
2005                 logical = 0;
2006             }
2007             else
2008                 sv_setsv(save_scalar(PL_replgv), ret);
2009             break;
2010         }
2011         case OPEN:
2012             n = ARG(scan);  /* which paren pair */
2013             PL_reg_start_tmp[n] = locinput;
2014             if (n > PL_regsize)
2015                 PL_regsize = n;
2016             break;
2017         case CLOSE:
2018             n = ARG(scan);  /* which paren pair */
2019             PL_regstartp[n] = PL_reg_start_tmp[n] - PL_bostr;
2020             PL_regendp[n] = locinput - PL_bostr;
2021             if (n > *PL_reglastparen)
2022                 *PL_reglastparen = n;
2023             break;
2024         case GROUPP:
2025             n = ARG(scan);  /* which paren pair */
2026             sw = (*PL_reglastparen >= n && PL_regendp[n] != -1);
2027             break;
2028         case IFTHEN:
2029             if (sw)
2030                 next = NEXTOPER(NEXTOPER(scan));
2031             else {
2032                 next = scan + ARG(scan);
2033                 if (OP(next) == IFTHEN) /* Fake one. */
2034                     next = NEXTOPER(NEXTOPER(next));
2035             }
2036             break;
2037         case LOGICAL:
2038             logical = scan->flags;
2039             break;
2040         case CURLYX: {
2041                 CURCUR cc;
2042                 CHECKPOINT cp = PL_savestack_ix;
2043
2044                 if (OP(PREVOPER(next)) == NOTHING) /* LONGJMP */
2045                     next += ARG(next);
2046                 cc.oldcc = PL_regcc;
2047                 PL_regcc = &cc;
2048                 cc.parenfloor = *PL_reglastparen;
2049                 cc.cur = -1;
2050                 cc.min = ARG1(scan);
2051                 cc.max  = ARG2(scan);
2052                 cc.scan = NEXTOPER(scan) + EXTRA_STEP_2ARGS;
2053                 cc.next = next;
2054                 cc.minmod = minmod;
2055                 cc.lastloc = 0;
2056                 PL_reginput = locinput;
2057                 n = regmatch(PREVOPER(next));   /* start on the WHILEM */
2058                 regcpblow(cp);
2059                 PL_regcc = cc.oldcc;
2060                 saySAME(n);
2061             }
2062             /* NOT REACHED */
2063         case WHILEM: {
2064                 /*
2065                  * This is really hard to understand, because after we match
2066                  * what we're trying to match, we must make sure the rest of
2067                  * the RE is going to match for sure, and to do that we have
2068                  * to go back UP the parse tree by recursing ever deeper.  And
2069                  * if it fails, we have to reset our parent's current state
2070                  * that we can try again after backing off.
2071                  */
2072
2073                 CHECKPOINT cp, lastcp;
2074                 CURCUR* cc = PL_regcc;
2075                 char *lastloc = cc->lastloc; /* Detection of 0-len. */
2076                 
2077                 n = cc->cur + 1;        /* how many we know we matched */
2078                 PL_reginput = locinput;
2079
2080                 DEBUG_r(
2081                     PerlIO_printf(Perl_debug_log, 
2082                                   "%*s  %ld out of %ld..%ld  cc=%lx\n", 
2083                                   REPORT_CODE_OFF+PL_regindent*2, "",
2084                                   (long)n, (long)cc->min, 
2085                                   (long)cc->max, (long)cc)
2086                     );
2087
2088                 /* If degenerate scan matches "", assume scan done. */
2089
2090                 if (locinput == cc->lastloc && n >= cc->min) {
2091                     PL_regcc = cc->oldcc;
2092                     ln = PL_regcc->cur;
2093                     DEBUG_r(
2094                         PerlIO_printf(Perl_debug_log,
2095                            "%*s  empty match detected, try continuation...\n",
2096                            REPORT_CODE_OFF+PL_regindent*2, "")
2097                         );
2098                     if (regmatch(cc->next))
2099                         sayYES;
2100                     DEBUG_r(
2101                         PerlIO_printf(Perl_debug_log,
2102                                       "%*s  failed...\n",
2103                                       REPORT_CODE_OFF+PL_regindent*2, "")
2104                         );
2105                     PL_regcc->cur = ln;
2106                     PL_regcc = cc;
2107                     sayNO;
2108                 }
2109
2110                 /* First just match a string of min scans. */
2111
2112                 if (n < cc->min) {
2113                     cc->cur = n;
2114                     cc->lastloc = locinput;
2115                     if (regmatch(cc->scan))
2116                         sayYES;
2117                     cc->cur = n - 1;
2118                     cc->lastloc = lastloc;
2119                     DEBUG_r(
2120                         PerlIO_printf(Perl_debug_log,
2121                                       "%*s  failed...\n",
2122                                       REPORT_CODE_OFF+PL_regindent*2, "")
2123                         );
2124                     sayNO;
2125                 }
2126
2127                 /* Prefer next over scan for minimal matching. */
2128
2129                 if (cc->minmod) {
2130                     PL_regcc = cc->oldcc;
2131                     ln = PL_regcc->cur;
2132                     cp = regcppush(cc->parenfloor);
2133                     REGCP_SET;
2134                     if (regmatch(cc->next)) {
2135                         regcpblow(cp);
2136                         sayYES; /* All done. */
2137                     }
2138                     REGCP_UNWIND;
2139                     regcppop();
2140                     PL_regcc->cur = ln;
2141                     PL_regcc = cc;
2142
2143                     if (n >= cc->max) { /* Maximum greed exceeded? */
2144                         if (ckWARN(WARN_UNSAFE) && n >= REG_INFTY 
2145                             && !(PL_reg_flags & RF_warned)) {
2146                             PL_reg_flags |= RF_warned;
2147                             Perl_warner(aTHX_ WARN_UNSAFE, "%s limit (%d) exceeded",
2148                                  "Complex regular subexpression recursion",
2149                                  REG_INFTY - 1);
2150                         }
2151                         sayNO;
2152                     }
2153
2154                     DEBUG_r(
2155                         PerlIO_printf(Perl_debug_log,
2156                                       "%*s  trying longer...\n",
2157                                       REPORT_CODE_OFF+PL_regindent*2, "")
2158                         );
2159                     /* Try scanning more and see if it helps. */
2160                     PL_reginput = locinput;
2161                     cc->cur = n;
2162                     cc->lastloc = locinput;
2163                     cp = regcppush(cc->parenfloor);
2164                     REGCP_SET;
2165                     if (regmatch(cc->scan)) {
2166                         regcpblow(cp);
2167                         sayYES;
2168                     }
2169                     DEBUG_r(
2170                         PerlIO_printf(Perl_debug_log,
2171                                       "%*s  failed...\n",
2172                                       REPORT_CODE_OFF+PL_regindent*2, "")
2173                         );
2174                     REGCP_UNWIND;
2175                     regcppop();
2176                     cc->cur = n - 1;
2177                     cc->lastloc = lastloc;
2178                     sayNO;
2179                 }
2180
2181                 /* Prefer scan over next for maximal matching. */
2182
2183                 if (n < cc->max) {      /* More greed allowed? */
2184                     cp = regcppush(cc->parenfloor);
2185                     cc->cur = n;
2186                     cc->lastloc = locinput;
2187                     REGCP_SET;
2188                     if (regmatch(cc->scan)) {
2189                         regcpblow(cp);
2190                         sayYES;
2191                     }
2192                     REGCP_UNWIND;
2193                     regcppop();         /* Restore some previous $<digit>s? */
2194                     PL_reginput = locinput;
2195                     DEBUG_r(
2196                         PerlIO_printf(Perl_debug_log,
2197                                       "%*s  failed, try continuation...\n",
2198                                       REPORT_CODE_OFF+PL_regindent*2, "")
2199                         );
2200                 }
2201                 if (ckWARN(WARN_UNSAFE) && n >= REG_INFTY 
2202                         && !(PL_reg_flags & RF_warned)) {
2203                     PL_reg_flags |= RF_warned;
2204                     Perl_warner(aTHX_ WARN_UNSAFE, "%s limit (%d) exceeded",
2205                          "Complex regular subexpression recursion",
2206                          REG_INFTY - 1);
2207                 }
2208
2209                 /* Failed deeper matches of scan, so see if this one works. */
2210                 PL_regcc = cc->oldcc;
2211                 ln = PL_regcc->cur;
2212                 if (regmatch(cc->next))
2213                     sayYES;
2214                 DEBUG_r(
2215                     PerlIO_printf(Perl_debug_log, "%*s  failed...\n",
2216                                   REPORT_CODE_OFF+PL_regindent*2, "")
2217                     );
2218                 PL_regcc->cur = ln;
2219                 PL_regcc = cc;
2220                 cc->cur = n - 1;
2221                 cc->lastloc = lastloc;
2222                 sayNO;
2223             }
2224             /* NOT REACHED */
2225         case BRANCHJ: 
2226             next = scan + ARG(scan);
2227             if (next == scan)
2228                 next = NULL;
2229             inner = NEXTOPER(NEXTOPER(scan));
2230             goto do_branch;
2231         case BRANCH: 
2232             inner = NEXTOPER(scan);
2233           do_branch:
2234             {
2235                 CHECKPOINT lastcp;
2236                 c1 = OP(scan);
2237                 if (OP(next) != c1)     /* No choice. */
2238                     next = inner;       /* Avoid recursion. */
2239                 else {
2240                     int lastparen = *PL_reglastparen;
2241
2242                     REGCP_SET;
2243                     do {
2244                         PL_reginput = locinput;
2245                         if (regmatch(inner))
2246                             sayYES;
2247                         REGCP_UNWIND;
2248                         for (n = *PL_reglastparen; n > lastparen; n--)
2249                             PL_regendp[n] = -1;
2250                         *PL_reglastparen = n;
2251                         scan = next;
2252                         /*SUPPRESS 560*/
2253                         if (n = (c1 == BRANCH ? NEXT_OFF(next) : ARG(next)))
2254                             next += n;
2255                         else
2256                             next = NULL;
2257                         inner = NEXTOPER(scan);
2258                         if (c1 == BRANCHJ) {
2259                             inner = NEXTOPER(inner);
2260                         }
2261                     } while (scan != NULL && OP(scan) == c1);
2262                     sayNO;
2263                     /* NOTREACHED */
2264                 }
2265             }
2266             break;
2267         case MINMOD:
2268             minmod = 1;
2269             break;
2270         case CURLYM:
2271         {
2272             I32 l = 0;
2273             CHECKPOINT lastcp;
2274             
2275             /* We suppose that the next guy does not need
2276                backtracking: in particular, it is of constant length,
2277                and has no parenths to influence future backrefs. */
2278             ln = ARG1(scan);  /* min to match */
2279             n  = ARG2(scan);  /* max to match */
2280             paren = scan->flags;
2281             if (paren) {
2282                 if (paren > PL_regsize)
2283                     PL_regsize = paren;
2284                 if (paren > *PL_reglastparen)
2285                     *PL_reglastparen = paren;
2286             }
2287             scan = NEXTOPER(scan) + NODE_STEP_REGNODE;
2288             if (paren)
2289                 scan += NEXT_OFF(scan); /* Skip former OPEN. */
2290             PL_reginput = locinput;
2291             if (minmod) {
2292                 minmod = 0;
2293                 if (ln && regrepeat_hard(scan, ln, &l) < ln)
2294                     sayNO;
2295                 if (ln && l == 0 && n >= ln
2296                     /* In fact, this is tricky.  If paren, then the
2297                        fact that we did/didnot match may influence
2298                        future execution. */
2299                     && !(paren && ln == 0))
2300                     ln = n;
2301                 locinput = PL_reginput;
2302                 if (PL_regkind[(U8)OP(next)] == EXACT) {
2303                     c1 = UCHARAT(OPERAND(next) + 1);
2304                     if (OP(next) == EXACTF)
2305                         c2 = PL_fold[c1];
2306                     else if (OP(next) == EXACTFL)
2307                         c2 = PL_fold_locale[c1];
2308                     else
2309                         c2 = c1;
2310                 }
2311                 else
2312                     c1 = c2 = -1000;
2313                 REGCP_SET;
2314                 /* This may be improved if l == 0.  */
2315                 while (n >= ln || (n == REG_INFTY && ln > 0 && l)) { /* ln overflow ? */
2316                     /* If it could work, try it. */
2317                     if (c1 == -1000 ||
2318                         UCHARAT(PL_reginput) == c1 ||
2319                         UCHARAT(PL_reginput) == c2)
2320                     {
2321                         if (paren) {
2322                             if (n) {
2323                                 PL_regstartp[paren] =
2324                                     HOPc(PL_reginput, -l) - PL_bostr;
2325                                 PL_regendp[paren] = PL_reginput - PL_bostr;
2326                             }
2327                             else
2328                                 PL_regendp[paren] = -1;
2329                         }
2330                         if (regmatch(next))
2331                             sayYES;
2332                         REGCP_UNWIND;
2333                     }
2334                     /* Couldn't or didn't -- move forward. */
2335                     PL_reginput = locinput;
2336                     if (regrepeat_hard(scan, 1, &l)) {
2337                         ln++;
2338                         locinput = PL_reginput;
2339                     }
2340                     else
2341                         sayNO;
2342                 }
2343             }
2344             else {
2345                 n = regrepeat_hard(scan, n, &l);
2346                 if (n != 0 && l == 0
2347                     /* In fact, this is tricky.  If paren, then the
2348                        fact that we did/didnot match may influence
2349                        future execution. */
2350                     && !(paren && ln == 0))
2351                     ln = n;
2352                 locinput = PL_reginput;
2353                 DEBUG_r(
2354                     PerlIO_printf(Perl_debug_log,
2355                                   "%*s  matched %ld times, len=%ld...\n",
2356                                   REPORT_CODE_OFF+PL_regindent*2, "", n, l)
2357                     );
2358                 if (n >= ln) {
2359                     if (PL_regkind[(U8)OP(next)] == EXACT) {
2360                         c1 = UCHARAT(OPERAND(next) + 1);
2361                         if (OP(next) == EXACTF)
2362                             c2 = PL_fold[c1];
2363                         else if (OP(next) == EXACTFL)
2364                             c2 = PL_fold_locale[c1];
2365                         else
2366                             c2 = c1;
2367                     }
2368                     else
2369                         c1 = c2 = -1000;
2370                 }
2371                 REGCP_SET;
2372                 while (n >= ln) {
2373                     /* If it could work, try it. */
2374                     if (c1 == -1000 ||
2375                         UCHARAT(PL_reginput) == c1 ||
2376                         UCHARAT(PL_reginput) == c2)
2377                     {
2378                         DEBUG_r(
2379                                 PerlIO_printf(Perl_debug_log,
2380                                               "%*s  trying tail with n=%ld...\n",
2381                                               REPORT_CODE_OFF+PL_regindent*2, "", n)
2382                             );
2383                         if (paren) {
2384                             if (n) {
2385                                 PL_regstartp[paren] = HOPc(PL_reginput, -l) - PL_bostr;
2386                                 PL_regendp[paren] = PL_reginput - PL_bostr;
2387                             }
2388                             else
2389                                 PL_regendp[paren] = -1;
2390                         }
2391                         if (regmatch(next))
2392                             sayYES;
2393                         REGCP_UNWIND;
2394                     }
2395                     /* Couldn't or didn't -- back up. */
2396                     n--;
2397                     locinput = HOPc(locinput, -l);
2398                     PL_reginput = locinput;
2399                 }
2400             }
2401             sayNO;
2402             break;
2403         }
2404         case CURLYN:
2405             paren = scan->flags;        /* Which paren to set */
2406             if (paren > PL_regsize)
2407                 PL_regsize = paren;
2408             if (paren > *PL_reglastparen)
2409                 *PL_reglastparen = paren;
2410             ln = ARG1(scan);  /* min to match */
2411             n  = ARG2(scan);  /* max to match */
2412             scan = regnext(NEXTOPER(scan) + NODE_STEP_REGNODE);
2413             goto repeat;
2414         case CURLY:
2415             paren = 0;
2416             ln = ARG1(scan);  /* min to match */
2417             n  = ARG2(scan);  /* max to match */
2418             scan = NEXTOPER(scan) + NODE_STEP_REGNODE;
2419             goto repeat;
2420         case STAR:
2421             ln = 0;
2422             n = REG_INFTY;
2423             scan = NEXTOPER(scan);
2424             paren = 0;
2425             goto repeat;
2426         case PLUS:
2427             ln = 1;
2428             n = REG_INFTY;
2429             scan = NEXTOPER(scan);
2430             paren = 0;
2431           repeat:
2432             /*
2433             * Lookahead to avoid useless match attempts
2434             * when we know what character comes next.
2435             */
2436             if (PL_regkind[(U8)OP(next)] == EXACT) {
2437                 c1 = UCHARAT(OPERAND(next) + 1);
2438                 if (OP(next) == EXACTF)
2439                     c2 = PL_fold[c1];
2440                 else if (OP(next) == EXACTFL)
2441                     c2 = PL_fold_locale[c1];
2442                 else
2443                     c2 = c1;
2444             }
2445             else
2446                 c1 = c2 = -1000;
2447             PL_reginput = locinput;
2448             if (minmod) {
2449                 CHECKPOINT lastcp;
2450                 minmod = 0;
2451                 if (ln && regrepeat(scan, ln) < ln)
2452                     sayNO;
2453                 locinput = PL_reginput;
2454                 REGCP_SET;
2455                 if (c1 != -1000) {
2456                     char *e = locinput + n - ln; /* Should not check after this */
2457                     char *old = locinput;
2458
2459                     if (e >= PL_regeol || (n == REG_INFTY))
2460                         e = PL_regeol - 1;
2461                     while (1) {
2462                         /* Find place 'next' could work */
2463                         if (c1 == c2) {
2464                             while (locinput <= e && *locinput != c1)
2465                                 locinput++;
2466                         } else {
2467                             while (locinput <= e 
2468                                    && *locinput != c1
2469                                    && *locinput != c2)
2470                                 locinput++;                         
2471                         }
2472                         if (locinput > e) 
2473                             sayNO;
2474                         /* PL_reginput == old now */
2475                         if (locinput != old) {
2476                             ln = 1;     /* Did some */
2477                             if (regrepeat(scan, locinput - old) <
2478                                  locinput - old)
2479                                 sayNO;
2480                         }
2481                         /* PL_reginput == locinput now */
2482                         if (paren) {
2483                             if (ln) {
2484                                 PL_regstartp[paren] = HOPc(locinput, -1) - PL_bostr;
2485                                 PL_regendp[paren] = locinput - PL_bostr;
2486                             }
2487                             else
2488                                 PL_regendp[paren] = -1;
2489                         }
2490                         if (regmatch(next))
2491                             sayYES;
2492                         PL_reginput = locinput; /* Could be reset... */
2493                         REGCP_UNWIND;
2494                         /* Couldn't or didn't -- move forward. */
2495                         old = locinput++;
2496                     }
2497                 }
2498                 else
2499                 while (n >= ln || (n == REG_INFTY && ln > 0)) { /* ln overflow ? */
2500                     /* If it could work, try it. */
2501                     if (c1 == -1000 ||
2502                         UCHARAT(PL_reginput) == c1 ||
2503                         UCHARAT(PL_reginput) == c2)
2504                     {
2505                         if (paren) {
2506                             if (n) {
2507                                 PL_regstartp[paren] = HOPc(PL_reginput, -1) - PL_bostr;
2508                                 PL_regendp[paren] = PL_reginput - PL_bostr;
2509                             }
2510                             else
2511                                 PL_regendp[paren] = -1;
2512                         }
2513                         if (regmatch(next))
2514                             sayYES;
2515                         REGCP_UNWIND;
2516                     }
2517                     /* Couldn't or didn't -- move forward. */
2518                     PL_reginput = locinput;
2519                     if (regrepeat(scan, 1)) {
2520                         ln++;
2521                         locinput = PL_reginput;
2522                     }
2523                     else
2524                         sayNO;
2525                 }
2526             }
2527             else {
2528                 CHECKPOINT lastcp;
2529                 n = regrepeat(scan, n);
2530                 locinput = PL_reginput;
2531                 if (ln < n && PL_regkind[(U8)OP(next)] == EOL &&
2532                     (!PL_multiline  || OP(next) == SEOL))
2533                     ln = n;                     /* why back off? */
2534                 REGCP_SET;
2535                 if (paren) {
2536                     while (n >= ln) {
2537                         /* If it could work, try it. */
2538                         if (c1 == -1000 ||
2539                             UCHARAT(PL_reginput) == c1 ||
2540                             UCHARAT(PL_reginput) == c2)
2541                             {
2542                                 if (paren && n) {
2543                                     if (n) {
2544                                         PL_regstartp[paren] = HOPc(PL_reginput, -1) - PL_bostr;
2545                                         PL_regendp[paren] = PL_reginput - PL_bostr;
2546                                     }
2547                                     else
2548                                         PL_regendp[paren] = -1;
2549                                 }
2550                                 if (regmatch(next))
2551                                     sayYES;
2552                                 REGCP_UNWIND;
2553                             }
2554                         /* Couldn't or didn't -- back up. */
2555                         n--;
2556                         PL_reginput = locinput = HOPc(locinput, -1);
2557                     }
2558                 }
2559                 else {
2560                     while (n >= ln) {
2561                         /* If it could work, try it. */
2562                         if (c1 == -1000 ||
2563                             UCHARAT(PL_reginput) == c1 ||
2564                             UCHARAT(PL_reginput) == c2)
2565                             {
2566                                 if (regmatch(next))
2567                                     sayYES;
2568                                 REGCP_UNWIND;
2569                             }
2570                         /* Couldn't or didn't -- back up. */
2571                         n--;
2572                         PL_reginput = locinput = HOPc(locinput, -1);
2573                     }
2574                 }
2575             }
2576             sayNO;
2577             break;
2578         case END:
2579             if (PL_reg_call_cc) {
2580                 re_cc_state *cur_call_cc = PL_reg_call_cc;
2581                 CURCUR *cctmp = PL_regcc;
2582                 regexp *re = PL_reg_re;
2583                 CHECKPOINT cp, lastcp;
2584                 
2585                 cp = regcppush(0);      /* Save *all* the positions. */
2586                 REGCP_SET;
2587                 regcp_set_to(PL_reg_call_cc->ss); /* Restore parens of
2588                                                     the caller. */
2589                 PL_reginput = locinput; /* Make position available to
2590                                            the callcc. */
2591                 cache_re(PL_reg_call_cc->re);
2592                 PL_regcc = PL_reg_call_cc->cc;
2593                 PL_reg_call_cc = PL_reg_call_cc->prev;
2594                 if (regmatch(cur_call_cc->node)) {
2595                     PL_reg_call_cc = cur_call_cc;
2596                     regcpblow(cp);
2597                     sayYES;
2598                 }
2599                 REGCP_UNWIND;
2600                 regcppop();
2601                 PL_reg_call_cc = cur_call_cc;
2602                 PL_regcc = cctmp;
2603                 PL_reg_re = re;
2604                 cache_re(re);
2605
2606                 DEBUG_r(
2607                     PerlIO_printf(Perl_debug_log,
2608                                   "%*s  continuation failed...\n",
2609                                   REPORT_CODE_OFF+PL_regindent*2, "")
2610                     );
2611                 sayNO;
2612             }
2613             if (locinput < PL_regtill)
2614                 sayNO;                  /* Cannot match: too short. */
2615             /* Fall through */
2616         case SUCCEED:
2617             PL_reginput = locinput;     /* put where regtry can find it */
2618             sayYES;                     /* Success! */
2619         case SUSPEND:
2620             n = 1;
2621             PL_reginput = locinput;
2622             goto do_ifmatch;        
2623         case UNLESSM:
2624             n = 0;
2625             if (scan->flags) {
2626                 if (UTF) {              /* XXXX This is absolutely
2627                                            broken, we read before
2628                                            start of string. */
2629                     s = HOPMAYBEc(locinput, -scan->flags);
2630                     if (!s)
2631                         goto say_yes;
2632                     PL_reginput = s;
2633                 }
2634                 else {
2635                     if (locinput < PL_bostr + scan->flags) 
2636                         goto say_yes;
2637                     PL_reginput = locinput - scan->flags;
2638                     goto do_ifmatch;
2639                 }
2640             }
2641             else
2642                 PL_reginput = locinput;
2643             goto do_ifmatch;
2644         case IFMATCH:
2645             n = 1;
2646             if (scan->flags) {
2647                 if (UTF) {              /* XXXX This is absolutely
2648                                            broken, we read before
2649                                            start of string. */
2650                     s = HOPMAYBEc(locinput, -scan->flags);
2651                     if (!s || s < PL_bostr)
2652                         goto say_no;
2653                     PL_reginput = s;
2654                 }
2655                 else {
2656                     if (locinput < PL_bostr + scan->flags) 
2657                         goto say_no;
2658                     PL_reginput = locinput - scan->flags;
2659                     goto do_ifmatch;
2660                 }
2661             }
2662             else
2663                 PL_reginput = locinput;
2664
2665           do_ifmatch:
2666             inner = NEXTOPER(NEXTOPER(scan));
2667             if (regmatch(inner) != n) {
2668               say_no:
2669                 if (logical) {
2670                     logical = 0;
2671                     sw = 0;
2672                     goto do_longjump;
2673                 }
2674                 else
2675                     sayNO;
2676             }
2677           say_yes:
2678             if (logical) {
2679                 logical = 0;
2680                 sw = 1;
2681             }
2682             if (OP(scan) == SUSPEND) {
2683                 locinput = PL_reginput;
2684                 nextchr = UCHARAT(locinput);
2685             }
2686             /* FALL THROUGH. */
2687         case LONGJMP:
2688           do_longjump:
2689             next = scan + ARG(scan);
2690             if (next == scan)
2691                 next = NULL;
2692             break;
2693         default:
2694             PerlIO_printf(PerlIO_stderr(), "%lx %d\n",
2695                           (unsigned long)scan, OP(scan));
2696             Perl_croak(aTHX_ "regexp memory corruption");
2697         }
2698         scan = next;
2699     }
2700
2701     /*
2702     * We get here only if there's trouble -- normally "case END" is
2703     * the terminating point.
2704     */
2705     Perl_croak(aTHX_ "corrupted regexp pointers");
2706     /*NOTREACHED*/
2707     sayNO;
2708
2709 yes:
2710 #ifdef DEBUGGING
2711     PL_regindent--;
2712 #endif
2713     return 1;
2714
2715 no:
2716 #ifdef DEBUGGING
2717     PL_regindent--;
2718 #endif
2719     return 0;
2720 }
2721
2722 /*
2723  - regrepeat - repeatedly match something simple, report how many
2724  */
2725 /*
2726  * [This routine now assumes that it will only match on things of length 1.
2727  * That was true before, but now we assume scan - reginput is the count,
2728  * rather than incrementing count on every character.  [Er, except utf8.]]
2729  */
2730 STATIC I32
2731 S_regrepeat(pTHX_ regnode *p, I32 max)
2732 {
2733     dTHR;
2734     register char *scan;
2735     register char *opnd;
2736     register I32 c;
2737     register char *loceol = PL_regeol;
2738     register I32 hardcount = 0;
2739
2740     scan = PL_reginput;
2741     if (max != REG_INFTY && max < loceol - scan)
2742       loceol = scan + max;
2743     opnd = (char *) OPERAND(p);
2744     switch (OP(p)) {
2745     case REG_ANY:
2746         while (scan < loceol && *scan != '\n')
2747             scan++;
2748         break;
2749     case SANY:
2750         scan = loceol;
2751         break;
2752     case ANYUTF8:
2753         loceol = PL_regeol;
2754         while (scan < loceol && *scan != '\n') {
2755             scan += UTF8SKIP(scan);
2756             hardcount++;
2757         }
2758         break;
2759     case SANYUTF8:
2760         loceol = PL_regeol;
2761         while (scan < loceol) {
2762             scan += UTF8SKIP(scan);
2763             hardcount++;
2764         }
2765         break;
2766     case EXACT:         /* length of string is 1 */
2767         c = UCHARAT(++opnd);
2768         while (scan < loceol && UCHARAT(scan) == c)
2769             scan++;
2770         break;
2771     case EXACTF:        /* length of string is 1 */
2772         c = UCHARAT(++opnd);
2773         while (scan < loceol &&
2774                (UCHARAT(scan) == c || UCHARAT(scan) == PL_fold[c]))
2775             scan++;
2776         break;
2777     case EXACTFL:       /* length of string is 1 */
2778         PL_reg_flags |= RF_tainted;
2779         c = UCHARAT(++opnd);
2780         while (scan < loceol &&
2781                (UCHARAT(scan) == c || UCHARAT(scan) == PL_fold_locale[c]))
2782             scan++;
2783         break;
2784     case ANYOFUTF8:
2785         loceol = PL_regeol;
2786         while (scan < loceol && REGINCLASSUTF8(p, (U8*)scan)) {
2787             scan += UTF8SKIP(scan);
2788             hardcount++;
2789         }
2790         break;
2791     case ANYOF:
2792         while (scan < loceol && REGINCLASS(opnd, *scan))
2793             scan++;
2794         break;
2795     case ALNUM:
2796         while (scan < loceol && isALNUM(*scan))
2797             scan++;
2798         break;
2799     case ALNUMUTF8:
2800         loceol = PL_regeol;
2801         while (scan < loceol && swash_fetch(PL_utf8_alnum, (U8*)scan)) {
2802             scan += UTF8SKIP(scan);
2803             hardcount++;
2804         }
2805         break;
2806     case ALNUML:
2807         PL_reg_flags |= RF_tainted;
2808         while (scan < loceol && isALNUM_LC(*scan))
2809             scan++;
2810         break;
2811     case ALNUMLUTF8:
2812         PL_reg_flags |= RF_tainted;
2813         loceol = PL_regeol;
2814         while (scan < loceol && isALNUM_LC_utf8((U8*)scan)) {
2815             scan += UTF8SKIP(scan);
2816             hardcount++;
2817         }
2818         break;
2819         break;
2820     case NALNUM:
2821         while (scan < loceol && !isALNUM(*scan))
2822             scan++;
2823         break;
2824     case NALNUMUTF8:
2825         loceol = PL_regeol;
2826         while (scan < loceol && !swash_fetch(PL_utf8_alnum, (U8*)scan)) {
2827             scan += UTF8SKIP(scan);
2828             hardcount++;
2829         }
2830         break;
2831     case NALNUML:
2832         PL_reg_flags |= RF_tainted;
2833         while (scan < loceol && !isALNUM_LC(*scan))
2834             scan++;
2835         break;
2836     case NALNUMLUTF8:
2837         PL_reg_flags |= RF_tainted;
2838         loceol = PL_regeol;
2839         while (scan < loceol && !isALNUM_LC_utf8((U8*)scan)) {
2840             scan += UTF8SKIP(scan);
2841             hardcount++;
2842         }
2843         break;
2844     case SPACE:
2845         while (scan < loceol && isSPACE(*scan))
2846             scan++;
2847         break;
2848     case SPACEUTF8:
2849         loceol = PL_regeol;
2850         while (scan < loceol && (*scan == ' ' || swash_fetch(PL_utf8_space,(U8*)scan))) {
2851             scan += UTF8SKIP(scan);
2852             hardcount++;
2853         }
2854         break;
2855     case SPACEL:
2856         PL_reg_flags |= RF_tainted;
2857         while (scan < loceol && isSPACE_LC(*scan))
2858             scan++;
2859         break;
2860     case SPACELUTF8:
2861         PL_reg_flags |= RF_tainted;
2862         loceol = PL_regeol;
2863         while (scan < loceol && (*scan == ' ' || isSPACE_LC_utf8((U8*)scan))) {
2864             scan += UTF8SKIP(scan);
2865             hardcount++;
2866         }
2867         break;
2868     case NSPACE:
2869         while (scan < loceol && !isSPACE(*scan))
2870             scan++;
2871         break;
2872     case NSPACEUTF8:
2873         loceol = PL_regeol;
2874         while (scan < loceol && !(*scan == ' ' || swash_fetch(PL_utf8_space,(U8*)scan))) {
2875             scan += UTF8SKIP(scan);
2876             hardcount++;
2877         }
2878         break;
2879     case NSPACEL:
2880         PL_reg_flags |= RF_tainted;
2881         while (scan < loceol && !isSPACE_LC(*scan))
2882             scan++;
2883         break;
2884     case NSPACELUTF8:
2885         PL_reg_flags |= RF_tainted;
2886         loceol = PL_regeol;
2887         while (scan < loceol && !(*scan == ' ' || isSPACE_LC_utf8((U8*)scan))) {
2888             scan += UTF8SKIP(scan);
2889             hardcount++;
2890         }
2891         break;
2892     case DIGIT:
2893         while (scan < loceol && isDIGIT(*scan))
2894             scan++;
2895         break;
2896     case DIGITUTF8:
2897         loceol = PL_regeol;
2898         while (scan < loceol && swash_fetch(PL_utf8_digit,(U8*)scan)) {
2899             scan += UTF8SKIP(scan);
2900             hardcount++;
2901         }
2902         break;
2903         break;
2904     case NDIGIT:
2905         while (scan < loceol && !isDIGIT(*scan))
2906             scan++;
2907         break;
2908     case NDIGITUTF8:
2909         loceol = PL_regeol;
2910         while (scan < loceol && !swash_fetch(PL_utf8_digit,(U8*)scan)) {
2911             scan += UTF8SKIP(scan);
2912             hardcount++;
2913         }
2914         break;
2915     default:            /* Called on something of 0 width. */
2916         break;          /* So match right here or not at all. */
2917     }
2918
2919     if (hardcount)
2920         c = hardcount;
2921     else
2922         c = scan - PL_reginput;
2923     PL_reginput = scan;
2924
2925     DEBUG_r( 
2926         {
2927                 SV *prop = sv_newmortal();
2928
2929                 regprop(prop, p);
2930                 PerlIO_printf(Perl_debug_log, 
2931                               "%*s  %s can match %ld times out of %ld...\n", 
2932                               REPORT_CODE_OFF+1, "", SvPVX(prop),c,max);
2933         });
2934     
2935     return(c);
2936 }
2937
2938 /*
2939  - regrepeat_hard - repeatedly match something, report total lenth and length
2940  * 
2941  * The repeater is supposed to have constant length.
2942  */
2943
2944 STATIC I32
2945 S_regrepeat_hard(pTHX_ regnode *p, I32 max, I32 *lp)
2946 {
2947     dTHR;
2948     register char *scan;
2949     register char *start;
2950     register char *loceol = PL_regeol;
2951     I32 l = 0;
2952     I32 count = 0, res = 1;
2953
2954     if (!max)
2955         return 0;
2956
2957     start = PL_reginput;
2958     if (UTF) {
2959         while (PL_reginput < loceol && (scan = PL_reginput, res = regmatch(p))) {
2960             if (!count++) {
2961                 l = 0;
2962                 while (start < PL_reginput) {
2963                     l++;
2964                     start += UTF8SKIP(start);
2965                 }
2966                 *lp = l;
2967                 if (l == 0)
2968                     return max;
2969             }
2970             if (count == max)
2971                 return count;
2972         }
2973     }
2974     else {
2975         while (PL_reginput < loceol && (scan = PL_reginput, res = regmatch(p))) {
2976             if (!count++) {
2977                 *lp = l = PL_reginput - start;
2978                 if (max != REG_INFTY && l*max < loceol - scan)
2979                     loceol = scan + l*max;
2980                 if (l == 0)
2981                     return max;
2982             }
2983         }
2984     }
2985     if (!res)
2986         PL_reginput = scan;
2987     
2988     return count;
2989 }
2990
2991 /*
2992  - reginclass - determine if a character falls into a character class
2993  */
2994
2995 STATIC bool
2996 S_reginclass(pTHX_ register char *p, register I32 c)
2997 {
2998     dTHR;
2999     char flags = ANYOF_FLAGS(p);
3000     bool match = FALSE;
3001
3002     c &= 0xFF;
3003     if (ANYOF_BITMAP_TEST(p, c))
3004         match = TRUE;
3005     else if (flags & ANYOF_FOLD) {
3006         I32 cf;
3007         if (flags & ANYOF_LOCALE) {
3008             PL_reg_flags |= RF_tainted;
3009             cf = PL_fold_locale[c];
3010         }
3011         else
3012             cf = PL_fold[c];
3013         if (ANYOF_BITMAP_TEST(p, cf))
3014             match = TRUE;
3015     }
3016
3017     if (!match && (flags & ANYOF_CLASS)) {
3018         PL_reg_flags |= RF_tainted;
3019         if (
3020             (ANYOF_CLASS_TEST(p, ANYOF_ALNUM)   &&  isALNUM_LC(c))  ||
3021             (ANYOF_CLASS_TEST(p, ANYOF_NALNUM)  && !isALNUM_LC(c))  ||
3022             (ANYOF_CLASS_TEST(p, ANYOF_SPACE)   &&  isSPACE_LC(c))  ||
3023             (ANYOF_CLASS_TEST(p, ANYOF_NSPACE)  && !isSPACE_LC(c))  ||
3024             (ANYOF_CLASS_TEST(p, ANYOF_DIGIT)   &&  isDIGIT_LC(c))  ||
3025             (ANYOF_CLASS_TEST(p, ANYOF_NDIGIT)  && !isDIGIT_LC(c))  ||
3026             (ANYOF_CLASS_TEST(p, ANYOF_ALNUMC)  &&  isALNUMC_LC(c)) ||
3027             (ANYOF_CLASS_TEST(p, ANYOF_NALNUMC) && !isALNUMC_LC(c)) ||
3028             (ANYOF_CLASS_TEST(p, ANYOF_ALPHA)   &&  isALPHA_LC(c))  ||
3029             (ANYOF_CLASS_TEST(p, ANYOF_NALPHA)  && !isALPHA_LC(c))  ||
3030             (ANYOF_CLASS_TEST(p, ANYOF_ASCII)   &&  isASCII(c))     ||
3031             (ANYOF_CLASS_TEST(p, ANYOF_NASCII)  && !isASCII(c))     ||
3032             (ANYOF_CLASS_TEST(p, ANYOF_CNTRL)   &&  isCNTRL_LC(c))  ||
3033             (ANYOF_CLASS_TEST(p, ANYOF_NCNTRL)  && !isCNTRL_LC(c))  ||
3034             (ANYOF_CLASS_TEST(p, ANYOF_GRAPH)   &&  isGRAPH_LC(c))  ||
3035             (ANYOF_CLASS_TEST(p, ANYOF_NGRAPH)  && !isGRAPH_LC(c))  ||
3036             (ANYOF_CLASS_TEST(p, ANYOF_LOWER)   &&  isLOWER_LC(c))  ||
3037             (ANYOF_CLASS_TEST(p, ANYOF_NLOWER)  && !isLOWER_LC(c))  ||
3038             (ANYOF_CLASS_TEST(p, ANYOF_PRINT)   &&  isPRINT_LC(c))  ||
3039             (ANYOF_CLASS_TEST(p, ANYOF_NPRINT)  && !isPRINT_LC(c))  ||
3040             (ANYOF_CLASS_TEST(p, ANYOF_PUNCT)   &&  isPUNCT_LC(c))  ||
3041             (ANYOF_CLASS_TEST(p, ANYOF_NPUNCT)  && !isPUNCT_LC(c))  ||
3042             (ANYOF_CLASS_TEST(p, ANYOF_UPPER)   &&  isUPPER_LC(c))  ||
3043             (ANYOF_CLASS_TEST(p, ANYOF_NUPPER)  && !isUPPER_LC(c))  ||
3044             (ANYOF_CLASS_TEST(p, ANYOF_XDIGIT)  &&  isXDIGIT(c))    ||
3045             (ANYOF_CLASS_TEST(p, ANYOF_NXDIGIT) && !isXDIGIT(c))
3046             ) /* How's that for a conditional? */
3047         {
3048             match = TRUE;
3049         }
3050     }
3051
3052     return (flags & ANYOF_INVERT) ? !match : match;
3053 }
3054
3055 STATIC bool
3056 S_reginclassutf8(pTHX_ regnode *f, U8 *p)
3057 {                                           
3058     dTHR;
3059     char flags = ARG1(f);
3060     bool match = FALSE;
3061     SV *sv = (SV*)PL_regdata->data[ARG2(f)];
3062
3063     if (swash_fetch(sv, p))
3064         match = TRUE;
3065     else if (flags & ANYOF_FOLD) {
3066         I32 cf;
3067         U8 tmpbuf[10];
3068         if (flags & ANYOF_LOCALE) {
3069             PL_reg_flags |= RF_tainted;
3070             uv_to_utf8(tmpbuf, toLOWER_LC_utf8(p));
3071         }
3072         else
3073             uv_to_utf8(tmpbuf, toLOWER_utf8(p));
3074         if (swash_fetch(sv, tmpbuf))
3075             match = TRUE;
3076     }
3077
3078     /* UTF8 combined with ANYOF_CLASS is ill-defined. */
3079
3080     return (flags & ANYOF_INVERT) ? !match : match;
3081 }
3082
3083 STATIC U8 *
3084 S_reghop(pTHX_ U8 *s, I32 off)
3085 {                               
3086     dTHR;
3087     if (off >= 0) {
3088         while (off-- && s < (U8*)PL_regeol)
3089             s += UTF8SKIP(s);
3090     }
3091     else {
3092         while (off++) {
3093             if (s > (U8*)PL_bostr) {
3094                 s--;
3095                 if (*s & 0x80) {
3096                     while (s > (U8*)PL_bostr && (*s & 0xc0) == 0x80)
3097                         s--;
3098                 }               /* XXX could check well-formedness here */
3099             }
3100         }
3101     }
3102     return s;
3103 }
3104
3105 STATIC U8 *
3106 S_reghopmaybe(pTHX_ U8* s, I32 off)
3107 {
3108     dTHR;
3109     if (off >= 0) {
3110         while (off-- && s < (U8*)PL_regeol)
3111             s += UTF8SKIP(s);
3112         if (off >= 0)
3113             return 0;
3114     }
3115     else {
3116         while (off++) {
3117             if (s > (U8*)PL_bostr) {
3118                 s--;
3119                 if (*s & 0x80) {
3120                     while (s > (U8*)PL_bostr && (*s & 0xc0) == 0x80)
3121                         s--;
3122                 }               /* XXX could check well-formedness here */
3123             }
3124             else
3125                 break;
3126         }
3127         if (off <= 0)
3128             return 0;
3129     }
3130     return s;
3131 }
3132
3133 #ifdef PERL_OBJECT
3134 #define NO_XSLOCKS
3135 #include "XSUB.h"
3136 #endif
3137
3138 static void
3139 restore_pos(pTHXo_ void *arg)
3140 {
3141     dTHR;
3142     if (PL_reg_eval_set) {
3143         if (PL_reg_oldsaved) {
3144             PL_reg_re->subbeg = PL_reg_oldsaved;
3145             PL_reg_re->sublen = PL_reg_oldsavedlen;
3146             RX_MATCH_COPIED_on(PL_reg_re);
3147         }
3148         PL_reg_magic->mg_len = PL_reg_oldpos;
3149         PL_reg_eval_set = 0;
3150         PL_curpm = PL_reg_oldcurpm;
3151     }   
3152 }
3153