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