add patch (via PM)
[p5sagit/p5-mst-13.2.git] / regexec.c
1 /*    regexec.c
2  */
3
4 /*
5  * "One Ring to rule them all, One Ring to find them..."
6  */
7
8 /* NOTE: this is derived from Henry Spencer's regexp code, and should not
9  * confused with the original package (see point 3 below).  Thanks, Henry!
10  */
11
12 /* Additional note: this code is very heavily munged from Henry's version
13  * in places.  In some spots I've traded clarity for efficiency, so don't
14  * blame Henry for some of the lack of readability.
15  */
16
17 /* The names of the functions have been changed from regcomp and
18  * regexec to  pregcomp and pregexec in order to avoid conflicts
19  * with the POSIX routines of the same names.
20 */
21
22 #ifdef IN_XSUB_RE
23 /* We *really* need to overwrite these symbols: */
24 #  define Perl_regexec_flags my_regexec
25 #  define Perl_regdump my_regdump
26 #  define Perl_regprop my_regprop
27 /* *These* symbols are masked to allow static link. */
28 #  define Perl_pregexec my_pregexec
29 #endif 
30
31 /*SUPPRESS 112*/
32 /*
33  * pregcomp and pregexec -- regsub and regerror are not used in perl
34  *
35  *      Copyright (c) 1986 by University of Toronto.
36  *      Written by Henry Spencer.  Not derived from licensed software.
37  *
38  *      Permission is granted to anyone to use this software for any
39  *      purpose on any computer system, and to redistribute it freely,
40  *      subject to the following restrictions:
41  *
42  *      1. The author is not responsible for the consequences of use of
43  *              this software, no matter how awful, even if they arise
44  *              from defects in it.
45  *
46  *      2. The origin of this software must not be misrepresented, either
47  *              by explicit claim or by omission.
48  *
49  *      3. Altered versions must be plainly marked as such, and must not
50  *              be misrepresented as being the original software.
51  *
52  ****    Alterations to Henry's code are...
53  ****
54  ****    Copyright (c) 1991-1997, Larry Wall
55  ****
56  ****    You may distribute under the terms of either the GNU General Public
57  ****    License or the Artistic License, as specified in the README file.
58  *
59  * Beware that some of this code is subtly aware of the way operator
60  * precedence is structured in regular expressions.  Serious changes in
61  * regular-expression syntax might require a total rethink.
62  */
63 #include "EXTERN.h"
64 #include "perl.h"
65 #include "regcomp.h"
66
67 #define RF_tainted      1               /* tainted information used? */
68 #define RF_warned       2               /* warned about big count? */
69 #define RF_evaled       4               /* Did an EVAL with setting? */
70
71 #define RS_init         1               /* eval environment created */
72 #define RS_set          2               /* replsv value is set */
73
74 #ifndef STATIC
75 #define STATIC  static
76 #endif
77
78 #ifndef PERL_OBJECT
79 typedef I32 CHECKPOINT;
80
81 /*
82  * Forwards.
83  */
84
85 static I32 regmatch _((regnode *prog));
86 static I32 regrepeat _((regnode *p, I32 max));
87 static I32 regrepeat_hard _((regnode *p, I32 max, I32 *lp));
88 static I32 regtry _((regexp *prog, char *startpos));
89
90 static bool reginclass _((char *p, I32 c));
91 static CHECKPOINT regcppush _((I32 parenfloor));
92 static char * regcppop _((void));
93 #endif
94 #define REGINCLASS(p,c)  (*(p) ? reginclass(p,c) : ANYOF_TEST(p,c))
95
96 STATIC CHECKPOINT
97 regcppush(I32 parenfloor)
98 {
99     dTHR;
100     int retval = savestack_ix;
101     int i = (regsize - parenfloor) * 4;
102     int p;
103
104     SSCHECK(i + 5);
105     for (p = regsize; p > parenfloor; p--) {
106         SSPUSHPTR(regendp[p]);
107         SSPUSHPTR(regstartp[p]);
108         SSPUSHPTR(reg_start_tmp[p]);
109         SSPUSHINT(p);
110     }
111     SSPUSHINT(regsize);
112     SSPUSHINT(*reglastparen);
113     SSPUSHPTR(reginput);
114     SSPUSHINT(i + 3);
115     SSPUSHINT(SAVEt_REGCONTEXT);
116     return retval;
117 }
118
119 /* These are needed since we do not localize EVAL nodes: */
120 #  define REGCP_SET  DEBUG_r(PerlIO_printf(Perl_debug_log, "  Setting an EVAL scope, savestack=%i\n", savestack_ix)); lastcp = savestack_ix
121 #  define REGCP_UNWIND  DEBUG_r(lastcp != savestack_ix ? PerlIO_printf(Perl_debug_log,"  Clearing an EVAL scope, savestack=%i..%i\n", lastcp, savestack_ix) : 0); regcpblow(lastcp)
122
123 STATIC char *
124 regcppop(void)
125 {
126     dTHR;
127     I32 i = SSPOPINT;
128     U32 paren = 0;
129     char *input;
130     char *tmps;
131     assert(i == SAVEt_REGCONTEXT);
132     i = SSPOPINT;
133     input = (char *) SSPOPPTR;
134     *reglastparen = SSPOPINT;
135     regsize = SSPOPINT;
136     for (i -= 3; i > 0; i -= 4) {
137         paren = (U32)SSPOPINT;
138         reg_start_tmp[paren] = (char *) SSPOPPTR;
139         regstartp[paren] = (char *) SSPOPPTR;
140         tmps = (char*)SSPOPPTR;
141         if (paren <= *reglastparen)
142             regendp[paren] = tmps;
143         DEBUG_r(
144             PerlIO_printf(Perl_debug_log, "     restoring \\%d to %d(%d)..%d%s\n",
145                           paren, regstartp[paren] - regbol, 
146                           reg_start_tmp[paren] - regbol,
147                           regendp[paren] - regbol, 
148                           (paren > *reglastparen ? "(no)" : ""));
149         );
150     }
151     DEBUG_r(
152         if (*reglastparen + 1 <= regnpar) {
153             PerlIO_printf(Perl_debug_log, "     restoring \\%d..\\%d to undef\n",
154                           *reglastparen + 1, regnpar);
155         }
156     );
157     for (paren = *reglastparen + 1; paren <= regnpar; paren++) {
158         if (paren > regsize)
159             regstartp[paren] = Nullch;
160         regendp[paren] = Nullch;
161     }
162     return input;
163 }
164
165 #define regcpblow(cp) LEAVE_SCOPE(cp)
166
167 /*
168  * pregexec and friends
169  */
170
171 /*
172  - pregexec - match a regexp against a string
173  */
174 I32
175 pregexec(register regexp *prog, char *stringarg, register char *strend, char *strbeg, I32 minend, SV *screamer, U32 nosave)
176 /* strend: pointer to null at end of string */
177 /* strbeg: real beginning of string */
178 /* minend: end of match must be >=minend after stringarg. */
179 /* nosave: For optimizations. */
180 {
181     return
182         regexec_flags(prog, stringarg, strend, strbeg, minend, screamer, NULL, 
183                       nosave ? 0 : REXEC_COPY_STR);
184 }
185   
186 /*
187  - regexec_flags - match a regexp against a string
188  */
189 I32
190 regexec_flags(register regexp *prog, char *stringarg, register char *strend, char *strbeg, I32 minend, SV *screamer, void *data, U32 flags)
191 /* strend: pointer to null at end of string */
192 /* strbeg: real beginning of string */
193 /* minend: end of match must be >=minend after stringarg. */
194 /* data: May be used for some additional optimizations. */
195 /* nosave: For optimizations. */
196 {
197     register char *s;
198     register regnode *c;
199     register char *startpos = stringarg;
200     register I32 tmp;
201     I32 minlen;         /* must match at least this many chars */
202     I32 dontbother = 0; /* how many characters not to try at end */
203     CURCUR cc;
204     I32 start_shift = 0;                /* Offset of the start to find
205                                          constant substr. */
206     I32 end_shift = 0;                  /* Same for the end. */
207     I32 scream_pos = -1;                /* Internal iterator of scream. */
208     char *scream_olds;
209     SV* oreplsv = GvSV(replgv);
210
211     cc.cur = 0;
212     cc.oldcc = 0;
213     regcc = &cc;
214
215     regprecomp = prog->precomp;         /* Needed for error messages. */
216 #ifdef DEBUGGING
217     regnarrate = debug & 512;
218     regprogram = prog->program;
219 #endif
220
221     /* Be paranoid... */
222     if (prog == NULL || startpos == NULL) {
223         croak("NULL regexp parameter");
224         return 0;
225     }
226
227     minlen = prog->minlen;
228     if (strend - startpos < minlen) goto phooey;
229
230     if (startpos == strbeg)     /* is ^ valid at stringarg? */
231         regprev = '\n';
232     else {
233         regprev = stringarg[-1];
234         if (!multiline && regprev == '\n')
235             regprev = '\0';             /* force ^ to NOT match */
236     }
237
238     /* Check validity of program. */
239     if (UCHARAT(prog->program) != MAGIC) {
240         FAIL("corrupted regexp program");
241     }
242
243     regnpar = prog->nparens;
244     reg_flags = 0;
245     reg_eval_set = 0;
246
247     /* If there is a "must appear" string, look for it. */
248     s = startpos;
249     if (!(flags & REXEC_CHECKED) 
250         && prog->check_substr != Nullsv &&
251         !(prog->reganch & ROPT_ANCH_GPOS) &&
252         (!(prog->reganch & (ROPT_ANCH_BOL | ROPT_ANCH_MBOL))
253          || (multiline && prog->check_substr == prog->anchored_substr)) )
254     {
255         start_shift = prog->check_offset_min;
256         /* Should be nonnegative! */
257         end_shift = minlen - start_shift - SvCUR(prog->check_substr);
258         if (screamer) {
259             if (screamfirst[BmRARE(prog->check_substr)] >= 0)
260                     s = screaminstr(screamer, prog->check_substr, 
261                                     start_shift + (stringarg - strbeg),
262                                     end_shift, &scream_pos, 0);
263             else
264                     s = Nullch;
265             scream_olds = s;
266         }
267         else
268             s = fbm_instr((unsigned char*)s + start_shift,
269                           (unsigned char*)strend - end_shift,
270                 prog->check_substr, 0);
271         if (!s) {
272             ++BmUSEFUL(prog->check_substr);     /* hooray */
273             goto phooey;        /* not present */
274         } else if ((s - stringarg) > prog->check_offset_max) {
275             ++BmUSEFUL(prog->check_substr);     /* hooray/2 */
276             s -= prog->check_offset_max;
277         } else if (!prog->naughty 
278                    && --BmUSEFUL(prog->check_substr) < 0
279                    && prog->check_substr == prog->float_substr) { /* boo */
280             SvREFCNT_dec(prog->check_substr);
281             prog->check_substr = Nullsv;        /* disable */
282             prog->float_substr = Nullsv;        /* clear */
283             s = startpos;
284         } else s = startpos;
285     }
286
287     /* Mark beginning of line for ^ and lookbehind. */
288     regbol = startpos;
289     bostr  = strbeg;
290
291     /* Mark end of line for $ (and such) */
292     regeol = strend;
293
294     /* see how far we have to get to not match where we matched before */
295     regtill = startpos+minend;
296
297     DEBUG_r(
298         PerlIO_printf(Perl_debug_log, 
299                       "Matching `%.60s%s' against `%.*s%s'\n",
300                       prog->precomp, 
301                       (strlen(prog->precomp) > 60 ? "..." : ""),
302                       (strend - startpos > 60 ? 60 : strend - startpos),
303                       startpos, 
304                       (strend - startpos > 60 ? "..." : ""))
305         );
306
307     /* Simplest case:  anchored match need be tried only once. */
308     /*  [unless only anchor is BOL and multiline is set] */
309     if (prog->reganch & ROPT_ANCH) {
310         if (regtry(prog, startpos))
311             goto got_it;
312         else if (!(prog->reganch & ROPT_ANCH_GPOS) &&
313                  (multiline || (prog->reganch & ROPT_IMPLICIT)
314                   || (prog->reganch & ROPT_ANCH_MBOL)))
315         {
316             if (minlen)
317                 dontbother = minlen - 1;
318             strend -= dontbother;
319             /* for multiline we only have to try after newlines */
320             if (s > startpos)
321                 s--;
322             while (s < strend) {
323                 if (*s++ == '\n') {
324                     if (s < strend && regtry(prog, s))
325                         goto got_it;
326                 }
327             }
328         }
329         goto phooey;
330     }
331
332     /* Messy cases:  unanchored match. */
333     if (prog->anchored_substr && prog->reganch & ROPT_SKIP) { 
334         /* we have /x+whatever/ */
335         /* it must be a one character string */
336         char ch = SvPVX(prog->anchored_substr)[0];
337         while (s < strend) {
338             if (*s == ch) {
339                 if (regtry(prog, s)) goto got_it;
340                 s++;
341                 while (s < strend && *s == ch)
342                     s++;
343             }
344             s++;
345         }
346     }
347     /*SUPPRESS 560*/
348     else if (prog->anchored_substr != Nullsv
349              || (prog->float_substr != Nullsv 
350                  && prog->float_max_offset < strend - s)) {
351         SV *must = prog->anchored_substr 
352             ? prog->anchored_substr : prog->float_substr;
353         I32 back_max = 
354             prog->anchored_substr ? prog->anchored_offset : prog->float_max_offset;
355         I32 back_min = 
356             prog->anchored_substr ? prog->anchored_offset : prog->float_min_offset;
357         I32 delta = back_max - back_min;
358         char *last = strend - SvCUR(must) - back_min; /* Cannot start after this */
359         char *last1 = s - 1;            /* Last position checked before */
360
361         /* XXXX check_substr already used to find `s', can optimize if
362            check_substr==must. */
363         scream_pos = -1;
364         dontbother = end_shift;
365         strend -= dontbother;
366         while ( (s <= last) &&
367                 (screamer 
368                  ? (s = screaminstr(screamer, must, s + back_min - strbeg,
369                                     end_shift, &scream_pos, 0))
370                  : (s = fbm_instr((unsigned char*)s + back_min,
371                                   (unsigned char*)strend, must, 0))) ) {
372             if (s - back_max > last1) {
373                 last1 = s - back_min;
374                 s = s - back_max;
375             } else {
376                 char *t = last1 + 1;            
377
378                 last1 = s - back_min;
379                 s = t;          
380             }
381             while (s <= last1) {
382                 if (regtry(prog, s))
383                     goto got_it;
384                 s++;
385             }
386         }
387         goto phooey;
388     } else if (c = prog->regstclass) {
389         I32 doevery = (prog->reganch & ROPT_SKIP) == 0;
390         char *Class;
391
392         if (minlen)
393             dontbother = minlen - 1;
394         strend -= dontbother;   /* don't bother with what can't match */
395         tmp = 1;
396         /* We know what class it must start with. */
397         switch (OP(c)) {
398         case ANYOF:
399             Class = (char *) OPERAND(c);
400             while (s < strend) {
401                 if (REGINCLASS(Class, *s)) {
402                     if (tmp && regtry(prog, s))
403                         goto got_it;
404                     else
405                         tmp = doevery;
406                 }
407                 else
408                     tmp = 1;
409                 s++;
410             }
411             break;
412         case BOUNDL:
413             reg_flags |= RF_tainted;
414             /* FALL THROUGH */
415         case BOUND:
416             if (minlen)
417                 dontbother++,strend--;
418             tmp = (s != startpos) ? UCHARAT(s - 1) : regprev;
419             tmp = ((OP(c) == BOUND ? isALNUM(tmp) : isALNUM_LC(tmp)) != 0);
420             while (s < strend) {
421                 if (tmp == !(OP(c) == BOUND ? isALNUM(*s) : isALNUM_LC(*s))) {
422                     tmp = !tmp;
423                     if (regtry(prog, s))
424                         goto got_it;
425                 }
426                 s++;
427             }
428             if ((minlen || tmp) && regtry(prog,s))
429                 goto got_it;
430             break;
431         case NBOUNDL:
432             reg_flags |= RF_tainted;
433             /* FALL THROUGH */
434         case NBOUND:
435             if (minlen)
436                 dontbother++,strend--;
437             tmp = (s != startpos) ? UCHARAT(s - 1) : regprev;
438             tmp = ((OP(c) == NBOUND ? isALNUM(tmp) : isALNUM_LC(tmp)) != 0);
439             while (s < strend) {
440                 if (tmp == !(OP(c) == NBOUND ? isALNUM(*s) : isALNUM_LC(*s)))
441                     tmp = !tmp;
442                 else if (regtry(prog, s))
443                     goto got_it;
444                 s++;
445             }
446             if ((minlen || !tmp) && regtry(prog,s))
447                 goto got_it;
448             break;
449         case ALNUM:
450             while (s < strend) {
451                 if (isALNUM(*s)) {
452                     if (tmp && regtry(prog, s))
453                         goto got_it;
454                     else
455                         tmp = doevery;
456                 }
457                 else
458                     tmp = 1;
459                 s++;
460             }
461             break;
462         case ALNUML:
463             reg_flags |= RF_tainted;
464             while (s < strend) {
465                 if (isALNUM_LC(*s)) {
466                     if (tmp && regtry(prog, s))
467                         goto got_it;
468                     else
469                         tmp = doevery;
470                 }
471                 else
472                     tmp = 1;
473                 s++;
474             }
475             break;
476         case NALNUM:
477             while (s < strend) {
478                 if (!isALNUM(*s)) {
479                     if (tmp && regtry(prog, s))
480                         goto got_it;
481                     else
482                         tmp = doevery;
483                 }
484                 else
485                     tmp = 1;
486                 s++;
487             }
488             break;
489         case NALNUML:
490             reg_flags |= RF_tainted;
491             while (s < strend) {
492                 if (!isALNUM_LC(*s)) {
493                     if (tmp && regtry(prog, s))
494                         goto got_it;
495                     else
496                         tmp = doevery;
497                 }
498                 else
499                     tmp = 1;
500                 s++;
501             }
502             break;
503         case SPACE:
504             while (s < strend) {
505                 if (isSPACE(*s)) {
506                     if (tmp && regtry(prog, s))
507                         goto got_it;
508                     else
509                         tmp = doevery;
510                 }
511                 else
512                     tmp = 1;
513                 s++;
514             }
515             break;
516         case SPACEL:
517             reg_flags |= RF_tainted;
518             while (s < strend) {
519                 if (isSPACE_LC(*s)) {
520                     if (tmp && regtry(prog, s))
521                         goto got_it;
522                     else
523                         tmp = doevery;
524                 }
525                 else
526                     tmp = 1;
527                 s++;
528             }
529             break;
530         case NSPACE:
531             while (s < strend) {
532                 if (!isSPACE(*s)) {
533                     if (tmp && regtry(prog, s))
534                         goto got_it;
535                     else
536                         tmp = doevery;
537                 }
538                 else
539                     tmp = 1;
540                 s++;
541             }
542             break;
543         case NSPACEL:
544             reg_flags |= RF_tainted;
545             while (s < strend) {
546                 if (!isSPACE_LC(*s)) {
547                     if (tmp && regtry(prog, s))
548                         goto got_it;
549                     else
550                         tmp = doevery;
551                 }
552                 else
553                     tmp = 1;
554                 s++;
555             }
556             break;
557         case DIGIT:
558             while (s < strend) {
559                 if (isDIGIT(*s)) {
560                     if (tmp && regtry(prog, s))
561                         goto got_it;
562                     else
563                         tmp = doevery;
564                 }
565                 else
566                     tmp = 1;
567                 s++;
568             }
569             break;
570         case NDIGIT:
571             while (s < strend) {
572                 if (!isDIGIT(*s)) {
573                     if (tmp && regtry(prog, s))
574                         goto got_it;
575                     else
576                         tmp = doevery;
577                 }
578                 else
579                     tmp = 1;
580                 s++;
581             }
582             break;
583         }
584     }
585     else {
586         dontbother = 0;
587         if (prog->float_substr != Nullsv) {     /* Trim the end. */
588             char *last;
589             I32 oldpos = scream_pos;
590
591             if (screamer) {
592                 last = screaminstr(screamer, prog->float_substr, s - strbeg,
593                                    end_shift, &scream_pos, 1); /* last one */
594                 if (!last) {
595                     last = scream_olds; /* Only one occurence. */
596                 }
597             } else {
598                 STRLEN len;
599                 char *little = SvPV(prog->float_substr, len);
600                 last = rninstr(s, strend, little, little + len);
601             }
602             if (last == NULL) goto phooey; /* Should not happen! */
603             dontbother = strend - last - 1;
604         }
605         if (minlen && (dontbother < minlen))
606             dontbother = minlen - 1;
607         strend -= dontbother;
608         /* We don't know much -- general case. */
609         do {
610             if (regtry(prog, s))
611                 goto got_it;
612         } while (s++ < strend);
613     }
614
615     /* Failure. */
616     goto phooey;
617
618 got_it:
619     strend += dontbother;       /* uncheat */
620     prog->subbeg = strbeg;
621     prog->subend = strend;
622     RX_MATCH_TAINTED_set(prog, reg_flags & RF_tainted);
623
624     /* make sure $`, $&, $', and $digit will work later */
625     if (strbeg != prog->subbase) {      /* second+ //g match.  */
626         if (!(flags & REXEC_COPY_STR)) {
627             if (prog->subbase) {
628                 Safefree(prog->subbase);
629                 prog->subbase = Nullch;
630             }
631         }
632         else {
633             I32 i = strend - startpos + (stringarg - strbeg);
634             s = savepvn(strbeg, i);
635             Safefree(prog->subbase);
636             prog->subbase = s;
637             prog->subbeg = prog->subbase;
638             prog->subend = prog->subbase + i;
639             s = prog->subbase + (stringarg - strbeg);
640             for (i = 0; i <= prog->nparens; i++) {
641                 if (prog->endp[i]) {
642                     prog->startp[i] = s + (prog->startp[i] - startpos);
643                     prog->endp[i] = s + (prog->endp[i] - startpos);
644                 }
645             }
646         }
647     }
648     /* Preserve the current value of $^R */
649     if (oreplsv != GvSV(replgv)) {
650         sv_setsv(oreplsv, GvSV(replgv));/* So that when GvSV(replgv) is
651                                            restored, the value remains
652                                            the same. */
653     }
654     return 1;
655
656 phooey:
657     return 0;
658 }
659
660 /*
661  - regtry - try match at specific point
662  */
663 STATIC I32                      /* 0 failure, 1 success */
664 regtry(regexp *prog, char *startpos)
665 {
666     dTHR;
667     register I32 i;
668     register char **sp;
669     register char **ep;
670     CHECKPOINT lastcp;
671
672     if ((prog->reganch & ROPT_EVAL_SEEN) && !reg_eval_set) {
673         reg_eval_set = RS_init;
674         DEBUG_r(DEBUG_s(
675             PerlIO_printf(Perl_debug_log, "  setting stack tmpbase at %i\n", stack_sp - stack_base);
676             ));
677         SAVEINT(cxstack[cxstack_ix].blk_oldsp);
678         cxstack[cxstack_ix].blk_oldsp = stack_sp - stack_base;
679         /* Otherwise OP_NEXTSTATE will free whatever on stack now.  */
680         SAVETMPS;
681         /* Apparently this is not needed, judging by wantarray. */
682         /* SAVEINT(cxstack[cxstack_ix].blk_gimme);
683            cxstack[cxstack_ix].blk_gimme = G_SCALAR; */
684     }
685     reginput = startpos;
686     regstartp = prog->startp;
687     regendp = prog->endp;
688     reglastparen = &prog->lastparen;
689     prog->lastparen = 0;
690     regsize = 0;
691     if (reg_start_tmpl <= prog->nparens) {
692         reg_start_tmpl = prog->nparens*3/2 + 3;
693         if(reg_start_tmp)
694             Renew(reg_start_tmp, reg_start_tmpl, char*);
695         else
696             New(22,reg_start_tmp, reg_start_tmpl, char*);
697     }
698
699     sp = prog->startp;
700     ep = prog->endp;
701     regdata = prog->data;
702     if (prog->nparens) {
703         for (i = prog->nparens; i >= 0; i--) {
704             *sp++ = NULL;
705             *ep++ = NULL;
706         }
707     }
708     REGCP_SET;
709     if (regmatch(prog->program + 1)) {
710         prog->startp[0] = startpos;
711         prog->endp[0] = reginput;
712         return 1;
713     }
714     REGCP_UNWIND;
715     return 0;
716 }
717
718 /*
719  - regmatch - main matching routine
720  *
721  * Conceptually the strategy is simple:  check to see whether the current
722  * node matches, call self recursively to see whether the rest matches,
723  * and then act accordingly.  In practice we make some effort to avoid
724  * recursion, in particular by going through "ordinary" nodes (that don't
725  * need to know whether the rest of the match failed) by a loop instead of
726  * by recursion.
727  */
728 /* [lwall] I've hoisted the register declarations to the outer block in order to
729  * maybe save a little bit of pushing and popping on the stack.  It also takes
730  * advantage of machines that use a register save mask on subroutine entry.
731  */
732 STATIC I32                      /* 0 failure, 1 success */
733 regmatch(regnode *prog)
734 {
735     dTHR;
736     register regnode *scan;     /* Current node. */
737     regnode *next;              /* Next node. */
738     regnode *inner;             /* Next node in internal branch. */
739     register I32 nextchr; /* renamed nextchr - nextchar colides with function of same name */
740     register I32 n;             /* no or next */
741     register I32 ln;            /* len or last */
742     register char *s;           /* operand or save */
743     register char *locinput = reginput;
744     register I32 c1, c2, paren; /* case fold search, parenth */
745     int minmod = 0, sw = 0, logical = 0;
746 #ifdef DEBUGGING
747     regindent++;
748 #endif
749
750     nextchr = UCHARAT(locinput);
751     scan = prog;
752     while (scan != NULL) {
753 #define sayNO_L (logical ? (logical = 0, sw = 0, goto cont) : sayNO)
754 #ifdef DEBUGGING
755 #  define sayYES goto yes
756 #  define sayNO goto no
757 #  define saySAME(x) if (x) goto yes; else goto no
758 #  define REPORT_CODE_OFF 24
759 #else
760 #  define sayYES return 1
761 #  define sayNO return 0
762 #  define saySAME(x) return x
763 #endif
764         DEBUG_r( {
765             SV *prop = sv_newmortal();
766             int docolor = *colors[0];
767             int taill = (docolor ? 10 : 7); /* 3 chars for "> <" */
768             int l = (regeol - locinput > taill ? taill : regeol - locinput);
769             int pref_len = (locinput - bostr > (5 + taill) - l 
770                             ? (5 + taill) - l : locinput - bostr);
771
772             if (l + pref_len < (5 + taill) && l < regeol - locinput)
773                 l = ( regeol - locinput > (5 + taill) - pref_len 
774                       ? (5 + taill) - pref_len : regeol - locinput);
775             regprop(prop, scan);
776             PerlIO_printf(Perl_debug_log, 
777                           "%4i <%s%.*s%s%s%s%.*s%s>%*s|%*s%2d%s\n",
778                           locinput - bostr, 
779                           colors[2], pref_len, locinput - pref_len, colors[3],
780                           (docolor ? "" : "> <"),
781                           colors[0], l, locinput, colors[1],
782                           15 - l - pref_len + 1,
783                           "",
784                           regindent*2, "", scan - regprogram,
785                           SvPVX(prop));
786         } );
787
788         next = scan + NEXT_OFF(scan);
789         if (next == scan)
790             next = NULL;
791
792         switch (OP(scan)) {
793         case BOL:
794             if (locinput == bostr
795                 ? regprev == '\n'
796                 : (multiline && 
797                    (nextchr || locinput < regeol) && locinput[-1] == '\n') )
798             {
799                 /* regtill = regbol; */
800                 break;
801             }
802             sayNO;
803         case MBOL:
804             if (locinput == bostr
805                 ? regprev == '\n'
806                 : ((nextchr || locinput < regeol) && locinput[-1] == '\n') )
807             {
808                 break;
809             }
810             sayNO;
811         case SBOL:
812             if (locinput == regbol && regprev == '\n')
813                 break;
814             sayNO;
815         case GPOS:
816             if (locinput == regbol)
817                 break;
818             sayNO;
819         case EOL:
820             if (multiline)
821                 goto meol;
822             else
823                 goto seol;
824         case MEOL:
825           meol:
826             if ((nextchr || locinput < regeol) && nextchr != '\n')
827                 sayNO;
828             break;
829         case SEOL:
830           seol:
831             if ((nextchr || locinput < regeol) && nextchr != '\n')
832                 sayNO;
833             if (regeol - locinput > 1)
834                 sayNO;
835             break;
836         case EOS:
837             if (regeol != locinput)
838                 sayNO;
839             break;
840         case SANY:
841             if (!nextchr && locinput >= regeol)
842                 sayNO;
843             nextchr = UCHARAT(++locinput);
844             break;
845         case ANY:
846             if (!nextchr && locinput >= regeol || nextchr == '\n')
847                 sayNO;
848             nextchr = UCHARAT(++locinput);
849             break;
850         case EXACT:
851             s = (char *) OPERAND(scan);
852             ln = UCHARAT(s++);
853             /* Inline the first character, for speed. */
854             if (UCHARAT(s) != nextchr)
855                 sayNO;
856             if (regeol - locinput < ln)
857                 sayNO;
858             if (ln > 1 && memNE(s, locinput, ln))
859                 sayNO;
860             locinput += ln;
861             nextchr = UCHARAT(locinput);
862             break;
863         case EXACTFL:
864             reg_flags |= RF_tainted;
865             /* FALL THROUGH */
866         case EXACTF:
867             s = (char *) OPERAND(scan);
868             ln = UCHARAT(s++);
869             /* Inline the first character, for speed. */
870             if (UCHARAT(s) != nextchr &&
871                 UCHARAT(s) != ((OP(scan) == EXACTF)
872                                ? fold : fold_locale)[nextchr])
873                 sayNO;
874             if (regeol - locinput < ln)
875                 sayNO;
876             if (ln > 1 && (OP(scan) == EXACTF
877                            ? ibcmp(s, locinput, ln)
878                            : ibcmp_locale(s, locinput, ln)))
879                 sayNO;
880             locinput += ln;
881             nextchr = UCHARAT(locinput);
882             break;
883         case ANYOF:
884             s = (char *) OPERAND(scan);
885             if (nextchr < 0)
886                 nextchr = UCHARAT(locinput);
887             if (!REGINCLASS(s, nextchr))
888                 sayNO;
889             if (!nextchr && locinput >= regeol)
890                 sayNO;
891             nextchr = UCHARAT(++locinput);
892             break;
893         case ALNUML:
894             reg_flags |= RF_tainted;
895             /* FALL THROUGH */
896         case ALNUM:
897             if (!nextchr)
898                 sayNO;
899             if (!(OP(scan) == ALNUM
900                   ? isALNUM(nextchr) : isALNUM_LC(nextchr)))
901                 sayNO;
902             nextchr = UCHARAT(++locinput);
903             break;
904         case NALNUML:
905             reg_flags |= RF_tainted;
906             /* FALL THROUGH */
907         case NALNUM:
908             if (!nextchr && locinput >= regeol)
909                 sayNO;
910             if (OP(scan) == NALNUM
911                 ? isALNUM(nextchr) : isALNUM_LC(nextchr))
912                 sayNO;
913             nextchr = UCHARAT(++locinput);
914             break;
915         case BOUNDL:
916         case NBOUNDL:
917             reg_flags |= RF_tainted;
918             /* FALL THROUGH */
919         case BOUND:
920         case NBOUND:
921             /* was last char in word? */
922             ln = (locinput != regbol) ? UCHARAT(locinput - 1) : regprev;
923             if (OP(scan) == BOUND || OP(scan) == NBOUND) {
924                 ln = isALNUM(ln);
925                 n = isALNUM(nextchr);
926             }
927             else {
928                 ln = isALNUM_LC(ln);
929                 n = isALNUM_LC(nextchr);
930             }
931             if (((!ln) == (!n)) == (OP(scan) == BOUND || OP(scan) == BOUNDL))
932                 sayNO;
933             break;
934         case SPACEL:
935             reg_flags |= RF_tainted;
936             /* FALL THROUGH */
937         case SPACE:
938             if (!nextchr && locinput >= regeol)
939                 sayNO;
940             if (!(OP(scan) == SPACE
941                   ? isSPACE(nextchr) : isSPACE_LC(nextchr)))
942                 sayNO;
943             nextchr = UCHARAT(++locinput);
944             break;
945         case NSPACEL:
946             reg_flags |= RF_tainted;
947             /* FALL THROUGH */
948         case NSPACE:
949             if (!nextchr)
950                 sayNO;
951             if (OP(scan) == SPACE
952                 ? isSPACE(nextchr) : isSPACE_LC(nextchr))
953                 sayNO;
954             nextchr = UCHARAT(++locinput);
955             break;
956         case DIGIT:
957             if (!isDIGIT(nextchr))
958                 sayNO;
959             nextchr = UCHARAT(++locinput);
960             break;
961         case NDIGIT:
962             if (!nextchr && locinput >= regeol)
963                 sayNO;
964             if (isDIGIT(nextchr))
965                 sayNO;
966             nextchr = UCHARAT(++locinput);
967             break;
968         case REFFL:
969             reg_flags |= RF_tainted;
970             /* FALL THROUGH */
971         case REF:
972         case REFF:
973             n = ARG(scan);  /* which paren pair */
974             s = regstartp[n];
975             if (*reglastparen < n || !s)
976                 sayNO;                  /* Do not match unless seen CLOSEn. */
977             if (s == regendp[n])
978                 break;
979             /* Inline the first character, for speed. */
980             if (UCHARAT(s) != nextchr &&
981                 (OP(scan) == REF ||
982                  (UCHARAT(s) != ((OP(scan) == REFF
983                                   ? fold : fold_locale)[nextchr]))))
984                 sayNO;
985             ln = regendp[n] - s;
986             if (locinput + ln > regeol)
987                 sayNO;
988             if (ln > 1 && (OP(scan) == REF
989                            ? memNE(s, locinput, ln)
990                            : (OP(scan) == REFF
991                               ? ibcmp(s, locinput, ln)
992                               : ibcmp_locale(s, locinput, ln))))
993                 sayNO;
994             locinput += ln;
995             nextchr = UCHARAT(locinput);
996             break;
997
998         case NOTHING:
999         case TAIL:
1000             break;
1001         case BACK:
1002             break;
1003         case EVAL:
1004         {
1005             dSP;
1006             OP_4tree *oop = op;
1007             COP *ocurcop = curcop;
1008             SV **ocurpad = curpad;
1009             SV *ret;
1010             
1011             n = ARG(scan);
1012             op = (OP_4tree*)regdata->data[n];
1013             DEBUG_r( PerlIO_printf(Perl_debug_log, "  re_eval 0x%x\n", op) );
1014             curpad = AvARRAY((AV*)regdata->data[n + 1]);
1015
1016             CALLRUNOPS();                       /* Scalar context. */
1017             SPAGAIN;
1018             ret = POPs;
1019             PUTBACK;
1020             
1021             if (logical) {
1022                 logical = 0;
1023                 sw = SvTRUE(ret);
1024             } else
1025                 sv_setsv(save_scalar(replgv), ret);
1026             op = oop;
1027             curpad = ocurpad;
1028             curcop = ocurcop;
1029             break;
1030         }
1031         case OPEN:
1032             n = ARG(scan);  /* which paren pair */
1033             reg_start_tmp[n] = locinput;
1034             if (n > regsize)
1035                 regsize = n;
1036             break;
1037         case CLOSE:
1038             n = ARG(scan);  /* which paren pair */
1039             regstartp[n] = reg_start_tmp[n];
1040             regendp[n] = locinput;
1041             if (n > *reglastparen)
1042                 *reglastparen = n;
1043             break;
1044         case GROUPP:
1045             n = ARG(scan);  /* which paren pair */
1046             sw = (*reglastparen >= n && regendp[n] != NULL);
1047             break;
1048         case IFTHEN:
1049             if (sw)
1050                 next = NEXTOPER(NEXTOPER(scan));
1051             else {
1052                 next = scan + ARG(scan);
1053                 if (OP(next) == IFTHEN) /* Fake one. */
1054                     next = NEXTOPER(NEXTOPER(next));
1055             }
1056             break;
1057         case LOGICAL:
1058             logical = 1;
1059             break;
1060         case CURLYX: {
1061                 CURCUR cc;
1062                 CHECKPOINT cp = savestack_ix;
1063
1064                 if (OP(PREVOPER(next)) == NOTHING) /* LONGJMP */
1065                     next += ARG(next);
1066                 cc.oldcc = regcc;
1067                 regcc = &cc;
1068                 cc.parenfloor = *reglastparen;
1069                 cc.cur = -1;
1070                 cc.min = ARG1(scan);
1071                 cc.max  = ARG2(scan);
1072                 cc.scan = NEXTOPER(scan) + EXTRA_STEP_2ARGS;
1073                 cc.next = next;
1074                 cc.minmod = minmod;
1075                 cc.lastloc = 0;
1076                 reginput = locinput;
1077                 n = regmatch(PREVOPER(next));   /* start on the WHILEM */
1078                 regcpblow(cp);
1079                 regcc = cc.oldcc;
1080                 saySAME(n);
1081             }
1082             /* NOT REACHED */
1083         case WHILEM: {
1084                 /*
1085                  * This is really hard to understand, because after we match
1086                  * what we're trying to match, we must make sure the rest of
1087                  * the RE is going to match for sure, and to do that we have
1088                  * to go back UP the parse tree by recursing ever deeper.  And
1089                  * if it fails, we have to reset our parent's current state
1090                  * that we can try again after backing off.
1091                  */
1092
1093                 CHECKPOINT cp, lastcp;
1094                 CURCUR* cc = regcc;
1095                 char *lastloc = cc->lastloc; /* Detection of 0-len. */
1096                 
1097                 n = cc->cur + 1;        /* how many we know we matched */
1098                 reginput = locinput;
1099
1100                 DEBUG_r(
1101                     PerlIO_printf(Perl_debug_log, 
1102                                   "%*s  %ld out of %ld..%ld  cc=%lx\n", 
1103                                   REPORT_CODE_OFF+regindent*2, "",
1104                                   (long)n, (long)cc->min, 
1105                                   (long)cc->max, (long)cc)
1106                     );
1107
1108                 /* If degenerate scan matches "", assume scan done. */
1109
1110                 if (locinput == cc->lastloc && n >= cc->min) {
1111                     regcc = cc->oldcc;
1112                     ln = regcc->cur;
1113                     DEBUG_r(
1114                         PerlIO_printf(Perl_debug_log, "%*s  empty match detected, try continuation...\n", REPORT_CODE_OFF+regindent*2, "")
1115                         );
1116                     if (regmatch(cc->next))
1117                         sayYES;
1118                     DEBUG_r(
1119                         PerlIO_printf(Perl_debug_log, "%*s  failed...\n", REPORT_CODE_OFF+regindent*2, "")
1120                         );
1121                     regcc->cur = ln;
1122                     regcc = cc;
1123                     sayNO;
1124                 }
1125
1126                 /* First just match a string of min scans. */
1127
1128                 if (n < cc->min) {
1129                     cc->cur = n;
1130                     cc->lastloc = locinput;
1131                     if (regmatch(cc->scan))
1132                         sayYES;
1133                     cc->cur = n - 1;
1134                     cc->lastloc = lastloc;
1135                     DEBUG_r(
1136                         PerlIO_printf(Perl_debug_log, "%*s  failed...\n", REPORT_CODE_OFF+regindent*2, "")
1137                         );
1138                     sayNO;
1139                 }
1140
1141                 /* Prefer next over scan for minimal matching. */
1142
1143                 if (cc->minmod) {
1144                     regcc = cc->oldcc;
1145                     ln = regcc->cur;
1146                     cp = regcppush(cc->parenfloor);
1147                     REGCP_SET;
1148                     if (regmatch(cc->next)) {
1149                         regcpblow(cp);
1150                         sayYES; /* All done. */
1151                     }
1152                     REGCP_UNWIND;
1153                     regcppop();
1154                     regcc->cur = ln;
1155                     regcc = cc;
1156
1157                     if (n >= cc->max) { /* Maximum greed exceeded? */
1158                         if (dowarn && n >= REG_INFTY 
1159                             && !(reg_flags & RF_warned)) {
1160                             reg_flags |= RF_warned;
1161                             warn("count exceeded %d", REG_INFTY - 1);
1162                         }
1163                         sayNO;
1164                     }
1165
1166                     DEBUG_r(
1167                         PerlIO_printf(Perl_debug_log, "%*s  trying longer...\n", REPORT_CODE_OFF+regindent*2, "")
1168                         );
1169                     /* Try scanning more and see if it helps. */
1170                     reginput = locinput;
1171                     cc->cur = n;
1172                     cc->lastloc = locinput;
1173                     cp = regcppush(cc->parenfloor);
1174                     REGCP_SET;
1175                     if (regmatch(cc->scan)) {
1176                         regcpblow(cp);
1177                         sayYES;
1178                     }
1179                     DEBUG_r(
1180                         PerlIO_printf(Perl_debug_log, "%*s  failed...\n", REPORT_CODE_OFF+regindent*2, "")
1181                         );
1182                     REGCP_UNWIND;
1183                     regcppop();
1184                     cc->cur = n - 1;
1185                     cc->lastloc = lastloc;
1186                     sayNO;
1187                 }
1188
1189                 /* Prefer scan over next for maximal matching. */
1190
1191                 if (n < cc->max) {      /* More greed allowed? */
1192                     cp = regcppush(cc->parenfloor);
1193                     cc->cur = n;
1194                     cc->lastloc = locinput;
1195                     REGCP_SET;
1196                     if (regmatch(cc->scan)) {
1197                         regcpblow(cp);
1198                         sayYES;
1199                     }
1200                     REGCP_UNWIND;
1201                     regcppop();         /* Restore some previous $<digit>s? */
1202                     reginput = locinput;
1203                     DEBUG_r(
1204                         PerlIO_printf(Perl_debug_log, "%*s  failed, try continuation...\n", REPORT_CODE_OFF+regindent*2, "")
1205                         );
1206                 }
1207                 if (dowarn && n >= REG_INFTY && !(reg_flags & RF_warned)) {
1208                     reg_flags |= RF_warned;
1209                     warn("count exceeded %d", REG_INFTY - 1);
1210                 }
1211
1212                 /* Failed deeper matches of scan, so see if this one works. */
1213                 regcc = cc->oldcc;
1214                 ln = regcc->cur;
1215                 if (regmatch(cc->next))
1216                     sayYES;
1217                 DEBUG_r(
1218                     PerlIO_printf(Perl_debug_log, "%*s  failed...\n", REPORT_CODE_OFF+regindent*2, "")
1219                     );
1220                 regcc->cur = ln;
1221                 regcc = cc;
1222                 cc->cur = n - 1;
1223                 cc->lastloc = lastloc;
1224                 sayNO;
1225             }
1226             /* NOT REACHED */
1227         case BRANCHJ: 
1228             next = scan + ARG(scan);
1229             if (next == scan)
1230                 next = NULL;
1231             inner = NEXTOPER(NEXTOPER(scan));
1232             goto do_branch;
1233         case BRANCH: 
1234             inner = NEXTOPER(scan);
1235           do_branch:
1236             {
1237                 CHECKPOINT lastcp;
1238                 c1 = OP(scan);
1239                 if (OP(next) != c1)     /* No choice. */
1240                     next = inner;       /* Avoid recursion. */
1241                 else {
1242                     int lastparen = *reglastparen;
1243
1244                     REGCP_SET;
1245                     do {
1246                         reginput = locinput;
1247                         if (regmatch(inner))
1248                             sayYES;
1249                         REGCP_UNWIND;
1250                         for (n = *reglastparen; n > lastparen; n--)
1251                             regendp[n] = 0;
1252                         *reglastparen = n;
1253                         scan = next;
1254                         /*SUPPRESS 560*/
1255                         if (n = (c1 == BRANCH ? NEXT_OFF(next) : ARG(next)))
1256                             next += n;
1257                         else
1258                             next = NULL;
1259                         inner = NEXTOPER(scan);
1260                         if (c1 == BRANCHJ) {
1261                             inner = NEXTOPER(inner);
1262                         }
1263                     } while (scan != NULL && OP(scan) == c1);
1264                     sayNO;
1265                     /* NOTREACHED */
1266                 }
1267             }
1268             break;
1269         case MINMOD:
1270             minmod = 1;
1271             break;
1272         case CURLYM:
1273         {
1274             I32 l = 0;
1275             CHECKPOINT lastcp;
1276             
1277             /* We suppose that the next guy does not need
1278                backtracking: in particular, it is of constant length,
1279                and has no parenths to influence future backrefs. */
1280             ln = ARG1(scan);  /* min to match */
1281             n  = ARG2(scan);  /* max to match */
1282             paren = scan->flags;
1283             if (paren) {
1284                 if (paren > regsize)
1285                     regsize = paren;
1286                 if (paren > *reglastparen)
1287                     *reglastparen = paren;
1288             }
1289             scan = NEXTOPER(scan) + NODE_STEP_REGNODE;
1290             if (paren)
1291                 scan += NEXT_OFF(scan); /* Skip former OPEN. */
1292             reginput = locinput;
1293             if (minmod) {
1294                 minmod = 0;
1295                 if (ln && regrepeat_hard(scan, ln, &l) < ln)
1296                     sayNO;
1297                 if (ln && l == 0 && n >= ln
1298                     /* In fact, this is tricky.  If paren, then the
1299                        fact that we did/didnot match may influence
1300                        future execution. */
1301                     && !(paren && ln == 0))
1302                     ln = n;
1303                 locinput = reginput;
1304                 if (regkind[(U8)OP(next)] == EXACT) {
1305                     c1 = UCHARAT(OPERAND(next) + 1);
1306                     if (OP(next) == EXACTF)
1307                         c2 = fold[c1];
1308                     else if (OP(next) == EXACTFL)
1309                         c2 = fold_locale[c1];
1310                     else
1311                         c2 = c1;
1312                 } else
1313                     c1 = c2 = -1000;
1314                 REGCP_SET;
1315                 /* This may be improved if l == 0.  */
1316                 while (n >= ln || (n == REG_INFTY && ln > 0 && l)) { /* ln overflow ? */
1317                     /* If it could work, try it. */
1318                     if (c1 == -1000 ||
1319                         UCHARAT(reginput) == c1 ||
1320                         UCHARAT(reginput) == c2)
1321                     {
1322                         if (paren) {
1323                             if (n) {
1324                                 regstartp[paren] = reginput - l;
1325                                 regendp[paren] = reginput;
1326                             } else
1327                                 regendp[paren] = NULL;
1328                         }
1329                         if (regmatch(next))
1330                             sayYES;
1331                         REGCP_UNWIND;
1332                     }
1333                     /* Couldn't or didn't -- move forward. */
1334                     reginput = locinput;
1335                     if (regrepeat_hard(scan, 1, &l)) {
1336                         ln++;
1337                         locinput = reginput;
1338                     }
1339                     else
1340                         sayNO;
1341                 }
1342             } else {
1343                 n = regrepeat_hard(scan, n, &l);
1344                 if (n != 0 && l == 0
1345                     /* In fact, this is tricky.  If paren, then the
1346                        fact that we did/didnot match may influence
1347                        future execution. */
1348                     && !(paren && ln == 0))
1349                     ln = n;
1350                 locinput = reginput;
1351                 DEBUG_r(
1352                     PerlIO_printf(Perl_debug_log, "%*s  matched %ld times, len=%ld...\n", REPORT_CODE_OFF+regindent*2, "", n, l)
1353                     );
1354                 if (n >= ln) {
1355                     if (regkind[(U8)OP(next)] == EXACT) {
1356                         c1 = UCHARAT(OPERAND(next) + 1);
1357                         if (OP(next) == EXACTF)
1358                             c2 = fold[c1];
1359                         else if (OP(next) == EXACTFL)
1360                             c2 = fold_locale[c1];
1361                         else
1362                             c2 = c1;
1363                     } else
1364                         c1 = c2 = -1000;
1365                 }
1366                 REGCP_SET;
1367                 while (n >= ln) {
1368                     /* If it could work, try it. */
1369                     if (c1 == -1000 ||
1370                         UCHARAT(reginput) == c1 ||
1371                         UCHARAT(reginput) == c2)
1372                         {
1373                             DEBUG_r(
1374                                 PerlIO_printf(Perl_debug_log, "%*s  trying tail with n=%ld...\n", REPORT_CODE_OFF+regindent*2, "", n)
1375                                 );
1376                             if (paren) {
1377                                 if (n) {
1378                                     regstartp[paren] = reginput - l;
1379                                     regendp[paren] = reginput;
1380                                 } else
1381                                     regendp[paren] = NULL;
1382                             }
1383                             if (regmatch(next))
1384                                 sayYES;
1385                             REGCP_UNWIND;
1386                         }
1387                     /* Couldn't or didn't -- back up. */
1388                     n--;
1389                     locinput -= l;
1390                     reginput = locinput;
1391                 }
1392             }
1393             sayNO;
1394             break;
1395         }
1396         case CURLYN:
1397             paren = scan->flags;        /* Which paren to set */
1398             if (paren > regsize)
1399                 regsize = paren;
1400             if (paren > *reglastparen)
1401                 *reglastparen = paren;
1402             ln = ARG1(scan);  /* min to match */
1403             n  = ARG2(scan);  /* max to match */
1404             scan = regnext(NEXTOPER(scan) + NODE_STEP_REGNODE);
1405             goto repeat;
1406         case CURLY:
1407             paren = 0;
1408             ln = ARG1(scan);  /* min to match */
1409             n  = ARG2(scan);  /* max to match */
1410             scan = NEXTOPER(scan) + NODE_STEP_REGNODE;
1411             goto repeat;
1412         case STAR:
1413             ln = 0;
1414             n = REG_INFTY;
1415             scan = NEXTOPER(scan);
1416             paren = 0;
1417             goto repeat;
1418         case PLUS:
1419             ln = 1;
1420             n = REG_INFTY;
1421             scan = NEXTOPER(scan);
1422             paren = 0;
1423           repeat:
1424             /*
1425             * Lookahead to avoid useless match attempts
1426             * when we know what character comes next.
1427             */
1428             if (regkind[(U8)OP(next)] == EXACT) {
1429                 c1 = UCHARAT(OPERAND(next) + 1);
1430                 if (OP(next) == EXACTF)
1431                     c2 = fold[c1];
1432                 else if (OP(next) == EXACTFL)
1433                     c2 = fold_locale[c1];
1434                 else
1435                     c2 = c1;
1436             }
1437             else
1438                 c1 = c2 = -1000;
1439             reginput = locinput;
1440             if (minmod) {
1441                 CHECKPOINT lastcp;
1442                 minmod = 0;
1443                 if (ln && regrepeat(scan, ln) < ln)
1444                     sayNO;
1445                 REGCP_SET;
1446                 while (n >= ln || (n == REG_INFTY && ln > 0)) { /* ln overflow ? */
1447                     /* If it could work, try it. */
1448                     if (c1 == -1000 ||
1449                         UCHARAT(reginput) == c1 ||
1450                         UCHARAT(reginput) == c2)
1451                     {
1452                         if (paren) {
1453                             if (n) {
1454                                 regstartp[paren] = reginput - 1;
1455                                 regendp[paren] = reginput;
1456                             } else
1457                                 regendp[paren] = NULL;
1458                         }
1459                         if (regmatch(next))
1460                             sayYES;
1461                         REGCP_UNWIND;
1462                     }
1463                     /* Couldn't or didn't -- move forward. */
1464                     reginput = locinput + ln;
1465                     if (regrepeat(scan, 1)) {
1466                         ln++;
1467                         reginput = locinput + ln;
1468                     } else
1469                         sayNO;
1470                 }
1471             }
1472             else {
1473                 CHECKPOINT lastcp;
1474                 n = regrepeat(scan, n);
1475                 if (ln < n && regkind[(U8)OP(next)] == EOL &&
1476                     (!multiline  || OP(next) == SEOL))
1477                     ln = n;                     /* why back off? */
1478                 REGCP_SET;
1479                 if (paren) {
1480                     while (n >= ln) {
1481                         /* If it could work, try it. */
1482                         if (c1 == -1000 ||
1483                             UCHARAT(reginput) == c1 ||
1484                             UCHARAT(reginput) == c2)
1485                             {
1486                                 if (paren && n) {
1487                                     if (n) {
1488                                         regstartp[paren] = reginput - 1;
1489                                         regendp[paren] = reginput;
1490                                     } else
1491                                         regendp[paren] = NULL;
1492                                 }
1493                                 if (regmatch(next))
1494                                     sayYES;
1495                                 REGCP_UNWIND;
1496                             }
1497                         /* Couldn't or didn't -- back up. */
1498                         n--;
1499                         reginput = locinput + n;
1500                     }
1501                 } else {
1502                     while (n >= ln) {
1503                         /* If it could work, try it. */
1504                         if (c1 == -1000 ||
1505                             UCHARAT(reginput) == c1 ||
1506                             UCHARAT(reginput) == c2)
1507                             {
1508                                 if (regmatch(next))
1509                                     sayYES;
1510                                 REGCP_UNWIND;
1511                             }
1512                         /* Couldn't or didn't -- back up. */
1513                         n--;
1514                         reginput = locinput + n;
1515                     }
1516                 }
1517             }
1518             sayNO;
1519             break;
1520         case END:
1521             if (locinput < regtill)
1522                 sayNO;                  /* Cannot match: too short. */
1523             /* Fall through */
1524         case SUCCEED:
1525             reginput = locinput;        /* put where regtry can find it */
1526             sayYES;                     /* Success! */
1527         case SUSPEND:
1528             n = 1;
1529             goto do_ifmatch;        
1530         case UNLESSM:
1531             n = 0;
1532             if (locinput < bostr + scan->flags) 
1533                 goto say_yes;
1534             goto do_ifmatch;
1535         case IFMATCH:
1536             n = 1;
1537             if (locinput < bostr + scan->flags) 
1538                 goto say_no;
1539           do_ifmatch:
1540             reginput = locinput - scan->flags;
1541             inner = NEXTOPER(NEXTOPER(scan));
1542             if (regmatch(inner) != n) {
1543               say_no:
1544                 if (logical) {
1545                     logical = 0;
1546                     sw = 0;
1547                     goto do_longjump;
1548                 } else
1549                     sayNO;
1550             }
1551           say_yes:
1552             if (logical) {
1553                 logical = 0;
1554                 sw = 1;
1555             }
1556             if (OP(scan) == SUSPEND) {
1557                 locinput = reginput;
1558                 nextchr = UCHARAT(locinput);
1559             }
1560             /* FALL THROUGH. */
1561         case LONGJMP:
1562           do_longjump:
1563             next = scan + ARG(scan);
1564             if (next == scan)
1565                 next = NULL;
1566             break;
1567         default:
1568             PerlIO_printf(PerlIO_stderr(), "%lx %d\n",
1569                           (unsigned long)scan, OP(scan));
1570             FAIL("regexp memory corruption");
1571         }
1572         scan = next;
1573     }
1574
1575     /*
1576     * We get here only if there's trouble -- normally "case END" is
1577     * the terminating point.
1578     */
1579     FAIL("corrupted regexp pointers");
1580     /*NOTREACHED*/
1581     sayNO;
1582
1583 yes:
1584 #ifdef DEBUGGING
1585     regindent--;
1586 #endif
1587     return 1;
1588
1589 no:
1590 #ifdef DEBUGGING
1591     regindent--;
1592 #endif
1593     return 0;
1594 }
1595
1596 /*
1597  - regrepeat - repeatedly match something simple, report how many
1598  */
1599 /*
1600  * [This routine now assumes that it will only match on things of length 1.
1601  * That was true before, but now we assume scan - reginput is the count,
1602  * rather than incrementing count on every character.]
1603  */
1604 STATIC I32
1605 regrepeat(regnode *p, I32 max)
1606 {
1607     register char *scan;
1608     register char *opnd;
1609     register I32 c;
1610     register char *loceol = regeol;
1611
1612     scan = reginput;
1613     if (max != REG_INFTY && max < loceol - scan)
1614       loceol = scan + max;
1615     opnd = (char *) OPERAND(p);
1616     switch (OP(p)) {
1617     case ANY:
1618         while (scan < loceol && *scan != '\n')
1619             scan++;
1620         break;
1621     case SANY:
1622         scan = loceol;
1623         break;
1624     case EXACT:         /* length of string is 1 */
1625         c = UCHARAT(++opnd);
1626         while (scan < loceol && UCHARAT(scan) == c)
1627             scan++;
1628         break;
1629     case EXACTF:        /* length of string is 1 */
1630         c = UCHARAT(++opnd);
1631         while (scan < loceol &&
1632                (UCHARAT(scan) == c || UCHARAT(scan) == fold[c]))
1633             scan++;
1634         break;
1635     case EXACTFL:       /* length of string is 1 */
1636         reg_flags |= RF_tainted;
1637         c = UCHARAT(++opnd);
1638         while (scan < loceol &&
1639                (UCHARAT(scan) == c || UCHARAT(scan) == fold_locale[c]))
1640             scan++;
1641         break;
1642     case ANYOF:
1643         while (scan < loceol && REGINCLASS(opnd, *scan))
1644             scan++;
1645         break;
1646     case ALNUM:
1647         while (scan < loceol && isALNUM(*scan))
1648             scan++;
1649         break;
1650     case ALNUML:
1651         reg_flags |= RF_tainted;
1652         while (scan < loceol && isALNUM_LC(*scan))
1653             scan++;
1654         break;
1655     case NALNUM:
1656         while (scan < loceol && !isALNUM(*scan))
1657             scan++;
1658         break;
1659     case NALNUML:
1660         reg_flags |= RF_tainted;
1661         while (scan < loceol && !isALNUM_LC(*scan))
1662             scan++;
1663         break;
1664     case SPACE:
1665         while (scan < loceol && isSPACE(*scan))
1666             scan++;
1667         break;
1668     case SPACEL:
1669         reg_flags |= RF_tainted;
1670         while (scan < loceol && isSPACE_LC(*scan))
1671             scan++;
1672         break;
1673     case NSPACE:
1674         while (scan < loceol && !isSPACE(*scan))
1675             scan++;
1676         break;
1677     case NSPACEL:
1678         reg_flags |= RF_tainted;
1679         while (scan < loceol && !isSPACE_LC(*scan))
1680             scan++;
1681         break;
1682     case DIGIT:
1683         while (scan < loceol && isDIGIT(*scan))
1684             scan++;
1685         break;
1686     case NDIGIT:
1687         while (scan < loceol && !isDIGIT(*scan))
1688             scan++;
1689         break;
1690     default:            /* Called on something of 0 width. */
1691         break;          /* So match right here or not at all. */
1692     }
1693
1694     c = scan - reginput;
1695     reginput = scan;
1696
1697     DEBUG_r( 
1698         {
1699                 SV *prop = sv_newmortal();
1700
1701                 regprop(prop, p);
1702                 PerlIO_printf(Perl_debug_log, 
1703                               "%*s  %s can match %ld times out of %ld...\n", 
1704                               REPORT_CODE_OFF+1, "", SvPVX(prop),c,max);
1705         });
1706     
1707     return(c);
1708 }
1709
1710 /*
1711  - regrepeat_hard - repeatedly match something, report total lenth and length
1712  * 
1713  * The repeater is supposed to have constant length.
1714  */
1715
1716 STATIC I32
1717 regrepeat_hard(regnode *p, I32 max, I32 *lp)
1718 {
1719     register char *scan;
1720     register char *start;
1721     register char *loceol = regeol;
1722     I32 l = -1;
1723
1724     start = reginput;
1725     while (reginput < loceol && (scan = reginput, regmatch(p))) {
1726         if (l == -1) {
1727             *lp = l = reginput - start;
1728             if (max != REG_INFTY && l*max < loceol - scan)
1729                 loceol = scan + l*max;
1730             if (l == 0) {
1731                 return max;
1732             }
1733         }
1734     }
1735     if (reginput < loceol)
1736         reginput = scan;
1737     else
1738         scan = reginput;
1739     
1740     return (scan - start)/l;
1741 }
1742
1743 /*
1744  - regclass - determine if a character falls into a character class
1745  */
1746
1747 STATIC bool
1748 reginclass(register char *p, register I32 c)
1749 {
1750     char flags = *p;
1751     bool match = FALSE;
1752
1753     c &= 0xFF;
1754     if (ANYOF_TEST(p, c))
1755         match = TRUE;
1756     else if (flags & ANYOF_FOLD) {
1757         I32 cf;
1758         if (flags & ANYOF_LOCALE) {
1759             reg_flags |= RF_tainted;
1760             cf = fold_locale[c];
1761         }
1762         else
1763             cf = fold[c];
1764         if (ANYOF_TEST(p, cf))
1765             match = TRUE;
1766     }
1767
1768     if (!match && (flags & ANYOF_ISA)) {
1769         reg_flags |= RF_tainted;
1770
1771         if (((flags & ANYOF_ALNUML)  && isALNUM_LC(c))  ||
1772             ((flags & ANYOF_NALNUML) && !isALNUM_LC(c)) ||
1773             ((flags & ANYOF_SPACEL)  && isSPACE_LC(c))  ||
1774             ((flags & ANYOF_NSPACEL) && !isSPACE_LC(c)))
1775         {
1776             match = TRUE;
1777         }
1778     }
1779
1780     return (flags & ANYOF_INVERT) ? !match : match;
1781 }
1782
1783
1784