[master] 618908d Enable taglists in VSL query expressions

Martin Blix Grydeland martin at varnish-cache.org
Tue Oct 1 14:48:18 CEST 2013


commit 618908db7c66f1adad78e6e1b958213c472e0a44
Author: Martin Blix Grydeland <martin at varnish-software.com>
Date:   Wed Sep 25 13:21:02 2013 +0200

    Enable taglists in VSL query expressions

diff --git a/bin/varnishtest/tests/l00001.vtc b/bin/varnishtest/tests/l00001.vtc
index 3030d3e..b585fa2 100644
--- a/bin/varnishtest/tests/l00001.vtc
+++ b/bin/varnishtest/tests/l00001.vtc
@@ -172,3 +172,10 @@ logexpect l1 -d 1 -g vxid -q "RespHeader[2] == 123" {
 	  expect * =	ReqEnd
 	  expect * =	End
 } -run
+
+# Test taglists
+logexpect l1 -d 1 -g vxid -q "Debug,Resp* == 200" {
+	  expect 0 *	Begin	req
+	  expect * =	ReqEnd
+	  expect * =	End
+} -run
diff --git a/lib/libvarnishapi/vsl_api.h b/lib/libvarnishapi/vsl_api.h
index 7094fec..65007fd 100644
--- a/lib/libvarnishapi/vsl_api.h
+++ b/lib/libvarnishapi/vsl_api.h
@@ -40,6 +40,8 @@
 int vsl_diag(struct VSL_data *vsl, const char *fmt, ...)
     __printflike(2, 3);
 int vsl_skip(struct VSL_cursor *c, ssize_t words);
+void vsl_vbm_bitset(int bit, void *priv);
+void vsl_vbm_bitclr(int bit, void *priv);
 
 typedef void vslc_delete_f(struct VSL_cursor *);
 typedef int vslc_next_f(struct VSL_cursor *);
diff --git a/lib/libvarnishapi/vsl_arg.c b/lib/libvarnishapi/vsl_arg.c
index dc58a66..7795165 100644
--- a/lib/libvarnishapi/vsl_arg.c
+++ b/lib/libvarnishapi/vsl_arg.c
@@ -212,14 +212,14 @@ VSLQ_Name2Grouping(const char *name, int l)
 	return (n);
 }
 
-static void
+void __match_proto__(VSL_tagfind_f)
 vsl_vbm_bitset(int bit, void *priv)
 {
 
 	vbit_set((struct vbitmap *)priv, bit);
 }
 
-static void
+void __match_proto__(VSL_tagfind_f)
 vsl_vbm_bitclr(int bit, void *priv)
 {
 
diff --git a/lib/libvarnishapi/vsl_query.c b/lib/libvarnishapi/vsl_query.c
index e42705a..1ef92e9 100644
--- a/lib/libvarnishapi/vsl_query.c
+++ b/lib/libvarnishapi/vsl_query.c
@@ -39,6 +39,7 @@
 #include "miniobj.h"
 #include "vre.h"
 #include "vsb.h"
+#include "vbm.h"
 
 #include "vapi/vsl.h"
 #include "vsl_api.h"
@@ -187,6 +188,7 @@ vslq_test(const struct vex *vex, struct VSL_transaction * const ptrans[])
 
 	CHECK_OBJ_NOTNULL(vex, VEX_MAGIC);
 	CHECK_OBJ_NOTNULL(vex->lhs, VEX_LHS_MAGIC);
+	AN(vex->lhs->tags);
 	CHECK_OBJ_NOTNULL(vex->rhs, VEX_RHS_MAGIC);
 
 	for (t = ptrans[0]; t != NULL; t = *++ptrans) {
@@ -200,14 +202,12 @@ vslq_test(const struct vex *vex, struct VSL_transaction * const ptrans[])
 			assert(i == 1);
 			AN(t->c->rec.ptr);
 
-			if (vex->lhs->tag != VSL_TAG(t->c->rec.ptr))
+			if (!vbit_test(vex->lhs->tags, VSL_TAG(t->c->rec.ptr)))
 				continue;
 
 			i = vslq_test_rec(vex, &t->c->rec);
 			if (i)
 				return (i);
-
-
 		}
 	}
 
diff --git a/lib/libvarnishapi/vxp.h b/lib/libvarnishapi/vxp.h
index 73b3bc0..5d653bc 100644
--- a/lib/libvarnishapi/vxp.h
+++ b/lib/libvarnishapi/vxp.h
@@ -35,8 +35,8 @@
 
 #include "vxp_tokens.h"
 
-#define isword(c) \
-	(isalpha(c) || isdigit(c) || (c) == '_' || (c) == '-' || (c) == '.')
+#define isword(c)  (isalpha(c) || isdigit(c) || (c) == '_' || (c) == '-' || \
+	    (c) == '.' || (c) == '*' || (c) == ',')
 
 #define PF(t)	(int)((t)->e - (t)->b), (t)->b
 
