1 /*	$OpenBSD: regexp.c,v 1.4 2003/03/16 03:16:45 deraadt Exp $	*/
2 
3 /*
4  * regcomp and regexec -- regsub and regerror are elsewhere
5  *
6  *	Copyright (c) 1986 by University of Toronto.
7  *	Written by Henry Spencer.  Not derived from licensed software.
8  *
9  *	Permission is granted to anyone to use this software for any
10  *	purpose on any computer system, and to redistribute it freely,
11  *	subject to the following restrictions:
12  *
13  *	1. The author is not responsible for the consequences of use of
14  *		this software, no matter how awful, even if they arise
15  *		from defects in it.
16  *
17  *	2. The origin of this software must not be misrepresented, either
18  *		by explicit claim or by omission.
19  *
20  *	3. Altered versions must be plainly marked as such, and must not
21  *		be misrepresented as being the original software.
22  *** THIS IS AN ALTERED VERSION.  It was altered by John Gilmore,
23  *** hoptoad!gnu, on 27 Dec 1986, to add \n as an alternative to |
24  *** to assist in implementing egrep.
25  *** THIS IS AN ALTERED VERSION.  It was altered by John Gilmore,
26  *** hoptoad!gnu, on 27 Dec 1986, to add \< and \> for word-matching
27  *** as in BSD grep and ex.
28  *** THIS IS AN ALTERED VERSION.  It was altered by John Gilmore,
29  *** hoptoad!gnu, on 28 Dec 1986, to optimize characters quoted with \.
30  *** THIS IS AN ALTERED VERSION.  It was altered by James A. Woods,
31  *** ames!jaw, on 19 June 1987, to quash a regcomp() redundancy.
32  *
33  * Beware that some of this code is subtly aware of the way operator
34  * precedence is structured in regular expressions.  Serious changes in
35  * regular-expression syntax might require a total rethink.
36  */
37 
38 #ifndef lint
39 static char *rcsid = "$OpenBSD: regexp.c,v 1.4 2003/03/16 03:16:45 deraadt Exp $";
40 #endif /* not lint */
41 
42 #include <regexp.h>
43 #include <stdio.h>
44 #include <ctype.h>
45 #include <stdlib.h>
46 #include <string.h>
47 #include "regmagic.h"
48 
49 /*
50  * The "internal use only" fields in regexp.h are present to pass info from
51  * compile to execute that permits the execute phase to run lots faster on
52  * simple cases.  They are:
53  *
54  * regstart	char that must begin a match; '\0' if none obvious
55  * reganch	is the match anchored (at beginning-of-line only)?
56  * regmust	string (pointer into program) that match must include, or NULL
57  * regmlen	length of regmust string
58  *
59  * Regstart and reganch permit very fast decisions on suitable starting points
60  * for a match, cutting down the work a lot.  Regmust permits fast rejection
61  * of lines that cannot possibly match.  The regmust tests are costly enough
62  * that regcomp() supplies a regmust only if the r.e. contains something
63  * potentially expensive (at present, the only such thing detected is * or +
64  * at the start of the r.e., which can involve a lot of backup).  Regmlen is
65  * supplied because the test in regexec() needs it and regcomp() is computing
66  * it anyway.
67  */
68 
69 /*
70  * Structure for regexp "program".  This is essentially a linear encoding
71  * of a nondeterministic finite-state machine (aka syntax charts or
72  * "railroad normal form" in parsing technology).  Each node is an opcode
73  * plus a "next" pointer, possibly plus an operand.  "Next" pointers of
74  * all nodes except BRANCH implement concatenation; a "next" pointer with
75  * a BRANCH on both ends of it is connecting two alternatives.  (Here we
76  * have one of the subtle syntax dependencies:  an individual BRANCH (as
77  * opposed to a collection of them) is never concatenated with anything
78  * because of operator precedence.)  The operand of some types of node is
79  * a literal string; for others, it is a node leading into a sub-FSM.  In
80  * particular, the operand of a BRANCH node is the first node of the branch.
81  * (NB this is *not* a tree structure:  the tail of the branch connects
82  * to the thing following the set of BRANCHes.)  The opcodes are:
83  */
84 
85 /* definition	number	opnd?	meaning */
86 #define	END	0	/* no	End of program. */
87 #define	BOL	1	/* no	Match "" at beginning of line. */
88 #define	EOL	2	/* no	Match "" at end of line. */
89 #define	ANY	3	/* no	Match any one character. */
90 #define	ANYOF	4	/* str	Match any character in this string. */
91 #define	ANYBUT	5	/* str	Match any character not in this string. */
92 #define	BRANCH	6	/* node	Match this alternative, or the next... */
93 #define	BACK	7	/* no	Match "", "next" ptr points backward. */
94 #define	EXACTLY	8	/* str	Match this string. */
95 #define	NOTHING	9	/* no	Match empty string. */
96 #define	STAR	10	/* node	Match this (simple) thing 0 or more times. */
97 #define	PLUS	11	/* node	Match this (simple) thing 1 or more times. */
98 #define	WORDA	12	/* no	Match "" at wordchar, where prev is nonword */
99 #define	WORDZ	13	/* no	Match "" at nonwordchar, where prev is word */
100 #define	OPEN	20	/* no	Mark this point in input as start of #n. */
101 			/*	OPEN+1 is number 1, etc. */
102 #define	CLOSE	30	/* no	Analogous to OPEN. */
103 
104 /*
105  * Opcode notes:
106  *
107  * BRANCH	The set of branches constituting a single choice are hooked
108  *		together with their "next" pointers, since precedence prevents
109  *		anything being concatenated to any individual branch.  The
110  *		"next" pointer of the last BRANCH in a choice points to the
111  *		thing following the whole choice.  This is also where the
112  *		final "next" pointer of each individual branch points; each
113  *		branch starts with the operand node of a BRANCH node.
114  *
115  * BACK		Normal "next" pointers all implicitly point forward; BACK
116  *		exists to make loop structures possible.
117  *
118  * STAR,PLUS	'?', and complex '*' and '+', are implemented as circular
119  *		BRANCH structures using BACK.  Simple cases (one character
120  *		per match) are implemented with STAR and PLUS for speed
121  *		and to minimize recursive plunges.
122  *
123  * OPEN,CLOSE	...are numbered at compile time.
124  */
125 
126 /*
127  * A node is one char of opcode followed by two chars of "next" pointer.
128  * "Next" pointers are stored as two 8-bit pieces, high order first.  The
129  * value is a positive offset from the opcode of the node containing it.
130  * An operand, if any, simply follows the node.  (Note that much of the
131  * code generation knows about this implicit relationship.)
132  *
133  * Using two bytes for the "next" pointer is vast overkill for most things,
134  * but allows patterns to get big without disasters.
135  */
136 #define	OP(p)	(*(p))
137 #define	NEXT(p)	(((*((p)+1)&0377)<<8) + (*((p)+2)&0377))
138 #define	OPERAND(p)	((p) + 3)
139 
140 /*
141  * See regmagic.h for one further detail of program structure.
142  */
143 
144 
145 /*
146  * Utility definitions.
147  */
148 #ifndef CHARBITS
149 #define	UCHARAT(p)	((int)*(unsigned char *)(p))
150 #else
151 #define	UCHARAT(p)	((int)*(p)&CHARBITS)
152 #endif
153 
154 #define	FAIL(m)	{ v8_regerror(m); return(NULL); }
155 #define	ISMULT(c)	((c) == '*' || (c) == '+' || (c) == '?')
156 
157 /*
158  * Flags to be passed up and down.
159  */
160 #define	HASWIDTH	01	/* Known never to match null string. */
161 #define	SIMPLE		02	/* Simple enough to be STAR/PLUS operand. */
162 #define	SPSTART		04	/* Starts with * or +. */
163 #define	WORST		0	/* Worst case. */
164 
165 /*
166  * Global work variables for regcomp().
167  */
168 static char *regparse;		/* Input-scan pointer. */
169 static int regnpar;		/* () count. */
170 static char regdummy;
171 static char *regcode;		/* Code-emit pointer; &regdummy = don't. */
172 static long regsize;		/* Code size. */
173 
174 /*
175  * Forward declarations for regcomp()'s friends.
176  */
177 #ifndef STATIC
178 #define	STATIC	static
179 #endif
180 STATIC char *reg(int, int *);
181 STATIC char *regbranch(int *);
182 STATIC char *regpiece(int *);
183 STATIC char *regatom(int *);
184 STATIC char *regnode(char);
185 STATIC char *regnext(char *);
186 STATIC void regc(char);
187 STATIC void reginsert(char, char *);
188 STATIC void regtail(char *, char *);
189 STATIC void regoptail(char *, char *);
190 #ifdef STRCSPN
191 STATIC int strcspn(char *, char *);
192 #endif
193 
194 /*
195  - regcomp - compile a regular expression into internal code
196  *
197  * We can't allocate space until we know how big the compiled form will be,
198  * but we can't compile it (and thus know how big it is) until we've got a
199  * place to put the code.  So we cheat:  we compile it twice, once with code
200  * generation turned off and size counting turned on, and once "for real".
201  * This also means that we don't allocate space until we are sure that the
202  * thing really will compile successfully, and we never have to move the
203  * code and thus invalidate pointers into it.  (Note that it has to be in
204  * one piece because free() must be able to free it all.)
205  *
206  * Beware that the optimization-preparation code in here knows about some
207  * of the structure of the compiled regexp.
208  */
209 regexp *
v8_regcomp(exp)210 v8_regcomp(exp)
211 const char *exp;
212 {
213 	register regexp *r;
214 	register char *scan;
215 	register char *longest;
216 	register int len;
217 	int flags;
218 
219 	if (exp == NULL)
220 		FAIL("NULL argument");
221 
222 	/* First pass: determine size, legality. */
223 #ifdef notdef
224 	if (exp[0] == '.' && exp[1] == '*') exp += 2;  /* aid grep */
225 #endif
226 	regparse = (char *)exp;
227 	regnpar = 1;
228 	regsize = 0L;
229 	regcode = &regdummy;
230 	regc(MAGIC);
231 	if (reg(0, &flags) == NULL)
232 		return(NULL);
233 
234 	/* Small enough for pointer-storage convention? */
235 	if (regsize >= 32767L)		/* Probably could be 65535L. */
236 		FAIL("regexp too big");
237 
238 	/* Allocate space. */
239 	r = (regexp *)malloc(sizeof(regexp) + (unsigned)regsize);
240 	if (r == NULL)
241 		FAIL("out of space");
242 
243 	/* Second pass: emit code. */
244 	regparse = (char *)exp;
245 	regnpar = 1;
246 	regcode = r->program;
247 	regc(MAGIC);
248 	if (reg(0, &flags) == NULL)
249 		return(NULL);
250 
251 	/* Dig out information for optimizations. */
252 	r->regstart = '\0';	/* Worst-case defaults. */
253 	r->reganch = 0;
254 	r->regmust = NULL;
255 	r->regmlen = 0;
256 	scan = r->program+1;			/* First BRANCH. */
257 	if (OP(regnext(scan)) == END) {		/* Only one top-level choice. */
258 		scan = OPERAND(scan);
259 
260 		/* Starting-point info. */
261 		if (OP(scan) == EXACTLY)
262 			r->regstart = *OPERAND(scan);
263 		else if (OP(scan) == BOL)
264 			r->reganch++;
265 
266 		/*
267 		 * If there's something expensive in the r.e., find the
268 		 * longest literal string that must appear and make it the
269 		 * regmust.  Resolve ties in favor of later strings, since
270 		 * the regstart check works with the beginning of the r.e.
271 		 * and avoiding duplication strengthens checking.  Not a
272 		 * strong reason, but sufficient in the absence of others.
273 		 */
274 		if (flags&SPSTART) {
275 			longest = NULL;
276 			len = 0;
277 			for (; scan != NULL; scan = regnext(scan))
278 				if (OP(scan) == EXACTLY && strlen(OPERAND(scan)) >= len) {
279 					longest = OPERAND(scan);
280 					len = strlen(OPERAND(scan));
281 				}
282 			r->regmust = longest;
283 			r->regmlen = len;
284 		}
285 	}
286 
287 	return(r);
288 }
289 
290 /*
291  - reg - regular expression, i.e. main body or parenthesized thing
292  *
293  * Caller must absorb opening parenthesis.
294  *
295  * Combining parenthesis handling with the base level of regular expression
296  * is a trifle forced, but the need to tie the tails of the branches to what
297  * follows makes it hard to avoid.
298  */
299 static char *
reg(paren,flagp)300 reg(paren, flagp)
301 int paren;			/* Parenthesized? */
302 int *flagp;
303 {
304 	register char *ret;
305 	register char *br;
306 	register char *ender;
307 	register int parno = 0;
308 	int flags;
309 
310 	*flagp = HASWIDTH;	/* Tentatively. */
311 
312 	/* Make an OPEN node, if parenthesized. */
313 	if (paren) {
314 		if (regnpar >= NSUBEXP)
315 			FAIL("too many ()");
316 		parno = regnpar;
317 		regnpar++;
318 		ret = regnode(OPEN+parno);
319 	} else
320 		ret = NULL;
321 
322 	/* Pick up the branches, linking them together. */
323 	br = regbranch(&flags);
324 	if (br == NULL)
325 		return(NULL);
326 	if (ret != NULL)
327 		regtail(ret, br);	/* OPEN -> first. */
328 	else
329 		ret = br;
330 	if (!(flags&HASWIDTH))
331 		*flagp &= ~HASWIDTH;
332 	*flagp |= flags&SPSTART;
333 	while (*regparse == '|' || *regparse == '\n') {
334 		regparse++;
335 		br = regbranch(&flags);
336 		if (br == NULL)
337 			return(NULL);
338 		regtail(ret, br);	/* BRANCH -> BRANCH. */
339 		if (!(flags&HASWIDTH))
340 			*flagp &= ~HASWIDTH;
341 		*flagp |= flags&SPSTART;
342 	}
343 
344 	/* Make a closing node, and hook it on the end. */
345 	ender = regnode((paren) ? CLOSE+parno : END);
346 	regtail(ret, ender);
347 
348 	/* Hook the tails of the branches to the closing node. */
349 	for (br = ret; br != NULL; br = regnext(br))
350 		regoptail(br, ender);
351 
352 	/* Check for proper termination. */
353 	if (paren && *regparse++ != ')') {
354 		FAIL("unmatched ()");
355 	} else if (!paren && *regparse != '\0') {
356 		if (*regparse == ')') {
357 			FAIL("unmatched ()");
358 		} else
359 			FAIL("junk on end");	/* "Can't happen". */
360 		/* NOTREACHED */
361 	}
362 
363 	return(ret);
364 }
365 
366 /*
367  - regbranch - one alternative of an | operator
368  *
369  * Implements the concatenation operator.
370  */
371 static char *
regbranch(flagp)372 regbranch(flagp)
373 int *flagp;
374 {
375 	register char *ret;
376 	register char *chain;
377 	register char *latest;
378 	int flags;
379 
380 	*flagp = WORST;		/* Tentatively. */
381 
382 	ret = regnode(BRANCH);
383 	chain = NULL;
384 	while (*regparse != '\0' && *regparse != ')' &&
385 	       *regparse != '\n' && *regparse != '|') {
386 		latest = regpiece(&flags);
387 		if (latest == NULL)
388 			return(NULL);
389 		*flagp |= flags&HASWIDTH;
390 		if (chain == NULL)	/* First piece. */
391 			*flagp |= flags&SPSTART;
392 		else
393 			regtail(chain, latest);
394 		chain = latest;
395 	}
396 	if (chain == NULL)	/* Loop ran zero times. */
397 		(void) regnode(NOTHING);
398 
399 	return(ret);
400 }
401 
402 /*
403  - regpiece - something followed by possible [*+?]
404  *
405  * Note that the branching code sequences used for ? and the general cases
406  * of * and + are somewhat optimized:  they use the same NOTHING node as
407  * both the endmarker for their branch list and the body of the last branch.
408  * It might seem that this node could be dispensed with entirely, but the
409  * endmarker role is not redundant.
410  */
411 static char *
regpiece(flagp)412 regpiece(flagp)
413 int *flagp;
414 {
415 	register char *ret;
416 	register char op;
417 	register char *next;
418 	int flags;
419 
420 	ret = regatom(&flags);
421 	if (ret == NULL)
422 		return(NULL);
423 
424 	op = *regparse;
425 	if (!ISMULT(op)) {
426 		*flagp = flags;
427 		return(ret);
428 	}
429 
430 	if (!(flags&HASWIDTH) && op != '?')
431 		FAIL("*+ operand could be empty");
432 	*flagp = (op != '+') ? (WORST|SPSTART) : (WORST|HASWIDTH);
433 
434 	if (op == '*' && (flags&SIMPLE))
435 		reginsert(STAR, ret);
436 	else if (op == '*') {
437 		/* Emit x* as (x&|), where & means "self". */
438 		reginsert(BRANCH, ret);			/* Either x */
439 		regoptail(ret, regnode(BACK));		/* and loop */
440 		regoptail(ret, ret);			/* back */
441 		regtail(ret, regnode(BRANCH));		/* or */
442 		regtail(ret, regnode(NOTHING));		/* null. */
443 	} else if (op == '+' && (flags&SIMPLE))
444 		reginsert(PLUS, ret);
445 	else if (op == '+') {
446 		/* Emit x+ as x(&|), where & means "self". */
447 		next = regnode(BRANCH);			/* Either */
448 		regtail(ret, next);
449 		regtail(regnode(BACK), ret);		/* loop back */
450 		regtail(next, regnode(BRANCH));		/* or */
451 		regtail(ret, regnode(NOTHING));		/* null. */
452 	} else if (op == '?') {
453 		/* Emit x? as (x|) */
454 		reginsert(BRANCH, ret);			/* Either x */
455 		regtail(ret, regnode(BRANCH));		/* or */
456 		next = regnode(NOTHING);		/* null. */
457 		regtail(ret, next);
458 		regoptail(ret, next);
459 	}
460 	regparse++;
461 	if (ISMULT(*regparse))
462 		FAIL("nested *?+");
463 
464 	return(ret);
465 }
466 
467 /*
468  - regatom - the lowest level
469  *
470  * Optimization:  gobbles an entire sequence of ordinary characters so that
471  * it can turn them into a single node, which is smaller to store and
472  * faster to run.  Backslashed characters are exceptions, each becoming a
473  * separate node; the code is simpler that way and it's not worth fixing.
474  */
475 static char *
regatom(flagp)476 regatom(flagp)
477 int *flagp;
478 {
479 	register char *ret;
480 	int flags;
481 
482 	*flagp = WORST;		/* Tentatively. */
483 
484 	switch (*regparse++) {
485 	/* FIXME: these chars only have meaning at beg/end of pat? */
486 	case '^':
487 		ret = regnode(BOL);
488 		break;
489 	case '$':
490 		ret = regnode(EOL);
491 		break;
492 	case '.':
493 		ret = regnode(ANY);
494 		*flagp |= HASWIDTH|SIMPLE;
495 		break;
496 	case '[': {
497 			register int class;
498 			register int classend;
499 
500 			if (*regparse == '^') {	/* Complement of range. */
501 				ret = regnode(ANYBUT);
502 				regparse++;
503 			} else
504 				ret = regnode(ANYOF);
505 			if (*regparse == ']' || *regparse == '-')
506 				regc(*regparse++);
507 			while (*regparse != '\0' && *regparse != ']') {
508 				if (*regparse == '-') {
509 					regparse++;
510 					if (*regparse == ']' || *regparse == '\0')
511 						regc('-');
512 					else {
513 						class = UCHARAT(regparse-2)+1;
514 						classend = UCHARAT(regparse);
515 						if (class > classend+1)
516 							FAIL("invalid [] range");
517 						for (; class <= classend; class++)
518 							regc(class);
519 						regparse++;
520 					}
521 				} else
522 					regc(*regparse++);
523 			}
524 			regc('\0');
525 			if (*regparse != ']')
526 				FAIL("unmatched []");
527 			regparse++;
528 			*flagp |= HASWIDTH|SIMPLE;
529 		}
530 		break;
531 	case '(':
532 		ret = reg(1, &flags);
533 		if (ret == NULL)
534 			return(NULL);
535 		*flagp |= flags&(HASWIDTH|SPSTART);
536 		break;
537 	case '\0':
538 	case '|':
539 	case '\n':
540 	case ')':
541 		FAIL("internal urp");	/* Supposed to be caught earlier. */
542 		break;
543 	case '?':
544 	case '+':
545 	case '*':
546 		FAIL("?+* follows nothing");
547 		break;
548 	case '\\':
549 		switch (*regparse++) {
550 		case '\0':
551 			FAIL("trailing \\");
552 			break;
553 		case '<':
554 			ret = regnode(WORDA);
555 			break;
556 		case '>':
557 			ret = regnode(WORDZ);
558 			break;
559 		/* FIXME: Someday handle \1, \2, ... */
560 		default:
561 			/* Handle general quoted chars in exact-match routine */
562 			goto de_fault;
563 		}
564 		break;
565 	de_fault:
566 	default:
567 		/*
568 		 * Encode a string of characters to be matched exactly.
569 		 *
570 		 * This is a bit tricky due to quoted chars and due to
571 		 * '*', '+', and '?' taking the SINGLE char previous
572 		 * as their operand.
573 		 *
574 		 * On entry, the char at regparse[-1] is going to go
575 		 * into the string, no matter what it is.  (It could be
576 		 * following a \ if we are entered from the '\' case.)
577 		 *
578 		 * Basic idea is to pick up a good char in  ch  and
579 		 * examine the next char.  If it's *+? then we twiddle.
580 		 * If it's \ then we frozzle.  If it's other magic char
581 		 * we push  ch  and terminate the string.  If none of the
582 		 * above, we push  ch  on the string and go around again.
583 		 *
584 		 *  regprev  is used to remember where "the current char"
585 		 * starts in the string, if due to a *+? we need to back
586 		 * up and put the current char in a separate, 1-char, string.
587 		 * When  regprev  is NULL,  ch  is the only char in the
588 		 * string; this is used in *+? handling, and in setting
589 		 * flags |= SIMPLE at the end.
590 		 */
591 		{
592 			char *regprev;
593 			register char ch;
594 
595 			regparse--;			/* Look at cur char */
596 			ret = regnode(EXACTLY);
597 			for ( regprev = 0 ; ; ) {
598 				ch = *regparse++;	/* Get current char */
599 				switch (*regparse) {	/* look at next one */
600 
601 				default:
602 					regc(ch);	/* Add cur to string */
603 					break;
604 
605 				case '.': case '[': case '(':
606 				case ')': case '|': case '\n':
607 				case '$': case '^':
608 				case '\0':
609 				/* FIXME, $ and ^ should not always be magic */
610 				magic:
611 					regc(ch);	/* dump cur char */
612 					goto done;	/* and we are done */
613 
614 				case '?': case '+': case '*':
615 					if (!regprev) 	/* If just ch in str, */
616 						goto magic;	/* use it */
617 					/* End mult-char string one early */
618 					regparse = regprev; /* Back up parse */
619 					goto done;
620 
621 				case '\\':
622 					regc(ch);	/* Cur char OK */
623 					switch (regparse[1]){ /* Look after \ */
624 					case '\0':
625 					case '<':
626 					case '>':
627 					/* FIXME: Someday handle \1, \2, ... */
628 						goto done; /* Not quoted */
629 					default:
630 						/* Backup point is \, scan							 * point is after it. */
631 						regprev = regparse;
632 						regparse++;
633 						continue;	/* NOT break; */
634 					}
635 				}
636 				regprev = regparse;	/* Set backup point */
637 			}
638 		done:
639 			regc('\0');
640 			*flagp |= HASWIDTH;
641 			if (!regprev)		/* One char? */
642 				*flagp |= SIMPLE;
643 		}
644 		break;
645 	}
646 
647 	return(ret);
648 }
649 
650 /*
651  - regnode - emit a node
652  */
653 static char *			/* Location. */
regnode(op)654 regnode(op)
655 char op;
656 {
657 	register char *ret;
658 	register char *ptr;
659 
660 	ret = regcode;
661 	if (ret == &regdummy) {
662 		regsize += 3;
663 		return(ret);
664 	}
665 
666 	ptr = ret;
667 	*ptr++ = op;
668 	*ptr++ = '\0';		/* Null "next" pointer. */
669 	*ptr++ = '\0';
670 	regcode = ptr;
671 
672 	return(ret);
673 }
674 
675 /*
676  - regc - emit (if appropriate) a byte of code
677  */
678 static void
regc(b)679 regc(b)
680 char b;
681 {
682 	if (regcode != &regdummy)
683 		*regcode++ = b;
684 	else
685 		regsize++;
686 }
687 
688 /*
689  - reginsert - insert an operator in front of already-emitted operand
690  *
691  * Means relocating the operand.
692  */
693 static void
reginsert(op,opnd)694 reginsert(op, opnd)
695 char op;
696 char *opnd;
697 {
698 	register char *src;
699 	register char *dst;
700 	register char *place;
701 
702 	if (regcode == &regdummy) {
703 		regsize += 3;
704 		return;
705 	}
706 
707 	src = regcode;
708 	regcode += 3;
709 	dst = regcode;
710 	while (src > opnd)
711 		*--dst = *--src;
712 
713 	place = opnd;		/* Op node, where operand used to be. */
714 	*place++ = op;
715 	*place++ = '\0';
716 	*place++ = '\0';
717 }
718 
719 /*
720  - regtail - set the next-pointer at the end of a node chain
721  */
722 static void
regtail(p,val)723 regtail(p, val)
724 char *p;
725 char *val;
726 {
727 	register char *scan;
728 	register char *temp;
729 	register int offset;
730 
731 	if (p == &regdummy)
732 		return;
733 
734 	/* Find last node. */
735 	scan = p;
736 	for (;;) {
737 		temp = regnext(scan);
738 		if (temp == NULL)
739 			break;
740 		scan = temp;
741 	}
742 
743 	if (OP(scan) == BACK)
744 		offset = scan - val;
745 	else
746 		offset = val - scan;
747 	*(scan+1) = (offset>>8)&0377;
748 	*(scan+2) = offset&0377;
749 }
750 
751 /*
752  - regoptail - regtail on operand of first argument; nop if operandless
753  */
754 static void
regoptail(p,val)755 regoptail(p, val)
756 char *p;
757 char *val;
758 {
759 	/* "Operandless" and "op != BRANCH" are synonymous in practice. */
760 	if (p == NULL || p == &regdummy || OP(p) != BRANCH)
761 		return;
762 	regtail(OPERAND(p), val);
763 }
764 
765 /*
766  * regexec and friends
767  */
768 
769 /*
770  * Global work variables for regexec().
771  */
772 static char *reginput;		/* String-input pointer. */
773 static char *regbol;		/* Beginning of input, for ^ check. */
774 static char **regstartp;	/* Pointer to startp array. */
775 static char **regendp;		/* Ditto for endp. */
776 
777 /*
778  * Forwards.
779  */
780 STATIC int regtry(const regexp *, const char *);
781 STATIC int regmatch(char *);
782 STATIC int regrepeat(char *);
783 
784 #ifdef DEBUG
785 int regnarrate = 0;
786 void regdump(regexp *);
787 STATIC char *regprop(char *);
788 #endif
789 
790 /*
791  - regexec - match a regexp against a string
792  */
793 int
v8_regexec(prog,string)794 v8_regexec(prog, string)
795 register const regexp *prog;
796 register const char *string;
797 {
798 	register char *s;
799 
800 	/* Be paranoid... */
801 	if (prog == NULL || string == NULL) {
802 		v8_regerror("NULL parameter");
803 		return(0);
804 	}
805 
806 	/* Check validity of program. */
807 	if (UCHARAT(prog->program) != MAGIC) {
808 		v8_regerror("corrupted program");
809 		return(0);
810 	}
811 
812 	/* If there is a "must appear" string, look for it. */
813 	if (prog->regmust != NULL) {
814 		s = (char *)string;
815 		while ((s = strchr(s, prog->regmust[0])) != NULL) {
816 			if (strncmp(s, prog->regmust, prog->regmlen) == 0)
817 				break;	/* Found it. */
818 			s++;
819 		}
820 		if (s == NULL)	/* Not present. */
821 			return(0);
822 	}
823 
824 	/* Mark beginning of line for ^ . */
825 	regbol = (char *)string;
826 
827 	/* Simplest case:  anchored match need be tried only once. */
828 	if (prog->reganch)
829 		return(regtry(prog, string));
830 
831 	/* Messy cases:  unanchored match. */
832 	s = (char *)string;
833 	if (prog->regstart != '\0')
834 		/* We know what char it must start with. */
835 		while ((s = strchr(s, prog->regstart)) != NULL) {
836 			if (regtry(prog, s))
837 				return(1);
838 			s++;
839 		}
840 	else
841 		/* We don't -- general case. */
842 		do {
843 			if (regtry(prog, s))
844 				return(1);
845 		} while (*s++ != '\0');
846 
847 	/* Failure. */
848 	return(0);
849 }
850 
851 /*
852  - regtry - try match at specific point
853  */
854 static int			/* 0 failure, 1 success */
regtry(prog,string)855 regtry(prog, string)
856 const regexp *prog;
857 const char *string;
858 {
859 	register int i;
860 	register char **sp;
861 	register char **ep;
862 
863 	reginput = (char *)string;				/* XXX */
864 	regstartp = (char **)prog->startp;			/* XXX */
865 	regendp = (char **)prog->endp;				/* XXX */
866 
867 	sp = (char **)prog->startp;				/* XXX */
868 	ep = (char **)prog->endp;				/* XXX */
869 	for (i = NSUBEXP; i > 0; i--) {
870 		*sp++ = NULL;
871 		*ep++ = NULL;
872 	}
873 	if (regmatch((char *)prog->program + 1)) {		/* XXX */
874 		((regexp *)prog)->startp[0] = (char *)string;	/* XXX */
875 		((regexp *)prog)->endp[0] = reginput;		/* XXX */
876 		return(1);
877 	} else
878 		return(0);
879 }
880 
881 /*
882  - regmatch - main matching routine
883  *
884  * Conceptually the strategy is simple:  check to see whether the current
885  * node matches, call self recursively to see whether the rest matches,
886  * and then act accordingly.  In practice we make some effort to avoid
887  * recursion, in particular by going through "ordinary" nodes (that don't
888  * need to know whether the rest of the match failed) by a loop instead of
889  * by recursion.
890  */
891 static int			/* 0 failure, 1 success */
regmatch(prog)892 regmatch(prog)
893 char *prog;
894 {
895 	register char *scan;	/* Current node. */
896 	char *next;		/* Next node. */
897 
898 	scan = prog;
899 #ifdef DEBUG
900 	if (scan != NULL && regnarrate)
901 		fprintf(stderr, "%s(\n", regprop(scan));
902 #endif
903 	while (scan != NULL) {
904 #ifdef DEBUG
905 		if (regnarrate)
906 			fprintf(stderr, "%s...\n", regprop(scan));
907 #endif
908 		next = regnext(scan);
909 
910 		switch (OP(scan)) {
911 		case BOL:
912 			if (reginput != regbol)
913 				return(0);
914 			break;
915 		case EOL:
916 			if (*reginput != '\0')
917 				return(0);
918 			break;
919 		case WORDA:
920 			/* Must be looking at a letter, digit, or _ */
921 			if ((!isalnum(*reginput)) && *reginput != '_')
922 				return(0);
923 			/* Prev must be BOL or nonword */
924 			if (reginput > regbol &&
925 			    (isalnum(reginput[-1]) || reginput[-1] == '_'))
926 				return(0);
927 			break;
928 		case WORDZ:
929 			/* Must be looking at non letter, digit, or _ */
930 			if (isalnum(*reginput) || *reginput == '_')
931 				return(0);
932 			/* We don't care what the previous char was */
933 			break;
934 		case ANY:
935 			if (*reginput == '\0')
936 				return(0);
937 			reginput++;
938 			break;
939 		case EXACTLY: {
940 				register int len;
941 				register char *opnd;
942 
943 				opnd = OPERAND(scan);
944 				/* Inline the first character, for speed. */
945 				if (*opnd != *reginput)
946 					return(0);
947 				len = strlen(opnd);
948 				if (len > 1 && strncmp(opnd, reginput, len) != 0)
949 					return(0);
950 				reginput += len;
951 			}
952 			break;
953 		case ANYOF:
954  			if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) == NULL)
955 				return(0);
956 			reginput++;
957 			break;
958 		case ANYBUT:
959  			if (*reginput == '\0' || strchr(OPERAND(scan), *reginput) != NULL)
960 				return(0);
961 			reginput++;
962 			break;
963 		case NOTHING:
964 			break;
965 		case BACK:
966 			break;
967 		case OPEN+1:
968 		case OPEN+2:
969 		case OPEN+3:
970 		case OPEN+4:
971 		case OPEN+5:
972 		case OPEN+6:
973 		case OPEN+7:
974 		case OPEN+8:
975 		case OPEN+9: {
976 				register int no;
977 				register char *save;
978 
979 				no = OP(scan) - OPEN;
980 				save = reginput;
981 
982 				if (regmatch(next)) {
983 					/*
984 					 * Don't set startp if some later
985 					 * invocation of the same parentheses
986 					 * already has.
987 					 */
988 					if (regstartp[no] == NULL)
989 						regstartp[no] = save;
990 					return(1);
991 				} else
992 					return(0);
993 			}
994 			break;
995 		case CLOSE+1:
996 		case CLOSE+2:
997 		case CLOSE+3:
998 		case CLOSE+4:
999 		case CLOSE+5:
1000 		case CLOSE+6:
1001 		case CLOSE+7:
1002 		case CLOSE+8:
1003 		case CLOSE+9: {
1004 				register int no;
1005 				register char *save;
1006 
1007 				no = OP(scan) - CLOSE;
1008 				save = reginput;
1009 
1010 				if (regmatch(next)) {
1011 					/*
1012 					 * Don't set endp if some later
1013 					 * invocation of the same parentheses
1014 					 * already has.
1015 					 */
1016 					if (regendp[no] == NULL)
1017 						regendp[no] = save;
1018 					return(1);
1019 				} else
1020 					return(0);
1021 			}
1022 			break;
1023 		case BRANCH: {
1024 				register char *save;
1025 
1026 				if (OP(next) != BRANCH)		/* No choice. */
1027 					next = OPERAND(scan);	/* Avoid recursion. */
1028 				else {
1029 					do {
1030 						save = reginput;
1031 						if (regmatch(OPERAND(scan)))
1032 							return(1);
1033 						reginput = save;
1034 						scan = regnext(scan);
1035 					} while (scan != NULL && OP(scan) == BRANCH);
1036 					return(0);
1037 					/* NOTREACHED */
1038 				}
1039 			}
1040 			break;
1041 		case STAR:
1042 		case PLUS: {
1043 				register char nextch;
1044 				register int no;
1045 				register char *save;
1046 				register int min;
1047 
1048 				/*
1049 				 * Lookahead to avoid useless match attempts
1050 				 * when we know what character comes next.
1051 				 */
1052 				nextch = '\0';
1053 				if (OP(next) == EXACTLY)
1054 					nextch = *OPERAND(next);
1055 				min = (OP(scan) == STAR) ? 0 : 1;
1056 				save = reginput;
1057 				no = regrepeat(OPERAND(scan));
1058 				while (no >= min) {
1059 					/* If it could work, try it. */
1060 					if (nextch == '\0' || *reginput == nextch)
1061 						if (regmatch(next))
1062 							return(1);
1063 					/* Couldn't or didn't -- back up. */
1064 					no--;
1065 					reginput = save + no;
1066 				}
1067 				return(0);
1068 			}
1069 			break;
1070 		case END:
1071 			return(1);	/* Success! */
1072 			break;
1073 		default:
1074 			v8_regerror("memory corruption");
1075 			return(0);
1076 			break;
1077 		}
1078 
1079 		scan = next;
1080 	}
1081 
1082 	/*
1083 	 * We get here only if there's trouble -- normally "case END" is
1084 	 * the terminating point.
1085 	 */
1086 	v8_regerror("corrupted pointers");
1087 	return(0);
1088 }
1089 
1090 /*
1091  - regrepeat - repeatedly match something simple, report how many
1092  */
1093 static int
regrepeat(p)1094 regrepeat(p)
1095 char *p;
1096 {
1097 	register int count = 0;
1098 	register char *scan;
1099 	register char *opnd;
1100 
1101 	scan = reginput;
1102 	opnd = OPERAND(p);
1103 	switch (OP(p)) {
1104 	case ANY:
1105 		count = strlen(scan);
1106 		scan += count;
1107 		break;
1108 	case EXACTLY:
1109 		while (*opnd == *scan) {
1110 			count++;
1111 			scan++;
1112 		}
1113 		break;
1114 	case ANYOF:
1115 		while (*scan != '\0' && strchr(opnd, *scan) != NULL) {
1116 			count++;
1117 			scan++;
1118 		}
1119 		break;
1120 	case ANYBUT:
1121 		while (*scan != '\0' && strchr(opnd, *scan) == NULL) {
1122 			count++;
1123 			scan++;
1124 		}
1125 		break;
1126 	default:		/* Oh dear.  Called inappropriately. */
1127 		v8_regerror("internal foulup");
1128 		count = 0;	/* Best compromise. */
1129 		break;
1130 	}
1131 	reginput = scan;
1132 
1133 	return(count);
1134 }
1135 
1136 /*
1137  - regnext - dig the "next" pointer out of a node
1138  */
1139 static char *
regnext(p)1140 regnext(p)
1141 register char *p;
1142 {
1143 	register int offset;
1144 
1145 	if (p == &regdummy)
1146 		return(NULL);
1147 
1148 	offset = NEXT(p);
1149 	if (offset == 0)
1150 		return(NULL);
1151 
1152 	if (OP(p) == BACK)
1153 		return(p-offset);
1154 	else
1155 		return(p+offset);
1156 }
1157 
1158 #ifdef DEBUG
1159 
1160 /*
1161  - regdump - dump a regexp onto stdout in vaguely comprehensible form
1162  */
1163 void
regdump(r)1164 regdump(r)
1165 regexp *r;
1166 {
1167 	register char *s;
1168 	register char op = EXACTLY;	/* Arbitrary non-END op. */
1169 	register char *next;
1170 	extern char *strchr();
1171 
1172 
1173 	s = r->program + 1;
1174 	while (op != END) {	/* While that wasn't END last time... */
1175 		op = OP(s);
1176 		printf("%2d%s", s-r->program, regprop(s));	/* Where, what. */
1177 		next = regnext(s);
1178 		if (next == NULL)		/* Next ptr. */
1179 			printf("(0)");
1180 		else
1181 			printf("(%d)", (s-r->program)+(next-s));
1182 		s += 3;
1183 		if (op == ANYOF || op == ANYBUT || op == EXACTLY) {
1184 			/* Literal string, where present. */
1185 			while (*s != '\0') {
1186 				putchar(*s);
1187 				s++;
1188 			}
1189 			s++;
1190 		}
1191 		putchar('\n');
1192 	}
1193 
1194 	/* Header fields of interest. */
1195 	if (r->regstart != '\0')
1196 		printf("start `%c' ", r->regstart);
1197 	if (r->reganch)
1198 		printf("anchored ");
1199 	if (r->regmust != NULL)
1200 		printf("must have \"%s\"", r->regmust);
1201 	printf("\n");
1202 }
1203 
1204 /*
1205  - regprop - printable representation of opcode
1206  */
1207 static char *
regprop(op)1208 regprop(op)
1209 char *op;
1210 {
1211 	register char *p = NULL;
1212 	static char buf[50];
1213 
1214 	switch (OP(op)) {
1215 	case BOL:
1216 		p = "BOL";
1217 		break;
1218 	case EOL:
1219 		p = "EOL";
1220 		break;
1221 	case ANY:
1222 		p = "ANY";
1223 		break;
1224 	case ANYOF:
1225 		p = "ANYOF";
1226 		break;
1227 	case ANYBUT:
1228 		p = "ANYBUT";
1229 		break;
1230 	case BRANCH:
1231 		p = "BRANCH";
1232 		break;
1233 	case EXACTLY:
1234 		p = "EXACTLY";
1235 		break;
1236 	case NOTHING:
1237 		p = "NOTHING";
1238 		break;
1239 	case BACK:
1240 		p = "BACK";
1241 		break;
1242 	case END:
1243 		p = "END";
1244 		break;
1245 	case OPEN+1:
1246 	case OPEN+2:
1247 	case OPEN+3:
1248 	case OPEN+4:
1249 	case OPEN+5:
1250 	case OPEN+6:
1251 	case OPEN+7:
1252 	case OPEN+8:
1253 	case OPEN+9:
1254 		snprintf(buf, sizeof buf, ":OPEN%d", OP(op)-OPEN);
1255 		break;
1256 	case CLOSE+1:
1257 	case CLOSE+2:
1258 	case CLOSE+3:
1259 	case CLOSE+4:
1260 	case CLOSE+5:
1261 	case CLOSE+6:
1262 	case CLOSE+7:
1263 	case CLOSE+8:
1264 	case CLOSE+9:
1265 		snprintf(buf, sizeof buf, ":CLOSE%d", OP(op)-CLOSE);
1266 		break;
1267 	case STAR:
1268 		p = "STAR";
1269 		break;
1270 	case PLUS:
1271 		p = "PLUS";
1272 		break;
1273 	case WORDA:
1274 		p = "WORDA";
1275 		break;
1276 	case WORDZ:
1277 		p = "WORDZ";
1278 		break;
1279 	default:
1280 		v8_regerror("corrupted opcode");
1281 		p = "ERROR";
1282 		break;
1283 	}
1284 	if (p != NULL)
1285 		(void) snprintf(buf, sizeof buf, ":%s", p);
1286 	return(buf);
1287 }
1288 #endif
1289 
1290 /*
1291  * The following is provided for those people who do not have strcspn() in
1292  * their C libraries.  They should get off their butts and do something
1293  * about it; at least one public-domain implementation of those (highly
1294  * useful) string routines has been published on Usenet.
1295  */
1296 #ifdef STRCSPN
1297 /*
1298  * strcspn - find length of initial segment of s1 consisting entirely
1299  * of characters not from s2
1300  */
1301 
1302 static int
strcspn(s1,s2)1303 strcspn(s1, s2)
1304 char *s1;
1305 char *s2;
1306 {
1307 	register char *scan1;
1308 	register char *scan2;
1309 	register int count;
1310 
1311 	count = 0;
1312 	for (scan1 = s1; *scan1 != '\0'; scan1++) {
1313 		for (scan2 = s2; *scan2 != '\0';)	/* ++ moved down. */
1314 			if (*scan1 == *scan2++)
1315 				return(count);
1316 		count++;
1317 	}
1318 	return(count);
1319 }
1320 #endif
1321