[master] 6f9595e More VCC changes

Federico G. Schwindt fgsch at lodoss.net
Mon Jan 30 15:17:05 CET 2017


commit 6f9595e6563cf53118048bcb5d1591a6b631b84c
Author: Federico G. Schwindt <fgsch at lodoss.net>
Date:   Mon Jan 30 14:08:09 2017 +0000

    More VCC changes
    
    - Try to distinguish between DURATION, REAL and INT automatically.
    - Explicitly mention which operands are possible when adding.
    
    Related to #2101.

diff --git a/bin/varnishtest/tests/v00020.vtc b/bin/varnishtest/tests/v00020.vtc
index e76e2cb..e7c0bb5 100644
--- a/bin/varnishtest/tests/v00020.vtc
+++ b/bin/varnishtest/tests/v00020.vtc
@@ -165,8 +165,7 @@ varnish v1 -errvcl {TIME + TIME not possible.} {
 	}
 }
 
-# XXX: error message should say something about DURATION
-varnish v1 -errvcl {Expected ID got ';'} {
+varnish v1 -errvcl {TIME + INT not possible.} {
 	backend b { .host = "127.0.0.1"; }
 	sub vcl_recv {
 		set req.http.foo = now + 1;
@@ -187,56 +186,42 @@ varnish v1 -errvcl {INT + TIME not possible.} {
 	}
 }
 
-# XXX: error message should spot DURATION
-varnish v1 -errvcl {Expected ';' got 's'} {
+varnish v1 -errvcl {INT + DURATION not possible.} {
 	backend b { .host = "127.0.0.1"; }
 	sub vcl_recv {
 		set req.http.foo = 1 + 1s;
 	}
 }
 
-# XXX: should spot DURATION
-varnish v1 -errvcl {Expected ';' got 's'} {
-	backend b { .host = "127.0.0.1"; }
-	sub vcl_recv {
-		set req.http.foo = 1s;
-	}
-}
-
-# XXX: should spot DURATION
-varnish v1 -errvcl {Expected ';' got 's'} {
+varnish v1 -errvcl {DURATION + INT not possible.} {
 	backend b { .host = "127.0.0.1"; }
 	sub vcl_recv {
 		set req.http.foo = 1s + 1;
 	}
 }
 
-# XXX: should spot DURATION
-varnish v1 -errvcl {Expected ';' got 's'} {
+varnish v1 -errvcl {DURATION + TIME not possible.} {
 	backend b { .host = "127.0.0.1"; }
 	sub vcl_recv {
 		set req.http.foo = 1s + now;
 	}
 }
 
-# XXX: should spot DURATION
-varnish v1 -errvcl {Expected ';' got 's'} {
+varnish v1 -errvcl {DURATION + STRING not possible.} {
 	backend b { .host = "127.0.0.1"; }
 	sub vcl_recv {
 		set req.http.foo = 1s + "foo";
 	}
 }
 
-# XXX: should spot DURATION
-varnish v1 -errvcl {Expected ';' got 's'} {
+varnish v1 -errvcl {STRING + DURATION not possible.} {
 	backend b { .host = "127.0.0.1"; }
 	sub vcl_recv {
 		set req.http.foo = "foo" + 1s;
 	}
 }
 
-# XXX: should spot DURATION
-varnish v1 -errvcl {Expected ID got ';'} {
+varnish v1 -errvcl {DURATION + INT not possible.} {
 	backend b { .host = "127.0.0.1"; }
 	sub vcl_recv {
 		set req.ttl = 1s + 1;
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index 415d54b..52c0041 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -847,24 +847,18 @@ vcc_expr4(struct vcc *tl, struct expr **e, vcc_type_t fmt)
 		 * XXX: but %a is ugly, isn't it ?
 		 */
 		assert(fmt != VOID);
-		if (fmt == DURATION) {
-			vcc_Duration(tl, &d);
-			ERRCHK(tl);
-			e1 = vcc_mk_expr(DURATION, "%g", d);
-		} else if (fmt == BYTES) {
+		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, "%f", vcc_DoubleVal(tl));
-			ERRCHK(tl);
-		} else if (fmt == INT) {
-			e1 = vcc_mk_expr(INT, "%.*s", PF(tl->t));
-			vcc_NextToken(tl);
 		} else {
 			vcc_NumVal(tl, &d, &i);
-			if (i)
+			ERRCHK(tl);
+			if (tl->t->tok == ID) {
+				e1 = vcc_mk_expr(DURATION, "%g",
+				    d * vcc_TimeUnit(tl));
+				ERRCHK(tl);
+			} else if (i || fmt == REAL)
 				e1 = vcc_mk_expr(REAL, "%f", d);
 			else
 				e1 = vcc_mk_expr(INT, "%ld", (long)d);
@@ -1000,12 +994,51 @@ vcc_expr_string_add(struct vcc *tl, struct expr **e, struct expr *e2)
 	}
 }
 
+static const struct adds {
+	unsigned	op;
+	vcc_type_t	a;
+	vcc_type_t	b;
+	vcc_type_t	fmt;
+} vcc_adds[] = {
+	/* OK */
+	{ '-', TIME,		TIME,		DURATION },
+	{ '+', TIME,		DURATION,	TIME },
+	{ '-', TIME,		DURATION,	TIME },
+	{ '+', DURATION,	DURATION,	DURATION },
+	{ '-', DURATION,	DURATION,	DURATION },
+	{ '+', BYTES,		BYTES,		BYTES },
+	{ '-', BYTES,		BYTES,		BYTES },
+	{ '+', INT,		INT,		INT },
+	{ '-', INT,		INT,		INT },
+	{ '+', REAL,		REAL,		REAL },
+	{ '-', REAL,		REAL,		REAL },
+	{ '+', REAL,		INT,		REAL },
+	{ '-', REAL,		INT,		REAL },
+	{ '+', INT,		REAL,		REAL },
+	{ '-', INT,		REAL,		REAL },
+
+	/* Error */
+	{ '+', TIME,		INT,		VOID },
+	{ '+', TIME,		REAL,		VOID },
+	{ '+', INT,		DURATION,	VOID },
+	{ '+', REAL,		DURATION,	VOID },
+	{ '+', DURATION,	INT,		VOID },
+	{ '+', DURATION,	REAL,		VOID },
+	{ '+', DURATION,	TIME,		VOID },
+	{ '+', DURATION,	STRING,		VOID },
+	{ '+', STRING,		DURATION,	VOID },
+
+	{ EOI, VOID, VOID, VOID }
+};
+
 static void
 vcc_expr_add(struct vcc *tl, struct expr **e, vcc_type_t fmt)
 {
+	const struct adds *ap;
 	struct expr  *e2;
 	vcc_type_t f2;
 	struct token *tk;
+	char buf[128];
 
 	*e = NULL;
 	vcc_expr_mul(tl, e, fmt);
@@ -1021,31 +1054,19 @@ vcc_expr_add(struct vcc *tl, struct expr **e, vcc_type_t fmt)
 			vcc_expr_mul(tl, &e2, f2);
 		ERRCHK(tl);
 
-#define ADD_OK(op, a, b, c)						  \
-		if (tk->tok == op[0] && (*e)->fmt == a && e2->fmt == b) { \
-			*e = vcc_expr_edit(c, "(\v1 " op " \v2)", *e, e2);\
-			continue;					  \
-		}							  \
-
-		ADD_OK("-", TIME,	TIME,		DURATION);
-		ADD_OK("+", TIME,	DURATION,	TIME);
-		ADD_OK("-", TIME,	DURATION,	TIME);
-		ADD_OK("+", DURATION,	DURATION,	DURATION);
-		ADD_OK("-", DURATION,	DURATION,	DURATION);
-		ADD_OK("+", BYTES,	BYTES,		BYTES);
-		ADD_OK("-", BYTES,	BYTES,		BYTES);
-		ADD_OK("+", INT,	INT,		INT);
-		ADD_OK("-", INT,	INT,		INT);
-		ADD_OK("+", REAL,	REAL,		REAL);
-		ADD_OK("-", REAL,	REAL,		REAL);
-		ADD_OK("+", REAL,	INT,		REAL);
-		ADD_OK("-", REAL,	INT,		REAL);
-		ADD_OK("+", INT,	REAL,		REAL);
-		ADD_OK("-", INT,	REAL,		REAL);
-
-#undef ADD_OK
-
-		if (tk->tok == '+') {
+		for (ap = vcc_adds; ap->op != EOI; ap++) {
+			if (tk->tok == ap->op && (*e)->fmt == ap->a &&
+			    e2->fmt == ap->b)
+				break;
+		}
+
+		if (ap->fmt != VOID) {
+			bprintf(buf, "(\v1 %c \v2)", ap->op);
+			*e = vcc_expr_edit(ap->fmt, buf, *e, e2);
+			continue;
+		}
+
+		if (tk->tok == '+' && ap->op == EOI) {
 			if ((*e)->fmt == STRING && e2->fmt == STRING) {
 				vcc_expr_string_add(tl, e, e2);
 				return;



More information about the varnish-commit mailing list