diff options
| -rw-r--r-- | maildrop/Makefile.am | 2 | ||||
| -rw-r--r-- | maildrop/re.C | 888 | ||||
| -rw-r--r-- | maildrop/re.h | 100 | ||||
| -rw-r--r-- | maildrop/search.C | 404 | ||||
| -rw-r--r-- | maildrop/search.h | 3 | 
5 files changed, 103 insertions, 1294 deletions
| diff --git a/maildrop/Makefile.am b/maildrop/Makefile.am index f256edd..9cb53a8 100644 --- a/maildrop/Makefile.am +++ b/maildrop/Makefile.am @@ -39,7 +39,7 @@ maildrop_SOURCES=deliver.C deliverdotlock.C deliverdotlock.h \  	dotlockmaildrop.C filelock.C filelock.h filter.C formatmbox.C \  	formatmbox.h globaltimer.C globaltimer.h lexer.C lexer.h log.C log.h \  	maildir.C maildir.h main.C message.C message.h messageinfo.C \ -	messageinfo.h mytime.h mywait.h pipefds.C pipefds.h re.C re.h \ +	messageinfo.h mytime.h mywait.h pipefds.C pipefds.h \  	recipe.C recipe.h recipenode.C recipenode.h recipeparse.C reeval.C \  	reeval.h regexpnode.h rematch.C rematch.h rematchmsg.C rematchmsg.h \  	rematchstr.C rematchstr.h search.C search.h token.C \ diff --git a/maildrop/re.C b/maildrop/re.C deleted file mode 100644 index f2ab94e..0000000 --- a/maildrop/re.C +++ /dev/null @@ -1,888 +0,0 @@ -#include	"config.h" -#include	"re.h" -#include	"mio.h" -#include	"regexpnode.h" -#include	"rematch.h" -#include	"funcs.h" -#include	"buffer.h" -#include	<ctype.h> - - -////////////////////////////////////////////////////////////////////////////// -// -// Create sets for the [:is....:] codes. -// - -static void mk_alnum(unsigned char *p) -{ -register unsigned i; - -	for (i=0; i<256; i++) -		if (isalnum(i)) -			p[i/8] |= 1 << (i % 8); -} - -static void mk_alpha(unsigned char *p) -{ -register unsigned i; - -	for (i=0; i<256; i++) -		if (isalpha(i)) -			p[i/8] |= 1 << (i % 8); -} - -static void mk_cntrl(unsigned char *p) -{ -register unsigned i; - -	for (i=0; i<256; i++) -		if (iscntrl(i)) -			p[i/8] |= 1 << (i % 8); -} - -static void mk_digit(unsigned char *p) -{ -register unsigned i; - -	for (i=0; i<256; i++) -		if (isdigit(i)) -			p[i/8] |= 1 << (i % 8); -} - -static void mk_graph(unsigned char *p) -{ -register unsigned i; - -	for (i=0; i<256; i++) -		if (isgraph(i)) -			p[i/8] |= 1 << (i % 8); -} - -static void mk_lower(unsigned char *p) -{ -register unsigned i; - -	for (i=0; i<256; i++) -		if (islower(i)) -			p[i/8] |= 1 << (i % 8); -} - -static void mk_print(unsigned char *p) -{ -register unsigned i; - -	for (i=0; i<256; i++) -		if (isprint(i)) -			p[i/8] |= 1 << (i % 8); -} - -static void mk_punct(unsigned char *p) -{ -register unsigned i; - -	for (i=0; i<256; i++) -		if (ispunct(i)) -			p[i/8] |= 1 << (i % 8); -} - -static void mk_space(unsigned char *p) -{ -register unsigned i; - -	for (i=0; i<256; i++) -		if (isspace(i)) -			p[i/8] |= 1 << (i % 8); -} - -static void mk_upper(unsigned char *p) -{ -register unsigned i; - -	for (i=0; i<256; i++) -		if (isupper(i)) -			p[i/8] |= 1 << (i % 8); -} - -static void mk_xdigit(unsigned char *p) -{ -register unsigned i; - -	for (i=0; i<256; i++) -		if (isxdigit(i)) -			p[i/8] |= 1 << (i % 8); -} - -static void mk_wbreak(unsigned char *p) -{ -register unsigned i; - -	for (i=0; i<256; i++) -		if (!isalnum(i) && i != '_') -			p[i/8] |= 1 << (i % 8); -} - -static const char *const is_setname[]={ -	":alnum:", -	":alpha:", -	":cntrl:", -	":digit:", -	":graph:", -	":lower:", -	":print:", -	":punct:", -	":space:", -	":upper:", -	":xdigit:", -	":wbreak:"}; - -static void (*is_setfunc[])(unsigned char *)={ -	mk_alnum, -	mk_alpha, -	mk_cntrl, -	mk_digit, -	mk_graph, -	mk_lower, -	mk_print, -	mk_punct, -	mk_space, -	mk_upper, -	mk_xdigit, -	mk_wbreak}; - -Re::Re() : chainedre(0), prevre(0), nodes(0), first(0), isCaret(0) -{ -} - -Re::~Re() -{ -	init(); -} - -void Re::init() -{ -	if (chainedre)	delete chainedre; -	chainedre=0; - -RegExpNode *n; - -	while ((n=nodes) != 0) -	{ -		nodes=n->next; -		delete n; -	} -} - -inline RegExpNode	*Re::allocnode() -{ -RegExpNode	*n; - -	if ((n=new RegExpNode(nextid++)) == 0) -		outofmem(); -	n->next=nodes; nodes=n; return(n); -} - -int Re::Compile(const char *ptr, int caseflag, int &errindex) -{ -	if (*ptr == '^') -	{ -		if (CompileS(ptr+1, caseflag, errindex))	return (-1); -		isCaret=1; -		return (0); -	} - -	if (CompileS("[.\n]*", 1, errindex) < 0)	return (-1); -	if ((chainedre=new Re) == 0) -		outofmem(); -	isDummy=1; -	chainedre->prevre=this; -	return (chainedre->CompileS(ptr, caseflag, errindex)); -} - -int Re::CompileS(const char *ptr, int caseflag, int &errindex) -{ -	expr=ptr; -	origexpr=expr; -	init(); -	nextid=0; -	first=0; -	isCaret=0; -	isDummy=0; -	casesensitive=caseflag; -	matchFull=0; - -int	rc=0; - -	try -	{ -	RegExpNode **p=CompileOrClause(&first); - -		if (*expr == '!') -		{ -		int dummy; - -			++expr; -			if ((chainedre=new Re) == 0) -				outofmem(); -			if ( chainedre->CompileS(expr, caseflag, dummy) < 0) -			{ -				expr += dummy; -				throw -1; -			} -			chainedre->prevre=this; -			if (VerboseLevel() > 7) -				merr.write("\n*** CHAINED TO ***\n"); - -		} else if (curchar())	throw -1; - -		final=*p=allocnode(); -		final->thechar=REFINAL; -	} -	catch (int n) -	{ -		init(); -		errindex=expr-origexpr; -		rc= n; -	} -	if (rc == 0 && VerboseLevel() > 7) -	{ -	RegExpNode *n; -	Buffer	b; - -		if (first) -		{ -			b="Start node: "; -			b.append( (unsigned long)first->id ); -			b += "\n\n"; -			b += '\0'; -			merr.write(b); -		} -		for (n=nodes; n; n=n->next) -		{ -			b="Node "; -			b.append( (unsigned long)n->id ); -			b += ": "; -			switch (n->thechar)	{ -			case RENULL: -				b  += "null"; -				break; -			case RESET: -				b += "[set] "; -				{ -				int i,j=0; - -					for (i=0; i<256; i=j) -					{ -						j=i+1; -						if ((n->reset[i/8] & -							(1 << (i % 8))) == 0) -							continue; -						for (j=i; j<256; j++) -							if ((n->reset[j/8] & -								(1 << (j % 8))) -								== 0) -							break; -						if (i < ' ' || i > 127) -						{ -							b += '#'; -							b.append((unsigned long) -								i); -						} -						else -						{ -							if (i == '#' -								|| i == '-' -								|| i == '\\') -								b += '\\'; -							b += (char)i; -						} -						if (i+1 == j)	continue; -						b += ('-'); -						--j; -					} -				} -				break; -			case REFINAL: -				b += "final"; -				break; -			default: -				if (n->thechar >= ' ' && n->thechar < 127) -				{ -					b += '\''; -					b += (char)n->thechar; -					b += '\''; -				} -				else -				{ -					b += "chr("; -					b.append((unsigned long)n->thechar); -					b += ')'; -				} -			} -			b += '\n'; -			b += '\0'; -			merr.write( b ); -			if (n->next1) -			{ -				b="    transition to "; -				b.append((unsigned long)n->next1->id); -				b += '\n'; -				b += '\0'; -				merr.write(b); -			} - -			if (n->next2) -			{ -				b="    transition to "; -				b.append((unsigned long)n->next2->id); -				b += '\n'; -				b += '\0'; -				merr.write(b); -			} -			merr.write("\n"); -		} -	} -	return (rc); -} - -RegExpNode **Re::CompileOrClause(RegExpNode **ptr) -{ -RegExpNode **finish=CompileAtomString(ptr); - -	if ( curchar() != '|')	return (finish); - -RegExpNode *realfinish=allocnode(); - -	realfinish->thechar=RENULL; -	*finish=realfinish; - -	while ( curchar() == '|' ) -	{ -		nextchar(); - -	RegExpNode *newstart=allocnode(); - -		newstart->thechar=RENULL; -		newstart->next1= *ptr; -		*ptr=newstart; - -		finish=CompileAtomString(&newstart->next2); -		*finish=realfinish; -	} -	return (&realfinish->next1); -} - -RegExpNode **Re::CompileAtomString(RegExpNode **ptr) -{ -int	c; - -	for (;;) -	{ -		c=curchar(); -		if (c == 0 || c == '|' || c == ')' || c == '!') -			break; -		ptr=CompileElement(ptr); -	} -	return (ptr); -} - -RegExpNode **Re::CompileElement(RegExpNode **start) -{ -RegExpNode **finish; - -	if (curchar() != '$') -	{ -		finish=CompileAtom(start); -	} -	else -	{ -		nextchar(); -		if (curchar() == 0) -		{ -			matchFull=1; -			return (start); -		} -		(*start)=allocnode(); -		(*start)->thechar='$'; -		finish= & (*start)->next1; -	} - -	switch (curchar())	{ -	case '+': -		(*finish)=allocnode(); -		(*finish)->thechar=RENULL; -		(*finish)->next1=(*start); -		finish= &(*finish)->next2; -		nextchar(); -		break; -	case '*': -		(*finish)=allocnode(); -		(*finish)->thechar=RENULL; -		(*finish)->next1=(*start); -		(*start)=(*finish); -		finish= &(*finish)->next2; -		nextchar(); -		break; -	case '?': - -		{ -		RegExpNode *newstart=allocnode(); - -			newstart->thechar=RENULL; -			(*finish)=allocnode(); -			(*finish)->thechar=RENULL; -			newstart->next1= *start; -			newstart->next2= *finish; -			*start=newstart; -			finish= &(*finish)->next1; -			nextchar(); -		} -		break; -	} -	return (finish); -} - -RegExpNode **Re::CompileAtom(RegExpNode **ptr) -{ -int	c=curchar(); - -	if (c == '(')	// Subexpression -	{ -		nextchar(); -		ptr=CompileOrClause(ptr); -		if ( curchar() != ')')	throw -1; -		nextchar(); -		return (ptr); -	} - -	(*ptr)=allocnode(); - -	if (c == '[' || c == '.') -	{ -	int	i, complement=0; - -		if ( ((*ptr)->reset=new unsigned char[256/8]) == 0) -			outofmem(); -		for (i=0; i<256/8; i++) -			(*ptr)->reset[i]=0; - -		if ( c == '.' ) -		{ -			(*ptr)->reset[ '\n' / 8 ] |= 1 << ('\n' % 8); -			complement=1; -		} -		else -		{ -			nextchar(); -			if ( curchar() == '^') -			{ -				complement=1; -				nextchar(); -			} - -			is_sets(*ptr); -		} -		nextchar(); -		if (complement) -			for (i=0; i<256/8; i++) -				(*ptr)->reset[i] ^= ~0; -		c=RESET; -	} -	else c=parsechar(); - -	(*ptr)->thechar=c; -	return (&(*ptr)->next1); -} - -void Re::is_sets(RegExpNode *p) -{ -Buffer	buf; -int	c=curchar(); -int	call_parsechar=1; - -	if (c == ':') -	{ -		do -		{ -			buf += c; -			nextchar(); -		} while ( (c=curchar()) >= 0 && isalpha(c)); - -		if (c == ':') -		{ -			buf += c; -			nextchar(); -			c=curchar(); -			if (c == ']') -			{ -				buf += '\0'; - -			const char *q=(const char *)buf; -			unsigned i; - -				for (i=0; i<sizeof(is_setname)/ -					sizeof(is_setname[0]); i++) -				{ -					if (strcmp(is_setname[i], q) == 0) -					{ -						(*is_setfunc[i])(p->reset); -						return; -					} -				} -			} -		} - -	int	i=0; - -		for (i=0; i<buf.Length(); i++) -		{ -			c=(int)(unsigned char)((const char*)buf)[i]; -			p->reset[ c / 8 ] |= 1 << (c % 8); -		} -		// In case the next character is '-', leave 'c' the way it -		// is. -		call_parsechar=0; -		if (curchar() == ']')	return; -	} - -	do -	{ -	int	c2; - -		if (c == 0)	throw -1; - -		if (c == '.') -		{ -			for (c2=0; c2 < 256/8; c2++) -				if (c2 != '\n' / 8) -					p->reset[c2]= ~0; -				else -					p->reset[c2] |= ~(1 << ('\n' % 8)); -			if (call_parsechar) -				nextchar(); -			call_parsechar=1; -			continue; -		} -		if (call_parsechar) -			c=parsechar(); -		c2=c; -		call_parsechar=1; - -		if (curchar() == '-') -		{ -			nextchar(); -			c2=parsechar(); -		} -		while ( c <= c2 ) -		{ -			p->reset[ c / 8 ] |= 1 << (c % 8); -			++c; -		} -	} while ((c=curchar()) != ']'); -} - -int Re::parsechar() -{ -int	c; - -	c=curchar(); -	if (c == 0)	throw -1; -	nextchar(); -	if (c != '\\') return (c); -	c=curchar(); - -	if (c == 0) -		throw -1; -	else if (c >= '0' && c <= '7') -	{ -	unsigned char uc=0; - -		while ( c >= '0' && c <= '7' ) -		{ -			uc = uc * 8 + (c-'0'); -			nextchar(); -			c=curchar(); -		} -		c=uc; -	} -	else -	{ -		c=backslash_char(c); -		nextchar(); -	} -	return (c); -} - -///////////////////////////////////////////////////////////////////////////// - -int Re::Match(ReMatch &string) -{ -	matched= -1; -	matchedpos=0; - -	charsmatched=0; -	state1.init(nextid); -	state2.init(nextid); - -	curstate= &state1; -	nextstate= &state2; - -	curstate->nodes[0]=first; -	curstate->numnodes=1; -	curstate->nodenums[first->id]=0; - -	final_id=final->id; - -	if (VerboseLevel() > 8) -	{ -		merr.write("*** MATCH START ***\n"); -	} - -	for (;;) -	{ -	// Compute null closure - -	unsigned n; - -		for (n=0; n<curstate->numnodes; n++) -		{ -		RegExpNode *p=curstate->nodes[n]; - -			if (p->thechar != RENULL)	continue; - -		RegExpNode *q=p->next1; - -			if (q && curstate->nodenums[q->id] != charsmatched) -			{ -				curstate->nodes[curstate->numnodes++]=q; -				curstate->nodenums[q->id]=charsmatched; -				if (VerboseLevel() > 8) -				{ -				Buffer b; - -					b="  Transition to state "; -					b.append((unsigned long)q->id); -					b += '\n'; -					b += '\0'; -					merr.write(b); -				} -			} - -			q=p->next2; -			if (q && curstate->nodenums[q->id] != charsmatched) -			{ -				curstate->nodes[curstate->numnodes++]=q; -				curstate->nodenums[q->id]=charsmatched; -				if (VerboseLevel() > 8) -				{ -				Buffer b; - -					b="  Transition to state "; -					b.append((unsigned long)q->id); -					b += '\n'; -					b += '\0'; -					merr.write(b); -				} -			} -		} - -	int	nextChar; - -		if (curstate->nodenums[final_id] == charsmatched) -		{ -		off_t	pos=string.GetCurrentPos(); - -			if (VerboseLevel() > 8) -				merr.write("**Final node.\n"); -			if (chainedre) -			{ -			unsigned long saved_matched_chainedre= -					chainedre->charsmatched; - -				// On subsequent passes, charsmatched gets -				// reset.  If, previously, we had a match, -				// don't forget # of characters matched! - -				if (VerboseLevel() > 8) -					merr.write( -					"**Final node - checking subexpr.\n"); -				if (chainedre->Match(string) == 0) -				{ -					if (VerboseLevel() > 8) -					{ -					Buffer	buf; - -						buf="**Subexpr matched after "; -						buf.append( (unsigned long) -							charsmatched); -						buf += " characters.\n"; -						buf += '\0'; -						merr.write(buf); -					} -					matched=0; -					matchedpos=charsmatched; -					if (isDummy)	// Don't need to -							// look for max matches -							// for the dummy block -					{ -						return (0); -					} -				} -				else -				{ -					if (VerboseLevel() > 8) -						merr.write( -						"**Subexpr didn't match.\n"); -					chainedre->charsmatched= -						saved_matched_chainedre; -				} -				string.SetCurrentPos(pos); -				nextChar=string.NextChar(); -			} -			else -			{ -				if (!matchFull)	// We don't need to match full -						// string. -				{ -					if (VerboseLevel() > 8) -					{ -					Buffer	buf; - -						buf="Matched "; -						buf.append( (unsigned long) -							charsmatched); -						buf += " characters.\n"; -						buf += '\0'; -						merr.write(buf); -					} -					matched=0; -					matchedpos=charsmatched; -				} - -				nextChar=string.NextChar(); -				if ( nextChar < 0) -				{ -					if (VerboseLevel() > 8) -					{ -					Buffer	buf; - -						buf="Matched "; -						buf.append( (unsigned long) -							charsmatched); -						buf += " characters.\n"; -						buf += '\0'; -						merr.write(buf); -					} -					return (0);	// Matched everything -				} -			} -		} -		else nextChar=string.NextChar(); - -		if (nextChar < 0) -		{ -			if (VerboseLevel() > 8) -				merr.write( -					"Failed - End of matching string.\n"); -			charsmatched=matchedpos; -			return (matched); -		} -		if (curstate->numnodes == 0)	// No sense to continue -		{ -			if (VerboseLevel() > 8) -				merr.write( -					"Failed - out of states.\n"); -			charsmatched=matchedpos; -			return (matched); -		} - -		if (VerboseLevel() > 8) -		{ -		Buffer	b; - -			b="Matching character: "; - -			if (nextChar <= ' ' || nextChar > 127) -			{ -				b += '#'; -				b.append((unsigned long)nextChar); -			} -			else	b += (char)nextChar; -			b += '\n'; -			b += '\0'; -			merr.write(b); -		} -		++charsmatched; - -		if (!casesensitive) -			nextChar=tolower(nextChar); - -		nextstate->numnodes=0; - -		for (n=0; n<curstate->numnodes; n++) -		{ -		RegExpNode *p=curstate->nodes[n]; - -			if (p->thechar == RESET) -			{ -				if ((p->reset[nextChar / 8] & -						(1 << (nextChar % 8))) == 0) -				{ -					if (casesensitive)	continue; - -				int	uchar=toupper(nextChar); -					if ((p->reset[uchar / 8] & -						(1 << (uchar % 8))) == 0) -							continue; -				} -			} -			else -			{ -				if (p->thechar != nextChar) -				{ -					if (casesensitive)	continue; -				int	uchar=toupper(nextChar); -					if (p->thechar != uchar) -						continue; -				} -			} - -		RegExpNode *q=p->next1; - -			if (q && nextstate->nodenums[q->id] != charsmatched) -			{ -				nextstate->nodes[nextstate->numnodes++]=q; -				nextstate->nodenums[q->id]=charsmatched; -				if (VerboseLevel() > 8) -				{ -				Buffer b; - -					b="  Transition to state "; -					b.append((unsigned long)q->id); -					b += '\n'; -					b += '\0'; -					merr.write(b); -				} -			} - -			q=p->next2; - -			if (q && nextstate->nodenums[q->id] != charsmatched) -			{ -				nextstate->nodes[nextstate->numnodes++]=q; -				nextstate->nodenums[q->id]=charsmatched; -				if (VerboseLevel() > 8) -				{ -				Buffer b; - -					b="  Transition to state "; -					b.append((unsigned long)q->id); -					b += '\n'; -					b += '\0'; -					merr.write(b); -				} -			} -		} - -	ReEval *swap=curstate; curstate=nextstate; nextstate=swap; -	} -} diff --git a/maildrop/re.h b/maildrop/re.h deleted file mode 100644 index 1c2d3ab..0000000 --- a/maildrop/re.h +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef	re_h -#define	re_h - - -#include	"config.h" -#include	<sys/types.h> -#include	"funcs.h" -#include	"reeval.h" - -class ReMatch; - -/////////////////////////////////////////////////////////////////////////// -// -//  The Re class represents a regular expression.   The regular expression -//  is translated into a non-deterministic automaton, stored as a list -//  of RegExpNodes. -// -//  Then, one or more strings are matched against the regular expression. -// -//  The Re object may dynamically allocate another Re object in order to -//  implement the ! operator.  Each ! operator introduces a dynamically- -//  allocated Re object, which contains the next chained regular expression. -//  Another ! operator causes another object to be allocated. -// -//  The ^ and $ anchors are implemented here.  The ABSENCE of a ^ anchor -//  causes a dummy "[.\n]*" expression to be created in the first Re object, -//  with the real expression being parsed in the 2nd Re object. -// -//  When a string is matched against a regular expression, when the current -//  state includes a FINAL state, and there is a chained Re object, the -//  remainder of the string gets matched against the chained Re object. -//  If the chained matched succeeds, the entire match succeeds, otherwise, -//  we continue matching the original string. -// -//  If a match is succesfull, MatchCount() may be called to return the number -//  of characters that were matched.  If an ! operator is used, the optional -//  argument to MatchCount(), if not null, can be used to call MatchCount() -//  to return the count that the next expression matched. -// -/////////////////////////////////////////////////////////////////////////// - -class	RegExpNode; - -class Re { - -	Re	*chainedre;		// Chained regular expression -	Re	*prevre; -	RegExpNode *nodes;		// Singly-linked list of nodes -	RegExpNode *first;		// Starting node -	RegExpNode *final;		// Final node -	unsigned nextid;		// When creating, next ID to assign - -	RegExpNode	*allocnode(); -	const	char *expr, *origexpr; - -	// When matching: -	int	matched; -	off_t matchedpos; -	ReEval	*curstate, *nextstate; -	unsigned final_id; - -	int	curchar() { return ((int)(unsigned char)*expr); } -	void	nextchar() { ++expr; } -	int	casesensitive; -	int	matchFull; -	int	isCaret; -	int	isDummy; -public: -	Re(); -	~Re(); - -	int Compile(const char *, int, int &); -			// Compile regular expression -private: -	int CompileS(const char *, int, int &); - - -	void init(); -	RegExpNode **CompileAtom(RegExpNode **); -	RegExpNode **CompileAtomString(RegExpNode **); -	RegExpNode **CompileOrClause(RegExpNode **); -	RegExpNode **CompileElement(RegExpNode **); -	void is_sets(RegExpNode *); - -	int	parsechar(); - -// Evaluation - -	ReEval	state1, state2; -	unsigned charsmatched; -public: -	int	Match(ReMatch &); -	unsigned MatchCount(Re **p =0) { -					if (p) *p=chainedre; -					return (charsmatched); } -	int	IsDummy()	{ return (isDummy); } -	int	IsAnchorStart()	{ return (isCaret); } -} ; - -#endif diff --git a/maildrop/search.C b/maildrop/search.C index 33a5792..d2756bb 100644 --- a/maildrop/search.C +++ b/maildrop/search.C @@ -32,8 +32,6 @@ void Search::cleanup()  int	Search::init(const char *expr, const char *opts)  { -	int	dummy; -  	match_header=0;  	match_body=0;  	weight1=1; @@ -49,84 +47,67 @@ int	Search::init(const char *expr, const char *opts)  		if (strchr(opts, 'w'))	match_body=1;  	} -	Buffer b; - -	b="MAILDROP_OLD_REGEXP"; - -	const char *p=GetVarStr(b); - -	if (atoi(p ? p:"0") == 0) -	{ -		const char *errptr; - -		cleanup(); +	const char *errptr; -		if (strchr(opts, 'w')) -		{ -			b="Pattern option 'w' is valid only when MAILDROP_OLD_REGEXP is set\n"; -			b += '\0'; -			merr.write(b); -			return -1; -		} +	cleanup(); -		int errindex; +	int errindex; -		pcre_regexp=pcre_compile(expr, -					 strchr(opts, 'D') ? 0:PCRE_CASELESS, -					 &errptr, -					 &errindex, 0); +	pcre_regexp=pcre_compile(expr, +				 strchr(opts, 'D') ? 0:PCRE_CASELESS, +				 &errptr, +				 &errindex, 0); -		if (!pcre_regexp) -		{ -			b="Invalid regular expression, offset "; -			b.append((unsigned long)errindex); -			b += " of: "; -			b += expr; -			b += ": "; -			b += errptr; -			b += "\n"; -			b += '\0'; -			merr.write(b); -			return -1; -		} +	if (!pcre_regexp) +	{ +		Buffer b; + +		b="Invalid regular expression, offset "; +		b.append((unsigned long)errindex); +		b += " of: "; +		b += expr; +		b += ": "; +		b += errptr; +		b += "\n"; +		b += '\0'; +		merr.write(b); +		return -1; +	} -		pcre_regexp_extra=pcre_study(pcre_regexp, 0, -					     &errptr); +	pcre_regexp_extra=pcre_study(pcre_regexp, 0, &errptr); -		if (errptr) -		{ -			b="Error parsing regular expression: "; -			b += expr; -			b += ": "; -			b += errptr; -			b += "\n"; -			b += '\0'; -			merr.write(b); -			return -1; -		} +	if (errptr) +	{ +		Buffer b; + +		b="Error parsing regular expression: "; +		b += expr; +		b += ": "; +		b += errptr; +		b += "\n"; +		b += '\0'; +		merr.write(b); +		return -1; +	} -		int cnt=0; +	int cnt=0; -		pcre_fullinfo(pcre_regexp, pcre_regexp_extra, -			      PCRE_INFO_CAPTURECOUNT, &cnt); +	pcre_fullinfo(pcre_regexp, pcre_regexp_extra, +		      PCRE_INFO_CAPTURECOUNT, &cnt); -		pcre_vector_count=(cnt+1)*3; +	pcre_vector_count=(cnt+1)*3; -		pcre_vectors=(int *)malloc(pcre_vector_count*sizeof(int)); +	pcre_vectors=(int *)malloc(pcre_vector_count*sizeof(int)); -		if (!pcre_vectors) -		{ -			b=strerror(errno); -			b += "\n"; -			b += '\0'; -			merr.write(b); -			return -1; -		} -	}				 -	else +	if (!pcre_vectors)  	{ -		if (regexp.Compile(expr, strchr(opts, 'D') ? 1:0, dummy)) -			return (-1); +		Buffer b; + +		b=strerror(errno); +		b += "\n"; +		b += '\0'; +		merr.write(b); +		return -1;  	}  	while (*opts) @@ -157,8 +138,7 @@ int Search::find(Message &msg, MessageInfo &,  	if (init(expr, opts))	return (-1);  	msg.Rewind(); -	return (strchr(opts, 'w') ? findinsection(msg, expr, foreachp): -		findinline(msg, expr, foreachp)); +	return (findinline(msg, expr, foreachp));  }  int Search::find(const char *str, const char *expr, const char *opts, @@ -185,57 +165,26 @@ int Search::find(const char *str, const char *expr, const char *opts,  	for (;;)  	{ -		if (pcre_regexp) -		{ -			match_count=pcre_exec(pcre_regexp, pcre_regexp_extra, -					      orig_str, strlen(orig_str), -					      startoffset, -					      0, -					      pcre_vectors, -					      pcre_vector_count); -			if (match_count <= 0) -				break; -			startoffset=pcre_vectors[1]; - -			score += weight1; -			weight1 *= weight2; - -			if (!scoring_match || foreachp) -			{ -				init_match_vars(orig_str, match_count, -						pcre_vectors, foreachp); -				if (!foreachp) -					break; -			} -			continue; -		} - -		ReMatchStr match(str); - -		if ( regexp.Match(match))	break; +		match_count=pcre_exec(pcre_regexp, pcre_regexp_extra, +				      orig_str, strlen(orig_str), +				      startoffset, +				      0, +				      pcre_vectors, +				      pcre_vector_count); +		if (match_count <= 0) +			break; +		startoffset=pcre_vectors[1];  		score += weight1;  		weight1 *= weight2;  		if (!scoring_match || foreachp)  		{ -			match.SetCurrentPos(0); -			init_match_vars(match, foreachp); +			init_match_vars(orig_str, match_count, +					pcre_vectors, foreachp);  			if (!foreachp) -				break;	// No need for more. -		} - -	Re *p; -	off_t	c=0; - -		for (p= ®exp; p; ) -			c += p->MatchCount( &p ); -		if (c == 0) -		{ -			if (!*str)	break; -			++c; +				break;  		} -		str += c;  	}  	return (0);  } @@ -291,85 +240,6 @@ int	eof;  				merr.write(msg);  			} -			if (pcre_regexp) -			{ -				const char *orig_str=current_line; -				int match_count; - -				match_count=pcre_exec(pcre_regexp, -						      pcre_regexp_extra, -						      orig_str, -						      strlen(orig_str), -						      0, -						      0, -						      pcre_vectors, -						      pcre_vector_count); - -				if (match_count > 0) -				{ -					score += weight1; -					weight1 *= weight2; - -					if (!scoring_match || foreachp) -					{ -						init_match_vars(orig_str, -								match_count, -								pcre_vectors, -								foreachp); -						if (!foreachp) -							return (0); -					} -				} -				else	if (VerboseLevel() > 2) -					merr.write("Not matched.\n"); -			} -			else -			{ -				ReMatchStr match(current_line); - -				if (regexp.Match(match) == 0) -				{ -					score += weight1; -					weight1 *= weight2; -					if (!scoring_match || foreachp) -					{ -						match.SetCurrentPos(0); -						init_match_vars(match, -								foreachp); -						if (!foreachp) -							return (0); -					} -				} -				else	if (VerboseLevel() > 2) -					merr.write("Not matched.\n"); -			} -		} -		if ( c == '\n')	break; -		current_line=next_line; -	} -	if (!match_body || eof)	return (0); - -	while (current_line.reset(), msg.appendline(current_line) == 0) -	{ -		current_line.pop(); -		current_line += '\0'; - -		if (VerboseLevel() > 2) -		{ -		Buffer	msg; - -			msg="Matching /"; -			msg.append(expr); -			msg.append("/ against "); -			msg += current_line; -			msg.pop();	// Trailing null byte. -			msg += '\n'; -			msg += '\0'; -			merr.write(msg); -		} - -		if (pcre_regexp) -		{  			const char *orig_str=current_line;  			int match_count; @@ -399,93 +269,61 @@ int	eof;  			}  			else	if (VerboseLevel() > 2)  				merr.write("Not matched.\n"); +		} +		if ( c == '\n')	break; +		current_line=next_line; +	} +	if (!match_body || eof)	return (0); -			continue; +	while (current_line.reset(), msg.appendline(current_line) == 0) +	{ +		current_line.pop(); +		current_line += '\0'; + +		if (VerboseLevel() > 2) +		{ +		Buffer	msg; + +			msg="Matching /"; +			msg.append(expr); +			msg.append("/ against "); +			msg += current_line; +			msg.pop();	// Trailing null byte. +			msg += '\n'; +			msg += '\0'; +			merr.write(msg);  		} -		ReMatchStr match(current_line); +		const char *orig_str=current_line; +		int match_count; -		if (regexp.Match(match) == 0) +		match_count=pcre_exec(pcre_regexp, +				      pcre_regexp_extra, +				      orig_str, +				      strlen(orig_str), +				      0, +				      0, +				      pcre_vectors, +				      pcre_vector_count); + +		if (match_count > 0)  		{  			score += weight1;  			weight1 *= weight2; +  			if (!scoring_match || foreachp)  			{ -				match.SetCurrentPos(0); -				init_match_vars(match, foreachp); +				init_match_vars(orig_str, +						match_count, +						pcre_vectors, +						foreachp);  				if (!foreachp)  					return (0);  			}  		}  		else	if (VerboseLevel() > 2) -				merr.write("Not matched.\n"); -	} -	return (0); -} - -/////////////////////////////////////////////////////////////////////////// -// -// Search anchored in the entire message. -// -/////////////////////////////////////////////////////////////////////////// +			merr.write("Not matched.\n"); -int Search::findinsection(Message &msg, const char *expr, Buffer *foreachp) -{ -	if (!match_header && !match_body)	return (0);	// Huh? - -	if (VerboseLevel() > 2) -	{ -	Buffer	m; - -		m="Matching /"; -		m.append(expr); -		m.append("/ against"); -		if (match_header) -			m.append(" header"); -		if (match_body) -			m.append(" body"); -		m += '\n'; -		m += '\0'; -		merr.write(m); -	} - -	if (!match_header) -	{ -	Buffer	dummy; - -		do -		{ -			dummy.reset(); -			if (msg.appendline(dummy) < 0)	return (0); -						// No message body, give up. -		} while (dummy.Length() != 1 || -				*(const char *)dummy != '\n'); -	} - -off_t start_pos=msg.tell(); -ReMatchMsg	match_msg(&msg, !match_body, match_header); - -	while ( match_msg.CurrentChar() >= 0 && regexp.Match(match_msg) == 0) -	{ -		score += weight1; -		weight1 *= weight2; - -		if (!scoring_match || foreachp) -		{ -			match_msg.SetCurrentPos(start_pos); -			init_match_vars(match_msg, foreachp); -			if (!foreachp) -				break;	// No need for more. -		} - -	Re *p; -	off_t c=0; - -		for (p= ®exp; p; ) -			c += p->MatchCount( &p ); -		if (c == 0)	++c; -		start_pos += c; -		match_msg.SetCurrentPos(start_pos);  	}  	return (0);  } @@ -533,41 +371,3 @@ void Search::init_match_vars(const char *str, int nranges, int *offsets,  		SetVar(varname, v);  	}  } - -void Search::init_match_vars(ReMatch &m, Buffer *foreachp) -{ -Re	*p; -Buffer	buf; -Buffer	varname; -unsigned long varnamecount=1; - -	varname="MATCH"; -	for (p= ®exp; p; ) -	{ -	Re	*q=p; -	unsigned	count=p->MatchCount(&p); - -		buf.reset(); -		while (count) -		{ -			buf.push( m.NextChar() ); -			count--; -		} - -		if ( !q->IsDummy()) -		{ -			if (foreachp) -			{ -				*foreachp += buf; -				*foreachp += '\0'; -			} -			else -			{ -				SetVar(varname, buf); -				++varnamecount; -				varname="MATCH"; -				varname.append(varnamecount); -			} -		} -	} -} diff --git a/maildrop/search.h b/maildrop/search.h index 1eda5aa..2ba726d 100644 --- a/maildrop/search.h +++ b/maildrop/search.h @@ -2,7 +2,6 @@  #define	search_h -#include	"re.h"  #include	"buffer.h"  #if	HAVE_PCRE_H @@ -48,7 +47,6 @@ class Search {  	int	*pcre_vectors;  	size_t	pcre_vector_count; -	Re	regexp;  	Buffer	current_line;  	Buffer	next_line; @@ -73,7 +71,6 @@ public:  private:  	int findinline(Message &, const char *, Buffer *);  	int findinsection(Message &, const char *, Buffer *); -	void init_match_vars(ReMatch &, Buffer *);  	void init_match_vars(const char *, int, int *, Buffer *);  } ;  #endif | 
