r5014 - trunk/varnish-cache/lib/libvcl

phk at varnish-cache.org phk at varnish-cache.org
Mon Jul 5 23:51:42 CEST 2010


Author: phk
Date: 2010-07-05 23:51:42 +0200 (Mon, 05 Jul 2010)
New Revision: 5014

Added:
   trunk/varnish-cache/lib/libvcl/vcc_types.h
Modified:
   trunk/varnish-cache/lib/libvcl/Makefile.am
   trunk/varnish-cache/lib/libvcl/vcc_compile.c
   trunk/varnish-cache/lib/libvcl/vcc_compile.h
   trunk/varnish-cache/lib/libvcl/vcc_parse.c
   trunk/varnish-cache/lib/libvcl/vcc_var.c
Log:
Start massaging the conditional parsing to handle non-variable left sides.



Modified: trunk/varnish-cache/lib/libvcl/Makefile.am
===================================================================
--- trunk/varnish-cache/lib/libvcl/Makefile.am	2010-07-05 21:01:42 UTC (rev 5013)
+++ trunk/varnish-cache/lib/libvcl/Makefile.am	2010-07-05 21:51:42 UTC (rev 5014)
@@ -10,6 +10,7 @@
 	vcc_priv.h \
 	vcc_compile.h \
 	vcc_token_defs.h \
+	vcc_types.h \
 	\
 	vcc_acl.c \
 	vcc_action.c \

Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_compile.c	2010-07-05 21:01:42 UTC (rev 5013)
+++ trunk/varnish-cache/lib/libvcl/vcc_compile.c	2010-07-05 21:51:42 UTC (rev 5014)
@@ -556,6 +556,8 @@
 	for (v = tl->vars; v->name != NULL; v++) {
 		sym = VCC_AddSymbol(tl, v->name);
 		sym->var = v;
+		sym->fmt = v->fmt;
+		sym->r_methods = v->r_methods;
 		if (v->fmt == HEADER)
 			sym->wildcard = 1;
 	}

Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.h
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_compile.h	2010-07-05 21:01:42 UTC (rev 5013)
+++ trunk/varnish-cache/lib/libvcl/vcc_compile.h	2010-07-05 21:51:42 UTC (rev 5014)
@@ -38,6 +38,12 @@
 
 struct acl_e;
 
+enum var_type {
+#define VCC_TYPE(foo)	foo,
+#include "vcc_types.h"
+#undef VCC_TYPE
+};
+
 struct membit {
 	VTAILQ_ENTRY(membit)	list;
 	void			*ptr;
@@ -70,6 +76,8 @@
 	unsigned			nlen;
 	unsigned			wildcard;
 	const struct var		*var;
+	enum var_type			fmt;
+	unsigned			r_methods;
 };
 
 VTAILQ_HEAD(tokenhead, token);
@@ -129,19 +137,6 @@
 	unsigned		nsockaddr;
 };
 
-enum var_type {
-	BACKEND,
-	BOOL,
-	INT,
-	// SIZE,
-	// FLOAT,
-	TIME,
-	DURATION,
-	STRING,
-	IP,
-	HEADER
-};
-
 enum ref_type {
 	R_SUB,
 	R_ACL,
@@ -164,7 +159,7 @@
 	const char		*rname;
 	unsigned		r_methods;
 	const char		*lname;
-	unsigned		l_methods;
+	unsigned		w_methods;
 	const char		*hdr;
 };
 
@@ -227,7 +222,7 @@
 void vcc_Parse(struct vcc *tl);
 void vcc_RTimeVal(struct vcc *tl, double *);
 void vcc_TimeVal(struct vcc *tl, double *);
-void vcc_SizeVal(struct vcc *tl, double *);
+// void vcc_SizeVal(struct vcc *tl, double *);
 unsigned vcc_UintVal(struct vcc *tl);
 double vcc_DoubleVal(struct vcc *tl);
 

