repost of patch for regular expressions in slocal

repost of patch for regular expressions in slocal

Post by Joel Reich » Tue, 13 Apr 2004 06:35:50


I posted this a couple of days ago, but I have a feeling it's being
filtered out by some news servers because the patch was an
attachment. It's just included here.

---old message---

Here's my hack at it. Although it probably isn't fit to go into the
code repository, it seems to work well and I can't think of a
situation where it would do harm.

A few notes first.

Regarding the compatibility with non-regex search strings, I've done
the logic in the following way. For each pattern, it does an `old'
match. If, and only if, that `old' match fails, does it check to see
if the string appears to be a perlish regex (i.e. of the form
/pattern/options). If that's the case, it attempts a regex match. This
logic would only present a problem if there was a regex that would
`false positive' match as an `old' match. I think the odds are against
this.

The delimiting slashes are the first and *last*. Any others between
are taken to be a part of the pattern.

The code is written using the POSIX API for regexes. Many systems
already have support for this so there's no need to grab a
library. The patch assumes the include file is called regex.h. If it
isn't, edit accordingly. If the functions aren't in the standard
library you'll need to link against the library that they are in
(obviously).

There's some debugging output in there. Feel free to run slocal with
-debug until your distrust of the code is sufficiently small.

The code always does an extended regex. `i' is the only option
supported, to do a case insensitive match. Other characters present
past the last `/' are harmless.

Cheers,

- Joel

--- uip/slocal.c.orig Thu Mar 2 18:52:47 2000
+++ uip/slocal.c Sat Apr 10 12:11:22 2004
@@ -29,6 +29,8 @@
#include <sys/ioctl.h>
#include <fcntl.h>

+#include <regex.h>
+
#ifdef INITGROUPS_HEADER
#include INITGROUPS_HEADER
#else
@@ -438,6 +440,39 @@

#define matches(a,b) (stringdex (b, a) >= 0)

