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