]> err.no Git - varnish/commitdiff
More polishing of backend compilation.
authorphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 7 Jul 2008 21:01:25 +0000 (21:01 +0000)
committerphk <phk@d4fa192b-c00b-0410-8231-f00ffab90ce4>
Mon, 7 Jul 2008 21:01:25 +0000 (21:01 +0000)
git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2889 d4fa192b-c00b-0410-8231-f00ffab90ce4

varnish-cache/bin/varnishtest/tests/v00002.vtc
varnish-cache/lib/libvcl/vcc_action.c
varnish-cache/lib/libvcl/vcc_backend.c
varnish-cache/lib/libvcl/vcc_compile.c
varnish-cache/lib/libvcl/vcc_compile.h
varnish-cache/lib/libvcl/vcc_dir_random.c
varnish-cache/lib/libvcl/vcc_token.c
varnish-cache/lib/libvcl/vcc_xref.c

index 17fc064f248ae102017d9ad0c5df5bcd621e3830..db1f91c02d51957cf223683c4106db416ec3ac50 100644 (file)
@@ -2,6 +2,20 @@
 
 test "VCL: test syntax/semantic checks on backend decls."
 
+# Missing backend
+varnish v1 -badvcl {
+}
+
+# Reference to non-existent backend
+varnish v1 -badvcl {
+       backend b1 {
+               .host = "localhost";
+       }
+       sub vcl_recv {
+               set req.backend = b2;
+       }
+}
+
 # Missing .host
 varnish v1 -badvcl {
        backend b1 {
@@ -44,3 +58,23 @@ varnish v1 -badvcl {
                { .weight = 1; .backend = 3745; }  // Brownie points for getting the joke
        }
 }
+
+# Check backend reference by name
+varnish v1 -badvcl {
+       backend b1 { .host = "127.0.0.2"; }
+       backend b2 b1;
+}
+
+# Check backend reference by non-C-compat name
+varnish v1 -badvcl {
+       backend b-1 { .host = "127.0.0.2"; }
+}
+
+# Assign backend by non-C-compat name
+# Check backend reference by non-C-compat name
+varnish v1 -badvcl {
+       backend b1 { .host = "127.0.0.2"; }
+       sub vcl_recv {
+               set req.backend = b-1;
+       }
+}
index ae8940b73a67271a27a859559d8fa3fe543c93a1..f419490641f47037a846fd212af0c96a24c4f2d1 100644 (file)
@@ -221,6 +221,8 @@ parse_set(struct tokenlist *tl)
                        return;
                }
                vcc_NextToken(tl);
+               vcc_ExpectCid(tl);
+               ERRCHK(tl);
                vcc_AddRef(tl, tl->t, R_BACKEND);
                Fb(tl, 0, "VGC_backend_%.*s", PF(tl->t));
                vcc_NextToken(tl);
index 01472f0e3d24ce337fa277a14cdb307eae561c6a..70fba9c5812f84743af17368a4ea1a8176710a6f 100644 (file)
  * SUCH DAMAGE.
  *
  * $Id$
+ *
+ * A necessary explanation of a convoluted policy:
+ *
+ * In VCL we have backends and directors.
+ *
+ * In VRT we have directors which reference (a number of) backend hosts.
+ *
+ * A VCL backend therefore has an implicit director of type "simple" created
+ * by the compiler, but not visible in VCL.
+ *
+ * A VCL backend is a "named host", these can be referenced by name form
+ * VCL directors, but not from VCL backends.
+ *
+ * The reason for this quasimadness is that we want to collect statistics
+ * for each actual kickable hardware backend machine, but we want to be
+ * able to refer to them multiple times in different directors.
+ *
+ * At the same time, we do not want to force users to declare each backend
+ * host with a name, if all they want to do is put it into a director, so
+ * backend hosts can be declared inline in the director, in which case
+ * its identity is the director and its numerical index therein.
  */
 
 #include "config.h"
 #include "vcc_compile.h"
 #include "libvarnish.h"
 
