00001 /* 00002 * the outer shell of regexec() 00003 * 00004 * This file includes engine.c *twice*, after muchos fiddling with the 00005 * macros that code uses. This lets the same code operate on two different 00006 * representations for state sets. 00007 */ 00008 #include <my_global.h> 00009 #include <m_string.h> 00010 #include <m_ctype.h> 00011 #ifdef __WIN__ 00012 #include <limits.h> 00013 #endif 00014 #include "my_regex.h" 00015 #include "utils.h" 00016 #include "regex2.h" 00017 00018 static int nope = 0; /* for use in asserts; shuts lint up */ 00019 00020 /* macros for manipulating states, small version */ 00021 #define states long 00022 #define states1 long /* for later use in regexec() decision. Ensure Win64 definition is correct.*/ 00023 #define CLEAR(v) ((v) = 0) 00024 #define SET0(v, n) ((v) &= ~((states) 1 << (n))) 00025 #define SET1(v, n) ((v) |= (states) 1 << (n)) 00026 #define ISSET(v, n) ((v) & ((states) 1 << (n))) 00027 #define ASSIGN(d, s) ((d) = (s)) 00028 #define EQ(a, b) ((a) == (b)) 00029 #define STATEVARS int dummy /* dummy version */ 00030 #define STATESETUP(m, n) /* nothing */ 00031 #define STATETEARDOWN(m) /* nothing */ 00032 #define SETUP(v) ((v) = 0) 00033 #define onestate long /* Changed from int by Monty */ 00034 #define INIT(o, n) ((o) = (unsigned states)1 << (n)) 00035 #define INC(o) ((o) <<= 1) 00036 #define ISSTATEIN(v, o) ((v) & (o)) 00037 /* some abbreviations; note that some of these know variable names! */ 00038 /* do "if I'm here, I can also be there" etc without branches */ 00039 #define FWD(dst, src, n) ((dst) |= ((unsigned states)(src)&(here)) << (n)) 00040 #define BACK(dst, src, n) ((dst) |= ((unsigned states)(src)&(here)) >> (n)) 00041 #define ISSETBACK(v, n) ((v) & ((unsigned states)here >> (n))) 00042 /* function names */ 00043 #define SNAMES /* engine.c looks after details */ 00044 00045 #include "engine.c" 00046 00047 /* now undo things */ 00048 #undef states 00049 #undef CLEAR 00050 #undef SET0 00051 #undef SET1 00052 #undef ISSET 00053 #undef ASSIGN 00054 #undef EQ 00055 #undef STATEVARS 00056 #undef STATESETUP 00057 #undef STATETEARDOWN 00058 #undef SETUP 00059 #undef onestate 00060 #undef INIT 00061 #undef INC 00062 #undef ISSTATEIN 00063 #undef FWD 00064 #undef BACK 00065 #undef ISSETBACK 00066 #undef SNAMES 00067 00068 /* macros for manipulating states, large version */ 00069 #define states char * 00070 #define CLEAR(v) memset(v, 0, m->g->nstates) 00071 #define SET0(v, n) ((v)[n] = 0) 00072 #define SET1(v, n) ((v)[n] = 1) 00073 #define ISSET(v, n) ((v)[n]) 00074 #define ASSIGN(d, s) memcpy(d, s, m->g->nstates) 00075 #define EQ(a, b) (memcmp(a, b, m->g->nstates) == 0) 00076 #define STATEVARS int vn; char *space 00077 #define STATESETUP(m, nv) { (m)->space = malloc((nv)*(m)->g->nstates); \ 00078 if ((m)->space == NULL) return(REG_ESPACE); \ 00079 (m)->vn = 0; } 00080 #define STATETEARDOWN(m) { free((m)->space); } 00081 #define SETUP(v) ((v) = &m->space[m->vn++ * m->g->nstates]) 00082 #define onestate int 00083 #define INIT(o, n) ((o) = (n)) 00084 #define INC(o) ((o)++) 00085 #define ISSTATEIN(v, o) ((v)[o]) 00086 /* some abbreviations; note that some of these know variable names! */ 00087 /* do "if I'm here, I can also be there" etc without branches */ 00088 #define FWD(dst, src, n) ((dst)[here+(n)] |= (src)[here]) 00089 #define BACK(dst, src, n) ((dst)[here-(n)] |= (src)[here]) 00090 #define ISSETBACK(v, n) ((v)[here - (n)]) 00091 /* function names */ 00092 #define LNAMES /* flag */ 00093 00094 #include "engine.c" 00095 00096 /* 00097 - regexec - interface for matching 00098 = extern int regexec(const regex_t *, const char *, size_t, \ 00099 = regmatch_t [], int); 00100 = #define REG_NOTBOL 00001 00101 = #define REG_NOTEOL 00002 00102 = #define REG_STARTEND 00004 00103 = #define REG_TRACE 00400 // tracing of execution 00104 = #define REG_LARGE 01000 // force large representation 00105 = #define REG_BACKR 02000 // force use of backref code 00106 * 00107 * We put this here so we can exploit knowledge of the state representation 00108 * when choosing which matcher to call. Also, by this point the matchers 00109 * have been prototyped. 00110 */ 00111 int /* 0 success, REG_NOMATCH failure */ 00112 my_regexec(preg, str, nmatch, pmatch, eflags) 00113 const my_regex_t *preg; 00114 const char *str; 00115 size_t nmatch; 00116 my_regmatch_t pmatch[]; 00117 int eflags; 00118 { 00119 register struct re_guts *g = preg->re_g; 00120 #ifdef REDEBUG 00121 # define GOODFLAGS(f) (f) 00122 #else 00123 # define GOODFLAGS(f) ((f)&(REG_NOTBOL|REG_NOTEOL|REG_STARTEND)) 00124 #endif 00125 00126 if (preg->re_magic != MAGIC1 || g->magic != MAGIC2) 00127 return(REG_BADPAT); 00128 assert(!(g->iflags&BAD)); 00129 if (g->iflags&BAD) /* backstop for no-debug case */ 00130 return(REG_BADPAT); 00131 eflags = GOODFLAGS(eflags); 00132 00133 if ((size_t) g->nstates <= CHAR_BIT*sizeof(states1) && 00134 !(eflags®_LARGE)) 00135 return(smatcher(preg->charset, g, (char *)str, nmatch, pmatch, eflags)); 00136 else 00137 return(lmatcher(preg->charset, g, (char *)str, nmatch, pmatch, eflags)); 00138 }
1.4.7

