]] "Poul-Henning Kamp" 

|       We will add a "vre.c" file to libvarnish, and all the varnish
|       code will call vre_comp(), vre_exec() etc. functions from
|       there.
| 
|       By default, this file will simply call PCRE functions, and
|       as shipped Varnish will depend in PCRE.
| 
|       If somebody for reasons of policy does not want to use PCRE,
|       they will only have to change the vre.c file to do so.

I've done that in the attached patch.  If somebody could please read
through it an ack it, that would be most appreciated.

-- 
Tollef Fog Heen 
Redpill Linpro -- Changing the game!
t: +47 21 54 41 73
diff --git a/varnish-cache/bin/varnishd/Makefile.am b/varnish-cache/bin/varnishd/Makefile.am
index dfdef42..daa389b 100644
--- a/varnish-cache/bin/varnishd/Makefile.am
+++ b/varnish-cache/bin/varnishd/Makefile.am
@@ -1,6 +1,6 @@
 # $Id$
 
-INCLUDES = -I$(top_srcdir)/include
+INCLUDES = -I$(top_srcdir)/include @PCRE_CFLAGS@
 
 sbin_PROGRAMS = varnishd
 
@@ -87,6 +87,7 @@ varnishd_LDADD = \
 	$(top_builddir)/lib/libvarnishcompat/libvarnishcompat.la \
 	$(top_builddir)/lib/libvcl/libvcl.la \
 	@JEMALLOC_LDADD@ \
+	@PCRE_LIBS@ \
 	${DL_LIBS} ${PTHREAD_LIBS} ${NET_LIBS} ${LIBM} ${LIBUMEM}
 
 EXTRA_DIST = default.vcl
diff --git a/varnish-cache/bin/varnishd/cache_ban.c b/varnish-cache/bin/varnishd/cache_ban.c
index 57bdb05..9c2e866 100644
--- a/varnish-cache/bin/varnishd/cache_ban.c
+++ b/varnish-cache/bin/varnishd/cache_ban.c
@@ -50,13 +50,13 @@ SVNID("$Id$")
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <regex.h>
 
 #include "shmlog.h"
 #include "cli.h"
 #include "cli_priv.h"
 #include "cache.h"
 #include "hash_slinger.h"
+#include "vre.h"
 
 #include "cache_ban.h"
 
@@ -116,7 +116,7 @@ BAN_Free(struct ban *b)
 		bt = VTAILQ_FIRST(&b->tests);
 		VTAILQ_REMOVE(&b->tests, bt, list);
 		if (bt->flags & BAN_T_REGEXP)
-			regfree(&bt->re);
+			VRE_free(bt->re);
 		if (bt->dst != NULL)
 			free(bt->dst);
 		if (bt->src != NULL)
@@ -137,10 +137,13 @@ ban_cond_str(const struct ban_test *bt, const char *p)
 
 	if (p == NULL)
 		return(!(bt->flags & BAN_T_NOT));
-	if (bt->flags & BAN_T_REGEXP)
-		i = regexec(&bt->re, p, 0, NULL, 0);
-	else
+	if (bt->flags & BAN_T_REGEXP) {
+		i = VRE_exec(bt->re, p, strlen(p), 0, 0, NULL, 0);
+		if (i >= 0)
+			i = 0;
+	} else {
 		i = strcmp(bt->dst, p);
+	}
 	if (bt->flags & BAN_T_NOT)
 		return (!i);
 	return (i);
