1 /**************************************************************************
3 * Copyright 2013-2014 RAD Game Tools and Valve Software
4 * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 **************************************************************************/
27 #ifndef D_FILE_OFFSET_BITS
28 #define _FILE_OFFSET_BITS 64
30 #ifndef _LARGEFILE64_SOURCE
31 #define _LARGEFILE64_SOURCE 1
35 * the outer shell of vogl_regexec()
37 * This file includes engine.c *twice*, after muchos fiddling with the
38 * macros that code uses. This lets the same code operate on two different
39 * representations for state sets.
41 #include <sys/types.h>
53 // static int vogl_nope = 0; /* for use in asserts; shuts lint up */
55 /* macros for manipulating states, small version */
56 #define states unsigned
57 #define states1 unsigned /* for later use in vogl_regexec() decision */
58 #define CLEAR(v) ((v) = 0)
59 #define SET0(v, n) ((v) &= ~((unsigned)1 << (n)))
60 #define SET1(v, n) ((v) |= (unsigned)1 << (n))
61 #define ISSET(v, n) ((v) & ((unsigned)1 << (n)))
62 #define ASSIGN(d, s) ((d) = (s))
63 #define EQ(a, b) ((a) == (b))
64 #define STATEVARS int dummy /* dummy version */
65 #define STATESETUP(m, n) /* nothing */
66 #define STATETEARDOWN(m) /* nothing */
67 #define SETUP(v) ((v) = 0)
68 #define onestate unsigned
69 #define INIT(o, n) ((o) = (unsigned)1 << (n))
70 #define INC(o) ((o) <<= 1)
71 #define ISSTATEIN(v, o) ((v) & (o))
72 /* some abbreviations; note that some of these know variable names! */
73 /* do "if I'm here, I can also be there" etc without branches */
74 #define FWD(dst, src, n) ((dst) |= ((unsigned)(src) & (here)) << (n))
75 #define BACK(dst, src, n) ((dst) |= ((unsigned)(src) & (here)) >> (n))
76 #define ISSETBACK(v, n) ((v) & ((unsigned)here >> (n)))
78 #define SNAMES /* engine.c looks after details */
103 /* macros for manipulating states, large version */
104 #define states char *
105 #define CLEAR(v) memset(v, 0, m->g->nstates)
106 #define SET0(v, n) ((v)[n] = 0)
107 #define SET1(v, n) ((v)[n] = 1)
108 #define ISSET(v, n) ((v)[n])
109 #define ASSIGN(d, s) memcpy(d, s, m->g->nstates)
110 #define EQ(a, b) (memcmp(a, b, m->g->nstates) == 0)
114 #define STATESETUP(m, nv) \
116 (m)->space = regex_malloc((nv) * (m)->g->nstates); \
117 if ((m)->space == NULL) \
118 return (REG_ESPACE); \
121 #define STATETEARDOWN(m) \
123 regex_free((m)->space); \
125 #define SETUP(v) ((v) = &m->space[m->vn++ * m->g->nstates])
127 #define INIT(o, n) ((o) = (n))
128 #define INC(o) ((o)++)
129 #define ISSTATEIN(v, o) ((v)[o])
130 /* some abbreviations; note that some of these know variable names! */
131 /* do "if I'm here, I can also be there" etc without branches */
132 #define FWD(dst, src, n) ((dst)[here + (n)] |= (src)[here])
133 #define BACK(dst, src, n) ((dst)[here - (n)] |= (src)[here])
134 #define ISSETBACK(v, n) ((v)[here - (n)])
136 #define LNAMES /* flag */
140 #define CASSERT(predicate, file) _impl_CASSERT_LINE(predicate, __LINE__, file)
142 #define _impl_PASTE(a, b) a##b
143 #define _impl_CASSERT_LINE(predicate, line, file) \
144 typedef char _impl_PASTE(assertion_failed_##file##_, line)[2 * !!(predicate) - 1];
147 - vogl_regexec - interface for matching
148 = extern int vogl_regexec(const regex_t *, const char *, size_t, \
149 = regmatch_t [], int);
150 = #define REG_NOTBOL 00001
151 = #define REG_NOTEOL 00002
152 = #define REG_STARTEND 00004
153 = #define REG_TRACE 00400 // tracing of execution
154 = #define REG_LARGE 01000 // force large representation
155 = #define REG_BACKR 02000 // force use of backref code
157 * We put this here so we can exploit knowledge of the state representation
158 * when choosing which matcher to call. Also, by this point the matchers
159 * have been prototyped.
161 int /* 0 success, REG_NOMATCH failure */
162 vogl_regexec(preg, string, nmatch, pmatch, eflags)
169 register struct re_guts *g = preg->re_g;
171 #define GOODFLAGS(f) (f)
173 #define GOODFLAGS(f) ((f) & (REG_NOTBOL | REG_NOTEOL | REG_STARTEND))
176 // Make sure off_t is ALWAYS 64-bits, because that's how the C++ code that calls this gets compiled.
177 CASSERT(sizeof(off_t) == sizeof(unsigned long long), regexec_c);
179 if (preg->re_magic != MAGIC1 || g->magic != MAGIC2)
181 assert(!(g->iflags & BAD));
182 if (g->iflags & BAD) /* backstop for no-debug case */
184 eflags = GOODFLAGS(eflags);
186 if (g->nstates <= (long)(CHAR_BIT * sizeof(states1)) && !(eflags & REG_LARGE))
187 return (smatcher(g, (char *)string, nmatch, pmatch, eflags));
189 return (lmatcher(g, (char *)string, nmatch, pmatch, eflags));