For now we default to REG_EXTENDED, but it might make sense
to let the user control this flag and the case sensitivity.
Another concern is the stringification of regexps, it may lead
to backslash madness. Maybe we should define '...' string types
also and do no backslash substitution in those at all.
git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@559
d4fa192b-c00b-0410-8231-
f00ffab90ce4
cache_vcl.c \
cache_vrt.c \
cache_vrt_acl.c \
+ cache_vrt_re.c \
cli_event.c \
hash_simple_list.c \
hash_classic.c \
--- /dev/null
+/*
+ * $Id$
+ *
+ * Runtime support for compiled VCL programs, regexps
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <regex.h>
+
+#include "shmlog.h"
+#include "vrt.h"
+#include "vrt_obj.h"
+#include "sbuf.h"
+#include "vcl.h"
+#include "cache.h"
+
+void
+VRT_re_init(void **rep, const char *re)
+{
+ regex_t *t;
+ int i;
+
+ t = calloc(sizeof *t, 1);
+ assert(t != NULL);
+ i = regcomp(t, re, REG_EXTENDED | REG_NOSUB);
+ assert(i == 0);
+ *rep = t;
+}
+
+void
+VRT_re_fini(void *rep)
+{
+
+ if (rep != NULL)
+ regfree(rep);
+}
+
+int
+VRT_re_match(const char *s, void *re)
+{
+ regex_t *t;
+ int i;
+
+ t = re;
+ i = regexec(t, s, 0, NULL, 0);
+ if (i == 0)
+ return (1);
+ assert(i == REG_NOMATCH);
+ return (0);
+}
+
+int
+VRT_re_test(struct sbuf *sb, const char *re)
+{
+ int i, j;
+ regex_t t;
+ char buf[BUFSIZ];
+
+ memset(&t, 0, sizeof t);
+ i = regcomp(&t, re, REG_EXTENDED | REG_NOSUB);
+ if (i == 0) {
+ regfree(&t);
+ return (0);
+ }
+ j = regerror(i, &t, buf, sizeof buf);
+ sbuf_printf(sb, "Regexp compilation error:\n\n%s\n\n", buf);
+ regfree(&t);
+ return (1);
+}
*/
struct sess;
+struct sbuf;
struct backend;
struct VCL_conf;
void VRT_acl_init(struct vrt_acl *);
void VRT_acl_fini(struct vrt_acl *);
+/* Regexp related */
+void VRT_re_init(void **, const char *);
+void VRT_re_fini(void *);
+int VRT_re_match(const char *, void *re);
+int VRT_re_test(struct sbuf *, const char *);
+
void VRT_count(struct sess *, unsigned);
int VRT_rewrite(const char *, const char *);
void VRT_error(struct sess *, unsigned, const char *);
#include "vcc_priv.h"
#include "vcc_compile.h"
+#include "vrt.h"
#include "libvcl.h"
static struct method method_tab[] = {
Fc(tl, 0, "(%g * %g)", v, sc);
}
+/*--------------------------------------------------------------------*/
+
+static void
+vcc_re(struct tokenlist *tl, const char *str, struct token *re)
+{
+ char buf[32], *p;
+
+ p = EncString(re);
+ if (VRT_re_test(tl->sb, p)) {
+ vcc_ErrWhere(tl, re);
+ return;
+ }
+ free(p);
+ sprintf(buf, "VGC_re_%u", tl->recnt++);
+
+ Fc(tl, 1, "VRT_re_match(%s, %s)\n", str, buf);
+ Fh(tl, 0, "void *%s;\n", buf);
+ Fi(tl, 0, "\tVRT_re_init(&%s, %T);\n", buf, re);
+ Ff(tl, 0, "\tVRT_re_fini(%s);\n", buf);
+}
+
+
/*--------------------------------------------------------------------*/
static void
switch (tl->t->tok) {
case '~':
- Fc(tl, 1, "string_match(%s, ", vp->rname);
vcc_NextToken(tl);
ExpectErr(tl, CSTR);
- Fc(tl, 0, "%T)\n", tl->t);
+ vcc_re(tl, vp->rname, tl->t);
vcc_NextToken(tl);
break;
case T_EQ:
int nbackend;
TAILQ_HEAD(, proc) procs;
struct proc *curproc;
+
+ unsigned recnt;
};
enum var_type {
fputs(" */\n", f);
fputs("\n", f);
fputs("struct sess;\n", f);
+ fputs("struct sbuf;\n", f);
fputs("struct backend;\n", f);
fputs("struct VCL_conf;\n", f);
fputs("\n", f);
fputs("void VRT_acl_init(struct vrt_acl *);\n", f);
fputs("void VRT_acl_fini(struct vrt_acl *);\n", f);
fputs("\n", f);
+ fputs("/* Regexp related */\n", f);
+ fputs("void VRT_re_init(void **, const char *);\n", f);
+ fputs("void VRT_re_fini(void *);\n", f);
+ fputs("int VRT_re_match(const char *, void *re);\n", f);
+ fputs("int VRT_re_test(struct sbuf *, const char *);\n", f);
+ fputs("\n", f);
fputs("void VRT_count(struct sess *, unsigned);\n", f);
fputs("int VRT_rewrite(const char *, const char *);\n", f);
fputs("void VRT_error(struct sess *, unsigned, const char *);\n", f);