@@ -199,15 +202,13 @@ ban_cond_obj_http(const struct ban_test *bt, const struct object *o,
 static int
 ban_parse_regexp(struct cli *cli, struct ban_test *bt, const char *a3)
 {
-	int i;
-	char buf[512];
-
-	i = regcomp(&bt->re, a3, REG_EXTENDED | REG_ICASE | REG_NOSUB);
-	if (i) {
-		(void)regerror(i, &bt->re, buf, sizeof buf);
-		regfree(&bt->re);
-		VSL(SLT_Debug, 0, "REGEX: <%s>", buf);
-		cli_out(cli, "%s", buf);
+	const char *error;
+	int erroroffset;
+
+	bt->re = VRE_compile(a3, 0, &error, &erroroffset);
+	if (bt->re == NULL) {
+		VSL(SLT_Debug, 0, "REGEX: <%s>", error);
+		cli_out(cli, "%s", error);
 		cli_result(cli, CLIS_PARAM);
 		return (-1);
 	}
diff --git a/varnish-cache/bin/varnishd/cache_ban.h b/varnish-cache/bin/varnishd/cache_ban.h
index 58a1ff8..38e465a 100644
--- a/varnish-cache/bin/varnishd/cache_ban.h
+++ b/varnish-cache/bin/varnishd/cache_ban.h
@@ -44,7 +44,7 @@ struct ban_test {
 	int			flags;
 #define BAN_T_REGEXP		(1 << 0)
 #define BAN_T_NOT		(1 << 1)
-	regex_t			re;
+	vre			*re;
 	char			*dst;
 	char			*src;
 };
diff --git a/varnish-cache/bin/varnishd/cache_vrt_re.c b/varnish-cache/bin/varnishd/cache_vrt_re.c
index e91f3c1..88d93c5 100644
--- a/varnish-cache/bin/varnishd/cache_vrt_re.c
+++ b/varnish-cache/bin/varnishd/cache_vrt_re.c
@@ -40,47 +40,47 @@ SVNID("$Id$")
 #include <string.h>
 #include <ctype.h>
 #include <stdlib.h>
-#include <regex.h>
 
 #include "shmlog.h"
 #include "vrt.h"
+#include "vre.h"
 #include "vcl.h"
 #include "cache.h"
 
 void
-VRT_re_init(void **rep, const char *re, int sub)
+VRT_re_init(void **rep, const char *re)
 {
-	regex_t	*t;
+	vre *t;
+	const char *error;
+	int erroroffset;
 
-	t = calloc(sizeof *t, 1);
-	XXXAN(t);
 	/* This was already check-compiled by the VCL compiler */
-	AZ(regcomp(t, re, REG_EXTENDED | REG_ICASE | (sub ? 0 : REG_NOSUB)));
+	t = VRE_compile(re, 0, &error, &erroroffset);
+	AN(t);
 	*rep = t;
 }
 
 void
 VRT_re_fini(void *rep)
 {
-
 	if (rep != NULL)
-		regfree(rep);
+		VRE_free(rep);
 }
 
 int
 VRT_re_match(const char *s, void *re)
 {
-	regex_t	*t;
+	vre *t;
 	int i;
 
 	if (s == NULL)
 		return (0);
 	AN(re);
 	t = re;
-	i = regexec(t, s, 0, NULL, 0);
-	if (i == 0)
+	i = VRE_exec(t, s, strlen(s), 0, 0, NULL, 0);
+	if (i >= 0)
 		return (1);
-	assert(i == REG_NOMATCH);
+	assert(i == VRE_ERROR_NOMATCH);
 	return (0);
 }
 
@@ -88,8 +88,8 @@ const char *
 VRT_regsub(const struct sess *sp, int all, const char *str, void *re,
     const char *sub)
 {
-	regmatch_t pm[10];
-	regex_t *t;
+	int ovector[30];
+	vre *t;
 	int i, l;
 	txt res;
 	char *b0;
@@ -100,10 +100,11 @@ VRT_regsub(const struct sess *sp, int all, const char *str, void *re,
 	if (str == NULL)
 		return ("");
 	t = re;
-	i = regexec(t, str, 10, pm, 0);
+	memset(&ovector, 0, sizeof(ovector));
+	i = VRE_exec(t, str, strlen(str), 0, 0, ovector, 30);
 
 	/* If it didn't match, we can return the original string */
-	if (i == REG_NOMATCH)
+	if (i == VRE_ERROR_NOMATCH)
 		return(str);
 
 	u = WS_Reserve(sp->http->ws, 0);
@@ -112,8 +113,7 @@ VRT_regsub(const struct sess *sp, int all, const char *str, void *re,
 
 	do {
 		/* Copy prefix to match */
-		Tadd(&res, str, pm[0].rm_so);
-
+		Tadd(&res, str, ovector[0]);
 		for (s = sub ; *s != '\0'; s++ ) {
 			if (*s != '\\' || s[1] == '\0') {
 				if (res.b < res.e)
@@ -123,19 +123,20 @@ VRT_regsub(const struct sess *sp, int all, const char *str, void *re,
 			s++;
 			if (isdigit(*s)) {
 				x = *s - '0';
-				l = pm[x].rm_eo - pm[x].rm_so;
-				Tadd(&res, str + pm[x].rm_so, l);
+				l = ovector[2*x+1] - ovector[2*x];
+				Tadd(&res, str + ovector[2*x], l);
 				continue;
 			} else {
 				if (res.b < res.e)
 					*res.b++ = *s;
 			}
 		}
-		str += pm[0].rm_eo;
+		str += ovector[1];
 		if (!all)
 			break;
-		i = regexec(t, str, 10, pm, 0);
-	} while (i != REG_NOMATCH);
+		memset(&ovector, 0, sizeof(ovector));
+		i = VRE_exec(t, str, strlen(str), 0, 0, ovector, 30);
+	} while (i != VRE_ERROR_NOMATCH);
 
 	/* Copy suffix to match */
 	l = strlen(str) + 1;
diff --git a/varnish-cache/bin/varnishlog/Makefile.am b/varnish-cache/bin/varnishlog/Makefile.am
index 85c8b92..7c23b9a 100644
--- a/varnish-cache/bin/varnishlog/Makefile.am
+++ b/varnish-cache/bin/varnishlog/Makefile.am
@@ -13,3 +13,4 @@ varnishlog_LDADD = \
 	$(top_builddir)/lib/libvarnishcompat/libvarnishcompat.la \
 	$(top_builddir)/lib/libvarnishapi/libvarnishapi.la \
 	${PTHREAD_LIBS}
+	@PCRE_LIBS@
diff --git a/varnish-cache/bin/varnishlog/varnishlog.c b/varnish-cache/bin/varnishlog/varnishlog.c
index 4e6245a..20cd440 100644
--- a/varnish-cache/bin/varnishlog/varnishlog.c
+++ b/varnish-cache/bin/varnishlog/varnishlog.c
@@ -36,7 +36,6 @@ SVNID("$Id$")
 
 #include <errno.h>
 #include <fcntl.h>
-#include <regex.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -51,6 +50,7 @@ SVNID("$Id$")
 
 #include "libvarnish.h"
 #include "shmlog.h"
+#include "vre.h"
 #include "varnishapi.h"
 
 static int	b_flag, c_flag;
@@ -80,7 +80,7 @@ static enum shmlogtag   last[65536];
 #define F_MATCH		(1 << 1)
 
 static int		match_tag = -1;
-static regex_t		match_re;
+static vre		*match_re;
 
 static void
 h_order_finish(int fd)
@@ -116,6 +116,7 @@ h_order(void *priv, enum shmlogtag tag, unsigned fd, unsigned len,
     unsigned spec, const char *ptr)
 {
 	char type;
+	int ovector[30];
 
 	(void)priv;
 
@@ -132,7 +133,8 @@ h_order(void *priv, enum shmlogtag tag, unsigned fd, unsigned len,
 		assert(ob[fd] != NULL);
 	}
 	if (tag == match_tag &&
-	    !regexec(&match_re, ptr, 0, NULL, 0))
+	    VRE_exec(match_re, ptr, len, 0, 0, ovector,
+		     sizeof(ovector)/sizeof(ovector[0])) > 0)
 		flg[fd] |= F_MATCH;
 
 	if ((tag == SLT_BackendOpen || tag == SLT_SessionOpen ||
@@ -198,6 +200,8 @@ static void
 do_order(struct VSL_data *vd, int argc, char **argv)
 {
 	int i;
+	const char *error;
+	int erroroffset;
 
 	if (argc == 2) {
 		match_tag = name2tag(argv[0]);
@@ -205,11 +209,9 @@ do_order(struct VSL_data *vd, int argc, char **argv)
 			fprintf(stderr, "Tag \"%s\" unknown\n", argv[0]);
 			exit(2);
 		}
-		i = regcomp(&match_re, argv[1], REG_EXTENDED | REG_NOSUB);
-		if (i) {
-			char buf[BUFSIZ];
-			regerror(i, &match_re, buf, sizeof buf);
-			fprintf(stderr, "%s\n", buf);
+		match_re = VRE_compile(argv[1], 0, &error, &erroroffset);
+		if (match_re == NULL) {
+			fprintf(stderr, "Invalid regex: %s\n", error);
 			exit(2);
 		}
 	}
diff --git a/varnish-cache/configure.ac b/varnish-cache/configure.ac
index 5c2d67f..4fc88a5 100644
--- a/varnish-cache/configure.ac
+++ b/varnish-cache/configure.ac
@@ -75,6 +75,37 @@ AC_SUBST(NET_LIBS)
 AC_CHECK_LIBM
 AC_SUBST(LIBM)
 
+PKG_PROG_PKG_CONFIG
+if test -n $PKG_CONFIG; then
+   PKG_CHECK_MODULES([PCRE], [libpcre])
+else
+   AC_CHECK_PROG(PCRE_CONFIG, pcre-config, pcre-config)
+   AC_ARG_WITH(pcre-config,
+               AS_HELP_STRING([--with-pcre-config=PATH],
+                              [Location of PCRE pcre-config (auto)]),
+               [pcre_config="$withval"],
+               [pcre_config=""])
+
+  if test "x$pcre_config" != "x" ; then
+    AC_MSG_CHECKING(for $pcre_config)
+
+    if test -f $pcre_config ; then
+      PCRE_CONFIG=$pcre_config
+      AC_MSG_RESULT(yes)
+    else
+      AC_MSG_RESULT(no - searching PATH)
+    fi
+  fi
+  if test "x$PCRE_CONFIG" = "x"; then
+    AC_CHECK_PROGS(PCRE_CONFIG, pcre-config)
+  fi
+  PCRE_CFLAGS=`$PCRE_CONFIG --cflags`
+  PCRE_LIBS=`$PCRE_CONFIG --libs`
+fi
+AC_SUBST(PCRE_CFLAGS)
+AC_SUBST(PCRE_LIBS)
+
+
 # Checks for header files.
 AC_HEADER_STDC
 AC_HEADER_SYS_WAIT
diff --git a/varnish-cache/include/vre.h b/varnish-cache/include/vre.h
new file mode 100644
index 0000000..4cd7d2b
--- /dev/null
+++ b/varnish-cache/include/vre.h
@@ -0,0 +1,45 @@
+/*-
+ * Copyright (c) 2009 Redpill Linpro AS
+ * All rights reserved.
+ *
+ * Author: Tollef Fog Heen <tfh...@redpill-linpro.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ *
+ * Regular expression support
+ *
+ */
+
+struct vre;
+typedef struct vre vre;
+
+/* This maps to PCRE error codes */
+#define VRE_ERROR_NOMATCH         (-1)
+
+/* And those to PCRE options */
+#define VRE_CASELESS           0x00000001
+
+vre *VRE_compile(const char *, int, const char **, int *);
+int VRE_exec(const vre *, const char *, int, int, int, int *, int);
+void VRE_free(vre *);
diff --git a/varnish-cache/include/vrt.h b/varnish-cache/include/vrt.h
index 150db3c..17dbf25 100644
--- a/varnish-cache/include/vrt.h
+++ b/varnish-cache/include/vrt.h
@@ -136,7 +136,7 @@ struct vrt_ref {
 void VRT_acl_log(const struct sess *, const char *msg);
 
 /* Regexp related */
-void VRT_re_init(void **, const char *, int sub);
+void VRT_re_init(void **, const char *);
 void VRT_re_fini(void *);
 int VRT_re_match(const char *, void *re);
 const char *VRT_regsub(const struct sess *sp, int all, const char *,
diff --git a/varnish-cache/lib/libvarnish/Makefile.am b/varnish-cache/lib/libvarnish/Makefile.am
index a28a857..67aa572 100644
--- a/varnish-cache/lib/libvarnish/Makefile.am
+++ b/varnish-cache/lib/libvarnish/Makefile.am
@@ -1,6 +1,6 @@
 # $Id$
 
-INCLUDES = -I$(top_srcdir)/include
+INCLUDES = -I$(top_srcdir)/include @PCRE_CFLAGS@
 
 lib_LTLIBRARIES = libvarnish.la
 
@@ -23,12 +23,13 @@ libvarnish_la_SOURCES = \
 	vev.c \
 	vlu.c \
 	vpf.c \
+	vre.c \
 	vsb.c \
 	vsha256.c \
 	vss.c \
 	vtmpfile.c
 
-libvarnish_la_LIBADD = ${RT_LIBS} ${NET_LIBS} ${LIBM}
+libvarnish_la_LIBADD = ${RT_LIBS} ${NET_LIBS} ${LIBM} @PCRE_LIBS@
 
 DISTCLEANFILES = svn_version.c
 svn_version.c: FORCE
diff --git a/varnish-cache/lib/libvarnish/vre.c b/varnish-cache/lib/libvarnish/vre.c
new file mode 100644
index 0000000..2fc7926
--- /dev/null
+++ b/varnish-cache/lib/libvarnish/vre.c
@@ -0,0 +1,71 @@
+/*-
+ * Copyright (c) 2006-2009 Redpill Linpro AS
+ * All rights reserved.
+ *
+ * Author: Tollef Fog Heen <tfh...@redpill-linpro.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <pcre.h>
+
+#include "libvarnish.h"
+#include "miniobj.h"
+#include "vre.h"
+
+struct vre {
+	unsigned		magic;
+#define VRE_MAGIC		0xe83097dc
+	pcre *re;
+};
+
+vre *VRE_compile(const char *pattern, int options,
+		 const char **errptr, int *erroffset) {
+	vre *v;
+
+	ALLOC_OBJ(v, VRE_MAGIC);
+	AN(v);
+	v->re = pcre_compile(pattern, options, errptr, erroffset, NULL);
+	if (v->re == NULL) {
+		VRE_free(v);
+		return NULL;
+	}
+	return v;
+}
+
+int VRE_exec(const vre *code, const char *subject, int length,
+	     int startoffset, int options, int *ovector, int ovecsize) {
+	CHECK_OBJ_NOTNULL(code, VRE_MAGIC);
+
+	return pcre_exec(code->re, NULL, subject, length,
+			 startoffset, options, ovector, ovecsize);
+}
+
+void VRE_free(vre *v) {
+
+	CHECK_OBJ(v, VRE_MAGIC);
+	if (v == NULL)
+		return;
+	pcre_free(v->re);
+	v->magic = 0;
+	FREE_OBJ(v);
+}
diff --git a/varnish-cache/lib/libvarnishapi/shmlog.c b/varnish-cache/lib/libvarnishapi/shmlog.c
index 37be28a..4f2a848 100644
--- a/varnish-cache/lib/libvarnishapi/shmlog.c
+++ b/varnish-cache/lib/libvarnishapi/shmlog.c
@@ -40,13 +40,13 @@ SVNID("$Id$")
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
-#include <regex.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 #include <unistd.h>
 
 #include "shmlog.h"
+#include "vre.h"
 #include "miniobj.h"
 #include "varnishapi.h"
 
@@ -84,8 +84,8 @@ struct VSL_data {
 #define M_SELECT		(1 << 3)
 
 	int			regflags;
-	regex_t			*regincl;
-	regex_t			*regexcl;
+	vre			*regincl;
+	vre			*regexcl;
 
 	unsigned long		skip;
 	unsigned long		keep;
@@ -170,7 +170,7 @@ VSL_New(void)
 	assert(VSL_S_BACKEND == M_BACKEND);
 	vd = calloc(sizeof *vd, 1);
 	assert(vd != NULL);
-	vd->regflags = REG_EXTENDED | REG_NOSUB;
+	vd->regflags = 0;
 	vd->magic = VSL_MAGIC;
 	vd->fd = -1;
 	return (vd);
@@ -272,9 +272,9 @@ int
 VSL_NextLog(struct VSL_data *vd, unsigned char **pp)
 {
 	unsigned char *p;
-	regmatch_t rm;
 	unsigned u, l;
 	int i;
+	int ovector[30];
 
 	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
 	while (1) {
@@ -315,19 +315,21 @@ VSL_NextLog(struct VSL_data *vd, unsigned char **pp)
 		if (vd->c_opt && !(vd->map[u] & M_CLIENT))
 			continue;
 		if (vd->regincl != NULL) {
-			rm.rm_so = 0;
-			rm.rm_eo = l;
-			i = regexec(vd->regincl,
-			    (char *)p + SHMLOG_DATA, 1, &rm, 0);
-			if (i == REG_NOMATCH)
+			i = VRE_exec(vd->regincl,
+				     (char *)p + SHMLOG_DATA,
+				     SHMLOG_LEN(p) - SHMLOG_DATA, /* Length */
+				     0, 0, ovector,
+				     sizeof(ovector)/sizeof(ovector[0]));
+			if (i == VRE_ERROR_NOMATCH)
 				continue;
 		}
 		if (vd->regexcl != NULL) {
-			rm.rm_so = 0;
-			rm.rm_eo = l;
-			i = regexec(vd->regexcl,
-			    (char *)p + SHMLOG_DATA, 1, &rm, 0);
-			if (i != REG_NOMATCH)
+			i = VRE_exec(vd->regincl,
+				     (char *)p + SHMLOG_DATA,
+				     SHMLOG_LEN(p) - SHMLOG_DATA, /* Length */
+				     0, 0, ovector,
+				     sizeof(ovector)/sizeof(ovector[0]));
+			if (i != VRE_ERROR_NOMATCH)
 				continue;
 		}
 		*pp = p;
@@ -412,9 +414,9 @@ vsl_r_arg(struct VSL_data *vd, const char *opt)
 static int
 vsl_IX_arg(struct VSL_data *vd, const char *opt, int arg)
 {
-	int i;
-	regex_t **rp;
-	char buf[BUFSIZ];
+	vre **rp;
+	const char *error;
+	int erroroffset;
 
 	CHECK_OBJ_NOTNULL(vd, VSL_MAGIC);
 	if (arg == 'I')
@@ -425,15 +427,9 @@ vsl_IX_arg(struct VSL_data *vd, const char *opt, int arg)
 		fprintf(stderr, "Option %c can only be given once", arg);
 		return (-1);
 	}
-	*rp = calloc(sizeof(regex_t), 1);
+	*rp = VRE_compile(opt, vd->regflags, &error, &erroroffset);
 	if (*rp == NULL) {
-		perror("malloc");
-		return (-1);
-	}
-	i = regcomp(*rp, opt, vd->regflags);
-	if (i) {
-		regerror(i, *rp, buf, sizeof buf);
-		fprintf(stderr, "%s", buf);
+		fprintf(stderr, "Illegal regex: %s\n", error);
 		return (-1);
 	}
 	return (1);
@@ -547,7 +543,7 @@ VSL_Arg(struct VSL_data *vd, int arg, const char *opt)
 	case 'i': case 'x': return (vsl_ix_arg(vd, opt, arg));
 	case 'r': return (vsl_r_arg(vd, opt));
 	case 'I': case 'X': return (vsl_IX_arg(vd, opt, arg));
-	case 'C': vd->regflags = REG_ICASE; return (1);
+	case 'C': vd->regflags = VRE_CASELESS; return (1);
 	case 's': return (vsl_s_arg(vd, opt));
 	case 'k': return (vsl_k_arg(vd, opt));
 	default:
diff --git a/varnish-cache/lib/libvcl/vcc_compile.h b/varnish-cache/lib/libvcl/vcc_compile.h
index 256da13..be44bfb 100644
--- a/varnish-cache/lib/libvcl/vcc_compile.h
+++ b/varnish-cache/lib/libvcl/vcc_compile.h
@@ -198,7 +198,7 @@ unsigned vcc_UintVal(struct tokenlist *tl);
 double vcc_DoubleVal(struct tokenlist *tl);
 
 /* vcc_string.c */
-char *vcc_regexp(struct tokenlist *tl, int sub);
+char *vcc_regexp(struct tokenlist *tl);
 int vcc_StringVal(struct tokenlist *tl);
 void vcc_ExpectedStringval(struct tokenlist *tl);
 
diff --git a/varnish-cache/lib/libvcl/vcc_fixed_token.c b/varnish-cache/lib/libvcl/vcc_fixed_token.c
index baa9fa5..7901de5 100644
--- a/varnish-cache/lib/libvcl/vcc_fixed_token.c
+++ b/varnish-cache/lib/libvcl/vcc_fixed_token.c
@@ -276,7 +276,7 @@ vcl_output_lang_h(struct vsb *sb)
 	vsb_cat(sb, "#define VRT_ACL_MAXADDR\t\t16\t/* max(IPv4, IPv6) */\n");
 	vsb_cat(sb, "\nvoid VRT_acl_log(const struct sess *, const char *ms");
 	vsb_cat(sb, "g);\n\n/* Regexp related */\nvoid VRT_re_init(void **,");
-	vsb_cat(sb, " const char *, int sub);\nvoid VRT_re_fini(void *);\n");
+	vsb_cat(sb, " const char *);\nvoid VRT_re_fini(void *);\n");
 	vsb_cat(sb, "int VRT_re_match(const char *, void *re);\n");
 	vsb_cat(sb, "const char *VRT_regsub(const struct sess *sp, int all,");
 	vsb_cat(sb, " const char *,\n    void *, const char *);\n");
diff --git a/varnish-cache/lib/libvcl/vcc_parse.c b/varnish-cache/lib/libvcl/vcc_parse.c
index d6079f2..ef2b09a 100644
--- a/varnish-cache/lib/libvcl/vcc_parse.c
+++ b/varnish-cache/lib/libvcl/vcc_parse.c
@@ -225,7 +225,7 @@ Cond_String(const struct var *vp, struct tokenlist *tl)
 		     tl->t->tok == '~' ? "" : "!");
 		vcc_NextToken(tl);
 		ExpectErr(tl, CSTR);
-		p = vcc_regexp(tl, 0);
+		p = vcc_regexp(tl);
 		ERRCHK(tl);
 		vcc_NextToken(tl);
 		Fb(tl, 1, "%s, %s)\n", vp->rname, p);
diff --git a/varnish-cache/lib/libvcl/vcc_string.c b/varnish-cache/lib/libvcl/vcc_string.c
index 564e3da..900a8fd 100644
--- a/varnish-cache/lib/libvcl/vcc_string.c
+++ b/varnish-cache/lib/libvcl/vcc_string.c
@@ -34,7 +34,6 @@ SVNID("$Id$")
 
 #include <stdio.h>
 #include <string.h>
-#include <regex.h>
 
 #include "vsb.h"
 
@@ -43,30 +42,30 @@ SVNID("$Id$")
 #include "libvarnish.h"
 
 #include "vrt.h"
+#include "vre.h"
 
 /*--------------------------------------------------------------------*/
 
 char *
-vcc_regexp(struct tokenlist *tl, int sub)
+vcc_regexp(struct tokenlist *tl)
 {
 	char buf[BUFSIZ], *p;
-	regex_t	t;
-	int i;
+	vre *t;
+	const char *error;
+	int erroroffset;
 
 	Expect(tl, CSTR);
 	if (tl->err)
 		return (NULL);
 	memset(&t, 0, sizeof t);
-	i = regcomp(&t, tl->t->dec, REG_EXTENDED | (sub ? 0 : REG_NOSUB));
-	if (i != 0) {
-		(void)regerror(i, &t, buf, sizeof buf);
+	t = VRE_compile(tl->t->dec, 0, &error, &erroroffset);
+	if (t == NULL) {
 		vsb_printf(tl->sb,
-		    "Regexp compilation error:\n\n%s\n\n", buf);
+		    "Regexp compilation error:\n\n%s\n\n", error);
 		vcc_ErrWhere(tl, tl->t);
-		regfree(&t);
 		return (NULL);
 	}
-	regfree(&t);
+	VRE_free(t);
 	sprintf(buf, "VGC_re_%u", tl->recnt++);
 	p = TlAlloc(tl, strlen(buf) + 1);
 	strcpy(p, buf);
@@ -74,7 +73,7 @@ vcc_regexp(struct tokenlist *tl, int sub)
 	Fh(tl, 0, "static void *%s;\n", buf);
 	Fi(tl, 0, "\tVRT_re_init(&%s, ",buf);
 	EncToken(tl->fi, tl->t);
-	Fi(tl, 0, ", %d);\n", sub);
+	Fi(tl, 0, ");\n");
 	Ff(tl, 0, "\tVRT_re_fini(%s);\n", buf);
 	return (p);
 }
@@ -108,7 +107,7 @@ vcc_regsub(struct tokenlist *tl, int all)
 	Expect(tl, CSTR);
 	if (tl->err)
 		return (0);
-	p = vcc_regexp(tl, 1);
+	p = vcc_regexp(tl);
 	vcc_NextToken(tl);
 	Fb(tl, 0, ", %s, ", p);
 
_______________________________________________
varnish-dev mailing list
varnish-dev@projects.linpro.no
http://projects.linpro.no/mailman/listinfo/varnish-dev

Reply via email to