[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