]> err.no Git - varnish/commitdiff
Teach the VCL compiler about default functions, so that users will
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Wed, 12 Jul 2006 08:34:48 +0000 (08:34 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Wed, 12 Jul 2006 08:34:48 +0000 (08:34 +0000)
not have to copy&paste the default methods if they have no special
requirements for a particular method.

No such facility exists for backends, so a backend description is
now the minumum VCL program.

When we initialize the VCL compiler we hand it a piece of source code
with the "default code", this must include definitions of all methods
named with a "default_" prefix (ie: "default_vcl_recv" etc).

During compilation we always compile this piece of source code in (after
the user supplied VCL source).

If the user did not provide a particular method, the default method is
used instead.  The user can also call the default method directly,
for instance by:

sub vcl_recv {
if (req.http.Expect) {
error;
}
call default_vcl_recv;
}

Later on, this could be expanded to allow other subroutines to be
included in the default VCL for the users calling convenience.

git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@449 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishd/varnishd.c
varnish-cache/include/libvcl.h
varnish-cache/lib/libvcl/vcl_compile.c

index d732126755edb9830c4476dc7c4391951669cfe1..8315532bed6360bcdfc65c7fb6fbf560a2d3511e 100644 (file)
 
 /*--------------------------------------------------------------------*/
 
+static const char *default_vcl =
+    "sub default_vcl_recv {\n"
+    "    if (req.request != \"GET\" && req.request != \"HEAD\") {\n"
+    "        pipe;\n"
+    "    }\n"
+    "    if (req.http.Expect) {\n"
+    "        pipe;\n"
+    "    }\n"
+    "    if (req.http.Authenticate || req.http.Cookie) {\n"
+    "        pass;\n"
+    "    }\n"
+    "    lookup;\n"
+    "}\n"
+    "\n"
+    "sub default_vcl_hit {\n"
+    "    if (!obj.cacheable) {\n"
+    "        pass;\n"
+    "    }\n"
+    "    deliver;\n"
+    "}\n"
+    "\n"
+    "sub default_vcl_miss {\n"
+    "    fetch;\n"
+    "}\n"
+    "\n"
+    "sub default_vcl_fetch {\n"
+    "    if (!obj.valid) {\n"
+    "        error;\n"
+    "    }\n"
+    "    if (!obj.cacheable) {\n"
+    "        pass;\n"
+    "    }\n"
+    "    insert;\n"
+    "}\n"
+    "sub default_vcl_timeout {\n"
+    "    discard;\n"
+    "}\n";
+
+/*--------------------------------------------------------------------*/
+
 struct heritage heritage;
 struct event_base *mgt_eb;
 
@@ -90,44 +130,7 @@ vcl_default(const char *bflag)
            "backend default {\n"
            "    set backend.host = \"%*.*s\";\n"
            "    set backend.port = \"%s\";\n"
-           "}\n"
-           "sub vcl_recv {\n"
-           "    if (req.request != \"GET\" && req.request != \"HEAD\") {\n"
-           "        pipe;\n"
-           "    }\n"
-           "    if (req.http.Expect) {\n"
-           "        pipe;\n"
-           "    }\n"
-           "    if (req.http.Authenticate || req.http.Cookie) {\n"
-           "        pass;\n"
-           "    }\n"
-           "    lookup;\n"
-           "}\n"
-           "\n"
-           "sub vcl_hit {\n"
-           "    if (!obj.cacheable) {\n"
-           "        pass;\n"
-           "    }\n"
-           "    deliver;\n"
-           "}\n"
-           "\n"
-           "sub vcl_miss {\n"
-           "    fetch;\n"
-           "}\n"
-           "\n"
-           "sub vcl_fetch {\n"
-           "    if (!obj.valid) {\n"
-           "        error;\n"
-           "    }\n"
-           "    if (!obj.cacheable) {\n"
-           "        pass;\n"
-           "    }\n"
-           "    insert;\n"
-           "}\n"
-           "sub vcl_timeout {\n"
-           "    discard;\n"
-           "}\n"
-           "", p - bflag, p - bflag, bflag, q);
+           "}\n", p - bflag, p - bflag, bflag, q);
        assert(buf != NULL);
        sb = sbuf_new(NULL, NULL, 0, SBUF_AUTOEXTEND);
        assert(sb != NULL);