+int rematches(const char *string, const char *p) {
+ regex_t preg;
+ int errcode;
+ char errbuf[100], *tmp, *opts, *pattern=malloc(strlen(p));
+ strcpy(pattern, p+1);
+ for(opts=pattern; NULL!=(tmp=strchr(opts, '/')); opts=tmp+1)
+ ;
+ *(opts-1)='\0';
+ if(debug)
+ debug_printf("Regex %s\nOpts %s\n", pattern, opts);
+ if(errcode=regcomp(&preg, pattern, REG_EXTENDED|((NULL!=strchr(opts, 'i'))?REG_ICASE:0))) {
+ if(debug) {
+ regerror(errcode, &preg, errbuf, 100);
+ debug_printf("Regcomp error: %s\n", errbuf);
+ }
+ regfree(&preg);
+ free(pattern);
+ return(0);
+ }
+ if(errcode=regexec(&preg, string, 0, 0, 0)) {
+ if(debug) {
+ regerror(errcode, &preg, errbuf, 100);
+ debug_printf("Regexec error: %s\n", errbuf);
+ }
+ regfree(&preg);
+ free(pattern);
+ return(0);
+ }
+ regfree(&preg);
+ free(pattern);
+ return(1);
+}
+
/*
* Parse the delivery file, and process incoming message.
*/
@@ -578,7 +613,9 @@
* see if the pattern matches.
*/
if ((p = lookup (hdrs, field)) && (p->p_value != NULL)
- && matches (p->p_value, pattern)) {
+ && (matches (p->p_value, pattern)
+ || ('/'==*pattern && NULL!=strchr(pattern+1, '/')
+ && rematches(p->p_value, pattern)))) {
next = 1;
} else {
next = 0;
 
 
 

repost of patch for regular expressions in slocal

Post by Jim Cochra » Thu, 15 Apr 2004 07:41:16


I'm a little late responding, but thanks for posting this. I'm impressed
by how fast you put it together.

I don't have the time/energy to install the patch myself, unfortunately,
but I'm hoping that it will inspire the developers to incorporate it or
something similar in an upcoming release.

In the mean time, I hope you're enjoying it :-)

 
 
 

repost of patch for regular expressions in slocal

Post by Joel Reich » Thu, 15 Apr 2004 16:49:51

Jim Cochrane < XXXX@XXXXX.COM > writes:


Do any developers read this newsgroup or do I need to send it to them?

Cheers,

- Joel
 
 
 

repost of patch for regular expressions in slocal

Post by Joel Hatto » Wed, 21 Apr 2004 09:43:43

i guys,

On Wed, 14 Apr 2004, Joel Reicher wrote:


In case this saves you some development time, here's a patch supplied by
John Beck on the exmh-users (well worth subscribing to, btw, for mh users)
mailing list. He gave me permission to repost here. If the patch breaks,
let me know and I'll send it to you directly.

cheers,
joel

--

my opinions in this email are not endorsed by the University of Qld
this message may not be onforwarded without my expressed permission

BEGIN slocal-regex.patch

--- config.h.in.orig Sun Feb 6 04:40:21 2000
+++ config.h.in Mon Feb 28 21:03:03 2000
@@ -394,6 +394,9 @@
/* Define if you have the <netdb.h> header file. */
#undef HAVE_NETDB_H

+/* Define if you have the <regex.h> header file. */
+#undef HAVE_REGEX_H
+
/* Define if you have the <stdlib.h> header file. */
#undef HAVE_STDLIB_H

--- configure.orig Sun Feb 20 03:21:40 2000
+++ configure Mon Feb 28 21:03:03 2000
@@ -2152,7 +2152,7 @@

fi

-for ac_hdr in string.h memory.h stdlib.h unistd.h errno.h fcntl.h \
+for ac_hdr in string.h memory.h stdlib.h unistd.h errno.h fcntl.h regex.h
\
limits.h crypt.h termcap.h termio.h termios.h locale.h \
netdb.h sys/param.h sys/time.h sys/utsname.h arpa/inet.h
\
arpa/ftp.h
--- configure.in.orig Tue Jan 25 22:39:49 2000
+++ configure.in Mon Feb 28 21:03:03 2000
@@ -300,7 +300,7 @@
AC_HEADER_TIME
AC_HEADER_SYS_WAIT
AC_HEADER_STAT
-AC_CHECK_HEADERS(string.h memory.h stdlib.h unistd.h errno.h fcntl.h \
+AC_CHECK_HEADERS(string.h memory.h stdlib.h unistd.h errno.h fcntl.h
regex.h \
limits.h crypt.h termcap.h termio.h termios.h locale.h \
netdb.h sys/param.h sys/time.h sys/utsname.h arpa/inet.h
\
arpa/ftp.h)
--- uip/slocal.c.Orig Sun Feb 6 04:41:00 2000
+++ uip/slocal.c.orig Mon Feb 28 21:06:46 2000
@@ -28,6 +28,9 @@
#include <signal.h>
#include <sys/ioctl.h>
#include <fcntl.h>
+#ifdef HAVE_REGEX_H
+# include <regex.h>
+#endif

#include <grp.h> /* initgroups() is here on Solaris 2.6 */
#include <unistd.h> /* initgroups() is here on HP-UX 10.20 */
@@ -186,6 +189,9 @@
static void debug_printf (char *fmt, ...);
static int suppress_duplicates (int, char *);
static char *trim (char *);
+#ifdef HAVE_REGEX_H
+static int matches(char *, char *);
+#endif


int
@@ -434,7 +440,9 @@
}


+#ifndef HAVE_REGEX_H
#define matches(a,b) (stringdex (b, a) >= 0)
+#endif

/*
* Parse the delivery file, and process incoming message.
@@ -1027,7 +1035,39 @@
return 0;
}

+#ifdef HAVE_REGEX_H
+static int
+matches (char *string, char *pattern)
+{
+ regex_t compiled;
+ int errcode = 0;
+
+ if (errcode = regcomp(&compiled, pattern,
+ REG_EXTENDED | REG_ICASE | REG_NEWLINE |
REG_NOSUB))
+ goto error;

+ errcode = regexec(&compiled, string, 0, NULL, 0);
+ regfree(&compiled);
+
+ switch (errcode) {
+ case 0:
+ return 1; /* a match ! */
+ case REG_NOMATCH:
+ return 0; /* no match */
+ default:
+ goto error;
+ }
+
+error:
+ {
+ char errbuf[512];
+
+ regerror(errcode, &compiled, errbuf, sizeof(errbuf));
+ adios (NULL, errbuf);
+ }
+}
+#endif
+
/*
* Deliver message to a nmh folder.
*/
@@ -1213,8 +1253,6 @@
for (cp = buffer + strlen (buffer) - 1; cp >= buffer; cp--)