From b8d277b027fdeaa2f55011442f85b0677ffac3b8 Mon Sep 17 00:00:00 2001 From: phk Date: Tue, 8 Jul 2008 07:30:42 +0000 Subject: [PATCH] Unify parsing of backends and directors. Use table to dispatch director parsing. Get trailing '}' into backend host ident string. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@2900 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/lib/libvcl/vcc_backend.c | 106 ++++++++++++---------- varnish-cache/lib/libvcl/vcc_compile.h | 7 +- varnish-cache/lib/libvcl/vcc_dir_random.c | 14 +-- varnish-cache/lib/libvcl/vcc_parse.c | 2 +- 4 files changed, 66 insertions(+), 63 deletions(-) diff --git a/varnish-cache/lib/libvcl/vcc_backend.c b/varnish-cache/lib/libvcl/vcc_backend.c index f054dba3..1283f2fd 100644 --- a/varnish-cache/lib/libvcl/vcc_backend.c +++ b/varnish-cache/lib/libvcl/vcc_backend.c @@ -72,7 +72,6 @@ struct host { struct token *name; }; - static const char * CheckHostPort(const char *host, const char *port) { @@ -100,21 +99,25 @@ CheckHostPort(const char *host, const char *port) */ static void -vcc_EmitBeIdent(struct vsb *v, const struct token *name, const char *qual, int serial, const struct token *first, const struct token *last) +vcc_EmitBeIdent(struct vsb *v, const struct token *name, const struct token *qual, int serial, const struct token *first, const struct token *last) { - vsb_printf(v, "\t.ident ="); + AN(name); AN(qual); - vsb_printf(v, "\n\t \"%s %.*s\"", qual, PF(name)); - if (serial != 0) - vsb_printf(v, "\n\t \"[%d]\"", serial); - while (first != last) { + assert(first != last); + vsb_printf(v, "\t.ident ="); + vsb_printf(v, "\n\t \"%.*s %.*s [%d] \"", + PF(qual), PF(name), serial); + while (1) { if (first->dec != NULL) vsb_printf(v, "\n\t \"\\\"\" %.*s \"\\\" \"", PF(first)); else vsb_printf(v, "\n\t \"%.*s \"", PF(first)); + if (first == last) + break; first = VTAILQ_NEXT(first, list); + AN(first); } vsb_printf(v, ",\n"); } @@ -232,7 +235,7 @@ vcc_FieldsOk(struct tokenlist *tl, const struct fld_spec *fs) */ static void -vcc_ParseHostDef(struct tokenlist *tl, int *nbh, const struct token *name, const char *qual, int serial) +vcc_ParseHostDef(struct tokenlist *tl, int *nbh, const struct token *name, const struct token *qual, int serial) { struct token *t_field; struct token *t_first; @@ -347,7 +350,7 @@ vcc_ParseHostDef(struct tokenlist *tl, int *nbh, const struct token *name, const */ void -vcc_ParseBackendHost(struct tokenlist *tl, int *nbh, const struct token *name, const char *qual, int serial) +vcc_ParseBackendHost(struct tokenlist *tl, int *nbh, const struct token *name, const struct token *qual, int serial) { struct host *h; struct token *t; @@ -390,39 +393,22 @@ vcc_ParseBackendHost(struct tokenlist *tl, int *nbh, const struct token *name, c } /*-------------------------------------------------------------------- - * Parse a plain backend + * Parse a plain backend aka a simple director */ -void -vcc_ParseBackend(struct tokenlist *tl) +static void +vcc_ParseSimpleDirector(struct tokenlist *tl, const struct token *t_first, struct token *t_dir) { struct host *h; h = TlAlloc(tl, sizeof *h); + h->name = t_dir; - vcc_NextToken(tl); - - vcc_ExpectCid(tl); /* ID: name */ + vcc_ParseHostDef(tl, &h->hnum, h->name, t_first, 0); ERRCHK(tl); - h->name = tl->t; - vcc_NextToken(tl); - - vcc_ParseHostDef(tl, &h->hnum, h->name, "backend", 0); - if (tl->err) { - vsb_printf(tl->sb, - "\nIn backend specfication starting at:\n"); - vcc_ErrWhere(tl, h->name); - return; - } 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->ndirector); - - vcc_AddDef(tl, h->name, R_BACKEND); - Fi(tl, 0, "\tVRT_init_dir_simple(cli, &VGC_backend_%.*s , &sbe_%.*s);\n", PF(h->name), PF(h->name)); @@ -434,42 +420,68 @@ vcc_ParseBackend(struct tokenlist *tl) Fc(tl, 0, "\t.host = &bh_%d,\n", h->hnum); Fc(tl, 0, "};\n"); - tl->ndirector++; } /*-------------------------------------------------------------------- - * Parse directors + * Parse directors and backends */ +static const struct dirlist { + const char *name; + parsedirector_f *func; +} dirlist[] = { + { "random", vcc_ParseRandomDirector }, + { NULL, NULL } +}; + void vcc_ParseDirector(struct tokenlist *tl) { - struct token *t_dir, *t_first; + struct token *t_dir, *t_first, *t_policy; + struct dirlist const *dl; t_first = tl->t; - vcc_NextToken(tl); /* ID: director */ + vcc_NextToken(tl); /* ID: director | backend */ vcc_ExpectCid(tl); /* ID: name */ ERRCHK(tl); t_dir = tl->t; vcc_NextToken(tl); - ExpectErr(tl, ID); /* ID: policy */ - if (vcc_IdIs(tl->t, "random")) - vcc_ParseRandomDirector(tl, t_dir); - else { - vsb_printf(tl->sb, "Unknown director policy: "); - vcc_ErrToken(tl, tl->t); - vsb_printf(tl->sb, " at\n"); - vcc_ErrWhere(tl, tl->t); - return; + Fh(tl, 1, "\n#define VGC_backend_%.*s (VCL_conf.director[%d])\n", + PF(t_dir), tl->ndirector); + vcc_AddDef(tl, t_dir, R_BACKEND); + tl->ndirector++; + + if (vcc_IdIs(t_first, "backend")) { + vcc_ParseSimpleDirector(tl, t_first, t_dir); + } else { + ExpectErr(tl, ID); /* ID: policy */ + t_policy = tl->t; + vcc_NextToken(tl); + + for (dl = dirlist; dl->name != NULL; dl++) + if (vcc_IdIs(t_policy, dl->name)) + break; + if (dl->name == NULL) { + vsb_printf(tl->sb, "Unknown director policy: "); + vcc_ErrToken(tl, t_policy); + vsb_printf(tl->sb, " at\n"); + vcc_ErrWhere(tl, t_policy); + return; + } + ExpectErr(tl, '{'); + vcc_NextToken(tl); + dl->func(tl, t_policy, t_dir); + if (!tl->err) { + ExpectErr(tl, '}'); + vcc_NextToken(tl); + } } if (tl->err) { vsb_printf(tl->sb, - "\nIn director specfication starting at:\n", - PF(t_first)); + "\nIn %.*s specfication starting at:\n", PF(t_first)); vcc_ErrWhere(tl, t_first); return; } - tl->ndirector++; } diff --git a/varnish-cache/lib/libvcl/vcc_compile.h b/varnish-cache/lib/libvcl/vcc_compile.h index a852c133..4fff65bc 100644 --- a/varnish-cache/lib/libvcl/vcc_compile.h +++ b/varnish-cache/lib/libvcl/vcc_compile.h @@ -153,13 +153,14 @@ void vcc_ParseAction(struct tokenlist *tl); /* vcc_backend.c */ struct fld_spec; -void vcc_ParseBackend(struct tokenlist *tl); +typedef void parsedirector_f(struct tokenlist *tl, const struct token *t_policy, const struct token *t_dir); + void vcc_ParseDirector(struct tokenlist *tl); +void vcc_ParseBackendHost(struct tokenlist *tl, int *nbr, const struct token *name, const struct token *qual, int serial); struct fld_spec * vcc_FldSpec(struct tokenlist *tl, const char *first, ...); void vcc_ResetFldSpec(struct fld_spec *f); void vcc_IsField(struct tokenlist *tl, struct token **t, struct fld_spec *fs); void vcc_FieldsOk(struct tokenlist *tl, const struct fld_spec *fs); -void vcc_ParseBackendHost(struct tokenlist *tl, int *nbr, const struct token *name, const char *qual, int serial); /* vcc_compile.c */ extern struct method method_tab[]; @@ -174,7 +175,7 @@ void TlFree(struct tokenlist *tl, void *p); void *TlAlloc(struct tokenlist *tl, unsigned len); /* vcc_dir_random.c */ -void vcc_ParseRandomDirector(struct tokenlist *tl, struct token *t_dir); +parsedirector_f vcc_ParseRandomDirector; /* vcc_obj.c */ extern struct var vcc_vars[]; diff --git a/varnish-cache/lib/libvcl/vcc_dir_random.c b/varnish-cache/lib/libvcl/vcc_dir_random.c index effe9a41..43fa15f5 100644 --- a/varnish-cache/lib/libvcl/vcc_dir_random.c +++ b/varnish-cache/lib/libvcl/vcc_dir_random.c @@ -50,24 +50,15 @@ */ void -vcc_ParseRandomDirector(struct tokenlist *tl, struct token *t_dir) +vcc_ParseRandomDirector(struct tokenlist *tl, const struct token *t_policy, const struct token *t_dir) { struct token *t_field, *t_be; int nbh, nelem; struct fld_spec *fs; unsigned u; - Fh(tl, 1, "\n#define VGC_backend_%.*s (VCL_conf.director[%d])\n", - PF(t_dir), tl->ndirector); - vcc_AddDef(tl, t_dir, R_BACKEND); - fs = vcc_FldSpec(tl, "!backend", "!weight", NULL); - vcc_NextToken(tl); /* ID: policy (= random) */ - - ExpectErr(tl, '{'); - vcc_NextToken(tl); - Fc(tl, 0, "\nstatic const struct vrt_dir_random_entry vdre_%.*s[] = {\n", PF(t_dir)); @@ -86,7 +77,7 @@ vcc_ParseRandomDirector(struct tokenlist *tl, struct token *t_dir) ERRCHK(tl); if (vcc_IdIs(t_field, "backend")) { vcc_ParseBackendHost(tl, &nbh, - t_dir, "random", nelem); + t_dir, t_policy, nelem); Fc(tl, 0, " .host = &bh_%d,", nbh); ERRCHK(tl); } else if (vcc_IdIs(t_field, "weight")) { @@ -127,7 +118,6 @@ vcc_ParseRandomDirector(struct tokenlist *tl, struct token *t_dir) Fc(tl, 0, "\t.nmember = %d,\n", nelem); Fc(tl, 0, "\t.members = vdre_%.*s,\n", PF(t_dir)); Fc(tl, 0, "};\n"); - vcc_NextToken(tl); Fi(tl, 0, "\tVRT_init_dir_random(cli, &VGC_backend_%.*s , &vdr_%.*s);\n", PF(t_dir), PF(t_dir)); diff --git a/varnish-cache/lib/libvcl/vcc_parse.c b/varnish-cache/lib/libvcl/vcc_parse.c index 69f88853..c3c88f25 100644 --- a/varnish-cache/lib/libvcl/vcc_parse.c +++ b/varnish-cache/lib/libvcl/vcc_parse.c @@ -560,7 +560,7 @@ static struct toplev { } toplev[] = { { "acl", vcc_Acl }, { "sub", Function }, - { "backend", vcc_ParseBackend }, + { "backend", vcc_ParseDirector }, { "director", vcc_ParseDirector }, { NULL, NULL } }; -- 2.39.5