4c34b59c616b972d48ed19879bfcb9d517d19b23
[p5sagit/p5-mst-13.2.git] / regcomp.c
1 /*    regcomp.c
2  */
3
4 /*
5  * "A fair jaw-cracker dwarf-language must be."  --Samwise Gamgee
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  *
44  ****    Alterations to Henry's code are...
45  ****
46  ****    Copyright (c) 1991-1997, Larry Wall
47  ****
48  ****    You may distribute under the terms of either the GNU General Public
49  ****    License or the Artistic License, as specified in the README file.
50
51  *
52  * Beware that some of this code is subtly aware of the way operator
53  * precedence is structured in regular expressions.  Serious changes in
54  * regular-expression syntax might require a total rethink.
55  */
56 #include "EXTERN.h"
57 #include "perl.h"
58 #include "INTERN.h"
59 #include "regcomp.h"
60
61 #ifdef MSDOS
62 # if defined(BUGGY_MSC6)
63  /* MSC 6.00A breaks on op/regexp.t test 85 unless we turn this off */
64  # pragma optimize("a",off)
65  /* But MSC 6.00A is happy with 'w', for aliases only across function calls*/
66  # pragma optimize("w",on )
67 # endif /* BUGGY_MSC6 */
68 #endif /* MSDOS */
69
70 #ifndef STATIC
71 #define STATIC  static
72 #endif
73
74 #define ISMULT1(c)      ((c) == '*' || (c) == '+' || (c) == '?')
75 #define ISMULT2(s)      ((*s) == '*' || (*s) == '+' || (*s) == '?' || \
76         ((*s) == '{' && regcurly(s)))
77 #ifdef atarist
78 #define PERL_META       "^$.[()|?+*\\"
79 #else
80 #define META    "^$.[()|?+*\\"
81 #endif
82
83 #ifdef SPSTART
84 #undef SPSTART          /* dratted cpp namespace... */
85 #endif
86 /*
87  * Flags to be passed up and down.
88  */
89 #define WORST           0       /* Worst case. */
90 #define HASWIDTH        0x1     /* Known never to match null string. */
91 #define SIMPLE          0x2     /* Simple enough to be STAR/PLUS operand. */
92 #define SPSTART         0x4     /* Starts with * or +. */
93 #define TRYAGAIN        0x8     /* Weeded out a declaration. */
94
95 /*
96  * Forward declarations for pregcomp()'s friends.
97  */
98
99 static char *reg _((I32, I32 *));
100 static char *reganode _((char, unsigned short));
101 static char *regatom _((I32 *));
102 static char *regbranch _((I32 *));
103 static void regc _((char));
104 static char *regclass _((void));
105 STATIC I32 regcurly _((char *));
106 static char *regnode _((char));
107 static char *regpiece _((I32 *));
108 static void reginsert _((char, char *));
109 static void regoptail _((char *, char *));
110 static void regset _((char *, I32));
111 static void regtail _((char *, char *));
112 static char* regwhite _((char *, char *));
113 static char* nextchar _((void));
114
115 /*
116  - pregcomp - compile a regular expression into internal code
117  *
118  * We can't allocate space until we know how big the compiled form will be,
119  * but we can't compile it (and thus know how big it is) until we've got a
120  * place to put the code.  So we cheat:  we compile it twice, once with code
121  * generation turned off and size counting turned on, and once "for real".
122  * This also means that we don't allocate space until we are sure that the
123  * thing really will compile successfully, and we never have to move the
124  * code and thus invalidate pointers into it.  (Note that it has to be in
125  * one piece because free() must be able to free it all.) [NB: not true in perl]
126  *
127  * Beware that the optimization-preparation code in here knows about some
128  * of the structure of the compiled regexp.  [I'll say.]
129  */
130 regexp *
131 pregcomp(exp,xend,pm)
132 char* exp;
133 char* xend;
134 PMOP* pm;
135 {
136     register regexp *r;
137     register char *scan;
138     register SV *longish;
139     SV *longest;
140     register I32 len;
141     register char *first;
142     I32 flags;
143     I32 backish;
144     I32 backest;
145     I32 curback;
146     I32 minlen = 0;
147     I32 sawplus = 0;
148     I32 sawopen = 0;
149 #define MAX_REPEAT_DEPTH 12
150     struct {
151         char *opcode;
152         I32 count;
153     } repeat_stack[MAX_REPEAT_DEPTH];
154     I32 repeat_depth = 0;
155     I32 repeat_count = 1;       /* We start unmultiplied. */
156
157     if (exp == NULL)
158         croak("NULL regexp argument");
159
160     regprecomp = savepvn(exp, xend - exp);
161     regflags = pm->op_pmflags;
162     regsawback = 0;
163
164     /* First pass: determine size, legality. */
165     regparse = exp;
166     regxend = xend;
167     regnaughty = 0;
168     regnpar = 1;
169     regsize = 0L;
170     regcode = &regdummy;
171     regc((char)MAGIC);
172     if (reg(0, &flags) == NULL) {
173         Safefree(regprecomp);
174         regprecomp = Nullch;
175         return(NULL);
176     }
177
178     /* Small enough for pointer-storage convention? */
179     if (regsize >= 32767L)              /* Probably could be 65535L. */
180         FAIL("regexp too big");
181
182     /* Allocate space and initialize. */
183     Newc(1001, r, sizeof(regexp) + (unsigned)regsize, char, regexp);
184     if (r == NULL)
185         FAIL("regexp out of space");
186     r->prelen = xend - exp;
187     r->precomp = regprecomp;
188     r->subbeg = r->subbase = NULL;
189
190     /* Second pass: emit code. */
191     regparse = exp;
192     regxend = xend;
193     regnaughty = 0;
194     regnpar = 1;
195     regcode = r->program;
196     regc((char)MAGIC);
197     if (reg(0, &flags) == NULL)
198         return(NULL);
199
200     /* Dig out information for optimizations. */
201     pm->op_pmflags = regflags;
202     r->regstart = Nullsv;       /* Worst-case defaults. */
203     r->reganch = 0;
204     r->regmust = Nullsv;
205     r->regback = -1;
206     r->regstclass = Nullch;
207     r->naughty = regnaughty >= 10;      /* Probably an expensive pattern. */
208     scan = r->program+1;                        /* First BRANCH. */
209     if (OP(regnext(scan)) == END) {/* Only one top-level choice. */
210         scan = NEXTOPER(scan);
211
212         first = scan;
213         while ((OP(first) == OPEN && (sawopen = 1)) ||
214             (OP(first) == BRANCH && OP(regnext(first)) != BRANCH) ||
215             (OP(first) == PLUS) ||
216             (OP(first) == MINMOD) ||
217             (regkind[(U8)OP(first)] == CURLY && ARG1(first) > 0) ) {
218                 if (OP(first) == PLUS)
219                     sawplus = 1;
220                 else
221                     first += regarglen[(U8)OP(first)];
222                 first = NEXTOPER(first);
223         }
224
225         /* Starting-point info. */
226       again:
227         if (OP(first) == EXACT) {
228             r->regstart = newSVpv(OPERAND(first)+1,*OPERAND(first));
229             if (SvCUR(r->regstart) > !sawstudy)
230                 fbm_compile(r->regstart);
231             (void)SvUPGRADE(r->regstart, SVt_PVBM);
232         }
233         else if (strchr(simple+2,OP(first)))
234             r->regstclass = first;
235         else if (regkind[(U8)OP(first)] == BOUND ||
236                  regkind[(U8)OP(first)] == NBOUND)
237             r->regstclass = first;
238         else if (regkind[(U8)OP(first)] == BOL) {
239             r->reganch |= ROPT_ANCH_BOL;
240             first = NEXTOPER(first);
241             goto again;
242         }
243         else if (OP(first) == GPOS) {
244             r->reganch |= ROPT_ANCH_GPOS;
245             first = NEXTOPER(first);
246             goto again;
247         }
248         else if ((OP(first) == STAR &&
249             regkind[(U8)OP(NEXTOPER(first))] == ANY) &&
250             !(r->reganch & ROPT_ANCH) )
251         {
252             /* turn .* into ^.* with an implied $*=1 */
253             r->reganch |= ROPT_ANCH_BOL | ROPT_IMPLICIT;
254             first = NEXTOPER(first);
255             goto again;
256         }
257         if (sawplus && (!sawopen || !regsawback))
258             r->reganch |= ROPT_SKIP;    /* x+ must match 1st of run */
259
260         DEBUG_r(PerlIO_printf(Perl_debug_log, "first %d next %d offset %d\n",
261            OP(first), OP(NEXTOPER(first)), first - scan));
262         /*
263         * If there's something expensive in the r.e., find the
264         * longest literal string that must appear and make it the
265         * regmust.  Resolve ties in favor of later strings, since
266         * the regstart check works with the beginning of the r.e.
267         * and avoiding duplication strengthens checking.  Not a
268         * strong reason, but sufficient in the absence of others.
269         * [Now we resolve ties in favor of the earlier string if
270         * it happens that curback has been invalidated, since the
271         * earlier string may buy us something the later one won't.]
272         */
273         longish = newSVpv("",0);
274         longest = newSVpv("",0);
275         len = 0;
276         minlen = 0;
277         curback = 0;
278         backish = 0;
279         backest = 0;
280         while (OP(scan) != END) {
281             if (OP(scan) == BRANCH) {
282                 if (OP(regnext(scan)) == BRANCH) {
283                     curback = -30000;
284                     while (OP(scan) == BRANCH)
285                         scan = regnext(scan);
286                 }
287                 else    /* single branch is ok */
288                     scan = NEXTOPER(scan);
289                 continue;
290             }
291             if (OP(scan) == UNLESSM) {
292                 curback = -30000;
293                 scan = regnext(scan);
294                 continue;
295             }
296             if (OP(scan) == EXACT) {
297                 char *t;
298
299                 first = scan;
300                 while ((t = regnext(scan)) && OP(t) == CLOSE)
301                     scan = t;
302                 minlen += *OPERAND(first) * repeat_count;
303                 if (curback - backish == len) {
304                     sv_catpvn(longish, OPERAND(first)+1,
305                         *OPERAND(first));
306                     len += *OPERAND(first);
307                     curback += *OPERAND(first);
308                     first = regnext(scan);
309                 }
310                 else if (*OPERAND(first) >= len + (curback >= 0)) {
311                     len = *OPERAND(first);
312                     sv_setpvn(longish, OPERAND(first)+1,len);
313                     backish = curback;
314                     curback += len;
315                     first = regnext(scan);
316                 }
317                 else
318                     curback += *OPERAND(first);
319             }
320             else if (strchr(varies,OP(scan))) {
321                 int tcount;
322                 char *next;
323
324                 if (repeat_depth < MAX_REPEAT_DEPTH
325                     && ((OP(scan) == PLUS
326                          && (tcount = 1)
327                          && (next = NEXTOPER(scan)))
328                         || (regkind[(U8)OP(scan)] == CURLY
329                             && (tcount = ARG1(scan))
330                             && (next = NEXTOPER(scan)+4))))
331                 {
332                     /* We treat (abc)+ as (abc)(abc)*. */
333
334                     /* Mark the place to return back. */
335                     repeat_stack[repeat_depth].opcode = regnext(scan);
336                     repeat_stack[repeat_depth].count = repeat_count;
337                     repeat_depth++;
338                     repeat_count *= tcount;
339
340                     /* Go deeper: */
341                     scan = next;
342                     continue;
343                 }
344                 else {
345                     curback = -30000;
346                     len = 0;
347                     if (SvCUR(longish) > SvCUR(longest)) {
348                         sv_setsv(longest,longish);
349                         backest = backish;
350                     }
351                     sv_setpvn(longish,"",0);
352                 }
353             }
354             else if (strchr(simple,OP(scan))) {
355                 curback++;
356                 minlen += repeat_count;
357                 len = 0;
358                 if (SvCUR(longish) > SvCUR(longest)) {
359                     sv_setsv(longest,longish);
360                     backest = backish;
361                 }
362                 sv_setpvn(longish,"",0);
363             }
364             scan = regnext(scan);
365             if (!scan) {                /* Go up PLUS or CURLY. */
366                 if (!repeat_depth--)
367                     croak("panic: re scan");
368                 scan = repeat_stack[repeat_depth].opcode;
369                 repeat_count = repeat_stack[repeat_depth].count;
370                 /* Need to submit the longest string found: */
371                 curback = -30000;
372                 len = 0;
373                 if (SvCUR(longish) > SvCUR(longest)) {
374                     sv_setsv(longest,longish);
375                     backest = backish;
376                 }
377                 sv_setpvn(longish,"",0);
378             }
379         }
380
381         /* Prefer earlier on tie, unless we can tail match latter */
382
383         if (SvCUR(longish) + (first && regkind[(U8)OP(first)] == EOL)
384                 > SvCUR(longest))
385         {
386             sv_setsv(longest,longish);
387             backest = backish;
388         }
389         else
390             sv_setpvn(longish,"",0);
391         if (SvCUR(longest)
392             && (!r->regstart
393                 || !fbm_instr((unsigned char*) SvPVX(r->regstart),
394                               (unsigned char *) (SvPVX(r->regstart)
395                                                  + SvCUR(r->regstart)),
396                               longest)))
397         {
398             r->regmust = longest;
399             if (backest < 0)
400                 backest = -1;
401             r->regback = backest;
402             if (SvCUR(longest) > !(sawstudy || 
403                                    (first && regkind[(U8)OP(first)] == EOL)))
404                 fbm_compile(r->regmust);
405             (void)SvUPGRADE(r->regmust, SVt_PVBM);
406             BmUSEFUL(r->regmust) = 100;
407             if (first && regkind[(U8)OP(first)] == EOL && SvCUR(longish))
408                 SvTAIL_on(r->regmust);
409         }
410         else {
411             SvREFCNT_dec(longest);
412             longest = Nullsv;
413         }
414         SvREFCNT_dec(longish);
415     }
416
417     r->nparens = regnpar - 1;
418     r->minlen = minlen;
419     Newz(1002, r->startp, regnpar, char*);
420     Newz(1002, r->endp, regnpar, char*);
421     DEBUG_r(regdump(r));
422     return(r);
423 }
424
425 /*
426  - reg - regular expression, i.e. main body or parenthesized thing
427  *
428  * Caller must absorb opening parenthesis.
429  *
430  * Combining parenthesis handling with the base level of regular expression
431  * is a trifle forced, but the need to tie the tails of the branches to what
432  * follows makes it hard to avoid.
433  */
434 static char *
435 reg(paren, flagp)
436 I32 paren;                      /* Parenthesized? */
437 I32 *flagp;
438 {
439     register char *ret;
440     register char *br;
441     register char *ender = 0;
442     register I32 parno = 0;
443     I32 flags;
444
445     *flagp = HASWIDTH;  /* Tentatively. */
446
447     /* Make an OPEN node, if parenthesized. */
448     if (paren) {
449         if (*regparse == '?') {
450             regparse++;
451             paren = *regparse++;
452             ret = NULL;
453             switch (paren) {
454             case ':':
455             case '=':
456             case '!':
457                 break;
458             case '$':
459             case '@':
460                 croak("Sequence (?%c...) not implemented", (int)paren);
461                 break;
462             case '#':
463                 while (*regparse && *regparse != ')')
464                     regparse++;
465                 if (*regparse != ')')
466                     croak("Sequence (?#... not terminated");
467                 nextchar();
468                 *flagp = TRYAGAIN;
469                 return NULL;
470             default:
471                 --regparse;
472                 while (*regparse && strchr("iogmsx", *regparse))
473                     pmflag(&regflags, *regparse++);
474                 if (*regparse != ')')
475                     croak("Sequence (?%c...) not recognized", *regparse);
476                 nextchar();
477                 *flagp = TRYAGAIN;
478                 return NULL;
479             }
480         }
481         else {
482             parno = regnpar;
483             regnpar++;
484             ret = reganode(OPEN, parno);
485         }
486     } else
487         ret = NULL;
488
489     /* Pick up the branches, linking them together. */
490     br = regbranch(&flags);
491     if (br == NULL)
492         return(NULL);
493     if (ret != NULL)
494         regtail(ret, br);       /* OPEN -> first. */
495     else
496         ret = br;
497     if (!(flags&HASWIDTH))
498         *flagp &= ~HASWIDTH;
499     *flagp |= flags&SPSTART;
500     while (*regparse == '|') {
501         nextchar();
502         br = regbranch(&flags);
503         if (br == NULL)
504             return(NULL);
505         regtail(ret, br);       /* BRANCH -> BRANCH. */
506         if (!(flags&HASWIDTH))
507             *flagp &= ~HASWIDTH;
508         *flagp |= flags&SPSTART;
509     }
510
511     /* Make a closing node, and hook it on the end. */
512     switch (paren) {
513     case ':':
514         ender = regnode(NOTHING);
515         break;
516     case 1:
517         ender = reganode(CLOSE, parno);
518         break;
519     case '=':
520     case '!':
521         ender = regnode(SUCCEED);
522         *flagp &= ~HASWIDTH;
523         break;
524     case 0:
525         ender = regnode(END);
526         break;
527     }
528     regtail(ret, ender);
529
530     /* Hook the tails of the branches to the closing node. */
531     for (br = ret; br != NULL; br = regnext(br))
532         regoptail(br, ender);
533
534     if (paren == '=') {
535         reginsert(IFMATCH,ret);
536         regtail(ret, regnode(NOTHING));
537     }
538     else if (paren == '!') {
539         reginsert(UNLESSM,ret);
540         regtail(ret, regnode(NOTHING));
541     }
542
543     /* Check for proper termination. */
544     if (paren && (regparse >= regxend || *nextchar() != ')')) {
545         FAIL("unmatched () in regexp");
546     } else if (!paren && regparse < regxend) {
547         if (*regparse == ')') {
548             FAIL("unmatched () in regexp");
549         } else
550             FAIL("junk on end of regexp");      /* "Can't happen". */
551         /* NOTREACHED */
552     }
553
554     return(ret);
555 }
556
557 /*
558  - regbranch - one alternative of an | operator
559  *
560  * Implements the concatenation operator.
561  */
562 static char *
563 regbranch(flagp)
564 I32 *flagp;
565 {
566     register char *ret;
567     register char *chain;
568     register char *latest;
569     I32 flags = 0;
570
571     *flagp = WORST;             /* Tentatively. */
572
573     ret = regnode(BRANCH);
574     chain = NULL;
575     regparse--;
576     nextchar();
577     while (regparse < regxend && *regparse != '|' && *regparse != ')') {
578         flags &= ~TRYAGAIN;
579         latest = regpiece(&flags);
580         if (latest == NULL) {
581             if (flags & TRYAGAIN)
582                 continue;
583             return(NULL);
584         }
585         *flagp |= flags&HASWIDTH;
586         if (chain == NULL)      /* First piece. */
587             *flagp |= flags&SPSTART;
588         else {
589             regnaughty++;
590             regtail(chain, latest);
591         }
592         chain = latest;
593     }
594     if (chain == NULL)  /* Loop ran zero times. */
595         (void) regnode(NOTHING);
596
597     return(ret);
598 }
599
600 /*
601  - regpiece - something followed by possible [*+?]
602  *
603  * Note that the branching code sequences used for ? and the general cases
604  * of * and + are somewhat optimized:  they use the same NOTHING node as
605  * both the endmarker for their branch list and the body of the last branch.
606  * It might seem that this node could be dispensed with entirely, but the
607  * endmarker role is not redundant.
608  */
609 static char *
610 regpiece(flagp)
611 I32 *flagp;
612 {
613     register char *ret;
614     register char op;
615     register char *next;
616     I32 flags;
617     char *origparse = regparse;
618     char *maxpos;
619     I32 min;
620     I32 max = 32767;
621
622     ret = regatom(&flags);
623     if (ret == NULL) {
624         if (flags & TRYAGAIN)
625             *flagp |= TRYAGAIN;
626         return(NULL);
627     }
628
629     op = *regparse;
630     if (op == '(' && regparse[1] == '?' && regparse[2] == '#') {
631         while (op && op != ')')
632             op = *++regparse;
633         if (op) {
634             nextchar();
635             op = *regparse;
636         }
637     }
638
639     if (op == '{' && regcurly(regparse)) {
640         next = regparse + 1;
641         maxpos = Nullch;
642         while (isDIGIT(*next) || *next == ',') {
643             if (*next == ',') {
644                 if (maxpos)
645                     break;
646                 else
647                     maxpos = next;
648             }
649             next++;
650         }
651         if (*next == '}') {             /* got one */
652             if (!maxpos)
653                 maxpos = next;
654             regparse++;
655             min = atoi(regparse);
656             if (*maxpos == ',')
657                 maxpos++;
658             else
659                 maxpos = regparse;
660             max = atoi(maxpos);
661             if (!max && *maxpos != '0')
662                 max = 32767;            /* meaning "infinity" */
663             regparse = next;
664             nextchar();
665
666         do_curly:
667             if ((flags&SIMPLE)) {
668                 regnaughty += 2 + regnaughty / 2;
669                 reginsert(CURLY, ret);
670             }
671             else {
672                 regnaughty += 4 + regnaughty;   /* compound interest */
673                 regtail(ret, regnode(WHILEM));
674                 reginsert(CURLYX,ret);
675                 regtail(ret, regnode(NOTHING));
676             }
677
678             if (min > 0)
679                 *flagp = (WORST|HASWIDTH);
680             if (max && max < min)
681                 croak("Can't do {n,m} with n > m");
682             if (regcode != &regdummy) {
683 #ifdef REGALIGN
684                 *(unsigned short *)(ret+3) = min;
685                 *(unsigned short *)(ret+5) = max;
686 #else
687                 ret[3] = min >> 8; ret[4] = min & 0377;
688                 ret[5] = max  >> 8; ret[6] = max  & 0377;
689 #endif
690             }
691
692             goto nest_check;
693         }
694     }
695
696     if (!ISMULT1(op)) {
697         *flagp = flags;
698         return(ret);
699     }
700     nextchar();
701
702     *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
703
704     if (op == '*' && (flags&SIMPLE)) {
705         reginsert(STAR, ret);
706         regnaughty += 4;
707     }
708     else if (op == '*') {
709         min = 0;
710         goto do_curly;
711     } else if (op == '+' && (flags&SIMPLE)) {
712         reginsert(PLUS, ret);
713         regnaughty += 3;
714     }
715     else if (op == '+') {
716         min = 1;
717         goto do_curly;
718     } else if (op == '?') {
719         min = 0; max = 1;
720         goto do_curly;
721     }
722   nest_check:
723     if (dowarn && regcode != &regdummy && !(flags&HASWIDTH) && max > 10000) {
724         warn("%.*s matches null string many times",
725             regparse - origparse, origparse);
726     }
727
728     if (*regparse == '?') {
729         nextchar();
730         reginsert(MINMOD, ret);
731 #ifdef REGALIGN
732         regtail(ret, ret + 4);
733 #else
734         regtail(ret, ret + 3);
735 #endif
736     }
737     if (ISMULT2(regparse))
738         FAIL("nested *?+ in regexp");
739
740     return(ret);
741 }
742
743 /*
744  - regatom - the lowest level
745  *
746  * Optimization:  gobbles an entire sequence of ordinary characters so that
747  * it can turn them into a single node, which is smaller to store and
748  * faster to run.  Backslashed characters are exceptions, each becoming a
749  * separate node; the code is simpler that way and it's not worth fixing.
750  *
751  * [Yes, it is worth fixing, some scripts can run twice the speed.]
752  */
753 static char *
754 regatom(flagp)
755 I32 *flagp;
756 {
757     register char *ret = 0;
758     I32 flags;
759
760     *flagp = WORST;             /* Tentatively. */
761
762 tryagain:
763     switch (*regparse) {
764     case '^':
765         nextchar();
766         if (regflags & PMf_MULTILINE)
767             ret = regnode(MBOL);
768         else if (regflags & PMf_SINGLELINE)
769             ret = regnode(SBOL);
770         else
771             ret = regnode(BOL);
772         break;
773     case '$':
774         nextchar();
775         if (regflags & PMf_MULTILINE)
776             ret = regnode(MEOL);
777         else if (regflags & PMf_SINGLELINE)
778             ret = regnode(SEOL);
779         else
780             ret = regnode(EOL);
781         break;
782     case '.':
783         nextchar();
784         if (regflags & PMf_SINGLELINE)
785             ret = regnode(SANY);
786         else
787             ret = regnode(ANY);
788         regnaughty++;
789         *flagp |= HASWIDTH|SIMPLE;
790         break;
791     case '[':
792         regparse++;
793         ret = regclass();
794         *flagp |= HASWIDTH|SIMPLE;
795         break;
796     case '(':
797         nextchar();
798         ret = reg(1, &flags);
799         if (ret == NULL) {
800                 if (flags & TRYAGAIN)
801                     goto tryagain;
802                 return(NULL);
803         }
804         *flagp |= flags&(HASWIDTH|SPSTART);
805         break;
806     case '|':
807     case ')':
808         if (flags & TRYAGAIN) {
809             *flagp |= TRYAGAIN;
810             return NULL;
811         }
812         croak("internal urp in regexp at /%s/", regparse);
813                                 /* Supposed to be caught earlier. */
814         break;
815     case '{':
816         if (!regcurly(regparse)) {
817             regparse++;
818             goto defchar;
819         }
820         /* FALL THROUGH */
821     case '?':
822     case '+':
823     case '*':
824         FAIL("?+*{} follows nothing in regexp");
825         break;
826     case '\\':
827         switch (*++regparse) {
828         case 'A':
829             ret = regnode(SBOL);
830             *flagp |= SIMPLE;
831             nextchar();
832             break;
833         case 'G':
834             ret = regnode(GPOS);
835             *flagp |= SIMPLE;
836             nextchar();
837             break;
838         case 'Z':
839             ret = regnode(SEOL);
840             *flagp |= SIMPLE;
841             nextchar();
842             break;
843         case 'w':
844             ret = regnode((regflags & PMf_LOCALE) ? ALNUML : ALNUM);
845             *flagp |= HASWIDTH|SIMPLE;
846             nextchar();
847             break;
848         case 'W':
849             ret = regnode((regflags & PMf_LOCALE) ? NALNUML : NALNUM);
850             *flagp |= HASWIDTH|SIMPLE;
851             nextchar();
852             break;
853         case 'b':
854             ret = regnode((regflags & PMf_LOCALE) ? BOUNDL : BOUND);
855             *flagp |= SIMPLE;
856             nextchar();
857             break;
858         case 'B':
859             ret = regnode((regflags & PMf_LOCALE) ? NBOUNDL : NBOUND);
860             *flagp |= SIMPLE;
861             nextchar();
862             break;
863         case 's':
864             ret = regnode((regflags & PMf_LOCALE) ? SPACEL : SPACE);
865             *flagp |= HASWIDTH|SIMPLE;
866             nextchar();
867             break;
868         case 'S':
869             ret = regnode((regflags & PMf_LOCALE) ? NSPACEL : NSPACE);
870             *flagp |= HASWIDTH|SIMPLE;
871             nextchar();
872             break;
873         case 'd':
874             ret = regnode(DIGIT);
875             *flagp |= HASWIDTH|SIMPLE;
876             nextchar();
877             break;
878         case 'D':
879             ret = regnode(NDIGIT);
880             *flagp |= HASWIDTH|SIMPLE;
881             nextchar();
882             break;
883         case 'n':
884         case 'r':
885         case 't':
886         case 'f':
887         case 'e':
888         case 'a':
889         case 'x':
890         case 'c':
891         case '0':
892             goto defchar;
893         case '1': case '2': case '3': case '4':
894         case '5': case '6': case '7': case '8': case '9':
895             {
896                 I32 num = atoi(regparse);
897
898                 if (num > 9 && num >= regnpar)
899                     goto defchar;
900                 else {
901                     regsawback = 1;
902                     ret = reganode(REF, num);
903                     *flagp |= HASWIDTH;
904                     while (isDIGIT(*regparse))
905                         regparse++;
906                     regparse--;
907                     nextchar();
908                 }
909             }
910             break;
911         case '\0':
912             if (regparse >= regxend)
913                 FAIL("trailing \\ in regexp");
914             /* FALL THROUGH */
915         default:
916             goto defchar;
917         }
918         break;
919
920     case '#':
921         if (regflags & PMf_EXTENDED) {
922             while (regparse < regxend && *regparse != '\n') regparse++;
923             if (regparse < regxend)
924                 goto tryagain;
925         }
926         /* FALL THROUGH */
927
928     default: {
929             register I32 len;
930             register char ender;
931             register char *p;
932             char *oldp;
933             I32 numlen;
934
935             regparse++;
936
937         defchar:
938             ret = regnode((regflags & PMf_FOLD)
939                           ? ((regflags & PMf_LOCALE) ? EXACTFL : EXACTF)
940                           : EXACT);
941             regc(0);            /* save spot for len */
942             for (len = 0, p = regparse - 1;
943               len < 127 && p < regxend;
944               len++)
945             {
946                 oldp = p;
947
948                 if (regflags & PMf_EXTENDED)
949                     p = regwhite(p, regxend);
950                 switch (*p) {
951                 case '^':
952                 case '$':
953                 case '.':
954                 case '[':
955                 case '(':
956                 case ')':
957                 case '|':
958                     goto loopdone;
959                 case '\\':
960                     switch (*++p) {
961                     case 'A':
962                     case 'G':
963                     case 'Z':
964                     case 'w':
965                     case 'W':
966                     case 'b':
967                     case 'B':
968                     case 's':
969                     case 'S':
970                     case 'd':
971                     case 'D':
972                         --p;
973                         goto loopdone;
974                     case 'n':
975                         ender = '\n';
976                         p++;
977                         break;
978                     case 'r':
979                         ender = '\r';
980                         p++;
981                         break;
982                     case 't':
983                         ender = '\t';
984                         p++;
985                         break;
986                     case 'f':
987                         ender = '\f';
988                         p++;
989                         break;
990                     case 'e':
991                         ender = '\033';
992                         p++;
993                         break;
994                     case 'a':
995                         ender = '\007';
996                         p++;
997                         break;
998                     case 'x':
999                         ender = scan_hex(++p, 2, &numlen);
1000                         p += numlen;
1001                         break;
1002                     case 'c':
1003                         p++;
1004                         ender = UCHARAT(p++);
1005                         ender = toCTRL(ender);
1006                         break;
1007                     case '0': case '1': case '2': case '3':case '4':
1008                     case '5': case '6': case '7': case '8':case '9':
1009                         if (*p == '0' ||
1010                           (isDIGIT(p[1]) && atoi(p) >= regnpar) ) {
1011                             ender = scan_oct(p, 3, &numlen);
1012                             p += numlen;
1013                         }
1014                         else {
1015                             --p;
1016                             goto loopdone;
1017                         }
1018                         break;
1019                     case '\0':
1020                         if (p >= regxend)
1021                             FAIL("trailing \\ in regexp");
1022                         /* FALL THROUGH */
1023                     default:
1024                         ender = *p++;
1025                         break;
1026                     }
1027                     break;
1028                 default:
1029                     ender = *p++;
1030                     break;
1031                 }
1032                 if (regflags & PMf_EXTENDED)
1033                     p = regwhite(p, regxend);
1034                 if (ISMULT2(p)) { /* Back off on ?+*. */
1035                     if (len)
1036                         p = oldp;
1037                     else {
1038                         len++;
1039                         regc(ender);
1040                     }
1041                     break;
1042                 }
1043                 regc(ender);
1044             }
1045         loopdone:
1046             regparse = p - 1;
1047             nextchar();
1048             if (len < 0)
1049                 FAIL("internal disaster in regexp");
1050             if (len > 0)
1051                 *flagp |= HASWIDTH;
1052             if (len == 1)
1053                 *flagp |= SIMPLE;
1054             if (regcode != &regdummy)
1055                 *OPERAND(ret) = len;
1056             regc('\0');
1057         }
1058         break;
1059     }
1060
1061     return(ret);
1062 }
1063
1064 static char *
1065 regwhite(p, e)
1066 char *p;
1067 char *e;
1068 {
1069     while (p < e) {
1070         if (isSPACE(*p))
1071             ++p;
1072         else if (*p == '#') {
1073             do {
1074                 p++;
1075             } while (p < e && *p != '\n');
1076         }
1077         else
1078             break;
1079     }
1080     return p;
1081 }
1082
1083 static void
1084 regset(opnd, c)
1085 char *opnd;
1086 register I32 c;
1087 {
1088     if (opnd == &regdummy)
1089         return;
1090     c &= 0xFF;
1091     opnd[1 + (c >> 3)] |= (1 << (c & 7));
1092 }
1093
1094 static char *
1095 regclass()
1096 {
1097     register char *opnd;
1098     register I32 class;
1099     register I32 lastclass = 1234;
1100     register I32 range = 0;
1101     register char *ret;
1102     register I32 def;
1103     I32 numlen;
1104
1105     ret = regnode(ANYOF);
1106     opnd = regcode;
1107     for (class = 0; class < 33; class++)
1108         regc(0);
1109     if (*regparse == '^') {     /* Complement of range. */
1110         regnaughty++;
1111         regparse++;
1112         if (opnd != &regdummy)
1113             *opnd |= ANYOF_INVERT;
1114     }
1115     if (opnd != &regdummy) {
1116         if (regflags & PMf_FOLD)
1117             *opnd |= ANYOF_FOLD;
1118         if (regflags & PMf_LOCALE)
1119             *opnd |= ANYOF_LOCALE;
1120     }
1121     if (*regparse == ']' || *regparse == '-')
1122         goto skipcond;          /* allow 1st char to be ] or - */
1123     while (regparse < regxend && *regparse != ']') {
1124        skipcond:
1125         class = UCHARAT(regparse++);
1126         if (class == '\\') {
1127             class = UCHARAT(regparse++);
1128             switch (class) {
1129             case 'w':
1130                 if (regflags & PMf_LOCALE) {
1131                     if (opnd != &regdummy)
1132                         *opnd |= ANYOF_ALNUML;
1133                 }
1134                 else {
1135                     for (class = 0; class < 256; class++)
1136                         if (isALNUM(class))
1137                             regset(opnd, class);
1138                 }
1139                 lastclass = 1234;
1140                 continue;
1141             case 'W':
1142                 if (regflags & PMf_LOCALE) {
1143                     if (opnd != &regdummy)
1144                         *opnd |= ANYOF_NALNUML;
1145                 }
1146                 else {
1147                     for (class = 0; class < 256; class++)
1148                         if (!isALNUM(class))
1149                             regset(opnd, class);
1150                 }
1151                 lastclass = 1234;
1152                 continue;
1153             case 's':
1154                 if (regflags & PMf_LOCALE) {
1155                     if (opnd != &regdummy)
1156                         *opnd |= ANYOF_SPACEL;
1157                 }
1158                 else {
1159                     for (class = 0; class < 256; class++)
1160                         if (isSPACE(class))
1161                             regset(opnd, class);
1162                 }
1163                 lastclass = 1234;
1164                 continue;
1165             case 'S':
1166                 if (regflags & PMf_LOCALE) {
1167                     if (opnd != &regdummy)
1168                         *opnd |= ANYOF_NSPACEL;
1169                 }
1170                 else {
1171                     for (class = 0; class < 256; class++)
1172                         if (!isSPACE(class))
1173                             regset(opnd, class);
1174                 }
1175                 lastclass = 1234;
1176                 continue;
1177             case 'd':
1178                 for (class = '0'; class <= '9'; class++)
1179                     regset(opnd, class);
1180                 lastclass = 1234;
1181                 continue;
1182             case 'D':
1183                 for (class = 0; class < '0'; class++)
1184                     regset(opnd, class);
1185                 for (class = '9' + 1; class < 256; class++)
1186                     regset(opnd, class);
1187                 lastclass = 1234;
1188                 continue;
1189             case 'n':
1190                 class = '\n';
1191                 break;
1192             case 'r':
1193                 class = '\r';
1194                 break;
1195             case 't':
1196                 class = '\t';
1197                 break;
1198             case 'f':
1199                 class = '\f';
1200                 break;
1201             case 'b':
1202                 class = '\b';
1203                 break;
1204             case 'e':
1205                 class = '\033';
1206                 break;
1207             case 'a':
1208                 class = '\007';
1209                 break;
1210             case 'x':
1211                 class = scan_hex(regparse, 2, &numlen);
1212                 regparse += numlen;
1213                 break;
1214             case 'c':
1215                 class = UCHARAT(regparse++);
1216                 class = toCTRL(class);
1217                 break;
1218             case '0': case '1': case '2': case '3': case '4':
1219             case '5': case '6': case '7': case '8': case '9':
1220                 class = scan_oct(--regparse, 3, &numlen);
1221                 regparse += numlen;
1222                 break;
1223             }
1224         }
1225         if (range) {
1226             if (lastclass > class)
1227                 FAIL("invalid [] range in regexp");
1228             range = 0;
1229         }
1230         else {
1231             lastclass = class;
1232             if (*regparse == '-' && regparse+1 < regxend &&
1233               regparse[1] != ']') {
1234                 regparse++;
1235                 range = 1;
1236                 continue;       /* do it next time */
1237             }
1238         }
1239         for ( ; lastclass <= class; lastclass++)
1240             regset(opnd, lastclass);
1241         lastclass = class;
1242     }
1243     if (*regparse != ']')
1244         FAIL("unmatched [] in regexp");
1245     nextchar();
1246     return ret;
1247 }
1248
1249 static char*
1250 nextchar()
1251 {
1252     char* retval = regparse++;
1253
1254     for (;;) {
1255         if (*regparse == '(' && regparse[1] == '?' &&
1256                 regparse[2] == '#') {
1257             while (*regparse && *regparse != ')')
1258                 regparse++;
1259             regparse++;
1260             continue;
1261         }
1262         if (regflags & PMf_EXTENDED) {
1263             if (isSPACE(*regparse)) {
1264                 regparse++;
1265                 continue;
1266             }
1267             else if (*regparse == '#') {
1268                 while (*regparse && *regparse != '\n')
1269                     regparse++;
1270                 regparse++;
1271                 continue;
1272             }
1273         }
1274         return retval;
1275     }
1276 }
1277
1278 /*
1279 - regnode - emit a node
1280 */
1281 #ifdef CAN_PROTOTYPE
1282 static char *                   /* Location. */
1283 regnode(char op)
1284 #else
1285 static char *                   /* Location. */
1286 regnode(op)
1287 char op;
1288 #endif
1289 {
1290     register char *ret;
1291     register char *ptr;
1292
1293     ret = regcode;
1294     if (ret == &regdummy) {
1295 #ifdef REGALIGN
1296         if (!(regsize & 1))
1297             regsize++;
1298 #endif
1299         regsize += 3;
1300         return(ret);
1301     }
1302
1303 #ifdef REGALIGN
1304 #ifndef lint
1305     if (!((long)ret & 1))
1306       *ret++ = 127;
1307 #endif
1308 #endif
1309     ptr = ret;
1310     *ptr++ = op;
1311     *ptr++ = '\0';              /* Null "next" pointer. */
1312     *ptr++ = '\0';
1313     regcode = ptr;
1314
1315     return(ret);
1316 }
1317
1318 /*
1319 - reganode - emit a node with an argument
1320 */
1321 #ifdef CAN_PROTOTYPE
1322 static char *                   /* Location. */
1323 reganode(char op, unsigned short arg)
1324 #else
1325 static char *                   /* Location. */
1326 reganode(op, arg)
1327 char op;
1328 unsigned short arg;
1329 #endif
1330 {
1331     register char *ret;
1332     register char *ptr;
1333
1334     ret = regcode;
1335     if (ret == &regdummy) {
1336 #ifdef REGALIGN
1337         if (!(regsize & 1))
1338             regsize++;
1339 #endif
1340         regsize += 5;
1341         return(ret);
1342     }
1343
1344 #ifdef REGALIGN
1345 #ifndef lint
1346     if (!((long)ret & 1))
1347       *ret++ = 127;
1348 #endif
1349 #endif
1350     ptr = ret;
1351     *ptr++ = op;
1352     *ptr++ = '\0';              /* Null "next" pointer. */
1353     *ptr++ = '\0';
1354 #ifdef REGALIGN
1355     *(unsigned short *)(ret+3) = arg;
1356 #else
1357     ret[3] = arg >> 8; ret[4] = arg & 0377;
1358 #endif
1359     ptr += 2;
1360     regcode = ptr;
1361
1362     return(ret);
1363 }
1364
1365 /*
1366 - regc - emit (if appropriate) a byte of code
1367 */
1368 #ifdef CAN_PROTOTYPE
1369 static void
1370 regc(char b)
1371 #else
1372 static void
1373 regc(b)
1374 char b;
1375 #endif
1376 {
1377     if (regcode != &regdummy)
1378         *regcode++ = b;
1379     else
1380         regsize++;
1381 }
1382
1383 /*
1384 - reginsert - insert an operator in front of already-emitted operand
1385 *
1386 * Means relocating the operand.
1387 */
1388 #ifdef CAN_PROTOTYPE
1389 static void
1390 reginsert(char op, char *opnd)
1391 #else
1392 static void
1393 reginsert(op, opnd)
1394 char op;
1395 char *opnd;
1396 #endif
1397 {
1398     register char *src;
1399     register char *dst;
1400     register char *place;
1401     register int offset = (regkind[(U8)op] == CURLY ? 4 : 0);
1402
1403     if (regcode == &regdummy) {
1404 #ifdef REGALIGN
1405         regsize += 4 + offset;
1406 #else
1407         regsize += 3 + offset;
1408 #endif
1409         return;
1410     }
1411
1412     src = regcode;
1413 #ifdef REGALIGN
1414     regcode += 4 + offset;
1415 #else
1416     regcode += 3 + offset;
1417 #endif
1418     dst = regcode;
1419     while (src > opnd)
1420         *--dst = *--src;
1421
1422     place = opnd;               /* Op node, where operand used to be. */
1423     *place++ = op;
1424     *place++ = '\0';
1425     *place++ = '\0';
1426     while (offset-- > 0)
1427         *place++ = '\0';
1428 #ifdef REGALIGN
1429     *place++ = '\177';
1430 #endif
1431 }
1432
1433 /*
1434 - regtail - set the next-pointer at the end of a node chain
1435 */
1436 static void
1437 regtail(p, val)
1438 char *p;
1439 char *val;
1440 {
1441     register char *scan;
1442     register char *temp;
1443     register I32 offset;
1444
1445     if (p == &regdummy)
1446         return;
1447
1448     /* Find last node. */
1449     scan = p;
1450     for (;;) {
1451         temp = regnext(scan);
1452         if (temp == NULL)
1453             break;
1454         scan = temp;
1455     }
1456
1457 #ifdef REGALIGN
1458     offset = val - scan;
1459 #ifndef lint
1460     *(short*)(scan+1) = offset;
1461 #else
1462     offset = offset;
1463 #endif
1464 #else
1465     if (OP(scan) == BACK)
1466         offset = scan - val;
1467     else
1468         offset = val - scan;
1469     *(scan+1) = (offset>>8)&0377;
1470     *(scan+2) = offset&0377;
1471 #endif
1472 }
1473
1474 /*
1475 - regoptail - regtail on operand of first argument; nop if operandless
1476 */
1477 static void
1478 regoptail(p, val)
1479 char *p;
1480 char *val;
1481 {
1482     /* "Operandless" and "op != BRANCH" are synonymous in practice. */
1483     if (p == NULL || p == &regdummy || regkind[(U8)OP(p)] != BRANCH)
1484         return;
1485     regtail(NEXTOPER(p), val);
1486 }
1487
1488 /*
1489  - regcurly - a little FSA that accepts {\d+,?\d*}
1490  */
1491 STATIC I32
1492 regcurly(s)
1493 register char *s;
1494 {
1495     if (*s++ != '{')
1496         return FALSE;
1497     if (!isDIGIT(*s))
1498         return FALSE;
1499     while (isDIGIT(*s))
1500         s++;
1501     if (*s == ',')
1502         s++;
1503     while (isDIGIT(*s))
1504         s++;
1505     if (*s != '}')
1506         return FALSE;
1507     return TRUE;
1508 }
1509
1510 #ifdef DEBUGGING
1511
1512 /*
1513  - regdump - dump a regexp onto Perl_debug_log in vaguely comprehensible form
1514  */
1515 void
1516 regdump(r)
1517 regexp *r;
1518 {
1519     register char *s;
1520     register char op = EXACT;   /* Arbitrary non-END op. */
1521     register char *next;
1522
1523
1524     s = r->program + 1;
1525     while (op != END) { /* While that wasn't END last time... */
1526 #ifdef REGALIGN
1527         if (!((long)s & 1))
1528             s++;
1529 #endif
1530         op = OP(s);
1531         PerlIO_printf(Perl_debug_log, "%2d%s", s-r->program, regprop(s));       /* Where, what. */
1532         next = regnext(s);
1533         s += regarglen[(U8)op];
1534         if (next == NULL)               /* Next ptr. */
1535             PerlIO_printf(Perl_debug_log, "(0)");
1536         else 
1537             PerlIO_printf(Perl_debug_log, "(%d)", (s-r->program)+(next-s));
1538         s += 3;
1539         if (op == ANYOF) {
1540             s += 33;
1541         }
1542         if (regkind[(U8)op] == EXACT) {
1543             /* Literal string, where present. */
1544             s++;
1545             (void)PerlIO_putc(Perl_debug_log, ' ');
1546             (void)PerlIO_putc(Perl_debug_log, '<');
1547             while (*s != '\0') {
1548                 (void)PerlIO_putc(Perl_debug_log,*s);
1549                 s++;
1550             }
1551             (void)PerlIO_putc(Perl_debug_log, '>');
1552             s++;
1553         }
1554         (void)PerlIO_putc(Perl_debug_log, '\n');
1555     }
1556
1557     /* Header fields of interest. */
1558     if (r->regstart)
1559         PerlIO_printf(Perl_debug_log, "start `%s' ", SvPVX(r->regstart));
1560     if (r->regstclass)
1561         PerlIO_printf(Perl_debug_log, "stclass `%s' ", regprop(r->regstclass));
1562     if (r->reganch & ROPT_ANCH) {
1563         PerlIO_printf(Perl_debug_log, "anchored");
1564         if (r->reganch & ROPT_ANCH_BOL)
1565             PerlIO_printf(Perl_debug_log, "(BOL)");
1566         if (r->reganch & ROPT_ANCH_GPOS)
1567             PerlIO_printf(Perl_debug_log, "(GPOS)");
1568         PerlIO_putc(Perl_debug_log, ' ');
1569     }
1570     if (r->reganch & ROPT_SKIP)
1571         PerlIO_printf(Perl_debug_log, "plus ");
1572     if (r->reganch & ROPT_IMPLICIT)
1573         PerlIO_printf(Perl_debug_log, "implicit ");
1574     if (r->regmust != NULL)
1575         PerlIO_printf(Perl_debug_log, "must have \"%s\" back %ld ", SvPVX(r->regmust),
1576          (long) r->regback);
1577     PerlIO_printf(Perl_debug_log, "minlen %ld ", (long) r->minlen);
1578     PerlIO_printf(Perl_debug_log, "\n");
1579 }
1580
1581 /*
1582 - regprop - printable representation of opcode
1583 */
1584 char *
1585 regprop(op)
1586 char *op;
1587 {
1588     register char *p = 0;
1589
1590     (void) strcpy(buf, ":");
1591
1592     switch (OP(op)) {
1593     case BOL:
1594         p = "BOL";
1595         break;
1596     case MBOL:
1597         p = "MBOL";
1598         break;
1599     case SBOL:
1600         p = "SBOL";
1601         break;
1602     case EOL:
1603         p = "EOL";
1604         break;
1605     case MEOL:
1606         p = "MEOL";
1607         break;
1608     case SEOL:
1609         p = "SEOL";
1610         break;
1611     case ANY:
1612         p = "ANY";
1613         break;
1614     case SANY:
1615         p = "SANY";
1616         break;
1617     case ANYOF:
1618         p = "ANYOF";
1619         break;
1620     case BRANCH:
1621         p = "BRANCH";
1622         break;
1623     case EXACT:
1624         p = "EXACT";
1625         break;
1626     case EXACTF:
1627         p = "EXACTF";
1628         break;
1629     case EXACTFL:
1630         p = "EXACTFL";
1631         break;
1632     case NOTHING:
1633         p = "NOTHING";
1634         break;
1635     case BACK:
1636         p = "BACK";
1637         break;
1638     case END:
1639         p = "END";
1640         break;
1641     case BOUND:
1642         p = "BOUND";
1643         break;
1644     case BOUNDL:
1645         p = "BOUNDL";
1646         break;
1647     case NBOUND:
1648         p = "NBOUND";
1649         break;
1650     case NBOUNDL:
1651         p = "NBOUNDL";
1652         break;
1653     case CURLY:
1654         (void)sprintf(buf+strlen(buf), "CURLY {%d,%d}", ARG1(op),ARG2(op));
1655         p = NULL;
1656         break;
1657     case CURLYX:
1658         (void)sprintf(buf+strlen(buf), "CURLYX {%d,%d}", ARG1(op),ARG2(op));
1659         p = NULL;
1660         break;
1661     case REF:
1662         (void)sprintf(buf+strlen(buf), "REF%d", ARG1(op));
1663         p = NULL;
1664         break;
1665     case OPEN:
1666         (void)sprintf(buf+strlen(buf), "OPEN%d", ARG1(op));
1667         p = NULL;
1668         break;
1669     case CLOSE:
1670         (void)sprintf(buf+strlen(buf), "CLOSE%d", ARG1(op));
1671         p = NULL;
1672         break;
1673     case STAR:
1674         p = "STAR";
1675         break;
1676     case PLUS:
1677         p = "PLUS";
1678         break;
1679     case MINMOD:
1680         p = "MINMOD";
1681         break;
1682     case GPOS:
1683         p = "GPOS";
1684         break;
1685     case UNLESSM:
1686         p = "UNLESSM";
1687         break;
1688     case IFMATCH:
1689         p = "IFMATCH";
1690         break;
1691     case SUCCEED:
1692         p = "SUCCEED";
1693         break;
1694     case WHILEM:
1695         p = "WHILEM";
1696         break;
1697     case DIGIT:
1698         p = "DIGIT";
1699         break;
1700     case NDIGIT:
1701         p = "NDIGIT";
1702         break;
1703     case ALNUM:
1704         p = "ALNUM";
1705         break;
1706     case NALNUM:
1707         p = "NALNUM";
1708         break;
1709     case SPACE:
1710         p = "SPACE";
1711         break;
1712     case NSPACE:
1713         p = "NSPACE";
1714         break;
1715     case ALNUML:
1716         p = "ALNUML";
1717         break;
1718     case NALNUML:
1719         p = "NALNUML";
1720         break;
1721     case SPACEL:
1722         p = "SPACEL";
1723         break;
1724     case NSPACEL:
1725         p = "NSPACEL";
1726         break;
1727     default:
1728         FAIL("corrupted regexp opcode");
1729     }
1730     if (p != NULL)
1731         (void) strcat(buf, p);
1732     return(buf);
1733 }
1734 #endif /* DEBUGGING */
1735
1736 void
1737 pregfree(r)
1738 struct regexp *r;
1739 {
1740     if (!r)
1741         return;
1742     if (r->precomp) {
1743         Safefree(r->precomp);
1744         r->precomp = Nullch;
1745     }
1746     if (r->subbase) {
1747         Safefree(r->subbase);
1748         r->subbase = Nullch;
1749     }
1750     if (r->regmust) {
1751         SvREFCNT_dec(r->regmust);
1752         r->regmust = Nullsv;
1753     }
1754     if (r->regstart) {
1755         SvREFCNT_dec(r->regstart);
1756         r->regstart = Nullsv;
1757     }
1758     Safefree(r->startp);
1759     Safefree(r->endp);
1760     Safefree(r);
1761 }