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