On Thu, 2005-04-28 at 09:07 +0200, Paul J Stevens wrote:
> >>Currently the *only* place that uses (posix) regex is the namespace code in
> >>imap. I just finished a working implementation of base-subject retrieval 
> >>using
> >>pcre, but that's not in svn yet.
> > 
> > 
> > Why do we need regex for namespaces? The server defines the namespaces,
> > and they're all fixed-strings... aren't they?
> 
> I checked. _ic_list in imapcommands.c uses regex to find mailboxes bases
> on regexes by translating the LIST command to regex patterns.

Try the attached; I just whipped it up as a imap-style fnmatch()

It's not optimal: the *-sync shouldn't be recursive,
but I think it's pretty close to correct.

It has a test-harness, so if we find something it _DOESNT_ work on, it
can always be added.

-- 
Internet Connection High Quality Web Hosting
http://www.internetconnection.net/
/* listexpression match for imap (rfc2060) */

#define LISTEX_NOCASE	1
int listex_match(const char *p, const char *s,
			const char *x, int flags)
{
	int i;
	while (*p) {
		if (*p == '%') {
			while (*s && *s != *x) s++;
			p++;
			for (i = 0; x[i] && p[i] == x[i] && p[i] == s[i]; i++);
			if (! x[i]) {
				p += i; s += i;
				continue; /* sync'd */
			}
			if (s[i] || p[i]) return 0;
			return 1;

		}
		if (*p == '*') {
			/* use recursive for synchronize */
			p++;
			if (!(*p)) return 1;
			while (*s) {
				if (listex_match(p,s,x,flags)) return 1;
				s++;
			}
			return 0;

		}
		
		if (*p == *x) {
			for (i = 0; x[i] && p[i] == x[i] && p[i] == s[i]; i++);
			if (! x[i]) {
				p += i; s += i;
				continue; /* sync'd */
			}
			/* fall; try regular search */
		}

		if (flags & LISTEX_NOCASE && *p == *s) {
			p++; s++;
		} else if (*p == *s) {
			p++; s++;
		} else {
			/* failed */
			return 0;
		}
	}
	if (*p || *s) return 0;
	return 1;
}



#ifdef TEST
#include <stdio.h>
int main(int argc, char *argv[])
{
#define Y(z,q) if(z!=(q)) {fprintf(stderr,"Failed: %d != %s\n",z,#q);exit(1);}
#define X(z,a,b) Y(z,listex_match(a,b,".",0))
	X(1, "INBOX", "INBOX");
	X(0, "INBOX", "INBOX.Foo");
	X(0, "INBOX", "INBOX.Foo.Bar");

	X(0, "INBOX.%", "INBOX");
	X(1, "INBOX.%", "INBOX.Foo");
	X(0, "INBOX.%", "INBOX.Foo.Bar");

	X(0, "INBOX.*", "INBOX");
	X(1, "INBOX.*", "INBOX.Foo");
	X(1, "INBOX.*", "INBOX.Foo.Bar");

	X(1, "INBOX*", "INBOX");
	X(1, "INBOX*", "INBOX.Foo");
	X(1, "INBOX*", "INBOX.Foo.Bar");

	X(1, "INBOX%", "INBOX");
	X(0, "INBOX%", "INBOX.Foo");
	X(0, "INBOX%", "INBOX.Foo.Bar");

	X(0, "INBOX*Foo", "INBOX");
	X(1, "INBOX*Foo", "INBOX.Foo");
	X(0, "INBOX*Foo", "INBOX.Foo.Bar");

	X(0, "INBOX*Bar", "INBOX");
	X(0, "INBOX*Bar", "INBOX.Foo");
	X(1, "INBOX*Bar", "INBOX.Foo.Bar");

	X(0, "INBOX.*Bar", "INBOX");
	X(0, "INBOX.*Bar", "INBOX.Foo");
	X(1, "INBOX.*Bar", "INBOX.Foo.Bar");

}


#endif


Reply via email to