1 /*
2  * re_*comp and friends - compile REs
3  * This file #includes several others (see the bottom).
4  *
5  * Copyright (c) 1998, 1999 Henry Spencer.  All rights reserved.
6  *
7  * Development of this software was funded, in part, by Cray Research Inc.,
8  * UUNET Communications Services Inc., Sun Microsystems Inc., and Scriptics
9  * Corporation, none of whom are responsible for the results.  The author
10  * thanks all of them.
11  *
12  * Redistribution and use in source and binary forms -- with or without
13  * modification -- are permitted for any purpose, provided that
14  * redistributions in source form retain this entire copyright notice and
15  * indicate the origin and nature of any modifications.
16  *
17  * I'd appreciate being given credit for this package in the documentation
18  * of software which uses it, but that is not a requirement.
19  *
20  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
21  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
22  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL
23  * HENRY SPENCER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30  *
31  * src/backend/regex/regcomp.c
32  *
33  */
34 
35 #include "regex/regguts.h"
36 
37 /*
38  * forward declarations, up here so forward datatypes etc. are defined early
39  */
40 /* === regcomp.c === */
41 static void moresubs(struct vars *, int);
42 static int	freev(struct vars *, int);
43 static void makesearch(struct vars *, struct nfa *);
44 static struct subre *parse(struct vars *, int, int, struct state *, struct state *);
45 static struct subre *parsebranch(struct vars *, int, int, struct state *, struct state *, int);
46 static void parseqatom(struct vars *, int, int, struct state *, struct state *, struct subre *);
47 static void nonword(struct vars *, int, struct state *, struct state *);
48 static void word(struct vars *, int, struct state *, struct state *);
49 static int	scannum(struct vars *);
50 static void repeat(struct vars *, struct state *, struct state *, int, int);
51 static void bracket(struct vars *, struct state *, struct state *);
52 static void cbracket(struct vars *, struct state *, struct state *);
53 static void brackpart(struct vars *, struct state *, struct state *);
54 static const chr *scanplain(struct vars *);
55 static void onechr(struct vars *, chr, struct state *, struct state *);
56 static void wordchrs(struct vars *);
57 static void processlacon(struct vars *, struct state *, struct state *, int,
58 			 struct state *, struct state *);
59 static struct subre *subre(struct vars *, int, int, struct state *, struct state *);
60 static void freesubre(struct vars *, struct subre *);
61 static void freesrnode(struct vars *, struct subre *);
62 static void optst(struct vars *, struct subre *);
63 static int	numst(struct subre *, int);
64 static void markst(struct subre *);
65 static void cleanst(struct vars *);
66 static long nfatree(struct vars *, struct subre *, FILE *);
67 static long nfanode(struct vars *, struct subre *, int, FILE *);
68 static int	newlacon(struct vars *, struct state *, struct state *, int);
69 static void freelacons(struct subre *, int);
70 static void rfree(regex_t *);
71 static int	rcancelrequested(void);
72 static int	rstacktoodeep(void);
73 
74 #ifdef REG_DEBUG
75 static void dump(regex_t *, FILE *);
76 static void dumpst(struct subre *, FILE *, int);
77 static void stdump(struct subre *, FILE *, int);
78 static const char *stid(struct subre *, char *, size_t);
79 #endif
80 /* === regc_lex.c === */
81 static void lexstart(struct vars *);
82 static void prefixes(struct vars *);
83 static void lexnest(struct vars *, const chr *, const chr *);
84 static void lexword(struct vars *);
85 static int	next(struct vars *);
86 static int	lexescape(struct vars *);
87 static chr	lexdigits(struct vars *, int, int, int);
88 static int	brenext(struct vars *, chr);
89 static void skip(struct vars *);
90 static chr	newline(void);
91 static chr	chrnamed(struct vars *, const chr *, const chr *, chr);
92 
93 /* === regc_color.c === */
94 static void initcm(struct vars *, struct colormap *);
95 static void freecm(struct colormap *);
96 static color maxcolor(struct colormap *);
97 static color newcolor(struct colormap *);
98 static void freecolor(struct colormap *, color);
99 static color pseudocolor(struct colormap *);
100 static color subcolor(struct colormap *, chr);
101 static color subcolorhi(struct colormap *, color *);
102 static color newsub(struct colormap *, color);
103 static int	newhicolorrow(struct colormap *, int);
104 static void newhicolorcols(struct colormap *);
105 static void subcolorcvec(struct vars *, struct cvec *, struct state *, struct state *);
106 static void subcoloronechr(struct vars *, chr, struct state *, struct state *, color *);
107 static void subcoloronerange(struct vars *, chr, chr, struct state *, struct state *, color *);
108 static void subcoloronerow(struct vars *, int, struct state *, struct state *, color *);
109 static void okcolors(struct nfa *, struct colormap *);
110 static void colorchain(struct colormap *, struct arc *);
111 static void uncolorchain(struct colormap *, struct arc *);
112 static void rainbow(struct nfa *, struct colormap *, int, color, struct state *, struct state *);
113 static void colorcomplement(struct nfa *, struct colormap *, int, struct state *, struct state *, struct state *);
114 
115 #ifdef REG_DEBUG
116 static void dumpcolors(struct colormap *, FILE *);
117 static void dumpchr(chr, FILE *);
118 #endif
119 /* === regc_nfa.c === */
120 static struct nfa *newnfa(struct vars *, struct colormap *, struct nfa *);
121 static void freenfa(struct nfa *);
122 static struct state *newstate(struct nfa *);
123 static struct state *newfstate(struct nfa *, int flag);
124 static void dropstate(struct nfa *, struct state *);
125 static void freestate(struct nfa *, struct state *);
126 static void destroystate(struct nfa *, struct state *);
127 static void newarc(struct nfa *, int, color, struct state *, struct state *);
128 static void createarc(struct nfa *, int, color, struct state *, struct state *);
129 static struct arc *allocarc(struct nfa *, struct state *);
130 static void freearc(struct nfa *, struct arc *);
131 static void changearctarget(struct arc *, struct state *);
132 static int	hasnonemptyout(struct state *);
133 static struct arc *findarc(struct state *, int, color);
134 static void cparc(struct nfa *, struct arc *, struct state *, struct state *);
135 static void sortins(struct nfa *, struct state *);
136 static int	sortins_cmp(const void *, const void *);
137 static void sortouts(struct nfa *, struct state *);
138 static int	sortouts_cmp(const void *, const void *);
139 static void moveins(struct nfa *, struct state *, struct state *);
140 static void copyins(struct nfa *, struct state *, struct state *);
141 static void mergeins(struct nfa *, struct state *, struct arc **, int);
142 static void moveouts(struct nfa *, struct state *, struct state *);
143 static void copyouts(struct nfa *, struct state *, struct state *);
144 static void cloneouts(struct nfa *, struct state *, struct state *, struct state *, int);
145 static void delsub(struct nfa *, struct state *, struct state *);
146 static void deltraverse(struct nfa *, struct state *, struct state *);
147 static void dupnfa(struct nfa *, struct state *, struct state *, struct state *, struct state *);
148 static void duptraverse(struct nfa *, struct state *, struct state *);
149 static void cleartraverse(struct nfa *, struct state *);
150 static struct state *single_color_transition(struct state *, struct state *);
151 static void specialcolors(struct nfa *);
152 static long optimize(struct nfa *, FILE *);
153 static void pullback(struct nfa *, FILE *);
154 static int	pull(struct nfa *, struct arc *, struct state **);
155 static void pushfwd(struct nfa *, FILE *);
156 static int	push(struct nfa *, struct arc *, struct state **);
157 
158 #define INCOMPATIBLE	1		/* destroys arc */
159 #define SATISFIED	2			/* constraint satisfied */
160 #define COMPATIBLE	3			/* compatible but not satisfied yet */
161 static int	combine(struct arc *, struct arc *);
162 static void fixempties(struct nfa *, FILE *);
163 static struct state *emptyreachable(struct nfa *, struct state *,
164 			   struct state *, struct arc **);
165 static int	isconstraintarc(struct arc *);
166 static int	hasconstraintout(struct state *);
167 static void fixconstraintloops(struct nfa *, FILE *);
168 static int	findconstraintloop(struct nfa *, struct state *);
169 static void breakconstraintloop(struct nfa *, struct state *);
170 static void clonesuccessorstates(struct nfa *, struct state *, struct state *,
171 					 struct state *, struct arc *,
172 					 char *, char *, int);
173 static void cleanup(struct nfa *);
174 static void markreachable(struct nfa *, struct state *, struct state *, struct state *);
175 static void markcanreach(struct nfa *, struct state *, struct state *, struct state *);
176 static long analyze(struct nfa *);
177 static void compact(struct nfa *, struct cnfa *);
178 static void carcsort(struct carc *, size_t);
179 static int	carc_cmp(const void *, const void *);
180 static void freecnfa(struct cnfa *);
181 static void dumpnfa(struct nfa *, FILE *);
182 
183 #ifdef REG_DEBUG
184 static void dumpstate(struct state *, FILE *);
185 static void dumparcs(struct state *, FILE *);
186 static void dumparc(struct arc *, struct state *, FILE *);
187 static void dumpcnfa(struct cnfa *, FILE *);
188 static void dumpcstate(int, struct cnfa *, FILE *);
189 #endif
190 /* === regc_cvec.c === */
191 static struct cvec *newcvec(int, int);
192 static struct cvec *clearcvec(struct cvec *);
193 static void addchr(struct cvec *, chr);
194 static void addrange(struct cvec *, chr, chr);
195 static struct cvec *getcvec(struct vars *, int, int);
196 static void freecvec(struct cvec *);
197 
198 /* === regc_pg_locale.c === */
199 static int	pg_wc_isdigit(pg_wchar c);
200 static int	pg_wc_isalpha(pg_wchar c);
201 static int	pg_wc_isalnum(pg_wchar c);
202 static int	pg_wc_isupper(pg_wchar c);
203 static int	pg_wc_islower(pg_wchar c);
204 static int	pg_wc_isgraph(pg_wchar c);
205 static int	pg_wc_isprint(pg_wchar c);
206 static int	pg_wc_ispunct(pg_wchar c);
207 static int	pg_wc_isspace(pg_wchar c);
208 static pg_wchar pg_wc_toupper(pg_wchar c);
209 static pg_wchar pg_wc_tolower(pg_wchar c);
210 
211 /* === regc_locale.c === */
212 static chr	element(struct vars *, const chr *, const chr *);
213 static struct cvec *range(struct vars *, chr, chr, int);
214 static int	before(chr, chr);
215 static struct cvec *eclass(struct vars *, chr, int);
216 static struct cvec *cclass(struct vars *, const chr *, const chr *, int);
217 static int	cclass_column_index(struct colormap *, chr);
218 static struct cvec *allcases(struct vars *, chr);
219 static int	cmp(const chr *, const chr *, size_t);
220 static int	casecmp(const chr *, const chr *, size_t);
221 
222 
223 /* internal variables, bundled for easy passing around */
224 struct vars
225 {
226 	regex_t    *re;
227 	const chr  *now;			/* scan pointer into string */
228 	const chr  *stop;			/* end of string */
229 	const chr  *savenow;		/* saved now and stop for "subroutine call" */
230 	const chr  *savestop;
231 	int			err;			/* error code (0 if none) */
232 	int			cflags;			/* copy of compile flags */
233 	int			lasttype;		/* type of previous token */
234 	int			nexttype;		/* type of next token */
235 	chr			nextvalue;		/* value (if any) of next token */
236 	int			lexcon;			/* lexical context type (see lex.c) */
237 	int			nsubexp;		/* subexpression count */
238 	struct subre **subs;		/* subRE pointer vector */
239 	size_t		nsubs;			/* length of vector */
240 	struct subre *sub10[10];	/* initial vector, enough for most */
241 	struct nfa *nfa;			/* the NFA */
242 	struct colormap *cm;		/* character color map */
243 	color		nlcolor;		/* color of newline */
244 	struct state *wordchrs;		/* state in nfa holding word-char outarcs */
245 	struct subre *tree;			/* subexpression tree */
246 	struct subre *treechain;	/* all tree nodes allocated */
247 	struct subre *treefree;		/* any free tree nodes */
248 	int			ntree;			/* number of tree nodes, plus one */
249 	struct cvec *cv;			/* interface cvec */
250 	struct cvec *cv2;			/* utility cvec */
251 	struct subre *lacons;		/* lookaround-constraint vector */
252 	int			nlacons;		/* size of lacons[]; note that only slots
253 								 * numbered 1 .. nlacons-1 are used */
254 	size_t		spaceused;		/* approx. space used for compilation */
255 };
256 
257 /* parsing macros; most know that `v' is the struct vars pointer */
258 #define NEXT()	(next(v))		/* advance by one token */
259 #define SEE(t)	(v->nexttype == (t))	/* is next token this? */
260 #define EAT(t)	(SEE(t) && next(v)) /* if next is this, swallow it */
261 #define VISERR(vv)	((vv)->err != 0)	/* have we seen an error yet? */
262 #define ISERR() VISERR(v)
263 #define VERR(vv,e)	((vv)->nexttype = EOS, \
264 					 (vv)->err = ((vv)->err ? (vv)->err : (e)))
265 #define ERR(e)	VERR(v, e)		/* record an error */
266 #define NOERR() {if (ISERR()) return;}	/* if error seen, return */
267 #define NOERRN()	{if (ISERR()) return NULL;} /* NOERR with retval */
268 #define NOERRZ()	{if (ISERR()) return 0;}	/* NOERR with retval */
269 #define INSIST(c, e) do { if (!(c)) ERR(e); } while (0) /* error if c false */
270 #define NOTE(b) (v->re->re_info |= (b)) /* note visible condition */
271 #define EMPTYARC(x, y)	newarc(v->nfa, EMPTY, 0, x, y)
272 
273 /* token type codes, some also used as NFA arc types */
274 #define EMPTY	'n'				/* no token present */
275 #define EOS 'e'					/* end of string */
276 #define PLAIN	'p'				/* ordinary character */
277 #define DIGIT	'd'				/* digit (in bound) */
278 #define BACKREF 'b'				/* back reference */
279 #define COLLEL	'I'				/* start of [. */
280 #define ECLASS	'E'				/* start of [= */
281 #define CCLASS	'C'				/* start of [: */
282 #define END 'X'					/* end of [. [= [: */
283 #define RANGE	'R'				/* - within [] which might be range delim. */
284 #define LACON	'L'				/* lookaround constraint subRE */
285 #define AHEAD	'a'				/* color-lookahead arc */
286 #define BEHIND	'r'				/* color-lookbehind arc */
287 #define WBDRY	'w'				/* word boundary constraint */
288 #define NWBDRY	'W'				/* non-word-boundary constraint */
289 #define SBEGIN	'A'				/* beginning of string (even if not BOL) */
290 #define SEND	'Z'				/* end of string (even if not EOL) */
291 #define PREFER	'P'				/* length preference */
292 
293 /* is an arc colored, and hence on a color chain? */
294 #define COLORED(a) \
295 	((a)->type == PLAIN || (a)->type == AHEAD || (a)->type == BEHIND)
296 
297 
298 /* static function list */
299 static const struct fns functions = {
300 	rfree,						/* regfree insides */
301 	rcancelrequested,			/* check for cancel request */
302 	rstacktoodeep				/* check for stack getting dangerously deep */
303 };
304 
305 
306 
307 /*
308  * pg_regcomp - compile regular expression
309  *
310  * Note: on failure, no resources remain allocated, so pg_regfree()
311  * need not be applied to re.
312  */
313 int
pg_regcomp(regex_t * re,const chr * string,size_t len,int flags,Oid collation)314 pg_regcomp(regex_t *re,
315 		   const chr *string,
316 		   size_t len,
317 		   int flags,
318 		   Oid collation)
319 {
320 	struct vars var;
321 	struct vars *v = &var;
322 	struct guts *g;
323 	int			i;
324 	size_t		j;
325 
326 #ifdef REG_DEBUG
327 	FILE	   *debug = (flags & REG_PROGRESS) ? stdout : (FILE *) NULL;
328 #else
329 	FILE	   *debug = (FILE *) NULL;
330 #endif
331 
332 #define  CNOERR()	 { if (ISERR()) return freev(v, v->err); }
333 
334 	/* sanity checks */
335 
336 	if (re == NULL || string == NULL)
337 		return REG_INVARG;
338 	if ((flags & REG_QUOTE) &&
339 		(flags & (REG_ADVANCED | REG_EXPANDED | REG_NEWLINE)))
340 		return REG_INVARG;
341 	if (!(flags & REG_EXTENDED) && (flags & REG_ADVF))
342 		return REG_INVARG;
343 
344 	/* Initialize locale-dependent support */
345 	pg_set_regex_collation(collation);
346 
347 	/* initial setup (after which freev() is callable) */
348 	v->re = re;
349 	v->now = string;
350 	v->stop = v->now + len;
351 	v->savenow = v->savestop = NULL;
352 	v->err = 0;
353 	v->cflags = flags;
354 	v->nsubexp = 0;
355 	v->subs = v->sub10;
356 	v->nsubs = 10;
357 	for (j = 0; j < v->nsubs; j++)
358 		v->subs[j] = NULL;
359 	v->nfa = NULL;
360 	v->cm = NULL;
361 	v->nlcolor = COLORLESS;
362 	v->wordchrs = NULL;
363 	v->tree = NULL;
364 	v->treechain = NULL;
365 	v->treefree = NULL;
366 	v->cv = NULL;
367 	v->cv2 = NULL;
368 	v->lacons = NULL;
369 	v->nlacons = 0;
370 	v->spaceused = 0;
371 	re->re_magic = REMAGIC;
372 	re->re_info = 0;			/* bits get set during parse */
373 	re->re_csize = sizeof(chr);
374 	re->re_collation = collation;
375 	re->re_guts = NULL;
376 	re->re_fns = VS(&functions);
377 
378 	/* more complex setup, malloced things */
379 	re->re_guts = VS(MALLOC(sizeof(struct guts)));
380 	if (re->re_guts == NULL)
381 		return freev(v, REG_ESPACE);
382 	g = (struct guts *) re->re_guts;
383 	g->tree = NULL;
384 	initcm(v, &g->cmap);
385 	v->cm = &g->cmap;
386 	g->lacons = NULL;
387 	g->nlacons = 0;
388 	ZAPCNFA(g->search);
389 	v->nfa = newnfa(v, v->cm, (struct nfa *) NULL);
390 	CNOERR();
391 	/* set up a reasonably-sized transient cvec for getcvec usage */
392 	v->cv = newcvec(100, 20);
393 	if (v->cv == NULL)
394 		return freev(v, REG_ESPACE);
395 
396 	/* parsing */
397 	lexstart(v);				/* also handles prefixes */
398 	if ((v->cflags & REG_NLSTOP) || (v->cflags & REG_NLANCH))
399 	{
400 		/* assign newline a unique color */
401 		v->nlcolor = subcolor(v->cm, newline());
402 		okcolors(v->nfa, v->cm);
403 	}
404 	CNOERR();
405 	v->tree = parse(v, EOS, PLAIN, v->nfa->init, v->nfa->final);
406 	assert(SEE(EOS));			/* even if error; ISERR() => SEE(EOS) */
407 	CNOERR();
408 	assert(v->tree != NULL);
409 
410 	/* finish setup of nfa and its subre tree */
411 	specialcolors(v->nfa);
412 	CNOERR();
413 #ifdef REG_DEBUG
414 	if (debug != NULL)
415 	{
416 		fprintf(debug, "\n\n\n========= RAW ==========\n");
417 		dumpnfa(v->nfa, debug);
418 		dumpst(v->tree, debug, 1);
419 	}
420 #endif
421 	optst(v, v->tree);
422 	v->ntree = numst(v->tree, 1);
423 	markst(v->tree);
424 	cleanst(v);
425 #ifdef REG_DEBUG
426 	if (debug != NULL)
427 	{
428 		fprintf(debug, "\n\n\n========= TREE FIXED ==========\n");
429 		dumpst(v->tree, debug, 1);
430 	}
431 #endif
432 
433 	/* build compacted NFAs for tree and lacons */
434 	re->re_info |= nfatree(v, v->tree, debug);
435 	CNOERR();
436 	assert(v->nlacons == 0 || v->lacons != NULL);
437 	for (i = 1; i < v->nlacons; i++)
438 	{
439 		struct subre *lasub = &v->lacons[i];
440 
441 #ifdef REG_DEBUG
442 		if (debug != NULL)
443 			fprintf(debug, "\n\n\n========= LA%d ==========\n", i);
444 #endif
445 
446 		/* Prepend .* to pattern if it's a lookbehind LACON */
447 		nfanode(v, lasub, !LATYPE_IS_AHEAD(lasub->subno), debug);
448 	}
449 	CNOERR();
450 	if (v->tree->flags & SHORTER)
451 		NOTE(REG_USHORTEST);
452 
453 	/* build compacted NFAs for tree, lacons, fast search */
454 #ifdef REG_DEBUG
455 	if (debug != NULL)
456 		fprintf(debug, "\n\n\n========= SEARCH ==========\n");
457 #endif
458 	/* can sacrifice main NFA now, so use it as work area */
459 	(DISCARD) optimize(v->nfa, debug);
460 	CNOERR();
461 	makesearch(v, v->nfa);
462 	CNOERR();
463 	compact(v->nfa, &g->search);
464 	CNOERR();
465 
466 	/* looks okay, package it up */
467 	re->re_nsub = v->nsubexp;
468 	v->re = NULL;				/* freev no longer frees re */
469 	g->magic = GUTSMAGIC;
470 	g->cflags = v->cflags;
471 	g->info = re->re_info;
472 	g->nsub = re->re_nsub;
473 	g->tree = v->tree;
474 	v->tree = NULL;
475 	g->ntree = v->ntree;
476 	g->compare = (v->cflags & REG_ICASE) ? casecmp : cmp;
477 	g->lacons = v->lacons;
478 	v->lacons = NULL;
479 	g->nlacons = v->nlacons;
480 
481 #ifdef REG_DEBUG
482 	if (flags & REG_DUMP)
483 		dump(re, stdout);
484 #endif
485 
486 	assert(v->err == 0);
487 	return freev(v, 0);
488 }
489 
490 /*
491  * moresubs - enlarge subRE vector
492  */
493 static void
moresubs(struct vars * v,int wanted)494 moresubs(struct vars *v,
495 		 int wanted)			/* want enough room for this one */
496 {
497 	struct subre **p;
498 	size_t		n;
499 
500 	assert(wanted > 0 && (size_t) wanted >= v->nsubs);
501 	n = (size_t) wanted * 3 / 2 + 1;
502 
503 	if (v->subs == v->sub10)
504 	{
505 		p = (struct subre **) MALLOC(n * sizeof(struct subre *));
506 		if (p != NULL)
507 			memcpy(VS(p), VS(v->subs),
508 				   v->nsubs * sizeof(struct subre *));
509 	}
510 	else
511 		p = (struct subre **) REALLOC(v->subs, n * sizeof(struct subre *));
512 	if (p == NULL)
513 	{
514 		ERR(REG_ESPACE);
515 		return;
516 	}
517 	v->subs = p;
518 	for (p = &v->subs[v->nsubs]; v->nsubs < n; p++, v->nsubs++)
519 		*p = NULL;
520 	assert(v->nsubs == n);
521 	assert((size_t) wanted < v->nsubs);
522 }
523 
524 /*
525  * freev - free vars struct's substructures where necessary
526  *
527  * Optionally does error-number setting, and always returns error code
528  * (if any), to make error-handling code terser.
529  */
530 static int
freev(struct vars * v,int err)531 freev(struct vars *v,
532 	  int err)
533 {
534 	if (v->re != NULL)
535 		rfree(v->re);
536 	if (v->subs != v->sub10)
537 		FREE(v->subs);
538 	if (v->nfa != NULL)
539 		freenfa(v->nfa);
540 	if (v->tree != NULL)
541 		freesubre(v, v->tree);
542 	if (v->treechain != NULL)
543 		cleanst(v);
544 	if (v->cv != NULL)
545 		freecvec(v->cv);
546 	if (v->cv2 != NULL)
547 		freecvec(v->cv2);
548 	if (v->lacons != NULL)
549 		freelacons(v->lacons, v->nlacons);
550 	ERR(err);					/* nop if err==0 */
551 
552 	return v->err;
553 }
554 
555 /*
556  * makesearch - turn an NFA into a search NFA (implicit prepend of .*?)
557  * NFA must have been optimize()d already.
558  */
559 static void
makesearch(struct vars * v,struct nfa * nfa)560 makesearch(struct vars *v,
561 		   struct nfa *nfa)
562 {
563 	struct arc *a;
564 	struct arc *b;
565 	struct state *pre = nfa->pre;
566 	struct state *s;
567 	struct state *s2;
568 	struct state *slist;
569 
570 	/* no loops are needed if it's anchored */
571 	for (a = pre->outs; a != NULL; a = a->outchain)
572 	{
573 		assert(a->type == PLAIN);
574 		if (a->co != nfa->bos[0] && a->co != nfa->bos[1])
575 			break;
576 	}
577 	if (a != NULL)
578 	{
579 		/* add implicit .* in front */
580 		rainbow(nfa, v->cm, PLAIN, COLORLESS, pre, pre);
581 
582 		/* and ^* and \A* too -- not always necessary, but harmless */
583 		newarc(nfa, PLAIN, nfa->bos[0], pre, pre);
584 		newarc(nfa, PLAIN, nfa->bos[1], pre, pre);
585 	}
586 
587 	/*
588 	 * Now here's the subtle part.  Because many REs have no lookback
589 	 * constraints, often knowing when you were in the pre state tells you
590 	 * little; it's the next state(s) that are informative.  But some of them
591 	 * may have other inarcs, i.e. it may be possible to make actual progress
592 	 * and then return to one of them.  We must de-optimize such cases,
593 	 * splitting each such state into progress and no-progress states.
594 	 */
595 
596 	/* first, make a list of the states reachable from pre and elsewhere */
597 	slist = NULL;
598 	for (a = pre->outs; a != NULL; a = a->outchain)
599 	{
600 		s = a->to;
601 		for (b = s->ins; b != NULL; b = b->inchain)
602 		{
603 			if (b->from != pre)
604 				break;
605 		}
606 
607 		/*
608 		 * We want to mark states as being in the list already by having non
609 		 * NULL tmp fields, but we can't just store the old slist value in tmp
610 		 * because that doesn't work for the first such state.  Instead, the
611 		 * first list entry gets its own address in tmp.
612 		 */
613 		if (b != NULL && s->tmp == NULL)
614 		{
615 			s->tmp = (slist != NULL) ? slist : s;
616 			slist = s;
617 		}
618 	}
619 
620 	/* do the splits */
621 	for (s = slist; s != NULL; s = s2)
622 	{
623 		s2 = newstate(nfa);
624 		NOERR();
625 		copyouts(nfa, s, s2);
626 		NOERR();
627 		for (a = s->ins; a != NULL; a = b)
628 		{
629 			b = a->inchain;
630 			if (a->from != pre)
631 			{
632 				cparc(nfa, a, a->from, s2);
633 				freearc(nfa, a);
634 			}
635 		}
636 		s2 = (s->tmp != s) ? s->tmp : NULL;
637 		s->tmp = NULL;			/* clean up while we're at it */
638 	}
639 }
640 
641 /*
642  * parse - parse an RE
643  *
644  * This is actually just the top level, which parses a bunch of branches
645  * tied together with '|'.  They appear in the tree as the left children
646  * of a chain of '|' subres.
647  */
648 static struct subre *
parse(struct vars * v,int stopper,int type,struct state * init,struct state * final)649 parse(struct vars *v,
650 	  int stopper,				/* EOS or ')' */
651 	  int type,					/* LACON (lookaround subRE) or PLAIN */
652 	  struct state *init,		/* initial state */
653 	  struct state *final)		/* final state */
654 {
655 	struct state *left;			/* scaffolding for branch */
656 	struct state *right;
657 	struct subre *branches;		/* top level */
658 	struct subre *branch;		/* current branch */
659 	struct subre *t;			/* temporary */
660 	int			firstbranch;	/* is this the first branch? */
661 
662 	assert(stopper == ')' || stopper == EOS);
663 
664 	branches = subre(v, '|', LONGER, init, final);
665 	NOERRN();
666 	branch = branches;
667 	firstbranch = 1;
668 	do
669 	{							/* a branch */
670 		if (!firstbranch)
671 		{
672 			/* need a place to hang it */
673 			branch->right = subre(v, '|', LONGER, init, final);
674 			NOERRN();
675 			branch = branch->right;
676 		}
677 		firstbranch = 0;
678 		left = newstate(v->nfa);
679 		right = newstate(v->nfa);
680 		NOERRN();
681 		EMPTYARC(init, left);
682 		EMPTYARC(right, final);
683 		NOERRN();
684 		branch->left = parsebranch(v, stopper, type, left, right, 0);
685 		NOERRN();
686 		branch->flags |= UP(branch->flags | branch->left->flags);
687 		if ((branch->flags & ~branches->flags) != 0)	/* new flags */
688 			for (t = branches; t != branch; t = t->right)
689 				t->flags |= branch->flags;
690 	} while (EAT('|'));
691 	assert(SEE(stopper) || SEE(EOS));
692 
693 	if (!SEE(stopper))
694 	{
695 		assert(stopper == ')' && SEE(EOS));
696 		ERR(REG_EPAREN);
697 	}
698 
699 	/* optimize out simple cases */
700 	if (branch == branches)
701 	{							/* only one branch */
702 		assert(branch->right == NULL);
703 		t = branch->left;
704 		branch->left = NULL;
705 		freesubre(v, branches);
706 		branches = t;
707 	}
708 	else if (!MESSY(branches->flags))
709 	{							/* no interesting innards */
710 		freesubre(v, branches->left);
711 		branches->left = NULL;
712 		freesubre(v, branches->right);
713 		branches->right = NULL;
714 		branches->op = '=';
715 	}
716 
717 	return branches;
718 }
719 
720 /*
721  * parsebranch - parse one branch of an RE
722  *
723  * This mostly manages concatenation, working closely with parseqatom().
724  * Concatenated things are bundled up as much as possible, with separate
725  * ',' nodes introduced only when necessary due to substructure.
726  */
727 static struct subre *
parsebranch(struct vars * v,int stopper,int type,struct state * left,struct state * right,int partial)728 parsebranch(struct vars *v,
729 			int stopper,		/* EOS or ')' */
730 			int type,			/* LACON (lookaround subRE) or PLAIN */
731 			struct state *left, /* leftmost state */
732 			struct state *right,	/* rightmost state */
733 			int partial)		/* is this only part of a branch? */
734 {
735 	struct state *lp;			/* left end of current construct */
736 	int			seencontent;	/* is there anything in this branch yet? */
737 	struct subre *t;
738 
739 	lp = left;
740 	seencontent = 0;
741 	t = subre(v, '=', 0, left, right);	/* op '=' is tentative */
742 	NOERRN();
743 	while (!SEE('|') && !SEE(stopper) && !SEE(EOS))
744 	{
745 		if (seencontent)
746 		{						/* implicit concat operator */
747 			lp = newstate(v->nfa);
748 			NOERRN();
749 			moveins(v->nfa, right, lp);
750 		}
751 		seencontent = 1;
752 
753 		/* NB, recursion in parseqatom() may swallow rest of branch */
754 		parseqatom(v, stopper, type, lp, right, t);
755 		NOERRN();
756 	}
757 
758 	if (!seencontent)
759 	{							/* empty branch */
760 		if (!partial)
761 			NOTE(REG_UUNSPEC);
762 		assert(lp == left);
763 		EMPTYARC(left, right);
764 	}
765 
766 	return t;
767 }
768 
769 /*
770  * parseqatom - parse one quantified atom or constraint of an RE
771  *
772  * The bookkeeping near the end cooperates very closely with parsebranch();
773  * in particular, it contains a recursion that can involve parsing the rest
774  * of the branch, making this function's name somewhat inaccurate.
775  */
776 static void
parseqatom(struct vars * v,int stopper,int type,struct state * lp,struct state * rp,struct subre * top)777 parseqatom(struct vars *v,
778 		   int stopper,			/* EOS or ')' */
779 		   int type,			/* LACON (lookaround subRE) or PLAIN */
780 		   struct state *lp,	/* left state to hang it on */
781 		   struct state *rp,	/* right state to hang it on */
782 		   struct subre *top)	/* subtree top */
783 {
784 	struct state *s;			/* temporaries for new states */
785 	struct state *s2;
786 
787 #define  ARCV(t, val)	 newarc(v->nfa, t, val, lp, rp)
788 	int			m,
789 				n;
790 	struct subre *atom;			/* atom's subtree */
791 	struct subre *t;
792 	int			cap;			/* capturing parens? */
793 	int			latype;			/* lookaround constraint type */
794 	int			subno;			/* capturing-parens or backref number */
795 	int			atomtype;
796 	int			qprefer;		/* quantifier short/long preference */
797 	int			f;
798 	struct subre **atomp;		/* where the pointer to atom is */
799 
800 	/* initial bookkeeping */
801 	atom = NULL;
802 	assert(lp->nouts == 0);		/* must string new code */
803 	assert(rp->nins == 0);		/* between lp and rp */
804 	subno = 0;					/* just to shut lint up */
805 
806 	/* an atom or constraint... */
807 	atomtype = v->nexttype;
808 	switch (atomtype)
809 	{
810 			/* first, constraints, which end by returning */
811 		case '^':
812 			ARCV('^', 1);
813 			if (v->cflags & REG_NLANCH)
814 				ARCV(BEHIND, v->nlcolor);
815 			NEXT();
816 			return;
817 			break;
818 		case '$':
819 			ARCV('$', 1);
820 			if (v->cflags & REG_NLANCH)
821 				ARCV(AHEAD, v->nlcolor);
822 			NEXT();
823 			return;
824 			break;
825 		case SBEGIN:
826 			ARCV('^', 1);		/* BOL */
827 			ARCV('^', 0);		/* or BOS */
828 			NEXT();
829 			return;
830 			break;
831 		case SEND:
832 			ARCV('$', 1);		/* EOL */
833 			ARCV('$', 0);		/* or EOS */
834 			NEXT();
835 			return;
836 			break;
837 		case '<':
838 			wordchrs(v);		/* does NEXT() */
839 			s = newstate(v->nfa);
840 			NOERR();
841 			nonword(v, BEHIND, lp, s);
842 			word(v, AHEAD, s, rp);
843 			return;
844 			break;
845 		case '>':
846 			wordchrs(v);		/* does NEXT() */
847 			s = newstate(v->nfa);
848 			NOERR();
849 			word(v, BEHIND, lp, s);
850 			nonword(v, AHEAD, s, rp);
851 			return;
852 			break;
853 		case WBDRY:
854 			wordchrs(v);		/* does NEXT() */
855 			s = newstate(v->nfa);
856 			NOERR();
857 			nonword(v, BEHIND, lp, s);
858 			word(v, AHEAD, s, rp);
859 			s = newstate(v->nfa);
860 			NOERR();
861 			word(v, BEHIND, lp, s);
862 			nonword(v, AHEAD, s, rp);
863 			return;
864 			break;
865 		case NWBDRY:
866 			wordchrs(v);		/* does NEXT() */
867 			s = newstate(v->nfa);
868 			NOERR();
869 			word(v, BEHIND, lp, s);
870 			word(v, AHEAD, s, rp);
871 			s = newstate(v->nfa);
872 			NOERR();
873 			nonword(v, BEHIND, lp, s);
874 			nonword(v, AHEAD, s, rp);
875 			return;
876 			break;
877 		case LACON:				/* lookaround constraint */
878 			latype = v->nextvalue;
879 			NEXT();
880 			s = newstate(v->nfa);
881 			s2 = newstate(v->nfa);
882 			NOERR();
883 			t = parse(v, ')', LACON, s, s2);
884 			freesubre(v, t);	/* internal structure irrelevant */
885 			NOERR();
886 			assert(SEE(')'));
887 			NEXT();
888 			processlacon(v, s, s2, latype, lp, rp);
889 			return;
890 			break;
891 			/* then errors, to get them out of the way */
892 		case '*':
893 		case '+':
894 		case '?':
895 		case '{':
896 			ERR(REG_BADRPT);
897 			return;
898 			break;
899 		default:
900 			ERR(REG_ASSERT);
901 			return;
902 			break;
903 			/* then plain characters, and minor variants on that theme */
904 		case ')':				/* unbalanced paren */
905 			if ((v->cflags & REG_ADVANCED) != REG_EXTENDED)
906 			{
907 				ERR(REG_EPAREN);
908 				return;
909 			}
910 			/* legal in EREs due to specification botch */
911 			NOTE(REG_UPBOTCH);
912 			/* fall through into case PLAIN */
913 			/* FALLTHROUGH */
914 		case PLAIN:
915 			onechr(v, v->nextvalue, lp, rp);
916 			okcolors(v->nfa, v->cm);
917 			NOERR();
918 			NEXT();
919 			break;
920 		case '[':
921 			if (v->nextvalue == 1)
922 				bracket(v, lp, rp);
923 			else
924 				cbracket(v, lp, rp);
925 			assert(SEE(']') || ISERR());
926 			NEXT();
927 			break;
928 		case '.':
929 			rainbow(v->nfa, v->cm, PLAIN,
930 					(v->cflags & REG_NLSTOP) ? v->nlcolor : COLORLESS,
931 					lp, rp);
932 			NEXT();
933 			break;
934 			/* and finally the ugly stuff */
935 		case '(':				/* value flags as capturing or non */
936 			cap = (type == LACON) ? 0 : v->nextvalue;
937 			if (cap)
938 			{
939 				v->nsubexp++;
940 				subno = v->nsubexp;
941 				if ((size_t) subno >= v->nsubs)
942 					moresubs(v, subno);
943 				assert((size_t) subno < v->nsubs);
944 			}
945 			else
946 				atomtype = PLAIN;	/* something that's not '(' */
947 			NEXT();
948 			/* need new endpoints because tree will contain pointers */
949 			s = newstate(v->nfa);
950 			s2 = newstate(v->nfa);
951 			NOERR();
952 			EMPTYARC(lp, s);
953 			EMPTYARC(s2, rp);
954 			NOERR();
955 			atom = parse(v, ')', type, s, s2);
956 			assert(SEE(')') || ISERR());
957 			NEXT();
958 			NOERR();
959 			if (cap)
960 			{
961 				v->subs[subno] = atom;
962 				t = subre(v, '(', atom->flags | CAP, s, s2);
963 				NOERR();
964 				t->subno = subno;
965 				t->left = atom;
966 				atom = t;
967 			}
968 			/* postpone everything else pending possible {0} */
969 			break;
970 		case BACKREF:			/* the Feature From The Black Lagoon */
971 			INSIST(type != LACON, REG_ESUBREG);
972 			INSIST(v->nextvalue < v->nsubs, REG_ESUBREG);
973 			INSIST(v->subs[v->nextvalue] != NULL, REG_ESUBREG);
974 			NOERR();
975 			assert(v->nextvalue > 0);
976 			atom = subre(v, 'b', BACKR, lp, rp);
977 			NOERR();
978 			subno = v->nextvalue;
979 			atom->subno = subno;
980 			EMPTYARC(lp, rp);	/* temporarily, so there's something */
981 			NEXT();
982 			break;
983 	}
984 
985 	/* ...and an atom may be followed by a quantifier */
986 	switch (v->nexttype)
987 	{
988 		case '*':
989 			m = 0;
990 			n = DUPINF;
991 			qprefer = (v->nextvalue) ? LONGER : SHORTER;
992 			NEXT();
993 			break;
994 		case '+':
995 			m = 1;
996 			n = DUPINF;
997 			qprefer = (v->nextvalue) ? LONGER : SHORTER;
998 			NEXT();
999 			break;
1000 		case '?':
1001 			m = 0;
1002 			n = 1;
1003 			qprefer = (v->nextvalue) ? LONGER : SHORTER;
1004 			NEXT();
1005 			break;
1006 		case '{':
1007 			NEXT();
1008 			m = scannum(v);
1009 			if (EAT(','))
1010 			{
1011 				if (SEE(DIGIT))
1012 					n = scannum(v);
1013 				else
1014 					n = DUPINF;
1015 				if (m > n)
1016 				{
1017 					ERR(REG_BADBR);
1018 					return;
1019 				}
1020 				/* {m,n} exercises preference, even if it's {m,m} */
1021 				qprefer = (v->nextvalue) ? LONGER : SHORTER;
1022 			}
1023 			else
1024 			{
1025 				n = m;
1026 				/* {m} passes operand's preference through */
1027 				qprefer = 0;
1028 			}
1029 			if (!SEE('}'))
1030 			{					/* catches errors too */
1031 				ERR(REG_BADBR);
1032 				return;
1033 			}
1034 			NEXT();
1035 			break;
1036 		default:				/* no quantifier */
1037 			m = n = 1;
1038 			qprefer = 0;
1039 			break;
1040 	}
1041 
1042 	/* annoying special case:  {0} or {0,0} cancels everything */
1043 	if (m == 0 && n == 0)
1044 	{
1045 		/*
1046 		 * If we had capturing subexpression(s) within the atom, we don't want
1047 		 * to destroy them, because it's legal (if useless) to back-ref them
1048 		 * later.  Hence, just unlink the atom from lp/rp and then ignore it.
1049 		 */
1050 		if (atom != NULL && (atom->flags & CAP))
1051 		{
1052 			delsub(v->nfa, lp, atom->begin);
1053 			delsub(v->nfa, atom->end, rp);
1054 		}
1055 		else
1056 		{
1057 			/* Otherwise, we can clean up any subre infrastructure we made */
1058 			if (atom != NULL)
1059 				freesubre(v, atom);
1060 			delsub(v->nfa, lp, rp);
1061 		}
1062 		EMPTYARC(lp, rp);
1063 		return;
1064 	}
1065 
1066 	/* if not a messy case, avoid hard part */
1067 	assert(!MESSY(top->flags));
1068 	f = top->flags | qprefer | ((atom != NULL) ? atom->flags : 0);
1069 	if (atomtype != '(' && atomtype != BACKREF && !MESSY(UP(f)))
1070 	{
1071 		if (!(m == 1 && n == 1))
1072 			repeat(v, lp, rp, m, n);
1073 		if (atom != NULL)
1074 			freesubre(v, atom);
1075 		top->flags = f;
1076 		return;
1077 	}
1078 
1079 	/*
1080 	 * hard part:  something messy
1081 	 *
1082 	 * That is, capturing parens, back reference, short/long clash, or an atom
1083 	 * with substructure containing one of those.
1084 	 */
1085 
1086 	/* now we'll need a subre for the contents even if they're boring */
1087 	if (atom == NULL)
1088 	{
1089 		atom = subre(v, '=', 0, lp, rp);
1090 		NOERR();
1091 	}
1092 
1093 	/*----------
1094 	 * Prepare a general-purpose state skeleton.
1095 	 *
1096 	 * In the no-backrefs case, we want this:
1097 	 *
1098 	 * [lp] ---> [s] ---prefix---> [begin] ---atom---> [end] ---rest---> [rp]
1099 	 *
1100 	 * where prefix is some repetitions of atom.  In the general case we need
1101 	 *
1102 	 * [lp] ---> [s] ---iterator---> [s2] ---rest---> [rp]
1103 	 *
1104 	 * where the iterator wraps around [begin] ---atom---> [end]
1105 	 *
1106 	 * We make the s state here for both cases; s2 is made below if needed
1107 	 *----------
1108 	 */
1109 	s = newstate(v->nfa);		/* first, new endpoints for the atom */
1110 	s2 = newstate(v->nfa);
1111 	NOERR();
1112 	moveouts(v->nfa, lp, s);
1113 	moveins(v->nfa, rp, s2);
1114 	NOERR();
1115 	atom->begin = s;
1116 	atom->end = s2;
1117 	s = newstate(v->nfa);		/* set up starting state */
1118 	NOERR();
1119 	EMPTYARC(lp, s);
1120 	NOERR();
1121 
1122 	/* break remaining subRE into x{...} and what follows */
1123 	t = subre(v, '.', COMBINE(qprefer, atom->flags), lp, rp);
1124 	NOERR();
1125 	t->left = atom;
1126 	atomp = &t->left;
1127 
1128 	/* here we should recurse... but we must postpone that to the end */
1129 
1130 	/* split top into prefix and remaining */
1131 	assert(top->op == '=' && top->left == NULL && top->right == NULL);
1132 	top->left = subre(v, '=', top->flags, top->begin, lp);
1133 	NOERR();
1134 	top->op = '.';
1135 	top->right = t;
1136 
1137 	/* if it's a backref, now is the time to replicate the subNFA */
1138 	if (atomtype == BACKREF)
1139 	{
1140 		assert(atom->begin->nouts == 1);	/* just the EMPTY */
1141 		delsub(v->nfa, atom->begin, atom->end);
1142 		assert(v->subs[subno] != NULL);
1143 
1144 		/*
1145 		 * And here's why the recursion got postponed: it must wait until the
1146 		 * skeleton is filled in, because it may hit a backref that wants to
1147 		 * copy the filled-in skeleton.
1148 		 */
1149 		dupnfa(v->nfa, v->subs[subno]->begin, v->subs[subno]->end,
1150 			   atom->begin, atom->end);
1151 		NOERR();
1152 	}
1153 
1154 	/*
1155 	 * It's quantifier time.  If the atom is just a backref, we'll let it deal
1156 	 * with quantifiers internally.
1157 	 */
1158 	if (atomtype == BACKREF)
1159 	{
1160 		/* special case:  backrefs have internal quantifiers */
1161 		EMPTYARC(s, atom->begin);	/* empty prefix */
1162 		/* just stuff everything into atom */
1163 		repeat(v, atom->begin, atom->end, m, n);
1164 		atom->min = (short) m;
1165 		atom->max = (short) n;
1166 		atom->flags |= COMBINE(qprefer, atom->flags);
1167 		/* rest of branch can be strung starting from atom->end */
1168 		s2 = atom->end;
1169 	}
1170 	else if (m == 1 && n == 1 &&
1171 			 (qprefer == 0 ||
1172 			  (atom->flags & (LONGER | SHORTER | MIXED)) == 0 ||
1173 			  qprefer == (atom->flags & (LONGER | SHORTER | MIXED))))
1174 	{
1175 		/* no/vacuous quantifier:  done */
1176 		EMPTYARC(s, atom->begin);	/* empty prefix */
1177 		/* rest of branch can be strung starting from atom->end */
1178 		s2 = atom->end;
1179 	}
1180 	else if (m > 0 && !(atom->flags & BACKR))
1181 	{
1182 		/*
1183 		 * If there's no backrefs involved, we can turn x{m,n} into
1184 		 * x{m-1,n-1}x, with capturing parens in only the second x.  This is
1185 		 * valid because we only care about capturing matches from the final
1186 		 * iteration of the quantifier.  It's a win because we can implement
1187 		 * the backref-free left side as a plain DFA node, since we don't
1188 		 * really care where its submatches are.
1189 		 */
1190 		dupnfa(v->nfa, atom->begin, atom->end, s, atom->begin);
1191 		assert(m >= 1 && m != DUPINF && n >= 1);
1192 		repeat(v, s, atom->begin, m - 1, (n == DUPINF) ? n : n - 1);
1193 		f = COMBINE(qprefer, atom->flags);
1194 		t = subre(v, '.', f, s, atom->end); /* prefix and atom */
1195 		NOERR();
1196 		t->left = subre(v, '=', PREF(f), s, atom->begin);
1197 		NOERR();
1198 		t->right = atom;
1199 		*atomp = t;
1200 		/* rest of branch can be strung starting from atom->end */
1201 		s2 = atom->end;
1202 	}
1203 	else
1204 	{
1205 		/* general case: need an iteration node */
1206 		s2 = newstate(v->nfa);
1207 		NOERR();
1208 		moveouts(v->nfa, atom->end, s2);
1209 		NOERR();
1210 		dupnfa(v->nfa, atom->begin, atom->end, s, s2);
1211 		repeat(v, s, s2, m, n);
1212 		f = COMBINE(qprefer, atom->flags);
1213 		t = subre(v, '*', f, s, s2);
1214 		NOERR();
1215 		t->min = (short) m;
1216 		t->max = (short) n;
1217 		t->left = atom;
1218 		*atomp = t;
1219 		/* rest of branch is to be strung from iteration's end state */
1220 	}
1221 
1222 	/* and finally, look after that postponed recursion */
1223 	t = top->right;
1224 	if (!(SEE('|') || SEE(stopper) || SEE(EOS)))
1225 		t->right = parsebranch(v, stopper, type, s2, rp, 1);
1226 	else
1227 	{
1228 		EMPTYARC(s2, rp);
1229 		t->right = subre(v, '=', 0, s2, rp);
1230 	}
1231 	NOERR();
1232 	assert(SEE('|') || SEE(stopper) || SEE(EOS));
1233 	t->flags |= COMBINE(t->flags, t->right->flags);
1234 	top->flags |= COMBINE(top->flags, t->flags);
1235 }
1236 
1237 /*
1238  * nonword - generate arcs for non-word-character ahead or behind
1239  */
1240 static void
nonword(struct vars * v,int dir,struct state * lp,struct state * rp)1241 nonword(struct vars *v,
1242 		int dir,				/* AHEAD or BEHIND */
1243 		struct state *lp,
1244 		struct state *rp)
1245 {
1246 	int			anchor = (dir == AHEAD) ? '$' : '^';
1247 
1248 	assert(dir == AHEAD || dir == BEHIND);
1249 	newarc(v->nfa, anchor, 1, lp, rp);
1250 	newarc(v->nfa, anchor, 0, lp, rp);
1251 	colorcomplement(v->nfa, v->cm, dir, v->wordchrs, lp, rp);
1252 	/* (no need for special attention to \n) */
1253 }
1254 
1255 /*
1256  * word - generate arcs for word character ahead or behind
1257  */
1258 static void
word(struct vars * v,int dir,struct state * lp,struct state * rp)1259 word(struct vars *v,
1260 	 int dir,					/* AHEAD or BEHIND */
1261 	 struct state *lp,
1262 	 struct state *rp)
1263 {
1264 	assert(dir == AHEAD || dir == BEHIND);
1265 	cloneouts(v->nfa, v->wordchrs, lp, rp, dir);
1266 	/* (no need for special attention to \n) */
1267 }
1268 
1269 /*
1270  * scannum - scan a number
1271  */
1272 static int						/* value, <= DUPMAX */
scannum(struct vars * v)1273 scannum(struct vars *v)
1274 {
1275 	int			n = 0;
1276 
1277 	while (SEE(DIGIT) && n < DUPMAX)
1278 	{
1279 		n = n * 10 + v->nextvalue;
1280 		NEXT();
1281 	}
1282 	if (SEE(DIGIT) || n > DUPMAX)
1283 	{
1284 		ERR(REG_BADBR);
1285 		return 0;
1286 	}
1287 	return n;
1288 }
1289 
1290 /*
1291  * repeat - replicate subNFA for quantifiers
1292  *
1293  * The sub-NFA strung from lp to rp is modified to represent m to n
1294  * repetitions of its initial contents.
1295  *
1296  * The duplication sequences used here are chosen carefully so that any
1297  * pointers starting out pointing into the subexpression end up pointing into
1298  * the last occurrence.  (Note that it may not be strung between the same
1299  * left and right end states, however!)  This used to be important for the
1300  * subRE tree, although the important bits are now handled by the in-line
1301  * code in parse(), and when this is called, it doesn't matter any more.
1302  */
1303 static void
repeat(struct vars * v,struct state * lp,struct state * rp,int m,int n)1304 repeat(struct vars *v,
1305 	   struct state *lp,
1306 	   struct state *rp,
1307 	   int m,
1308 	   int n)
1309 {
1310 #define  SOME	 2
1311 #define  INF	 3
1312 #define  PAIR(x, y)  ((x)*4 + (y))
1313 #define  REDUCE(x)	 ( ((x) == DUPINF) ? INF : (((x) > 1) ? SOME : (x)) )
1314 	const int	rm = REDUCE(m);
1315 	const int	rn = REDUCE(n);
1316 	struct state *s;
1317 	struct state *s2;
1318 
1319 	switch (PAIR(rm, rn))
1320 	{
1321 		case PAIR(0, 0):		/* empty string */
1322 			delsub(v->nfa, lp, rp);
1323 			EMPTYARC(lp, rp);
1324 			break;
1325 		case PAIR(0, 1):		/* do as x| */
1326 			EMPTYARC(lp, rp);
1327 			break;
1328 		case PAIR(0, SOME):		/* do as x{1,n}| */
1329 			repeat(v, lp, rp, 1, n);
1330 			NOERR();
1331 			EMPTYARC(lp, rp);
1332 			break;
1333 		case PAIR(0, INF):		/* loop x around */
1334 			s = newstate(v->nfa);
1335 			NOERR();
1336 			moveouts(v->nfa, lp, s);
1337 			moveins(v->nfa, rp, s);
1338 			EMPTYARC(lp, s);
1339 			EMPTYARC(s, rp);
1340 			break;
1341 		case PAIR(1, 1):		/* no action required */
1342 			break;
1343 		case PAIR(1, SOME):		/* do as x{0,n-1}x = (x{1,n-1}|)x */
1344 			s = newstate(v->nfa);
1345 			NOERR();
1346 			moveouts(v->nfa, lp, s);
1347 			dupnfa(v->nfa, s, rp, lp, s);
1348 			NOERR();
1349 			repeat(v, lp, s, 1, n - 1);
1350 			NOERR();
1351 			EMPTYARC(lp, s);
1352 			break;
1353 		case PAIR(1, INF):		/* add loopback arc */
1354 			s = newstate(v->nfa);
1355 			s2 = newstate(v->nfa);
1356 			NOERR();
1357 			moveouts(v->nfa, lp, s);
1358 			moveins(v->nfa, rp, s2);
1359 			EMPTYARC(lp, s);
1360 			EMPTYARC(s2, rp);
1361 			EMPTYARC(s2, s);
1362 			break;
1363 		case PAIR(SOME, SOME):	/* do as x{m-1,n-1}x */
1364 			s = newstate(v->nfa);
1365 			NOERR();
1366 			moveouts(v->nfa, lp, s);
1367 			dupnfa(v->nfa, s, rp, lp, s);
1368 			NOERR();
1369 			repeat(v, lp, s, m - 1, n - 1);
1370 			break;
1371 		case PAIR(SOME, INF):	/* do as x{m-1,}x */
1372 			s = newstate(v->nfa);
1373 			NOERR();
1374 			moveouts(v->nfa, lp, s);
1375 			dupnfa(v->nfa, s, rp, lp, s);
1376 			NOERR();
1377 			repeat(v, lp, s, m - 1, n);
1378 			break;
1379 		default:
1380 			ERR(REG_ASSERT);
1381 			break;
1382 	}
1383 }
1384 
1385 /*
1386  * bracket - handle non-complemented bracket expression
1387  * Also called from cbracket for complemented bracket expressions.
1388  */
1389 static void
bracket(struct vars * v,struct state * lp,struct state * rp)1390 bracket(struct vars *v,
1391 		struct state *lp,
1392 		struct state *rp)
1393 {
1394 	assert(SEE('['));
1395 	NEXT();
1396 	while (!SEE(']') && !SEE(EOS))
1397 		brackpart(v, lp, rp);
1398 	assert(SEE(']') || ISERR());
1399 	okcolors(v->nfa, v->cm);
1400 }
1401 
1402 /*
1403  * cbracket - handle complemented bracket expression
1404  * We do it by calling bracket() with dummy endpoints, and then complementing
1405  * the result.  The alternative would be to invoke rainbow(), and then delete
1406  * arcs as the b.e. is seen... but that gets messy.
1407  */
1408 static void
cbracket(struct vars * v,struct state * lp,struct state * rp)1409 cbracket(struct vars *v,
1410 		 struct state *lp,
1411 		 struct state *rp)
1412 {
1413 	struct state *left = newstate(v->nfa);
1414 	struct state *right = newstate(v->nfa);
1415 
1416 	NOERR();
1417 	bracket(v, left, right);
1418 	if (v->cflags & REG_NLSTOP)
1419 		newarc(v->nfa, PLAIN, v->nlcolor, left, right);
1420 	NOERR();
1421 
1422 	assert(lp->nouts == 0);		/* all outarcs will be ours */
1423 
1424 	/*
1425 	 * Easy part of complementing, and all there is to do since the MCCE code
1426 	 * was removed.
1427 	 */
1428 	colorcomplement(v->nfa, v->cm, PLAIN, left, lp, rp);
1429 	NOERR();
1430 	dropstate(v->nfa, left);
1431 	assert(right->nins == 0);
1432 	freestate(v->nfa, right);
1433 }
1434 
1435 /*
1436  * brackpart - handle one item (or range) within a bracket expression
1437  */
1438 static void
brackpart(struct vars * v,struct state * lp,struct state * rp)1439 brackpart(struct vars *v,
1440 		  struct state *lp,
1441 		  struct state *rp)
1442 {
1443 	chr			startc;
1444 	chr			endc;
1445 	struct cvec *cv;
1446 	const chr  *startp;
1447 	const chr  *endp;
1448 	chr			c[1];
1449 
1450 	/* parse something, get rid of special cases, take shortcuts */
1451 	switch (v->nexttype)
1452 	{
1453 		case RANGE:				/* a-b-c or other botch */
1454 			ERR(REG_ERANGE);
1455 			return;
1456 			break;
1457 		case PLAIN:
1458 			c[0] = v->nextvalue;
1459 			NEXT();
1460 			/* shortcut for ordinary chr (not range) */
1461 			if (!SEE(RANGE))
1462 			{
1463 				onechr(v, c[0], lp, rp);
1464 				return;
1465 			}
1466 			startc = element(v, c, c + 1);
1467 			NOERR();
1468 			break;
1469 		case COLLEL:
1470 			startp = v->now;
1471 			endp = scanplain(v);
1472 			INSIST(startp < endp, REG_ECOLLATE);
1473 			NOERR();
1474 			startc = element(v, startp, endp);
1475 			NOERR();
1476 			break;
1477 		case ECLASS:
1478 			startp = v->now;
1479 			endp = scanplain(v);
1480 			INSIST(startp < endp, REG_ECOLLATE);
1481 			NOERR();
1482 			startc = element(v, startp, endp);
1483 			NOERR();
1484 			cv = eclass(v, startc, (v->cflags & REG_ICASE));
1485 			NOERR();
1486 			subcolorcvec(v, cv, lp, rp);
1487 			return;
1488 			break;
1489 		case CCLASS:
1490 			startp = v->now;
1491 			endp = scanplain(v);
1492 			INSIST(startp < endp, REG_ECTYPE);
1493 			NOERR();
1494 			cv = cclass(v, startp, endp, (v->cflags & REG_ICASE));
1495 			NOERR();
1496 			subcolorcvec(v, cv, lp, rp);
1497 			return;
1498 			break;
1499 		default:
1500 			ERR(REG_ASSERT);
1501 			return;
1502 			break;
1503 	}
1504 
1505 	if (SEE(RANGE))
1506 	{
1507 		NEXT();
1508 		switch (v->nexttype)
1509 		{
1510 			case PLAIN:
1511 			case RANGE:
1512 				c[0] = v->nextvalue;
1513 				NEXT();
1514 				endc = element(v, c, c + 1);
1515 				NOERR();
1516 				break;
1517 			case COLLEL:
1518 				startp = v->now;
1519 				endp = scanplain(v);
1520 				INSIST(startp < endp, REG_ECOLLATE);
1521 				NOERR();
1522 				endc = element(v, startp, endp);
1523 				NOERR();
1524 				break;
1525 			default:
1526 				ERR(REG_ERANGE);
1527 				return;
1528 				break;
1529 		}
1530 	}
1531 	else
1532 		endc = startc;
1533 
1534 	/*
1535 	 * Ranges are unportable.  Actually, standard C does guarantee that digits
1536 	 * are contiguous, but making that an exception is just too complicated.
1537 	 */
1538 	if (startc != endc)
1539 		NOTE(REG_UUNPORT);
1540 	cv = range(v, startc, endc, (v->cflags & REG_ICASE));
1541 	NOERR();
1542 	subcolorcvec(v, cv, lp, rp);
1543 }
1544 
1545 /*
1546  * scanplain - scan PLAIN contents of [. etc.
1547  *
1548  * Certain bits of trickery in lex.c know that this code does not try
1549  * to look past the final bracket of the [. etc.
1550  */
1551 static const chr *				/* just after end of sequence */
scanplain(struct vars * v)1552 scanplain(struct vars *v)
1553 {
1554 	const chr  *endp;
1555 
1556 	assert(SEE(COLLEL) || SEE(ECLASS) || SEE(CCLASS));
1557 	NEXT();
1558 
1559 	endp = v->now;
1560 	while (SEE(PLAIN))
1561 	{
1562 		endp = v->now;
1563 		NEXT();
1564 	}
1565 
1566 	assert(SEE(END) || ISERR());
1567 	NEXT();
1568 
1569 	return endp;
1570 }
1571 
1572 /*
1573  * onechr - fill in arcs for a plain character, and possible case complements
1574  * This is mostly a shortcut for efficient handling of the common case.
1575  */
1576 static void
onechr(struct vars * v,chr c,struct state * lp,struct state * rp)1577 onechr(struct vars *v,
1578 	   chr c,
1579 	   struct state *lp,
1580 	   struct state *rp)
1581 {
1582 	if (!(v->cflags & REG_ICASE))
1583 	{
1584 		color		lastsubcolor = COLORLESS;
1585 
1586 		subcoloronechr(v, c, lp, rp, &lastsubcolor);
1587 		return;
1588 	}
1589 
1590 	/* rats, need general case anyway... */
1591 	subcolorcvec(v, allcases(v, c), lp, rp);
1592 }
1593 
1594 /*
1595  * wordchrs - set up word-chr list for word-boundary stuff, if needed
1596  *
1597  * The list is kept as a bunch of arcs between two dummy states; it's
1598  * disposed of by the unreachable-states sweep in NFA optimization.
1599  * Does NEXT().  Must not be called from any unusual lexical context.
1600  * This should be reconciled with the \w etc. handling in lex.c, and
1601  * should be cleaned up to reduce dependencies on input scanning.
1602  */
1603 static void
wordchrs(struct vars * v)1604 wordchrs(struct vars *v)
1605 {
1606 	struct state *left;
1607 	struct state *right;
1608 
1609 	if (v->wordchrs != NULL)
1610 	{
1611 		NEXT();					/* for consistency */
1612 		return;
1613 	}
1614 
1615 	left = newstate(v->nfa);
1616 	right = newstate(v->nfa);
1617 	NOERR();
1618 	/* fine point:	implemented with [::], and lexer will set REG_ULOCALE */
1619 	lexword(v);
1620 	NEXT();
1621 	assert(v->savenow != NULL && SEE('['));
1622 	bracket(v, left, right);
1623 	assert((v->savenow != NULL && SEE(']')) || ISERR());
1624 	NEXT();
1625 	NOERR();
1626 	v->wordchrs = left;
1627 }
1628 
1629 /*
1630  * processlacon - generate the NFA representation of a LACON
1631  *
1632  * In the general case this is just newlacon() + newarc(), but some cases
1633  * can be optimized.
1634  */
1635 static void
processlacon(struct vars * v,struct state * begin,struct state * end,int latype,struct state * lp,struct state * rp)1636 processlacon(struct vars *v,
1637 			 struct state *begin,	/* start of parsed LACON sub-re */
1638 			 struct state *end, /* end of parsed LACON sub-re */
1639 			 int latype,
1640 			 struct state *lp,	/* left state to hang it on */
1641 			 struct state *rp)	/* right state to hang it on */
1642 {
1643 	struct state *s1;
1644 	int			n;
1645 
1646 	/*
1647 	 * Check for lookaround RE consisting of a single plain color arc (or set
1648 	 * of arcs); this would typically be a simple chr or a bracket expression.
1649 	 */
1650 	s1 = single_color_transition(begin, end);
1651 	switch (latype)
1652 	{
1653 		case LATYPE_AHEAD_POS:
1654 			/* If lookahead RE is just colorset C, convert to AHEAD(C) */
1655 			if (s1 != NULL)
1656 			{
1657 				cloneouts(v->nfa, s1, lp, rp, AHEAD);
1658 				return;
1659 			}
1660 			break;
1661 		case LATYPE_AHEAD_NEG:
1662 			/* If lookahead RE is just colorset C, convert to AHEAD(^C)|$ */
1663 			if (s1 != NULL)
1664 			{
1665 				colorcomplement(v->nfa, v->cm, AHEAD, s1, lp, rp);
1666 				newarc(v->nfa, '$', 1, lp, rp);
1667 				newarc(v->nfa, '$', 0, lp, rp);
1668 				return;
1669 			}
1670 			break;
1671 		case LATYPE_BEHIND_POS:
1672 			/* If lookbehind RE is just colorset C, convert to BEHIND(C) */
1673 			if (s1 != NULL)
1674 			{
1675 				cloneouts(v->nfa, s1, lp, rp, BEHIND);
1676 				return;
1677 			}
1678 			break;
1679 		case LATYPE_BEHIND_NEG:
1680 			/* If lookbehind RE is just colorset C, convert to BEHIND(^C)|^ */
1681 			if (s1 != NULL)
1682 			{
1683 				colorcomplement(v->nfa, v->cm, BEHIND, s1, lp, rp);
1684 				newarc(v->nfa, '^', 1, lp, rp);
1685 				newarc(v->nfa, '^', 0, lp, rp);
1686 				return;
1687 			}
1688 			break;
1689 		default:
1690 			assert(NOTREACHED);
1691 	}
1692 
1693 	/* General case: we need a LACON subre and arc */
1694 	n = newlacon(v, begin, end, latype);
1695 	newarc(v->nfa, LACON, n, lp, rp);
1696 }
1697 
1698 /*
1699  * subre - allocate a subre
1700  */
1701 static struct subre *
subre(struct vars * v,int op,int flags,struct state * begin,struct state * end)1702 subre(struct vars *v,
1703 	  int op,
1704 	  int flags,
1705 	  struct state *begin,
1706 	  struct state *end)
1707 {
1708 	struct subre *ret = v->treefree;
1709 
1710 	/*
1711 	 * Checking for stack overflow here is sufficient to protect parse() and
1712 	 * its recursive subroutines.
1713 	 */
1714 	if (STACK_TOO_DEEP(v->re))
1715 	{
1716 		ERR(REG_ETOOBIG);
1717 		return NULL;
1718 	}
1719 
1720 	if (ret != NULL)
1721 		v->treefree = ret->left;
1722 	else
1723 	{
1724 		ret = (struct subre *) MALLOC(sizeof(struct subre));
1725 		if (ret == NULL)
1726 		{
1727 			ERR(REG_ESPACE);
1728 			return NULL;
1729 		}
1730 		ret->chain = v->treechain;
1731 		v->treechain = ret;
1732 	}
1733 
1734 	assert(strchr("=b|.*(", op) != NULL);
1735 
1736 	ret->op = op;
1737 	ret->flags = flags;
1738 	ret->id = 0;				/* will be assigned later */
1739 	ret->subno = 0;
1740 	ret->min = ret->max = 1;
1741 	ret->left = NULL;
1742 	ret->right = NULL;
1743 	ret->begin = begin;
1744 	ret->end = end;
1745 	ZAPCNFA(ret->cnfa);
1746 
1747 	return ret;
1748 }
1749 
1750 /*
1751  * freesubre - free a subRE subtree
1752  */
1753 static void
freesubre(struct vars * v,struct subre * sr)1754 freesubre(struct vars *v,		/* might be NULL */
1755 		  struct subre *sr)
1756 {
1757 	if (sr == NULL)
1758 		return;
1759 
1760 	if (sr->left != NULL)
1761 		freesubre(v, sr->left);
1762 	if (sr->right != NULL)
1763 		freesubre(v, sr->right);
1764 
1765 	freesrnode(v, sr);
1766 }
1767 
1768 /*
1769  * freesrnode - free one node in a subRE subtree
1770  */
1771 static void
freesrnode(struct vars * v,struct subre * sr)1772 freesrnode(struct vars *v,		/* might be NULL */
1773 		   struct subre *sr)
1774 {
1775 	if (sr == NULL)
1776 		return;
1777 
1778 	if (!NULLCNFA(sr->cnfa))
1779 		freecnfa(&sr->cnfa);
1780 	sr->flags = 0;
1781 
1782 	if (v != NULL && v->treechain != NULL)
1783 	{
1784 		/* we're still parsing, maybe we can reuse the subre */
1785 		sr->left = v->treefree;
1786 		v->treefree = sr;
1787 	}
1788 	else
1789 		FREE(sr);
1790 }
1791 
1792 /*
1793  * optst - optimize a subRE subtree
1794  */
1795 static void
optst(struct vars * v,struct subre * t)1796 optst(struct vars *v,
1797 	  struct subre *t)
1798 {
1799 	/*
1800 	 * DGP (2007-11-13): I assume it was the programmer's intent to eventually
1801 	 * come back and add code to optimize subRE trees, but the routine coded
1802 	 * just spends effort traversing the tree and doing nothing. We can do
1803 	 * nothing with less effort.
1804 	 */
1805 	return;
1806 }
1807 
1808 /*
1809  * numst - number tree nodes (assigning "id" indexes)
1810  */
1811 static int						/* next number */
numst(struct subre * t,int start)1812 numst(struct subre *t,
1813 	  int start)				/* starting point for subtree numbers */
1814 {
1815 	int			i;
1816 
1817 	assert(t != NULL);
1818 
1819 	i = start;
1820 	t->id = (short) i++;
1821 	if (t->left != NULL)
1822 		i = numst(t->left, i);
1823 	if (t->right != NULL)
1824 		i = numst(t->right, i);
1825 	return i;
1826 }
1827 
1828 /*
1829  * markst - mark tree nodes as INUSE
1830  *
1831  * Note: this is a great deal more subtle than it looks.  During initial
1832  * parsing of a regex, all subres are linked into the treechain list;
1833  * discarded ones are also linked into the treefree list for possible reuse.
1834  * After we are done creating all subres required for a regex, we run markst()
1835  * then cleanst(), which results in discarding all subres not reachable from
1836  * v->tree.  We then clear v->treechain, indicating that subres must be found
1837  * by descending from v->tree.  This changes the behavior of freesubre(): it
1838  * will henceforth FREE() unwanted subres rather than sticking them into the
1839  * treefree list.  (Doing that any earlier would result in dangling links in
1840  * the treechain list.)  This all means that freev() will clean up correctly
1841  * if invoked before or after markst()+cleanst(); but it would not work if
1842  * called partway through this state conversion, so we mustn't error out
1843  * in or between these two functions.
1844  */
1845 static void
markst(struct subre * t)1846 markst(struct subre *t)
1847 {
1848 	assert(t != NULL);
1849 
1850 	t->flags |= INUSE;
1851 	if (t->left != NULL)
1852 		markst(t->left);
1853 	if (t->right != NULL)
1854 		markst(t->right);
1855 }
1856 
1857 /*
1858  * cleanst - free any tree nodes not marked INUSE
1859  */
1860 static void
cleanst(struct vars * v)1861 cleanst(struct vars *v)
1862 {
1863 	struct subre *t;
1864 	struct subre *next;
1865 
1866 	for (t = v->treechain; t != NULL; t = next)
1867 	{
1868 		next = t->chain;
1869 		if (!(t->flags & INUSE))
1870 			FREE(t);
1871 	}
1872 	v->treechain = NULL;
1873 	v->treefree = NULL;			/* just on general principles */
1874 }
1875 
1876 /*
1877  * nfatree - turn a subRE subtree into a tree of compacted NFAs
1878  */
1879 static long						/* optimize results from top node */
nfatree(struct vars * v,struct subre * t,FILE * f)1880 nfatree(struct vars *v,
1881 		struct subre *t,
1882 		FILE *f)				/* for debug output */
1883 {
1884 	assert(t != NULL && t->begin != NULL);
1885 
1886 	if (t->left != NULL)
1887 		(DISCARD) nfatree(v, t->left, f);
1888 	if (t->right != NULL)
1889 		(DISCARD) nfatree(v, t->right, f);
1890 
1891 	return nfanode(v, t, 0, f);
1892 }
1893 
1894 /*
1895  * nfanode - do one NFA for nfatree or lacons
1896  *
1897  * If converttosearch is true, apply makesearch() to the NFA.
1898  */
1899 static long						/* optimize results */
nfanode(struct vars * v,struct subre * t,int converttosearch,FILE * f)1900 nfanode(struct vars *v,
1901 		struct subre *t,
1902 		int converttosearch,
1903 		FILE *f)				/* for debug output */
1904 {
1905 	struct nfa *nfa;
1906 	long		ret = 0;
1907 
1908 	assert(t->begin != NULL);
1909 
1910 #ifdef REG_DEBUG
1911 	if (f != NULL)
1912 	{
1913 		char		idbuf[50];
1914 
1915 		fprintf(f, "\n\n\n========= TREE NODE %s ==========\n",
1916 				stid(t, idbuf, sizeof(idbuf)));
1917 	}
1918 #endif
1919 	nfa = newnfa(v, v->cm, v->nfa);
1920 	NOERRZ();
1921 	dupnfa(nfa, t->begin, t->end, nfa->init, nfa->final);
1922 	if (!ISERR())
1923 		specialcolors(nfa);
1924 	if (!ISERR())
1925 		ret = optimize(nfa, f);
1926 	if (converttosearch && !ISERR())
1927 		makesearch(v, nfa);
1928 	if (!ISERR())
1929 		compact(nfa, &t->cnfa);
1930 
1931 	freenfa(nfa);
1932 	return ret;
1933 }
1934 
1935 /*
1936  * newlacon - allocate a lookaround-constraint subRE
1937  */
1938 static int						/* lacon number */
newlacon(struct vars * v,struct state * begin,struct state * end,int latype)1939 newlacon(struct vars *v,
1940 		 struct state *begin,
1941 		 struct state *end,
1942 		 int latype)
1943 {
1944 	int			n;
1945 	struct subre *newlacons;
1946 	struct subre *sub;
1947 
1948 	if (v->nlacons == 0)
1949 	{
1950 		n = 1;					/* skip 0th */
1951 		newlacons = (struct subre *) MALLOC(2 * sizeof(struct subre));
1952 	}
1953 	else
1954 	{
1955 		n = v->nlacons;
1956 		newlacons = (struct subre *) REALLOC(v->lacons,
1957 											 (n + 1) * sizeof(struct subre));
1958 	}
1959 	if (newlacons == NULL)
1960 	{
1961 		ERR(REG_ESPACE);
1962 		return 0;
1963 	}
1964 	v->lacons = newlacons;
1965 	v->nlacons = n + 1;
1966 	sub = &v->lacons[n];
1967 	sub->begin = begin;
1968 	sub->end = end;
1969 	sub->subno = latype;
1970 	ZAPCNFA(sub->cnfa);
1971 	return n;
1972 }
1973 
1974 /*
1975  * freelacons - free lookaround-constraint subRE vector
1976  */
1977 static void
freelacons(struct subre * subs,int n)1978 freelacons(struct subre *subs,
1979 		   int n)
1980 {
1981 	struct subre *sub;
1982 	int			i;
1983 
1984 	assert(n > 0);
1985 	for (sub = subs + 1, i = n - 1; i > 0; sub++, i--)	/* no 0th */
1986 		if (!NULLCNFA(sub->cnfa))
1987 			freecnfa(&sub->cnfa);
1988 	FREE(subs);
1989 }
1990 
1991 /*
1992  * rfree - free a whole RE (insides of regfree)
1993  */
1994 static void
rfree(regex_t * re)1995 rfree(regex_t *re)
1996 {
1997 	struct guts *g;
1998 
1999 	if (re == NULL || re->re_magic != REMAGIC)
2000 		return;
2001 
2002 	re->re_magic = 0;			/* invalidate RE */
2003 	g = (struct guts *) re->re_guts;
2004 	re->re_guts = NULL;
2005 	re->re_fns = NULL;
2006 	if (g != NULL)
2007 	{
2008 		g->magic = 0;
2009 		freecm(&g->cmap);
2010 		if (g->tree != NULL)
2011 			freesubre((struct vars *) NULL, g->tree);
2012 		if (g->lacons != NULL)
2013 			freelacons(g->lacons, g->nlacons);
2014 		if (!NULLCNFA(g->search))
2015 			freecnfa(&g->search);
2016 		FREE(g);
2017 	}
2018 }
2019 
2020 /*
2021  * rcancelrequested - check for external request to cancel regex operation
2022  *
2023  * Return nonzero to fail the operation with error code REG_CANCEL,
2024  * zero to keep going
2025  *
2026  * The current implementation is Postgres-specific.  If we ever get around
2027  * to splitting the regex code out as a standalone library, there will need
2028  * to be some API to let applications define a callback function for this.
2029  */
2030 static int
rcancelrequested(void)2031 rcancelrequested(void)
2032 {
2033 	return InterruptPending && (QueryCancelPending || ProcDiePending);
2034 }
2035 
2036 /*
2037  * rstacktoodeep - check for stack getting dangerously deep
2038  *
2039  * Return nonzero to fail the operation with error code REG_ETOOBIG,
2040  * zero to keep going
2041  *
2042  * The current implementation is Postgres-specific.  If we ever get around
2043  * to splitting the regex code out as a standalone library, there will need
2044  * to be some API to let applications define a callback function for this.
2045  */
2046 static int
rstacktoodeep(void)2047 rstacktoodeep(void)
2048 {
2049 	return stack_is_too_deep();
2050 }
2051 
2052 #ifdef REG_DEBUG
2053 
2054 /*
2055  * dump - dump an RE in human-readable form
2056  */
2057 static void
dump(regex_t * re,FILE * f)2058 dump(regex_t *re,
2059 	 FILE *f)
2060 {
2061 	struct guts *g;
2062 	int			i;
2063 
2064 	if (re->re_magic != REMAGIC)
2065 		fprintf(f, "bad magic number (0x%x not 0x%x)\n", re->re_magic,
2066 				REMAGIC);
2067 	if (re->re_guts == NULL)
2068 	{
2069 		fprintf(f, "NULL guts!!!\n");
2070 		return;
2071 	}
2072 	g = (struct guts *) re->re_guts;
2073 	if (g->magic != GUTSMAGIC)
2074 		fprintf(f, "bad guts magic number (0x%x not 0x%x)\n", g->magic,
2075 				GUTSMAGIC);
2076 
2077 	fprintf(f, "\n\n\n========= DUMP ==========\n");
2078 	fprintf(f, "nsub %d, info 0%lo, csize %d, ntree %d\n",
2079 			(int) re->re_nsub, re->re_info, re->re_csize, g->ntree);
2080 
2081 	dumpcolors(&g->cmap, f);
2082 	if (!NULLCNFA(g->search))
2083 	{
2084 		fprintf(f, "\nsearch:\n");
2085 		dumpcnfa(&g->search, f);
2086 	}
2087 	for (i = 1; i < g->nlacons; i++)
2088 	{
2089 		struct subre *lasub = &g->lacons[i];
2090 		const char *latype;
2091 
2092 		switch (lasub->subno)
2093 		{
2094 			case LATYPE_AHEAD_POS:
2095 				latype = "positive lookahead";
2096 				break;
2097 			case LATYPE_AHEAD_NEG:
2098 				latype = "negative lookahead";
2099 				break;
2100 			case LATYPE_BEHIND_POS:
2101 				latype = "positive lookbehind";
2102 				break;
2103 			case LATYPE_BEHIND_NEG:
2104 				latype = "negative lookbehind";
2105 				break;
2106 			default:
2107 				latype = "???";
2108 				break;
2109 		}
2110 		fprintf(f, "\nla%d (%s):\n", i, latype);
2111 		dumpcnfa(&lasub->cnfa, f);
2112 	}
2113 	fprintf(f, "\n");
2114 	dumpst(g->tree, f, 0);
2115 }
2116 
2117 /*
2118  * dumpst - dump a subRE tree
2119  */
2120 static void
dumpst(struct subre * t,FILE * f,int nfapresent)2121 dumpst(struct subre *t,
2122 	   FILE *f,
2123 	   int nfapresent)			/* is the original NFA still around? */
2124 {
2125 	if (t == NULL)
2126 		fprintf(f, "null tree\n");
2127 	else
2128 		stdump(t, f, nfapresent);
2129 	fflush(f);
2130 }
2131 
2132 /*
2133  * stdump - recursive guts of dumpst
2134  */
2135 static void
stdump(struct subre * t,FILE * f,int nfapresent)2136 stdump(struct subre *t,
2137 	   FILE *f,
2138 	   int nfapresent)			/* is the original NFA still around? */
2139 {
2140 	char		idbuf[50];
2141 
2142 	fprintf(f, "%s. `%c'", stid(t, idbuf, sizeof(idbuf)), t->op);
2143 	if (t->flags & LONGER)
2144 		fprintf(f, " longest");
2145 	if (t->flags & SHORTER)
2146 		fprintf(f, " shortest");
2147 	if (t->flags & MIXED)
2148 		fprintf(f, " hasmixed");
2149 	if (t->flags & CAP)
2150 		fprintf(f, " hascapture");
2151 	if (t->flags & BACKR)
2152 		fprintf(f, " hasbackref");
2153 	if (!(t->flags & INUSE))
2154 		fprintf(f, " UNUSED");
2155 	if (t->subno != 0)
2156 		fprintf(f, " (#%d)", t->subno);
2157 	if (t->min != 1 || t->max != 1)
2158 	{
2159 		fprintf(f, " {%d,", t->min);
2160 		if (t->max != DUPINF)
2161 			fprintf(f, "%d", t->max);
2162 		fprintf(f, "}");
2163 	}
2164 	if (nfapresent)
2165 		fprintf(f, " %ld-%ld", (long) t->begin->no, (long) t->end->no);
2166 	if (t->left != NULL)
2167 		fprintf(f, " L:%s", stid(t->left, idbuf, sizeof(idbuf)));
2168 	if (t->right != NULL)
2169 		fprintf(f, " R:%s", stid(t->right, idbuf, sizeof(idbuf)));
2170 	if (!NULLCNFA(t->cnfa))
2171 	{
2172 		fprintf(f, "\n");
2173 		dumpcnfa(&t->cnfa, f);
2174 	}
2175 	fprintf(f, "\n");
2176 	if (t->left != NULL)
2177 		stdump(t->left, f, nfapresent);
2178 	if (t->right != NULL)
2179 		stdump(t->right, f, nfapresent);
2180 }
2181 
2182 /*
2183  * stid - identify a subtree node for dumping
2184  */
2185 static const char *				/* points to buf or constant string */
stid(struct subre * t,char * buf,size_t bufsize)2186 stid(struct subre *t,
2187 	 char *buf,
2188 	 size_t bufsize)
2189 {
2190 	/* big enough for hex int or decimal t->id? */
2191 	if (bufsize < sizeof(void *) * 2 + 3 || bufsize < sizeof(t->id) * 3 + 1)
2192 		return "unable";
2193 	if (t->id != 0)
2194 		sprintf(buf, "%d", t->id);
2195 	else
2196 		sprintf(buf, "%p", t);
2197 	return buf;
2198 }
2199 #endif							/* REG_DEBUG */
2200 
2201 
2202 #include "regc_lex.c"
2203 #include "regc_color.c"
2204 #include "regc_nfa.c"
2205 #include "regc_cvec.c"
2206 #include "regc_pg_locale.c"
2207 #include "regc_locale.c"
2208