+struct host {
+       VTAILQ_ENTRY(host)      list;
+       int                     hnum;
+       struct token            *name;
+};
+
+
 static const char *
 CheckHostPort(const char *host, const char *port)
 {
@@ -365,25 +393,24 @@ void
 vcc_ParseBackend(struct tokenlist *tl)
 {
        struct host *h;
-       int nbh;
 
        h = TlAlloc(tl, sizeof *h);
 
        vcc_NextToken(tl);
 
-       ExpectErr(tl, ID);              /* name */
+       vcc_ExpectCid(tl);              /* ID: name */
+       ERRCHK(tl);
        h->name = tl->t;
        vcc_NextToken(tl);
 
-       vcc_ParseHostDef(tl, &nbh, h->name, "backend", 0);
+       vcc_ParseHostDef(tl, &h->hnum, h->name, "backend", 0);
        ERRCHK(tl);
 
-       h->hnum = nbh;
        VTAILQ_INSERT_TAIL(&tl->hosts, h, list);
 
        /* In the compiled vcl we use these macros to refer to backends */
        Fh(tl, 1, "\n#define VGC_backend_%.*s (VCL_conf.director[%d])\n",
-           PF(h->name), tl->nbackend);
+           PF(h->name), tl->ndirector);
 
        vcc_AddDef(tl, h->name, R_BACKEND);
 
@@ -395,10 +422,10 @@ vcc_ParseBackend(struct tokenlist *tl)
        Fc(tl, 0, "\nstatic const struct vrt_dir_simple sbe_%.*s = {\n",
            PF(h->name));
        Fc(tl, 0, "\t.name = \"%.*s\",\n", PF(h->name));
-       Fc(tl, 0, "\t.host = &bh_%d,\n", nbh);
+       Fc(tl, 0, "\t.host = &bh_%d,\n", h->hnum);
        Fc(tl, 0, "};\n");
 
-       tl->nbackend++;
+       tl->ndirector++;
 }
 
 /*--------------------------------------------------------------------
@@ -413,7 +440,8 @@ vcc_ParseDirector(struct tokenlist *tl)
        t_first = tl->t;
        vcc_NextToken(tl);              /* ID: director */
 
-       ExpectErr(tl, ID);              /* ID: name */
+       vcc_ExpectCid(tl);              /* ID: name */
+       ERRCHK(tl);
        t_dir = tl->t;
        vcc_NextToken(tl);
 
@@ -434,5 +462,5 @@ vcc_ParseDirector(struct tokenlist *tl)
                vcc_ErrWhere(tl, t_first);
                return;
        }
-       tl->nbackend++;
+       tl->ndirector++;
 }
index d55eae7f957a14ee30da0af72aed99d25b7733bd..58d339c46bcaa64cf9c1c86c2edfa770616e2a2e 100644 (file)
@@ -341,13 +341,14 @@ EmitStruct(const struct tokenlist *tl)
        }
        Fc(tl, 0, "};\n");
 
-       Fc(tl, 0, "\nstatic struct director\t*directors[%d];\n", tl->nbackend);
+       Fc(tl, 0, "\nstatic struct director\t*directors[%d];\n",
+           tl->ndirector);
 
        Fc(tl, 0, "\nconst struct VCL_conf VCL_conf = {\n");
        Fc(tl, 0, "\t.magic = VCL_CONF_MAGIC,\n");
        Fc(tl, 0, "\t.init_func = VGC_Init,\n");
        Fc(tl, 0, "\t.fini_func = VGC_Fini,\n");
-       Fc(tl, 0, "\t.ndirector = %d,\n", tl->nbackend);
+       Fc(tl, 0, "\t.ndirector = %d,\n", tl->ndirector);
        Fc(tl, 0, "\t.director = directors,\n");
        Fc(tl, 0, "\t.ref = VGC_ref,\n");
        Fc(tl, 0, "\t.nref = VGC_NREFS,\n");
@@ -596,9 +597,10 @@ vcc_CompileSource(struct vsb *sb, struct source *sp)
                return (vcc_DestroyTokenList(tl, NULL));
 
        /* Check if we have any backends at all */