Modified: trunk/varnish-cache/lib/libvcl/vcc_parse.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_parse.c	2010-07-05 21:01:42 UTC (rev 5013)
+++ trunk/varnish-cache/lib/libvcl/vcc_parse.c	2010-07-05 21:51:42 UTC (rev 5014)
@@ -323,11 +323,93 @@
 	vcc_NextToken(tl);
 }
 
+const char *typenm[] = {
+#define VCC_TYPE(foo)	[foo] = #foo,
+#include "vcc_types.h"
+#undef VCC_TYPE
+};
+
+static int
+vcc_Relation(struct vcc *tl, enum var_type fmt)
+{
+
+	switch(tl->t->tok) {
+	case T_EQ:
+	case T_NEQ:
+		if (fmt != BOOL)
+			return (tl->t->tok);
+		break;
+	case '>':
+	case T_GEQ:
+	case '<':
+	case T_LEQ:
+		if (fmt == INT || fmt == TIME || fmt == DURATION)
+			return (tl->t->tok);
+		break;
+	case '~':
+	case T_NOMATCH:
+		if (fmt == IP || fmt == STRING || fmt == HEADER)
+			return (tl->t->tok);
+		break;
+	default:
+		if (fmt == STRING || fmt == HEADER || fmt == BOOL)
+			return (-1);
+		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
-vcc_Cond_2(struct vcc *tl)
+vcc_Cond_3(struct vcc *tl)
 {
 	const struct var *vp;
+	const struct symbol *sym;
 
+	sym = VCC_FindSymbol(tl, tl->t);
+	if (sym == NULL) {
+		vsb_printf(tl->sb,
+		    "Syntax error in condition.\n"
+		    "Expected '(', '!' or variable name.\n"
+		    "Found ");
+		vcc_ErrToken(tl, tl->t);
+		vsb_printf(tl->sb, "\n");
+		vcc_ErrWhere(tl, tl->t);
+		return;
+	}
+	vcc_AddUses(tl, tl->t, sym->r_methods, "Not available");
+	AN(sym->var);
+	vp = vcc_FindVar(tl, tl->t, 0, "cannot be read");
+	ERRCHK(tl);
+	assert(vp != NULL);
+	vcc_NextToken(tl);
+	vcc_Relation(tl, sym->fmt);
+	switch (vp->fmt) {
+	case INT:	L(tl, vcc_Cond_Int(vp, tl)); break;
+	// case SIZE:	L(tl, vcc_Cond_Int(vp, tl)); break;
+	case BOOL:	L(tl, vcc_Cond_Bool(vp, tl)); break;
+	case IP:	L(tl, vcc_Cond_Ip(vp, tl)); break;
+	case STRING:	L(tl, vcc_Cond_String(vp, tl)); break;
+	case TIME:	L(tl, vcc_Cond_Int(vp, tl)); break;
+	case DURATION:	L(tl, vcc_Cond_Int(vp, tl)); break;
+	case BACKEND:	L(tl, vcc_Cond_Backend(vp, tl)); break;
+	default:
+		vsb_printf(tl->sb,
+		    "Variable '%s'"
+		    " has no conditions that can be checked\n",
+		    vp->name);
+		vcc_ErrWhere(tl, tl->t);
+		return;
+	}
+}
+
+static void
+vcc_Cond_2(struct vcc *tl)
+{
+
 	C(tl, ",");
 	if (tl->t->tok == '!') {
 		Fb(tl, 1, "!(\n");
@@ -339,38 +421,22 @@
 		vcc_NextToken(tl);
 		vcc_Cond_0(tl);
 		SkipToken(tl, ')');
-	} else if (tl->t->tok == ID) {
-		vp = vcc_FindVar(tl, tl->t, 0, "cannot be read");
-		ERRCHK(tl);
-		assert(vp != NULL);
-		vcc_NextToken(tl);
-		switch (vp->fmt) {
-		case INT:	L(tl, vcc_Cond_Int(vp, tl)); break;
-		// case SIZE:	L(tl, vcc_Cond_Int(vp, tl)); break;
-		case BOOL:	L(tl, vcc_Cond_Bool(vp, tl)); break;
-		case IP:	L(tl, vcc_Cond_Ip(vp, tl)); break;
-		case STRING:	L(tl, vcc_Cond_String(vp, tl)); break;
-		case TIME:	L(tl, vcc_Cond_Int(vp, tl)); break;
-		case DURATION:	L(tl, vcc_Cond_Int(vp, tl)); break;
-		case BACKEND:	L(tl, vcc_Cond_Backend(vp, tl)); break;
-		default:
-			vsb_printf(tl->sb,
-			    "Variable '%s'"
-			    " has no conditions that can be checked\n",
-			    vp->name);
-			vcc_ErrWhere(tl, tl->t);
-			return;
-		}
-	} else {
-		vsb_printf(tl->sb,
-		    "Syntax error in condition, expected '(', '!' or"
-		    " variable name, found ");
-		vcc_ErrToken(tl, tl->t);
-		vsb_printf(tl->sb, "\n");
-		vcc_ErrWhere(tl, tl->t);
+		Fb(tl, 1, ")\n");
 		return;
 	}
-	Fb(tl, 1, ")\n");
+	if (tl->t->tok == ID) {
+		vcc_Cond_3(tl);
+		Fb(tl, 1, ")\n");
+		return;
+	} 
+	vsb_printf(tl->sb,
+	    "Syntax error in condition.\n"
+	    "Expected '(', '!' or variable name.\n"
+	    "Found ");
+	vcc_ErrToken(tl, tl->t);
+	vsb_printf(tl->sb, "\n");
+	vcc_ErrWhere(tl, tl->t);
+	return;
 }
 
 static void

Added: trunk/varnish-cache/lib/libvcl/vcc_types.h
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_types.h	                        (rev 0)
+++ trunk/varnish-cache/lib/libvcl/vcc_types.h	2010-07-05 21:51:42 UTC (rev 5014)
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2010 Linpro AS
+ * All rights reserved.
+ *
+ * Author: Poul-Henning Kamp <phk at phk.freebsd.dk>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $Id$
+ */
+
+VCC_TYPE(BACKEND)
+VCC_TYPE(BOOL)
+VCC_TYPE(INT)
+VCC_TYPE(TIME)
+VCC_TYPE(DURATION)
+VCC_TYPE(STRING)
+VCC_TYPE(IP)
+VCC_TYPE(HEADER)

Modified: trunk/varnish-cache/lib/libvcl/vcc_var.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_var.c	2010-07-05 21:01:42 UTC (rev 5013)
+++ trunk/varnish-cache/lib/libvcl/vcc_var.c	2010-07-05 21:51:42 UTC (rev 5014)
@@ -62,7 +62,7 @@
 	p[i] = '\0';
 	v->name = p;
 	v->r_methods = vh->r_methods;
-	v->l_methods = vh->l_methods;
+	v->w_methods = vh->w_methods;
 	v->fmt = STRING;
 	v->hdr = vh->hdr;
 	l = strlen(v->name + vh->len) + 1;
@@ -99,7 +99,7 @@
 		v = sym->var;
 		AN(v);
 
-		if (wr_access && v->l_methods == 0) {
+		if (wr_access && v->w_methods == 0) {
 			vsb_printf(tl->sb, "Variable ");
 			vcc_ErrToken(tl, t);
 			vsb_printf(tl->sb, " is read only.");
@@ -107,7 +107,7 @@
 			vcc_ErrWhere(tl, t);
 			return (NULL);
 		} else if (wr_access) {
-			vcc_AddUses(tl, t, v->l_methods, use);
+			vcc_AddUses(tl, t, v->w_methods, use);
 		} else if (v->r_methods == 0) {
 			vsb_printf(tl->sb, "Variable ");
 			vcc_ErrToken(tl, t);




More information about the varnish-commit mailing list