r1281 - in trunk/varnish-cache: include lib/libvcl
phk at projects.linpro.no
phk at projects.linpro.no
Fri Mar 9 11:31:29 CET 2007
Author: phk
Date: 2007-03-09 11:31:29 +0100 (Fri, 09 Mar 2007)
New Revision: 1281
Modified:
trunk/varnish-cache/include/vcl.h
trunk/varnish-cache/include/vrt.h
trunk/varnish-cache/lib/libvcl/vcc_acl.c
trunk/varnish-cache/lib/libvcl/vcc_compile.c
trunk/varnish-cache/lib/libvcl/vcc_compile.h
trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c
trunk/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl
trunk/varnish-cache/lib/libvcl/vcc_token.c
trunk/varnish-cache/lib/libvcl/vcc_token_defs.h
Log:
Implement a facility for source file modularization in the VCL
compiler. The syntax is:
include "filename" ;
Unlike the C preprocessors #include directive, a VCL include can
appear anywhere in the sourcefile:
if {req.Cookie == include "cookie.vcl" ; || !req.Host } {
}
and have cookie.vcl contain just:
"8435398475983275293759843"
Technically this results in a change to how we account for source
code references in the counter/profile table as well, and as a result
the entire source code of the VCL program is now compiled into the
shared library for easy reference.
Modified: trunk/varnish-cache/include/vcl.h
===================================================================
--- trunk/varnish-cache/include/vcl.h 2007-03-08 10:09:18 UTC (rev 1280)
+++ trunk/varnish-cache/include/vcl.h 2007-03-09 10:31:29 UTC (rev 1281)
@@ -22,6 +22,10 @@
unsigned nref;
unsigned busy;
+ unsigned nsrc;
+ const char **srcname;
+ const char **srcbody;
+
void *priv;
vcl_init_f *init_func;
Modified: trunk/varnish-cache/include/vrt.h
===================================================================
--- trunk/varnish-cache/include/vrt.h 2007-03-08 10:09:18 UTC (rev 1280)
+++ trunk/varnish-cache/include/vrt.h 2007-03-09 10:31:29 UTC (rev 1281)
@@ -40,7 +40,8 @@
struct VCL_conf;
struct vrt_ref {
- unsigned file;
+ unsigned source;
+ unsigned offset;
unsigned line;
unsigned pos;
unsigned count;
Modified: trunk/varnish-cache/lib/libvcl/vcc_acl.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_acl.c 2007-03-08 10:09:18 UTC (rev 1280)
+++ trunk/varnish-cache/lib/libvcl/vcc_acl.c 2007-03-09 10:31:29 UTC (rev 1281)
@@ -120,14 +120,14 @@
mask = UintVal(tl);
}
Fc(tl, 1, "{ %u, %u, %u, ", not, mask, para);
- EncString(tl->fc, t);
+ EncToken(tl->fc, t);
Fc(tl, 0, ", \"");
if (para)
Fc(tl, 0, "(");
if (not)
Fc(tl, 0, "!");
Fc(tl, 0, "\\\"\" ");
- EncString(tl->fc, t);
+ EncToken(tl->fc, t);
Fc(tl, 0, " \"\\\"");
if (mask)
Fc(tl, 0, "/%u", mask);
Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_compile.c 2007-03-08 10:09:18 UTC (rev 1280)
+++ trunk/varnish-cache/lib/libvcl/vcc_compile.c 2007-03-09 10:31:29 UTC (rev 1281)
@@ -86,8 +86,8 @@
#include "libvcl.h"
static struct method method_tab[] = {
-#define VCL_RET_MAC(a,b,c,d)
-#define VCL_MET_MAC(a,b,c) { "vcl_"#a, "default_vcl_"#a, c },
+#define VCL_RET_MAC(l,U,b,n)
+#define VCL_MET_MAC(l,U,m) { "vcl_"#l, "default_vcl_"#l, m },
#include "vcl_returns.h"
#undef VCL_MET_MAC
#undef VCL_RET_MAC
@@ -170,23 +170,42 @@
/*--------------------------------------------------------------------*/
void
-EncString(struct vsb *sb, struct token *t)
+EncString(struct vsb *sb, const char *b, const char *e)
{
- const char *p;
- assert(t->tok == CSTR);
+ if (e == NULL)
+ e = strchr(b, '\0');
+
vsb_cat(sb, "\"");
- for (p = t->dec; *p != '\0'; p++) {
- if (*p == '\\' || *p == '"')
- vsb_printf(sb, "\\%c", *p);
- else if (isgraph(*p))
- vsb_printf(sb, "%c", *p);
- else
- vsb_printf(sb, "\\%03o", *p);
+ for (; b < e; b++) {
+ switch (*b) {
+ case '\\':
+ case '"':
+ vsb_printf(sb, "\\%c", *b);
+ break;
+ case '\n': vsb_printf(sb, "\\n"); break;
+ case '\t': vsb_printf(sb, "\\t"); break;
+ case '\r': vsb_printf(sb, "\\r"); break;
+ case ' ': vsb_printf(sb, " "); break;
+ default:
+ if (isgraph(*b))
+ vsb_printf(sb, "%c", *b);
+ else
+ vsb_printf(sb, "\\%03o", *b);
+ break;
+ }
}
vsb_cat(sb, "\"");
}
+void
+EncToken(struct vsb *sb, struct token *t)
+{
+
+ assert(t->tok == CSTR);
+ EncString(sb, t->dec, NULL);
+}
+
/*--------------------------------------------------------------------*/
static int
@@ -505,7 +524,7 @@
Fc(tl, 1, "VRT_re_match(%s, %s)\n", str, buf);
Fh(tl, 0, "void *%s;\n", buf);
Fi(tl, 0, "\tVRT_re_init(&%s, ",buf);
- EncString(tl->fi, re);
+ EncToken(tl->fi, re);
Fi(tl, 0, ");\n");
Ff(tl, 0, "\tVRT_re_fini(%s);\n", buf);
}
@@ -530,7 +549,7 @@
tl->t->tok == T_EQ ? "!" : "", vp->rname);
vcc_NextToken(tl);
ExpectErr(tl, CSTR);
- EncString(tl->fc, tl->t);
+ EncToken(tl->fc, tl->t);
Fc(tl, 0, ")\n");
vcc_NextToken(tl);
break;
@@ -974,7 +993,7 @@
ExpectErr(tl, CSTR);
t_host = tl->t;
Fc(tl, 1, "\t%s ", vp->lname);
- EncString(tl->fc, t_host);
+ EncToken(tl->fc, t_host);
Fc(tl, 0, ");\n");
vcc_NextToken(tl);
break;
@@ -982,7 +1001,7 @@
ExpectErr(tl, CSTR);
t_port = tl->t;
Fc(tl, 1, "\t%s ", vp->lname);
- EncString(tl->fc, t_port);
+ EncToken(tl->fc, t_port);
Fc(tl, 0, ");\n");
vcc_NextToken(tl);
break;
@@ -1282,32 +1301,39 @@
return (nerr);
}
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * Output the location/profiling table. For each counted token, we
+ * record source+line+charpos for the first character in the token.
+ */
static void
LocTable(struct tokenlist *tl)
{
struct token *t;
- unsigned fil, lin, pos;
+ unsigned lin, pos;
+ struct source *sp;
const char *p;
Fh(tl, 0, "#define VGC_NREFS %u\n", tl->cnt + 1);
Fh(tl, 0, "static struct vrt_ref VGC_ref[VGC_NREFS];\n");
Fc(tl, 0, "static struct vrt_ref VGC_ref[VGC_NREFS] = {\n");
- fil = 0;
lin = 1;
pos = 0;
- p = vcc_default_vcl_b;
+ sp = 0;
+ p = NULL;
TAILQ_FOREACH(t, &tl->tokens, list) {
if (t->cnt == 0)
continue;
+ assert(t->src != NULL);
+ if (t->src != sp) {
+ lin = 1;
+ pos = 0;
+ sp = t->src;
+ p = sp->b;
+ }
+ assert(sp != NULL);
+ assert(p != NULL);
for (;p < t->b; p++) {
- if (p == vcc_default_vcl_e) {
- p = tl->b;
- fil = 1;
- lin = 1;
- pos = 0;
- }
if (*p == '\n') {
lin++;
pos = 0;
@@ -1318,13 +1344,12 @@
pos++;
}
- Fc(tl, 0, " [%3u] = { %d, %4u, %3u, 0, \"%.*s\" },\n",
- t->cnt, fil, lin, pos + 1, PF(t));
+ Fc(tl, 0, " [%3u] = { %d, %8u, %4u, %3u, 0, \"%.*s\" },\n",
+ t->cnt, sp->idx, t->b - sp->b, lin, pos + 1, PF(t));
}
Fc(tl, 0, "};\n");
}
-
/*--------------------------------------------------------------------*/
static void
@@ -1352,7 +1377,24 @@
static void
EmitStruct(struct tokenlist *tl)
{
+ struct source *sp;
+ Fc(tl, 0, "\nconst char *srcname[%u] = {\n", tl->nsources);
+ TAILQ_FOREACH(sp, &tl->sources, list) {
+ Fc(tl, 0, "\t");
+ EncString(tl->fc, sp->name, NULL);
+ Fc(tl, 0, ",\n");
+ }
+ Fc(tl, 0, "};\n");
+
+ Fc(tl, 0, "\nconst char *srcbody[%u] = {\n", tl->nsources);
+ TAILQ_FOREACH(sp, &tl->sources, list) {
+ Fc(tl, 0, "\t");
+ EncString(tl->fc, sp->b, sp->e);
+ Fc(tl, 0, ",\n");
+ }
+ Fc(tl, 0, "};\n");
+
Fc(tl, 0, "\nstruct VCL_conf VCL_conf = {\n");
Fc(tl, 0, "\t.magic = VCL_CONF_MAGIC,\n");
Fc(tl, 0, "\t.init_func = VGC_Init,\n");
@@ -1360,6 +1402,9 @@
Fc(tl, 0, "\t.nbackend = %d,\n", tl->nbackend);
Fc(tl, 0, "\t.ref = VGC_ref,\n");
Fc(tl, 0, "\t.nref = VGC_NREFS,\n");
+ Fc(tl, 0, "\t.nsrc = %u,\n", tl->nsources);
+ Fc(tl, 0, "\t.srcname = srcname,\n");
+ Fc(tl, 0, "\t.srcbody = srcbody,\n");
#define VCL_RET_MAC(l,u,b,n)
#define VCL_MET_MAC(l,u,b) \
if (FindRefStr(tl, "vcl_" #l, R_FUNC)) { \
@@ -1377,10 +1422,112 @@
/*--------------------------------------------------------------------*/
-char *
-VCC_Compile(struct vsb *sb, const char *b, const char *e)
+static struct source *
+vcc_new_source(const char *b, const char *e, const char *name)
{
- struct tokenlist tokens;
+ struct source *sp;
+
+ if (e == NULL)
+ e = strchr(b, '\0');
+ sp = calloc(sizeof *sp, 1);
+ assert(sp != NULL);
+ sp->name = strdup(name);
+ sp->b = b;
+ sp->e = e;
+ return (sp);
+}
+
+static void
+vcc_destroy_source(struct source *sp)
+{
+
+ free(sp->name);
+ free(sp);
+}
+
+/*--------------------------------------------------------------------*/
+
+static struct source *
+vcc_file_source(struct vsb *sb, const char *fn)
+{
+ char *f;
+ int fd, i;
+ struct stat st;
+
+ fd = open(fn, O_RDONLY);
+ if (fd < 0) {
+ vsb_printf(sb, "Cannot open file '%s': %s\n",
+ fn, strerror(errno));
+ return (NULL);
+ }
+ assert(0 == fstat(fd, &st));
+ f = malloc(st.st_size + 1);
+ assert(f != NULL);
+ i = read(fd, f, st.st_size);
+ assert(i == st.st_size);
+ close(fd);
+ f[i] = '\0';
+ return (vcc_new_source(f, f + i, fn));
+}
+
+/*--------------------------------------------------------------------*/
+
+static void
+vcc_resolve_includes(struct tokenlist *tl)
+{
+ struct token *t, *t1, *t2;
+ struct source *sp;
+
+ TAILQ_FOREACH(t, &tl->tokens, list) {
+ if (t->tok != T_INCLUDE)
+ continue;
+
+ t1 = TAILQ_NEXT(t, list);
+ assert(t1 != NULL); /* There's always an EOI */
+ if (t1->tok != CSTR) {
+ vsb_printf(tl->sb,
+ "include not followed by string constant.\n");
+ vcc_ErrWhere(tl, t1);
+ return;
+ }
+ t2 = TAILQ_NEXT(t1, list);
+ assert(t2 != NULL); /* There's always an EOI */
+ if (t2->tok != ';') {
+ vsb_printf(tl->sb,
+ "include <string> not followed by semicolon.\n");
+ vcc_ErrWhere(tl, t1);
+ return;
+ }
+ assert(t2 != NULL);
+
+ sp = vcc_file_source(tl->sb, t1->dec);
+ if (sp == NULL) {
+ vcc_ErrWhere(tl, t1);
+ return;
+ }
+ TAILQ_INSERT_TAIL(&tl->sources, sp, list);
+ sp->idx = tl->nsources++;
+ tl->t = t2;
+ vcc_Lexer(tl, sp);
+
+ TAILQ_REMOVE(&tl->tokens, t, list);
+ TAILQ_REMOVE(&tl->tokens, t1, list);
+ TAILQ_REMOVE(&tl->tokens, t2, list);
+ vcc_FreeToken(t);
+ vcc_FreeToken(t1);
+ vcc_FreeToken(t2);
+ if (!tl->err)
+ vcc_resolve_includes(tl);
+ return;
+ }
+}
+
+/*--------------------------------------------------------------------*/
+
+static char *
+vcc_CompileSource(struct vsb *sb, struct source *sp)
+{
+ struct tokenlist tokens, *tl;
struct ref *r;
struct token *t;
FILE *fo;
@@ -1389,11 +1536,15 @@
int i;
memset(&tokens, 0, sizeof tokens);
- TAILQ_INIT(&tokens.tokens);
- TAILQ_INIT(&tokens.refs);
- TAILQ_INIT(&tokens.procs);
+ tl = &tokens;
+ TAILQ_INIT(&tl->tokens);
+ TAILQ_INIT(&tl->refs);
+ TAILQ_INIT(&tl->procs);
+ TAILQ_INIT(&tl->sources);
tokens.sb = sb;
+ tl->nsources = 0;
+
tokens.fc = vsb_new(NULL, NULL, 0, VSB_AUTOEXTEND);
assert(tokens.fc != NULL);
@@ -1406,38 +1557,52 @@
tokens.ff = vsb_new(NULL, NULL, 0, VSB_AUTOEXTEND);
assert(tokens.ff != NULL);
- Fh(&tokens, 0, "extern struct VCL_conf VCL_conf;\n");
+#define VCL_MET_MAC(l,U,m) \
+ tokens.fm_##l = vsb_new(NULL, NULL, 0, VSB_AUTOEXTEND); \
+ assert(tokens.fm_##l != NULL);
+#include "vcl_returns.h"
+#undef VCL_MET_MAC
- Fi(&tokens, 0, "\tVRT_alloc_backends(&VCL_conf);\n");
+ Fh(tl, 0, "extern struct VCL_conf VCL_conf;\n");
- tokens.b = b;
- if (e == NULL)
- e = strchr(b, '\0');
- assert(e != NULL);
- tokens.e = e;
- vcc_Lexer(&tokens, vcc_default_vcl_b, vcc_default_vcl_e);
- vcc_Lexer(&tokens, b, e);
- vcc_AddToken(&tokens, EOI, e, e);
+ Fi(tl, 0, "\tVRT_alloc_backends(&VCL_conf);\n");
+
+ TAILQ_INSERT_TAIL(&tl->sources, sp, list);
+ sp->idx = tl->nsources++;
+ vcc_Lexer(tl, sp);
if (tokens.err)
goto done;
- tokens.t = TAILQ_FIRST(&tokens.tokens);
- Parse(&tokens);
+
+ sp = vcc_new_source(vcc_default_vcl_b, vcc_default_vcl_e, "Default");
+ TAILQ_INSERT_TAIL(&tl->sources, sp, list);
+ sp->idx = tl->nsources++;
+ vcc_Lexer(tl, sp);
+ vcc_AddToken(tl, EOI, sp->e, sp->e);
if (tokens.err)
goto done;
- Consistency(&tokens);
+
+ vcc_resolve_includes(tl);
if (tokens.err)
goto done;
- LocTable(&tokens);
- Ff(&tokens, 0, "\tVRT_free_backends(&VCL_conf);\n");
+ tokens.t = TAILQ_FIRST(&tl->tokens);
+ Parse(tl);
+ if (tokens.err)
+ goto done;
+ Consistency(tl);
+ if (tokens.err)
+ goto done;
+ LocTable(tl);
- EmitInitFunc(&tokens);
+ Ff(tl, 0, "\tVRT_free_backends(&VCL_conf);\n");
- EmitFiniFunc(&tokens);
+ EmitInitFunc(tl);
- EmitStruct(&tokens);
+ EmitFiniFunc(tl);
- if (CheckRefs(&tokens))
+ EmitStruct(tl);
+
+ if (CheckRefs(tl))
goto done;
of = strdup("/tmp/vcl.XXXXXXXX");
@@ -1472,18 +1637,22 @@
}
done:
+#define VCL_MET_MAC(l,U,m) vsb_delete(tokens.fm_##l);
+#include "vcl_returns.h"
+#undef VCL_MET_MAC
+
/* Free References */
- while (!TAILQ_EMPTY(&tokens.refs)) {
- r = TAILQ_FIRST(&tokens.refs);
- TAILQ_REMOVE(&tokens.refs, r, list);
+ while (!TAILQ_EMPTY(&tl->refs)) {
+ r = TAILQ_FIRST(&tl->refs);
+ TAILQ_REMOVE(&tl->refs, r, list);
free(r);
}
/* Free Tokens */
- while (!TAILQ_EMPTY(&tokens.tokens)) {
- t = TAILQ_FIRST(&tokens.tokens);
- TAILQ_REMOVE(&tokens.tokens, t, list);
- free(t);
+ while (!TAILQ_EMPTY(&tl->tokens)) {
+ t = TAILQ_FIRST(&tl->tokens);
+ TAILQ_REMOVE(&tl->tokens, t, list);
+ vcc_FreeToken(t);
}
return (of);
}
@@ -1491,26 +1660,32 @@
/*--------------------------------------------------------------------*/
char *
+VCC_Compile(struct vsb *sb, const char *b, const char *e)
+{
+ struct source *sp;
+ char *r;
+
+ sp = vcc_new_source(b, e, "input");
+ if (sp == NULL)
+ return (NULL);
+ r = vcc_CompileSource(sb, sp);
+ vcc_destroy_source(sp);
+ return (r);
+}
+
+/*--------------------------------------------------------------------*/
+
+char *
VCC_CompileFile(struct vsb *sb, const char *fn)
{
- char *f, *r;
- int fd, i;
- struct stat st;
+ struct source *sp;
+ char *r;
- fd = open(fn, O_RDONLY);
- if (fd < 0) {
- vsb_printf(sb, "Cannot open file '%s': %s",
- fn, strerror(errno));
+ sp = vcc_file_source(sb, fn);
+ if (sp == NULL)
return (NULL);
- }
- assert(0 == fstat(fd, &st));
- f = malloc(st.st_size + 1);
- assert(f != NULL);
- i = read(fd, f, st.st_size);
- assert(i == st.st_size);
- f[i] = '\0';
- r = VCC_Compile(sb, f, NULL);
- free(f);
+ r = vcc_CompileSource(sb, sp);
+ vcc_destroy_source(sp);
return (r);
}
Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.h
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_compile.h 2007-03-08 10:09:18 UTC (rev 1280)
+++ trunk/varnish-cache/lib/libvcl/vcc_compile.h 2007-03-09 10:31:29 UTC (rev 1281)
@@ -34,23 +34,38 @@
#define INDENT 2
+struct source {
+ TAILQ_ENTRY(source) list;
+ char *name;
+ const char *b;
+ const char *e;
+ unsigned idx;
+};
+
struct token {
unsigned tok;
const char *b;
const char *e;
+ struct source *src;
TAILQ_ENTRY(token) list;
unsigned cnt;
char *dec;
};
+TAILQ_HEAD(tokenhead, token);
+
struct tokenlist {
- TAILQ_HEAD(, token) tokens;
- const char *b;
- const char *e;
+ struct tokenhead tokens;
+ TAILQ_HEAD(, source) sources;
+ unsigned nsources;
+ struct source *src;
struct token *t;
int indent;
unsigned cnt;
struct vsb *fc, *fh, *fi, *ff;
+#define VCL_MET_MAC(l,U,m) struct vsb *fm_##l;
+#include "vcl_returns.h"
+#undef VCL_MET_MAC
TAILQ_HEAD(, ref) refs;
struct vsb *sb;
int err;
@@ -138,7 +153,8 @@
unsigned UintVal(struct tokenlist *tl);
void AddDef(struct tokenlist *tl, struct token *t, enum ref_type type);
void AddRef(struct tokenlist *tl, struct token *t, enum ref_type type);
-void EncString(struct vsb *sb, struct token *t);
+void EncToken(struct vsb *sb, struct token *t);
+void EncString(struct vsb *sb, const char *b, const char *e);
/* vcc_obj.c */
@@ -153,10 +169,11 @@
void vcc__Expect(struct tokenlist *tl, unsigned tok, int line);
int vcc_Teq(struct token *t1, struct token *t2);
int vcc_IdIs(struct token *t, const char *p);
-void vcc_Lexer(struct tokenlist *tl, const char *b, const char *e);
+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);
void vcc_AddToken(struct tokenlist *tl, unsigned tok, const char *b, const char *e);
+void vcc_FreeToken(struct token *t);
#define ERRCHK(tl) do { if ((tl)->err) return; } while (0)
#define ErrInternal(tl) vcc__ErrInternal(tl, __func__, __LINE__)
Modified: trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c 2007-03-08 10:09:18 UTC (rev 1280)
+++ trunk/varnish-cache/lib/libvcl/vcc_fixed_token.c 2007-03-09 10:31:29 UTC (rev 1281)
@@ -242,6 +242,12 @@
*q = p + 6;
return (T_INSERT);
}
+ if (p[0] == 'i' && p[1] == 'n' && p[2] == 'c' &&
+ p[3] == 'l' && p[4] == 'u' && p[5] == 'd' &&
+ p[6] == 'e' && !isvar(p[7])) {
+ *q = p + 7;
+ return (T_INCLUDE);
+ }
if (p[0] == 'i' && p[1] == 'f' && !isvar(p[2])) {
*q = p + 2;
return (T_IF);
@@ -399,6 +405,7 @@
vcl_tnames[T_HASH] = "hash";
vcl_tnames[T_IF] = "if";
vcl_tnames[T_INC] = "++";
+ vcl_tnames[T_INCLUDE] = "include";
vcl_tnames[T_INCR] = "+=";
vcl_tnames[T_INSERT] = "insert";
vcl_tnames[T_LEQ] = "<=";
@@ -455,6 +462,10 @@
fputs(" unsigned nref;\n", f);
fputs(" unsigned busy;\n", f);
fputs("\n", f);
+ fputs(" unsigned nsrc;\n", f);
+ fputs(" const char **srcname;\n", f);
+ fputs(" const char **srcbody;\n", f);
+ fputs("\n", f);
fputs(" void *priv;\n", f);
fputs("\n", f);
fputs(" vcl_init_f *init_func;\n", f);
@@ -511,7 +522,8 @@
fputs("struct VCL_conf;\n", f);
fputs("\n", f);
fputs("struct vrt_ref {\n", f);
- fputs(" unsigned file;\n", f);
+ fputs(" unsigned source;\n", f);
+ fputs(" unsigned offset;\n", f);
fputs(" unsigned line;\n", f);
fputs(" unsigned pos;\n", f);
fputs(" unsigned count;\n", f);
Modified: trunk/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl 2007-03-08 10:09:18 UTC (rev 1280)
+++ trunk/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl 2007-03-09 10:31:29 UTC (rev 1281)
@@ -61,6 +61,8 @@
# Language keywords
#
set keywords {
+ include
+
if else elseif elsif
func proc sub
@@ -140,6 +142,10 @@
unsigned nref;
unsigned busy;
+ unsigned nsrc;
+ const char **srcname;
+ const char **srcbody;
+
void *priv;
vcl_init_f *init_func;
Modified: trunk/varnish-cache/lib/libvcl/vcc_token.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_token.c 2007-03-08 10:09:18 UTC (rev 1280)
+++ trunk/varnish-cache/lib/libvcl/vcc_token.c 2007-03-09 10:31:29 UTC (rev 1281)
@@ -70,20 +70,16 @@
{
unsigned lin, pos, x, y;
const char *p, *l, *f, *b, *e;
+ struct source *sp;
lin = 1;
pos = 0;
if (t->tok == METHOD)
return;
- 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;
- }
+ sp = t->src;
+ f = sp->name;
+ b = sp->b;
+ e = sp->e;
for (l = p = b; p < t->b; p++) {
if (*p == '\n') {
lin++;
@@ -266,27 +262,44 @@
t->tok = tok;
t->b = b;
t->e = e;
- TAILQ_INSERT_TAIL(&tl->tokens, t, list);
+ t->src = tl->src;
+ if (tl->t != NULL)
+ TAILQ_INSERT_AFTER(&tl->tokens, tl->t, t, list);
+ else
+ TAILQ_INSERT_TAIL(&tl->tokens, t, list);
tl->t = t;
if (0) {
fprintf(stderr, "[%s %.*s] ",
- vcl_tnames[tok],(int)(e - b), b);
+ vcl_tnames[tok], PF(t));
if (tok == EOI)
fprintf(stderr, "\n");
}
}
/*--------------------------------------------------------------------
+ * Free a token
+ */
+
+void
+vcc_FreeToken(struct token *t)
+{
+
+ /* XXX: more */
+ free(t);
+}
+
+/*--------------------------------------------------------------------
* Lexical analysis and token generation
*/
void
-vcc_Lexer(struct tokenlist *tl, const char *b, const char *e)
+vcc_Lexer(struct tokenlist *tl, struct source *sp)
{
const char *p, *q;
unsigned u;
- for (p = b; p < e; ) {
+ tl->src = sp;
+ for (p = sp->b; p < sp->e; ) {
/* Skip any whitespace */
if (isspace(*p)) {
@@ -296,7 +309,7 @@
/* Skip '#.*\n' comments */
if (*p == '#') {
- while (p < e && *p != '\n')
+ while (p < sp->e && *p != '\n')
p++;
continue;
}
@@ -304,7 +317,7 @@
/* Skip C-style comments */
if (*p == '/' && p[1] == '*') {
p += 2;
- for (p += 2; p < e; p++) {
+ for (p += 2; p < sp->e; p++) {
if (*p == '*' && p[1] == '/') {
p += 2;
break;
@@ -315,7 +328,7 @@
/* Skip C++-style comments */
if (*p == '/' && p[1] == '/') {
- while (p < e && *p != '\n')
+ while (p < sp->e && *p != '\n')
p++;
continue;
}
@@ -330,7 +343,7 @@
/* Match strings, with \\ and \" escapes */
if (*p == '"') {
- for (q = p + 1; q < e; q++) {
+ for (q = p + 1; q < sp->e; q++) {
if (*q == '"') {
q++;
break;
@@ -352,11 +365,11 @@
/* Match Identifiers */
if (isident1(*p)) {
- for (q = p; q < e; q++)
+ for (q = p; q < sp->e; q++)
if (!isident(*q))
break;
if (isvar(*q)) {
- for (; q < e; q++)
+ for (; q < sp->e; q++)
if (!isvar(*q))
break;
vcc_AddToken(tl, VAR, p, q);
@@ -369,7 +382,7 @@
/* Match numbers { [0-9]+ } */
if (isdigit(*p)) {
- for (q = p; q < e; q++)
+ for (q = p; q < sp->e; q++)
if (!isdigit(*q))
break;
vcc_AddToken(tl, CNUM, p, q);
Modified: trunk/varnish-cache/lib/libvcl/vcc_token_defs.h
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_token_defs.h 2007-03-08 10:09:18 UTC (rev 1280)
+++ trunk/varnish-cache/lib/libvcl/vcc_token_defs.h 2007-03-09 10:31:29 UTC (rev 1281)
@@ -7,47 +7,48 @@
*/
#define LOW_TOKEN 128
-#define T_IF 128
-#define T_ELSE 129
-#define T_ELSEIF 130
-#define T_ELSIF 131
-#define T_FUNC 132
-#define T_PROC 133
-#define T_SUB 134
-#define T_ACL 135
-#define T_BACKEND 136
-#define T_CALL 137
-#define T_NO_CACHE 138
-#define T_NO_NEW_CACHE 139
-#define T_SET 140
-#define T_REWRITE 141
-#define T_SWITCH_CONFIG 142
-#define T_ERROR 143
-#define T_LOOKUP 144
-#define T_HASH 145
-#define T_PIPE 146
-#define T_PASS 147
-#define T_FETCH 148
-#define T_INSERT 149
-#define T_DELIVER 150
-#define T_DISCARD 151
-#define T_INC 152
-#define T_DEC 153
-#define T_CAND 154
-#define T_COR 155
-#define T_LEQ 156
-#define T_EQ 157
-#define T_NEQ 158
-#define T_GEQ 159
-#define T_SHR 160
-#define T_SHL 161
-#define T_INCR 162
-#define T_DECR 163
-#define T_MUL 164
-#define T_DIV 165
-#define ID 166
-#define VAR 167
-#define CNUM 168
-#define CSTR 169
-#define EOI 170
-#define METHOD 171
+#define T_INCLUDE 128
+#define T_IF 129
+#define T_ELSE 130
+#define T_ELSEIF 131
+#define T_ELSIF 132
+#define T_FUNC 133
+#define T_PROC 134
+#define T_SUB 135
+#define T_ACL 136
+#define T_BACKEND 137
+#define T_CALL 138
+#define T_NO_CACHE 139
+#define T_NO_NEW_CACHE 140
+#define T_SET 141
+#define T_REWRITE 142
+#define T_SWITCH_CONFIG 143
+#define T_ERROR 144
+#define T_LOOKUP 145
+#define T_HASH 146
+#define T_PIPE 147
+#define T_PASS 148
+#define T_FETCH 149
+#define T_INSERT 150
+#define T_DELIVER 151
+#define T_DISCARD 152
+#define T_INC 153
+#define T_DEC 154
+#define T_CAND 155
+#define T_COR 156
+#define T_LEQ 157
+#define T_EQ 158
+#define T_NEQ 159
+#define T_GEQ 160
+#define T_SHR 161
+#define T_SHL 162
+#define T_INCR 163
+#define T_DECR 164
+#define T_MUL 165
+#define T_DIV 166
+#define ID 167
+#define VAR 168
+#define CNUM 169
+#define CSTR 170
+#define EOI 171
+#define METHOD 172
More information about the varnish-commit
mailing list