version 1.10, 2001/09/08 00:12:40 |
version 1.11, 2002/12/19 21:24:28 |
|
|
fa *fatab[NFA]; |
fa *fatab[NFA]; |
int nfatab = 0; /* entries in fatab */ |
int nfatab = 0; /* entries in fatab */ |
|
|
fa *makedfa(char *s, int anchor) /* returns dfa for reg expr s */ |
fa *makedfa(const char *s, int anchor) /* returns dfa for reg expr s */ |
{ |
{ |
int i, use, nuse; |
int i, use, nuse; |
fa *pfa; |
fa *pfa; |
|
|
return mkdfa(s, anchor); |
return mkdfa(s, anchor); |
for (i = 0; i < nfatab; i++) /* is it there already? */ |
for (i = 0; i < nfatab; i++) /* is it there already? */ |
if (fatab[i]->anchor == anchor |
if (fatab[i]->anchor == anchor |
&& strcmp(fatab[i]->restr, s) == 0) { |
&& strcmp((const char *) fatab[i]->restr, s) == 0) { |
fatab[i]->use = now++; |
fatab[i]->use = now++; |
return fatab[i]; |
return fatab[i]; |
} |
} |
|
|
return pfa; |
return pfa; |
} |
} |
|
|
fa *mkdfa(char *s, int anchor) /* does the real work of making a dfa */ |
fa *mkdfa(const char *s, int anchor) /* does the real work of making a dfa */ |
/* anchor = 1 for anchored matches, else 0 */ |
/* anchor = 1 for anchored matches, else 0 */ |
{ |
{ |
Node *p, *p1; |
Node *p, *p1; |
|
|
return c; |
return c; |
} |
} |
|
|
char *cclenter(char *argp) /* add a character class */ |
char *cclenter(const char *argp) /* add a character class */ |
{ |
{ |
int i, c, c2; |
int i, c, c2; |
uschar *p = (uschar *) argp; |
uschar *p = (uschar *) argp; |
|
|
return (char *) tostring((char *) buf); |
return (char *) tostring((char *) buf); |
} |
} |
|
|
void overflo(char *s) |
void overflo(const char *s) |
{ |
{ |
FATAL("regular expression too big: %.30s...", s); |
FATAL("regular expression too big: %.30s...", s); |
} |
} |
|
|
} |
} |
} |
} |
|
|
int member(int c, char *sarg) /* is c in s? */ |
int member(int c, const char *sarg) /* is c in s? */ |
{ |
{ |
uschar *s = (uschar *) sarg; |
uschar *s = (uschar *) sarg; |
|
|
|
|
return(0); |
return(0); |
} |
} |
|
|
int match(fa *f, char *p0) /* shortest match ? */ |
int match(fa *f, const char *p0) /* shortest match ? */ |
{ |
{ |
int s, ns; |
int s, ns; |
uschar *p = (uschar *) p0; |
uschar *p = (uschar *) p0; |
|
|
return(0); |
return(0); |
} |
} |
|
|
int pmatch(fa *f, char *p0) /* longest match, for sub */ |
int pmatch(fa *f, const char *p0) /* longest match, for sub */ |
{ |
{ |
int s, ns; |
int s, ns; |
uschar *p = (uschar *) p0; |
uschar *p = (uschar *) p0; |
|
|
return (0); |
return (0); |
} |
} |
|
|
int nematch(fa *f, char *p0) /* non-empty match, for sub */ |
int nematch(fa *f, const char *p0) /* non-empty match, for sub */ |
{ |
{ |
int s, ns; |
int s, ns; |
uschar *p = (uschar *) p0; |
uschar *p = (uschar *) p0; |
|
|
return (0); |
return (0); |
} |
} |
|
|
Node *reparse(char *p) /* parses regular expression pointed to by p */ |
Node *reparse(const char *p) /* parses regular expression pointed to by p */ |
{ /* uses relex() to scan regular expression */ |
{ /* uses relex() to scan regular expression */ |
Node *np; |
Node *np; |
|
|
dprintf( ("reparse <%s>\n", p) ); |
dprintf( ("reparse <%s>\n", p) ); |
lastre = prestr = (uschar *) p; /* prestr points to string to be parsed */ |
lastre = prestr = (uschar *) p; /* prestr points to string to be parsed */ |
rtok = relex(); |
rtok = relex(); |
|
/* GNU compatibility: an empty regexp matches anything */ |
if (rtok == '\0') |
if (rtok == '\0') |
FATAL("empty regular expression"); |
/* FATAL("empty regular expression"); previous */ |
|
return(op2(ALL, NIL, NIL)); |
np = regexp(); |
np = regexp(); |
if (rtok != '\0') |
if (rtok != '\0') |
FATAL("syntax error in regular expression %s at %s", lastre, prestr); |
FATAL("syntax error in regular expression %s at %s", lastre, prestr); |
|
|
} |
} |
} |
} |
|
|
|
/* |
|
* Character class definitions conformant to the POSIX locale as |
|
* defined in IEEE P1003.1 draft 7 of June 2001, assuming the source |
|
* and operating character sets are both ASCII (ISO646) or supersets |
|
* thereof. |
|
* |
|
* Note that to avoid overflowing the temporary buffer used in |
|
* relex(), the expanded character class (prior to range expansion) |
|
* must be less than twice the size of their full name. |
|
*/ |
|
struct charclass { |
|
const char *cc_name; |
|
int cc_namelen; |
|
const char *cc_expand; |
|
} charclasses[] = { |
|
{ "alnum", 5, "0-9A-Za-z" }, |
|
{ "alpha", 5, "A-Za-z" }, |
|
{ "blank", 5, " \t" }, |
|
{ "cntrl", 5, "\000-\037\177" }, |
|
{ "digit", 5, "0-9" }, |
|
{ "graph", 5, "\041-\176" }, |
|
{ "lower", 5, "a-z" }, |
|
{ "print", 5, " \041-\176" }, |
|
{ "punct", 5, "\041-\057\072-\100\133-\140\173-\176" }, |
|
{ "space", 5, " \f\n\r\t\v" }, |
|
{ "upper", 5, "A-Z" }, |
|
{ "xdigit", 6, "0-9A-Fa-f" }, |
|
{ NULL, 0, NULL }, |
|
}; |
|
|
|
|
int relex(void) /* lexical analyzer for reparse */ |
int relex(void) /* lexical analyzer for reparse */ |
{ |
{ |
int c, n; |
int c, n; |
|
|
static uschar *buf = 0; |
static uschar *buf = 0; |
static int bufsz = 100; |
static int bufsz = 100; |
uschar *bp; |
uschar *bp; |
|
struct charclass *cc; |
|
const uschar *p; |
|
|
switch (c = *prestr++) { |
switch (c = *prestr++) { |
case '|': return OR; |
case '|': return OR; |
|
|
} |
} |
else |
else |
cflag = 0; |
cflag = 0; |
n = 2 * strlen(prestr)+1; |
n = 2 * strlen((const char *) prestr)+1; |
if (!adjbuf((char **) &buf, &bufsz, n, n, (char **) &bp, 0)) |
if (!adjbuf((char **) &buf, &bufsz, n, n, (char **) &bp, 0)) |
FATAL("out of space for reg expr %.10s...", lastre); |
FATAL("out of space for reg expr %.10s...", lastre); |
for (; ; ) { |
for (; ; ) { |
|
|
*bp++ = c; |
*bp++ = c; |
/* } else if (c == '\n') { */ |
/* } else if (c == '\n') { */ |
/* FATAL("newline in character class %.20s...", lastre); */ |
/* FATAL("newline in character class %.20s...", lastre); */ |
|
} else if (c == '[' && *prestr == ':') { |
|
/* POSIX char class names, Dag-Erling Smorgrav, des@ofug.org */ |
|
for (cc = charclasses; cc->cc_name; cc++) |
|
if (strncmp((const char *) prestr + 1, (const char *) cc->cc_name, cc->cc_namelen) == 0) |
|
break; |
|
if (cc->cc_name != NULL && prestr[1 + cc->cc_namelen] == ':' && |
|
prestr[2 + cc->cc_namelen] == ']') { |
|
prestr += cc->cc_namelen + 3; |
|
for (p = (const uschar *) cc->cc_expand; *p; p++) |
|
*bp++ = *p; |
|
} else |
|
*bp++ = c; |
} else if (c == '\0') { |
} else if (c == '\0') { |
FATAL("nonterminated character class %.20s", lastre); |
FATAL("nonterminated character class %.20s", lastre); |
} else if (bp == buf) { /* 1st char is special */ |
} else if (bp == buf) { /* 1st char is special */ |