[master] 8bb7e90 Switch to globbing on the whole string

Federico G. Schwindt fgsch at lodoss.net
Mon Sep 12 23:59:10 CEST 2016


commit 8bb7e90f9adf8502cd0be382cb546a28f9e24390
Author: Federico G. Schwindt <fgsch at lodoss.net>
Date:   Sun Sep 11 03:09:54 2016 +0100

    Switch to globbing on the whole string
    
    Fixes #2022

diff --git a/bin/varnishstat/varnishstat_options.h b/bin/varnishstat/varnishstat_options.h
index ceeafac..65a961c 100644
--- a/bin/varnishstat/varnishstat_options.h
+++ b/bin/varnishstat/varnishstat_options.h
@@ -39,13 +39,10 @@
 #define STAT_OPT_f							\
 	VOPT("f:", "[-f <glob>]", "Field inclusion glob",		\
 	    "Field inclusion glob."					\
-	    " A field glob consists of three parts, type, ident and"	\
-	    " name, where ident is optional. Each part can contain a"	\
-	    " '*' character at the end to match a prefix. Use"		\
-	    " backslash to escape characters. If the argument starts"	\
-	    " with '^' it is used as an exclusion glob. Multiple -f"	\
-	    " arguments may be given, and they will be applied in"	\
-	    " order."							\
+	    " Use backslash to escape characters. If the argument"	\
+	    " starts with '^' it is used as an exclusion glob."		\
+	    " Multiple -f arguments may be given, and they will be"	\
+	    " applied in order."					\
 	)
 #define STAT_OPT_j							\
 	VOPT("j", "[-j]", "Print statistics to stdout as JSON",		\
diff --git a/bin/varnishtest/tests/u00002.vtc b/bin/varnishtest/tests/u00002.vtc
index 38ce280..9f083ec 100644
--- a/bin/varnishtest/tests/u00002.vtc
+++ b/bin/varnishtest/tests/u00002.vtc
@@ -15,3 +15,12 @@ process p1 {varnishstat -1 -n ${v1_name} -f ^LCK.vbe.destroy \
 shell "grep -q vbe ${tmpdir}/p1/stdout"
 shell "grep -q mempool ${tmpdir}/p1/stdout"
 err_shell "" "grep -q LCK.vbe.destroy ${tmpdir}/p1/stdout"
+
+process p2 {varnishstat -1 -n ${v1_name} -f ^*vbe.destroy \
+	-f *vbe* -f *mempool*} -run
+
+shell "grep -q vbe ${tmpdir}/p2/stdout"
+shell "grep -q mempool ${tmpdir}/p2/stdout"
+err_shell "" "grep -q LCK.vbe.destroy ${tmpdir}/p2/stdout"
+
+shell "cmp -s ${tmpdir}/p1/stdout ${tmpdir}/p2/stdout"
diff --git a/lib/libvarnishapi/vsc.c b/lib/libvarnishapi/vsc.c
index f051cea..6af266e 100644
--- a/lib/libvarnishapi/vsc.c
+++ b/lib/libvarnishapi/vsc.c
@@ -33,6 +33,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 
+#include <fnmatch.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -42,6 +43,7 @@
 #include "vas.h"
 #include "miniobj.h"
 #include "vqueue.h"
+#include "vsb.h"
 
 #include "vapi/vsc.h"
 #include "vapi/vsm.h"
@@ -75,14 +77,8 @@ struct vsc_sf {
 	unsigned		magic;
 #define VSC_SF_MAGIC		0x558478dd
 	VTAILQ_ENTRY(vsc_sf)	list;
-	int			flags;
-#define VSC_SF_EXCL		(1 << 0)
-#define VSC_SF_TY_WC		(1 << 1)
-#define VSC_SF_ID_WC		(1 << 2)
-#define VSC_SF_NM_WC		(1 << 3)
-	char			*type;
-	char			*ident;
-	char			*name;
+	char			*pattern;
+	unsigned		exclude;
 };
 
 struct vsc {
@@ -151,9 +147,7 @@ vsc_delete_sf_list(struct vsc *vsc)
 		sf = VTAILQ_FIRST(&vsc->sf_list);
 		CHECK_OBJ_NOTNULL(sf, VSC_SF_MAGIC);
 		VTAILQ_REMOVE(&vsc->sf_list, sf, list);
-		free(sf->type);
-		free(sf->ident);
-		free(sf->name);
+		free(sf->pattern);
 		FREE_OBJ(sf);
 	}
 }
@@ -180,105 +174,20 @@ vsc_f_arg(struct VSM_data *vd, const char *opt)
 {
 	struct vsc *vsc = vsc_setup(vd);
 	struct vsc_sf *sf;
-	const char *error = NULL;
-	const char *p, *q;
-	char *r;
-	int i;
-	int flags = 0;
-	char *parts[3];
 
 	AN(vd);
 	AN(opt);
 
-	if (opt[0] == '^') {
-		flags |= VSC_SF_EXCL;
-		opt++;
-	}
-
-	/* Split on '.' */
-	memset(parts, 0, sizeof parts);
-	for (i = 0, p = opt; *p != '\0'; i++) {
-		for (q = p; *q != '\0' && *q != '.'; q++)
-			if (*q == '\\')
-				q++;
-		if (i < 3) {
-			parts[i] = malloc(1 + q - p);
-			AN(parts[i]);
-			memcpy(parts[i], p, q - p);
-			parts[i][q - p] = '\0';
-			p = r = parts[i];
-
-			/* Unescape */
-			while (1) {
-				if (*p == '\\')
-					p++;
-				if (*p == '\0')
-					break;
-				*r++ = *p++;
-			}
-			*r = '\0';
-		}
-		p = q;
-		if (*p == '.')
-			p++;
-	}
-	if (i < 1 || i > 3) {
-		(void)vsm_diag(vd, "-f: Wrong number of elements");
-		for (i = 0; i < 3; i++)
-			free(parts[i]);
-		return (-1);
-	}
-
-	/* Set fields */
 	ALLOC_OBJ(sf, VSC_SF_MAGIC);
 	AN(sf);
-	sf->flags = flags;
-	AN(parts[0]);
-	sf->type = parts[0];
-	if (i == 2) {
-		AN(parts[1]);
-		sf->name = parts[1];
-	} else if (i == 3) {
-		AN(parts[1]);
-		sf->ident = parts[1];
-		AN(parts[2]);
-		sf->name = parts[2];
-	}
 
-	/* Check for wildcards */
-	if (sf->type != NULL) {
-		r = strchr(sf->type, '*');
-		if (r != NULL && r[1] == '\0') {
-			*r = '\0';
-			sf->flags |= VSC_SF_TY_WC;
-		} else if (r != NULL)
-			error = "-f: Wildcard not last";
-	}
-	if (sf->ident != NULL) {
-		r = strchr(sf->ident, '*');
-		if (r != NULL && r[1] == '\0') {
-			*r = '\0';
-			sf->flags |= VSC_SF_ID_WC;
-		} else if (r != NULL)
-			error = "-f: Wildcard not last";
-	}
-	if (sf->name != NULL) {
-		r = strchr(sf->name, '*');
-		if (r != NULL && r[1] == '\0') {
-			*r = '\0';
-			sf->flags |= VSC_SF_NM_WC;
-		} else if (r != NULL)
-			error = "-f: Wildcard not last";
+	if (opt[0] == '^') {
+		sf->exclude = 1;
+		opt++;
 	}
 
-	if (error != NULL) {
-		(void)vsm_diag(vd, "%s", error);
-		free(sf->type);
-		free(sf->ident);
-		free(sf->name);
-		FREE_OBJ(sf);
-		return (-1);
-	}
+	sf->pattern = strdup(opt);
+	AN(sf->pattern);
 
 	VTAILQ_INSERT_TAIL(&vsc->sf_list, sf, list);
 	return (1);
@@ -449,52 +358,43 @@ vsc_build_pt_list(struct VSM_data *vd)
 /*--------------------------------------------------------------------
  */
 
-static inline int
-iter_test(const char *s1, const char *s2, int wc)
-{
-
-	if (s1 == NULL)
-		return (0);
-	if (!wc)
-		return (strcmp(s1, s2));
-	for (; *s1 != '\0' && *s1 == *s2; s1++, s2++)
-		continue;
-	return (*s1 != '\0');
-}
-
 static void
 vsc_filter_pt_list(struct VSM_data *vd)
 {
 	struct vsc *vsc = vsc_setup(vd);
 	struct vsc_sf *sf;
 	struct vsc_pt *pt, *pt2;
-	VTAILQ_HEAD(, vsc_pt)	pt_list;
+	VTAILQ_HEAD(, vsc_pt) pt_list;
+	struct vsb *vsb;
 
 	if (VTAILQ_EMPTY(&vsc->sf_list))
 		return;
 
+	vsb = VSB_new_auto();
+	AN(vsb);
+
 	VTAILQ_INIT(&pt_list);
 	VTAILQ_FOREACH(sf, &vsc->sf_list, list) {
 		CHECK_OBJ_NOTNULL(sf, VSC_SF_MAGIC);
 		VTAILQ_FOREACH_SAFE(pt, &vsc->pt_list, list, pt2) {
 			CHECK_OBJ_NOTNULL(pt, VSC_PT_MAGIC);
-			if (iter_test(sf->type, pt->point.section->type,
-			    sf->flags & VSC_SF_TY_WC))
-				continue;
-			if (iter_test(sf->ident, pt->point.section->ident,
-			    sf->flags & VSC_SF_ID_WC))
-				continue;
-			if (iter_test(sf->name, pt->point.desc->name,
-			    sf->flags & VSC_SF_NM_WC))
+			VSB_clear(vsb);
+			VSB_printf(vsb, "%s.%s.%s",
+			    pt->point.section->type,
+			    pt->point.section->ident,
+			    pt->point.desc->name);
+			VSB_finish(vsb);
+			if (fnmatch(sf->pattern, VSB_data(vsb), 0))
 				continue;
 			VTAILQ_REMOVE(&vsc->pt_list, pt, list);
-			if (sf->flags & VSC_SF_EXCL) {
+			if (sf->exclude)
 				FREE_OBJ(pt);
-			} else {
+			else
 				VTAILQ_INSERT_TAIL(&pt_list, pt, list);
-			}
 		}
 	}
+
+	VSB_destroy(&vsb);
 	vsc_delete_pt_list(vsc);
 	VTAILQ_CONCAT(&vsc->pt_list, &pt_list, list);
 }



More information about the varnish-commit mailing list