From fda70c5d1090437bf91d56e62e0a49ad96c3c566 Mon Sep 17 00:00:00 2001 From: phk Date: Sun, 1 Apr 2007 08:48:08 +0000 Subject: [PATCH] Introduce table based search for actions, and make "set" the first one. This eliminates the need to have the identifier "set" be its own token rather than being a simple ID. git-svn-id: svn+ssh://projects.linpro.no/svn/varnish/trunk@1297 d4fa192b-c00b-0410-8231-f00ffab90ce4 --- varnish-cache/lib/libvcl/vcc_action.c | 209 ++++++++++-------- varnish-cache/lib/libvcl/vcc_fixed_token.c | 6 - .../lib/libvcl/vcc_gen_fixed_token.tcl | 1 - varnish-cache/lib/libvcl/vcc_parse.c | 10 +- varnish-cache/lib/libvcl/vcc_token_defs.h | 63 +++--- 5 files changed, 158 insertions(+), 131 deletions(-) diff --git a/varnish-cache/lib/libvcl/vcc_action.c b/varnish-cache/lib/libvcl/vcc_action.c index bba28b62..822795df 100644 --- a/varnish-cache/lib/libvcl/vcc_action.c +++ b/varnish-cache/lib/libvcl/vcc_action.c @@ -69,15 +69,131 @@ /*--------------------------------------------------------------------*/ +static void +parse_set(struct tokenlist *tl) +{ + struct var *vp; + struct token *at, *vt; + + ExpectErr(tl, VAR); + vt = tl->t; + vp = FindVar(tl, tl->t, vcc_vars); + ERRCHK(tl); + assert(vp != NULL); + Fb(tl, 1, "%s", vp->lname); + vcc_NextToken(tl); + switch (vp->fmt) { + case INT: + case SIZE: + case RATE: + case TIME: + case FLOAT: + if (tl->t->tok != '=') + Fb(tl, 0, "%s %c ", vp->rname, *tl->t->b); + at = tl->t; + vcc_NextToken(tl); + switch (at->tok) { + case T_MUL: + case T_DIV: + Fb(tl, 0, "%g", vcc_DoubleVal(tl)); + break; + case T_INCR: + case T_DECR: + case '=': + if (vp->fmt == TIME) + vcc_TimeVal(tl); + else if (vp->fmt == SIZE) + vcc_SizeVal(tl); + else if (vp->fmt == RATE) + vcc_RateVal(tl); + else if (vp->fmt == FLOAT) + Fb(tl, 0, "%g", vcc_DoubleVal(tl)); + else { + vsb_printf(tl->sb, "Cannot assign this variable type.\n"); + vcc_ErrWhere(tl, vt); + return; + } + break; + default: + vsb_printf(tl->sb, "Illegal assignment operator.\n"); + vcc_ErrWhere(tl, at); + return; + } + 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_vcc_IpVal(tl); + Fb(tl, 0, "= %uU; /* %u.%u.%u.%u */\n", + u, + (u >> 24) & 0xff, + (u >> 16) & 0xff, + (u >> 8) & 0xff, + u & 0xff); + break; + } + vsb_printf(tl->sb, "Illegal assignment operator "); + vcc_ErrToken(tl, tl->t); + vsb_printf(tl->sb, + " only '=' is legal for IP numbers\n"); + vcc_ErrWhere(tl, tl->t); + return; +#endif + case BACKEND: + if (tl->t->tok == '=') { + vcc_NextToken(tl); + vcc_AddRef(tl, tl->t, R_BACKEND); + Fb(tl, 0, "VGC_backend_%.*s", PF(tl->t)); + vcc_NextToken(tl); + Fb(tl, 0, ");\n"); + break; + } + vsb_printf(tl->sb, "Illegal assignment operator "); + vcc_ErrToken(tl, tl->t); + vsb_printf(tl->sb, + " only '=' is legal for backend\n"); + vcc_ErrWhere(tl, tl->t); + return; + default: + vsb_printf(tl->sb, + "Assignments not possible for '%s'\n", vp->name); + vcc_ErrWhere(tl, tl->t); + return; + } +} + +/*--------------------------------------------------------------------*/ + +typedef action_f(struct tokenlist *tl); + +static struct action_table { + const char *name; + action_f *func; +} action_table[] = { + { "set", parse_set }, + { NULL, NULL } +}; + + void vcc_ParseAction(struct tokenlist *tl) { unsigned a; - struct var *vp; - struct token *at, *vt; + struct token *at; + struct action_table *atp; at = tl->t; vcc_NextToken(tl); + if (at->tok == ID) { + for(atp = action_table; atp->name != NULL; atp++) { + if (vcc_IdIs(at, atp->name)) { + atp->func(tl); + return; + } + } + } switch (at->tok) { case T_NO_NEW_CACHE: Fb(tl, 1, "VCL_no_new_cache(sp);\n"); @@ -127,95 +243,6 @@ vcc_ParseAction(struct tokenlist *tl) Fb(tl, 0, ", %.*s);\n", PF(tl->t)); vcc_NextToken(tl); return; - case T_SET: - ExpectErr(tl, VAR); - vt = tl->t; - vp = FindVar(tl, tl->t, vcc_vars); - ERRCHK(tl); - assert(vp != NULL); - Fb(tl, 1, "%s", vp->lname); - vcc_NextToken(tl); - switch (vp->fmt) { - case INT: - case SIZE: - case RATE: - case TIME: - case FLOAT: - if (tl->t->tok != '=') - Fb(tl, 0, "%s %c ", vp->rname, *tl->t->b); - at = tl->t; - vcc_NextToken(tl); - switch (at->tok) { - case T_MUL: - case T_DIV: - Fb(tl, 0, "%g", vcc_DoubleVal(tl)); - break; - case T_INCR: - case T_DECR: - case '=': - if (vp->fmt == TIME) - vcc_TimeVal(tl); - else if (vp->fmt == SIZE) - vcc_SizeVal(tl); - else if (vp->fmt == RATE) - vcc_RateVal(tl); - else if (vp->fmt == FLOAT) - Fb(tl, 0, "%g", vcc_DoubleVal(tl)); - else { - vsb_printf(tl->sb, "Cannot assign this variable type.\n"); - vcc_ErrWhere(tl, vt); - return; - } - break; - default: - vsb_printf(tl->sb, "Illegal assignment operator.\n"); - vcc_ErrWhere(tl, at); - return; - } - 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_vcc_IpVal(tl); - Fb(tl, 0, "= %uU; /* %u.%u.%u.%u */\n", - u, - (u >> 24) & 0xff, - (u >> 16) & 0xff, - (u >> 8) & 0xff, - u & 0xff); - break; - } - vsb_printf(tl->sb, "Illegal assignment operator "); - vcc_ErrToken(tl, tl->t); - vsb_printf(tl->sb, - " only '=' is legal for IP numbers\n"); - vcc_ErrWhere(tl, tl->t); - return; -#endif - case BACKEND: - if (tl->t->tok == '=') { - vcc_NextToken(tl); - vcc_AddRef(tl, tl->t, R_BACKEND); - Fb(tl, 0, "VGC_backend_%.*s", PF(tl->t)); - vcc_NextToken(tl); - Fb(tl, 0, ");\n"); - break; - } - vsb_printf(tl->sb, "Illegal assignment operator "); - vcc_ErrToken(tl, tl->t); - vsb_printf(tl->sb, - " only '=' is legal for backend\n"); - vcc_ErrWhere(tl, tl->t); - return; - default: - vsb_printf(tl->sb, - "Assignments not possible for '%s'\n", vp->name); - vcc_ErrWhere(tl, tl->t); - return; - } - return; default: vsb_printf(tl->sb, "Expected action, 'if' or '}'\n"); vcc_ErrWhere(tl, at); diff --git a/varnish-cache/lib/libvcl/vcc_fixed_token.c b/varnish-cache/lib/libvcl/vcc_fixed_token.c index dc8bdf41..70031da6 100644 --- a/varnish-cache/lib/libvcl/vcc_fixed_token.c +++ b/varnish-cache/lib/libvcl/vcc_fixed_token.c @@ -317,11 +317,6 @@ vcl_fixed_token(const char *p, const char **q) *q = p + 3; return (T_SUB); } - if (p[0] == 's' && p[1] == 'e' && p[2] == 't' - && !isvar(p[3])) { - *q = p + 3; - return (T_SET); - } return (0); case '{': if (p[0] == '{') { @@ -419,7 +414,6 @@ vcl_init_tnames(void) vcl_tnames[T_PIPE] = "pipe"; vcl_tnames[T_PROC] = "proc"; vcl_tnames[T_REWRITE] = "rewrite"; - vcl_tnames[T_SET] = "set"; vcl_tnames[T_SHL] = "<<"; vcl_tnames[T_SHR] = ">>"; vcl_tnames[T_SUB] = "sub"; diff --git a/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl b/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl index d9627448..a01bae8a 100755 --- a/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl +++ b/varnish-cache/lib/libvcl/vcc_gen_fixed_token.tcl @@ -74,7 +74,6 @@ set keywords { call no_cache no_new_cache - set rewrite switch_config } diff --git a/varnish-cache/lib/libvcl/vcc_parse.c b/varnish-cache/lib/libvcl/vcc_parse.c index 84e9b960..b01052b6 100644 --- a/varnish-cache/lib/libvcl/vcc_parse.c +++ b/varnish-cache/lib/libvcl/vcc_parse.c @@ -565,7 +565,15 @@ Backend(struct tokenlist *tl) while (1) { if (tl->t->tok == '}') break; - ExpectErr(tl, T_SET); + ExpectErr(tl, ID); + if (!vcc_IdIs(tl->t, "set")) { + vsb_printf(tl->sb, + "Expected 'set', found "); + vcc_ErrToken(tl, tl->t); + vsb_printf(tl->sb, " at\n"); + vcc_ErrWhere(tl, tl->t); + return; + } vcc_NextToken(tl); ExpectErr(tl, VAR); vp = FindVar(tl, tl->t, vcc_be_vars); diff --git a/varnish-cache/lib/libvcl/vcc_token_defs.h b/varnish-cache/lib/libvcl/vcc_token_defs.h index 89d3c811..8d91ba28 100644 --- a/varnish-cache/lib/libvcl/vcc_token_defs.h +++ b/varnish-cache/lib/libvcl/vcc_token_defs.h @@ -20,35 +20,34 @@ #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 +#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 -- 2.39.5