xref: /csrg-svn/lib/libc/regex/regexec.c (revision 56355)
1 /*-
2  * Copyright (c) 1992 Henry Spencer.
3  * Copyright (c) 1992 The Regents of the University of California.
4  * All rights reserved.
5  *
6  * This code is derived from software contributed to Berkeley by
7  * Henry Spencer of the University of Toronto.
8  *
9  * %sccs.include.redist.c%
10  *
11  *	@(#)regexec.c	5.2 (Berkeley) 09/30/92
12  */
13 
14 #if defined(LIBC_SCCS) && !defined(lint)
15 static char sccsid[] = "@(#)regexec.c	5.2 (Berkeley) 09/30/92";
16 #endif /* LIBC_SCCS and not lint */
17 
18 /*
19  * the outer shell of regexec()
20  *
21  * This file includes engine.c *twice*, after muchos fiddling with the
22  * macros that code uses.  This lets the same code operate on two different
23  * representations for state sets.
24  */
25 #include <sys/types.h>
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <limits.h>
30 #include <ctype.h>
31 #include <regex.h>
32 
33 #include "utils.h"
34 #include "regex2.h"
35 
36 /* macros for manipulating states, small version */
37 #define	states	long
38 #define	states1	states		/* for later use in regexec() decision */
39 #define	CLEAR(v)	((v) = 0)
40 #define	SET0(v, n)	((v) &= ~(1 << (n)))
41 #define	SET1(v, n)	((v) |= 1 << (n))
42 #define	ISSET(v, n)	((v) & (1 << (n)))
43 #define	ASSIGN(d, s)	((d) = (s))
44 #define	EQ(a, b)	((a) == (b))
45 #define	STATEVARS	int dummy	/* dummy version */
46 #define	STATESETUP(m, n)	/* nothing */
47 #define	STATETEARDOWN(m)	/* nothing */
48 #define	SETUP(v)	((v) = 0)
49 #define	onestate	int
50 #define	INIT(o, n)	((o) = 1 << (n))
51 #define	INC(o)	((o) <<= 1)
52 #define	ISSTATEIN(v, o)	((v) & (o))
53 /* some abbreviations; note that some of these know variable names! */
54 /* do "if I'm here, I can also be there" etc without branches */
55 #define	FWD(dst, src, n)	((dst) |= ((src)&(here)) << (n))
56 #define	BACK(dst, src, n)	((dst) |= ((src)&(here)) >> (n))
57 #define	ISSETBACK(v, n)	((v) & (here >> (n)))
58 /* function names */
59 #define SNAMES			/* engine.c looks after details */
60 
61 #include "engine.c"
62 
63 /* now undo things */
64 #undef	states
65 #undef	CLEAR
66 #undef	SET0
67 #undef	SET1
68 #undef	ISSET
69 #undef	ASSIGN
70 #undef	EQ
71 #undef	STATEVARS
72 #undef	STATESETUP
73 #undef	STATETEARDOWN
74 #undef	SETUP
75 #undef	onestate
76 #undef	INIT
77 #undef	INC
78 #undef	ISSTATEIN
79 #undef	FWD
80 #undef	BACK
81 #undef	ISSETBACK
82 #undef	SNAMES
83 
84 /* macros for manipulating states, large version */
85 #define	states	char *
86 #define	CLEAR(v)	memset(v, 0, m->g->nstates)
87 #define	SET0(v, n)	((v)[n] = 0)
88 #define	SET1(v, n)	((v)[n] = 1)
89 #define	ISSET(v, n)	((v)[n])
90 #define	ASSIGN(d, s)	memcpy(d, s, m->g->nstates)
91 #define	EQ(a, b)	(memcmp(a, b, m->g->nstates) == 0)
92 #define	STATEVARS	int vn; char *space
93 #define	STATESETUP(m, nv)	{ (m)->space = malloc((nv)*(m)->g->nstates); \
94 				if ((m)->space == NULL) return(REG_ESPACE); \
95 				(m)->vn = 0; }
96 #define	STATETEARDOWN(m)	{ free((m)->space); }
97 #define	SETUP(v)	((v) = &m->space[m->vn++ * m->g->nstates])
98 #define	onestate	int
99 #define	INIT(o, n)	((o) = (n))
100 #define	INC(o)	((o)++)
101 #define	ISSTATEIN(v, o)	((v)[o])
102 /* some abbreviations; note that some of these know variable names! */
103 /* do "if I'm here, I can also be there" etc without branches */
104 #define	FWD(dst, src, n)	((dst)[here+(n)] |= (src)[here])
105 #define	BACK(dst, src, n)	((dst)[here-(n)] |= (src)[here])
106 #define	ISSETBACK(v, n)	((v)[here - (n)])
107 /* function names */
108 #define	LNAMES			/* flag */
109 
110 #include "engine.c"
111 
112 /*
113  - regexec - interface for matching
114  = extern int regexec(const regex_t *preg, const char *string, size_t nmatch, \
115  =					regmatch_t pmatch[], int eflags);
116  = #define	REG_NOTBOL	00001
117  = #define	REG_NOTEOL	00002
118  = #define	REG_STARTEND	00004
119  = #define	REG_TRACE	00400
120  = #define	REG_LARGE	01000
121  = #define	REG_BACKR	02000
122  *
123  * We put this here so we can exploit knowledge of the state representation
124  * when choosing which matcher to call.  Also, by this point the matchers
125  * have been prototyped.
126  */
127 int				/* 0 success, REG_NOMATCH failure */
128 regexec(preg, string, nmatch, pmatch, eflags)
129 const regex_t *preg;
130 const char *string;
131 size_t nmatch;
132 regmatch_t pmatch[];
133 int eflags;
134 {
135 	register struct re_guts *g = preg->re_g;
136 #ifdef REDEBUG
137 #	define	GOODFLAGS(f)	(f)
138 #else
139 #	define	GOODFLAGS(f)	((f)&(REG_NOTBOL|REG_NOTEOL|REG_STARTEND))
140 #endif
141 
142 	if (preg->re_magic != MAGIC1 || g->magic != MAGIC2)
143 		return(REG_BADPAT);
144 	assert(!(g->iflags&BAD));
145 	if (g->iflags&BAD)		/* backstop for no-debug case */
146 		return(REG_BADPAT);
147 	eflags = GOODFLAGS(eflags);	/* xxx should we complain? */
148 
149 	if (g->nstates <= CHAR_BIT*sizeof(states1) && !(eflags&REG_LARGE))
150 		return(smatcher(g, (uchar *)string, nmatch, pmatch, eflags));
151 	else
152 		return(lmatcher(g, (uchar *)string, nmatch, pmatch, eflags));
153 }
154