1 /* NOTE: this is derived from Henry Spencer's regexp code, and should not
2 * confused with the original package (see point 3 below). Thanks, Henry!
5 /* Additional note: this code is very heavily munged from Henry's version
6 * in places. In some spots I've traded clarity for efficiency, so don't
7 * blame Henry for some of the lack of readability.
10 /* $RCSfile: regcomp.c,v $$Revision: 4.0.1.5 $$Date: 92/06/08 15:23:36 $
13 * Revision 4.0.1.5 92/06/08 15:23:36 lwall
14 * patch20: Perl now distinguishes overlapped copies from non-overlapped
15 * patch20: /^stuff/ wrongly assumed an implicit $* == 1
16 * patch20: /x{0}/ was wrongly interpreted as /x{0,}/
17 * patch20: added \W, \S and \D inside /[...]/
19 * Revision 4.0.1.4 91/11/05 22:55:14 lwall
22 * Revision 4.0.1.3 91/11/05 18:22:28 lwall
23 * patch11: minimum match length calculation in regexp is now cumulative
24 * patch11: initial .* in pattern had dependency on value of $*
25 * patch11: certain patterns made use of garbage pointers from uncleared memory
26 * patch11: prepared for ctype implementations that don't define isascii()
28 * Revision 4.0.1.2 91/06/07 11:48:24 lwall
29 * patch4: new copyright notice
30 * patch4: /(x+) \1/ incorrectly optimized to not match "xxx xx"
31 * patch4: // wouldn't use previous pattern if it started with a null character
33 * Revision 4.0.1.1 91/04/12 09:04:45 lwall
34 * patch1: random cleanup in cpp namespace
36 * Revision 4.0 91/03/20 01:39:01 lwall
42 * regcomp and regexec -- regsub and regerror are not used in perl
44 * Copyright (c) 1986 by University of Toronto.
45 * Written by Henry Spencer. Not derived from licensed software.
47 * Permission is granted to anyone to use this software for any
48 * purpose on any computer system, and to redistribute it freely,
49 * subject to the following restrictions:
51 * 1. The author is not responsible for the consequences of use of
52 * this software, no matter how awful, even if they arise
55 * 2. The origin of this software must not be misrepresented, either
56 * by explicit claim or by omission.
58 * 3. Altered versions must be plainly marked as such, and must not
59 * be misrepresented as being the original software.
62 **** Alterations to Henry's code are...
64 **** Copyright (c) 1991, Larry Wall
66 **** You may distribute under the terms of either the GNU General Public
67 **** License or the Artistic License, as specified in the README file.
70 * Beware that some of this code is subtly aware of the way operator
71 * precedence is structured in regular expressions. Serious changes in
72 * regular-expression syntax might require a total rethink.
80 # if defined(BUGGY_MSC6)
81 /* MSC 6.00A breaks on op/regexp.t test 85 unless we turn this off */
82 # pragma optimize("a",off)
83 /* But MSC 6.00A is happy with 'w', for aliases only across function calls*/
84 # pragma optimize("w",on )
85 # endif /* BUGGY_MSC6 */
92 #define ISMULT1(c) ((c) == '*' || (c) == '+' || (c) == '?')
93 #define ISMULT2(s) ((*s) == '*' || (*s) == '+' || (*s) == '?' || \
94 ((*s) == '{' && regcurly(s)))
96 #define PERL_META "^$.[()|?+*\\"
98 #define META "^$.[()|?+*\\"
102 #undef SPSTART /* dratted cpp namespace... */
105 * Flags to be passed up and down.
107 #define HASWIDTH 01 /* Known never to match null string. */
108 #define SIMPLE 02 /* Simple enough to be STAR/PLUS operand. */
109 #define SPSTART 04 /* Starts with * or +. */
110 #define WORST 0 /* Worst case. */
113 * Global work variables for regcomp().
115 static char *regprecomp; /* uncompiled string. */
116 static char *regparse; /* Input-scan pointer. */
117 static char *regxend; /* End of input for compile */
118 static int regnpar; /* () count. */
119 static char *regcode; /* Code-emit pointer; ®dummy = don't. */
120 static long regsize; /* Code size. */
122 static int regsawbracket; /* Did we do {d,d} trick? */
123 static int regsawback; /* Did we see \1, ...? */
126 * Forward declarations for regcomp()'s friends.
128 STATIC int regcurly();
130 STATIC char *regbranch();
131 STATIC char *regpiece();
132 STATIC char *regatom();
133 STATIC char *regclass();
134 STATIC char *regnode();
135 STATIC char *reganode();
137 STATIC void reginsert();
138 STATIC void regtail();
139 STATIC void regoptail();
142 - regcomp - compile a regular expression into internal code
144 * We can't allocate space until we know how big the compiled form will be,
145 * but we can't compile it (and thus know how big it is) until we've got a
146 * place to put the code. So we cheat: we compile it twice, once with code
147 * generation turned off and size counting turned on, and once "for real".
148 * This also means that we don't allocate space until we are sure that the
149 * thing really will compile successfully, and we never have to move the
150 * code and thus invalidate pointers into it. (Note that it has to be in
151 * one piece because free() must be able to free it all.) [NB: not true in perl]
153 * Beware that the optimization-preparation code in here knows about some
154 * of the structure of the compiled regexp. [I'll say.]
157 regcomp(exp,xend,fold)
164 register STR *longish;
167 register char *first;
177 fatal("NULL regexp argument");
179 /* First pass: determine size, legality. */
183 regprecomp = nsavestr(exp,xend-exp);
190 if (reg(0, &flags) == NULL) {
191 Safefree(regprecomp);
196 /* Small enough for pointer-storage convention? */
197 if (regsize >= 32767L) /* Probably could be 65535L. */
198 FAIL("regexp too big");
200 /* Allocate space. */
201 Newc(1001, r, sizeof(regexp) + (unsigned)regsize, char, regexp);
203 FAIL("regexp out of space");
205 /* Second pass: emit code. */
207 Copy(regprecomp,exp,xend-exp,char);
208 r->prelen = xend-exp;
209 r->precomp = regprecomp;
210 r->subbeg = r->subbase = NULL;
213 regcode = r->program;
215 if (reg(0, &flags) == NULL)
218 /* Dig out information for optimizations. */
219 r->regstart = Nullstr; /* Worst-case defaults. */
221 r->regmust = Nullstr;
223 r->regstclass = Nullch;
224 scan = r->program+1; /* First BRANCH. */
225 if (OP(regnext(scan)) == END) {/* Only one top-level choice. */
226 scan = NEXTOPER(scan);
229 while ((OP(first) == OPEN && (sawopen = 1)) ||
230 (OP(first) == BRANCH && OP(regnext(first)) != BRANCH) ||
231 (OP(first) == PLUS) ||
232 (OP(first) == CURLY && ARG1(first) > 0) ) {
233 if (OP(first) == PLUS)
236 first += regarglen[OP(first)];
237 first = NEXTOPER(first);
240 /* Starting-point info. */
242 if (OP(first) == EXACTLY) {
244 str_make(OPERAND(first)+1,*OPERAND(first));
245 if (r->regstart->str_cur > !(sawstudy|fold))
246 fbmcompile(r->regstart,fold);
248 else if ((exp = index(simple,OP(first))) && exp > simple)
249 r->regstclass = first;
250 else if (OP(first) == BOUND || OP(first) == NBOUND)
251 r->regstclass = first;
252 else if (OP(first) == BOL) {
253 r->reganch = ROPT_ANCH;
254 first = NEXTOPER(first);
257 else if ((OP(first) == STAR && OP(NEXTOPER(first)) == ANY) &&
258 !(r->reganch & ROPT_ANCH) ) {
259 /* turn .* into ^.* with an implied $*=1 */
260 r->reganch = ROPT_ANCH | ROPT_IMPLICIT;
261 first = NEXTOPER(first);
264 if (sawplus && (!sawopen || !regsawback))
265 r->reganch |= ROPT_SKIP; /* x+ must match 1st of run */
269 fprintf(stderr,"first %d next %d offset %d\n",
270 OP(first), OP(NEXTOPER(first)), first - scan);
273 * If there's something expensive in the r.e., find the
274 * longest literal string that must appear and make it the
275 * regmust. Resolve ties in favor of later strings, since
276 * the regstart check works with the beginning of the r.e.
277 * and avoiding duplication strengthens checking. Not a
278 * strong reason, but sufficient in the absence of others.
279 * [Now we resolve ties in favor of the earlier string if
280 * it happens that curback has been invalidated, since the
281 * earlier string may buy us something the later one won't.]
283 longish = str_make("",0);
284 longest = str_make("",0);
290 while (OP(scan) != END) {
291 if (OP(scan) == BRANCH) {
292 if (OP(regnext(scan)) == BRANCH) {
294 while (OP(scan) == BRANCH)
295 scan = regnext(scan);
297 else /* single branch is ok */
298 scan = NEXTOPER(scan);
300 if (OP(scan) == EXACTLY) {
304 while (OP(t = regnext(scan)) == CLOSE)
306 minlen += *OPERAND(first);
307 if (curback - backish == len) {
308 str_ncat(longish, OPERAND(first)+1,
310 len += *OPERAND(first);
311 curback += *OPERAND(first);
312 first = regnext(scan);
314 else if (*OPERAND(first) >= len + (curback >= 0)) {
315 len = *OPERAND(first);
316 str_nset(longish, OPERAND(first)+1,len);
319 first = regnext(scan);
322 curback += *OPERAND(first);
324 else if (index(varies,OP(scan))) {
327 if (longish->str_cur > longest->str_cur) {
328 str_sset(longest,longish);
331 str_nset(longish,"",0);
332 if (OP(scan) == PLUS &&
333 index(simple,OP(NEXTOPER(scan))))
335 else if (OP(scan) == CURLY &&
336 index(simple,OP(NEXTOPER(scan)+4)))
337 minlen += ARG1(scan);
339 else if (index(simple,OP(scan))) {
343 if (longish->str_cur > longest->str_cur) {
344 str_sset(longest,longish);
347 str_nset(longish,"",0);
349 scan = regnext(scan);
352 /* Prefer earlier on tie, unless we can tail match latter */
354 if (longish->str_cur + (OP(first) == EOL) > longest->str_cur) {
355 str_sset(longest,longish);
359 str_nset(longish,"",0);
364 !fbminstr((unsigned char*) r->regstart->str_ptr,
365 (unsigned char *) r->regstart->str_ptr
366 + r->regstart->str_cur,
371 r->regmust = longest;
374 r->regback = backest;
376 > !(sawstudy || fold || OP(first) == EOL) )
377 fbmcompile(r->regmust,fold);
378 r->regmust->str_u.str_useful = 100;
379 if (OP(first) == EOL && longish->str_cur)
380 r->regmust->str_pok |= SP_TAIL;
389 r->do_folding = fold;
390 r->nparens = regnpar - 1;
392 Newz(1002, r->startp, regnpar, char*);
393 Newz(1002, r->endp, regnpar, char*);
402 - reg - regular expression, i.e. main body or parenthesized thing
404 * Caller must absorb opening parenthesis.
406 * Combining parenthesis handling with the base level of regular expression
407 * is a trifle forced, but the need to tie the tails of the branches to what
408 * follows makes it hard to avoid.
412 int paren; /* Parenthesized? */
417 register char *ender;
421 *flagp = HASWIDTH; /* Tentatively. */
423 /* Make an OPEN node, if parenthesized. */
427 ret = reganode(OPEN, parno);
431 /* Pick up the branches, linking them together. */
432 br = regbranch(&flags);
436 regtail(ret, br); /* OPEN -> first. */
439 if (!(flags&HASWIDTH))
441 *flagp |= flags&SPSTART;
442 while (*regparse == '|') {
444 br = regbranch(&flags);
447 regtail(ret, br); /* BRANCH -> BRANCH. */
448 if (!(flags&HASWIDTH))
450 *flagp |= flags&SPSTART;
453 /* Make a closing node, and hook it on the end. */
455 ender = reganode(CLOSE, parno);
457 ender = regnode(END);
460 /* Hook the tails of the branches to the closing node. */
461 for (br = ret; br != NULL; br = regnext(br))
462 regoptail(br, ender);
464 /* Check for proper termination. */
465 if (paren && *regparse++ != ')') {
466 FAIL("unmatched () in regexp");
467 } else if (!paren && regparse < regxend) {
468 if (*regparse == ')') {
469 FAIL("unmatched () in regexp");
471 FAIL("junk on end of regexp"); /* "Can't happen". */
479 - regbranch - one alternative of an | operator
481 * Implements the concatenation operator.
488 register char *chain;
489 register char *latest;
492 *flagp = WORST; /* Tentatively. */
494 ret = regnode(BRANCH);
496 while (regparse < regxend && *regparse != '|' && *regparse != ')') {
497 latest = regpiece(&flags);
500 *flagp |= flags&HASWIDTH;
501 if (chain == NULL) /* First piece. */
502 *flagp |= flags&SPSTART;
504 regtail(chain, latest);
507 if (chain == NULL) /* Loop ran zero times. */
508 (void) regnode(NOTHING);
514 - regpiece - something followed by possible [*+?]
516 * Note that the branching code sequences used for ? and the general cases
517 * of * and + are somewhat optimized: they use the same NOTHING node as
518 * both the endmarker for their branch list and the body of the last branch.
519 * It might seem that this node could be dispensed with entirely, but the
520 * endmarker role is not redundant.
530 char *origparse = regparse;
531 int orignpar = regnpar;
536 ret = regatom(&flags);
542 /* Here's a total kludge: if after the atom there's a {\d+,?\d*}
543 * then we decrement the first number by one and reset our
544 * parsing back to the beginning of the same atom. If the first number
545 * is down to 0, decrement the second number instead and fake up
546 * a ? after it. Given the way this compiler doesn't keep track
547 * of offsets on the first pass, this is the only way to replicate
548 * a piece of code. Sigh.
550 if (op == '{' && regcurly(regparse)) {
553 while (isDIGIT(*next) || *next == ',') {
562 if (*next == '}') { /* got one */
566 iter = atoi(regparse);
567 if (flags&SIMPLE) { /* we can do it right after all */
570 reginsert(CURLY, ret);
572 *flagp = (WORST|HASWIDTH);
578 if (!tmp && *max != '0')
579 tmp = 32767; /* meaning "infinity" */
580 if (tmp && tmp < iter)
581 fatal("Can't do {n,m} with n > m");
582 if (regcode != ®dummy) {
584 *(unsigned short *)(ret+3) = iter;
585 *(unsigned short *)(ret+5) = tmp;
587 ret[3] = iter >> 8; ret[4] = iter & 0377;
588 ret[5] = tmp >> 8; ret[6] = tmp & 0377;
594 regsawbracket++; /* remember we clobbered exp */
597 sprintf(regparse,"%.*d", max-regparse, iter - 1);
599 if (*max == ',' && max[1] != '}') {
600 if (atoi(max+1) <= 0)
601 fatal("Can't do {n,m} with n > m");
603 sprintf(max+1,"%.*d", next-(max+1), atoi(max+1) - 1);
606 if (iter != 1 || *max == ',') {
607 regparse = origparse; /* back up input pointer */
608 regnpar = orignpar; /* don't make more parens */
620 if (max == next) { /* any number more? */
622 op = '*'; /* fake up one with a star */
625 op = '?'; /* fake up optional atom */
627 sprintf(max,"%.*d", next-max, iter - 1);
632 regparse = origparse - 1; /* offset ++ below */
637 fatal("Can't do {n,0}");
640 fatal("Can't do {0}");
649 if (!(flags&HASWIDTH) && op != '?')
650 FAIL("regexp *+ operand could be empty");
651 *flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
653 if (op == '*' && (flags&SIMPLE))
654 reginsert(STAR, ret);
655 else if (op == '*') {
656 /* Emit x* as (x&|), where & means "self". */
657 reginsert(BRANCH, ret); /* Either x */
658 regoptail(ret, regnode(BACK)); /* and loop */
659 regoptail(ret, ret); /* back */
660 regtail(ret, regnode(BRANCH)); /* or */
661 regtail(ret, regnode(NOTHING)); /* null. */
662 } else if (op == '+' && (flags&SIMPLE))
663 reginsert(PLUS, ret);
664 else if (op == '+') {
665 /* Emit x+ as x(&|), where & means "self". */
666 next = regnode(BRANCH); /* Either */
668 regtail(regnode(BACK), ret); /* loop back */
669 regtail(next, regnode(BRANCH)); /* or */
670 regtail(ret, regnode(NOTHING)); /* null. */
671 } else if (op == '?') {
672 /* Emit x? as (x|) */
673 reginsert(BRANCH, ret); /* Either x */
674 regtail(ret, regnode(BRANCH)); /* or */
675 next = regnode(NOTHING); /* null. */
677 regoptail(ret, next);
681 if (ISMULT2(regparse))
682 FAIL("nested *?+ in regexp");
688 - regatom - the lowest level
690 * Optimization: gobbles an entire sequence of ordinary characters so that
691 * it can turn them into a single node, which is smaller to store and
692 * faster to run. Backslashed characters are exceptions, each becoming a
693 * separate node; the code is simpler that way and it's not worth fixing.
695 * [Yes, it is worth fixing, some scripts can run twice the speed.]
704 *flagp = WORST; /* Tentatively. */
706 switch (*regparse++) {
715 *flagp |= HASWIDTH|SIMPLE;
719 *flagp |= HASWIDTH|SIMPLE;
722 ret = reg(1, &flags);
725 *flagp |= flags&(HASWIDTH|SPSTART);
729 FAIL("internal urp in regexp"); /* Supposed to be caught earlier. */
734 FAIL("?+* follows nothing in regexp");
739 ret = regnode(ALNUM);
740 *flagp |= HASWIDTH|SIMPLE;
744 ret = regnode(NALNUM);
745 *flagp |= HASWIDTH|SIMPLE;
749 ret = regnode(BOUND);
754 ret = regnode(NBOUND);
759 ret = regnode(SPACE);
760 *flagp |= HASWIDTH|SIMPLE;
764 ret = regnode(NSPACE);
765 *flagp |= HASWIDTH|SIMPLE;
769 ret = regnode(DIGIT);
770 *flagp |= HASWIDTH|SIMPLE;
774 ret = regnode(NDIGIT);
775 *flagp |= HASWIDTH|SIMPLE;
788 case '1': case '2': case '3': case '4':
789 case '5': case '6': case '7': case '8': case '9':
791 int num = atoi(regparse);
793 if (num > 9 && num >= regnpar)
797 ret = reganode(REF, num);
798 while (isDIGIT(*regparse))
805 if (regparse >= regxend)
806 FAIL("trailing \\ in regexp");
820 ret = regnode(EXACTLY);
821 regc(0); /* save spot for len */
822 for (len=0, p=regparse-1;
823 len < 127 && p < regxend;
873 ender = scanhex(++p, 2, &numlen);
880 ender = toupper(ender);
883 case '0': case '1': case '2': case '3':case '4':
884 case '5': case '6': case '7': case '8':case '9':
886 (isDIGIT(p[1]) && atoi(p) >= regnpar) ) {
887 ender = scanoct(p, 3, &numlen);
897 FAIL("trailing \\ in regexp");
908 if (regfold && isUPPER(ender))
909 ender = tolower(ender);
910 if (ISMULT2(p)) { /* Back off on ?+*. */
924 FAIL("internal disaster in regexp");
928 if (regcode != ®dummy)
944 if (regcode == ®dummy)
948 bits[c >> 3] &= ~(1 << (c & 7));
950 bits[c >> 3] |= (1 << (c & 7));
958 register int lastclass;
959 register int range = 0;
964 ret = regnode(ANYOF);
965 if (*regparse == '^') { /* Complement of range. */
972 for (class = 0; class < 32; class++)
974 if (*regparse == ']' || *regparse == '-')
975 goto skipcond; /* allow 1st char to be ] or - */
976 while (regparse < regxend && *regparse != ']') {
978 class = UCHARAT(regparse++);
980 class = UCHARAT(regparse++);
983 for (class = 0; class < 256; class++)
985 regset(bits,def,class);
989 for (class = 0; class < 256; class++)
991 regset(bits,def,class);
995 for (class = 0; class < 256; class++)
997 regset(bits,def,class);
1001 for (class = 0; class < 256; class++)
1002 if (!isSPACE(class))
1003 regset(bits,def,class);
1007 for (class = '0'; class <= '9'; class++)
1008 regset(bits,def,class);
1012 for (class = 0; class < '0'; class++)
1013 regset(bits,def,class);
1014 for (class = '9' + 1; class < 256; class++)
1015 regset(bits,def,class);
1040 class = scanhex(regparse, 2, &numlen);
1044 class = *regparse++;
1046 class = toupper(class);
1049 case '0': case '1': case '2': case '3': case '4':
1050 case '5': case '6': case '7': case '8': case '9':
1051 class = scanoct(--regparse, 3, &numlen);
1057 if (lastclass > class)
1058 FAIL("invalid [] range in regexp");
1063 if (*regparse == '-' && regparse+1 < regxend &&
1064 regparse[1] != ']') {
1067 continue; /* do it next time */
1070 for ( ; lastclass <= class; lastclass++) {
1071 regset(bits,def,lastclass);
1072 if (regfold && isUPPER(lastclass))
1073 regset(bits,def,tolower(lastclass));
1077 if (*regparse != ']')
1078 FAIL("unmatched [] in regexp");
1084 - regnode - emit a node
1086 static char * /* Location. */
1094 if (ret == ®dummy) {
1105 if (!((long)ret & 1))
1111 *ptr++ = '\0'; /* Null "next" pointer. */
1119 - reganode - emit a node with an argument
1121 static char * /* Location. */
1130 if (ret == ®dummy) {
1141 if (!((long)ret & 1))
1147 *ptr++ = '\0'; /* Null "next" pointer. */
1150 *(unsigned short *)(ret+3) = arg;
1152 ret[3] = arg >> 8; ret[4] = arg & 0377;
1161 - regc - emit (if appropriate) a byte of code
1167 if (regcode != ®dummy)
1174 - reginsert - insert an operator in front of already-emitted operand
1176 * Means relocating the operand.
1185 register char *place;
1186 register offset = (op == CURLY ? 4 : 0);
1188 if (regcode == ®dummy) {
1190 regsize += 4 + offset;
1192 regsize += 3 + offset;
1199 regcode += 4 + offset;
1201 regcode += 3 + offset;
1207 place = opnd; /* Op node, where operand used to be. */
1211 while (offset-- > 0)
1219 - regtail - set the next-pointer at the end of a node chain
1226 register char *scan;
1227 register char *temp;
1228 register int offset;
1233 /* Find last node. */
1236 temp = regnext(scan);
1243 offset = val - scan;
1245 *(short*)(scan+1) = offset;
1250 if (OP(scan) == BACK)
1251 offset = scan - val;
1253 offset = val - scan;
1254 *(scan+1) = (offset>>8)&0377;
1255 *(scan+2) = offset&0377;
1260 - regoptail - regtail on operand of first argument; nop if operandless
1267 /* "Operandless" and "op != BRANCH" are synonymous in practice. */
1268 if (p == NULL || p == ®dummy || OP(p) != BRANCH)
1270 regtail(NEXTOPER(p), val);
1274 - regcurly - a little FSA that accepts {\d+,?\d*}
1298 - regdump - dump a regexp onto stderr in vaguely comprehensible form
1305 register char op = EXACTLY; /* Arbitrary non-END op. */
1306 register char *next;
1310 while (op != END) { /* While that wasn't END last time... */
1316 fprintf(stderr,"%2d%s", s-r->program, regprop(s)); /* Where, what. */
1319 if (next == NULL) /* Next ptr. */
1320 fprintf(stderr,"(0)");
1322 fprintf(stderr,"(%d)", (s-r->program)+(next-s));
1327 if (op == EXACTLY) {
1328 /* Literal string, where present. */
1330 while (*s != '\0') {
1336 (void)putchar('\n');
1339 /* Header fields of interest. */
1341 fprintf(stderr,"start `%s' ", r->regstart->str_ptr);
1343 fprintf(stderr,"stclass `%s' ", regprop(r->regstclass));
1344 if (r->reganch & ROPT_ANCH)
1345 fprintf(stderr,"anchored ");
1346 if (r->reganch & ROPT_SKIP)
1347 fprintf(stderr,"plus ");
1348 if (r->reganch & ROPT_IMPLICIT)
1349 fprintf(stderr,"implicit ");
1350 if (r->regmust != NULL)
1351 fprintf(stderr,"must have \"%s\" back %d ", r->regmust->str_ptr,
1353 fprintf(stderr, "minlen %d ", r->minlen);
1354 fprintf(stderr,"\n");
1358 - regprop - printable representation of opcode
1366 (void) strcpy(buf, ":");
1421 (void)sprintf(buf+strlen(buf), "CURLY {%d,%d}",
1426 (void)sprintf(buf+strlen(buf), "REF%d", ARG1(op));
1430 (void)sprintf(buf+strlen(buf), "OPEN%d", ARG1(op));
1434 (void)sprintf(buf+strlen(buf), "CLOSE%d", ARG1(op));
1444 FAIL("corrupted regexp opcode");
1447 (void) strcat(buf, p);
1450 #endif /* DEBUGGING */
1457 Safefree(r->precomp);
1458 r->precomp = Nullch;
1461 Safefree(r->subbase);
1462 r->subbase = Nullch;
1465 str_free(r->regmust);
1466 r->regmust = Nullstr;
1469 str_free(r->regstart);
1470 r->regstart = Nullstr;
1472 Safefree(r->startp);