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