Commit d2ee8d31 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Reduce the scope of VCC code that knows about variables, specifically

the handling of if() expressions.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@5031 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent 579a9a68
...@@ -449,18 +449,19 @@ vcc_acl_emit(const struct vcc *tl, const char *acln, int anon) ...@@ -449,18 +449,19 @@ vcc_acl_emit(const struct vcc *tl, const char *acln, int anon)
} }
void void
vcc_Cond_Ip(const struct var *vp, struct vcc *tl) vcc_Cond_Ip(struct vcc *tl, const char *a1)
{ {
unsigned tcond; unsigned tcond;
char acln[32]; char acln[32];
switch (tl->t->tok) { switch (tl->t->tok) {
/* XXX: T_NOMATCH */
case '~': case '~':
vcc_NextToken(tl); vcc_NextToken(tl);
ExpectErr(tl, ID); ExpectErr(tl, ID);
vcc_AddRef(tl, tl->t, R_ACL); vcc_AddRef(tl, tl->t, R_ACL);
Fb(tl, 1, "match_acl_named_%.*s(sp, %s)\n", Fb(tl, 1, "match_acl_named_%.*s(sp, %s)\n",
PF(tl->t), vp->rname); PF(tl->t), a1);
vcc_NextToken(tl); vcc_NextToken(tl);
break; break;
case T_EQ: case T_EQ:
...@@ -473,7 +474,7 @@ vcc_Cond_Ip(const struct var *vp, struct vcc *tl) ...@@ -473,7 +474,7 @@ vcc_Cond_Ip(const struct var *vp, struct vcc *tl)
vcc_acl_entry(tl); vcc_acl_entry(tl);
vcc_acl_emit(tl, acln, 1); vcc_acl_emit(tl, acln, 1);
Fb(tl, 1, "%smatch_acl_anon_%s(sp, %s)\n", Fb(tl, 1, "%smatch_acl_anon_%s(sp, %s)\n",
(tcond == T_NEQ ? "!" : ""), acln, vp->rname); (tcond == T_NEQ ? "!" : ""), acln, a1);
break; break;
default: default:
vsb_printf(tl->sb, "Invalid condition "); vsb_printf(tl->sb, "Invalid condition ");
......
...@@ -127,10 +127,8 @@ parse_set(struct vcc *tl) ...@@ -127,10 +127,8 @@ parse_set(struct vcc *tl)
vcc_NextToken(tl); vcc_NextToken(tl);
switch (vp->fmt) { switch (vp->fmt) {
case INT: case INT:
// case SIZE:
case TIME: case TIME:
case DURATION: case DURATION:
// case FLOAT:
if (tl->t->tok != '=') if (tl->t->tok != '=')
Fb(tl, 0, "%s %c ", vp->rname, *tl->t->b); Fb(tl, 0, "%s %c ", vp->rname, *tl->t->b);
at = tl->t; at = tl->t;
...@@ -153,22 +151,6 @@ parse_set(struct vcc *tl) ...@@ -153,22 +151,6 @@ parse_set(struct vcc *tl)
} }
Fb(tl, 0, ");\n"); Fb(tl, 0, ");\n");
break; break;
#if 0 /* XXX: enable if we find a legit use */
case IP:
if (tl->t->tok != '=') {
illegal_assignment(tl, "IP numbers");
return;
}
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;
#endif
case BACKEND: case BACKEND:
if (tl->t->tok != '=') { if (tl->t->tok != '=') {
illegal_assignment(tl, "backend"); illegal_assignment(tl, "backend");
......
...@@ -174,7 +174,7 @@ struct method { ...@@ -174,7 +174,7 @@ struct method {
/* vcc_acl.c */ /* vcc_acl.c */
void vcc_Acl(struct vcc *tl); void vcc_Acl(struct vcc *tl);
void vcc_Cond_Ip(const struct var *vp, struct vcc *tl); void vcc_Cond_Ip(struct vcc *tl, const char *a1);
/* vcc_action.c */ /* vcc_action.c */
int vcc_ParseAction(struct vcc *tl); int vcc_ParseAction(struct vcc *tl);
......
...@@ -60,6 +60,18 @@ static void vcc_Cond_0(struct vcc *tl); ...@@ -60,6 +60,18 @@ static void vcc_Cond_0(struct vcc *tl);
tl->t->cnt = tl->cnt; \ tl->t->cnt = tl->cnt; \
} while (0) } while (0)
/*--------------------------------------------------------------------*/
static void
vcc_inval_test(struct vcc *tl, const char *type, const char *valid)
{
vsb_printf(tl->sb, "Invalid test ");
vcc_ErrToken(tl, tl->t);
vsb_printf(tl->sb, " on expression of type %s.\n", type);
vsb_printf(tl->sb, " only %s are legal\n", valid);
vcc_ErrWhere(tl, tl->t);
}
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* Recognize and convert units of time, return seconds. * Recognize and convert units of time, return seconds.
*/ */
...@@ -93,37 +105,6 @@ vcc_TimeUnit(struct vcc *tl) ...@@ -93,37 +105,6 @@ vcc_TimeUnit(struct vcc *tl)
return (sc); return (sc);
} }
#if 0
/*--------------------------------------------------------------------
* Recognize and convert units of size, return bytes.
*/
static double
vcc_SizeUnit(struct vcc *tl)
{
double sc = 1.0;
assert(tl->t->tok == ID);
if (vcc_IdIs(tl->t, "b"))
sc = 1.0;
else if (vcc_IdIs(tl->t, "kb"))
sc = 1024.0;
else if (vcc_IdIs(tl->t, "mb") || vcc_IdIs(tl->t, "Mb"))
sc = 1024.0 * 1024.0;
else if (vcc_IdIs(tl->t, "gb") || vcc_IdIs(tl->t, "Gb"))
sc = 1024.0 * 1024.0 * 1024.0;
else {
vsb_printf(tl->sb, "Unknown size unit ");
vcc_ErrToken(tl, tl->t);
vsb_printf(tl->sb, ". Legal are 'kb', 'mb' and 'gb'\n");
vcc_ErrWhere(tl, tl->t);
return (1.0);
}
vcc_NextToken(tl);
return (sc);
}
#endif
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* Recognize and convert { CNUM } to unsigned value * Recognize and convert { CNUM } to unsigned value
* The tokenizer made sure we only get digits. * The tokenizer made sure we only get digits.
...@@ -209,26 +190,10 @@ vcc_TimeVal(struct vcc *tl, double *d) ...@@ -209,26 +190,10 @@ vcc_TimeVal(struct vcc *tl, double *d)
*d = v * sc; *d = v * sc;
} }
#if 0
/*--------------------------------------------------------------------*/
void
vcc_SizeVal(struct vcc *tl, double *d)
{
double v, sc;
v = vcc_DoubleVal(tl);
ERRCHK(tl);
ExpectErr(tl, ID);
sc = vcc_SizeUnit(tl);
*d = v * sc;
}
#endif
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
static void static void
vcc_Cond_String(const struct var *vp, struct vcc *tl) vcc_Cond_String(struct vcc *tl, const char *a1)
{ {
char *p; char *p;
...@@ -242,12 +207,17 @@ vcc_Cond_String(const struct var *vp, struct vcc *tl) ...@@ -242,12 +207,17 @@ vcc_Cond_String(const struct var *vp, struct vcc *tl)
p = vcc_regexp(tl); p = vcc_regexp(tl);
ERRCHK(tl); ERRCHK(tl);
vcc_NextToken(tl); vcc_NextToken(tl);
Fb(tl, 1, "%s, %s)\n", vp->rname, p); Fb(tl, 1, "%s, %s)\n", a1, p);
break; break;
case T_LEQ:
case T_GEQ:
case '>':
case '<':
vcc_inval_test(tl, "STRING", "'==', '!=', '~' and '!~'");
case T_EQ: case T_EQ:
case T_NEQ: case T_NEQ:
Fb(tl, 1, "%sVRT_strcmp(%s, ", Fb(tl, 1, "%sVRT_strcmp(%s, ",
tl->t->tok == T_EQ ? "!" : "", vp->rname); tl->t->tok == T_EQ ? "!" : "", a1);
vcc_NextToken(tl); vcc_NextToken(tl);
if (!vcc_StringVal(tl)) { if (!vcc_StringVal(tl)) {
vcc_ExpectedStringval(tl); vcc_ExpectedStringval(tl);
...@@ -256,16 +226,16 @@ vcc_Cond_String(const struct var *vp, struct vcc *tl) ...@@ -256,16 +226,16 @@ vcc_Cond_String(const struct var *vp, struct vcc *tl)
Fb(tl, 0, ")\n"); Fb(tl, 0, ")\n");
break; break;
default: default:
Fb(tl, 1, "%s != (void*)0\n", vp->rname); Fb(tl, 1, "%s != (void*)0\n", a1);
break; break;
} }
} }
static void static void
vcc_Cond_Int(const struct var *vp, struct vcc *tl) vcc_Cond_Int(struct vcc *tl, const char *a1)
{ {
Fb(tl, 1, "%s ", vp->rname); Fb(tl, 1, "%s ", a1);
switch (tl->t->tok) { switch (tl->t->tok) {
case T_EQ: case T_EQ:
case T_NEQ: case T_NEQ:
...@@ -275,44 +245,33 @@ vcc_Cond_Int(const struct var *vp, struct vcc *tl) ...@@ -275,44 +245,33 @@ vcc_Cond_Int(const struct var *vp, struct vcc *tl)
case '<': case '<':
Fb(tl, 0, "%.*s ", PF(tl->t)); Fb(tl, 0, "%.*s ", PF(tl->t));
vcc_NextToken(tl); vcc_NextToken(tl);
vcc_VarVal(tl, vp, NULL); Fb(tl, 0, "%u", vcc_UintVal(tl));
ERRCHK(tl); ERRCHK(tl);
Fb(tl, 0, "\n"); Fb(tl, 0, "\n");
break; break;
default: default:
vsb_printf(tl->sb, "Invalid condition "); vcc_inval_test(tl, "INT",
vcc_ErrToken(tl, tl->t); "'==', '!=', '<', '>', '<=' and '>='");
vsb_printf(tl->sb, " on numeric variable\n");
vsb_printf(tl->sb,
" only '==', '!=', '<', '>', '<=' and '>=' are legal\n");
vcc_ErrWhere(tl, tl->t);
break; break;
} }
} }
static void static void
vcc_Cond_Bool(const struct var *vp, const struct vcc *tl) vcc_Cond_Bool(struct vcc *tl, const char *a1)
{ {
Fb(tl, 1, "%s\n", vp->rname); Fb(tl, 1, "%s\n", a1);
} }
static void static void
vcc_Cond_Backend(const struct var *vp, struct vcc *tl) vcc_Cond_Backend(struct vcc *tl, const char *a1)
{ {
Fb(tl, 1, "%s\n", vp->rname); Fb(tl, 1, "%s\n", a1);
if (tl->t->tok == T_EQ) { if (tl->t->tok == T_EQ || tl->t->tok == T_NEQ) {
Fb(tl, 1, " ==\n"); Fb(tl, 1, " %.*s\n", PF(tl->t));
} else if (tl->t->tok == T_NEQ) {
Fb(tl, 1, " !=\n");
} else { } else {
vsb_printf(tl->sb, "Invalid condition "); vcc_inval_test(tl, "BACKEND", "'==' and '!='");
vcc_ErrToken(tl, tl->t);
vsb_printf(tl->sb, " on backend variable\n");
vsb_printf(tl->sb,
" only '==' and '!=' are legal\n");
vcc_ErrWhere(tl, tl->t);
return; return;
} }
vcc_NextToken(tl); vcc_NextToken(tl);
...@@ -323,44 +282,56 @@ vcc_Cond_Backend(const struct var *vp, struct vcc *tl) ...@@ -323,44 +282,56 @@ vcc_Cond_Backend(const struct var *vp, struct vcc *tl)
vcc_NextToken(tl); vcc_NextToken(tl);
} }
const char *typenm[] = { static void
#define VCC_TYPE(foo) [foo] = #foo, vcc_Cond_Time(struct vcc *tl, const char *a1)
#include "vcc_types.h"
#undef VCC_TYPE
};
static int
vcc_Relation(struct vcc *tl, enum var_type fmt)
{ {
double d;
switch(tl->t->tok) { Fb(tl, 1, "%s ", a1);
switch (tl->t->tok) {
case T_EQ: case T_EQ:
case T_NEQ: case T_NEQ:
if (fmt != BOOL) case T_LEQ:
return (tl->t->tok);
break;
case '>':
case T_GEQ: case T_GEQ:
case '>':
case '<': case '<':
case T_LEQ: Fb(tl, 0, "%.*s ", PF(tl->t));
if (fmt == INT || fmt == TIME || fmt == DURATION) vcc_NextToken(tl);
return (tl->t->tok); vcc_RTimeVal(tl, &d);
ERRCHK(tl);
Fb(tl, 0, "%g\n", d);
break; break;
case '~': default:
case T_NOMATCH: vcc_inval_test(tl, "TIME",
if (fmt == IP || fmt == STRING || fmt == HEADER) "'==', '!=', '<', '>', '<=' and '>='");
return (tl->t->tok); break;
}
}
static void
vcc_Cond_Duration(struct vcc *tl, const char *a1)
{
double d;
Fb(tl, 1, "%s ", a1);
switch (tl->t->tok) {
case T_EQ:
case T_NEQ:
case T_LEQ:
case T_GEQ:
case '>':
case '<':
Fb(tl, 0, "%.*s ", PF(tl->t));
vcc_NextToken(tl);
vcc_RTimeVal(tl, &d);
ERRCHK(tl);
Fb(tl, 0, "%g\n", d);
break; break;
default: default:
if (fmt == STRING || fmt == HEADER || fmt == BOOL) vcc_inval_test(tl, "DURATION",
return (-1); "'==', '!=', '<', '>', '<=' and '>='");
break; break;
} }
vsb_printf(tl->sb, "Invalid comparison/match operator ");
vsb_printf(tl->sb, " for type %s.\n", typenm[fmt]);
vcc_ErrToken(tl, tl->t);
vcc_ErrWhere(tl, tl->t);
return (-1);
} }
static void static void
...@@ -386,16 +357,14 @@ vcc_Cond_3(struct vcc *tl) ...@@ -386,16 +357,14 @@ vcc_Cond_3(struct vcc *tl)
ERRCHK(tl); ERRCHK(tl);
assert(vp != NULL); assert(vp != NULL);
vcc_NextToken(tl); vcc_NextToken(tl);
vcc_Relation(tl, sym->fmt);
switch (vp->fmt) { switch (vp->fmt) {
case INT: L(tl, vcc_Cond_Int(vp, tl)); break; case BACKEND: L(tl, vcc_Cond_Backend(tl, vp->rname)); break;
// case SIZE: L(tl, vcc_Cond_Int(vp, tl)); break; case BOOL: L(tl, vcc_Cond_Bool(tl, vp->rname)); break;
case BOOL: L(tl, vcc_Cond_Bool(vp, tl)); break; case DURATION: L(tl, vcc_Cond_Duration(tl, vp->rname)); break;
case IP: L(tl, vcc_Cond_Ip(vp, tl)); break; case INT: L(tl, vcc_Cond_Int(tl, vp->rname)); break;
case STRING: L(tl, vcc_Cond_String(vp, tl)); break; case IP: L(tl, vcc_Cond_Ip(tl, vp->rname)); break;
case TIME: L(tl, vcc_Cond_Int(vp, tl)); break; case STRING: L(tl, vcc_Cond_String(tl, vp->rname)); break;
case DURATION: L(tl, vcc_Cond_Int(vp, tl)); break; case TIME: L(tl, vcc_Cond_Time(tl, vp->rname)); break;
case BACKEND: L(tl, vcc_Cond_Backend(vp, tl)); break;
default: default:
vsb_printf(tl->sb, vsb_printf(tl->sb,
"Variable '%s'" "Variable '%s'"
......
...@@ -144,16 +144,6 @@ vcc_VarVal(struct vcc *tl, const struct var *vp, const struct token *vt) ...@@ -144,16 +144,6 @@ vcc_VarVal(struct vcc *tl, const struct var *vp, const struct token *vt)
vcc_RTimeVal(tl, &d); vcc_RTimeVal(tl, &d);
ERRCHK(tl); ERRCHK(tl);
Fb(tl, 0, "%g", d); Fb(tl, 0, "%g", d);
#if 0
} else if (vp->fmt == SIZE) {
vcc_SizeVal(tl, &d);
ERRCHK(tl);
Fb(tl, 0, "%g", d);
#endif
#if 0
} else if (vp->fmt == FLOAT) {
Fb(tl, 0, "%g", vcc_DoubleVal(tl));
#endif
} else if (vp->fmt == INT) { } else if (vp->fmt == INT) {
Fb(tl, 0, "%u", vcc_UintVal(tl)); Fb(tl, 0, "%u", vcc_UintVal(tl));
} else { } else {
......
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