struct token *name;
};
-
static const char *
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");
}
*/
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;
*/
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;
}
/*--------------------------------------------------------------------
- * 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));
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++;
}
*/
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));
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")) {
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));