From 0fda6d38dd48bc2c95df50fd380b89767476bf8f Mon Sep 17 00:00:00 2001 From: phk Date: Sat, 24 Mar 2007 22:09:53 +0000 Subject: [PATCH] Twist the compiler logic around a bit. Concatenate all definitions of the method functions into one instance of the function: sub vcl_pipe { foo; } sub vcl_pipe { bar; } is now the same as sub vcl_pipe { foo; bar; } This avoids all the magic related to the default functions and hopefully makes the newly introduced "include" facility much more useful. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@1284 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/bin/varnishd/mgt_vcc.c | 16 +- varnish-cache/include/vcl_returns.h | 1 + varnish-cache/lib/libvcl/vcc_compile.c | 114 ++++++------ varnish-cache/lib/libvcl/vcc_compile.h | 12 +- .../lib/libvcl/vcc_gen_fixed_token.tcl | 3 + varnish-cache/lib/libvcl/vcc_parse.c | 172 ++++++++---------- 6 files changed, 157 insertions(+), 161 deletions(-) diff --git a/varnish-cache/bin/varnishd/mgt_vcc.c b/varnish-cache/bin/varnishd/mgt_vcc.c index 301c0147..0e01241a 100644 --- a/varnish-cache/bin/varnishd/mgt_vcc.c +++ b/varnish-cache/bin/varnishd/mgt_vcc.c @@ -66,7 +66,7 @@ static TAILQ_HEAD(, vclprog) vclhead = TAILQ_HEAD_INITIALIZER(vclhead); /* keep this in synch with man/vcl.7 */ static const char *default_vcl = - "sub default_vcl_recv {\n" + "sub vcl_recv {\n" " if (req.request != \"GET\" && req.request != \"HEAD\") {\n" " pipe;\n" " }\n" @@ -79,30 +79,30 @@ static const char *default_vcl = " lookup;\n" "}\n" "\n" - "sub default_vcl_pipe {\n" + "sub vcl_pipe {\n" " pipe;\n" "}\n" "\n" - "sub default_vcl_pass {\n" + "sub vcl_pass {\n" " pass;\n" "}\n" "\n" - "sub default_vcl_hash {\n" + "sub vcl_hash {\n" " hash;\n" "}\n" "\n" - "sub default_vcl_hit {\n" + "sub vcl_hit {\n" " if (!obj.cacheable) {\n" " pass;\n" " }\n" " deliver;\n" "}\n" "\n" - "sub default_vcl_miss {\n" + "sub vcl_miss {\n" " fetch;\n" "}\n" "\n" - "sub default_vcl_fetch {\n" + "sub vcl_fetch {\n" " if (!obj.valid) {\n" " error;\n" " }\n" @@ -114,7 +114,7 @@ static const char *default_vcl = " }\n" " insert;\n" "}\n" - "sub default_vcl_timeout {\n" + "sub vcl_timeout {\n" " discard;\n" "}\n"; diff --git a/varnish-cache/include/vcl_returns.h b/varnish-cache/include/vcl_returns.h index 59fcc657..b3b057dd 100644 --- a/varnish-cache/include/vcl_returns.h +++ b/varnish-cache/include/vcl_returns.h @@ -41,3 +41,4 @@ VCL_MET_MAC(hit,HIT,(VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_DELIVER)) VCL_MET_MAC(fetch,FETCH,(VCL_RET_ERROR|VCL_RET_PASS|VCL_RET_INSERT)) VCL_MET_MAC(timeout,TIMEOUT,(VCL_RET_FETCH|VCL_RET_DISCARD)) #endif +#define N_METHODS 8 diff --git a/varnish-cache/lib/libvcl/vcc_compile.c b/varnish-cache/lib/libvcl/vcc_compile.c index 4d9c6b21..dfc4163d 100644 --- a/varnish-cache/lib/libvcl/vcc_compile.c +++ b/varnish-cache/lib/libvcl/vcc_compile.c @@ -87,7 +87,7 @@ static struct method method_tab[] = { #define VCL_RET_MAC(l,U,b,n) -#define VCL_MET_MAC(l,U,m) { "vcl_"#l, "default_vcl_"#l, m }, +#define VCL_MET_MAC(l,U,m) { "vcl_"#l, m }, #include "vcl_returns.h" #undef VCL_MET_MAC #undef VCL_RET_MAC @@ -96,7 +96,21 @@ static struct method method_tab[] = { /*--------------------------------------------------------------------*/ -const char *vcc_default_vcl_b, *vcc_default_vcl_e; +static const char *vcc_default_vcl_b, *vcc_default_vcl_e; + +/*--------------------------------------------------------------------*/ + +int +IsMethod(struct token *t) +{ + struct method *m; + + for(m = method_tab; m->name != NULL; m++) { + if (vcc_IdIs(t, m->name)) + return (m - method_tab); + } + return (-1); +} /*-------------------------------------------------------------------- * Printf output to the two vsbs, possibly indented @@ -114,6 +128,19 @@ Fh(struct tokenlist *tl, int indent, const char *fmt, ...) va_end(ap); } +void +Fb(struct tokenlist *tl, int indent, const char *fmt, ...) +{ + va_list ap; + + assert(tl->fb != NULL); + if (indent) + vsb_printf(tl->fb, "%*.*s", tl->indent, tl->indent, ""); + va_start(ap, fmt); + vsb_vprintf(tl->fb, fmt, ap); + va_end(ap); +} + void Fc(struct tokenlist *tl, int indent, const char *fmt, ...) { @@ -152,8 +179,8 @@ Ff(struct tokenlist *tl, int indent, const char *fmt, ...) /*--------------------------------------------------------------------*/ -void -EncString(struct vsb *sb, const char *b, const char *e) +static void +EncString(struct vsb *sb, const char *b, const char *e, int mode) { if (e == NULL) @@ -166,7 +193,11 @@ EncString(struct vsb *sb, const char *b, const char *e) case '"': vsb_printf(sb, "\\%c", *b); break; - case '\n': vsb_printf(sb, "\\n"); break; + case '\n': + vsb_printf(sb, "\\n"); + if (mode) + vsb_printf(sb, "\"\n\t\""); + break; case '\t': vsb_printf(sb, "\\t"); break; case '\r': vsb_printf(sb, "\\r"); break; case ' ': vsb_printf(sb, " "); break; @@ -186,7 +217,7 @@ EncToken(struct vsb *sb, struct token *t) { assert(t->tok == CSTR); - EncString(sb, t->dec, NULL); + EncString(sb, t->dec, NULL, 0); } /*-------------------------------------------------------------------- @@ -212,20 +243,6 @@ FindRef(struct tokenlist *tl, struct token *t, enum ref_type type) return (r); } -static int -FindRefStr(struct tokenlist *tl, const char *s, enum ref_type type) -{ - struct ref *r; - - TAILQ_FOREACH(r, &tl->refs, list) { - if (r->type != type) - continue; - if (vcc_IdIs(r->name, s)) - return (1); - } - return (0); -} - void AddRef(struct tokenlist *tl, struct token *t, enum ref_type type) { @@ -233,20 +250,6 @@ AddRef(struct tokenlist *tl, struct token *t, enum ref_type type) FindRef(tl, t, type)->refcnt++; } -static void -AddRefStr(struct tokenlist *tl, const char *s, enum ref_type type) -{ - struct token *t; - - t = calloc(sizeof *t, 1); - assert(t != NULL); - t->b = s; - t->e = strchr(s, '\0'); - t->tok = METHOD; - AddRef(tl, t, type); - /* XXX: possibly leaking t */ -} - void AddDef(struct tokenlist *tl, struct token *t, enum ref_type type) { @@ -407,8 +410,6 @@ Consistency(struct tokenlist *tl) TAILQ_FOREACH(p, &tl->procs, list) { for(m = method_tab; m->name != NULL; m++) { - if (vcc_IdIs(p->name, m->defname)) - p->called = 1; if (vcc_IdIs(p->name, m->name)) break; } @@ -564,15 +565,18 @@ EmitStruct(struct tokenlist *tl) 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); + EncString(tl->fc, sp->name, NULL, 0); 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, " /* "); + EncString(tl->fc, sp->name, NULL, 0); + Fc(tl, 0, "*/\n"); Fc(tl, 0, "\t"); - EncString(tl->fc, sp->b, sp->e); + EncString(tl->fc, sp->b, sp->e, 1); Fc(tl, 0, ",\n"); } Fc(tl, 0, "};\n"); @@ -589,13 +593,7 @@ EmitStruct(struct tokenlist *tl) 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)) { \ - Fc(tl, 0, "\t." #l "_func = VGC_function_vcl_" #l ",\n"); \ - AddRefStr(tl, "vcl_" #l, R_FUNC); \ - } else { \ - Fc(tl, 0, "\t." #l "_func = VGC_function_default_vcl_" #l ",\n"); \ - } \ - AddRefStr(tl, "default_vcl_" #l, R_FUNC); + Fc(tl, 0, "\t." #l "_func = VGC_function_vcl_" #l ",\n"); #include "vcl_returns.h" #undef VCL_MET_MAC #undef VCL_RET_MAC @@ -744,11 +742,10 @@ vcc_CompileSource(struct vsb *sb, struct source *sp) assert(tl->ff != NULL); /* body code of methods */ -#define VCL_MET_MAC(l,U,m) \ - tl->fm_##l = vsb_new(NULL, NULL, 0, VSB_AUTOEXTEND); \ - assert(tl->fm_##l != NULL); -#include "vcl_returns.h" -#undef VCL_MET_MAC + for (i = 0; i < N_METHODS; i++) { + tl->fm[i] = vsb_new(NULL, NULL, 0, VSB_AUTOEXTEND); \ + assert(tl->fm[i] != NULL); + } Fh(tl, 0, "extern struct VCL_conf VCL_conf;\n"); @@ -779,6 +776,18 @@ vcc_CompileSource(struct vsb *sb, struct source *sp) Consistency(tl); if (tl->err) goto done; + + /* Emit method functions */ + for (i = 0; i < N_METHODS; i++) { + Fc(tl, 1, "static int\n"); + Fc(tl, 1, "VGC_function_%s (struct sess *sp)\n", + method_tab[i].name); + vsb_finish(tl->fm[i]); + Fc(tl, 1, "{\n"); + Fc(tl, 1, "%s", vsb_data(tl->fm[i])); + Fc(tl, 1, "}\n\n"); + } + LocTable(tl); Ff(tl, 0, "\tVRT_free_backends(&VCL_conf);\n"); @@ -824,9 +833,8 @@ vcc_CompileSource(struct vsb *sb, struct source *sp) } done: -#define VCL_MET_MAC(l,U,m) vsb_delete(tl->fm_##l); -#include "vcl_returns.h" -#undef VCL_MET_MAC + for (i = 0; i < N_METHODS; i++) + vsb_delete(tl->fm[i]); /* Free References */ while (!TAILQ_EMPTY(&tl->refs)) { diff --git a/varnish-cache/lib/libvcl/vcc_compile.h b/varnish-cache/lib/libvcl/vcc_compile.h index 187dee6c..f6307a74 100644 --- a/varnish-cache/lib/libvcl/vcc_compile.h +++ b/varnish-cache/lib/libvcl/vcc_compile.h @@ -62,16 +62,15 @@ struct tokenlist { 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 + struct vsb *fc, *fh, *fi, *ff, *fb; + struct vsb *fm[N_METHODS]; TAILQ_HEAD(, ref) refs; struct vsb *sb; int err; int nbackend; TAILQ_HEAD(, proc) procs; struct proc *curproc; + struct proc *mprocs[N_METHODS]; unsigned recnt; }; @@ -115,7 +114,6 @@ struct var { struct method { const char *name; - const char *defname; unsigned returns; }; @@ -145,19 +143,19 @@ void vcc_Acl(struct tokenlist *tl); void vcc_Cond_Ip(struct var *vp, struct tokenlist *tl); /* vcc_compile.c */ -extern const char *vcc_default_vcl_b, *vcc_default_vcl_e; void Fh(struct tokenlist *tl, int indent, const char *fmt, ...); void Fc(struct tokenlist *tl, int indent, const char *fmt, ...); +void Fb(struct tokenlist *tl, int indent, const char *fmt, ...); void Fi(struct tokenlist *tl, int indent, const char *fmt, ...); void Ff(struct tokenlist *tl, int indent, const char *fmt, ...); 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 EncToken(struct vsb *sb, struct token *t); -void EncString(struct vsb *sb, const char *b, const char *e); struct var *FindVar(struct tokenlist *tl, struct token *t, struct var *vl); void AddCall(struct tokenlist *tl, struct token *t); struct proc *AddProc(struct tokenlist *tl, struct token *t, int def); +int IsMethod(struct token *t); /* vcc_obj.c */ extern struct var vcc_be_vars[]; diff --git a/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl b/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl index 0b2f9804..317d3c1b 100755 --- a/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl +++ b/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl @@ -185,6 +185,7 @@ puts $for "#define VCL_RET_MAX $i" puts $for "#endif" puts $for "" puts $for "#ifdef VCL_MET_MAC" +set u 0 foreach m $methods { puts -nonewline $for "VCL_MET_MAC([lindex $m 0]" puts -nonewline $for ",[string toupper [lindex $m 0]]" @@ -195,8 +196,10 @@ foreach m $methods { } puts -nonewline $for ")" puts $for ")" + incr u } puts $for "#endif" +puts $for "#define N_METHODS $u" close $for #---------------------------------------------------------------------- diff --git a/varnish-cache/lib/libvcl/vcc_parse.c b/varnish-cache/lib/libvcl/vcc_parse.c index 53f18b00..6bfe344f 100644 --- a/varnish-cache/lib/libvcl/vcc_parse.c +++ b/varnish-cache/lib/libvcl/vcc_parse.c @@ -85,20 +85,10 @@ #include "vrt.h" #include "libvcl.h" -static struct method method_tab[] = { -#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 - { NULL, 0U } -}; - /*--------------------------------------------------------------------*/ static void Compound(struct tokenlist *tl); static void Cond_0(struct tokenlist *tl); -const char *vcc_default_vcl_b, *vcc_default_vcl_e; /*--------------------------------------------------------------------*/ @@ -109,26 +99,10 @@ const char *vcc_default_vcl_b, *vcc_default_vcl_e; } while (0) #define C(tl, sep) do { \ - Fc(tl, 1, "VRT_count(sp, %u)%s\n", ++tl->cnt, sep); \ + Fb(tl, 1, "VRT_count(sp, %u)%s\n", ++tl->cnt, sep); \ tl->t->cnt = tl->cnt; \ } while (0) -/*--------------------------------------------------------------------*/ - -static int -IsMethod(struct token *t) -{ - struct method *m; - - for(m = method_tab; m->name != NULL; m++) { - if (vcc_IdIs(t, m->defname)) - return (2); - if (vcc_IdIs(t, m->name)) - return (1); - } - return (0); -} - /*-------------------------------------------------------------------- * Recognize and convert units of time, return seconds. */ @@ -264,7 +238,7 @@ TimeVal(struct tokenlist *tl) v = DoubleVal(tl); ExpectErr(tl, ID); sc = TimeUnit(tl); - Fc(tl, 0, "(%g * %g)", v, sc); + Fb(tl, 0, "(%g * %g)", v, sc); } static void @@ -275,7 +249,7 @@ SizeVal(struct tokenlist *tl) v = DoubleVal(tl); ExpectErr(tl, ID); sc = SizeUnit(tl); - Fc(tl, 0, "(%g * %g)", v, sc); + Fb(tl, 0, "(%g * %g)", v, sc); } static void @@ -286,7 +260,7 @@ RateVal(struct tokenlist *tl) v = DoubleVal(tl); ExpectErr(tl, ID); sc = RateUnit(tl); - Fc(tl, 0, "(%g * %g)", v, sc); + Fb(tl, 0, "(%g * %g)", v, sc); } /*--------------------------------------------------------------------*/ @@ -303,7 +277,7 @@ vcc_re(struct tokenlist *tl, const char *str, struct token *re) } sprintf(buf, "VGC_re_%u", tl->recnt++); - Fc(tl, 1, "VRT_re_match(%s, %s)\n", str, buf); + Fb(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); EncToken(tl->fi, re); @@ -327,16 +301,16 @@ Cond_String(struct var *vp, struct tokenlist *tl) break; case T_EQ: case T_NEQ: - Fc(tl, 1, "%sstrcmp(%s, ", + Fb(tl, 1, "%sstrcmp(%s, ", tl->t->tok == T_EQ ? "!" : "", vp->rname); vcc_NextToken(tl); ExpectErr(tl, CSTR); - EncToken(tl->fc, tl->t); - Fc(tl, 0, ")\n"); + EncToken(tl->fb, tl->t); + Fb(tl, 0, ")\n"); vcc_NextToken(tl); break; default: - Fc(tl, 1, "%s != (void*)0", vp->rname); + Fb(tl, 1, "%s != (void*)0\n", vp->rname); break; } } @@ -345,7 +319,7 @@ static void Cond_Int(struct var *vp, struct tokenlist *tl) { - Fc(tl, 1, "%s ", vp->rname); + Fb(tl, 1, "%s ", vp->rname); switch (tl->t->tok) { case T_EQ: case T_NEQ: @@ -353,7 +327,7 @@ Cond_Int(struct var *vp, struct tokenlist *tl) case T_GEQ: case '>': case '<': - Fc(tl, 0, "%.*s ", PF(tl->t)); + Fb(tl, 0, "%.*s ", PF(tl->t)); vcc_NextToken(tl); switch(vp->fmt) { case TIME: @@ -361,7 +335,7 @@ Cond_Int(struct var *vp, struct tokenlist *tl) break; case INT: ExpectErr(tl, CNUM); - Fc(tl, 0, "%.*s ", PF(tl->t)); + Fb(tl, 0, "%.*s ", PF(tl->t)); vcc_NextToken(tl); break; case SIZE: @@ -374,7 +348,7 @@ Cond_Int(struct var *vp, struct tokenlist *tl) vcc_ErrWhere(tl, tl->t); return; } - Fc(tl, 0, "\n"); + Fb(tl, 0, "\n"); break; default: vsb_printf(tl->sb, "Illegal condition "); @@ -391,14 +365,14 @@ static void Cond_Bool(struct var *vp, struct tokenlist *tl) { - Fc(tl, 1, "%s\n", vp->rname); + Fb(tl, 1, "%s\n", vp->rname); } static void Cond_Backend(struct var *vp, struct tokenlist *tl) { - Fc(tl, 1, "%s\n", vp->rname); + Fb(tl, 1, "%s\n", vp->rname); } static void @@ -408,10 +382,10 @@ Cond_2(struct tokenlist *tl) C(tl, ","); if (tl->t->tok == '!') { - Fc(tl, 1, "!(\n"); + Fb(tl, 1, "!(\n"); vcc_NextToken(tl); } else { - Fc(tl, 1, "(\n"); + Fb(tl, 1, "(\n"); } if (tl->t->tok == '(') { vcc_NextToken(tl); @@ -448,35 +422,35 @@ Cond_2(struct tokenlist *tl) vcc_ErrWhere(tl, tl->t); return; } - Fc(tl, 1, ")\n"); + Fb(tl, 1, ")\n"); } static void Cond_1(struct tokenlist *tl) { - Fc(tl, 1, "(\n"); + Fb(tl, 1, "(\n"); L(tl, Cond_2(tl)); while (tl->t->tok == T_CAND) { vcc_NextToken(tl); - Fc(tl, 1, ") && (\n"); + Fb(tl, 1, ") && (\n"); L(tl, Cond_2(tl)); } - Fc(tl, 1, ")\n"); + Fb(tl, 1, ")\n"); } static void Cond_0(struct tokenlist *tl) { - Fc(tl, 1, "(\n"); + Fb(tl, 1, "(\n"); L(tl, Cond_1(tl)); while (tl->t->tok == T_COR) { vcc_NextToken(tl); - Fc(tl, 1, ") || (\n"); + Fb(tl, 1, ") || (\n"); L(tl, Cond_1(tl)); } - Fc(tl, 1, ")\n"); + Fb(tl, 1, ")\n"); } static void @@ -485,10 +459,10 @@ Conditional(struct tokenlist *tl) ExpectErr(tl, '('); vcc_NextToken(tl); - Fc(tl, 1, "(\n"); + Fb(tl, 1, "(\n"); L(tl, Cond_0(tl)); ERRCHK(tl); - Fc(tl, 1, ")\n"); + Fb(tl, 1, ")\n"); ExpectErr(tl, ')'); vcc_NextToken(tl); } @@ -500,7 +474,7 @@ IfStmt(struct tokenlist *tl) { ExpectErr(tl, T_IF); - Fc(tl, 1, "if \n"); + Fb(tl, 1, "if \n"); vcc_NextToken(tl); L(tl, Conditional(tl)); ERRCHK(tl); @@ -511,7 +485,7 @@ IfStmt(struct tokenlist *tl) case T_ELSE: vcc_NextToken(tl); if (tl->t->tok != T_IF) { - Fc(tl, 1, "else \n"); + Fb(tl, 1, "else \n"); L(tl, Compound(tl)); ERRCHK(tl); return; @@ -519,7 +493,7 @@ IfStmt(struct tokenlist *tl) /* FALLTHROUGH */ case T_ELSEIF: case T_ELSIF: - Fc(tl, 1, "else if \n"); + Fb(tl, 1, "else if \n"); vcc_NextToken(tl); L(tl, Conditional(tl)); ERRCHK(tl); @@ -546,13 +520,13 @@ Action(struct tokenlist *tl) vcc_NextToken(tl); switch (at->tok) { case T_NO_NEW_CACHE: - Fc(tl, 1, "VCL_no_new_cache(sp);\n"); + Fb(tl, 1, "VCL_no_new_cache(sp);\n"); return; case T_NO_CACHE: - Fc(tl, 1, "VCL_no_cache(sp);\n"); + Fb(tl, 1, "VCL_no_cache(sp);\n"); return; #define VCL_RET_MAC(a,b,c,d) case T_##b: \ - Fc(tl, 1, "VRT_done(sp, VCL_RET_%s);\n", #b); \ + Fb(tl, 1, "VRT_done(sp, VCL_RET_%s);\n", #b); \ tl->curproc->returns |= VCL_RET_##b; \ tl->curproc->returnt[d] = at; \ return; @@ -563,35 +537,35 @@ Action(struct tokenlist *tl) a = UintVal(tl); else a = 0; - Fc(tl, 1, "VRT_error(sp, %u", a); + Fb(tl, 1, "VRT_error(sp, %u", a); if (tl->t->tok == CSTR) { - Fc(tl, 0, ", %.*s", PF(tl->t)); + Fb(tl, 0, ", %.*s", PF(tl->t)); vcc_NextToken(tl); } else { - Fc(tl, 0, ", (const char *)0"); + Fb(tl, 0, ", (const char *)0"); } - Fc(tl, 0, ");\n"); - Fc(tl, 1, "VRT_done(sp, VCL_RET_ERROR);\n"); + Fb(tl, 0, ");\n"); + Fb(tl, 1, "VRT_done(sp, VCL_RET_ERROR);\n"); return; case T_SWITCH_CONFIG: ExpectErr(tl, ID); - Fc(tl, 1, "VCL_switch_config(\"%.*s\");\n", PF(tl->t)); + Fb(tl, 1, "VCL_switch_config(\"%.*s\");\n", PF(tl->t)); vcc_NextToken(tl); return; case T_CALL: ExpectErr(tl, ID); AddCall(tl, tl->t); AddRef(tl, tl->t, R_FUNC); - Fc(tl, 1, "if (VGC_function_%.*s(sp))\n", PF(tl->t)); - Fc(tl, 1, "\treturn (1);\n"); + Fb(tl, 1, "if (VGC_function_%.*s(sp))\n", PF(tl->t)); + Fb(tl, 1, "\treturn (1);\n"); vcc_NextToken(tl); return; case T_REWRITE: ExpectErr(tl, CSTR); - Fc(tl, 1, "VCL_rewrite(%.*s", PF(tl->t)); + Fb(tl, 1, "VCL_rewrite(%.*s", PF(tl->t)); vcc_NextToken(tl); ExpectErr(tl, CSTR); - Fc(tl, 0, ", %.*s);\n", PF(tl->t)); + Fb(tl, 0, ", %.*s);\n", PF(tl->t)); vcc_NextToken(tl); return; case T_SET: @@ -599,7 +573,7 @@ Action(struct tokenlist *tl) vp = FindVar(tl, tl->t, vcc_vars); ERRCHK(tl); assert(vp != NULL); - Fc(tl, 1, "%s", vp->lname); + Fb(tl, 1, "%s", vp->lname); vcc_NextToken(tl); switch (vp->fmt) { case INT: @@ -608,11 +582,11 @@ Action(struct tokenlist *tl) case TIME: case FLOAT: if (tl->t->tok != '=') - Fc(tl, 0, "%s %c ", vp->rname, *tl->t->b); + Fb(tl, 0, "%s %c ", vp->rname, *tl->t->b); a = tl->t->tok; vcc_NextToken(tl); if (a == T_MUL || a == T_DIV) - Fc(tl, 0, "%g", DoubleVal(tl)); + Fb(tl, 0, "%g", DoubleVal(tl)); else if (vp->fmt == TIME) TimeVal(tl); else if (vp->fmt == SIZE) @@ -620,15 +594,15 @@ Action(struct tokenlist *tl) else if (vp->fmt == RATE) RateVal(tl); else - Fc(tl, 0, "%g", DoubleVal(tl)); - Fc(tl, 0, ");\n"); + Fb(tl, 0, "%g", DoubleVal(tl)); + Fb(tl, 0, ");\n"); break; #if 0 /* XXX: enable if we find a legit use */ case IP: if (tl->t->tok == '=') { vcc_NextToken(tl); u = vcc_IpVal(tl); - Fc(tl, 0, "= %uU; /* %u.%u.%u.%u */\n", + Fb(tl, 0, "= %uU; /* %u.%u.%u.%u */\n", u, (u >> 24) & 0xff, (u >> 16) & 0xff, @@ -647,9 +621,9 @@ Action(struct tokenlist *tl) if (tl->t->tok == '=') { vcc_NextToken(tl); AddRef(tl, tl->t, R_BACKEND); - Fc(tl, 0, "VGC_backend_%.*s", PF(tl->t)); + Fb(tl, 0, "VGC_backend_%.*s", PF(tl->t)); vcc_NextToken(tl); - Fc(tl, 0, ");\n"); + Fb(tl, 0, ");\n"); break; } vsb_printf(tl->sb, "Illegal assignment operator "); @@ -679,7 +653,7 @@ Compound(struct tokenlist *tl) { ExpectErr(tl, '{'); - Fc(tl, 1, "{\n"); + Fb(tl, 1, "{\n"); tl->indent += INDENT; C(tl, ";"); vcc_NextToken(tl); @@ -695,7 +669,7 @@ Compound(struct tokenlist *tl) case '}': vcc_NextToken(tl); tl->indent -= INDENT; - Fc(tl, 1, "}\n"); + Fb(tl, 1, "}\n"); return; case EOI: vsb_printf(tl->sb, @@ -853,28 +827,40 @@ Backend(struct tokenlist *tl) static void Function(struct tokenlist *tl) { - struct token *tn; + int m; vcc_NextToken(tl); ExpectErr(tl, ID); - tl->curproc = AddProc(tl, tl->t, 1); - tl->curproc->exists++; - tn = tl->t; - AddDef(tl, tl->t, R_FUNC); - Fh(tl, 0, "static int VGC_function_%.*s (struct sess *sp);\n", - PF(tl->t)); - Fc(tl, 1, "static int\n"); - Fc(tl, 1, "VGC_function_%.*s (struct sess *sp)\n", PF(tl->t)); + + m = IsMethod(tl->t); + if (m != -1) { + assert(m < N_METHODS); + tl->fb = tl->fm[m]; + if (tl->mprocs[m] == NULL) { + tl->mprocs[m] = AddProc(tl, tl->t, 1); + tl->mprocs[m]->exists++; + AddDef(tl, tl->t, R_FUNC); + AddRef(tl, tl->t, R_FUNC); + } + tl->curproc = tl->mprocs[m]; + } else { + tl->fb = tl->fc; + tl->curproc = AddProc(tl, tl->t, 1); + tl->curproc->exists++; + AddDef(tl, tl->t, R_FUNC); + Fh(tl, 0, "static int VGC_function_%.*s (struct sess *sp);\n", + PF(tl->t)); + Fc(tl, 1, "static int\n"); + Fc(tl, 1, "VGC_function_%.*s (struct sess *sp)\n", PF(tl->t)); + } vcc_NextToken(tl); tl->indent += INDENT; - Fc(tl, 1, "{\n"); + Fb(tl, 1, "{\n"); L(tl, Compound(tl)); - if (IsMethod(tn) == 1) { - Fc(tl, 1, "VGC_function_default_%.*s(sp);\n", PF(tn)); - } - Fc(tl, 1, "}\n"); + Fb(tl, 1, "}\n"); tl->indent -= INDENT; - Fc(tl, 0, "\n"); + Fb(tl, 0, "\n"); + tl->fb = NULL; } /*-------------------------------------------------------------------- -- 2.39.5