[asperl] add AS patch#15
[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
60 #define REG_COMP_C
61 #include "regcomp.h"
62
63 #ifdef op
64 #undef op
65 #endif /* op */
66
67 #ifdef MSDOS
68 # if defined(BUGGY_MSC6)
69  /* MSC 6.00A breaks on op/regexp.t test 85 unless we turn this off */
70  # pragma optimize("a",off)
71  /* But MSC 6.00A is happy with 'w', for aliases only across function calls*/
72  # pragma optimize("w",on )
73 # endif /* BUGGY_MSC6 */
74 #endif /* MSDOS */
75
76 #ifndef STATIC
77 #define STATIC  static
78 #endif
79
80 #define ISMULT1(c)      ((c) == '*' || (c) == '+' || (c) == '?')
81 #define ISMULT2(s)      ((*s) == '*' || (*s) == '+' || (*s) == '?' || \
82         ((*s) == '{' && regcurly(s)))
83 #ifdef atarist
84 #define PERL_META       "^$.[()|?+*\\"
85 #else
86 #define META    "^$.[()|?+*\\"
87 #endif
88
89 #ifdef SPSTART
90 #undef SPSTART          /* dratted cpp namespace... */
91 #endif
92 /*
93  * Flags to be passed up and down.
94  */
95 #define WORST           0       /* Worst case. */
96 #define HASWIDTH        0x1     /* Known never to match null string. */
97 #define SIMPLE          0x2     /* Simple enough to be STAR/PLUS operand. */
98 #define SPSTART         0x4     /* Starts with * or +. */
99 #define TRYAGAIN        0x8     /* Weeded out a declaration. */
100
101 /*
102  * Forward declarations for pregcomp()'s friends.
103  */
104
105 static char* regwhite _((char *, char *));
106 #ifndef PERL_OBJECT
107 static regnode *reg _((I32, I32 *));
108 static regnode *reganode _((U8, U32));
109 static regnode *regatom _((I32 *));
110 static regnode *regbranch _((I32 *, I32));
111 static void regc _((U8, char *));
112 static regnode *regclass _((void));
113 STATIC I32 regcurly _((char *));
114 static regnode *reg_node _((U8));
115 static regnode *regpiece _((I32 *));
116 static void reginsert _((U8, regnode *));
117 static void regoptail _((regnode *, regnode *));
118 static void regset _((char *, I32));
119 static void regtail _((regnode *, regnode *));
120 static char* nextchar _((void));
121
122 static void re_croak2 _((const char* pat1,const char* pat2,...)) __attribute__((noreturn));
123 #endif
124
125 /* Length of a variant. */
126
127 #ifndef PERL_OBJECT
128 typedef struct {
129     I32 len_min;
130     I32 len_delta;
131     I32 pos_min;
132     I32 pos_delta;
133     SV *last_found;
134     I32 last_end;                       /* min value, <0 unless valid. */
135     I32 last_start_min;
136     I32 last_start_max;
137     SV **longest;                       /* Either &l_fixed, or &l_float. */
138     SV *longest_fixed;
139     I32 offset_fixed;
140     SV *longest_float;
141     I32 offset_float_min;
142     I32 offset_float_max;
143     I32 flags;
144 } scan_data_t;
145 #endif
146
147 static scan_data_t zero_scan_data = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
148
149 #define SF_BEFORE_EOL           (SF_BEFORE_SEOL|SF_BEFORE_MEOL)
150 #define SF_BEFORE_SEOL          0x1
151 #define SF_BEFORE_MEOL          0x2
152 #define SF_FIX_BEFORE_EOL       (SF_FIX_BEFORE_SEOL|SF_FIX_BEFORE_MEOL)
153 #define SF_FL_BEFORE_EOL        (SF_FL_BEFORE_SEOL|SF_FL_BEFORE_MEOL)
154
155 #define SF_FIX_SHIFT_EOL        (+2)
156 #define SF_FL_SHIFT_EOL         (+4)
157
158 #define SF_FIX_BEFORE_SEOL      (SF_BEFORE_SEOL << SF_FIX_SHIFT_EOL)
159 #define SF_FIX_BEFORE_MEOL      (SF_BEFORE_MEOL << SF_FIX_SHIFT_EOL)
160
161 #define SF_FL_BEFORE_SEOL       (SF_BEFORE_SEOL << SF_FL_SHIFT_EOL)
162 #define SF_FL_BEFORE_MEOL       (SF_BEFORE_MEOL << SF_FL_SHIFT_EOL) /* 0x20 */
163 #define SF_IS_INF               0x40
164 #define SF_HAS_PAR              0x80
165 #define SF_IN_PAR               0x100
166 #define SF_HAS_EVAL             0x200
167 #define SCF_DO_SUBSTR           0x400
168
169 STATIC void
170 scan_commit(scan_data_t *data)
171 {
172     STRLEN l = SvCUR(data->last_found);
173     STRLEN old_l = SvCUR(*data->longest);
174     
175     if ((l >= old_l) && ((l > old_l) || (data->flags & SF_BEFORE_EOL))) {
176         sv_setsv(*data->longest, data->last_found);
177         if (*data->longest == data->longest_fixed) {
178             data->offset_fixed = l ? data->last_start_min : data->pos_min;
179             if (data->flags & SF_BEFORE_EOL)
180                 data->flags 
181                     |= ((data->flags & SF_BEFORE_EOL) << SF_FIX_SHIFT_EOL);
182             else
183                 data->flags &= ~SF_FIX_BEFORE_EOL;
184         } else {
185             data->offset_float_min = l ? data->last_start_min : data->pos_min;
186             data->offset_float_max = (l 
187                                       ? data->last_start_max 
188                                       : data->pos_min + data->pos_delta);
189             if (data->flags & SF_BEFORE_EOL)
190                 data->flags 
191                     |= ((data->flags & SF_BEFORE_EOL) << SF_FL_SHIFT_EOL);
192             else
193                 data->flags &= ~SF_FL_BEFORE_EOL;
194         }
195     }
196     SvCUR_set(data->last_found, 0);
197     data->last_end = -1;
198     data->flags &= ~SF_BEFORE_EOL;
199 }
200
201 /* Stops at toplevel WHILEM as well as at `last'. At end *scanp is set
202    to the position after last scanned or to NULL. */
203
204 STATIC I32
205 study_chunk(regnode **scanp, I32 *deltap, regnode *last, scan_data_t *data, U32 flags)
206                         /* scanp: Start here (read-write). */
207                         /* deltap: Write maxlen-minlen here. */
208                         /* last: Stop before this one. */
209 {
210     I32 min = 0, pars = 0, code;
211     regnode *scan = *scanp, *next;
212     I32 delta = 0;
213     int is_inf = (flags & SCF_DO_SUBSTR) && (data->flags & SF_IS_INF);
214     I32 is_par = OP(scan) == OPEN ? ARG(scan) : 0;
215     scan_data_t data_fake;
216     
217     while (scan && OP(scan) != END && scan < last) {
218         /* Peephole optimizer: */
219
220         if (regkind[(U8)OP(scan)] == EXACT) {
221             regnode *n = regnext(scan);
222             U32 stringok = 1;
223 #ifdef DEBUGGING
224             regnode *stop = scan;
225 #endif 
226
227             next = scan + (*OPERAND(scan) + 2 - 1)/sizeof(regnode) + 2;
228             /* Skip NOTHING, merge EXACT*. */
229             while (n &&
230                    ( regkind[(U8)OP(n)] == NOTHING || 
231                      (stringok && (OP(n) == OP(scan))))
232                    && NEXT_OFF(n)
233                    && NEXT_OFF(scan) + NEXT_OFF(n) < I16_MAX) {
234                 if (OP(n) == TAIL || n > next)
235                     stringok = 0;
236                 if (regkind[(U8)OP(n)] == NOTHING) {
237                     NEXT_OFF(scan) += NEXT_OFF(n);
238                     next = n + NODE_STEP_REGNODE;
239 #ifdef DEBUGGING
240                     if (stringok)
241                         stop = n;
242 #endif 
243                     n = regnext(n);
244                 } else {
245                     int oldl = *OPERAND(scan);
246                     regnode *nnext = regnext(n);
247                     
248                     if (oldl + *OPERAND(n) > U8_MAX) 
249                         break;
250                     NEXT_OFF(scan) += NEXT_OFF(n);
251                     *OPERAND(scan) += *OPERAND(n);
252                     next = n + (*OPERAND(n) + 2 - 1)/sizeof(regnode) + 2;
253                     /* Now we can overwrite *n : */
254                     Move(OPERAND(n) + 1, OPERAND(scan) + oldl + 1,
255                          *OPERAND(n) + 1, char);
256 #ifdef DEBUGGING
257                     if (stringok)
258                         stop = next - 1;
259 #endif 
260                     n = nnext;
261                 }
262             }
263 #ifdef DEBUGGING
264             /* Allow dumping */
265             n = scan + (*OPERAND(scan) + 2 - 1)/sizeof(regnode) + 2;
266             while (n <= stop) {
267                 if (regkind[(U8)OP(n)] != NOTHING || OP(n) == NOTHING) {
268                     OP(n) = OPTIMIZED;
269                     NEXT_OFF(n) = 0;
270                 }
271                 n++;
272             }
273 #endif 
274
275         }
276         if (OP(scan) != CURLYX) {
277             int max = (reg_off_by_arg[OP(scan)] ? I32_MAX : U16_MAX);
278             int off = (reg_off_by_arg[OP(scan)] ? ARG(scan) : NEXT_OFF(scan));
279             int noff;
280             regnode *n = scan;
281             
282             /* Skip NOTHING and LONGJMP. */
283             while ((n = regnext(n))
284                    && ((regkind[(U8)OP(n)] == NOTHING && (noff = NEXT_OFF(n)))
285                        || ((OP(n) == LONGJMP) && (noff = ARG(n))))
286                    && off + noff < max)
287                 off += noff;
288             if (reg_off_by_arg[OP(scan)])
289                 ARG(scan) = off;
290             else 
291                 NEXT_OFF(scan) = off;
292         }
293         if (OP(scan) == BRANCH || OP(scan) == BRANCHJ 
294                    || OP(scan) == IFTHEN || OP(scan) == SUSPEND) {
295             next = regnext(scan);
296             code = OP(scan);
297             
298             if (OP(next) == code || code == IFTHEN || code == SUSPEND) { 
299                 I32 max1 = 0, min1 = I32_MAX, num = 0;
300                 
301                 if (flags & SCF_DO_SUBSTR)
302                     scan_commit(data);
303                 while (OP(scan) == code) {
304                     I32 deltanext, minnext;
305
306                     num++;
307                     data_fake.flags = 0;
308                     next = regnext(scan);
309                     scan = NEXTOPER(scan);
310                     if (code != BRANCH)
311                         scan = NEXTOPER(scan);
312                     /* We suppose the run is continuous, last=next...*/
313                     minnext = study_chunk(&scan, &deltanext, next,
314                                           &data_fake, 0);
315                     if (min1 > minnext) 
316                         min1 = minnext;
317                     if (max1 < minnext + deltanext)
318                         max1 = minnext + deltanext;
319                     if (deltanext == I32_MAX)
320                         is_inf = 1;
321                     scan = next;
322                     if (data_fake.flags & (SF_HAS_PAR|SF_IN_PAR))
323                         pars++;
324                     if (data && (data_fake.flags & SF_HAS_EVAL))
325                         data->flags |= SF_HAS_EVAL;
326                     if (code == SUSPEND) 
327                         break;
328                 }
329                 if (code == IFTHEN && num < 2) /* Empty ELSE branch */
330                     min1 = 0;
331                 if (flags & SCF_DO_SUBSTR) {
332                     data->pos_min += min1;
333                     data->pos_delta += max1 - min1;
334                     if (max1 != min1 || is_inf)
335                         data->longest = &(data->longest_float);
336                 }
337                 min += min1;
338                 delta += max1 - min1;
339             } else if (code == BRANCHJ) /* single branch is optimized. */
340                 scan = NEXTOPER(NEXTOPER(scan));
341             else                        /* single branch is optimized. */
342                 scan = NEXTOPER(scan);
343             continue;
344         } else if (OP(scan) == EXACT) {
345             min += *OPERAND(scan);
346             if (flags & SCF_DO_SUBSTR) { /* Update longest substr. */
347                 I32 l = *OPERAND(scan);
348
349                 /* The code below prefers earlier match for fixed
350                    offset, later match for variable offset.  */
351                 if (data->last_end == -1) { /* Update the start info. */
352                     data->last_start_min = data->pos_min;
353                     data->last_start_max = is_inf
354                         ? I32_MAX : data->pos_min + data->pos_delta; 
355                 }
356                 sv_catpvn(data->last_found, (char *)(OPERAND(scan)+1), l);
357                 data->last_end = data->pos_min + l;
358                 data->pos_min += l; /* As in the first entry. */
359                 data->flags &= ~SF_BEFORE_EOL;
360             }
361         } else if (regkind[(U8)OP(scan)] == EXACT) {
362             if (flags & SCF_DO_SUBSTR) 
363                 scan_commit(data);
364             min += *OPERAND(scan);
365             if (data && (flags & SCF_DO_SUBSTR))
366                 data->pos_min += *OPERAND(scan);
367         } else if (strchr(varies,OP(scan))) {
368             I32 mincount, maxcount, minnext, deltanext, pos_before, fl;
369             regnode *oscan = scan;
370             
371             switch (regkind[(U8)OP(scan)]) {
372             case WHILEM:
373                 scan = NEXTOPER(scan);
374                 goto finish;
375             case PLUS:
376                 if (flags & SCF_DO_SUBSTR) {
377                     next = NEXTOPER(scan);
378                     if (OP(next) == EXACT) {
379                         mincount = 1; 
380                         maxcount = REG_INFTY; 
381                         next = regnext(scan);
382                         scan = NEXTOPER(scan);
383                         goto do_curly;
384                     }
385                 }
386                 if (flags & SCF_DO_SUBSTR)
387                     data->pos_min++;
388                 min++;
389                 /* Fall through. */
390             case STAR:
391                 is_inf = 1; 
392                 scan = regnext(scan);
393                 if (flags & SCF_DO_SUBSTR) {
394                     scan_commit(data);
395                     data->longest = &(data->longest_float);
396                 }
397                 goto optimize_curly_tail;
398             case CURLY:
399                 mincount = ARG1(scan); 
400                 maxcount = ARG2(scan);
401                 next = regnext(scan);
402                 scan = NEXTOPER(scan) + EXTRA_STEP_2ARGS;
403               do_curly:
404                 if (flags & SCF_DO_SUBSTR) {
405                     if (mincount == 0) scan_commit(data);
406                     pos_before = data->pos_min;
407                 }
408                 if (data) {
409                     fl = data->flags;
410                     data->flags &= ~(SF_HAS_PAR|SF_IN_PAR|SF_HAS_EVAL);
411                     if (is_inf)
412                         data->flags |= SF_IS_INF;
413                 }
414                 /* This will finish on WHILEM, setting scan, or on NULL: */
415                 minnext = study_chunk(&scan, &deltanext, last, data, 
416                                       mincount == 0 
417                                         ? (flags & ~SCF_DO_SUBSTR) : flags);
418                 if (!scan)              /* It was not CURLYX, but CURLY. */
419                     scan = next;
420                 if (dowarn && (minnext + deltanext == 0) 
421                     && !(data->flags & (SF_HAS_PAR|SF_IN_PAR))) 
422                     warn("Strange *+?{} on zero-length expression");
423                 min += minnext * mincount;
424                 is_inf |= (maxcount == REG_INFTY && (minnext + deltanext) > 0
425                            || deltanext == I32_MAX);
426                 delta += (minnext + deltanext) * maxcount - minnext * mincount;
427
428                 /* Try powerful optimization CURLYX => CURLYN. */
429 #ifdef REGALIGN_STRUCT
430                 if (  OP(oscan) == CURLYX && data 
431                       && data->flags & SF_IN_PAR
432                       && !(data->flags & SF_HAS_EVAL)
433                       && !deltanext && minnext == 1 ) {
434                     /* Try to optimize to CURLYN.  */
435                     regnode *nxt = NEXTOPER(oscan) + EXTRA_STEP_2ARGS;
436                     regnode *nxt1 = nxt, *nxt2;
437
438                     /* Skip open. */
439                     nxt = regnext(nxt);
440                     if (!strchr(simple,OP(nxt))
441                         && !(regkind[(U8)OP(nxt)] == EXACT
442                              && *OPERAND(nxt) == 1)) 
443                         goto nogo;
444                     nxt2 = nxt;
445                     nxt = regnext(nxt);
446                     if (OP(nxt) != CLOSE) 
447                         goto nogo;
448                     /* Now we know that nxt2 is the only contents: */
449                     oscan->flags = ARG(nxt);
450                     OP(oscan) = CURLYN;
451                     OP(nxt1) = NOTHING; /* was OPEN. */
452 #ifdef DEBUGGING
453                     OP(nxt1 + 1) = OPTIMIZED; /* was count. */
454                     NEXT_OFF(nxt1+ 1) = 0; /* just for consistancy. */
455                     NEXT_OFF(nxt2) = 0; /* just for consistancy with CURLY. */
456                     OP(nxt) = OPTIMIZED;        /* was CLOSE. */
457                     OP(nxt + 1) = OPTIMIZED; /* was count. */
458                     NEXT_OFF(nxt+ 1) = 0; /* just for consistancy. */
459 #endif 
460                 }
461 #endif 
462               nogo:
463
464                 /* Try optimization CURLYX => CURLYM. */
465                 if (  OP(oscan) == CURLYX && data 
466 #ifdef REGALIGN_STRUCT
467                       && !(data->flags & SF_HAS_PAR)
468 #else
469                       && !(data->flags & (SF_HAS_PAR|SF_IN_PAR))
470 #endif 
471                       && !(data->flags & SF_HAS_EVAL)
472                       && !deltanext  ) {
473                     /* XXXX How to optimize if data == 0? */
474                     /* Optimize to a simpler form.  */
475                     regnode *nxt = NEXTOPER(oscan) + EXTRA_STEP_2ARGS; /* OPEN */
476                     regnode *nxt2;
477
478                     OP(oscan) = CURLYM;
479                     while ( (nxt2 = regnext(nxt)) /* skip over embedded stuff*/
480                             && (OP(nxt2) != WHILEM)) 
481                         nxt = nxt2;
482                     OP(nxt2)  = SUCCEED; /* Whas WHILEM */
483 #ifdef REGALIGN_STRUCT
484                     /* Need to optimize away parenths. */
485                     if (data->flags & SF_IN_PAR) {
486                         /* Set the parenth number.  */
487                         regnode *nxt1 = NEXTOPER(oscan) + EXTRA_STEP_2ARGS; /* OPEN*/
488
489                         if (OP(nxt) != CLOSE) 
490                             FAIL("panic opt close");
491                         oscan->flags = ARG(nxt);
492                         OP(nxt1) = OPTIMIZED;   /* was OPEN. */
493                         OP(nxt) = OPTIMIZED;    /* was CLOSE. */
494 #ifdef DEBUGGING
495                         OP(nxt1 + 1) = OPTIMIZED; /* was count. */
496                         OP(nxt + 1) = OPTIMIZED; /* was count. */
497                         NEXT_OFF(nxt1 + 1) = 0; /* just for consistancy. */
498                         NEXT_OFF(nxt + 1) = 0; /* just for consistancy. */
499 #endif 
500 #if 0
501                         while ( nxt1 && (OP(nxt1) != WHILEM)) {
502                             regnode *nnxt = regnext(nxt1);
503                             
504                             if (nnxt == nxt) {
505                                 if (reg_off_by_arg[OP(nxt1)])
506                                     ARG_SET(nxt1, nxt2 - nxt1);
507                                 else if (nxt2 - nxt1 < U16_MAX)
508                                     NEXT_OFF(nxt1) = nxt2 - nxt1;
509                                 else
510                                     OP(nxt) = NOTHING;  /* Cannot beautify */
511                             }
512                             nxt1 = nnxt;
513                         }
514 #endif
515                         /* Optimize again: */
516                         study_chunk(&nxt1, &deltanext, nxt, NULL, 0);
517                     } else
518                         oscan->flags = 0;
519 #endif 
520                 }
521                 if (data && fl & (SF_HAS_PAR|SF_IN_PAR)) 
522                     pars++;
523                 if (flags & SCF_DO_SUBSTR) {
524                     SV *last_str = Nullsv;
525                     int counted = mincount != 0;
526
527                     if (data->last_end > 0 && mincount != 0) { /* Ends with a string. */
528                         I32 b = pos_before >= data->last_start_min 
529                             ? pos_before : data->last_start_min;
530                         STRLEN l;
531                         char *s = SvPV(data->last_found, l);
532                         
533                         l -= b - data->last_start_min;
534                         /* Get the added string: */
535                         last_str = newSVpv(s  +  b - data->last_start_min, l);
536                         if (deltanext == 0 && pos_before == b) {
537                             /* What was added is a constant string */
538                             if (mincount > 1) {
539                                 SvGROW(last_str, (mincount * l) + 1);
540                                 repeatcpy(SvPVX(last_str) + l, 
541                                           SvPVX(last_str), l, mincount - 1);
542                                 SvCUR(last_str) *= mincount;
543                                 /* Add additional parts. */
544                                 SvCUR_set(data->last_found, 
545                                           SvCUR(data->last_found) - l);
546                                 sv_catsv(data->last_found, last_str);
547                                 data->last_end += l * (mincount - 1);
548                             }
549                         }
550                     }
551                     /* It is counted once already... */
552                     data->pos_min += minnext * (mincount - counted);
553                     data->pos_delta += - counted * deltanext +
554                         (minnext + deltanext) * maxcount - minnext * mincount;
555                     if (mincount != maxcount) {
556                         scan_commit(data);
557                         if (mincount && last_str) {
558                             sv_setsv(data->last_found, last_str);
559                             data->last_end = data->pos_min;
560                             data->last_start_min = 
561                                 data->pos_min - SvCUR(last_str);
562                             data->last_start_max = is_inf 
563                                 ? I32_MAX 
564                                 : data->pos_min + data->pos_delta
565                                 - SvCUR(last_str);
566                         }
567                         data->longest = &(data->longest_float);
568                     }
569                 }
570                 if (data && (fl & SF_HAS_EVAL))
571                     data->flags |= SF_HAS_EVAL;
572               optimize_curly_tail:
573 #ifdef REGALIGN
574                 if (OP(oscan) != CURLYX) {
575                     while (regkind[(U8)OP(next = regnext(oscan))] == NOTHING
576                            && NEXT_OFF(next))
577                         NEXT_OFF(oscan) += NEXT_OFF(next);
578                 }
579 #endif
580                 continue;
581             default:                    /* REF only? */
582                 if (flags & SCF_DO_SUBSTR) {
583                     scan_commit(data);
584                     data->longest = &(data->longest_float);
585                 }
586                 is_inf = 1;
587                 break;
588             }
589         } else if (strchr(simple,OP(scan))) {
590             if (flags & SCF_DO_SUBSTR) {
591                 scan_commit(data);
592                 data->pos_min++;
593             }
594             min++;
595         } else if (regkind[(U8)OP(scan)] == EOL && flags & SCF_DO_SUBSTR) {
596             data->flags |= (OP(scan) == MEOL
597                             ? SF_BEFORE_MEOL
598                             : SF_BEFORE_SEOL);
599         } else if (regkind[(U8)OP(scan)] == BRANCHJ
600                    && (scan->flags || data)
601                    && (OP(scan) == IFMATCH || OP(scan) == UNLESSM)) {
602             I32 deltanext, minnext;
603             regnode *nscan;
604
605             data_fake.flags = 0;
606             next = regnext(scan);
607             nscan = NEXTOPER(NEXTOPER(scan));
608             minnext = study_chunk(&nscan, &deltanext, last, &data_fake, 0);
609             if (scan->flags) {
610                 if (deltanext) {
611                     FAIL("variable length lookbehind not implemented");
612                 } else if (minnext > U8_MAX) {
613                     FAIL2("lookbehind longer than %d not implemented", U8_MAX);
614                 }
615                 scan->flags = minnext;
616             }
617             if (data && data_fake.flags & (SF_HAS_PAR|SF_IN_PAR))
618                 pars++;
619             if (data && (data_fake.flags & SF_HAS_EVAL))
620                 data->flags |= SF_HAS_EVAL;
621         } else if (OP(scan) == OPEN) {
622             pars++;
623         } else if (OP(scan) == CLOSE && ARG(scan) == is_par) {
624 #ifdef REGALIGN_STRUCT
625             next = regnext(scan);
626
627             if ( next && (OP(next) != WHILEM) && next < last)
628 #endif 
629                 is_par = 0;             /* Disable optimization */
630         } else if (OP(scan) == EVAL) {
631                 if (data)
632                     data->flags |= SF_HAS_EVAL;
633         }
634         /* Else: zero-length, ignore. */
635         scan = regnext(scan);
636     }
637
638   finish:
639     *scanp = scan;
640     *deltap = is_inf ? I32_MAX : delta;
641     if (flags & SCF_DO_SUBSTR && is_inf) 
642         data->pos_delta = I32_MAX - data->pos_min;
643     if (is_par > U8_MAX)
644         is_par = 0;
645     if (is_par && pars==1 && data) {
646         data->flags |= SF_IN_PAR;
647         data->flags &= ~SF_HAS_PAR;
648     } else if (pars && data) {
649         data->flags |= SF_HAS_PAR;
650         data->flags &= ~SF_IN_PAR;
651     }
652     return min;
653 }
654
655 STATIC I32
656 add_data(I32 n, char *s)
657 {
658     if (rx->data) {
659         Renewc(rx->data, 
660                sizeof(*rx->data) + sizeof(void*) * (rx->data->count + n - 1), 
661                char, struct reg_data);
662         Renew(rx->data->what, rx->data->count + n, U8);
663         rx->data->count += n;
664     } else {
665         Newc(1207, rx->data, sizeof(*rx->data) + sizeof(void*) * (n - 1),
666              char, struct reg_data);
667         New(1208, rx->data->what, n, U8);
668         rx->data->count = n;
669     }
670     Copy(s, rx->data->what + rx->data->count - n, n, U8);
671     return rx->data->count - n;
672 }
673
674 /*
675  - pregcomp - compile a regular expression into internal code
676  *
677  * We can't allocate space until we know how big the compiled form will be,
678  * but we can't compile it (and thus know how big it is) until we've got a
679  * place to put the code.  So we cheat:  we compile it twice, once with code
680  * generation turned off and size counting turned on, and once "for real".
681  * This also means that we don't allocate space until we are sure that the
682  * thing really will compile successfully, and we never have to move the
683  * code and thus invalidate pointers into it.  (Note that it has to be in
684  * one piece because free() must be able to free it all.) [NB: not true in perl]
685  *
686  * Beware that the optimization-preparation code in here knows about some
687  * of the structure of the compiled regexp.  [I'll say.]
688  */
689 regexp *
690 pregcomp(char *exp, char *xend, PMOP *pm)
691 {
692     register regexp *r;
693     regnode *scan;
694     SV **longest;
695     SV *longest_fixed;
696     SV *longest_float;
697     regnode *first;
698     I32 flags;
699     I32 minlen = 0;
700     I32 sawplus = 0;
701     I32 sawopen = 0;
702
703     if (exp == NULL)
704         FAIL("NULL regexp argument");
705
706     regprecomp = savepvn(exp, xend - exp);
707     DEBUG_r(PerlIO_printf(Perl_debug_log, "compiling RE `%*s'\n",
708                           xend - exp, regprecomp));
709     regflags = pm->op_pmflags;
710     regsawback = 0;
711
712     regseen = 0;
713     seen_zerolen = *exp == '^' ? -1 : 0;
714     extralen = 0;
715
716     /* First pass: determine size, legality. */
717     regparse = exp;
718     regxend = xend;
719     regnaughty = 0;
720     regnpar = 1;
721     regsize = 0L;
722     regcode = &regdummy;
723     regc((U8)MAGIC, (char*)regcode);
724     if (reg(0, &flags) == NULL) {
725         Safefree(regprecomp);
726         regprecomp = Nullch;
727         return(NULL);
728     }
729     DEBUG_r(PerlIO_printf(Perl_debug_log, "size %d ", regsize));
730
731     DEBUG_r(
732         if (!colorset) {
733             int i = 0;
734             char *s = PerlEnv_getenv("TERMCAP_COLORS");
735             
736             colorset = 1;
737             if (s) {
738                 colors[0] = s = savepv(s);
739                 while (++i < 4) {
740                     s = strchr(s, '\t');
741                     if (!s) 
742                         FAIL("Not enough TABs in TERMCAP_COLORS");
743                     *s = '\0';
744                     colors[i] = ++s;
745                 }
746             } else {
747                 while (i < 4) 
748                     colors[i++] = "";
749             }
750             /* Reset colors: */
751             PerlIO_printf(Perl_debug_log, "%s%s%s%s", 
752                           colors[0],colors[1],colors[2],colors[3]);
753         }
754         );
755
756     /* Small enough for pointer-storage convention?
757        If extralen==0, this means that we will not need long jumps. */
758 #ifndef REGALIGN_STRUCT
759     if (regsize >= 0x10000L && extralen)
760         FAIL("regexp too big");
761 #else
762     if (regsize >= 0x10000L && extralen)
763         regsize += extralen;
764     else
765         extralen = 0;
766 #endif 
767
768     /* Allocate space and initialize. */
769     Newc(1001, r, sizeof(regexp) + (unsigned)regsize * sizeof(regnode),
770          char, regexp);
771     if (r == NULL)
772         FAIL("regexp out of space");
773     r->refcnt = 1;
774     r->prelen = xend - exp;
775     r->precomp = regprecomp;
776     r->subbeg = r->subbase = NULL;
777     rx = r;
778
779     /* Second pass: emit code. */
780     regparse = exp;
781     regxend = xend;
782     regnaughty = 0;
783     regnpar = 1;
784     regcode = r->program;
785     regc((U8)MAGIC, (char*) regcode++);
786     r->data = 0;
787     if (reg(0, &flags) == NULL)
788         return(NULL);
789
790     /* Dig out information for optimizations. */
791     pm->op_pmflags = regflags;
792     r->reganch = 0;
793     r->regstclass = NULL;
794     r->naughty = regnaughty >= 10;      /* Probably an expensive pattern. */
795     scan = r->program + 1;              /* First BRANCH. */
796
797     /* XXXX To minimize changes to RE engine we always allocate
798        3-units-long substrs field. */
799     Newz(1004, r->substrs, 1, struct reg_substr_data);
800
801     if (OP(scan) != BRANCH) {   /* Only one top-level choice. */
802         scan_data_t data;
803         I32 fake;
804         STRLEN longest_float_length, longest_fixed_length;
805
806         StructCopy(&zero_scan_data, &data, scan_data_t);
807         first = scan;
808         /* Skip introductions and multiplicators >= 1. */
809         while ((OP(first) == OPEN && (sawopen = 1)) ||
810             (OP(first) == BRANCH && OP(regnext(first)) != BRANCH) ||
811             (OP(first) == PLUS) ||
812             (OP(first) == MINMOD) ||
813             (regkind[(U8)OP(first)] == CURLY && ARG1(first) > 0) ) {
814                 if (OP(first) == PLUS)
815                     sawplus = 1;
816                 else
817                     first += regarglen[(U8)OP(first)];
818                 first = NEXTOPER(first);
819         }
820
821         /* Starting-point info. */
822       again:
823         if (OP(first) == EXACT);        /* Empty, get anchored substr later. */
824         else if (strchr(simple+2,OP(first)))
825             r->regstclass = first;
826         else if (regkind[(U8)OP(first)] == BOUND ||
827                  regkind[(U8)OP(first)] == NBOUND)
828             r->regstclass = first;
829         else if (regkind[(U8)OP(first)] == BOL) {
830             r->reganch |= (OP(first) == MBOL ? ROPT_ANCH_MBOL: ROPT_ANCH_BOL);
831             first = NEXTOPER(first);
832             goto again;
833         }
834         else if (OP(first) == GPOS) {
835             r->reganch |= ROPT_ANCH_GPOS;
836             first = NEXTOPER(first);
837             goto again;
838         }
839         else if ((OP(first) == STAR &&
840             regkind[(U8)OP(NEXTOPER(first))] == ANY) &&
841             !(r->reganch & ROPT_ANCH) )
842         {
843             /* turn .* into ^.* with an implied $*=1 */
844             r->reganch |= ROPT_ANCH_BOL | ROPT_IMPLICIT;
845             first = NEXTOPER(first);
846             goto again;
847         }
848         if (sawplus && (!sawopen || !regsawback))
849             r->reganch |= ROPT_SKIP;    /* x+ must match 1st of run */
850
851         /* Scan is after the zeroth branch, first is atomic matcher. */
852         DEBUG_r(PerlIO_printf(Perl_debug_log, "first at %d\n", 
853                               first - scan + 1));
854         /*
855         * If there's something expensive in the r.e., find the
856         * longest literal string that must appear and make it the
857         * regmust.  Resolve ties in favor of later strings, since
858         * the regstart check works with the beginning of the r.e.
859         * and avoiding duplication strengthens checking.  Not a
860         * strong reason, but sufficient in the absence of others.
861         * [Now we resolve ties in favor of the earlier string if
862         * it happens that c_offset_min has been invalidated, since the
863         * earlier string may buy us something the later one won't.]
864         */
865         minlen = 0;
866
867         data.longest_fixed = newSVpv("",0);
868         data.longest_float = newSVpv("",0);
869         data.last_found = newSVpv("",0);
870         data.longest = &(data.longest_fixed);
871         first = scan;
872         
873         minlen = study_chunk(&first, &fake, scan + regsize, /* Up to end */
874                              &data, SCF_DO_SUBSTR);
875         if ( regnpar == 1 && data.longest == &(data.longest_fixed)
876              && data.last_start_min == 0 && data.last_end > 0 
877              && !seen_zerolen
878              && (!(regseen & REG_SEEN_GPOS) || (r->reganch & ROPT_ANCH_GPOS)))
879             r->reganch |= ROPT_CHECK_ALL;
880         scan_commit(&data);
881         SvREFCNT_dec(data.last_found);
882
883         longest_float_length = SvCUR(data.longest_float);
884         if (longest_float_length
885             || (data.flags & SF_FL_BEFORE_EOL
886                 && (!(data.flags & SF_FL_BEFORE_MEOL)
887                     || (regflags & PMf_MULTILINE)))) {
888             if (SvCUR(data.longest_fixed) 
889                 && data.offset_fixed == data.offset_float_min)
890                 goto remove;            /* Like in (a)+. */
891             
892             r->float_substr = data.longest_float;
893             r->float_min_offset = data.offset_float_min;
894             r->float_max_offset = data.offset_float_max;
895             fbm_compile(r->float_substr, 0);
896             BmUSEFUL(r->float_substr) = 100;
897             if (data.flags & SF_FL_BEFORE_EOL /* Cannot have SEOL and MULTI */
898                 && (!(data.flags & SF_FL_BEFORE_MEOL)
899                     || (regflags & PMf_MULTILINE))) 
900                 SvTAIL_on(r->float_substr);
901         } else {
902           remove:
903             r->float_substr = Nullsv;
904             SvREFCNT_dec(data.longest_float);
905             longest_float_length = 0;
906         }
907
908         longest_fixed_length = SvCUR(data.longest_fixed);
909         if (longest_fixed_length
910             || (data.flags & SF_FIX_BEFORE_EOL /* Cannot have SEOL and MULTI */
911                 && (!(data.flags & SF_FIX_BEFORE_MEOL)
912                     || (regflags & PMf_MULTILINE)))) {
913             r->anchored_substr = data.longest_fixed;
914             r->anchored_offset = data.offset_fixed;
915             fbm_compile(r->anchored_substr, 0);
916             BmUSEFUL(r->anchored_substr) = 100;
917             if (data.flags & SF_FIX_BEFORE_EOL /* Cannot have SEOL and MULTI */
918                 && (!(data.flags & SF_FIX_BEFORE_MEOL)
919                     || (regflags & PMf_MULTILINE)))
920                 SvTAIL_on(r->anchored_substr);
921         } else {
922             r->anchored_substr = Nullsv;
923             SvREFCNT_dec(data.longest_fixed);
924             longest_fixed_length = 0;
925         }
926
927         /* A temporary algorithm prefers floated substr to fixed one to dig more info. */
928         if (longest_fixed_length > longest_float_length) {
929             r->check_substr = r->anchored_substr;
930             r->check_offset_min = r->check_offset_max = r->anchored_offset;
931             if (r->reganch & ROPT_ANCH_SINGLE)
932                 r->reganch |= ROPT_NOSCAN;
933         } else {
934             r->check_substr = r->float_substr;
935             r->check_offset_min = data.offset_float_min;
936             r->check_offset_max = data.offset_float_max;
937         }
938     } else {
939         /* Several toplevels. Best we can is to set minlen. */
940         I32 fake;
941         
942         DEBUG_r(PerlIO_printf(Perl_debug_log, "\n"));
943         scan = r->program + 1;
944         minlen = study_chunk(&scan, &fake, scan + regsize, NULL, 0);
945         r->check_substr = r->anchored_substr = r->float_substr = Nullsv;
946     }
947
948     r->nparens = regnpar - 1;
949     r->minlen = minlen;
950     if (regseen & REG_SEEN_GPOS) 
951         r->reganch |= ROPT_GPOS_SEEN;
952     if (regseen & REG_SEEN_LOOKBEHIND)
953         r->reganch |= ROPT_LOOKBEHIND_SEEN;
954     Newz(1002, r->startp, regnpar, char*);
955     Newz(1002, r->endp, regnpar, char*);
956     DEBUG_r(regdump(r));
957     return(r);
958 }
959
960 /*
961  - reg - regular expression, i.e. main body or parenthesized thing
962  *
963  * Caller must absorb opening parenthesis.
964  *
965  * Combining parenthesis handling with the base level of regular expression
966  * is a trifle forced, but the need to tie the tails of the branches to what
967  * follows makes it hard to avoid.
968  */
969 STATIC regnode *
970 reg(I32 paren, I32 *flagp)
971     /* paren: Parenthesized? 0=top, 1=(, inside: changed to letter. */
972 {
973     register regnode *ret;              /* Will be the head of the group. */
974     register regnode *br;
975     register regnode *lastbr;
976     register regnode *ender = 0;
977     register I32 parno = 0;
978     I32 flags, oregflags = regflags, have_branch = 0, open = 0;
979     char c;
980
981     *flagp = HASWIDTH;  /* Tentatively. */
982
983     /* Make an OPEN node, if parenthesized. */
984     if (paren) {
985         if (*regparse == '?') {
986             regparse++;
987             paren = *regparse++;
988             ret = NULL;                 /* For look-ahead/behind. */
989             switch (paren) {
990             case '<':
991 #ifndef REGALIGN_STRUCT
992                 FAIL("lookbehind non-implemented without REGALIGN_STRUCT");
993 #endif 
994                 regseen |= REG_SEEN_LOOKBEHIND;
995                 if (*regparse == '!') 
996                     paren = ',';
997                 if (*regparse != '=' && *regparse != '!') 
998                     goto unknown;
999                 regparse++;
1000             case '=':
1001             case '!':
1002                 seen_zerolen++;
1003             case ':':
1004             case '>':
1005                 break;
1006             case '$':
1007             case '@':
1008                 FAIL2("Sequence (?%c...) not implemented", (int)paren);
1009                 break;
1010             case '#':
1011                 while (*regparse && *regparse != ')')
1012                     regparse++;
1013                 if (*regparse != ')')
1014                     FAIL("Sequence (?#... not terminated");
1015                 nextchar();
1016                 *flagp = TRYAGAIN;
1017                 return NULL;
1018             case '{':
1019             {
1020                 dTHR;
1021                 I32 count = 1, n = 0;
1022                 char c;
1023                 char *s = regparse;
1024                 SV *sv;
1025                 OP_4tree *sop, *rop;
1026
1027                 seen_zerolen++;
1028                 while (count && (c = *regparse)) {
1029                     if (c == '\\' && regparse[1])
1030                         regparse++;
1031                     else if (c == '{') 
1032                         count++;
1033                     else if (c == '}') 
1034                         count--;
1035                     regparse++;
1036                 }
1037                 if (*regparse != ')')
1038                     FAIL("Sequence (?{...}) not terminated or not {}-balanced");
1039                 if (!SIZE_ONLY) {
1040                     AV *av;
1041                     
1042                     if (regparse - 1 - s) 
1043                         sv = newSVpv(s, regparse - 1 - s);
1044                     else
1045                         sv = newSVpv("", 0);
1046
1047                     rop = sv_compile_2op(sv, &sop, "re", &av);
1048
1049                     n = add_data(3, "nso");
1050                     rx->data->data[n] = (void*)rop;
1051                     rx->data->data[n+1] = (void*)av;
1052                     rx->data->data[n+2] = (void*)sop;
1053                     SvREFCNT_dec(sv);
1054                 } else {                /* First pass */
1055                     if (tainted)
1056                         FAIL("Eval-group in insecure regular expression");
1057                 }
1058                 
1059                 nextchar();
1060                 return reganode(EVAL, n);
1061             }
1062             case '(':
1063             {
1064                 if (regparse[0] == '?') {
1065                     if (regparse[1] == '=' || regparse[1] == '!' 
1066                         || regparse[1] == '<' 
1067                         || regparse[1] == '{') { /* Lookahead or eval. */
1068                         I32 flag;
1069                         
1070                         ret = reg_node(LOGICAL);
1071                         regtail(ret, reg(1, &flag));
1072                         goto insert_if;
1073                     } 
1074                 } else if (regparse[0] >= '1' && regparse[0] <= '9' ) {
1075                     parno = atoi(regparse++);
1076
1077                     while (isDIGIT(*regparse))
1078                         regparse++;
1079                     ret = reganode(GROUPP, parno);
1080                     if ((c = *nextchar()) != ')')
1081                         FAIL2("Switch (?(number%c not recognized", c);
1082                   insert_if:
1083                     regtail(ret, reganode(IFTHEN, 0));
1084                     br = regbranch(&flags, 1);
1085                     if (br == NULL)
1086                         br = reganode(LONGJMP, 0);
1087                     else
1088                         regtail(br, reganode(LONGJMP, 0));
1089                     c = *nextchar();
1090                     if (c == '|') {
1091                         lastbr = reganode(IFTHEN, 0); /* Fake one for optimizer. */
1092                         regbranch(&flags, 1);
1093                         regtail(ret, lastbr);
1094                         c = *nextchar();
1095                     } else
1096                         lastbr = NULL;
1097                     if (c != ')')
1098                         FAIL("Switch (?(condition)... contains too many branches");
1099                     ender = reg_node(TAIL);
1100                     regtail(br, ender);
1101                     if (lastbr) {
1102                         regtail(lastbr, ender);
1103                         regtail(NEXTOPER(NEXTOPER(lastbr)), ender);
1104                     } else
1105                         regtail(ret, ender);
1106                     return ret;
1107                 } else {
1108                     FAIL2("Unknown condition for (?(%.2s", regparse);
1109                 }
1110             }
1111             case 0:
1112                 FAIL("Sequence (? incomplete");
1113                 break;
1114             default:
1115                 --regparse;
1116                 while (*regparse && strchr("iogcmsx", *regparse))
1117                     pmflag(&regflags, *regparse++);
1118               unknown:
1119                 if (*regparse != ')')
1120                     FAIL2("Sequence (?%c...) not recognized", *regparse);
1121                 nextchar();
1122                 *flagp = TRYAGAIN;
1123                 return NULL;
1124             }
1125         }
1126         else {
1127             parno = regnpar;
1128             regnpar++;
1129             ret = reganode(OPEN, parno);
1130             open = 1;
1131         }
1132     } else
1133         ret = NULL;
1134
1135     /* Pick up the branches, linking them together. */
1136     br = regbranch(&flags, 1);
1137     if (br == NULL)
1138         return(NULL);
1139     if (*regparse == '|') {
1140         if (!SIZE_ONLY && extralen) {
1141             reginsert(BRANCHJ, br);
1142         } else
1143             reginsert(BRANCH, br);
1144         have_branch = 1;
1145         if (SIZE_ONLY)
1146             extralen += 1;              /* For BRANCHJ-BRANCH. */
1147     } else if (paren == ':') {
1148         *flagp |= flags&SIMPLE;
1149     }
1150     if (open) {                         /* Starts with OPEN. */
1151         regtail(ret, br);               /* OPEN -> first. */
1152     } else if (paren != '?')            /* Not Conditional */
1153         ret = br;
1154     if (!(flags&HASWIDTH))
1155         *flagp &= ~HASWIDTH;
1156     *flagp |= flags&SPSTART;
1157     lastbr = br;
1158     while (*regparse == '|') {
1159         if (!SIZE_ONLY && extralen) {
1160             ender = reganode(LONGJMP,0);
1161             regtail(NEXTOPER(NEXTOPER(lastbr)), ender); /* Append to the previous. */
1162         }
1163         if (SIZE_ONLY)
1164             extralen += 2;              /* Account for LONGJMP. */
1165         nextchar();
1166         br = regbranch(&flags, 0);
1167         if (br == NULL)
1168             return(NULL);
1169         regtail(lastbr, br);            /* BRANCH -> BRANCH. */
1170         lastbr = br;
1171         if (!(flags&HASWIDTH))
1172             *flagp &= ~HASWIDTH;
1173         *flagp |= flags&SPSTART;
1174     }
1175
1176     if (have_branch || paren != ':') {
1177         /* Make a closing node, and hook it on the end. */
1178         switch (paren) {
1179         case ':':
1180             ender = reg_node(TAIL);
1181             break;
1182         case 1:
1183             ender = reganode(CLOSE, parno);
1184             break;
1185         case '<':
1186         case '>':
1187         case ',':
1188         case '=':
1189         case '!':
1190             ender = reg_node(SUCCEED);
1191             *flagp &= ~HASWIDTH;
1192             break;
1193         case 0:
1194             ender = reg_node(END);
1195             break;
1196         }
1197         regtail(lastbr, ender);
1198
1199         if (have_branch) {
1200             /* Hook the tails of the branches to the closing node. */
1201             for (br = ret; br != NULL; br = regnext(br)) {
1202                 regoptail(br, ender);
1203             }
1204         }
1205     }
1206
1207     {
1208         char *p;
1209         static char parens[] = "=!<,>";
1210
1211         if (paren && (p = strchr(parens, paren))) {
1212             int node = ((p - parens) % 2) ? UNLESSM : IFMATCH;
1213             int flag = (p - parens) > 1;
1214
1215             if (paren == '>')
1216                 node = SUSPEND, flag = 0;
1217             reginsert(node,ret);
1218 #ifdef REGALIGN_STRUCT
1219             ret->flags = flag;
1220 #endif 
1221             regtail(ret, reg_node(TAIL));
1222         }
1223     }
1224
1225     /* Check for proper termination. */
1226     if (paren && (regparse >= regxend || *nextchar() != ')')) {
1227         FAIL("unmatched () in regexp");
1228     } else if (!paren && regparse < regxend) {
1229         if (*regparse == ')') {
1230             FAIL("unmatched () in regexp");
1231         } else
1232             FAIL("junk on end of regexp");      /* "Can't happen". */
1233         /* NOTREACHED */
1234     }
1235     if (paren != 0) {
1236         regflags = oregflags;
1237     }
1238
1239     return(ret);
1240 }
1241
1242 /*
1243  - regbranch - one alternative of an | operator
1244  *
1245  * Implements the concatenation operator.
1246  */
1247 STATIC regnode *
1248 regbranch(I32 *flagp, I32 first)
1249 {
1250     register regnode *ret;
1251     register regnode *chain = NULL;
1252     register regnode *latest;
1253     I32 flags = 0, c = 0;
1254
1255     if (first) 
1256         ret = NULL;
1257     else {
1258         if (!SIZE_ONLY && extralen) 
1259             ret = reganode(BRANCHJ,0);
1260         else
1261             ret = reg_node(BRANCH);
1262     }
1263         
1264     if (!first && SIZE_ONLY) 
1265         extralen += 1;                  /* BRANCHJ */
1266     
1267     *flagp = WORST;                     /* Tentatively. */
1268
1269     regparse--;
1270     nextchar();
1271     while (regparse < regxend && *regparse != '|' && *regparse != ')') {
1272         flags &= ~TRYAGAIN;
1273         latest = regpiece(&flags);
1274         if (latest == NULL) {
1275             if (flags & TRYAGAIN)
1276                 continue;
1277             return(NULL);
1278         } else if (ret == NULL)
1279             ret = latest;
1280         *flagp |= flags&HASWIDTH;
1281         if (chain == NULL)      /* First piece. */
1282             *flagp |= flags&SPSTART;
1283         else {
1284             regnaughty++;
1285             regtail(chain, latest);
1286         }
1287         chain = latest;
1288         c++;
1289     }
1290     if (chain == NULL) {        /* Loop ran zero times. */
1291         chain = reg_node(NOTHING);
1292         if (ret == NULL)
1293             ret = chain;
1294     }
1295     if (c == 1) {
1296         *flagp |= flags&SIMPLE;
1297     }
1298
1299     return(ret);
1300 }
1301
1302 /*
1303  - regpiece - something followed by possible [*+?]
1304  *
1305  * Note that the branching code sequences used for ? and the general cases
1306  * of * and + are somewhat optimized:  they use the same NOTHING node as
1307  * both the endmarker for their branch list and the body of the last branch.
1308  * It might seem that this node could be dispensed with entirely, but the
1309  * endmarker role is not redundant.
1310  */
1311 STATIC regnode *
1312 regpiece(I32 *flagp)
1313 {
1314     register regnode *ret;
1315     register char op;
1316     register char *next;
1317     I32 flags;
1318     char *origparse = regparse;
1319     char *maxpos;
1320     I32 min;
1321     I32 max = REG_INFTY;
1322
1323     ret = regatom(&flags);
1324     if (ret == NULL) {
1325         if (flags & TRYAGAIN)
1326             *flagp |= TRYAGAIN;
1327         return(NULL);
1328     }
1329
1330     op = *regparse;
1331
1332     if (op == '{' && regcurly(regparse)) {
1333         next = regparse + 1;
1334         maxpos = Nullch;
1335         while (isDIGIT(*next) || *next == ',') {
1336             if (*next == ',') {
1337                 if (maxpos)
1338                     break;
1339                 else
1340                     maxpos = next;
1341             }
1342             next++;
1343         }
1344         if (*next == '}') {             /* got one */
1345             if (!maxpos)
1346                 maxpos = next;
1347             regparse++;
1348             min = atoi(regparse);
1349             if (*maxpos == ',')
1350                 maxpos++;
1351             else
1352                 maxpos = regparse;
1353             max = atoi(maxpos);
1354             if (!max && *maxpos != '0')
1355                 max = REG_INFTY;                /* meaning "infinity" */
1356             else if (max >= REG_INFTY)
1357                 FAIL2("Quantifier in {,} bigger than %d", REG_INFTY - 1);
1358             regparse = next;
1359             nextchar();
1360
1361         do_curly:
1362             if ((flags&SIMPLE)) {
1363                 regnaughty += 2 + regnaughty / 2;
1364                 reginsert(CURLY, ret);
1365             }
1366             else {
1367                 regnaughty += 4 + regnaughty;   /* compound interest */
1368                 regtail(ret, reg_node(WHILEM));
1369                 if (!SIZE_ONLY && extralen) {
1370                     reginsert(LONGJMP,ret);
1371                     reginsert(NOTHING,ret);
1372                     NEXT_OFF(ret) = 3;  /* Go over LONGJMP. */
1373                 }
1374                 reginsert(CURLYX,ret);
1375                 if (!SIZE_ONLY && extralen)
1376                     NEXT_OFF(ret) = 3;  /* Go over NOTHING to LONGJMP. */
1377                 regtail(ret, reg_node(NOTHING));
1378                 if (SIZE_ONLY)
1379                     extralen += 3;
1380             }
1381 #ifdef REGALIGN_STRUCT
1382             ret->flags = 0;
1383 #endif 
1384
1385             if (min > 0)
1386                 *flagp = (WORST|HASWIDTH);
1387             if (max && max < min)
1388                 FAIL("Can't do {n,m} with n > m");
1389             if (!SIZE_ONLY) {
1390                 ARG1_SET(ret, min);
1391                 ARG2_SET(ret, max);
1392             }
1393
1394             goto nest_check;
1395         }
1396     }
1397
1398     if (!ISMULT1(op)) {
1399         *flagp = flags;
1400         return(ret);
1401     }
1402
1403 #if 0                           /* Now runtime fix should be reliable. */
1404     if (!(flags&HASWIDTH) && op != '?')
1405       FAIL("regexp *+ operand could be empty");
1406 #endif 
1407
1408     nextchar();
1409
1410     *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
1411
1412     if (op == '*' && (flags&SIMPLE)) {
1413         reginsert(STAR, ret);
1414 #ifdef REGALIGN_STRUCT
1415         ret->flags = 0;
1416 #endif 
1417         regnaughty += 4;
1418     }
1419     else if (op == '*') {
1420         min = 0;
1421         goto do_curly;
1422     } else if (op == '+' && (flags&SIMPLE)) {
1423         reginsert(PLUS, ret);
1424 #ifdef REGALIGN_STRUCT
1425         ret->flags = 0;
1426 #endif 
1427         regnaughty += 3;
1428     }
1429     else if (op == '+') {
1430         min = 1;
1431         goto do_curly;
1432     } else if (op == '?') {
1433         min = 0; max = 1;
1434         goto do_curly;
1435     }
1436   nest_check:
1437     if (dowarn && !SIZE_ONLY && !(flags&HASWIDTH) && max > 10000) {
1438         warn("%.*s matches null string many times",
1439             regparse - origparse, origparse);
1440     }
1441
1442     if (*regparse == '?') {
1443         nextchar();
1444         reginsert(MINMOD, ret);
1445 #ifdef REGALIGN
1446         regtail(ret, ret + NODE_STEP_REGNODE);
1447 #else
1448         regtail(ret, ret + 3);
1449 #endif
1450     }
1451     if (ISMULT2(regparse))
1452         FAIL("nested *?+ in regexp");
1453
1454     return(ret);
1455 }
1456
1457 /*
1458  - regatom - the lowest level
1459  *
1460  * Optimization:  gobbles an entire sequence of ordinary characters so that
1461  * it can turn them into a single node, which is smaller to store and
1462  * faster to run.  Backslashed characters are exceptions, each becoming a
1463  * separate node; the code is simpler that way and it's not worth fixing.
1464  *
1465  * [Yes, it is worth fixing, some scripts can run twice the speed.]
1466  */
1467 STATIC regnode *
1468 regatom(I32 *flagp)
1469 {
1470     register regnode *ret = 0;
1471     I32 flags;
1472
1473     *flagp = WORST;             /* Tentatively. */
1474
1475 tryagain:
1476     switch (*regparse) {
1477     case '^':
1478         seen_zerolen++;
1479         nextchar();
1480         if (regflags & PMf_MULTILINE)
1481             ret = reg_node(MBOL);
1482         else if (regflags & PMf_SINGLELINE)
1483             ret = reg_node(SBOL);
1484         else
1485             ret = reg_node(BOL);
1486         break;
1487     case '$':
1488         if (regparse[1]) 
1489             seen_zerolen++;
1490         nextchar();
1491         if (regflags & PMf_MULTILINE)
1492             ret = reg_node(MEOL);
1493         else if (regflags & PMf_SINGLELINE)
1494             ret = reg_node(SEOL);
1495         else
1496             ret = reg_node(EOL);
1497         break;
1498     case '.':
1499         nextchar();
1500         if (regflags & PMf_SINGLELINE)
1501             ret = reg_node(SANY);
1502         else
1503             ret = reg_node(ANY);
1504         regnaughty++;
1505         *flagp |= HASWIDTH|SIMPLE;
1506         break;
1507     case '[':
1508         regparse++;
1509         ret = regclass();
1510         *flagp |= HASWIDTH|SIMPLE;
1511         break;
1512     case '(':
1513         nextchar();
1514         ret = reg(1, &flags);
1515         if (ret == NULL) {
1516                 if (flags & TRYAGAIN)
1517                     goto tryagain;
1518                 return(NULL);
1519         }
1520         *flagp |= flags&(HASWIDTH|SPSTART|SIMPLE);
1521         break;
1522     case '|':
1523     case ')':
1524         if (flags & TRYAGAIN) {
1525             *flagp |= TRYAGAIN;
1526             return NULL;
1527         }
1528         FAIL2("internal urp in regexp at /%s/", regparse);
1529                                 /* Supposed to be caught earlier. */
1530         break;
1531     case '{':
1532         if (!regcurly(regparse)) {
1533             regparse++;
1534             goto defchar;
1535         }
1536         /* FALL THROUGH */
1537     case '?':
1538     case '+':
1539     case '*':
1540         FAIL("?+*{} follows nothing in regexp");
1541         break;
1542     case '\\':
1543         switch (*++regparse) {
1544         case 'A':
1545             seen_zerolen++;
1546             ret = reg_node(SBOL);
1547             *flagp |= SIMPLE;
1548             nextchar();
1549             break;
1550         case 'G':
1551             ret = reg_node(GPOS);
1552             regseen |= REG_SEEN_GPOS;
1553             *flagp |= SIMPLE;
1554             nextchar();
1555             break;
1556         case 'Z':
1557             ret = reg_node(SEOL);
1558             *flagp |= SIMPLE;
1559             nextchar();
1560             break;
1561         case 'w':
1562             ret = reg_node((regflags & PMf_LOCALE) ? ALNUML : ALNUM);
1563             *flagp |= HASWIDTH|SIMPLE;
1564             nextchar();
1565             break;
1566         case 'W':
1567             ret = reg_node((regflags & PMf_LOCALE) ? NALNUML : NALNUM);
1568             *flagp |= HASWIDTH|SIMPLE;
1569             nextchar();
1570             break;
1571         case 'b':
1572             seen_zerolen++;
1573             ret = reg_node((regflags & PMf_LOCALE) ? BOUNDL : BOUND);
1574             *flagp |= SIMPLE;
1575             nextchar();
1576             break;
1577         case 'B':
1578             seen_zerolen++;
1579             ret = reg_node((regflags & PMf_LOCALE) ? NBOUNDL : NBOUND);
1580             *flagp |= SIMPLE;
1581             nextchar();
1582             break;
1583         case 's':
1584             ret = reg_node((regflags & PMf_LOCALE) ? SPACEL : SPACE);
1585             *flagp |= HASWIDTH|SIMPLE;
1586             nextchar();
1587             break;
1588         case 'S':
1589             ret = reg_node((regflags & PMf_LOCALE) ? NSPACEL : NSPACE);
1590             *flagp |= HASWIDTH|SIMPLE;
1591             nextchar();
1592             break;
1593         case 'd':
1594             ret = reg_node(DIGIT);
1595             *flagp |= HASWIDTH|SIMPLE;
1596             nextchar();
1597             break;
1598         case 'D':
1599             ret = reg_node(NDIGIT);
1600             *flagp |= HASWIDTH|SIMPLE;
1601             nextchar();
1602             break;
1603         case 'n':
1604         case 'r':
1605         case 't':
1606         case 'f':
1607         case 'e':
1608         case 'a':
1609         case 'x':
1610         case 'c':
1611         case '0':
1612             goto defchar;
1613         case '1': case '2': case '3': case '4':
1614         case '5': case '6': case '7': case '8': case '9':
1615             {
1616                 I32 num = atoi(regparse);
1617
1618                 if (num > 9 && num >= regnpar)
1619                     goto defchar;
1620                 else {
1621                     regsawback = 1;
1622                     ret = reganode((regflags & PMf_FOLD)
1623                                    ? ((regflags & PMf_LOCALE) ? REFFL : REFF)
1624                                    : REF, num);
1625                     *flagp |= HASWIDTH;
1626                     while (isDIGIT(*regparse))
1627                         regparse++;
1628                     regparse--;
1629                     nextchar();
1630                 }
1631             }
1632             break;
1633         case '\0':
1634             if (regparse >= regxend)
1635                 FAIL("trailing \\ in regexp");
1636             /* FALL THROUGH */
1637         default:
1638             goto defchar;
1639         }
1640         break;
1641
1642     case '#':
1643         if (regflags & PMf_EXTENDED) {
1644             while (regparse < regxend && *regparse != '\n') regparse++;
1645             if (regparse < regxend)
1646                 goto tryagain;
1647         }
1648         /* FALL THROUGH */
1649
1650     default: {
1651             register I32 len;
1652             register U8 ender;
1653             register char *p;
1654             char *oldp, *s;
1655             I32 numlen;
1656
1657             regparse++;
1658
1659         defchar:
1660             ret = reg_node((regflags & PMf_FOLD)
1661                           ? ((regflags & PMf_LOCALE) ? EXACTFL : EXACTF)
1662                           : EXACT);
1663             s = (char *) OPERAND(ret);
1664             regc(0, s++);               /* save spot for len */
1665             for (len = 0, p = regparse - 1;
1666               len < 127 && p < regxend;
1667               len++)
1668             {
1669                 oldp = p;
1670
1671                 if (regflags & PMf_EXTENDED)
1672                     p = regwhite(p, regxend);
1673                 switch (*p) {
1674                 case '^':
1675                 case '$':
1676                 case '.':
1677                 case '[':
1678                 case '(':
1679                 case ')':
1680                 case '|':
1681                     goto loopdone;
1682                 case '\\':
1683                     switch (*++p) {
1684                     case 'A':
1685                     case 'G':
1686                     case 'Z':
1687                     case 'w':
1688                     case 'W':
1689                     case 'b':
1690                     case 'B':
1691                     case 's':
1692                     case 'S':
1693                     case 'd':
1694                     case 'D':
1695                         --p;
1696                         goto loopdone;
1697                     case 'n':
1698                         ender = '\n';
1699                         p++;
1700                         break;
1701                     case 'r':
1702                         ender = '\r';
1703                         p++;
1704                         break;
1705                     case 't':
1706                         ender = '\t';
1707                         p++;
1708                         break;
1709                     case 'f':
1710                         ender = '\f';
1711                         p++;
1712                         break;
1713                     case 'e':
1714                         ender = '\033';
1715                         p++;
1716                         break;
1717                     case 'a':
1718                         ender = '\007';
1719                         p++;
1720                         break;
1721                     case 'x':
1722                         ender = scan_hex(++p, 2, &numlen);
1723                         p += numlen;
1724                         break;
1725                     case 'c':
1726                         p++;
1727                         ender = UCHARAT(p++);
1728                         ender = toCTRL(ender);
1729                         break;
1730                     case '0': case '1': case '2': case '3':case '4':
1731                     case '5': case '6': case '7': case '8':case '9':
1732                         if (*p == '0' ||
1733                           (isDIGIT(p[1]) && atoi(p) >= regnpar) ) {
1734                             ender = scan_oct(p, 3, &numlen);
1735                             p += numlen;
1736                         }
1737                         else {
1738                             --p;
1739                             goto loopdone;
1740                         }
1741                         break;
1742                     case '\0':
1743                         if (p >= regxend)
1744                             FAIL("trailing \\ in regexp");
1745                         /* FALL THROUGH */
1746                     default:
1747                         ender = *p++;
1748                         break;
1749                     }
1750                     break;
1751                 default:
1752                     ender = *p++;
1753                     break;
1754                 }
1755                 if (regflags & PMf_EXTENDED)
1756                     p = regwhite(p, regxend);
1757                 if (ISMULT2(p)) { /* Back off on ?+*. */
1758                     if (len)
1759                         p = oldp;
1760                     else {
1761                         len++;
1762                         regc(ender, s++);
1763                     }
1764                     break;
1765                 }
1766                 regc(ender, s++);
1767             }
1768         loopdone:
1769             regparse = p - 1;
1770             nextchar();
1771             if (len < 0)
1772                 FAIL("internal disaster in regexp");
1773             if (len > 0)
1774                 *flagp |= HASWIDTH;
1775             if (len == 1)
1776                 *flagp |= SIMPLE;
1777             if (!SIZE_ONLY)
1778                 *OPERAND(ret) = len;
1779             regc('\0', s++);
1780             if (SIZE_ONLY) {
1781 #ifdef REGALIGN_STRUCT
1782                 regsize += (len + 2 + sizeof(regnode) - 1) / sizeof(regnode);
1783 #endif 
1784             } else {
1785                 regcode += (len + 2 + sizeof(regnode) - 1) / sizeof(regnode);
1786             }
1787         }
1788         break;
1789     }
1790
1791     return(ret);
1792 }
1793
1794 static char *
1795 regwhite(char *p, char *e)
1796 {
1797     while (p < e) {
1798         if (isSPACE(*p))
1799             ++p;
1800         else if (*p == '#') {
1801             do {
1802                 p++;
1803             } while (p < e && *p != '\n');
1804         }
1805         else
1806             break;
1807     }
1808     return p;
1809 }
1810
1811 STATIC void
1812 regset(char *opnd, register I32 c)
1813 {
1814     if (SIZE_ONLY)
1815         return;
1816     c &= 0xFF;
1817     opnd[1 + (c >> 3)] |= (1 << (c & 7));
1818 }
1819
1820 STATIC regnode *
1821 regclass(void)
1822 {
1823     register char *opnd, *s;
1824     register I32 Class;
1825     register I32 lastclass = 1234;
1826     register I32 range = 0;
1827     register regnode *ret;
1828     register I32 def;
1829     I32 numlen;
1830
1831     s = opnd = (char *) OPERAND(regcode);
1832     ret = reg_node(ANYOF);
1833     for (Class = 0; Class < 33; Class++)
1834         regc(0, s++);
1835     if (*regparse == '^') {     /* Complement of range. */
1836         regnaughty++;
1837         regparse++;
1838         if (!SIZE_ONLY)
1839             *opnd |= ANYOF_INVERT;
1840     }
1841     if (!SIZE_ONLY) {
1842         regcode += ANY_SKIP;
1843         if (regflags & PMf_FOLD)
1844             *opnd |= ANYOF_FOLD;
1845         if (regflags & PMf_LOCALE)
1846             *opnd |= ANYOF_LOCALE;
1847     } else {
1848         regsize += ANY_SKIP;
1849     }
1850     if (*regparse == ']' || *regparse == '-')
1851         goto skipcond;          /* allow 1st char to be ] or - */
1852     while (regparse < regxend && *regparse != ']') {
1853        skipcond:
1854         Class = UCHARAT(regparse++);
1855         if (Class == '[' && regparse + 1 < regxend &&
1856             /* I smell either [: or [= or [. -- POSIX has been here, right? */
1857             (*regparse == ':' || *regparse == '=' || *regparse == '.')) {
1858             char  posixccc = *regparse;
1859             char* posixccs = regparse++;
1860             
1861             while (regparse < regxend && *regparse != posixccc)
1862                 regparse++;
1863             if (regparse == regxend)
1864                 /* Grandfather lone [:, [=, [. */
1865                 regparse = posixccs;
1866             else {
1867                 regparse++; /* skip over the posixccc */
1868                 if (*regparse == ']') {
1869                     /* Not Implemented Yet.
1870                      * (POSIX Extended Character Classes, that is)
1871                      * The text between e.g. [: and :] would start
1872                      * at posixccs + 1 and stop at regparse - 2. */
1873                     if (dowarn && !SIZE_ONLY)
1874                         warn("Character class syntax [%c %c] is reserved for future extensions", posixccc, posixccc);
1875                     regparse++; /* skip over the ending ] */
1876                 }
1877             }
1878         }
1879         if (Class == '\\') {
1880             Class = UCHARAT(regparse++);
1881             switch (Class) {
1882             case 'w':
1883                 if (regflags & PMf_LOCALE) {
1884                     if (!SIZE_ONLY)
1885                         *opnd |= ANYOF_ALNUML;
1886                 }
1887                 else {
1888                     for (Class = 0; Class < 256; Class++)
1889                         if (isALNUM(Class))
1890                             regset(opnd, Class);
1891                 }
1892                 lastclass = 1234;
1893                 continue;
1894             case 'W':
1895                 if (regflags & PMf_LOCALE) {
1896                     if (!SIZE_ONLY)
1897                         *opnd |= ANYOF_NALNUML;
1898                 }
1899                 else {
1900                     for (Class = 0; Class < 256; Class++)
1901                         if (!isALNUM(Class))
1902                             regset(opnd, Class);
1903                 }
1904                 lastclass = 1234;
1905                 continue;
1906             case 's':
1907                 if (regflags & PMf_LOCALE) {
1908                     if (!SIZE_ONLY)
1909                         *opnd |= ANYOF_SPACEL;
1910                 }
1911                 else {
1912                     for (Class = 0; Class < 256; Class++)
1913                         if (isSPACE(Class))
1914                             regset(opnd, Class);
1915                 }
1916                 lastclass = 1234;
1917                 continue;
1918             case 'S':
1919                 if (regflags & PMf_LOCALE) {
1920                     if (!SIZE_ONLY)
1921                         *opnd |= ANYOF_NSPACEL;
1922                 }
1923                 else {
1924                     for (Class = 0; Class < 256; Class++)
1925                         if (!isSPACE(Class))
1926                             regset(opnd, Class);
1927                 }
1928                 lastclass = 1234;
1929                 continue;
1930             case 'd':
1931                 for (Class = '0'; Class <= '9'; Class++)
1932                     regset(opnd, Class);
1933                 lastclass = 1234;
1934                 continue;
1935             case 'D':
1936                 for (Class = 0; Class < '0'; Class++)
1937                     regset(opnd, Class);
1938                 for (Class = '9' + 1; Class < 256; Class++)
1939                     regset(opnd, Class);
1940                 lastclass = 1234;
1941                 continue;
1942             case 'n':
1943                 Class = '\n';
1944                 break;
1945             case 'r':
1946                 Class = '\r';
1947                 break;
1948             case 't':
1949                 Class = '\t';
1950                 break;
1951             case 'f':
1952                 Class = '\f';
1953                 break;
1954             case 'b':
1955                 Class = '\b';
1956                 break;
1957             case 'e':
1958                 Class = '\033';
1959                 break;
1960             case 'a':
1961                 Class = '\007';
1962                 break;
1963             case 'x':
1964                 Class = scan_hex(regparse, 2, &numlen);
1965                 regparse += numlen;
1966                 break;
1967             case 'c':
1968                 Class = UCHARAT(regparse++);
1969                 Class = toCTRL(Class);
1970                 break;
1971             case '0': case '1': case '2': case '3': case '4':
1972             case '5': case '6': case '7': case '8': case '9':
1973                 Class = scan_oct(--regparse, 3, &numlen);
1974                 regparse += numlen;
1975                 break;
1976             }
1977         }
1978         if (range) {
1979             if (lastclass > Class)
1980                 FAIL("invalid [] range in regexp");
1981             range = 0;
1982         }
1983         else {
1984             lastclass = Class;
1985             if (*regparse == '-' && regparse+1 < regxend &&
1986               regparse[1] != ']') {
1987                 regparse++;
1988                 range = 1;
1989                 continue;       /* do it next time */
1990             }
1991         }
1992         for ( ; lastclass <= Class; lastclass++)
1993             regset(opnd, lastclass);
1994         lastclass = Class;
1995     }
1996     if (*regparse != ']')
1997         FAIL("unmatched [] in regexp");
1998     nextchar();
1999     return ret;
2000 }
2001
2002 STATIC char*
2003 nextchar(void)
2004 {
2005     char* retval = regparse++;
2006
2007     for (;;) {
2008         if (*regparse == '(' && regparse[1] == '?' &&
2009                 regparse[2] == '#') {
2010             while (*regparse && *regparse != ')')
2011                 regparse++;
2012             regparse++;
2013             continue;
2014         }
2015         if (regflags & PMf_EXTENDED) {
2016             if (isSPACE(*regparse)) {
2017                 regparse++;
2018                 continue;
2019             }
2020             else if (*regparse == '#') {
2021                 while (*regparse && *regparse != '\n')
2022                     regparse++;
2023                 regparse++;
2024                 continue;
2025             }
2026         }
2027         return retval;
2028     }
2029 }
2030
2031 /*
2032 - reg_node - emit a node
2033 */
2034 STATIC regnode *                        /* Location. */
2035 reg_node(U8 op)
2036 {
2037     register regnode *ret;
2038     register regnode *ptr;
2039
2040     ret = regcode;
2041     if (SIZE_ONLY) {
2042         SIZE_ALIGN(regsize);
2043 #ifdef REGALIGN_STRUCT
2044         regsize += 1;
2045 #else
2046         regsize += 3;
2047 #endif 
2048         return(ret);
2049     }
2050
2051     NODE_ALIGN_FILL(ret);
2052     ptr = ret;
2053     FILL_ADVANCE_NODE(ptr, op);
2054     regcode = ptr;
2055
2056     return(ret);
2057 }
2058
2059 /*
2060 - reganode - emit a node with an argument
2061 */
2062 STATIC regnode *                        /* Location. */
2063 reganode(U8 op, U32 arg)
2064 {
2065     register regnode *ret;
2066     register regnode *ptr;
2067
2068     ret = regcode;
2069     if (SIZE_ONLY) {
2070         SIZE_ALIGN(regsize);
2071 #ifdef REGALIGN
2072         regsize += 2;
2073 #else
2074         regsize += 5;
2075 #endif 
2076         return(ret);
2077     }
2078
2079     NODE_ALIGN_FILL(ret);
2080     ptr = ret;
2081     FILL_ADVANCE_NODE_ARG(ptr, op, arg);
2082     regcode = ptr;
2083
2084     return(ret);
2085 }
2086
2087 /*
2088 - regc - emit (if appropriate) a byte of code
2089 */
2090 STATIC void
2091 regc(U8 b, char* s)
2092 {
2093     if (!SIZE_ONLY)
2094         *s = b;
2095 }
2096
2097 /*
2098 - reginsert - insert an operator in front of already-emitted operand
2099 *
2100 * Means relocating the operand.
2101 */
2102 STATIC void
2103 reginsert(U8 op, regnode *opnd)
2104 {
2105     register regnode *src;
2106     register regnode *dst;
2107     register regnode *place;
2108     register int offset = regarglen[(U8)op];
2109     
2110 /* (regkind[(U8)op] == CURLY ? EXTRA_STEP_2ARGS : 0); */
2111
2112     if (SIZE_ONLY) {
2113         regsize += NODE_STEP_REGNODE + offset;
2114         return;
2115     }
2116
2117     src = regcode;
2118     regcode += NODE_STEP_REGNODE + offset;
2119     dst = regcode;
2120     while (src > opnd)
2121         StructCopy(--src, --dst, regnode);
2122
2123     place = opnd;               /* Op node, where operand used to be. */
2124     src = NEXTOPER(place);
2125     FILL_ADVANCE_NODE(place, op);
2126     Zero(src, offset, regnode);
2127 #if defined(REGALIGN) && !defined(REGALIGN_STRUCT)
2128     src[offset + 1] = '\177';
2129 #endif
2130 }
2131
2132 /*
2133 - regtail - set the next-pointer at the end of a node chain of p to val.
2134 */
2135 STATIC void
2136 regtail(regnode *p, regnode *val)
2137 {
2138     register regnode *scan;
2139     register regnode *temp;
2140     register I32 offset;
2141
2142     if (SIZE_ONLY)
2143         return;
2144
2145     /* Find last node. */
2146     scan = p;
2147     for (;;) {
2148         temp = regnext(scan);
2149         if (temp == NULL)
2150             break;
2151         scan = temp;
2152     }
2153
2154 #ifdef REGALIGN
2155 #  ifdef REGALIGN_STRUCT
2156     if (reg_off_by_arg[OP(scan)]) {
2157         ARG_SET(scan, val - scan);
2158     } else {
2159         NEXT_OFF(scan) = val - scan;
2160     }
2161 #  else
2162     offset = val - scan;
2163 #    ifndef lint
2164     *(short*)(scan+1) = offset;
2165 #    endif
2166 #endif 
2167 #else
2168     if (OP(scan) == BACK)
2169         offset = scan - val;
2170     else
2171         offset = val - scan;
2172     *(scan+1) = (offset>>8)&0377;
2173     *(scan+2) = offset&0377;
2174 #endif
2175 }
2176
2177 /*
2178 - regoptail - regtail on operand of first argument; nop if operandless
2179 */
2180 STATIC void
2181 regoptail(regnode *p, regnode *val)
2182 {
2183     /* "Operandless" and "op != BRANCH" are synonymous in practice. */
2184     if (p == NULL || SIZE_ONLY)
2185         return;
2186     if (regkind[(U8)OP(p)] == BRANCH) {
2187         regtail(NEXTOPER(p), val);
2188     } else if ( regkind[(U8)OP(p)] == BRANCHJ) {
2189         regtail(NEXTOPER(NEXTOPER(p)), val);
2190     } else
2191         return;
2192 }
2193
2194 /*
2195  - regcurly - a little FSA that accepts {\d+,?\d*}
2196  */
2197 STATIC I32
2198 regcurly(register char *s)
2199 {
2200     if (*s++ != '{')
2201         return FALSE;
2202     if (!isDIGIT(*s))
2203         return FALSE;
2204     while (isDIGIT(*s))
2205         s++;
2206     if (*s == ',')
2207         s++;
2208     while (isDIGIT(*s))
2209         s++;
2210     if (*s != '}')
2211         return FALSE;
2212     return TRUE;
2213 }
2214
2215 #ifdef DEBUGGING
2216
2217 STATIC regnode *
2218 dumpuntil(regnode *start, regnode *node, regnode *last, SV* sv, I32 l)
2219 {
2220     register char op = EXACT;   /* Arbitrary non-END op. */
2221     register regnode *next, *onode;
2222
2223     while (op != END && (!last || node < last)) {
2224         /* While that wasn't END last time... */
2225
2226         NODE_ALIGN(node);
2227         op = OP(node);
2228         if (op == CLOSE)
2229             l--;        
2230         next = regnext(node);
2231         /* Where, what. */
2232         if (OP(node) == OPTIMIZED)
2233             goto after_print;
2234         regprop(sv, node);
2235         PerlIO_printf(Perl_debug_log, "%4d%*s%s", node - start, 
2236                       2*l + 1, "", SvPVX(sv));
2237         if (next == NULL)               /* Next ptr. */
2238             PerlIO_printf(Perl_debug_log, "(0)");
2239         else 
2240             PerlIO_printf(Perl_debug_log, "(%d)", next - start);
2241         (void)PerlIO_putc(Perl_debug_log, '\n');
2242       after_print:
2243         if (regkind[(U8)op] == BRANCHJ) {
2244             register regnode *nnode = (OP(next) == LONGJMP 
2245                                        ? regnext(next) 
2246                                        : next);
2247             if (last && nnode > last)
2248                 nnode = last;
2249             node = dumpuntil(start, NEXTOPER(NEXTOPER(node)), nnode, sv, l + 1);
2250         } else if (regkind[(U8)op] == BRANCH) {
2251             node = dumpuntil(start, NEXTOPER(node), next, sv, l + 1);
2252         } else if ( op == CURLY) {   /* `next' might be very big: optimizer */
2253             node = dumpuntil(start, NEXTOPER(node) + EXTRA_STEP_2ARGS,
2254                              NEXTOPER(node) + EXTRA_STEP_2ARGS + 1, sv, l + 1);
2255         } else if (regkind[(U8)op] == CURLY && op != CURLYX) {
2256             node = dumpuntil(start, NEXTOPER(node) + EXTRA_STEP_2ARGS,
2257                              next, sv, l + 1);
2258         } else if ( op == PLUS || op == STAR) {
2259             node = dumpuntil(start, NEXTOPER(node), NEXTOPER(node) + 1, sv, l + 1);
2260         } else if (op == ANYOF) {
2261             node = NEXTOPER(node);
2262             node += ANY_SKIP;
2263         } else if (regkind[(U8)op] == EXACT) {
2264             /* Literal string, where present. */
2265             node += ((*OPERAND(node)) + 2 + sizeof(regnode) - 1) / sizeof(regnode);
2266             node = NEXTOPER(node);
2267         } else {
2268             node = NEXTOPER(node);
2269             node += regarglen[(U8)op];
2270         }
2271         if (op == CURLYX || op == OPEN)
2272             l++;
2273         else if (op == WHILEM)
2274             l--;
2275     }
2276     return node;
2277 }
2278
2279 /*
2280  - regdump - dump a regexp onto Perl_debug_log in vaguely comprehensible form
2281  */
2282 void
2283 regdump(regexp *r)
2284 {
2285     SV *sv = sv_newmortal();
2286
2287     (void)dumpuntil(r->program, r->program + 1, NULL, sv, 0);
2288
2289     /* Header fields of interest. */
2290     if (r->anchored_substr)
2291         PerlIO_printf(Perl_debug_log, "anchored `%s%s%s'%s at %d ", 
2292                       colors[0],
2293                       SvPVX(r->anchored_substr), 
2294                       colors[1],
2295                       SvTAIL(r->anchored_substr) ? "$" : "",
2296                       r->anchored_offset);
2297     if (r->float_substr)
2298         PerlIO_printf(Perl_debug_log, "floating `%s%s%s'%s at %d..%u ", 
2299                       colors[0],
2300                       SvPVX(r->float_substr), 
2301                       colors[1],
2302                       SvTAIL(r->float_substr) ? "$" : "",
2303                       r->float_min_offset, r->float_max_offset);
2304     if (r->check_substr)
2305         PerlIO_printf(Perl_debug_log, 
2306                       r->check_substr == r->float_substr 
2307                       ? "(checking floating" : "(checking anchored");
2308     if (r->reganch & ROPT_NOSCAN)
2309         PerlIO_printf(Perl_debug_log, " noscan");
2310     if (r->reganch & ROPT_CHECK_ALL)
2311         PerlIO_printf(Perl_debug_log, " isall");
2312     if (r->check_substr)
2313         PerlIO_printf(Perl_debug_log, ") ");
2314
2315     if (r->regstclass) {
2316         regprop(sv, r->regstclass);
2317         PerlIO_printf(Perl_debug_log, "stclass `%s' ", SvPVX(sv));
2318     }
2319     if (r->reganch & ROPT_ANCH) {
2320         PerlIO_printf(Perl_debug_log, "anchored");
2321         if (r->reganch & ROPT_ANCH_BOL)
2322             PerlIO_printf(Perl_debug_log, "(BOL)");
2323         if (r->reganch & ROPT_ANCH_MBOL)
2324             PerlIO_printf(Perl_debug_log, "(MBOL)");
2325         if (r->reganch & ROPT_ANCH_GPOS)
2326             PerlIO_printf(Perl_debug_log, "(GPOS)");
2327         PerlIO_putc(Perl_debug_log, ' ');
2328     }
2329     if (r->reganch & ROPT_GPOS_SEEN)
2330         PerlIO_printf(Perl_debug_log, "GPOS ");
2331     if (r->reganch & ROPT_SKIP)
2332         PerlIO_printf(Perl_debug_log, "plus ");
2333     if (r->reganch & ROPT_IMPLICIT)
2334         PerlIO_printf(Perl_debug_log, "implicit ");
2335     PerlIO_printf(Perl_debug_log, "minlen %ld ", (long) r->minlen);
2336     PerlIO_printf(Perl_debug_log, "\n");
2337 }
2338
2339 /*
2340 - regprop - printable representation of opcode
2341 */
2342 void
2343 regprop(SV *sv, regnode *o)
2344 {
2345     register char *p = 0;
2346
2347     sv_setpv(sv, ":");
2348     switch (OP(o)) {
2349     case BOL:
2350         p = "BOL";
2351         break;
2352     case MBOL:
2353         p = "MBOL";
2354         break;
2355     case SBOL:
2356         p = "SBOL";
2357         break;
2358     case EOL:
2359         p = "EOL";
2360         break;
2361     case MEOL:
2362         p = "MEOL";
2363         break;
2364     case SEOL:
2365         p = "SEOL";
2366         break;
2367     case ANY:
2368         p = "ANY";
2369         break;
2370     case SANY:
2371         p = "SANY";
2372         break;
2373     case ANYOF:
2374         p = "ANYOF";
2375         break;
2376     case BRANCH:
2377         p = "BRANCH";
2378         break;
2379     case EXACT:
2380         sv_catpvf(sv, "EXACT <%s%s%s>", colors[0], OPERAND(o) + 1, colors[1]);
2381         break;
2382     case EXACTF:
2383         sv_catpvf(sv, "EXACTF <%s%s%s>", colors[0], OPERAND(o) + 1, colors[1]);
2384         break;
2385     case EXACTFL:
2386         sv_catpvf(sv, "EXACTFL <%s%s%s>", colors[0], OPERAND(o) + 1, colors[1]);
2387         break;
2388     case NOTHING:
2389         p = "NOTHING";
2390         break;
2391     case TAIL:
2392         p = "TAIL";
2393         break;
2394     case BACK:
2395         p = "BACK";
2396         break;
2397     case END:
2398         p = "END";
2399         break;
2400     case BOUND:
2401         p = "BOUND";
2402         break;
2403     case BOUNDL:
2404         p = "BOUNDL";
2405         break;
2406     case NBOUND:
2407         p = "NBOUND";
2408         break;
2409     case NBOUNDL:
2410         p = "NBOUNDL";
2411         break;
2412     case CURLY:
2413         sv_catpvf(sv, "CURLY {%d,%d}", ARG1(o), ARG2(o));
2414         break;
2415     case CURLYM:
2416 #ifdef REGALIGN_STRUCT
2417         sv_catpvf(sv, "CURLYM[%d] {%d,%d}", o->flags, ARG1(o), ARG2(o));
2418 #else
2419         sv_catpvf(sv, "CURLYM {%d,%d}", ARG1(o), ARG2(o));
2420 #endif 
2421         break;
2422     case CURLYN:
2423 #ifdef REGALIGN_STRUCT
2424         sv_catpvf(sv, "CURLYN[%d] {%d,%d}", o->flags, ARG1(o), ARG2(o));
2425 #else
2426         sv_catpvf(sv, "CURLYN {%d,%d}", ARG1(o), ARG2(o));
2427 #endif 
2428         break;
2429     case CURLYX:
2430         sv_catpvf(sv, "CURLYX {%d,%d}", ARG1(o), ARG2(o));
2431         break;
2432     case REF:
2433         sv_catpvf(sv, "REF%d", ARG(o));
2434         break;
2435     case REFF:
2436         sv_catpvf(sv, "REFF%d", ARG(o));
2437         break;
2438     case REFFL:
2439         sv_catpvf(sv, "REFFL%d", ARG(o));
2440         break;
2441     case OPEN:
2442         sv_catpvf(sv, "OPEN%d", ARG(o));
2443         break;
2444     case CLOSE:
2445         sv_catpvf(sv, "CLOSE%d", ARG(o));
2446         p = NULL;
2447         break;
2448     case STAR:
2449         p = "STAR";
2450         break;
2451     case PLUS:
2452         p = "PLUS";
2453         break;
2454     case MINMOD:
2455         p = "MINMOD";
2456         break;
2457     case GPOS:
2458         p = "GPOS";
2459         break;
2460     case UNLESSM:
2461 #ifdef REGALIGN_STRUCT
2462         sv_catpvf(sv, "UNLESSM[-%d]", o->flags);
2463 #else
2464         p = "UNLESSM";
2465 #endif 
2466         break;
2467     case IFMATCH:
2468 #ifdef REGALIGN_STRUCT
2469         sv_catpvf(sv, "IFMATCH[-%d]", o->flags);
2470 #else
2471         p = "IFMATCH";
2472 #endif 
2473         break;
2474     case SUCCEED:
2475         p = "SUCCEED";
2476         break;
2477     case WHILEM:
2478         p = "WHILEM";
2479         break;
2480     case DIGIT:
2481         p = "DIGIT";
2482         break;
2483     case NDIGIT:
2484         p = "NDIGIT";
2485         break;
2486     case ALNUM:
2487         p = "ALNUM";
2488         break;
2489     case NALNUM:
2490         p = "NALNUM";
2491         break;
2492     case SPACE:
2493         p = "SPACE";
2494         break;
2495     case NSPACE:
2496         p = "NSPACE";
2497         break;
2498     case ALNUML:
2499         p = "ALNUML";
2500         break;
2501     case NALNUML:
2502         p = "NALNUML";
2503         break;
2504     case SPACEL:
2505         p = "SPACEL";
2506         break;
2507     case NSPACEL:
2508         p = "NSPACEL";
2509         break;
2510     case EVAL:
2511         p = "EVAL";
2512         break;
2513     case LONGJMP:
2514         p = "LONGJMP";
2515         break;
2516     case BRANCHJ:
2517         p = "BRANCHJ";
2518         break;
2519     case IFTHEN:
2520         p = "IFTHEN";
2521         break;
2522     case GROUPP:
2523         sv_catpvf(sv, "GROUPP%d", ARG(o));
2524         break;
2525     case LOGICAL:
2526         p = "LOGICAL";
2527         break;
2528     case SUSPEND:
2529         p = "SUSPEND";
2530         break;
2531     case RENUM:
2532         p = "RENUM";
2533         break;
2534     case OPTIMIZED:
2535         p = "OPTIMIZED";
2536         break;
2537     default:
2538         FAIL("corrupted regexp opcode");
2539     }
2540     if (p)
2541         sv_catpv(sv, p);
2542 }
2543 #endif /* DEBUGGING */
2544
2545 void
2546 pregfree(struct regexp *r)
2547 {
2548     if (!r || (--r->refcnt > 0))
2549         return;
2550     if (r->precomp)
2551         Safefree(r->precomp);
2552     if (r->subbase)
2553         Safefree(r->subbase);
2554     if (r->substrs) {
2555         if (r->anchored_substr)
2556             SvREFCNT_dec(r->anchored_substr);
2557         if (r->float_substr)
2558             SvREFCNT_dec(r->float_substr);
2559         Safefree(r->substrs);
2560     }
2561     if (r->data) {
2562         int n = r->data->count;
2563         while (--n >= 0) {
2564             switch (r->data->what[n]) {
2565             case 's':
2566                 SvREFCNT_dec((SV*)r->data->data[n]);
2567                 break;
2568             case 'o':
2569                 op_free((OP_4tree*)r->data->data[n]);
2570                 break;
2571             case 'n':
2572                 break;
2573             default:
2574                 FAIL2("panic: regfree data code '%c'", r->data->what[n]);
2575             }
2576         }
2577         Safefree(r->data->what);
2578         Safefree(r->data);
2579     }
2580     Safefree(r->startp);
2581     Safefree(r->endp);
2582     Safefree(r);
2583 }
2584
2585 /*
2586  - regnext - dig the "next" pointer out of a node
2587  *
2588  * [Note, when REGALIGN is defined there are two places in regmatch()
2589  * that bypass this code for speed.]
2590  */
2591 regnode *
2592 regnext(register regnode *p)
2593 {
2594     register I32 offset;
2595
2596     if (p == &regdummy)
2597         return(NULL);
2598
2599     offset = (reg_off_by_arg[OP(p)] ? ARG(p) : NEXT_OFF(p));
2600     if (offset == 0)
2601         return(NULL);
2602
2603 #ifdef REGALIGN
2604     return(p+offset);
2605 #else
2606     if (OP(p) == BACK)
2607         return(p-offset);
2608     else
2609         return(p+offset);
2610 #endif
2611 }
2612
2613 #ifdef I_STDARG
2614 STATIC void     
2615 re_croak2(const char* pat1,const char* pat2,...)
2616 #else
2617 /*VARARGS0*/
2618 static void     
2619 re_croak2(const char* pat1,const char* pat2, va_alist)
2620     const char* pat1;
2621     const char* pat2;
2622     va_dcl
2623 #endif 
2624 {
2625     va_list args;
2626     STRLEN l1 = strlen(pat1);
2627     STRLEN l2 = strlen(pat2);
2628     char buf[512];
2629     char *message;
2630
2631     if (l1 > 510)
2632         l1 = 510;
2633     if (l1 + l2 > 510)
2634         l2 = 510 - l1;
2635     Copy(pat1, buf, l1 , char);
2636     Copy(pat2, buf + l1, l2 , char);
2637     buf[l1 + l2 + 1] = '\n';
2638     buf[l1 + l2 + 2] = '\0';
2639 #ifdef I_STDARG
2640     va_start(args, pat2);
2641 #else
2642     va_start(args);
2643 #endif
2644     message = mess(buf, &args);
2645     va_end(args);
2646     l1 = strlen(message);
2647     if (l1 > 512)
2648         l1 = 512;
2649     Copy(message, buf, l1 , char);
2650     buf[l1] = '\0';                     /* Overwrite \n */
2651     croak("%s", buf);
2652 }