-       if (tl->nbackend == 0) {
+       if (tl->ndirector == 0) {
                vsb_printf(tl->sb,
-                   "No backends in VCL program, at least one is necessary.\n");
+                   "No backends or directors found in VCL program, "
+                   "at least one is necessary.\n");
                tl->err = 1;
                return (vcc_DestroyTokenList(tl, NULL));
        }
index fddbeaa87d0c0dd47b15ba2bf3103632e39d2ded..3f800cfc59bb1ef4ae7094ffc227ddf40fdf4852 100644 (file)
@@ -59,12 +59,6 @@ struct token {
        char                    *dec;
 };
 
-struct host {
-       VTAILQ_ENTRY(host)      list;
-       unsigned                hnum;
-       struct token            *name;
-};
-
 VTAILQ_HEAD(tokenhead, token);
 
 struct tokenlist {
@@ -86,7 +80,7 @@ struct tokenlist {
        struct vsb              *sb;
        int                     err;
        int                     nbackend_host;
-       int                     nbackend;
+       int                     ndirector;
        VTAILQ_HEAD(, proc)     procs;
        struct proc             *curproc;
        struct proc             *mprocs[N_METHODS];
@@ -205,6 +199,8 @@ void vcc_ErrWhere(struct tokenlist *tl, const struct token *t);
 void vcc__Expect(struct tokenlist *tl, unsigned tok, int line);
 int vcc_Teq(const struct token *t1, const struct token *t2);
 int vcc_IdIs(const struct token *t, const char *p);
+int vcc_isCid(struct token *t);
+void vcc_ExpectCid(struct tokenlist *tl);
 void vcc_Lexer(struct tokenlist *tl, struct source *sp);
 void vcc_NextToken(struct tokenlist *tl);
 void vcc__ErrInternal(struct tokenlist *tl, const char *func, unsigned line);
index 6cd9de1be36b3fda8c14a897e30f7713e5b2dc7e..2525a1c4dab983fac1b88e620b4cbf08353ba78e 100644 (file)
@@ -58,7 +58,7 @@ vcc_ParseRandomDirector(struct tokenlist *tl, struct token *t_dir)
        unsigned u;
 
        Fh(tl, 1, "\n#define VGC_backend_%.*s (VCL_conf.director[%d])\n",
-           PF(t_dir), tl->nbackend);
+           PF(t_dir), tl->ndirector);
        vcc_AddDef(tl, t_dir, R_BACKEND);
 
        fs = vcc_FldSpec(tl, "!backend", "!weight", NULL);
index b716033fa97dd2ed92ddf74c06e10d80aaf463be..b13dca4f94281f49039db220e86b7464d566e135 100644 (file)
@@ -187,6 +187,38 @@ vcc_IdIs(const struct token *t, const char *p)
        return (1);
 }
 
+/*--------------------------------------------------------------------
+ * Check that we have a C-identifier
+ */
+
+int
+vcc_isCid(struct token *t)
+{
+       const char *q;
+
+       assert(t->tok == ID);
+       for (q = t->b; q < t->e; q++) {
+               if (!isalnum(*q) && *q != '_') 
+                       return (0);
+       }
+       return (1);
+}
+
+void
+vcc_ExpectCid(struct tokenlist *tl)
+{
+
+       ExpectErr(tl, ID);
+       ERRCHK(tl);
+       if (vcc_isCid(tl->t))
+               return;
+       vsb_printf(tl->sb, "Identifier ");
+       vcc_ErrToken(tl, tl->t);
+       vsb_printf(tl->sb,
+           " contains illegal characters, use [0-9a-zA-Z_] only.\n");
+       vcc_ErrWhere(tl, tl->t);
+}
+
 /*--------------------------------------------------------------------
  * Decode %xx in a string
  */
index ab2be5ac37c758481728649de2a8189a9d97711e..21c324a304d1d29c98dfefec664abef560885d38 100644 (file)
@@ -143,7 +143,7 @@ vcc_AddDef(struct tokenlist *tl, struct token *t, enum ref_type type)
        r->name = t;
 
        /* The first backend is the default and thus has an implicit ref */
-       if (type == R_BACKEND && tl->nbackend == 0)
+       if (type == R_BACKEND && tl->ndirector == 0)
                r->refcnt++;
 }