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