@@ -82,7 +82,7 @@ struct vex_lhs {
 	   expression should be applied to */
 	unsigned		magic;
 #define VEX_LHS_MAGIC		0x1AD3D78D
-	int			tag;
+	struct vbitmap		*tags;
 	int			field;
 	int			level_min;
 	int			level_max;
diff --git a/lib/libvarnishapi/vxp_parse.c b/lib/libvarnishapi/vxp_parse.c
index aad8bde..83e6594 100644
--- a/lib/libvarnishapi/vxp_parse.c
+++ b/lib/libvarnishapi/vxp_parse.c
@@ -40,8 +40,10 @@
 
 #include "vas.h"
 #include "vsb.h"
+#include "vbm.h"
 #include "miniobj.h"
 #include "vapi/vsl.h"
+#include "vsl_api.h"
 
 #include "vxp.h"
 
@@ -51,29 +53,36 @@ static void
 vxp_expr_lhs(struct vxp *vxp, struct vex_lhs **plhs)
 {
 	char *p;
+	int i;
 
-	/* XXX: Tag wildcards */
 	AN(plhs);
 	AZ(*plhs);
 	if (vxp->t->tok != VAL) {
-		VSB_printf(vxp->sb, "Expected VSL tag got '%.*s' ", PF(vxp->t));
+		VSB_printf(vxp->sb, "Expected VSL taglist got '%.*s' ",
+		    PF(vxp->t));
 		vxp_ErrWhere(vxp, vxp->t, -1);
 		return;
 	}
 	ALLOC_OBJ(*plhs, VEX_LHS_MAGIC);
 	AN(*plhs);
-	(*plhs)->tag = VSL_Name2Tag(vxp->t->dec, -1);
-	if ((*plhs)->tag == -1) {
-		VSB_printf(vxp->sb, "Could not match '%.*s' to any tag ",
-		    PF(vxp->t));
+	(*plhs)->tags = vbit_init(SLT__MAX);
+	i = VSL_List2Tags(vxp->t->dec, -1, vsl_vbm_bitset, (*plhs)->tags);
+	if (i == -1) {
+		VSB_printf(vxp->sb, "Taglist matches zero tags");
 		vxp_ErrWhere(vxp, vxp->t, -1);
 		return;
-	} else if ((*plhs)->tag == -2) {
-		VSB_printf(vxp->sb, "'%.*s' matches multiple tags ",
-		    PF(vxp->t));
+	}
+	if (i == -2) {
+		VSB_printf(vxp->sb, "Taglist is ambiguous");
+		vxp_ErrWhere(vxp, vxp->t, -1);
+		return;
+	}
+	if (i == -3) {
+		VSB_printf(vxp->sb, "Syntax error in taglist");
 		vxp_ErrWhere(vxp, vxp->t, -1);
 		return;
 	}
+	assert(i > 0);
 	vxp_NextToken(vxp);
 
 	if (vxp->t->tok == '[') {
@@ -422,8 +431,11 @@ void
 vex_Free(struct vex **pvex)
 {
 
-	if ((*pvex)->lhs != NULL)
+	if ((*pvex)->lhs != NULL) {
+		if ((*pvex)->lhs->tags != NULL)
+			vbit_destroy((*pvex)->lhs->tags);
 		FREE_OBJ((*pvex)->lhs);
+	}
 	if ((*pvex)->rhs != NULL) {
 		if ((*pvex)->rhs->val_string)
 			free((*pvex)->rhs->val_string);
@@ -473,6 +485,25 @@ vex_print_rhs(const struct vex_rhs *rhs)
 }
 
 static void
+vex_print_tags(const struct vbitmap *vbm)
+{
+	int i;
+	int first = 1;
+
+	for (i = 0; i < SLT__MAX; i++) {
+		if (VSL_tags[i] == NULL)
+			continue;
+		if (!vbit_test(vbm, i))
+			continue;
+		if (first)
+			first = 0;
+		else
+			fprintf(stderr, ",");
+		fprintf(stderr, "%s", VSL_tags[i]);
+	}
+}
+
+static void
 vex_print(const struct vex *vex, int indent)
 {
 	CHECK_OBJ_NOTNULL(vex, VEX_MAGIC);
@@ -480,7 +511,10 @@ vex_print(const struct vex *vex, int indent)
 	fprintf(stderr, "%*s%s", indent, "", vxp_tnames[vex->tok]);
 	if (vex->lhs != NULL) {
 		CHECK_OBJ_NOTNULL(vex->lhs, VEX_LHS_MAGIC);
-		fprintf(stderr, " tag=%s", VSL_tags[vex->lhs->tag]);
+		AN(vex->lhs->tags);
+		fprintf(stderr, " lhs=(");
+		vex_print_tags(vex->lhs->tags);
+		fprintf(stderr, ")");
 		if (vex->lhs->field >= 0)
 			fprintf(stderr, "[%d]", vex->lhs->field);
 	}



More information about the varnish-commit mailing list