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