Commit 2ab588b7 authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Introduce the VCL type "BYTES" represented by a double, in unites of

bytes and make the two stevedore space variables that type.



git-svn-id: http://www.varnish-cache.org/svn/trunk/varnish-cache@5656 d4fa192b-c00b-0410-8231-f00ffab90ce4
parent ab92f91a
......@@ -77,6 +77,7 @@
-efile(451, "vcc_types.h") // No include guard
-efile(451, "symbol_kind.h") // No include guard
-efile(451, "config.h") // No include guard
-efile(451, "vrt_stv_var.h") // No include guard
//////////////
// -e458 // unprotected access
// -e456 // merged locking paths
......
# $Id$
test "Stevedore variables and BYTES type test"
server s1 {
rxreq
txresp
} -start
varnish v1 -vcl+backend {
sub vcl_fetch {
set beresp.http.foo =
storage.nowhere.free_space +
1 B + 1 KB + 1 MB + 1GB + 1TB;
}
} -start
client c1 {
txreq
rxresp
expect resp.status == 200
expect resp.http.foo == 1100586419201.000
} -run
......@@ -32,9 +32,9 @@
#define VRTSTVVAR(nm, vtype, ctype, dval) ctype VRT_Stv_ ## nm(const char *nm);
#endif
VRTSTVVAR(free_space, REAL, double, 0.)
VRTSTVVAR(used_space, REAL, double, 0.)
VRTSTVVAR(happy, BOOL, int, 0)
VRTSTVVAR(free_space, BYTES, double, 0.)
VRTSTVVAR(used_space, BYTES, double, 0.)
VRTSTVVAR(happy, BOOL, int, 0)
#ifdef VRTSTVVAR_PROTO
#undef VRTSTVVAR_PROTO
......
......@@ -191,6 +191,44 @@ vcc_TimeVal(struct vcc *tl, double *d)
*d = v * sc;
}
/*--------------------------------------------------------------------*/
static void
vcc_ByteVal(struct vcc *tl, double *d)
{
double v, sc;
v = vcc_DoubleVal(tl);
ERRCHK(tl);
if (tl->t->tok != ID) {
vsb_printf(tl->sb, "Expected BYTES unit (B, KB, MB...) got ");
vcc_ErrToken(tl, tl->t);
vsb_printf(tl->sb, "\n");
vcc_ErrWhere(tl, tl->t);
return;
}
if (vcc_IdIs(tl->t, "B"))
sc = 1.;
else if (vcc_IdIs(tl->t, "KB"))
sc = 1024.;
else if (vcc_IdIs(tl->t, "MB"))
sc = 1024. * 1024.;
else if (vcc_IdIs(tl->t, "GB"))
sc = 1024. * 1024. * 1024.;
else if (vcc_IdIs(tl->t, "TB"))
sc = 1024. * 1024. * 1024. * 1024.;
else {
vsb_printf(tl->sb, "Unknown BYTES unit ");
vcc_ErrToken(tl, tl->t);
vsb_printf(tl->sb,
". Legal are 'B', 'KB', 'MB', 'GB' and 'TB'\n");
vcc_ErrWhere(tl, tl->t);
return;
}
vcc_NextToken(tl);
*d = v * sc;
}
/*--------------------------------------------------------------------
* Facility for carrying expressions around and do text-processing on
* them.
......@@ -396,6 +434,7 @@ vcc_expr_tostring(struct expr **e, enum var_type fmt)
/* XXX: should DURATION insist on "s" suffix ? */
case INT: p = "VRT_int_string(sp, \v1)"; break;
case IP: p = "VRT_IP_string(sp, \v1)"; break;
case BYTES: p = "VRT_double_string(sp, \v1)"; break; /* XXX */
case REAL: p = "VRT_double_string(sp, \v1)"; break;
case TIME: p = "VRT_time_string(sp, \v1)"; break;
default: break;
......@@ -609,11 +648,20 @@ vcc_expr4(struct vcc *tl, struct expr **e, enum var_type fmt)
*e = e1;
break;
case CNUM:
/*
* XXX: %g may not have enough decimals by default
* XXX: but %a is ugly, isn't it ?
*/
assert(fmt != VOID);
if (fmt == DURATION) {
vcc_RTimeVal(tl, &d);
ERRCHK(tl);
e1 = vcc_mk_expr(DURATION, "%g", d);
} else if (fmt == BYTES) {
vcc_ByteVal(tl, &d);
ERRCHK(tl);
e1 = vcc_mk_expr(BYTES, "%.1f", d);
ERRCHK(tl);
} else if (fmt == REAL) {
e1 = vcc_mk_expr(REAL, "%g", vcc_DoubleVal(tl));
ERRCHK(tl);
......@@ -654,6 +702,7 @@ vcc_expr_mul(struct vcc *tl, struct expr **e, enum var_type fmt)
switch(f2) {
case INT: f2 = INT; break;
case DURATION: f2 = REAL; break;
case BYTES: f2 = REAL; break;
default:
if (tl->t->tok != '*' && tl->t->tok != '/')
return;
......@@ -724,6 +773,7 @@ vcc_expr_add(struct vcc *tl, struct expr **e, enum var_type fmt)
case INT: break;
case TIME: break;
case DURATION: break;
case BYTES: break;
default:
if (tl->t->tok != '+' && tl->t->tok != '-')
return;
......@@ -742,6 +792,9 @@ vcc_expr_add(struct vcc *tl, struct expr **e, enum var_type fmt)
ERRCHK(tl);
if (tk->tok == '-' && (*e)->fmt == TIME && e2->fmt == TIME) {
/* OK */
} else if (tk->tok == '-' &&
(*e)->fmt == BYTES && e2->fmt == BYTES) {
/* OK */
} else if (e2->fmt != f2) {
vsb_printf(tl->sb, "%s %.*s %s not possible.\n",
vcc_Type((*e)->fmt), PF(tk), vcc_Type(e2->fmt));
......@@ -768,24 +821,22 @@ vcc_expr_add(struct vcc *tl, struct expr **e, enum var_type fmt)
* ExprAdd(IP) '!~' IP
*/
#define NUM_REL(typ) \
{typ, T_EQ, "(\v1 == \v2)" }, \
{typ, T_NEQ, "(\v1 != \v2)" }, \
{typ, T_LEQ, "(\v1 <= \v2)" }, \
{typ, T_GEQ, "(\v1 >= \v2)" }, \
{typ, '<', "(\v1 < \v2)" }, \
{typ, '>', "(\v1 > \v2)" }
static const struct cmps {
enum var_type fmt;
unsigned token;
const char *emit;
} vcc_cmps[] = {
{INT, T_EQ, "(\v1 == \v2)" },
{INT, T_NEQ, "(\v1 != \v2)" },
{INT, T_LEQ, "(\v1 <= \v2)" },
{INT, T_GEQ, "(\v1 >= \v2)" },
{INT, '<', "(\v1 < \v2)" },
{INT, '>', "(\v1 > \v2)" },
{DURATION, T_EQ, "(\v1 == \v2)" },
{DURATION, T_NEQ, "(\v1 != \v2)" },
{DURATION, T_LEQ, "(\v1 <= \v2)" },
{DURATION, T_GEQ, "(\v1 >= \v2)" },
{DURATION, '<', "(\v1 < \v2)" },
{DURATION, '>', "(\v1 > \v2)" },
NUM_REL(INT),
NUM_REL(DURATION),
NUM_REL(BYTES),
{STRING, T_EQ, "!VRT_strcmp(\v1, \v2)" },
{STRING, T_NEQ, "VRT_strcmp(\v1, \v2)" },
......@@ -793,6 +844,8 @@ static const struct cmps {
{VOID, 0, NULL}
};
#undef NUM_REL
static void
vcc_expr_cmp(struct vcc *tl, struct expr **e, enum var_type fmt)
{
......@@ -818,6 +871,7 @@ vcc_expr_cmp(struct vcc *tl, struct expr **e, enum var_type fmt)
if (cp->fmt != VOID) {
vcc_NextToken(tl);
vcc_expr_add(tl, &e2, (*e)->fmt);
ERRCHK(tl);
if (e2->fmt != (*e)->fmt) { /* XXX */
vsb_printf(tl->sb, "Comparison of different types: ");
vsb_printf(tl->sb, "%s ", vcc_Type((*e)->fmt));
......
......@@ -96,7 +96,7 @@ static struct stvars {
#define VRTSTVVAR(nm, vtype, ctype, dval) { #nm, vtype },
#include "vrt_stv_var.h"
#undef VRTSTVVAR
{ NULL, 0 }
{ NULL, BOOL }
};
struct symbol *
......
......@@ -39,5 +39,6 @@ VCC_TYPE(STRING)
VCC_TYPE(STRING_LIST)
VCC_TYPE(IP)
VCC_TYPE(HEADER)
VCC_TYPE(BYTES)
VCC_TYPE(REAL)
/*lint -restore */
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