@@ -243,6 +246,9 @@ static void
 m_cli_func_exit(struct cli *cli, char **av, void *priv)
 {
 
+       (void)cli;
+       (void)av;
+       (void)priv;
        mgt_child_kill();
        exit (0);
 }
@@ -503,7 +509,7 @@ main(int argc, char *argv[])
        setbuf(stdout, NULL);
        setbuf(stderr, NULL);
  
-       VCC_InitCompile();
+       VCC_InitCompile(default_vcl);
 
        heritage.default_ttl = 120;
        heritage.wthread_min = 1;
index 65e1fa7a35553709b4dcb05f44db2174b32791d6..3c17e3a1cf668e117d802a18885cc033e3f21321 100644 (file)
@@ -4,6 +4,6 @@
 
 char *VCC_Compile(struct sbuf *sb, const char *b, const char *e);
 char *VCC_CompileFile(struct sbuf *sb, const char *fn);
-void VCC_InitCompile(void);
+void VCC_InitCompile(const char *default_vcl);
 
 
index ad38491581885bc7a38f220e577b729275ac677f..546136114719a923eaf067520ea42e3de592dd57 100644 (file)
@@ -128,10 +128,11 @@ struct var {
 
 static struct method {
        const char              *name;
+       const char              *defname;
        unsigned                returns;
 } method_tab[] = {
 #define VCL_RET_MAC(a,b,c)
-#define VCL_MET_MAC(a,b,c)     { "vcl_"#a, c },
+#define VCL_MET_MAC(a,b,c)     { "vcl_"#a, "default_vcl_"#a, c },
 #include "vcl_returns.h"
 #undef VCL_MET_MAC
 #undef VCL_RET_MAC
@@ -195,6 +196,7 @@ static void Compound(struct tokenlist *tl);
 static void Cond_0(struct tokenlist *tl);
 static struct proc *AddProc(struct tokenlist *tl, struct token *t, int def);
 static void AddCall(struct tokenlist *tl, struct token *t);
+static const char *vcc_default_vcl_b, *vcc_default_vcl_e;
 
 /*--------------------------------------------------------------------*/
 
@@ -223,13 +225,22 @@ static void
 ErrWhere(struct tokenlist *tl, struct token *t)
 {
        unsigned lin, pos, x, y;
-       const char *p, *l;
+       const char *p, *l, *f, *b, *e;
        
        lin = 1;
        pos = 0;
        if (t->tok == METHOD)
                return;
-       for (l = p = tl->b; p < t->b; p++) {
+       if (t->b >= vcc_default_vcl_b && t->b < vcc_default_vcl_e) {
+               f = "Default VCL code (compiled in)";
+               b = vcc_default_vcl_b;
+               e = vcc_default_vcl_e;
+       } else {
+               f = "VCL code";
+               b = tl->b;
+               e = tl->e;
+       }
+       for (l = p = b; p < t->b; p++) {
                if (*p == '\n') {
                        lin++;
                        pos = 0;
@@ -240,9 +251,9 @@ ErrWhere(struct tokenlist *tl, struct token *t)
                } else
                        pos++;
        }
-       sbuf_printf(tl->sb, "Line %d Pos %d\n", lin, pos);
+       sbuf_printf(tl->sb, "In %s Line %d Pos %d\n", f, lin, pos);
        x = y = 0;
-       for (p = l; p < tl->e && *p != '\n'; p++) {
+       for (p = l; p < e && *p != '\n'; p++) {
                if (*p == '\t') {
                        y &= ~7;
                        y += 8;
@@ -258,7 +269,7 @@ ErrWhere(struct tokenlist *tl, struct token *t)
        }
        sbuf_cat(tl->sb, "\n");
        x = y = 0;
-       for (p = l; p < tl->e && *p != '\n'; p++) {
+       for (p = l; p < e && *p != '\n'; p++) {
                if (p >= t->b && p < t->e) {
                        sbuf_bcat(tl->sb, "#", 1);
                        x++;
@@ -452,6 +463,20 @@ FindRef(struct tokenlist *tl, struct token *t, enum ref_type type)
        return (r);
 }
 
+static int
+FindRefStr(struct tokenlist *tl, const char *s, enum ref_type type)
+{
+       struct ref *r;
+
+       TAILQ_FOREACH(r, &tl->refs, list) {
+               if (r->type != type)
+                       continue;
+               if (IdIs(r->name, s))
+                       return (1);
+       }
+       return (0);
+}
+
 static void
 AddRef(struct tokenlist *tl, struct token *t, enum ref_type type)
 {
@@ -1381,8 +1406,13 @@ AddToken(struct tokenlist *tl, unsigned tok, const char *b, const char *e)
        t->e = e;
        TAILQ_INSERT_TAIL(&tl->tokens, t, list);
        tl->t = t;
-       if (0)
-               fprintf(stderr, "+ %s\n", vcl_tnames[tok]);
+       if (0) {
+               fprintf(stderr, "[%s %*.*s] ",
+                   vcl_tnames[tok],
+                   e - b, e - b, b);
+               if (tok == EOI)
+                       fprintf(stderr, "\n");
+       }
 }
 
 /*--------------------------------------------------------------------
@@ -1478,8 +1508,6 @@ Lexer(struct tokenlist *tl, const char *b, const char *e)
                ErrWhere(tl, tl->t);
                return;
        }
-       /* Add End Of Input token */
-       AddToken(tl, EOI, p, p);
 }
 
 /*--------------------------------------------------------------------
@@ -1575,6 +1603,8 @@ Consistency(struct tokenlist *tl)
 
        TAILQ_FOREACH(p, &tl->procs, list) {
                for(m = method_tab; m->name != NULL; m++) {
+                       if (IdIs(p->name, m->defname))
+                               p->called = 1;
                        if (IdIs(p->name, m->name))
                                break;
                }
@@ -1722,8 +1752,13 @@ EmitStruct(struct tokenlist *tl)
        Fc(tl, 0, "\t.nref = VGC_NREFS,\n");
 #define VCL_RET_MAC(l,u,b)
 #define VCL_MET_MAC(l,u,b) \
-       Fc(tl, 0, "\t." #l "_func = VGC_function_vcl_" #l ",\n"); \
-       AddRefStr(tl, "vcl_" #l, R_FUNC);
+       if (FindRefStr(tl, "vcl_" #l, R_FUNC)) { \
+               Fc(tl, 0, "\t." #l "_func = VGC_function_vcl_" #l ",\n"); \
+               AddRefStr(tl, "vcl_" #l, R_FUNC); \
+       } else { \
+               Fc(tl, 0, "\t." #l "_func = VGC_function_default_vcl_" #l ",\n"); \
+       } \
+       AddRefStr(tl, "default_vcl_" #l, R_FUNC);
 #include "vcl_returns.h"
 #undef VCL_MET_MAC
 #undef VCL_RET_MAC
@@ -1762,6 +1797,8 @@ VCC_Compile(struct sbuf *sb, const char *b, const char *e)
        assert(e != NULL);
        tokens.e = e;
        Lexer(&tokens, b, e);
+       Lexer(&tokens, vcc_default_vcl_b, vcc_default_vcl_e);
+       AddToken(&tokens, EOI, e, e);
        if (tokens.err)
                goto done;
        tokens.t = TAILQ_FIRST(&tokens.tokens);
@@ -1870,10 +1907,14 @@ VCC_T_arginfo(const struct printf_info *info __unused, size_t n, int *argtypes)
 /*--------------------------------------------------------------------*/
 
 void
-VCC_InitCompile(void)
+VCC_InitCompile(const char *default_vcl)
 {
        struct var *v;
 
+       vcc_default_vcl_b = default_vcl;
+       vcc_default_vcl_e = strchr(default_vcl, '\0');
+       assert(vcc_default_vcl_e != NULL);
+       
        register_printf_function ('T', VCC_T_render, VCC_T_arginfo);
        vcl_init_tnames();
        for (v = vars; v->name != NULL; v++)