Commit 15b88e65 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Unify parsing of backends and directors.

Use table to dispatch director parsing.

Get trailing '}' into backend host ident string.




git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@2900 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent fe11c73b
......@@ -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++;
}
......@@ -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[];
......
......@@ -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));
......
......@@ -560,7 +560,7 @@ static struct toplev {
} toplev[] = {
{ "acl", vcc_Acl },
{ "sub", Function },
{ "backend", vcc_ParseBackend },
{ "backend", vcc_ParseDirector },
{ "director", vcc_ParseDirector },
{ NULL, NULL }
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment