From e8856aac3e6a46469202221c3720b5b8c08594d1 Mon Sep 17 00:00:00 2001 From: phk Date: Tue, 10 Jul 2007 20:43:24 +0000 Subject: [PATCH] Add compiler side support for regsub() but only a dummy function in VRT. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@1666 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/cache_vrt_re.c | 19 ++++-- varnish-cache/include/vrt.h | 5 +- varnish-cache/lib/libvcl/vcc_compile.h | 1 + varnish-cache/lib/libvcl/vcc_fixed_token.c | 5 +- varnish-cache/lib/libvcl/vcc_parse.c | 28 +-------- varnish-cache/lib/libvcl/vcc_string.c | 71 ++++++++++++++++++++++ 6 files changed, 96 insertions(+), 33 deletions(-) diff --git a/varnish-cache/bin/varnishd/cache_vrt_re.c b/varnish-cache/bin/varnishd/cache_vrt_re.c index fc61b85e..6fa2b651 100644 --- a/varnish-cache/bin/varnishd/cache_vrt_re.c +++ b/varnish-cache/bin/varnishd/cache_vrt_re.c @@ -45,14 +45,14 @@ #include "cache.h" void -VRT_re_init(void **rep, const char *re) +VRT_re_init(void **rep, const char *re, int sub) { regex_t *t; t = calloc(sizeof *t, 1); XXXAN(t); /* This was already check-compiled by the VCL compiler */ - AZ(regcomp(t, re, REG_EXTENDED | REG_NOSUB)); + AZ(regcomp(t, re, REG_EXTENDED | (sub ? 0 : REG_NOSUB))); *rep = t; } @@ -82,14 +82,14 @@ VRT_re_match(const char *s, void *re) } int -VRT_re_test(struct vsb *sb, const char *re) +VRT_re_test(struct vsb *sb, const char *re, int sub) { int i; regex_t t; char buf[BUFSIZ]; memset(&t, 0, sizeof t); - i = regcomp(&t, re, REG_EXTENDED | REG_NOSUB); + i = regcomp(&t, re, REG_EXTENDED | (sub ? 0 : REG_NOSUB)); if (i == 0) { regfree(&t); return (0); @@ -99,3 +99,14 @@ VRT_re_test(struct vsb *sb, const char *re) regfree(&t); return (1); } + +char * +VRT_regsub(struct sess *sp, const char *str, void *re, const char *sub) +{ + static char foo[4] = "FOO"; + (void)sp; + (void)str; + (void)re; + (void)sub; + return (foo); +} diff --git a/varnish-cache/include/vrt.h b/varnish-cache/include/vrt.h index 0a45732b..6dbf869a 100644 --- a/varnish-cache/include/vrt.h +++ b/varnish-cache/include/vrt.h @@ -64,10 +64,11 @@ 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_init(void **, const char *, int sub); void VRT_re_fini(void *); int VRT_re_match(const char *, void *re); -int VRT_re_test(struct vsb *, const char *); +int VRT_re_test(struct vsb *, const char *, int sub); +char *VRT_regsub(struct sess *sp, const char *, void *, const char *); void VRT_count(struct sess *, unsigned); int VRT_rewrite(const char *, const char *); diff --git a/varnish-cache/lib/libvcl/vcc_compile.h b/varnish-cache/lib/libvcl/vcc_compile.h index bd7d6425..dd0da275 100644 --- a/varnish-cache/lib/libvcl/vcc_compile.h +++ b/varnish-cache/lib/libvcl/vcc_compile.h @@ -168,6 +168,7 @@ unsigned vcc_UintVal(struct tokenlist *tl); double vcc_DoubleVal(struct tokenlist *tl); /* vcc_string.c */ +char *vcc_regexp(struct tokenlist *tl, int sub); 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 a4fb3f74..9d606baf 100644 --- a/varnish-cache/lib/libvcl/vcc_fixed_token.c +++ b/varnish-cache/lib/libvcl/vcc_fixed_token.c @@ -420,10 +420,11 @@ vcl_output_lang_h(struct vsb *sb) vsb_cat(sb, "void VRT_acl_fini(struct vrt_acl *);\n"); vsb_cat(sb, "\n"); vsb_cat(sb, "/* Regexp related */\n"); - vsb_cat(sb, "void VRT_re_init(void **, const char *);\n"); + vsb_cat(sb, "void VRT_re_init(void **, const char *, int sub);\n"); vsb_cat(sb, "void VRT_re_fini(void *);\n"); vsb_cat(sb, "int VRT_re_match(const char *, void *re);\n"); - vsb_cat(sb, "int VRT_re_test(struct vsb *, const char *);\n"); + vsb_cat(sb, "int VRT_re_test(struct vsb *, const char *, int sub);\n"); + vsb_cat(sb, "char *VRT_regsub(struct sess *sp, const char *, void *, const char *);\n"); vsb_cat(sb, "\n"); vsb_cat(sb, "void VRT_count(struct sess *, unsigned);\n"); vsb_cat(sb, "int VRT_rewrite(const char *, const char *);\n"); diff --git a/varnish-cache/lib/libvcl/vcc_parse.c b/varnish-cache/lib/libvcl/vcc_parse.c index a0860d0d..efba57cd 100644 --- a/varnish-cache/lib/libvcl/vcc_parse.c +++ b/varnish-cache/lib/libvcl/vcc_parse.c @@ -218,41 +218,19 @@ vcc_RateVal(struct tokenlist *tl) Fb(tl, 0, "(%g * %g)", v, sc); } -/*--------------------------------------------------------------------*/ - -static void -vcc_re(struct tokenlist *tl, const char *str, const struct token *re) -{ - char buf[32]; - - assert(re->tok == CSTR); - if (VRT_re_test(tl->sb, re->dec)) { - vcc_ErrWhere(tl, re); - return; - } - sprintf(buf, "VGC_re_%u", tl->recnt++); - - Fb(tl, 1, "VRT_re_match(%s, %s)\n", str, buf); - Fh(tl, 0, "void *%s;\n", buf); - Fi(tl, 0, "\tVRT_re_init(&%s, ",buf); - EncToken(tl->fi, re); - Fi(tl, 0, ");\n"); - Ff(tl, 0, "\tVRT_re_fini(%s);\n", buf); -} - - /*--------------------------------------------------------------------*/ static void Cond_String(const struct var *vp, struct tokenlist *tl) { + char *p; switch (tl->t->tok) { case '~': vcc_NextToken(tl); - ExpectErr(tl, CSTR); - vcc_re(tl, vp->rname, tl->t); + p = vcc_regexp(tl, 0); vcc_NextToken(tl); + Fb(tl, 1, "VRT_re_match(%s, %s)\n", vp->rname, p); break; case T_EQ: case T_NEQ: diff --git a/varnish-cache/lib/libvcl/vcc_string.c b/varnish-cache/lib/libvcl/vcc_string.c index ec7723d4..6ec7a6a5 100644 --- a/varnish-cache/lib/libvcl/vcc_string.c +++ b/varnish-cache/lib/libvcl/vcc_string.c @@ -38,6 +38,75 @@ #include "vcc_compile.h" #include "libvarnish.h" +#include "vrt.h" + +/*--------------------------------------------------------------------*/ + +char * +vcc_regexp(struct tokenlist *tl, int sub) +{ + char buf[32], *p; + + Expect(tl, CSTR); + if (VRT_re_test(tl->sb, tl->t->dec, sub)) { + vcc_ErrWhere(tl, tl->t); + return (NULL); + } + sprintf(buf, "VGC_re_%u", tl->recnt++); + p = TlAlloc(tl, strlen(buf) + 1); + strcpy(p, buf); + + Fh(tl, 0, "void *%s;\n", buf); + Fi(tl, 0, "\tVRT_re_init(&%s, ",buf); + EncToken(tl->fi, tl->t); + Fi(tl, 0, ", %d);\n", sub); + Ff(tl, 0, "\tVRT_re_fini(%s);\n", buf); + return (p); +} + +/*--------------------------------------------------------------------*/ + +static int +vcc_regsub(struct tokenlist *tl) +{ + char *p; + + vcc_NextToken(tl); + + Fb(tl, 0, "VRT_regsub(sp, "); + + Expect(tl, '('); + vcc_NextToken(tl); + + if (!vcc_StringVal(tl)) { + vcc_ExpectedStringval(tl); + return (0); + } + + Expect(tl, ','); + vcc_NextToken(tl); + + Expect(tl, CSTR); + p = vcc_regexp(tl, 1); + vcc_NextToken(tl); + Fb(tl, 0, ", %s, ", p); + + Expect(tl, ','); + vcc_NextToken(tl); + + Expect(tl, CSTR); + if (!vcc_StringVal(tl)) { + vcc_ExpectedStringval(tl); + return (0); + } + + Expect(tl, ')'); + vcc_NextToken(tl); + Fb(tl, 0, ")"); + + return (1); +} + /*-------------------------------------------------------------------- * Parse a string value and emit something that results in a usable * "const char *". @@ -57,6 +126,8 @@ vcc_StringVal(struct tokenlist *tl) vcc_NextToken(tl); return (1); } + if (tl->t->tok == ID && vcc_IdIs(tl->t, "regsub")) + return (vcc_regsub(tl)); if (tl->t->tok == VAR) { vp = vcc_FindVar(tl, tl->t, vcc_vars); if (tl->err) -- 2.39.5