This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[inseparable changes from patch from perl5.003_11 to perl5.003_12]
[perl5.git] / regexec.c
1 /*    regexec.c
2  */
3
4 /*
5  * "One Ring to rule them all, One Ring to find them..."
6  */
7
8 /* NOTE: this is derived from Henry Spencer's regexp code, and should not
9  * confused with the original package (see point 3 below).  Thanks, Henry!
10  */
11
12 /* Additional note: this code is very heavily munged from Henry's version
13  * in places.  In some spots I've traded clarity for efficiency, so don't
14  * blame Henry for some of the lack of readability.
15  */
16
17 /* The names of the functions have been changed from regcomp and
18  * regexec to  pregcomp and pregexec in order to avoid conflicts
19  * with the POSIX routines of the same names.
20 */
21
22 /*SUPPRESS 112*/
23 /*
24  * pregcomp and pregexec -- regsub and regerror are not used in perl
25  *
26  *      Copyright (c) 1986 by University of Toronto.
27  *      Written by Henry Spencer.  Not derived from licensed software.
28  *
29  *      Permission is granted to anyone to use this software for any
30  *      purpose on any computer system, and to redistribute it freely,
31  *      subject to the following restrictions:
32  *
33  *      1. The author is not responsible for the consequences of use of
34  *              this software, no matter how awful, even if they arise
35  *              from defects in it.
36  *
37  *      2. The origin of this software must not be misrepresented, either
38  *              by explicit claim or by omission.
39  *
40  *      3. Altered versions must be plainly marked as such, and must not
41  *              be misrepresented as being the original software.
42  *
43  ****    Alterations to Henry's code are...
44  ****
45  ****    Copyright (c) 1991-1994, Larry Wall
46  ****
47  ****    You may distribute under the terms of either the GNU General Public
48  ****    License or the Artistic License, as specified in the README file.
49  *
50  * Beware that some of this code is subtly aware of the way operator
51  * precedence is structured in regular expressions.  Serious changes in
52  * regular-expression syntax might require a total rethink.
53  */
54 #include "EXTERN.h"
55 #include "perl.h"
56 #include "regcomp.h"
57
58 #ifndef STATIC
59 #define STATIC  static
60 #endif
61
62 #ifdef DEBUGGING
63 static I32 regnarrate = 0;
64 static char* regprogram = 0;
65 #endif
66
67 /* Current curly descriptor */
68 typedef struct curcur CURCUR;
69 struct curcur {
70     int         parenfloor;     /* how far back to strip paren data */
71     int         cur;            /* how many instances of scan we've matched */
72     int         min;            /* the minimal number of scans to match */
73     int         max;            /* the maximal number of scans to match */
74     int         minmod;         /* whether to work our way up or down */
75     char *      scan;           /* the thing to match */
76     char *      next;           /* what has to match after it */
77     char *      lastloc;        /* where we started matching this scan */
78     CURCUR *    oldcc;          /* current curly before we started this one */
79 };
80
81 static CURCUR* regcc;
82
83 typedef I32 CHECKPOINT;
84
85 static CHECKPOINT regcppush _((I32 parenfloor));
86 static char * regcppop _((void));
87
88 static CHECKPOINT
89 regcppush(parenfloor)
90 I32 parenfloor;
91 {
92     int retval = savestack_ix;
93     int i = (regsize - parenfloor) * 3;
94     int p;
95
96     SSCHECK(i + 5);
97     for (p = regsize; p > parenfloor; p--) {
98         SSPUSHPTR(regendp[p]);
99         SSPUSHPTR(regstartp[p]);
100         SSPUSHINT(p);
101     }
102     SSPUSHINT(regsize);
103     SSPUSHINT(*reglastparen);
104     SSPUSHPTR(reginput);
105     SSPUSHINT(i + 3);
106     SSPUSHINT(SAVEt_REGCONTEXT);
107     return retval;
108 }
109
110 static char *
111 regcppop()
112 {
113     I32 i = SSPOPINT;
114     U32 paren = 0;
115     char *input;
116     char *tmps;
117     assert(i == SAVEt_REGCONTEXT);
118     i = SSPOPINT;
119     input = (char *) SSPOPPTR;
120     *reglastparen = SSPOPINT;
121     regsize = SSPOPINT;
122     for (i -= 3; i > 0; i -= 3) {
123         paren = (U32)SSPOPINT;
124         regstartp[paren] = (char *) SSPOPPTR;
125         tmps = (char*)SSPOPPTR;
126         if (paren <= *reglastparen)
127             regendp[paren] = tmps;
128     }
129     for (paren = *reglastparen + 1; paren <= regnpar; paren++) {
130         if (paren > regsize)
131             regstartp[paren] = Nullch;
132         regendp[paren] = Nullch;
133     }
134     return input;
135 }
136
137 #define regcpblow(cp) leave_scope(cp)
138
139 /*
140  * pregexec and friends
141  */
142
143 /*
144  * Forwards.
145  */
146
147 static I32 regmatch _((char *prog));
148 static I32 regrepeat _((char *p, I32 max));
149 static I32 regtry _((regexp *prog, char *startpos));
150 static bool reginclass _((char *p, I32 c));
151
152 static bool regtainted;         /* tainted information used? */
153
154 /*
155  - pregexec - match a regexp against a string
156  */
157 I32
158 pregexec(prog, stringarg, strend, strbeg, minend, screamer, safebase)
159 register regexp *prog;
160 char *stringarg;
161 register char *strend;  /* pointer to null at end of string */
162 char *strbeg;   /* real beginning of string */
163 I32 minend;     /* end of match must be at least minend after stringarg */
164 SV *screamer;
165 I32 safebase;   /* no need to remember string in subbase */
166 {
167     register char *s;
168     register char *c;
169     register char *startpos = stringarg;
170     register I32 tmp;
171     I32 minlen = 0;             /* must match at least this many chars */
172     I32 dontbother = 0; /* how many characters not to try at end */
173     CURCUR cc;
174
175     cc.cur = 0;
176     cc.oldcc = 0;
177     regcc = &cc;
178
179 #ifdef DEBUGGING
180     regnarrate = debug & 512;
181     regprogram = prog->program;
182 #endif
183
184     /* Be paranoid... */
185     if (prog == NULL || startpos == NULL) {
186         croak("NULL regexp parameter");
187         return 0;
188     }
189
190     if (startpos == strbeg)     /* is ^ valid at stringarg? */
191         regprev = '\n';
192     else {
193         regprev = stringarg[-1];
194         if (!multiline && regprev == '\n')
195             regprev = '\0';             /* force ^ to NOT match */
196     }
197
198     regprecomp = prog->precomp;
199     /* Check validity of program. */
200     if (UCHARAT(prog->program) != MAGIC) {
201         FAIL("corrupted regexp program");
202     }
203
204     regnpar = prog->nparens;
205     regtainted = FALSE;
206
207     /* If there is a "must appear" string, look for it. */
208     s = startpos;
209     if (prog->regmust != Nullsv &&
210         (!(prog->reganch & ROPT_ANCH)
211          || (multiline && prog->regback >= 0)) )
212     {
213         if (stringarg == strbeg && screamer) {
214             if (screamfirst[BmRARE(prog->regmust)] >= 0)
215                     s = screaminstr(screamer,prog->regmust);
216             else
217                     s = Nullch;
218         }
219         else
220             s = fbm_instr((unsigned char*)s, (unsigned char*)strend,
221                 prog->regmust);
222         if (!s) {
223             ++BmUSEFUL(prog->regmust);  /* hooray */
224             goto phooey;        /* not present */
225         }
226         else if (prog->regback >= 0) {
227             s -= prog->regback;
228             if (s < startpos)
229                 s = startpos;
230             minlen = prog->regback + SvCUR(prog->regmust);
231         }
232         else if (!prog->naughty && --BmUSEFUL(prog->regmust) < 0) { /* boo */
233             SvREFCNT_dec(prog->regmust);
234             prog->regmust = Nullsv;     /* disable regmust */
235             s = startpos;
236         }
237         else {
238             s = startpos;
239             minlen = SvCUR(prog->regmust);
240         }
241     }
242
243     /* Mark beginning of line for ^ . */
244     regbol = startpos;
245
246     /* Mark end of line for $ (and such) */
247     regeol = strend;
248
249     /* see how far we have to get to not match where we matched before */
250     regtill = startpos+minend;
251
252     /* Simplest case:  anchored match need be tried only once. */
253     /*  [unless multiline is set] */
254     if (prog->reganch & ROPT_ANCH) {
255         if (regtry(prog, startpos))
256             goto got_it;
257         else if (multiline || (prog->reganch & ROPT_IMPLICIT)) {
258             if (minlen)
259                 dontbother = minlen - 1;
260             strend -= dontbother;
261             /* for multiline we only have to try after newlines */
262             if (s > startpos)
263                 s--;
264             while (s < strend) {
265                 if (*s++ == '\n') {
266                     if (s < strend && regtry(prog, s))
267                         goto got_it;
268                 }
269             }
270         }
271         goto phooey;
272     }
273
274     /* Messy cases:  unanchored match. */
275     if (prog->regstart) {
276         if (prog->reganch & ROPT_SKIP) {  /* we have /x+whatever/ */
277             /* it must be a one character string */
278             char ch = SvPVX(prog->regstart)[0];
279             while (s < strend) {
280                 if (*s == ch) {
281                     if (regtry(prog, s))
282                         goto got_it;
283                     s++;
284                     while (s < strend && *s == ch)
285                         s++;
286                 }
287                 s++;
288             }
289         }
290         else if (SvPOK(prog->regstart) == 3) {
291             /* We know what string it must start with. */
292             while ((s = fbm_instr((unsigned char*)s,
293               (unsigned char*)strend, prog->regstart)) != NULL)
294             {
295                 if (regtry(prog, s))
296                     goto got_it;
297                 s++;
298             }
299         }
300         else {
301             c = SvPVX(prog->regstart);
302             while ((s = ninstr(s, strend, c, c + SvCUR(prog->regstart))) != NULL)
303             {
304                 if (regtry(prog, s))
305                     goto got_it;
306                 s++;
307             }
308         }
309         goto phooey;
310     }
311     /*SUPPRESS 560*/
312     if (c = prog->regstclass) {
313         I32 doevery = (prog->reganch & ROPT_SKIP) == 0;
314
315         if (minlen)
316             dontbother = minlen - 1;
317         strend -= dontbother;   /* don't bother with what can't match */
318         tmp = 1;
319         /* We know what class it must start with. */
320         switch (OP(c)) {
321         case ANYOF:
322             c = OPERAND(c);
323             while (s < strend) {
324                 if (reginclass(c, *s)) {
325                     if (tmp && regtry(prog, s))
326                         goto got_it;
327                     else
328                         tmp = doevery;
329                 }
330                 else
331                     tmp = 1;
332                 s++;
333             }
334             break;
335         case BOUNDL:
336             regtainted = TRUE;
337             /* FALL THROUGH */
338         case BOUND:
339             if (minlen)
340                 dontbother++,strend--;
341             tmp = (s != startpos) ? UCHARAT(s - 1) : regprev;
342             tmp = ((OP(c) == BOUND ? isALNUM(tmp) : isALNUM_LC(tmp)) != 0);
343             while (s < strend) {
344                 if (tmp == !(OP(c) == BOUND ? isALNUM(*s) : isALNUM_LC(*s))) {
345                     tmp = !tmp;
346                     if (regtry(prog, s))
347                         goto got_it;
348                 }
349                 s++;
350             }
351             if ((minlen || tmp) && regtry(prog,s))
352                 goto got_it;
353             break;
354         case NBOUNDL:
355             regtainted = TRUE;
356             /* FALL THROUGH */
357         case NBOUND:
358             if (minlen)
359                 dontbother++,strend--;
360             tmp = (s != startpos) ? UCHARAT(s - 1) : regprev;
361             tmp = ((OP(c) == NBOUND ? isALNUM(tmp) : isALNUM_LC(tmp)) != 0);
362             while (s < strend) {
363                 if (tmp == !(OP(c) == NBOUND ? isALNUM(*s) : isALNUM_LC(*s)))
364                     tmp = !tmp;
365                 else if (regtry(prog, s))
366                     goto got_it;
367                 s++;
368             }
369             if ((minlen || !tmp) && regtry(prog,s))
370                 goto got_it;
371             break;
372         case ALNUM:
373             while (s < strend) {
374                 if (isALNUM(*s)) {
375                     if (tmp && regtry(prog, s))
376                         goto got_it;
377                     else
378                         tmp = doevery;
379                 }
380                 else
381                     tmp = 1;
382                 s++;
383             }
384             break;
385         case ALNUML:
386             regtainted = TRUE;
387             while (s < strend) {
388                 if (isALNUM_LC(*s)) {
389                     if (tmp && regtry(prog, s))
390                         goto got_it;
391                     else
392                         tmp = doevery;
393                 }
394                 else
395                     tmp = 1;
396                 s++;
397             }
398             break;
399         case NALNUM:
400             while (s < strend) {
401                 if (!isALNUM(*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 NALNUML:
413             regtainted = TRUE;
414             while (s < strend) {
415                 if (!isALNUM_LC(*s)) {
416                     if (tmp && regtry(prog, s))
417                         goto got_it;
418                     else
419                         tmp = doevery;
420                 }
421                 else
422                     tmp = 1;
423                 s++;
424             }
425             break;
426         case SPACE:
427             while (s < strend) {
428                 if (isSPACE(*s)) {
429                     if (tmp && regtry(prog, s))
430                         goto got_it;
431                     else
432                         tmp = doevery;
433                 }
434                 else
435                     tmp = 1;
436                 s++;
437             }
438             break;
439         case SPACEL:
440             regtainted = TRUE;
441             while (s < strend) {
442                 if (isSPACE_LC(*s)) {
443                     if (tmp && regtry(prog, s))
444                         goto got_it;
445                     else
446                         tmp = doevery;
447                 }
448                 else
449                     tmp = 1;
450                 s++;
451             }
452             break;
453         case NSPACE:
454             while (s < strend) {
455                 if (!isSPACE(*s)) {
456                     if (tmp && regtry(prog, s))
457                         goto got_it;
458                     else
459                         tmp = doevery;
460                 }
461                 else
462                     tmp = 1;
463                 s++;
464             }
465             break;
466         case NSPACEL:
467             regtainted = TRUE;
468             while (s < strend) {
469                 if (!isSPACE_LC(*s)) {
470                     if (tmp && regtry(prog, s))
471                         goto got_it;
472                     else
473                         tmp = doevery;
474                 }
475                 else
476                     tmp = 1;
477                 s++;
478             }
479             break;
480         case DIGIT:
481             while (s < strend) {
482                 if (isDIGIT(*s)) {
483                     if (tmp && regtry(prog, s))
484                         goto got_it;
485                     else
486                         tmp = doevery;
487                 }
488                 else
489                     tmp = 1;
490                 s++;
491             }
492             break;
493         case NDIGIT:
494             while (s < strend) {
495                 if (!isDIGIT(*s)) {
496                     if (tmp && regtry(prog, s))
497                         goto got_it;
498                     else
499                         tmp = doevery;
500                 }
501                 else
502                     tmp = 1;
503                 s++;
504             }
505             break;
506         }
507     }
508     else {
509         if (minlen)
510             dontbother = minlen - 1;
511         strend -= dontbother;
512         /* We don't know much -- general case. */
513         do {
514             if (regtry(prog, s))
515                 goto got_it;
516         } while (s++ < strend);
517     }
518
519     /* Failure. */
520     goto phooey;
521
522 got_it:
523     strend += dontbother;       /* uncheat */
524     prog->subbeg = strbeg;
525     prog->subend = strend;
526     prog->exec_tainted = regtainted;
527
528     /* make sure $`, $&, $', and $digit will work later */
529     if (!safebase && (strbeg != prog->subbase)) {
530         I32 i = strend - startpos + (stringarg - strbeg);
531         s = savepvn(strbeg, i);
532         Safefree(prog->subbase);
533         prog->subbase = s;
534         prog->subbeg = prog->subbase;
535         prog->subend = prog->subbase + i;
536         s = prog->subbase + (stringarg - strbeg);
537         for (i = 0; i <= prog->nparens; i++) {
538             if (prog->endp[i]) {
539                 prog->startp[i] = s + (prog->startp[i] - startpos);
540                 prog->endp[i] = s + (prog->endp[i] - startpos);
541             }
542         }
543     }
544     return 1;
545
546 phooey:
547     return 0;
548 }
549
550 /*
551  - regtry - try match at specific point
552  */
553 static I32                      /* 0 failure, 1 success */
554 regtry(prog, startpos)
555 regexp *prog;
556 char *startpos;
557 {
558     register I32 i;
559     register char **sp;
560     register char **ep;
561
562     reginput = startpos;
563     regstartp = prog->startp;
564     regendp = prog->endp;
565     reglastparen = &prog->lastparen;
566     prog->lastparen = 0;
567     regsize = 0;
568
569     sp = prog->startp;
570     ep = prog->endp;
571     if (prog->nparens) {
572         for (i = prog->nparens; i >= 0; i--) {
573             *sp++ = NULL;
574             *ep++ = NULL;
575         }
576     }
577     if (regmatch(prog->program + 1) && reginput >= regtill) {
578         prog->startp[0] = startpos;
579         prog->endp[0] = reginput;
580         return 1;
581     }
582     else
583         return 0;
584 }
585
586 /*
587  - regmatch - main matching routine
588  *
589  * Conceptually the strategy is simple:  check to see whether the current
590  * node matches, call self recursively to see whether the rest matches,
591  * and then act accordingly.  In practice we make some effort to avoid
592  * recursion, in particular by going through "ordinary" nodes (that don't
593  * need to know whether the rest of the match failed) by a loop instead of
594  * by recursion.
595  */
596 /* [lwall] I've hoisted the register declarations to the outer block in order to
597  * maybe save a little bit of pushing and popping on the stack.  It also takes
598  * advantage of machines that use a register save mask on subroutine entry.
599  */
600 static I32                      /* 0 failure, 1 success */
601 regmatch(prog)
602 char *prog;
603 {
604     register char *scan;        /* Current node. */
605     char *next;                 /* Next node. */
606     register I32 nextchar;
607     register I32 n;             /* no or next */
608     register I32 ln;            /* len or last */
609     register char *s;           /* operand or save */
610     register char *locinput = reginput;
611     register I32 c1, c2;        /* case fold search */
612     int minmod = 0;
613 #ifdef DEBUGGING
614     static int regindent = 0;
615     regindent++;
616 #endif
617
618     nextchar = UCHARAT(locinput);
619     scan = prog;
620     while (scan != NULL) {
621 #ifdef DEBUGGING
622 #define sayYES goto yes
623 #define sayNO goto no
624 #define saySAME(x) if (x) goto yes; else goto no
625         if (regnarrate) {
626             PerlIO_printf(Perl_debug_log, "%*s%2d%-8.8s\t<%.10s>\n", regindent*2, "",
627                 scan - regprogram, regprop(scan), locinput);
628         }
629 #else
630 #define sayYES return 1
631 #define sayNO return 0
632 #define saySAME(x) return x
633 #endif
634
635 #ifdef REGALIGN
636         next = scan + NEXT(scan);
637         if (next == scan)
638             next = NULL;
639 #else
640         next = regnext(scan);
641 #endif
642
643         switch (OP(scan)) {
644         case BOL:
645             if (locinput == regbol
646                 ? regprev == '\n'
647                 : ((nextchar || locinput < regeol) && locinput[-1] == '\n') )
648             {
649                 /* regtill = regbol; */
650                 break;
651             }
652             sayNO;
653         case MBOL:
654             if (locinput == regbol
655                 ? regprev == '\n'
656                 : ((nextchar || locinput < regeol) && locinput[-1] == '\n') )
657             {
658                 break;
659             }
660             sayNO;
661         case SBOL:
662             if (locinput == regbol && regprev == '\n')
663                 break;
664             sayNO;
665         case GBOL:
666             if (locinput == regbol)
667                 break;
668             sayNO;
669         case EOL:
670             if (multiline)
671                 goto meol;
672             else
673                 goto seol;
674         case MEOL:
675           meol:
676             if ((nextchar || locinput < regeol) && nextchar != '\n')
677                 sayNO;
678             break;
679         case SEOL:
680           seol:
681             if ((nextchar || locinput < regeol) && nextchar != '\n')
682                 sayNO;
683             if (regeol - locinput > 1)
684                 sayNO;
685             break;
686         case SANY:
687             if (!nextchar && locinput >= regeol)
688                 sayNO;
689             nextchar = UCHARAT(++locinput);
690             break;
691         case ANY:
692             if (!nextchar && locinput >= regeol || nextchar == '\n')
693                 sayNO;
694             nextchar = UCHARAT(++locinput);
695             break;
696         case EXACT:
697             s = OPERAND(scan);
698             ln = *s++;
699             /* Inline the first character, for speed. */
700             if (UCHARAT(s) != nextchar)
701                 sayNO;
702             if (regeol - locinput < ln)
703                 sayNO;
704             if (ln > 1 && memNE(s, locinput, ln))
705                 sayNO;
706             locinput += ln;
707             nextchar = UCHARAT(locinput);
708             break;
709         case EXACTFL:
710             regtainted = TRUE;
711             /* FALL THROUGH */
712         case EXACTF:
713             s = OPERAND(scan);
714             ln = *s++;
715             /* Inline the first character, for speed. */
716             if (UCHARAT(s) != nextchar &&
717                 UCHARAT(s) != ((OP(scan) == EXACTF)
718                                ? fold : fold_locale)[nextchar])
719                 sayNO;
720             if (regeol - locinput < ln)
721                 sayNO;
722             if (ln > 1 && (OP(scan) == EXACTF
723                            ? ibcmp(s, locinput, ln)
724                            : ibcmp_locale(s, locinput, ln)))
725                 sayNO;
726             locinput += ln;
727             nextchar = UCHARAT(locinput);
728             break;
729         case ANYOF:
730             s = OPERAND(scan);
731             if (nextchar < 0)
732                 nextchar = UCHARAT(locinput);
733             if (!reginclass(s, nextchar))
734                 sayNO;
735             if (!nextchar && locinput >= regeol)
736                 sayNO;
737             nextchar = UCHARAT(++locinput);
738             break;
739         case ALNUML:
740             regtainted = TRUE;
741             /* FALL THROUGH */
742         case ALNUM:
743             if (!nextchar)
744                 sayNO;
745             if (!(OP(scan) == ALNUM
746                   ? isALNUM(nextchar) : isALNUM_LC(nextchar)))
747                 sayNO;
748             nextchar = UCHARAT(++locinput);
749             break;
750         case NALNUML:
751             regtainted = TRUE;
752             /* FALL THROUGH */
753         case NALNUM:
754             if (!nextchar && locinput >= regeol)
755                 sayNO;
756             if (OP(scan) == NALNUM
757                 ? isALNUM(nextchar) : isALNUM_LC(nextchar))
758                 sayNO;
759             nextchar = UCHARAT(++locinput);
760             break;
761         case BOUNDL:
762         case NBOUNDL:
763             regtainted = TRUE;
764             /* FALL THROUGH */
765         case BOUND:
766         case NBOUND:
767             /* was last char in word? */
768             ln = (locinput != regbol) ? UCHARAT(locinput - 1) : regprev;
769             if (OP(scan) == BOUND || OP(scan) == NBOUND) {
770                 ln = isALNUM(ln);
771                 n = isALNUM(nextchar);
772             }
773             else {
774                 ln = isALNUM_LC(ln);
775                 n = isALNUM_LC(nextchar);
776             }
777             if (((!ln) == (!n)) == (OP(scan) == BOUND || OP(scan) == BOUNDL))
778                 sayNO;
779             break;
780         case SPACEL:
781             regtainted = TRUE;
782             /* FALL THROUGH */
783         case SPACE:
784             if (!nextchar && locinput >= regeol)
785                 sayNO;
786             if (!(OP(scan) == SPACE
787                   ? isSPACE(nextchar) : isSPACE_LC(nextchar)))
788                 sayNO;
789             nextchar = UCHARAT(++locinput);
790             break;
791         case NSPACEL:
792             regtainted = TRUE;
793             /* FALL THROUGH */
794         case NSPACE:
795             if (!nextchar)
796                 sayNO;
797             if (OP(scan) == SPACE
798                 ? isSPACE(nextchar) : isSPACE_LC(nextchar))
799                 sayNO;
800             nextchar = UCHARAT(++locinput);
801             break;
802         case DIGIT:
803             if (!isDIGIT(nextchar))
804                 sayNO;
805             nextchar = UCHARAT(++locinput);
806             break;
807         case NDIGIT:
808             if (!nextchar && locinput >= regeol)
809                 sayNO;
810             if (isDIGIT(nextchar))
811                 sayNO;
812             nextchar = UCHARAT(++locinput);
813             break;
814         case REF:
815             n = ARG1(scan);  /* which paren pair */
816             s = regstartp[n];
817             if (!s)
818                 sayNO;
819             if (!regendp[n])
820                 sayNO;
821             if (s == regendp[n])
822                 break;
823             /* Inline the first character, for speed. */
824             if (UCHARAT(s) != nextchar)
825                 sayNO;
826             ln = regendp[n] - s;
827             if (locinput + ln > regeol)
828                 sayNO;
829             if (ln > 1 && memNE(s, locinput, ln))
830                 sayNO;
831             locinput += ln;
832             nextchar = UCHARAT(locinput);
833             break;
834
835         case NOTHING:
836             break;
837         case BACK:
838             break;
839         case OPEN:
840             n = ARG1(scan);  /* which paren pair */
841             regstartp[n] = locinput;
842             if (n > regsize)
843                 regsize = n;
844             break;
845         case CLOSE:
846             n = ARG1(scan);  /* which paren pair */
847             regendp[n] = locinput;
848             if (n > *reglastparen)
849                 *reglastparen = n;
850             break;
851         case CURLYX: {
852                 CURCUR cc;
853                 CHECKPOINT cp = savestack_ix;
854                 cc.oldcc = regcc;
855                 regcc = &cc;
856                 cc.parenfloor = *reglastparen;
857                 cc.cur = -1;
858                 cc.min = ARG1(scan);
859                 cc.max  = ARG2(scan);
860                 cc.scan = NEXTOPER(scan) + 4;
861                 cc.next = next;
862                 cc.minmod = minmod;
863                 cc.lastloc = 0;
864                 reginput = locinput;
865                 n = regmatch(PREVOPER(next));   /* start on the WHILEM */
866                 regcpblow(cp);
867                 regcc = cc.oldcc;
868                 saySAME(n);
869             }
870             /* NOT REACHED */
871         case WHILEM: {
872                 /*
873                  * This is really hard to understand, because after we match
874                  * what we're trying to match, we must make sure the rest of
875                  * the RE is going to match for sure, and to do that we have
876                  * to go back UP the parse tree by recursing ever deeper.  And
877                  * if it fails, we have to reset our parent's current state
878                  * that we can try again after backing off.
879                  */
880
881                 CHECKPOINT cp;
882                 CURCUR* cc = regcc;
883                 n = cc->cur + 1;        /* how many we know we matched */
884                 reginput = locinput;
885
886 #ifdef DEBUGGING
887                 if (regnarrate)
888                     PerlIO_printf(Perl_debug_log, "%*s  %d  %lx\n", regindent*2, "",
889                         n, (long)cc);
890 #endif
891
892                 /* If degenerate scan matches "", assume scan done. */
893
894                 if (locinput == cc->lastloc) {
895                     regcc = cc->oldcc;
896                     ln = regcc->cur;
897                     if (regmatch(cc->next))
898                         sayYES;
899                     regcc->cur = ln;
900                     regcc = cc;
901                     sayNO;
902                 }
903
904                 /* First just match a string of min scans. */
905
906                 if (n < cc->min) {
907                     cc->cur = n;
908                     cc->lastloc = locinput;
909                     if (regmatch(cc->scan))
910                         sayYES;
911                     cc->cur = n - 1;
912                     sayNO;
913                 }
914
915                 /* Prefer next over scan for minimal matching. */
916
917                 if (cc->minmod) {
918                     regcc = cc->oldcc;
919                     ln = regcc->cur;
920                     cp = regcppush(cc->parenfloor);
921                     if (regmatch(cc->next)) {
922                         regcpblow(cp);
923                         sayYES; /* All done. */
924                     }
925                     regcppop();
926                     regcc->cur = ln;
927                     regcc = cc;
928
929                     if (n >= cc->max)   /* Maximum greed exceeded? */
930                         sayNO;
931
932                     /* Try scanning more and see if it helps. */
933                     reginput = locinput;
934                     cc->cur = n;
935                     cc->lastloc = locinput;
936                     cp = regcppush(cc->parenfloor);
937                     if (regmatch(cc->scan)) {
938                         regcpblow(cp);
939                         sayYES;
940                     }
941                     regcppop();
942                     cc->cur = n - 1;
943                     sayNO;
944                 }
945
946                 /* Prefer scan over next for maximal matching. */
947
948                 if (n < cc->max) {      /* More greed allowed? */
949                     cp = regcppush(cc->parenfloor);
950                     cc->cur = n;
951                     cc->lastloc = locinput;
952                     if (regmatch(cc->scan)) {
953                         regcpblow(cp);
954                         sayYES;
955                     }
956                     regcppop();         /* Restore some previous $<digit>s? */
957                     reginput = locinput;
958                 }
959
960                 /* Failed deeper matches of scan, so see if this one works. */
961                 regcc = cc->oldcc;
962                 ln = regcc->cur;
963                 if (regmatch(cc->next))
964                     sayYES;
965                 regcc->cur = ln;
966                 regcc = cc;
967                 cc->cur = n - 1;
968                 sayNO;
969             }
970             /* NOT REACHED */
971         case BRANCH: {
972                 if (OP(next) != BRANCH)   /* No choice. */
973                     next = NEXTOPER(scan);/* Avoid recursion. */
974                 else {
975                     int lastparen = *reglastparen;
976                     do {
977                         reginput = locinput;
978                         if (regmatch(NEXTOPER(scan)))
979                             sayYES;
980                         for (n = *reglastparen; n > lastparen; n--)
981                             regendp[n] = 0;
982                         *reglastparen = n;
983                             
984 #ifdef REGALIGN
985                         /*SUPPRESS 560*/
986                         if (n = NEXT(scan))
987                             scan += n;
988                         else
989                             scan = NULL;
990 #else
991                         scan = regnext(scan);
992 #endif
993                     } while (scan != NULL && OP(scan) == BRANCH);
994                     sayNO;
995                     /* NOTREACHED */
996                 }
997             }
998             break;
999         case MINMOD:
1000             minmod = 1;
1001             break;
1002         case CURLY:
1003             ln = ARG1(scan);  /* min to match */
1004             n  = ARG2(scan);  /* max to match */
1005             scan = NEXTOPER(scan) + 4;
1006             goto repeat;
1007         case STAR:
1008             ln = 0;
1009             n = 32767;
1010             scan = NEXTOPER(scan);
1011             goto repeat;
1012         case PLUS:
1013             /*
1014             * Lookahead to avoid useless match attempts
1015             * when we know what character comes next.
1016             */
1017             ln = 1;
1018             n = 32767;
1019             scan = NEXTOPER(scan);
1020           repeat:
1021             if (regkind[(U8)OP(next)] == EXACT) {
1022                 c1 = UCHARAT(OPERAND(next) + 1);
1023                 if (OP(next) == EXACTF)
1024                     c2 = fold[c1];
1025                 else if (OP(next) == EXACTFL)
1026                     c2 = fold_locale[c1];
1027                 else
1028                     c2 = c1;
1029             }
1030             else
1031                 c1 = c2 = -1000;
1032             reginput = locinput;
1033             if (minmod) {
1034                 minmod = 0;
1035                 if (ln && regrepeat(scan, ln) < ln)
1036                     sayNO;
1037                 while (n >= ln || (n == 32767 && ln > 0)) { /* ln overflow ? */
1038                     /* If it could work, try it. */
1039                     if (c1 == -1000 ||
1040                         UCHARAT(reginput) == c1 ||
1041                         UCHARAT(reginput) == c2)
1042                     {
1043                         if (regmatch(next))
1044                             sayYES;
1045                     }
1046                     /* Couldn't or didn't -- back up. */
1047                     reginput = locinput + ln;
1048                     if (regrepeat(scan, 1)) {
1049                         ln++;
1050                         reginput = locinput + ln;
1051                     }
1052                     else
1053                         sayNO;
1054                 }
1055             }
1056             else {
1057                 n = regrepeat(scan, n);
1058                 if (ln < n && regkind[(U8)OP(next)] == EOL &&
1059                     (!multiline || OP(next) == SEOL))
1060                     ln = n;                     /* why back off? */
1061                 while (n >= ln) {
1062                     /* If it could work, try it. */
1063                     if (c1 == -1000 ||
1064                         UCHARAT(reginput) == c1 ||
1065                         UCHARAT(reginput) == c2)
1066                     {
1067                         if (regmatch(next))
1068                             sayYES;
1069                     }
1070                     /* Couldn't or didn't -- back up. */
1071                     n--;
1072                     reginput = locinput + n;
1073                 }
1074             }
1075             sayNO;
1076         case SUCCEED:
1077         case END:
1078             reginput = locinput;        /* put where regtry can find it */
1079             sayYES;                     /* Success! */
1080         case IFMATCH:
1081             reginput = locinput;
1082             scan = NEXTOPER(scan);
1083             if (!regmatch(scan))
1084                 sayNO;
1085             break;
1086         case UNLESSM:
1087             reginput = locinput;
1088             scan = NEXTOPER(scan);
1089             if (regmatch(scan))
1090                 sayNO;
1091             break;
1092         default:
1093             PerlIO_printf(PerlIO_stderr(), "%x %d\n",(unsigned)scan,scan[1]);
1094             FAIL("regexp memory corruption");
1095         }
1096         scan = next;
1097     }
1098
1099     /*
1100     * We get here only if there's trouble -- normally "case END" is
1101     * the terminating point.
1102     */
1103     FAIL("corrupted regexp pointers");
1104     /*NOTREACHED*/
1105     sayNO;
1106
1107 yes:
1108 #ifdef DEBUGGING
1109     regindent--;
1110 #endif
1111     return 1;
1112
1113 no:
1114 #ifdef DEBUGGING
1115     regindent--;
1116 #endif
1117     return 0;
1118 }
1119
1120 /*
1121  - regrepeat - repeatedly match something simple, report how many
1122  */
1123 /*
1124  * [This routine now assumes that it will only match on things of length 1.
1125  * That was true before, but now we assume scan - reginput is the count,
1126  * rather than incrementing count on every character.]
1127  */
1128 static I32
1129 regrepeat(p, max)
1130 char *p;
1131 I32 max;
1132 {
1133     register char *scan;
1134     register char *opnd;
1135     register I32 c;
1136     register char *loceol = regeol;
1137
1138     scan = reginput;
1139     if (max != 32767 && max < loceol - scan)
1140       loceol = scan + max;
1141     opnd = OPERAND(p);
1142     switch (OP(p)) {
1143     case ANY:
1144         while (scan < loceol && *scan != '\n')
1145             scan++;
1146         break;
1147     case SANY:
1148         scan = loceol;
1149         break;
1150     case EXACT:         /* length of string is 1 */
1151         c = UCHARAT(++opnd);
1152         while (scan < loceol && UCHARAT(scan) == c)
1153             scan++;
1154         break;
1155     case EXACTF:        /* length of string is 1 */
1156         c = UCHARAT(++opnd);
1157         while (scan < loceol &&
1158                (UCHARAT(scan) == c || UCHARAT(scan) == fold[c]))
1159             scan++;
1160         break;
1161     case EXACTFL:       /* length of string is 1 */
1162         regtainted = TRUE;
1163         c = UCHARAT(++opnd);
1164         while (scan < loceol &&
1165                (UCHARAT(scan) == c || UCHARAT(scan) == fold_locale[c]))
1166             scan++;
1167         break;
1168     case ANYOF:
1169         while (scan < loceol && reginclass(opnd, *scan))
1170             scan++;
1171         break;
1172     case ALNUM:
1173         while (scan < loceol && isALNUM(*scan))
1174             scan++;
1175         break;
1176     case ALNUML:
1177         regtainted = TRUE;
1178         while (scan < loceol && isALNUM_LC(*scan))
1179             scan++;
1180         break;
1181     case NALNUM:
1182         while (scan < loceol && !isALNUM(*scan))
1183             scan++;
1184         break;
1185     case NALNUML:
1186         regtainted = TRUE;
1187         while (scan < loceol && !isALNUM_LC(*scan))
1188             scan++;
1189         break;
1190     case SPACE:
1191         while (scan < loceol && isSPACE(*scan))
1192             scan++;
1193         break;
1194     case SPACEL:
1195         regtainted = TRUE;
1196         while (scan < loceol && isSPACE_LC(*scan))
1197             scan++;
1198         break;
1199     case NSPACE:
1200         while (scan < loceol && !isSPACE(*scan))
1201             scan++;
1202         break;
1203     case NSPACEL:
1204         regtainted = TRUE;
1205         while (scan < loceol && !isSPACE_LC(*scan))
1206             scan++;
1207         break;
1208     case DIGIT:
1209         while (scan < loceol && isDIGIT(*scan))
1210             scan++;
1211         break;
1212     case NDIGIT:
1213         while (scan < loceol && !isDIGIT(*scan))
1214             scan++;
1215         break;
1216     default:            /* Called on something of 0 width. */
1217         break;          /* So match right here or not at all. */
1218     }
1219
1220     c = scan - reginput;
1221     reginput = scan;
1222
1223     return(c);
1224 }
1225
1226 /*
1227  - regclass - determine if a character falls into a character class
1228  */
1229
1230 static bool
1231 reginclass(p, c)
1232 register char *p;
1233 register I32 c;
1234 {
1235     char flags = *p;
1236     bool match = FALSE;
1237
1238     c &= 0xFF;
1239     if (p[1 + (c >> 3)] & (1 << (c & 7)))
1240         match = TRUE;
1241     else if (flags & ANYOF_FOLD) {
1242         I32 cf;
1243         if (flags & ANYOF_LOCALE) {
1244             regtainted = TRUE;
1245             cf = fold_locale[c];
1246         }
1247         else
1248             cf = fold[c];
1249         if (p[1 + (cf >> 3)] & (1 << (cf & 7)))
1250             match = TRUE;
1251     }
1252
1253     if (!match && (flags & ANYOF_ISA)) {
1254         regtainted = TRUE;
1255
1256         if (((flags & ANYOF_ALNUML)  && isALNUM_LC(c))  ||
1257             ((flags & ANYOF_NALNUML) && !isALNUM_LC(c)) ||
1258             ((flags & ANYOF_SPACEL)  && isSPACE_LC(c))  ||
1259             ((flags & ANYOF_NSPACEL) && !isSPACE_LC(c)))
1260         {
1261             match = TRUE;
1262         }
1263     }
1264
1265     return match ^ ((flags & ANYOF_INVERT) != 0);
1266 }
1267
1268 /*
1269  - regnext - dig the "next" pointer out of a node
1270  *
1271  * [Note, when REGALIGN is defined there are two places in regmatch()
1272  * that bypass this code for speed.]
1273  */
1274 char *
1275 regnext(p)
1276 register char *p;
1277 {
1278     register I32 offset;
1279
1280     if (p == &regdummy)
1281         return(NULL);
1282
1283     offset = NEXT(p);
1284     if (offset == 0)
1285         return(NULL);
1286
1287 #ifdef REGALIGN
1288     return(p+offset);
1289 #else
1290     if (OP(p) == BACK)
1291         return(p-offset);
1292     else
1293         return(p+offset);
1294 #endif
1295 }