xref: /illumos-gate/usr/src/lib/libc/port/regex/regcomp.c (revision ac2250cb76bb32944fd2c8a3ba2cd3f79747748d)
1 /*
2  * Copyright 2023 Bill Sommerfeld <sommerfeld@hamachi.org>
3  * Copyright 2013 Garrett D'Amore <garrett@damore.org>
4  * Copyright 2019 Nexenta by DDN, Inc. All rights reserved.
5  * Copyright 2012 Milan Jurik. All rights reserved.
6  * Copyright (c) 1992, 1993, 1994 Henry Spencer.
7  * Copyright (c) 1992, 1993, 1994
8  *	The Regents of the University of California.  All rights reserved.
9  *
10  * This code is derived from software contributed to Berkeley by
11  * Henry Spencer.
12  *
13  * Redistribution and use in source and binary forms, with or without
14  * modification, are permitted provided that the following conditions
15  * are met:
16  * 1. Redistributions of source code must retain the above copyright
17  *    notice, this list of conditions and the following disclaimer.
18  * 2. Redistributions in binary form must reproduce the above copyright
19  *    notice, this list of conditions and the following disclaimer in the
20  *    documentation and/or other materials provided with the distribution.
21  * 3. Neither the name of the University nor the names of its contributors
22  *    may be used to endorse or promote products derived from this software
23  *    without specific prior written permission.
24  *
25  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
26  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
28  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
29  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
31  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35  * SUCH DAMAGE.
36  */
37 
38 #include "lint.h"
39 #include "thr_uberdata.h"
40 #include "file64.h"
41 #include <sys/types.h>
42 #include <stdio.h>
43 #include <string.h>
44 #include <ctype.h>
45 #include <limits.h>
46 #include <regex.h>
47 #include <stdlib.h>
48 #include <stdbool.h>
49 #include <wchar.h>
50 #include <wctype.h>
51 
52 #include "../locale/runetype.h"
53 #include "../locale/collate.h"
54 
55 #include "utils.h"
56 #include "regex2.h"
57 
58 #include "cname.h"
59 #include "../locale/mblocal.h"
60 
61 /*
62  * Branching context, used to keep track of branch state for all of the branch-
63  * aware functions. In addition to keeping track of branch positions for the
64  * p_branch_* functions, we use this to simplify some clumsiness in BREs for
65  * detection of whether ^ is acting as an anchor or being used erroneously and
66  * also for whether we're in a sub-expression or not.
67  */
68 struct branchc {
69 	sopno start;
70 	sopno back;
71 	sopno fwd;
72 
73 	int nbranch;
74 	int nchain;
75 	bool outer;
76 	bool terminate;
77 };
78 
79 /*
80  * parse structure, passed up and down to avoid global variables and
81  * other clumsinesses
82  */
83 struct parse {
84 	const char *next;	/* next character in RE */
85 	const char *end;	/* end of string (-> NUL normally) */
86 	int error;		/* has an error been seen? */
87 	sop *strip;		/* malloced strip */
88 	sopno ssize;		/* malloced strip size (allocated) */
89 	sopno slen;		/* malloced strip length (used) */
90 	int ncsalloc;		/* number of csets allocated */
91 	wint_t nc;		/* size of small-char bitmap in cset */
92 	struct re_guts *g;
93 #define	NPAREN	10		/* we need to remember () 1-9 for back refs */
94 	sopno pbegin[NPAREN];	/* -> ( ([0] unused) */
95 	sopno pend[NPAREN];	/* -> ) ([0] unused) */
96 	bool allowbranch;	/* can this expression branch? */
97 	bool bre;		/* convenience; is this a BRE? */
98 	bool (*parse_expr)(struct parse *, struct branchc *);
99 	void (*pre_parse)(struct parse *, struct branchc *);
100 	void (*post_parse)(struct parse *, struct branchc *);
101 };
102 
103 /* ========= begin header generated by ./mkh ========= */
104 #ifdef __cplusplus
105 extern "C" {
106 #endif
107 
108 /* === regcomp.c === */
109 static bool p_ere_exp(struct parse *p, struct branchc *bc);
110 static void p_str(struct parse *p);
111 static int p_branch_eat_delim(struct parse *p, struct branchc *bc);
112 static void p_branch_ins_offset(struct parse *p, struct branchc *bc);
113 static void p_branch_fix_tail(struct parse *p, struct branchc *bc);
114 static bool p_branch_empty(struct parse *p, struct branchc *bc);
115 static bool p_branch_do(struct parse *p, struct branchc *bc);
116 static void p_bre_pre_parse(struct parse *p, struct branchc *bc);
117 static void p_bre_post_parse(struct parse *p, struct branchc *bc);
118 static void p_re(struct parse *p, int end1, int end2);
119 static bool p_simp_re(struct parse *p, struct branchc *bc);
120 static int p_count(struct parse *p);
121 static void p_bracket(struct parse *p);
122 static void p_b_term(struct parse *p, cset *cs);
123 static void p_b_cclass(struct parse *p, cset *cs);
124 static void p_b_eclass(struct parse *p, cset *cs);
125 static wint_t p_b_symbol(struct parse *p);
126 static wint_t p_b_coll_elem(struct parse *p, wint_t endc);
127 static wint_t othercase(wint_t ch);
128 static void bothcases(struct parse *p, wint_t ch);
129 static void ordinary(struct parse *p, wint_t ch);
130 static void nonnewline(struct parse *p);
131 static void repeat(struct parse *p, sopno start, int from, int to);
132 static int seterr(struct parse *p, int e);
133 static cset *allocset(struct parse *p);
134 static void freeset(struct parse *p, cset *cs);
135 static void CHadd(struct parse *p, cset *cs, wint_t ch);
136 static void CHaddrange(struct parse *p, cset *cs, wint_t min, wint_t max);
137 static void CHaddtype(struct parse *p, cset *cs, wctype_t wct);
138 static wint_t singleton(struct parse *p, cset *cs);
139 static sopno dupl(struct parse *p, sopno start, sopno finish);
140 static void doemit(struct parse *p, sop op, size_t opnd);
141 static void doinsert(struct parse *p, sop op, size_t opnd, sopno pos);
142 static void dofwd(struct parse *p, sopno pos, sop value);
143 static int enlarge(struct parse *p, sopno size);
144 static void stripsnug(struct parse *p, struct re_guts *g);
145 static void findmust(struct parse *p, struct re_guts *g);
146 static int altoffset(sop *scan, int offset);
147 static void computejumps(struct parse *p, struct re_guts *g);
148 static void computematchjumps(struct parse *p, struct re_guts *g);
149 static sopno pluscount(struct parse *p, struct re_guts *g);
150 static wint_t wgetnext(struct parse *p);
151 
152 #ifdef __cplusplus
153 }
154 #endif
155 /* ========= end header generated by ./mkh ========= */
156 
157 static char nuls[10];		/* place to point scanner in event of error */
158 
159 /*
160  * macros for use with parse structure
161  * BEWARE:  these know that the parse structure is named `p' !!!
162  */
163 #define	PEEK()	(*p->next)
164 #define	PEEK2()	(*(p->next+1))
165 #define	MORE()	(p->next < p->end)
166 #define	MORE2()	(p->next+1 < p->end)
167 #define	SEE(c)	(MORE() && PEEK() == (c))
168 #define	SEETWO(a, b)	(MORE() && MORE2() && PEEK() == (a) && PEEK2() == (b))
169 #define	SEESPEC(a)	(p->bre ? SEETWO('\\', a) : SEE(a))
170 #define	EAT(c)	((SEE(c)) ? (NEXT(), 1) : 0)
171 #define	EATTWO(a, b)	((SEETWO(a, b)) ? (NEXT2(), 1) : 0)
172 #define	NEXT()	(p->next++)
173 #define	NEXT2()	(p->next += 2)
174 #define	NEXTn(n)	(p->next += (n))
175 #define	GETNEXT()	(*p->next++)
176 #define	WGETNEXT()	wgetnext(p)
177 #define	SETERROR(e)	((void)seterr(p, (e)))
178 #define	REQUIRE(co, e)	((co) || seterr(p, e))
179 #define	MUSTSEE(c, e)	(REQUIRE(MORE() && PEEK() == (c), e))
180 #define	MUSTEAT(c, e)	(REQUIRE(MORE() && GETNEXT() == (c), e))
181 #define	MUSTNOTSEE(c, e)	(REQUIRE(!MORE() || PEEK() != (c), e))
182 #define	EMIT(op, sopnd)	doemit(p, (sop)(op), (size_t)(sopnd))
183 #define	INSERT(op, pos)	doinsert(p, (sop)(op), HERE()-(pos)+1, pos)
184 #define	AHEAD(pos)		dofwd(p, pos, HERE()-(pos))
185 #define	ASTERN(sop, pos)	EMIT(sop, HERE()-pos)
186 #define	HERE()		(p->slen)
187 #define	THERE()		(p->slen - 1)
188 #define	THERETHERE()	(p->slen - 2)
189 #define	DROP(n)	(p->slen -= (n))
190 
191 #ifndef NDEBUG
192 static int never = 0;		/* for use in asserts; shuts lint up */
193 #else
194 #define	never	0		/* some <assert.h>s have bugs too */
195 #endif
196 
197 /*
198  * regcomp - interface for parser and compilation
199  */
200 int				/* 0 success, otherwise REG_something */
201 regcomp(regex_t *_RESTRICT_KYWD preg, const char *_RESTRICT_KYWD pattern,
202     int cflags)
203 {
204 	struct parse pa;
205 	struct re_guts *g;
206 	struct parse *p = &pa;
207 	int i;
208 	size_t len;
209 	size_t maxlen;
210 #ifdef REDEBUG
211 #define	GOODFLAGS(f)	(f)
212 #else
213 #define	GOODFLAGS(f)	((f)&~REG_DUMP)
214 #endif
215 
216 	/*
217 	 * Which character values are kept in cset bitmaps?
218 	 *
219 	 * Character sets store their members as a bitmap (for low-codepoint
220 	 * characters) or as elements of an array; pa.nc sets the dividing
221 	 * point between them.
222 	 *
223 	 * The value of MB_CUR_MAX depends on the current locale; fetching the
224 	 * current locale can be expensive, so we pick a value now and stick
225 	 * with it for the lifetime of the compiled regex.
226 	 */
227 	pa.nc = ((MB_CUR_MAX) == 1 ? (NC_MAX) : (NC_WIDE));
228 
229 	/* We had REG_INVARG, but we don't have that on Solaris. */
230 	cflags = GOODFLAGS(cflags);
231 	if ((cflags&REG_EXTENDED) && (cflags&REG_NOSPEC))
232 		return (REG_EFATAL);
233 
234 	if (cflags&REG_PEND) {
235 		if (preg->re_endp < pattern)
236 			return (REG_EFATAL);
237 		len = preg->re_endp - pattern;
238 	} else
239 		len = strlen(pattern);
240 
241 	/* do the mallocs early so failure handling is easy */
242 	g = (struct re_guts *)malloc(sizeof (struct re_guts));
243 	if (g == NULL)
244 		return (REG_ESPACE);
245 	g->mb_cur_max = MB_CUR_MAX;
246 	/*
247 	 * Limit the pattern space to avoid a 32-bit overflow on buffer
248 	 * extension.  Also avoid any signed overflow in case of conversion
249 	 * so make the real limit based on a 31-bit overflow.
250 	 *
251 	 * Likely not applicable on 64-bit systems but handle the case
252 	 * generically (who are we to stop people from using ~715MB+
253 	 * patterns?).
254 	 */
255 	maxlen = ((size_t)-1 >> 1) / sizeof (sop) * 2 / 3;
256 	if (len >= maxlen) {
257 		free((char *)g);
258 		return (REG_ESPACE);
259 	}
260 	p->ssize = len/(size_t)2*(size_t)3 + (size_t)1;	/* ugh */
261 	assert(p->ssize >= len);
262 
263 	p->strip = (sop *)malloc(p->ssize * sizeof (sop));
264 	p->slen = 0;
265 	if (p->strip == NULL) {
266 		free((char *)g);
267 		return (REG_ESPACE);
268 	}
269 
270 	/* set things up */
271 	p->g = g;
272 	p->next = pattern;	/* convenience; we do not modify it */
273 	p->end = p->next + len;
274 	p->error = 0;
275 	p->ncsalloc = 0;
276 	for (i = 0; i < NPAREN; i++) {
277 		p->pbegin[i] = 0;
278 		p->pend[i] = 0;
279 	}
280 	if (cflags & REG_EXTENDED) {
281 		p->allowbranch = true;
282 		p->bre = false;
283 		p->parse_expr = p_ere_exp;
284 		p->pre_parse = NULL;
285 		p->post_parse = NULL;
286 	} else {
287 		p->allowbranch = false;
288 		p->bre = true;
289 		p->parse_expr = p_simp_re;
290 		p->pre_parse = p_bre_pre_parse;
291 		p->post_parse = p_bre_post_parse;
292 	}
293 	g->sets = NULL;
294 	g->ncsets = 0;
295 	g->cflags = cflags;
296 	g->iflags = 0;
297 	g->nbol = 0;
298 	g->neol = 0;
299 	g->must = NULL;
300 	g->moffset = -1;
301 	g->charjump = NULL;
302 	g->matchjump = NULL;
303 	g->mlen = 0;
304 	g->nsub = 0;
305 	g->backrefs = 0;
306 
307 	/* do it */
308 	EMIT(OEND, 0);
309 	g->firststate = THERE();
310 	if (cflags & REG_NOSPEC)
311 		p_str(p);
312 	else
313 		p_re(p, OUT, OUT);
314 	EMIT(OEND, 0);
315 	g->laststate = THERE();
316 
317 	/* tidy up loose ends and fill things in */
318 	stripsnug(p, g);
319 	findmust(p, g);
320 	/*
321 	 * only use Boyer-Moore algorithm if the pattern is bigger
322 	 * than three characters
323 	 */
324 	if (g->mlen > 3) {
325 		computejumps(p, g);
326 		computematchjumps(p, g);
327 		if (g->matchjump == NULL && g->charjump != NULL) {
328 			free(g->charjump);
329 			g->charjump = NULL;
330 		}
331 	}
332 	g->nplus = pluscount(p, g);
333 	g->magic = MAGIC2;
334 	preg->re_nsub = g->nsub;
335 	preg->re_g = g;
336 	preg->re_magic = MAGIC1;
337 #ifndef REDEBUG
338 	/* not debugging, so can't rely on the assert() in regexec() */
339 	if (g->iflags&BAD)
340 		SETERROR(REG_EFATAL);
341 #endif
342 
343 	/* win or lose, we're done */
344 	if (p->error != 0)	/* lose */
345 		regfree(preg);
346 	return (p->error);
347 }
348 
349 /*
350  * Parse one subERE, an atom possibly followed by a repetition op,
351  * return whether we should terminate or not.
352  */
353 static bool
354 p_ere_exp(struct parse *p, struct branchc *bc)
355 {
356 	char c;
357 	wint_t wc;
358 	sopno pos;
359 	int count;
360 	int count2;
361 	sopno subno;
362 	int wascaret = 0;
363 
364 	(void) bc;
365 	assert(MORE());		/* caller should have ensured this */
366 	c = GETNEXT();
367 
368 	pos = HERE();
369 	switch (c) {
370 	case '(':
371 		(void) REQUIRE(MORE(), REG_EPAREN);
372 		p->g->nsub++;
373 		subno = p->g->nsub;
374 		if (subno < NPAREN)
375 			p->pbegin[subno] = HERE();
376 		EMIT(OLPAREN, subno);
377 		if (!SEE(')'))
378 			p_re(p, ')', IGN);
379 		if (subno < NPAREN) {
380 			p->pend[subno] = HERE();
381 			assert(p->pend[subno] != 0);
382 		}
383 		EMIT(ORPAREN, subno);
384 		(void) MUSTEAT(')', REG_EPAREN);
385 		break;
386 #ifndef POSIX_MISTAKE
387 	case ')':		/* happens only if no current unmatched ( */
388 		/*
389 		 * You may ask, why the ifndef?  Because I didn't notice
390 		 * this until slightly too late for 1003.2, and none of the
391 		 * other 1003.2 regular-expression reviewers noticed it at
392 		 * all.  So an unmatched ) is legal POSIX, at least until
393 		 * we can get it fixed.
394 		 */
395 		SETERROR(REG_EPAREN);
396 		break;
397 #endif
398 	case '^':
399 		EMIT(OBOL, 0);
400 		p->g->iflags |= USEBOL;
401 		p->g->nbol++;
402 		wascaret = 1;
403 		break;
404 	case '$':
405 		EMIT(OEOL, 0);
406 		p->g->iflags |= USEEOL;
407 		p->g->neol++;
408 		break;
409 	case '|':
410 		SETERROR(REG_BADPAT);
411 		break;
412 	case '*':
413 	case '+':
414 	case '?':
415 	case '{':
416 		SETERROR(REG_BADRPT);
417 		break;
418 	case '.':
419 		if (p->g->cflags&REG_NEWLINE)
420 			nonnewline(p);
421 		else
422 			EMIT(OANY, 0);
423 		break;
424 	case '[':
425 		p_bracket(p);
426 		break;
427 	case '\\':
428 		(void) REQUIRE(MORE(), REG_EESCAPE);
429 		wc = WGETNEXT();
430 		switch (wc) {
431 		case '<':
432 			EMIT(OBOW, 0);
433 			break;
434 		case '>':
435 			EMIT(OEOW, 0);
436 			break;
437 		default:
438 			ordinary(p, wc);
439 			break;
440 		}
441 		break;
442 	default:
443 		if (p->error != 0)
444 			return (false);
445 		p->next--;
446 		wc = WGETNEXT();
447 		ordinary(p, wc);
448 		break;
449 	}
450 
451 	if (!MORE())
452 		return (false);
453 	c = PEEK();
454 	/* we call { a repetition if followed by a digit */
455 	if (!(c == '*' || c == '+' || c == '?' || c == '{'))
456 		return (false);		/* no repetition, we're done */
457 	else if (c == '{')
458 		(void) REQUIRE(MORE2() && \
459 		    (isdigit((uch)PEEK2()) || PEEK2() == ','), REG_BADRPT);
460 	NEXT();
461 
462 	(void) REQUIRE(!wascaret, REG_BADRPT);
463 	switch (c) {
464 	case '*':	/* implemented as +? */
465 		/* this case does not require the (y|) trick, noKLUDGE */
466 		INSERT(OPLUS_, pos);
467 		ASTERN(O_PLUS, pos);
468 		INSERT(OQUEST_, pos);
469 		ASTERN(O_QUEST, pos);
470 		break;
471 	case '+':
472 		INSERT(OPLUS_, pos);
473 		ASTERN(O_PLUS, pos);
474 		break;
475 	case '?':
476 		/* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
477 		INSERT(OCH_, pos);		/* offset slightly wrong */
478 		ASTERN(OOR1, pos);		/* this one's right */
479 		AHEAD(pos);			/* fix the OCH_ */
480 		EMIT(OOR2, 0);			/* offset very wrong... */
481 		AHEAD(THERE());			/* ...so fix it */
482 		ASTERN(O_CH, THERETHERE());
483 		break;
484 	case '{':
485 		count = p_count(p);
486 		if (EAT(',')) {
487 			if (isdigit((uch)PEEK())) {
488 				count2 = p_count(p);
489 				(void) REQUIRE(count <= count2, REG_BADBR);
490 			} else		/* single number with comma */
491 				count2 = INFINITY;
492 		} else		/* just a single number */
493 			count2 = count;
494 		repeat(p, pos, count, count2);
495 		if (!EAT('}')) {	/* error heuristics */
496 			while (MORE() && PEEK() != '}')
497 				NEXT();
498 			(void) REQUIRE(MORE(), REG_EBRACE);
499 			SETERROR(REG_BADBR);
500 		}
501 		break;
502 	}
503 
504 	if (!MORE())
505 		return (false);
506 	c = PEEK();
507 	if (!(c == '*' || c == '+' || c == '?' ||
508 	    (c == '{' && MORE2() && isdigit((uch)PEEK2()))))
509 		return (false);
510 	SETERROR(REG_BADRPT);
511 	return (false);
512 }
513 
514 /*
515  * p_str - string (no metacharacters) "parser"
516  */
517 static void
518 p_str(struct parse *p)
519 {
520 	(void) REQUIRE(MORE(), REG_BADPAT);
521 	while (MORE())
522 		ordinary(p, WGETNEXT());
523 }
524 
525 /*
526  * Eat consecutive branch delimiters for the kind of expression that we are
527  * parsing, return the number of delimiters that we ate.
528  */
529 static int
530 p_branch_eat_delim(struct parse *p, struct branchc *bc)
531 {
532 	int nskip;
533 
534 	(void) bc;
535 	nskip = 0;
536 	while (EAT('|'))
537 		++nskip;
538 	return (nskip);
539 }
540 
541 /*
542  * Insert necessary branch book-keeping operations. This emits a
543  * bogus 'next' offset, since we still have more to parse
544  */
545 static void
546 p_branch_ins_offset(struct parse *p, struct branchc *bc)
547 {
548 	if (bc->nbranch == 0) {
549 		INSERT(OCH_, bc->start);	/* offset is wrong */
550 		bc->fwd = bc->start;
551 		bc->back = bc->start;
552 	}
553 
554 	ASTERN(OOR1, bc->back);
555 	bc->back = THERE();
556 	AHEAD(bc->fwd);			/* fix previous offset */
557 	bc->fwd = HERE();
558 	EMIT(OOR2, 0);			/* offset is very wrong */
559 	++bc->nbranch;
560 }
561 
562 /*
563  * Fix the offset of the tail branch, if we actually had any branches.
564  * This is to correct the bogus placeholder offset that we use.
565  */
566 static void
567 p_branch_fix_tail(struct parse *p, struct branchc *bc)
568 {
569 	/* Fix bogus offset at the tail if we actually have branches */
570 	if (bc->nbranch > 0) {
571 		AHEAD(bc->fwd);
572 		ASTERN(O_CH, bc->back);
573 	}
574 }
575 
576 /*
577  * Signal to the parser that an empty branch has been encountered; this will,
578  * in the future, be used to allow for more permissive behavior with empty
579  * branches. The return value should indicate whether parsing may continue
580  * or not.
581  */
582 static bool
583 p_branch_empty(struct parse *p, struct branchc *bc)
584 {
585 	(void) bc;
586 	SETERROR(REG_BADPAT);
587 	return (false);
588 }
589 
590 /*
591  * Take care of any branching requirements. This includes inserting the
592  * appropriate branching instructions as well as eating all of the branch
593  * delimiters until we either run out of pattern or need to parse more pattern.
594  */
595 static bool
596 p_branch_do(struct parse *p, struct branchc *bc)
597 {
598 	int ate = 0;
599 
600 	ate = p_branch_eat_delim(p, bc);
601 	if (ate == 0)
602 		return (false);
603 	else if ((ate > 1 || (bc->outer && !MORE())) && !p_branch_empty(p, bc))
604 		/*
605 		 * Halt parsing only if we have an empty branch and
606 		 * p_branch_empty indicates that we must not continue.
607 		 * In the future, this will not  necessarily be an error.
608 		 */
609 		return (false);
610 	p_branch_ins_offset(p, bc);
611 
612 	return (true);
613 }
614 
615 static void
616 p_bre_pre_parse(struct parse *p, struct branchc *bc)
617 {
618 	(void) bc;
619 	/*
620 	 * Does not move cleanly into expression parser because of
621 	 * ordinary interpration of * at the beginning position of
622 	 * an expression.
623 	 */
624 	if (EAT('^')) {
625 		EMIT(OBOL, 0);
626 		p->g->iflags |= USEBOL;
627 		p->g->nbol++;
628 	}
629 }
630 
631 static void
632 p_bre_post_parse(struct parse *p, struct branchc *bc)
633 {
634 	/* Expression is terminating due to EOL token */
635 	if (bc->terminate) {
636 		DROP(1);
637 		EMIT(OEOL, 0);
638 		p->g->iflags |= USEEOL;
639 		p->g->neol++;
640 	}
641 }
642 
643 /*
644  * Top level parser, concatenation and BRE anchoring.
645  * Giving end1 as OUT essentially eliminates the end1/end2 check.
646  *
647  * This implementation is a bit of a kludge, in that a trailing $ is first
648  * taken as an ordinary character and then revised to be an anchor.
649  * The amount of lookahead needed to avoid this kludge is excessive.
650  */
651 static void
652 p_re(struct parse *p,
653     int end1,	/* first terminating character */
654     int end2)	/* second terminating character; ignored for EREs */
655 {
656 	struct branchc bc;
657 
658 	bc.nbranch = 0;
659 	if (end1 == OUT && end2 == OUT)
660 		bc.outer = true;
661 	else
662 		bc.outer = false;
663 #define	SEEEND()	(!p->bre ? SEE(end1) : SEETWO(end1, end2))
664 	for (;;) {
665 		bc.start = HERE();
666 		bc.nchain = 0;
667 		bc.terminate = false;
668 		if (p->pre_parse != NULL)
669 			p->pre_parse(p, &bc);
670 		while (MORE() && (!p->allowbranch || !SEESPEC('|')) &&
671 		    !SEEEND()) {
672 			bc.terminate = p->parse_expr(p, &bc);
673 			++bc.nchain;
674 		}
675 		if (p->post_parse != NULL)
676 			p->post_parse(p, &bc);
677 		(void) REQUIRE(HERE() != bc.start, REG_BADPAT);
678 		if (!p->allowbranch)
679 			break;
680 		/*
681 		 * p_branch_do's return value indicates whether we should
682 		 * continue parsing or not. This is both for correctness and
683 		 * a slight optimization, because it will check if we've
684 		 * encountered an empty branch or the end of the string
685 		 * immediately following a branch delimiter.
686 		 */
687 		if (!p_branch_do(p, &bc))
688 			break;
689 	}
690 #undef SEE_END
691 	if (p->allowbranch)
692 		p_branch_fix_tail(p, &bc);
693 	assert(!MORE() || SEE(end1));
694 }
695 
696 /*
697  * p_simp_re - parse a simple RE, an atom possibly followed by a repetition
698  */
699 static bool			/* was the simple RE an unbackslashed $? */
700 p_simp_re(struct parse *p, struct branchc *bc)
701 {
702 	int c;
703 	int count;
704 	int count2;
705 	sopno pos;
706 	int i;
707 	wint_t wc;
708 	sopno subno;
709 #define	BACKSL	(1<<CHAR_BIT)
710 
711 	pos = HERE();		/* repetition op, if any, covers from here */
712 
713 	assert(MORE());		/* caller should have ensured this */
714 	c = GETNEXT();
715 	if (c == '\\') {
716 		(void) REQUIRE(MORE(), REG_EESCAPE);
717 		c = BACKSL | GETNEXT();
718 	}
719 	switch (c) {
720 	case '.':
721 		if (p->g->cflags&REG_NEWLINE)
722 			nonnewline(p);
723 		else
724 			EMIT(OANY, 0);
725 		break;
726 	case '[':
727 		p_bracket(p);
728 		break;
729 	case BACKSL|'<':
730 		EMIT(OBOW, 0);
731 		break;
732 	case BACKSL|'>':
733 		EMIT(OEOW, 0);
734 		break;
735 	case BACKSL|'{':
736 		SETERROR(REG_BADRPT);
737 		break;
738 	case BACKSL|'(':
739 		p->g->nsub++;
740 		subno = p->g->nsub;
741 		if (subno < NPAREN)
742 			p->pbegin[subno] = HERE();
743 		EMIT(OLPAREN, subno);
744 		/* the MORE here is an error heuristic */
745 		if (MORE() && !SEETWO('\\', ')'))
746 			p_re(p, '\\', ')');
747 		if (subno < NPAREN) {
748 			p->pend[subno] = HERE();
749 			assert(p->pend[subno] != 0);
750 		}
751 		EMIT(ORPAREN, subno);
752 		(void) REQUIRE(EATTWO('\\', ')'), REG_EPAREN);
753 		break;
754 	case BACKSL|')':	/* should not get here -- must be user */
755 		SETERROR(REG_EPAREN);
756 		break;
757 	case BACKSL|'1':
758 	case BACKSL|'2':
759 	case BACKSL|'3':
760 	case BACKSL|'4':
761 	case BACKSL|'5':
762 	case BACKSL|'6':
763 	case BACKSL|'7':
764 	case BACKSL|'8':
765 	case BACKSL|'9':
766 		i = (c&~BACKSL) - '0';
767 		assert(i < NPAREN);
768 		if (p->pend[i] != 0) {
769 			assert(i <= p->g->nsub);
770 			EMIT(OBACK_, i);
771 			assert(p->pbegin[i] != 0);
772 			assert(OP(p->strip[p->pbegin[i]]) == OLPAREN);
773 			assert(OP(p->strip[p->pend[i]]) == ORPAREN);
774 			(void) dupl(p, p->pbegin[i]+1, p->pend[i]);
775 			EMIT(O_BACK, i);
776 		} else
777 			SETERROR(REG_ESUBREG);
778 		p->g->backrefs = 1;
779 		break;
780 	case '*':
781 		/*
782 		 * Ordinary if used as the first character beyond BOL anchor of
783 		 * a (sub-)expression, counts as a bad repetition operator if it
784 		 * appears otherwise.
785 		 */
786 		(void) REQUIRE(bc->nchain == 0, REG_BADRPT);
787 		/* FALLTHROUGH */
788 	default:
789 		if (p->error != 0)
790 			return (false);	/* Definitely not $... */
791 		p->next--;
792 		wc = WGETNEXT();
793 		ordinary(p, wc);
794 		break;
795 	}
796 
797 	if (EAT('*')) {		/* implemented as +? */
798 		/* this case does not require the (y|) trick, noKLUDGE */
799 		INSERT(OPLUS_, pos);
800 		ASTERN(O_PLUS, pos);
801 		INSERT(OQUEST_, pos);
802 		ASTERN(O_QUEST, pos);
803 	} else if (EATTWO('\\', '{')) {
804 		count = p_count(p);
805 		if (EAT(',')) {
806 			if (MORE() && isdigit((uch)PEEK())) {
807 				count2 = p_count(p);
808 				(void) REQUIRE(count <= count2, REG_BADBR);
809 			} else		/* single number with comma */
810 				count2 = INFINITY;
811 		} else		/* just a single number */
812 			count2 = count;
813 		repeat(p, pos, count, count2);
814 		if (!EATTWO('\\', '}')) {	/* error heuristics */
815 			while (MORE() && !SEETWO('\\', '}'))
816 				NEXT();
817 			(void) REQUIRE(MORE(), REG_EBRACE);
818 			SETERROR(REG_BADBR);
819 		}
820 	} else if (c == '$')	/* $ (but not \$) ends it */
821 		return (true);
822 
823 	return (false);
824 }
825 
826 /*
827  * p_count - parse a repetition count
828  */
829 static int			/* the value */
830 p_count(struct parse *p)
831 {
832 	int count = 0;
833 	int ndigits = 0;
834 
835 	while (MORE() && isdigit((uch)PEEK()) && count <= DUPMAX) {
836 		count = count*10 + (GETNEXT() - '0');
837 		ndigits++;
838 	}
839 
840 	(void) REQUIRE(ndigits > 0 && count <= DUPMAX, REG_BADBR);
841 	return (count);
842 }
843 
844 /*
845  * p_bracket - parse a bracketed character list
846  */
847 static void
848 p_bracket(struct parse *p)
849 {
850 	cset *cs;
851 	wint_t ch;
852 
853 	/* Dept of Truly Sickening Special-Case Kludges */
854 	if (p->next + 5 < p->end && strncmp(p->next, "[:<:]]", 6) == 0) {
855 		EMIT(OBOW, 0);
856 		NEXTn(6);
857 		return;
858 	}
859 	if (p->next + 5 < p->end && strncmp(p->next, "[:>:]]", 6) == 0) {
860 		EMIT(OEOW, 0);
861 		NEXTn(6);
862 		return;
863 	}
864 
865 	if ((cs = allocset(p)) == NULL)
866 		return;
867 
868 	if (p->g->cflags&REG_ICASE)
869 		cs->icase = 1;
870 	if (EAT('^'))
871 		cs->invert = 1;
872 	if (EAT(']'))
873 		CHadd(p, cs, ']');
874 	else if (EAT('-'))
875 		CHadd(p, cs, '-');
876 	while (MORE() && PEEK() != ']' && !SEETWO('-', ']'))
877 		p_b_term(p, cs);
878 	if (EAT('-'))
879 		CHadd(p, cs, '-');
880 	(void) MUSTEAT(']', REG_EBRACK);
881 
882 	if (p->error != 0)	/* don't mess things up further */
883 		return;
884 
885 	if (cs->invert && p->g->cflags&REG_NEWLINE)
886 		cs->bmp['\n' >> 3] |= 1 << ('\n' & 7);
887 
888 	if ((ch = singleton(p, cs)) != OUT) {	/* optimize singleton sets */
889 		ordinary(p, ch);
890 		freeset(p, cs);
891 	} else
892 		EMIT(OANYOF, (int)(cs - p->g->sets));
893 }
894 
895 /*
896  * p_b_term - parse one term of a bracketed character list
897  */
898 static void
899 p_b_term(struct parse *p, cset *cs)
900 {
901 	char c;
902 	wint_t start, finish;
903 	wint_t i;
904 	locale_t loc = __curlocale();
905 
906 	/* classify what we've got */
907 	switch ((MORE()) ? PEEK() : '\0') {
908 	case '[':
909 		c = (MORE2()) ? PEEK2() : '\0';
910 		break;
911 	case '-':
912 		SETERROR(REG_ERANGE);
913 		return;			/* NOTE RETURN */
914 	default:
915 		c = '\0';
916 		break;
917 	}
918 
919 	switch (c) {
920 	case ':':		/* character class */
921 		NEXT2();
922 		(void) REQUIRE(MORE(), REG_EBRACK);
923 		c = PEEK();
924 		(void) REQUIRE(c != '-' && c != ']', REG_ECTYPE);
925 		p_b_cclass(p, cs);
926 		(void) REQUIRE(MORE(), REG_EBRACK);
927 		(void) REQUIRE(EATTWO(':', ']'), REG_ECTYPE);
928 		break;
929 	case '=':		/* equivalence class */
930 		NEXT2();
931 		(void) REQUIRE(MORE(), REG_EBRACK);
932 		c = PEEK();
933 		(void) REQUIRE(c != '-' && c != ']', REG_ECOLLATE);
934 		p_b_eclass(p, cs);
935 		(void) REQUIRE(MORE(), REG_EBRACK);
936 		(void) REQUIRE(EATTWO('=', ']'), REG_ECOLLATE);
937 		break;
938 	default:		/* symbol, ordinary character, or range */
939 		start = p_b_symbol(p);
940 		if (SEE('-') && MORE2() && PEEK2() != ']') {
941 			/* range */
942 			NEXT();
943 			if (EAT('-'))
944 				finish = '-';
945 			else
946 				finish = p_b_symbol(p);
947 		} else
948 			finish = start;
949 		if (start == finish)
950 			CHadd(p, cs, start);
951 		else {
952 			if (loc->collate->lc_is_posix) {
953 				(void) REQUIRE((uch)start <= (uch)finish,
954 				    REG_ERANGE);
955 				CHaddrange(p, cs, start, finish);
956 			} else {
957 				(void) REQUIRE(_collate_range_cmp(start,
958 				    finish, loc) <= 0, REG_ERANGE);
959 				for (i = 0; i <= UCHAR_MAX; i++) {
960 					if (_collate_range_cmp(start, i, loc)
961 					    <= 0 &&
962 					    _collate_range_cmp(i, finish, loc)
963 					    <= 0)
964 						CHadd(p, cs, i);
965 				}
966 			}
967 		}
968 		break;
969 	}
970 }
971 
972 /*
973  * p_b_cclass - parse a character-class name and deal with it
974  */
975 static void
976 p_b_cclass(struct parse *p, cset *cs)
977 {
978 	const char *sp = p->next;
979 	size_t len;
980 	wctype_t wct;
981 	char clname[16];
982 
983 	while (MORE() && isalpha((uch)PEEK()))
984 		NEXT();
985 	len = p->next - sp;
986 	if (len >= sizeof (clname) - 1) {
987 		SETERROR(REG_ECTYPE);
988 		return;
989 	}
990 	(void) memcpy(clname, sp, len);
991 	clname[len] = '\0';
992 	if ((wct = wctype(clname)) == 0) {
993 		SETERROR(REG_ECTYPE);
994 		return;
995 	}
996 	CHaddtype(p, cs, wct);
997 }
998 
999 /*
1000  * p_b_eclass - parse an equivalence-class name and deal with it
1001  *
1002  * This implementation is incomplete. xxx
1003  */
1004 static void
1005 p_b_eclass(struct parse *p, cset *cs)
1006 {
1007 	wint_t c;
1008 
1009 	c = p_b_coll_elem(p, '=');
1010 	CHadd(p, cs, c);
1011 }
1012 
1013 /*
1014  * p_b_symbol - parse a character or [..]ed multicharacter collating symbol
1015  */
1016 static wint_t			/* value of symbol */
1017 p_b_symbol(struct parse *p)
1018 {
1019 	wint_t value;
1020 
1021 	(void) REQUIRE(MORE(), REG_EBRACK);
1022 	if (!EATTWO('[', '.'))
1023 		return (WGETNEXT());
1024 
1025 	/* collating symbol */
1026 	value = p_b_coll_elem(p, '.');
1027 	(void) REQUIRE(EATTWO('.', ']'), REG_ECOLLATE);
1028 	return (value);
1029 }
1030 
1031 /*
1032  * p_b_coll_elem - parse a collating-element name and look it up
1033  */
1034 static wint_t			/* value of collating element */
1035 p_b_coll_elem(struct parse *p,
1036     wint_t endc)		/* name ended by endc,']' */
1037 {
1038 	const char *sp = p->next;
1039 	struct cname *cp;
1040 	mbstate_t mbs;
1041 	wchar_t wc;
1042 	size_t clen, len;
1043 
1044 	while (MORE() && !SEETWO(endc, ']'))
1045 		NEXT();
1046 	if (!MORE()) {
1047 		SETERROR(REG_EBRACK);
1048 		return (0);
1049 	}
1050 	len = p->next - sp;
1051 	for (cp = cnames; cp->name != NULL; cp++)
1052 		if (strncmp(cp->name, sp, len) == 0 && strlen(cp->name) == len)
1053 			return (cp->code);	/* known name */
1054 	(void) memset(&mbs, 0, sizeof (mbs));
1055 	if ((clen = mbrtowc(&wc, sp, len, &mbs)) == len)
1056 		return (wc);			/* single character */
1057 	else if (clen == (size_t)-1 || clen == (size_t)-2)
1058 		SETERROR(REG_ECHAR);
1059 	else
1060 		SETERROR(REG_ECOLLATE);		/* neither */
1061 	return (0);
1062 }
1063 
1064 /*
1065  * othercase - return the case counterpart of an alphabetic
1066  */
1067 static wint_t			/* if no counterpart, return ch */
1068 othercase(wint_t ch)
1069 {
1070 	assert(iswalpha(ch));
1071 	if (iswupper(ch))
1072 		return (towlower(ch));
1073 	else if (iswlower(ch))
1074 		return (towupper(ch));
1075 	else			/* peculiar, but could happen */
1076 		return (ch);
1077 }
1078 
1079 /*
1080  * bothcases - emit a dualcase version of a two-case character
1081  *
1082  * Boy, is this implementation ever a kludge...
1083  */
1084 static void
1085 bothcases(struct parse *p, wint_t ch)
1086 {
1087 	const char *oldnext = p->next;
1088 	const char *oldend = p->end;
1089 	char bracket[3 + MB_LEN_MAX];
1090 	size_t n;
1091 	mbstate_t mbs;
1092 
1093 	assert(othercase(ch) != ch);	/* p_bracket() would recurse */
1094 	p->next = bracket;
1095 	(void) memset(&mbs, 0, sizeof (mbs));
1096 	n = wcrtomb(bracket, ch, &mbs);
1097 	assert(n != (size_t)-1);
1098 	bracket[n] = ']';
1099 	bracket[n + 1] = '\0';
1100 	p->end = bracket+n+1;
1101 	p_bracket(p);
1102 	assert(p->next == p->end);
1103 	p->next = oldnext;
1104 	p->end = oldend;
1105 }
1106 
1107 /*
1108  * ordinary - emit an ordinary character
1109  */
1110 static void
1111 ordinary(struct parse *p, wint_t ch)
1112 {
1113 	cset *cs;
1114 
1115 	if ((p->g->cflags&REG_ICASE) && iswalpha(ch) && othercase(ch) != ch)
1116 		bothcases(p, ch);
1117 	else if ((ch & OPDMASK) == ch)
1118 		EMIT(OCHAR, ch);
1119 	else {
1120 		/*
1121 		 * Kludge: character is too big to fit into an OCHAR operand.
1122 		 * Emit a singleton set.
1123 		 */
1124 		if ((cs = allocset(p)) == NULL)
1125 			return;
1126 		CHadd(p, cs, ch);
1127 		EMIT(OANYOF, (int)(cs - p->g->sets));
1128 	}
1129 }
1130 
1131 /*
1132  * nonnewline - emit REG_NEWLINE version of OANY
1133  *
1134  * Boy, is this implementation ever a kludge...
1135  */
1136 static void
1137 nonnewline(struct parse *p)
1138 {
1139 	const char *oldnext = p->next;
1140 	const char *oldend = p->end;
1141 	char bracket[4];
1142 
1143 	p->next = bracket;
1144 	p->end = bracket+3;
1145 	bracket[0] = '^';
1146 	bracket[1] = '\n';
1147 	bracket[2] = ']';
1148 	bracket[3] = '\0';
1149 	p_bracket(p);
1150 	assert(p->next == bracket+3);
1151 	p->next = oldnext;
1152 	p->end = oldend;
1153 }
1154 
1155 /*
1156  * repeat - generate code for a bounded repetition, recursively if needed
1157  */
1158 static void
1159 repeat(struct parse *p,
1160     sopno start,		/* operand from here to end of strip */
1161     int from,			/* repeated from this number */
1162     int to)			/* to this number of times (maybe INFINITY) */
1163 {
1164 	sopno finish = HERE();
1165 #define	N	2
1166 #define	INF	3
1167 #define	REP(f, t)	((f)*8 + (t))
1168 #define	MAP(n)	(((n) <= 1) ? (n) : ((n) == INFINITY) ? INF : N)
1169 	sopno copy;
1170 
1171 	if (p->error != 0)	/* head off possible runaway recursion */
1172 		return;
1173 
1174 	assert(from <= to);
1175 
1176 	switch (REP(MAP(from), MAP(to))) {
1177 	case REP(0, 0):			/* must be user doing this */
1178 		DROP(finish-start);	/* drop the operand */
1179 		break;
1180 	case REP(0, 1):			/* as x{1,1}? */
1181 	case REP(0, N):			/* as x{1,n}? */
1182 	case REP(0, INF):		/* as x{1,}? */
1183 		/* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
1184 		INSERT(OCH_, start);		/* offset is wrong... */
1185 		repeat(p, start+1, 1, to);
1186 		ASTERN(OOR1, start);
1187 		AHEAD(start);			/* ... fix it */
1188 		EMIT(OOR2, 0);
1189 		AHEAD(THERE());
1190 		ASTERN(O_CH, THERETHERE());
1191 		break;
1192 	case REP(1, 1):			/* trivial case */
1193 		/* done */
1194 		break;
1195 	case REP(1, N):			/* as x?x{1,n-1} */
1196 		/* KLUDGE: emit y? as (y|) until subtle bug gets fixed */
1197 		INSERT(OCH_, start);
1198 		ASTERN(OOR1, start);
1199 		AHEAD(start);
1200 		EMIT(OOR2, 0);			/* offset very wrong... */
1201 		AHEAD(THERE());			/* ...so fix it */
1202 		ASTERN(O_CH, THERETHERE());
1203 		copy = dupl(p, start+1, finish+1);
1204 		assert(copy == finish+4);
1205 		repeat(p, copy, 1, to-1);
1206 		break;
1207 	case REP(1, INF):		/* as x+ */
1208 		INSERT(OPLUS_, start);
1209 		ASTERN(O_PLUS, start);
1210 		break;
1211 	case REP(N, N):			/* as xx{m-1,n-1} */
1212 		copy = dupl(p, start, finish);
1213 		repeat(p, copy, from-1, to-1);
1214 		break;
1215 	case REP(N, INF):		/* as xx{n-1,INF} */
1216 		copy = dupl(p, start, finish);
1217 		repeat(p, copy, from-1, to);
1218 		break;
1219 	default:			/* "can't happen" */
1220 		SETERROR(REG_EFATAL);	/* just in case */
1221 		break;
1222 	}
1223 }
1224 
1225 /*
1226  * wgetnext - helper function for WGETNEXT() macro. Gets the next wide
1227  * character from the parse struct, signals a REG_ILLSEQ error if the
1228  * character can't be converted. Returns the number of bytes consumed.
1229  */
1230 static wint_t
1231 wgetnext(struct parse *p)
1232 {
1233 	mbstate_t mbs;
1234 	wchar_t wc;
1235 	size_t n;
1236 
1237 	(void) memset(&mbs, 0, sizeof (mbs));
1238 	n = mbrtowc(&wc, p->next, p->end - p->next, &mbs);
1239 	if (n == (size_t)-1 || n == (size_t)-2) {
1240 		SETERROR(REG_ECHAR);
1241 		return (0);
1242 	}
1243 	if (n == 0)
1244 		n = 1;
1245 	p->next += n;
1246 	return (wc);
1247 }
1248 
1249 /*
1250  * seterr - set an error condition
1251  */
1252 static int			/* useless but makes type checking happy */
1253 seterr(struct parse *p, int e)
1254 {
1255 	if (p->error == 0)	/* keep earliest error condition */
1256 		p->error = e;
1257 	p->next = nuls;		/* try to bring things to a halt */
1258 	p->end = nuls;
1259 	return (0);		/* make the return value well-defined */
1260 }
1261 
1262 /*
1263  * allocset - allocate a set of characters for []
1264  */
1265 static cset *
1266 allocset(struct parse *p)
1267 {
1268 	cset *cs, *ncs;
1269 
1270 	ncs = realloc(p->g->sets, (p->g->ncsets + 1) * sizeof (*ncs));
1271 	if (ncs == NULL) {
1272 		SETERROR(REG_ESPACE);
1273 		return (NULL);
1274 	}
1275 	p->g->sets = ncs;
1276 	cs = &p->g->sets[p->g->ncsets++];
1277 	(void) memset(cs, 0, sizeof (*cs));
1278 
1279 	return (cs);
1280 }
1281 
1282 /*
1283  * freeset - free a now-unused set
1284  */
1285 static void
1286 freeset(struct parse *p, cset *cs)
1287 {
1288 	cset *top = &p->g->sets[p->g->ncsets];
1289 
1290 	free(cs->wides);
1291 	free(cs->ranges);
1292 	free(cs->types);
1293 	(void) memset(cs, 0, sizeof (*cs));
1294 	if (cs == top-1)	/* recover only the easy case */
1295 		p->g->ncsets--;
1296 }
1297 
1298 /*
1299  * singleton - Determine whether a set contains only one character,
1300  * returning it if so, otherwise returning OUT.
1301  */
1302 static wint_t
1303 singleton(struct parse *p, cset *cs)
1304 {
1305 	wint_t i, s, n;
1306 
1307 	/* Exclude the complicated cases we don't want to deal with */
1308 	if (cs->nranges != 0 || cs->ntypes != 0 || cs->icase != 0)
1309 		return (OUT);
1310 
1311 	if (cs->nwides > 1)
1312 		return (OUT);
1313 
1314 	/* Count the number of characters present in the bitmap */
1315 	for (i = n = 0; i < p->nc; i++)
1316 		if (CHIN(p->nc, cs, i)) {
1317 			n++;
1318 			s = i;
1319 		}
1320 
1321 	if (n > 1)
1322 		return (OUT);
1323 
1324 	if (n == 1) {
1325 		if (cs->nwides == 0)
1326 			return (s);
1327 		else
1328 			return (OUT);
1329 	}
1330 	if (cs->nwides == 1)
1331 		return (cs->wides[0]);
1332 
1333 	return (OUT);
1334 }
1335 
1336 /*
1337  * CHadd - add character to character set.
1338  */
1339 static void
1340 CHadd(struct parse *p, cset *cs, wint_t ch)
1341 {
1342 	wint_t nch, *newwides;
1343 	assert(ch >= 0);
1344 	if (ch < p->nc)
1345 		cs->bmp[ch >> 3] |= 1 << (ch & 7);
1346 	else {
1347 		newwides = realloc(cs->wides, (cs->nwides + 1) *
1348 		    sizeof (*cs->wides));
1349 		if (newwides == NULL) {
1350 			SETERROR(REG_ESPACE);
1351 			return;
1352 		}
1353 		cs->wides = newwides;
1354 		cs->wides[cs->nwides++] = ch;
1355 	}
1356 	if (cs->icase) {
1357 		if ((nch = towlower(ch)) < p->nc)
1358 			cs->bmp[nch >> 3] |= 1 << (nch & 7);
1359 		if ((nch = towupper(ch)) < p->nc)
1360 			cs->bmp[nch >> 3] |= 1 << (nch & 7);
1361 	}
1362 }
1363 
1364 /*
1365  * CHaddrange - add all characters in the range [min,max] to a character set.
1366  */
1367 static void
1368 CHaddrange(struct parse *p, cset *cs, wint_t min, wint_t max)
1369 {
1370 	crange *newranges;
1371 
1372 	for (; min < p->nc && min <= max; min++)
1373 		CHadd(p, cs, min);
1374 	if (min >= max)
1375 		return;
1376 	newranges = realloc(cs->ranges, (cs->nranges + 1) *
1377 	    sizeof (*cs->ranges));
1378 	if (newranges == NULL) {
1379 		SETERROR(REG_ESPACE);
1380 		return;
1381 	}
1382 	cs->ranges = newranges;
1383 	cs->ranges[cs->nranges].min = min;
1384 	cs->ranges[cs->nranges].max = max;
1385 	cs->nranges++;
1386 }
1387 
1388 /*
1389  * CHaddtype - add all characters of a certain type to a character set.
1390  */
1391 static void
1392 CHaddtype(struct parse *p, cset *cs, wctype_t wct)
1393 {
1394 	wint_t i;
1395 	wctype_t *newtypes;
1396 
1397 	for (i = 0; i < p->nc; i++)
1398 		if (iswctype(i, wct))
1399 			CHadd(p, cs, i);
1400 	newtypes = realloc(cs->types, (cs->ntypes + 1) *
1401 	    sizeof (*cs->types));
1402 	if (newtypes == NULL) {
1403 		SETERROR(REG_ESPACE);
1404 		return;
1405 	}
1406 	cs->types = newtypes;
1407 	cs->types[cs->ntypes++] = wct;
1408 }
1409 
1410 /*
1411  * dupl - emit a duplicate of a bunch of sops
1412  */
1413 static sopno			/* start of duplicate */
1414 dupl(struct parse *p,
1415     sopno start,		/* from here */
1416     sopno finish)		/* to this less one */
1417 {
1418 	sopno ret = HERE();
1419 	sopno len = finish - start;
1420 
1421 	assert(finish >= start);
1422 	if (len == 0)
1423 		return (ret);
1424 	if (!enlarge(p, p->ssize + len)) /* this many unexpected additions */
1425 		return (ret);
1426 	assert(p->ssize >= p->slen + len);
1427 	(void) memcpy((char *)(p->strip + p->slen),
1428 	    (char *)(p->strip + start), (size_t)len*sizeof (sop));
1429 	p->slen += len;
1430 	return (ret);
1431 }
1432 
1433 /*
1434  * doemit - emit a strip operator
1435  *
1436  * It might seem better to implement this as a macro with a function as
1437  * hard-case backup, but it's just too big and messy unless there are
1438  * some changes to the data structures.  Maybe later.
1439  */
1440 static void
1441 doemit(struct parse *p, sop op, size_t opnd)
1442 {
1443 	/* avoid making error situations worse */
1444 	if (p->error != 0)
1445 		return;
1446 
1447 	/* deal with oversize operands ("can't happen", more or less) */
1448 	assert(opnd < 1<<OPSHIFT);
1449 
1450 	/* deal with undersized strip */
1451 	if (p->slen >= p->ssize)
1452 		if (!enlarge(p, (p->ssize+1) / 2 * 3))	/* +50% */
1453 			return;
1454 
1455 	/* finally, it's all reduced to the easy case */
1456 	p->strip[p->slen++] = SOP(op, opnd);
1457 }
1458 
1459 /*
1460  * doinsert - insert a sop into the strip
1461  */
1462 static void
1463 doinsert(struct parse *p, sop op, size_t opnd, sopno pos)
1464 {
1465 	sopno sn;
1466 	sop s;
1467 	int i;
1468 
1469 	/* avoid making error situations worse */
1470 	if (p->error != 0)
1471 		return;
1472 
1473 	sn = HERE();
1474 	EMIT(op, opnd);		/* do checks, ensure space */
1475 	assert(HERE() == sn+1);
1476 	s = p->strip[sn];
1477 
1478 	/* adjust paren pointers */
1479 	assert(pos > 0);
1480 	for (i = 1; i < NPAREN; i++) {
1481 		if (p->pbegin[i] >= pos) {
1482 			p->pbegin[i]++;
1483 		}
1484 		if (p->pend[i] >= pos) {
1485 			p->pend[i]++;
1486 		}
1487 	}
1488 
1489 	(void) memmove((char *)&p->strip[pos+1], (char *)&p->strip[pos],
1490 	    (HERE()-pos-1)*sizeof (sop));
1491 	p->strip[pos] = s;
1492 }
1493 
1494 /*
1495  * dofwd - complete a forward reference
1496  */
1497 static void
1498 dofwd(struct parse *p, sopno pos, sop value)
1499 {
1500 	/* avoid making error situations worse */
1501 	if (p->error != 0)
1502 		return;
1503 
1504 	assert(value < 1<<OPSHIFT);
1505 	p->strip[pos] = OP(p->strip[pos]) | value;
1506 }
1507 
1508 /*
1509  * enlarge - enlarge the strip
1510  */
1511 static int
1512 enlarge(struct parse *p, sopno size)
1513 {
1514 	sop *sp;
1515 
1516 	if (p->ssize >= size)
1517 		return (1);
1518 
1519 	sp = (sop *)realloc(p->strip, size*sizeof (sop));
1520 	if (sp == NULL) {
1521 		SETERROR(REG_ESPACE);
1522 		return (0);
1523 	}
1524 	p->strip = sp;
1525 	p->ssize = size;
1526 	return (1);
1527 }
1528 
1529 /*
1530  * stripsnug - compact the strip
1531  */
1532 static void
1533 stripsnug(struct parse *p, struct re_guts *g)
1534 {
1535 	g->nstates = p->slen;
1536 	g->strip = (sop *)realloc((char *)p->strip, p->slen * sizeof (sop));
1537 	if (g->strip == NULL) {
1538 		SETERROR(REG_ESPACE);
1539 		g->strip = p->strip;
1540 	}
1541 }
1542 
1543 /*
1544  * findmust - fill in must and mlen with longest mandatory literal string
1545  *
1546  * This algorithm could do fancy things like analyzing the operands of |
1547  * for common subsequences.  Someday.  This code is simple and finds most
1548  * of the interesting cases.
1549  *
1550  * Note that must and mlen got initialized during setup.
1551  */
1552 static void
1553 findmust(struct parse *p, struct re_guts *g)
1554 {
1555 	sop *scan;
1556 	sop *start = NULL;
1557 	sop *newstart = NULL;
1558 	sopno newlen;
1559 	sop s;
1560 	char *cp;
1561 	int offset;
1562 	char buf[MB_LEN_MAX];
1563 	size_t clen;
1564 	mbstate_t mbs;
1565 	locale_t loc = __curlocale();
1566 
1567 	/* avoid making error situations worse */
1568 	if (p->error != 0)
1569 		return;
1570 
1571 	/*
1572 	 * It's not generally safe to do a ``char'' substring search on
1573 	 * multibyte character strings, but it's safe for at least
1574 	 * UTF-8 (see RFC 3629).
1575 	 */
1576 	if (g->mb_cur_max > 1 &&
1577 	    strcmp(loc->runelocale->__encoding, "UTF-8") != 0)
1578 		return;
1579 
1580 	/* find the longest OCHAR sequence in strip */
1581 	newlen = 0;
1582 	offset = 0;
1583 	g->moffset = 0;
1584 	scan = g->strip + 1;
1585 	do {
1586 		s = *scan++;
1587 		switch (OP(s)) {
1588 		case OCHAR:		/* sequence member */
1589 			if (newlen == 0) {		/* new sequence */
1590 				(void) memset(&mbs, 0, sizeof (mbs));
1591 				newstart = scan - 1;
1592 			}
1593 			clen = wcrtomb(buf, OPND(s), &mbs);
1594 			if (clen == (size_t)-1)
1595 				goto toohard;
1596 			newlen += clen;
1597 			break;
1598 		case OPLUS_:		/* things that don't break one */
1599 		case OLPAREN:
1600 		case ORPAREN:
1601 			break;
1602 		case OQUEST_:		/* things that must be skipped */
1603 		case OCH_:
1604 			offset = altoffset(scan, offset);
1605 			scan--;
1606 			do {
1607 				scan += OPND(s);
1608 				s = *scan;
1609 				/* assert() interferes w debug printouts */
1610 				if (OP(s) != (sop)O_QUEST &&
1611 				    OP(s) != (sop)O_CH && OP(s) != (sop)OOR2) {
1612 					g->iflags |= BAD;
1613 					return;
1614 				}
1615 			} while (OP(s) != (sop)O_QUEST && OP(s) != (sop)O_CH);
1616 			/* FALLTHROUGH */
1617 		case OBOW:		/* things that break a sequence */
1618 		case OEOW:
1619 		case OBOL:
1620 		case OEOL:
1621 		case O_QUEST:
1622 		case O_CH:
1623 		case OEND:
1624 			if (newlen > (sopno)g->mlen) {		/* ends one */
1625 				start = newstart;
1626 				g->mlen = newlen;
1627 				if (offset > -1) {
1628 					g->moffset += offset;
1629 					offset = newlen;
1630 				} else
1631 					g->moffset = offset;
1632 			} else {
1633 				if (offset > -1)
1634 					offset += newlen;
1635 			}
1636 			newlen = 0;
1637 			break;
1638 		case OANY:
1639 			if (newlen > (sopno)g->mlen) {		/* ends one */
1640 				start = newstart;
1641 				g->mlen = newlen;
1642 				if (offset > -1) {
1643 					g->moffset += offset;
1644 					offset = newlen;
1645 				} else
1646 					g->moffset = offset;
1647 			} else {
1648 				if (offset > -1)
1649 					offset += newlen;
1650 			}
1651 			if (offset > -1)
1652 				offset++;
1653 			newlen = 0;
1654 			break;
1655 		case OANYOF:		/* may or may not invalidate offset */
1656 			/* First, everything as OANY */
1657 			if (newlen > (sopno)g->mlen) {		/* ends one */
1658 				start = newstart;
1659 				g->mlen = newlen;
1660 				if (offset > -1) {
1661 					g->moffset += offset;
1662 					offset = newlen;
1663 				} else
1664 					g->moffset = offset;
1665 			} else {
1666 				if (offset > -1)
1667 					offset += newlen;
1668 			}
1669 			if (offset > -1)
1670 				offset++;
1671 			newlen = 0;
1672 			break;
1673 		toohard:
1674 		default:
1675 			/*
1676 			 * Anything here makes it impossible or too hard
1677 			 * to calculate the offset -- so we give up;
1678 			 * save the last known good offset, in case the
1679 			 * must sequence doesn't occur later.
1680 			 */
1681 			if (newlen > (sopno)g->mlen) {		/* ends one */
1682 				start = newstart;
1683 				g->mlen = newlen;
1684 				if (offset > -1)
1685 					g->moffset += offset;
1686 				else
1687 					g->moffset = offset;
1688 			}
1689 			offset = -1;
1690 			newlen = 0;
1691 			break;
1692 		}
1693 	} while (OP(s) != OEND);
1694 
1695 	if (g->mlen == 0) {		/* there isn't one */
1696 		g->moffset = -1;
1697 		return;
1698 	}
1699 
1700 	/* turn it into a character string */
1701 	g->must = malloc((size_t)g->mlen + 1);
1702 	if (g->must == NULL) {		/* argh; just forget it */
1703 		g->mlen = 0;
1704 		g->moffset = -1;
1705 		return;
1706 	}
1707 	cp = g->must;
1708 	scan = start;
1709 	(void) memset(&mbs, 0, sizeof (mbs));
1710 	while (cp < g->must + g->mlen) {
1711 		while (OP(s = *scan++) != OCHAR)
1712 			continue;
1713 		clen = wcrtomb(cp, OPND(s), &mbs);
1714 		assert(clen != (size_t)-1);
1715 		cp += clen;
1716 	}
1717 	assert(cp == g->must + g->mlen);
1718 	*cp++ = '\0';		/* just on general principles */
1719 }
1720 
1721 /*
1722  * altoffset - choose biggest offset among multiple choices
1723  *
1724  * Compute, recursively if necessary, the largest offset among multiple
1725  * re paths.
1726  */
1727 static int
1728 altoffset(sop *scan, int offset)
1729 {
1730 	int largest;
1731 	int try;
1732 	sop s;
1733 
1734 	/* If we gave up already on offsets, return */
1735 	if (offset == -1)
1736 		return (-1);
1737 
1738 	largest = 0;
1739 	try = 0;
1740 	s = *scan++;
1741 	while (OP(s) != (sop)O_QUEST && OP(s) != (sop)O_CH) {
1742 		switch (OP(s)) {
1743 		case OOR1:
1744 			if (try > largest)
1745 				largest = try;
1746 			try = 0;
1747 			break;
1748 		case OQUEST_:
1749 		case OCH_:
1750 			try = altoffset(scan, try);
1751 			if (try == -1)
1752 				return (-1);
1753 			scan--;
1754 			do {
1755 				scan += OPND(s);
1756 				s = *scan;
1757 				if (OP(s) != (sop)O_QUEST &&
1758 				    OP(s) != (sop)O_CH && OP(s) != (sop)OOR2)
1759 					return (-1);
1760 			} while (OP(s) != (sop)O_QUEST && OP(s) != (sop)O_CH);
1761 			/*
1762 			 * We must skip to the next position, or we'll
1763 			 * leave altoffset() too early.
1764 			 */
1765 			scan++;
1766 			break;
1767 		case OANYOF:
1768 		case OCHAR:
1769 		case OANY:
1770 			try++;
1771 			/*FALLTHRU*/
1772 		case OBOW:
1773 		case OEOW:
1774 		case OLPAREN:
1775 		case ORPAREN:
1776 		case OOR2:
1777 			break;
1778 		default:
1779 			try = -1;
1780 			break;
1781 		}
1782 		if (try == -1)
1783 			return (-1);
1784 		s = *scan++;
1785 	}
1786 
1787 	if (try > largest)
1788 		largest = try;
1789 
1790 	return (largest+offset);
1791 }
1792 
1793 /*
1794  * computejumps - compute char jumps for BM scan
1795  *
1796  * This algorithm assumes g->must exists and is has size greater than
1797  * zero. It's based on the algorithm found on Computer Algorithms by
1798  * Sara Baase.
1799  *
1800  * A char jump is the number of characters one needs to jump based on
1801  * the value of the character from the text that was mismatched.
1802  */
1803 static void
1804 computejumps(struct parse *p, struct re_guts *g)
1805 {
1806 	int ch;
1807 	int mindex;
1808 
1809 	/* Avoid making errors worse */
1810 	if (p->error != 0)
1811 		return;
1812 
1813 	g->charjump = (int *)malloc((NC_MAX + 1) * sizeof (int));
1814 	if (g->charjump == NULL)	/* Not a fatal error */
1815 		return;
1816 	/* Adjust for signed chars, if necessary */
1817 	g->charjump = &g->charjump[-(CHAR_MIN)];
1818 
1819 	/*
1820 	 * If the character does not exist in the pattern, the jump
1821 	 * is equal to the number of characters in the pattern.
1822 	 */
1823 	for (ch = CHAR_MIN; ch < (CHAR_MAX + 1); ch++)
1824 		g->charjump[ch] = g->mlen;
1825 
1826 	/*
1827 	 * If the character does exist, compute the jump that would
1828 	 * take us to the last character in the pattern equal to it
1829 	 * (notice that we match right to left, so that last character
1830 	 * is the first one that would be matched).
1831 	 */
1832 	for (mindex = 0; mindex < g->mlen; mindex++)
1833 		g->charjump[(int)g->must[mindex]] = g->mlen - mindex - 1;
1834 }
1835 
1836 /*
1837  * computematchjumps - compute match jumps for BM scan
1838  *
1839  * This algorithm assumes g->must exists and is has size greater than
1840  * zero. It's based on the algorithm found on Computer Algorithms by
1841  * Sara Baase.
1842  *
1843  * A match jump is the number of characters one needs to advance based
1844  * on the already-matched suffix.
1845  * Notice that all values here are minus (g->mlen-1), because of the way
1846  * the search algorithm works.
1847  */
1848 static void
1849 computematchjumps(struct parse *p, struct re_guts *g)
1850 {
1851 	int mindex;		/* General "must" iterator */
1852 	int suffix;		/* Keeps track of matching suffix */
1853 	int ssuffix;		/* Keeps track of suffixes' suffix */
1854 	int *pmatches;
1855 				/*
1856 				 * pmatches[k] points to the next i
1857 				 * such that i+1...mlen is a substring
1858 				 * of k+1...k+mlen-i-1
1859 				 */
1860 
1861 	/* calm static analyzer, see comment above */
1862 	if (g->mlen < 1)
1863 		return;
1864 
1865 	/* Avoid making errors worse */
1866 	if (p->error != 0)
1867 		return;
1868 
1869 	pmatches = (int *)malloc(g->mlen * sizeof (unsigned int));
1870 	if (pmatches == NULL) {
1871 		g->matchjump = NULL;
1872 		return;
1873 	}
1874 
1875 	g->matchjump = (int *)malloc(g->mlen * sizeof (unsigned int));
1876 	if (g->matchjump == NULL) {	/* Not a fatal error */
1877 		free(pmatches);
1878 		return;
1879 	}
1880 
1881 	/* Set maximum possible jump for each character in the pattern */
1882 	for (mindex = 0; mindex < g->mlen; mindex++)
1883 		g->matchjump[mindex] = 2*g->mlen - mindex - 1;
1884 
1885 	/* Compute pmatches[] */
1886 	for (mindex = g->mlen - 1, suffix = g->mlen; mindex >= 0;
1887 	    mindex--, suffix--) {
1888 		pmatches[mindex] = suffix;
1889 
1890 		/*
1891 		 * If a mismatch is found, interrupting the substring,
1892 		 * compute the matchjump for that position. If no
1893 		 * mismatch is found, then a text substring mismatched
1894 		 * against the suffix will also mismatch against the
1895 		 * substring.
1896 		 */
1897 		while (suffix < g->mlen && g->must[mindex] != g->must[suffix]) {
1898 			g->matchjump[suffix] = MIN(g->matchjump[suffix],
1899 			    g->mlen - mindex - 1);
1900 			suffix = pmatches[suffix];
1901 		}
1902 	}
1903 
1904 	/*
1905 	 * Compute the matchjump up to the last substring found to jump
1906 	 * to the beginning of the largest must pattern prefix matching
1907 	 * it's own suffix.
1908 	 */
1909 	for (mindex = 0; mindex <= suffix; mindex++)
1910 		g->matchjump[mindex] = MIN(g->matchjump[mindex],
1911 		    g->mlen + suffix - mindex);
1912 
1913 	ssuffix = pmatches[suffix];
1914 	while (suffix < g->mlen) {
1915 		while (suffix <= ssuffix && suffix < g->mlen) {
1916 			g->matchjump[suffix] = MIN(g->matchjump[suffix],
1917 			    g->mlen + ssuffix - suffix);
1918 			suffix++;
1919 		}
1920 		if (suffix < g->mlen)
1921 			ssuffix = pmatches[ssuffix];
1922 	}
1923 
1924 	free(pmatches);
1925 }
1926 
1927 /*
1928  * pluscount - count + nesting
1929  */
1930 static sopno			/* nesting depth */
1931 pluscount(struct parse *p, struct re_guts *g)
1932 {
1933 	sop *scan;
1934 	sop s;
1935 	sopno plusnest = 0;
1936 	sopno maxnest = 0;
1937 
1938 	if (p->error != 0)
1939 		return (0);	/* there may not be an OEND */
1940 
1941 	scan = g->strip + 1;
1942 	do {
1943 		s = *scan++;
1944 		switch (OP(s)) {
1945 		case OPLUS_:
1946 			plusnest++;
1947 			break;
1948 		case O_PLUS:
1949 			if (plusnest > maxnest)
1950 				maxnest = plusnest;
1951 			plusnest--;
1952 			break;
1953 		}
1954 	} while (OP(s) != OEND);
1955 	if (plusnest != 0)
1956 		g->iflags |= BAD;
1957 	return (maxnest);
1958 }
1959