[experimental-ims] 5a7a850 New VSL api

Geoff Simmons geoff at varnish-cache.org
Mon Jan 9 21:52:41 CET 2012


commit 5a7a850f2d42aea69a782cff92d50aad88cfce43
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Nov 22 10:35:34 2011 +0000

    New VSL api

diff --git a/include/vapi/vsl.h b/include/vapi/vsl.h
index fb02051..35e09dc 100644
--- a/include/vapi/vsl.h
+++ b/include/vapi/vsl.h
@@ -26,6 +26,17 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
+ * This is the public API for the VSL access.
+ *
+ * VSL is a "subclass" of VSM.
+ *
+ * VSL can either read from VSM or from a file.
+ *
+ * When reading from a file, the filename is passed in with:
+ *	VSL_Arg(vd, "r", "/some/file");
+ * and once VSL_Dispatch()/VSL_NextSLT() will indicate EOF by returning -2.
+ * Another file can then be opened with VSL_Arg() and processed.
+ * 
  */
 
 #ifndef VAPI_VSL_H_INCLUDED
@@ -39,21 +50,6 @@ struct VSM_data;
  * VSL level access functions
  */
 
-void VSL_Setup(struct VSM_data *vd);
-	/*
-	 * Setup vd for use with VSL functions.
-	 * Must be called once before any other VSL function is called.
-	 */
-
-int VSL_Open(struct VSM_data *vd, int diag);
-	/*
-	 * Attempt to open the VSM (unless -r given)
-	 * If diag is non-zero, diagnostics are emitted.
-	 * Returns:
-	 *	0 on success
-	 *	!= 0 on failure
-	 */
-
 #define VSL_ARGS	"bCcdI:i:k:n:r:s:X:x:m:"
 #define VSL_b_USAGE	"[-b]"
 #define VSL_c_USAGE	"[-c]"
@@ -68,6 +64,7 @@ int VSL_Open(struct VSM_data *vd, int diag);
 #define VSL_s_USAGE	"[-s skip]"
 #define VSL_x_USAGE	"[-x tag]"
 #define VSL_X_USAGE	"[-X regexp]"
+
 #define VSL_USAGE	"[-bCcd] "		\
 			VSL_i_USAGE " "		\
 			VSL_I_USAGE " "		\
@@ -83,24 +80,79 @@ int VSL_Arg(struct VSM_data *vd, int arg, const char *opt);
 	/*
 	 * Handle standard log-presenter arguments
 	 * Return:
-	 *	-1 error
+	 *	-1 error, VSM_Error() returns diagnostic string
 	 *	 0 not handled
 	 *	 1 Handled.
 	 */
 
 typedef int VSL_handler_f(void *priv, enum VSL_tag_e tag, unsigned fd,
     unsigned len, unsigned spec, const char *ptr, uint64_t bitmap);
+	/*
+	 * This is the call-back function you must provide.
+	 *	priv is whatever you asked for it to be.
+	 *	tag is the SLT_mumble tag
+	 *	fd is the filedescriptor associated with this record
+	 *	len is the length of the data at ptr
+	 *	spec are the VSL_S_* flags
+	 *	ptr points to the data, beware of non-printables.
+	 *	bitmap is XXX ???
+	 */
 
 #define VSL_S_CLIENT	(1 << 0)
 #define VSL_S_BACKEND	(1 << 1)
+
 VSL_handler_f VSL_H_Print;
-struct VSM_data;
-void VSL_Select(const struct VSM_data *vd, unsigned tag);
-void VSL_NonBlocking(const struct VSM_data *vd, int nb);
+	/*
+	 * This call-back function will printf() the record to the FILE *
+	 * specified in priv.
+	 */
+
+void VSL_Select(struct VSM_data *vd, enum VSL_tag_e tag);
+	/*
+	 * This adds tags which shall always be selected, similar to using
+	 * the '-i' option.
+	 * VSL_Select()/-i takes precedence over all other filtering.
+	 */
+
 int VSL_Dispatch(struct VSM_data *vd, VSL_handler_f *func, void *priv);
-int VSL_NextLog(const struct VSM_data *lh, uint32_t **pp, uint64_t *bitmap);
-int VSL_Matched(const struct VSM_data *vd, uint64_t bitmap);
+	/*
+	 * Call func(priv, ...) for all filtered VSL records.
+	 *
+	 * Return values:
+	 *	!=0:	Non-zero return value from func()
+	 *	0:	no VSL records.
+	 *	-1:	VSL chunk was abandonned.
+	 *	-2:	End of file (-r) / -k arg exhausted / "done"
+	 */
+
+int VSL_NextSLT(struct VSM_data *lh, uint32_t **pp, uint64_t *bitmap);
+	/*
+	 * Return raw pointer to next filtered VSL record.
+	 *
+	 * Return values:
+	 *	1:	Valid VSL record at *pp
+	 *	0:	no VSL records
+	 *	-1:	VSL cunkwas abandonned
+	 *	-2:	End of file (-r) / -k arg exhausted / "done"
+	 */
+
+int VSL_Matched(struct VSM_data *vd, uint64_t bitmap);
+	/*
+	 */
+
 int VSL_Name2Tag(const char *name, int l);
+	/*
+	 * Convert string to tag number (= enum VSL_tag_e)
+	 *
+	 * Return values:
+	 *	>=0:	Tag number
+	 *	-1:	No tag matches
+	 *	-2:	Multiple tags match substring
+	 */
+
 extern const char *VSL_tags[256];
+	/*
+	 * Tag to string array.  Contains NULL for invalid tags.
+	 */
 
 #endif /* VAPI_VSL_H_INCLUDED */
diff --git a/include/vapi/vsm.h b/include/vapi/vsm.h
index 277a670..9635e8f 100644
--- a/include/vapi/vsm.h
+++ b/include/vapi/vsm.h
@@ -83,7 +83,7 @@ int VSM_n_Arg(struct VSM_data *vd, const char *n_arg);
 	 * Can also be, and normally is done through VSC_Arg()/VSL_Arg().
 	 * Returns:
 	 *	 1 on success
-	 *	 <0 on failure, use VSM_Error() to get diagnostics.
+	 *	 <0 on failure, VSM_Error() returns diagnostic string
 	 */
 
 const char *VSM_Name(const struct VSM_data *vd);
@@ -97,7 +97,7 @@ int VSM_Open(struct VSM_data *vd);
 	 * If diag is non-zero, diagnostics are emitted.
 	 * Returns:
 	 *	0 on success
-	 *	<0 on failure, use VSM_Error() to get diagnostics.
+	 *	<0 on failure, VSM_Error() returns diagnostic string
 	 */
 
 int VSM_Abandonned(const struct VSM_data *vd);
diff --git a/lib/libvarnishapi/vsl.c b/lib/libvarnishapi/vsl.c
index e1ace33..d45e1c3 100644
--- a/lib/libvarnishapi/vsl.c
+++ b/lib/libvarnishapi/vsl.c
@@ -51,37 +51,40 @@
 #include "vsl_api.h"
 #include "vsm_api.h"
 
-static void VSL_Close(struct VSM_data *vd);
-
 /*--------------------------------------------------------------------*/
 
 const char *VSL_tags[256] = {
-#define SLTM(foo)       [SLT_##foo] = #foo,
-#include "tbl/vsl_tags.h"
-#undef SLTM
+#  define SLTM(foo)       [SLT_##foo] = #foo,
+#  include "tbl/vsl_tags.h"
+#  undef SLTM
 };
 
 /*--------------------------------------------------------------------*/
 
-void
-VSL_Setup(struct VSM_data *vd)
+struct vsl *
+vsl_Setup(struct VSM_data *vd)
 {
 	struct vsl *vsl;
 
 	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
-	AZ(vd->vsl);
-	ALLOC_OBJ(vd->vsl, VSL_MAGIC);
-	AN(vd->vsl);
-	vsl = vd->vsl;
-	vsl->regflags = 0;
-	vsl->vbm_supress = vbit_init(256);
-	vsl->vbm_select = vbit_init(256);
-	vsl->r_fd = -1;
-	vsl->num_matchers = 0;
-	VTAILQ_INIT(&vsl->matchers);
+	if (vd->vsl == NULL) {
+		ALLOC_OBJ(vd->vsl, VSL_MAGIC);
+		AN(vd->vsl);
+		vsl = vd->vsl;
+		vsl->regflags = 0;
+		vsl->vbm_supress = vbit_init(256);
+		vsl->vbm_select = vbit_init(256);
+		vsl->r_fd = -1;
+		vsl->num_matchers = 0;
+		VTAILQ_INIT(&vsl->matchers);
+	}
+	CHECK_OBJ_NOTNULL(vd->vsl, VSL_MAGIC);
+	return (vd->vsl);
 }
 
-/*--------------------------------------------------------------------*/
+/*--------------------------------------------------------------------
+ * Called from VSM_Delete()
+ */
 
 void
 VSL_Delete(struct VSM_data *vd)
@@ -93,41 +96,66 @@ VSL_Delete(struct VSM_data *vd)
 	vd->vsl = NULL;
 	CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
 
+	if (vsl->r_fd > STDIN_FILENO)
+		(void)close(vsl->r_fd);
 	vbit_destroy(vsl->vbm_supress);
 	vbit_destroy(vsl->vbm_select);
 	free(vsl->rbuf);
-
 	FREE_OBJ(vsl);
 }
 
 /*--------------------------------------------------------------------*/
 
 void
-VSL_Select(const struct VSM_data *vd, unsigned tag)
+VSL_Select(struct VSM_data *vd, enum VSL_tag_e tag)
 {
-	struct vsl *vsl;
+	struct vsl *vsl = vsl_Setup(vd);
 
-	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
-	vsl = vd->vsl;
-	CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
-	vbit_set(vsl->vbm_select, tag);
+	vbit_set(vsl->vbm_select, (int)tag);
 }
 
+/*--------------------------------------------------------------------
+ */
 
-/*--------------------------------------------------------------------*/
+static int
+vsl_open(struct VSM_data *vd)
+{
+	struct vsl *vsl = vsl_Setup(vd);
+	int i;
 
-void
-VSL_NonBlocking(const struct VSM_data *vd, int nb)
+	assert(vsl->r_fd < 0);
+	i = VSM_Open(vd);
+	if (i)
+		return (i);
+	if (!VSM_Get(vd, &vsl->vf, VSL_CLASS, NULL, NULL)) {
+		VSM_Close(vd);
+		return (vsm_diag(vd, "No VSL chunk found "
+		    " (child not started ?)\n"));
+	}
+	vsl->log_start = vsl->vf.b;
+	vsl->log_end = vsl->vf.e;
+	vsl->log_ptr = vsl->log_start + 1;
+	if (!vsl->d_opt) {
+		while (*vsl->log_ptr != VSL_ENDMARKER)
+			vsl->log_ptr = VSL_NEXT(vsl->log_ptr);
+	}
+	return (0);
+}
+
+/*--------------------------------------------------------------------
+ */
+
+static void
+vsl_close(struct VSM_data *vd)
 {
-	struct vsl *vsl;
+	struct vsl *vsl = vsl_Setup(vd);
 
-	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
-	vsl = vd->vsl;
-	CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
-	if (nb)
-		vsl->flags |= F_NON_BLOCKING;
-	else
-		vsl->flags &= ~F_NON_BLOCKING;
+	assert(vsl->r_fd < 0);
+	VSM_Close(vd);
+	memset(&vsl->vf, 0, sizeof vsl->vf);
+	vsl->log_start = NULL;
+	vsl->log_end = NULL;
+	vsl->log_ptr = NULL;
 }
 
 /*--------------------------------------------------------------------
@@ -140,20 +168,19 @@ VSL_NonBlocking(const struct VSM_data *vd, int nb)
  */
 
 static int
-vsl_nextlog(struct vsl *vsl, uint32_t **pp)
+vsl_nextslt(struct VSM_data *vd, uint32_t **pp)
 {
+	struct vsl *vsl = vsl_Setup(vd);
 	unsigned l;
 	uint32_t t;
 	int i;
 
-	CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
-
 	*pp = NULL;
 	if (vsl->r_fd != -1) {
 		assert(vsl->rbuflen >= 8);
 		i = read(vsl->r_fd, vsl->rbuf, 8);
 		if (i == 0)
-			return (-1);
+			return (-2);
 		if (i != 8)
 			return (-1);
 		l = 2 + VSL_WORDS(VSL_LEN(vsl->rbuf));
@@ -169,9 +196,11 @@ vsl_nextlog(struct vsl *vsl, uint32_t **pp)
 		*pp = vsl->rbuf;
 		return (1);
 	}
+
+	if (vsl->log_ptr == NULL && vsl_open(vd))
+		return (0);
+
 	while (1) {
-		if (vsl->log_ptr == NULL)
-			return (0);
 		assert(vsl->log_ptr >= vsl->log_start + 1);
 		assert(vsl->log_ptr < vsl->log_end);
 		t = *vsl->log_ptr;
@@ -209,60 +238,65 @@ vsl_nextlog(struct vsl *vsl, uint32_t **pp)
 }
 
 int
-VSL_NextLog(const struct VSM_data *vd, uint32_t **pp, uint64_t *bits)
+VSL_NextSLT(struct VSM_data *vd, uint32_t **pp, uint64_t *bits)
 {
-	struct vsl *vsl;
+	struct vsl *vsl = vsl_Setup(vd);
 	uint32_t *p;
 	unsigned char t;
 	int i;
+	struct vsl_re_match *vrm;
+	int j;
 
-	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
-	vsl = vd->vsl;
-	CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
+	if (bits != NULL)
+		*bits = 0;
 
 	while (1) {
-		i = vsl_nextlog(vsl, &p);
-		if (i <= 0)
+		i = vsl_nextslt(vd, &p);
+		if (i < 0)
+			return (i);
+		if (i == 0 && (vsl->d_opt || vsl->r_fd >= 0))
+			return (i);
+		if (i == 0 && !VSM_StillValid(vd, &vsl->vf)) {
+			vsl_close(vd);
 			return (i);
-		t = VSL_TAG(p);
-		if (vsl->skip) {
-			--vsl->skip;
-			continue;
-		} else if (vsl->keep) {
-			if (--vsl->keep == 0)
-				return (-1);
 		}
 
+		t = VSL_TAG(p);
 		if (vbit_test(vsl->vbm_select, t)) {
-			*pp = p;
-			return (1);
-		}
-		if (vbit_test(vsl->vbm_supress, t))
+			/* nothing */
+		} else if (vbit_test(vsl->vbm_supress, t)) {
 			continue;
-		if (vsl->b_opt && !VSL_BACKEND(p))
+		} else if (vsl->b_opt && !VSL_BACKEND(p)) {
 			continue;
-		if (vsl->c_opt && !VSL_CLIENT(p))
+		} else if (vsl->c_opt && !VSL_CLIENT(p)) {
 			continue;
-		if (vsl->regincl != NULL) {
+		} else if (vsl->regincl != NULL) {
 			i = VRE_exec(vsl->regincl, VSL_DATA(p), VSL_LEN(p),
 			    0, 0, NULL, 0, NULL);
 			if (i == VRE_ERROR_NOMATCH)
 				continue;
-		}
-		if (vsl->regexcl != NULL) {
+		} else if (vsl->regexcl != NULL) {
 			i = VRE_exec(vsl->regexcl, VSL_DATA(p), VSL_LEN(p),
 			    0, 0, NULL, 0, NULL);
 			if (i != VRE_ERROR_NOMATCH)
 				continue;
 		}
+
+		if (vsl->skip) {
+			--vsl->skip;
+			continue;
+		} else if (vsl->keep) {
+			if (--vsl->keep == 0)
+				return (-2);
+		}
+
 		if (bits != NULL) {
-			struct vsl_re_match *vrm;
-			int j = 0;
+			j = 0;
 			VTAILQ_FOREACH(vrm, &vsl->matchers, next) {
 				if (vrm->tag == t) {
 					i = VRE_exec(vrm->re, VSL_DATA(p),
 					    VSL_LEN(p), 0, 0, NULL, 0, NULL);
-					if (i >= 0)
+					if (i >= 0) 	/* XXX ?? */
 						*bits |= (uintmax_t)1 << j;
 				}
 				j++;
@@ -278,41 +312,13 @@ VSL_NextLog(const struct VSM_data *vd, uint32_t **pp, uint64_t *bits)
 int
 VSL_Dispatch(struct VSM_data *vd, VSL_handler_f *func, void *priv)
 {
-	struct vsl *vsl;
 	int i;
 	unsigned u, l, s;
 	uint32_t *p;
 	uint64_t bitmap;
-	int tmo;
-
-	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
-	vsl = vd->vsl;
-	CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
 
-	tmo = 0;
 	while (1) {
-		bitmap = 0;
-		i = VSL_NextLog(vd, &p, &bitmap);
-		if (i == 0) {
-			if (vsl->r_fd != -1)
-				return(0);
-			if (vsl->flags & F_NON_BLOCKING)
-				return (0);
-			if (VSM_StillValid(vd, &vsl->vf) != 1) {
-				VSL_Close(vd);
-				if (VSL_Open(vd, 0))
-					return (-1);
-				AN(vsl->log_ptr);
-				assert(vsl->log_ptr >= vsl->log_start + 1);
-				assert(vsl->log_ptr < vsl->log_end);
-				continue;
-			}
-			tmo += SLEEP_USEC;
-			if (tmo > TIMEOUT_USEC)
-				return (0);
-			(void)usleep(SLEEP_USEC);
-			continue;
-		}
+		i = VSL_NextSLT(vd, &p, &bitmap);
 		if (i <= 0)
 			return (i);
 		u = VSL_ID(p);
@@ -322,9 +328,10 @@ VSL_Dispatch(struct VSM_data *vd, VSL_handler_f *func, void *priv)
 			s |= VSL_S_CLIENT;
 		if (VSL_BACKEND(p))
 			s |= VSL_S_BACKEND;
-		if (func(priv, (enum VSL_tag_e)VSL_TAG(p),
-		    u, l, s, VSL_DATA(p), bitmap))
-			return (1);
+		i = func(priv, (enum VSL_tag_e)VSL_TAG(p),
+		    u, l, s, VSL_DATA(p), bitmap);
+		if (i)
+			return (i);
 	}
 }
 
@@ -362,64 +369,14 @@ VSL_H_Print(void *priv, enum VSL_tag_e tag, unsigned fd, unsigned len,
 
 /*--------------------------------------------------------------------*/
 
-static void
-VSL_Close(struct VSM_data *vd)
-{
-	struct vsl *vsl;
-
-	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
-	vsl = vd->vsl;
-	CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
-
-	VSM_Close(vd);
-	vsl->log_start = NULL;
-	vsl->log_end = NULL;
-	vsl->log_ptr = NULL;
-}
-
-/*--------------------------------------------------------------------*/
-
 int
-VSL_Open(struct VSM_data *vd, int diag)
+VSL_Matched(struct VSM_data *vd, uint64_t bitmap)
 {
-	struct vsl *vsl;
-	int i;
-
-	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
-	vsl = vd->vsl;
-	CHECK_OBJ_NOTNULL(vsl, VSL_MAGIC);
-
-	if (vsl->r_fd == -1) {
-		i = VSM_Open(vd, diag);
-		if (i)
-			return (i);
-		if (!VSM_Get(vd, &vsl->vf, VSL_CLASS, NULL, NULL)) {
-			VSM_Close(vd);
-			if (diag)
-				vd->diag(vd->priv,
-				    "No VSL chunk found "
-				    " (child not started ?)\n");
-			return (1);
-		}
-		vsl->log_start = vsl->vf.b;
-		vsl->log_end = vsl->vf.e;
-		vsl->log_ptr = vsl->log_start + 1;
-		if (!vsl->d_opt) {
-			while (*vsl->log_ptr != VSL_ENDMARKER)
-				vsl->log_ptr = VSL_NEXT(vsl->log_ptr);
-		}
-	}
-	return (0);
-}
+	struct vsl *vsl = vsl_Setup(vd);
 
-/*--------------------------------------------------------------------*/
-
-int
-VSL_Matched(const struct VSM_data *vd, uint64_t bitmap)
-{
-	if (vd->vsl->num_matchers > 0) {
+	if (vsl->num_matchers > 0) {
 		uint64_t t;
-		t = vd->vsl->num_matchers | (vd->vsl->num_matchers - 1);
+		t = vsl->num_matchers | (vsl->num_matchers - 1);
 		return (bitmap == t);
 	}
 	return (1);
diff --git a/lib/libvarnishapi/vsl_api.h b/lib/libvarnishapi/vsl_api.h
index 013d1ae..0b38539 100644
--- a/lib/libvarnishapi/vsl_api.h
+++ b/lib/libvarnishapi/vsl_api.h
@@ -67,7 +67,6 @@ struct vsl {
 
 	unsigned		flags;
 #define F_SEEN_IX		(1 << 0)
-#define F_NON_BLOCKING		(1 << 1)
 
 	/*
 	 * Bit map of programatically selected tags, that cannot be suppressed.
@@ -89,3 +88,5 @@ struct vsl {
 	unsigned long		keep;
 };
 
+struct vsl *vsl_Setup(struct VSM_data *vd);
+
diff --git a/lib/libvarnishapi/vsl_arg.c b/lib/libvarnishapi/vsl_arg.c
index b855628..100d75a 100644
--- a/lib/libvarnishapi/vsl_arg.c
+++ b/lib/libvarnishapi/vsl_arg.c
@@ -82,21 +82,23 @@ VSL_Name2Tag(const char *name, int l)
 /*--------------------------------------------------------------------*/
 
 static int
-vsl_r_arg(const struct VSM_data *vd, const char *opt)
+vsl_r_arg(struct VSM_data *vd, const char *opt)
 {
+	struct vsl *vsl = vsl_Setup(vd);
 
-	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
+	if (vsl->r_fd > STDIN_FILENO)
+		(void)close(vsl->r_fd);
 	if (!strcmp(opt, "-"))
-		vd->vsl->r_fd = STDIN_FILENO;
+		vsl->r_fd = STDIN_FILENO;
 	else
-		vd->vsl->r_fd = open(opt, O_RDONLY);
-	if (vd->vsl->r_fd < 0) {
-		perror(opt);
-		return (-1);
-	} else if (vd->vsl->rbuflen == 0) {
-		vd->vsl->rbuf = malloc(1024);
-		AN(vd->vsl->rbuf);
-		vd->vsl->rbuflen = 1024;
+		vsl->r_fd = open(opt, O_RDONLY);
+	if (vsl->r_fd < 0)
+		return (vsm_diag(vd,
+		    "Could not open %s: %s", opt, strerror(errno)));
+	if (vsl->rbuflen == 0) {
+		vsl->rbuflen = BUFSIZ;
+		vsl->rbuf = malloc(vsl->rbuflen);
+		AN(vsl->rbuf);
 	}
 	return (1);
 }
@@ -104,43 +106,41 @@ vsl_r_arg(const struct VSM_data *vd, const char *opt)
 /*--------------------------------------------------------------------*/
 
 static int
-vsl_IX_arg(const struct VSM_data *vd, const char *opt, int arg)
+vsl_IX_arg(struct VSM_data *vd, const char *opt, int arg)
 {
+	struct vsl *vsl = vsl_Setup(vd);
 	vre_t **rp;
 	const char *error;
 	int erroroffset;
 
 	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
 	if (arg == 'I')
-		rp = &vd->vsl->regincl;
+		rp = &vsl->regincl;
 	else
-		rp = &vd->vsl->regexcl;
-	if (*rp != NULL) {
-		fprintf(stderr, "Option %c can only be given once", arg);
-		return (-1);
-	}
-	*rp = VRE_compile(opt, vd->vsl->regflags, &error, &erroroffset);
-	if (*rp == NULL) {
-		fprintf(stderr, "Illegal regex: %s\n", error);
-		return (-1);
-	}
+		rp = &vsl->regexcl;
+	if (*rp != NULL)
+		return (vsm_diag(vd, "Option %c can only be given once", arg));
+	*rp = VRE_compile(opt, vsl->regflags, &error, &erroroffset);
+	if (*rp == NULL)
+		return (vsm_diag(vd, "Illegal regex: %s\n", error));
 	return (1);
 }
 
 /*--------------------------------------------------------------------*/
 
 static int
-vsl_ix_arg(const struct VSM_data *vd, const char *opt, int arg)
+vsl_ix_arg(struct VSM_data *vd, const char *opt, int arg)
 {
+	struct vsl *vsl = vsl_Setup(vd);
 	int i, l;
 	const char *b, *e;
 
 	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
 	/* If first option is 'i', set all bits for supression */
-	if (arg == 'i' && !(vd->vsl->flags & F_SEEN_IX))
+	if (arg == 'i' && !(vsl->flags & F_SEEN_IX))
 		for (i = 0; i < 256; i++)
-			vbit_set(vd->vsl->vbm_supress, i);
-	vd->vsl->flags |= F_SEEN_IX;
+			vbit_set(vsl->vbm_supress, i);
+	vsl->flags |= F_SEEN_IX;
 
 	for (b = opt; *b; b = e) {
 		while (isspace(*b))
@@ -156,17 +156,15 @@ vsl_ix_arg(const struct VSM_data *vd, const char *opt, int arg)
 		i = VSL_Name2Tag(b, l);
 		if (i >= 0) {
 			if (arg == 'x')
-				vbit_set(vd->vsl->vbm_supress, i);
+				vbit_set(vsl->vbm_supress, i);
 			else
-				vbit_clr(vd->vsl->vbm_supress, i);
+				vbit_clr(vsl->vbm_supress, i);
 		} else if (i == -2) {
-			fprintf(stderr,
-			    "\"%*.*s\" matches multiple tags\n", l, l, b);
-			return (-1);
+			return (vsm_diag(vd, 
+			    "\"%*.*s\" matches multiple tags\n", l, l, b));
 		} else {
-			fprintf(stderr,
-			    "Could not match \"%*.*s\" to any tag\n", l, l, b);
-			return (-1);
+			return (vsm_diag(vd, 
+			    "Could not match \"%*.*s\" to any tag\n", l, l, b));
 		}
 	}
 	return (1);
@@ -176,8 +174,9 @@ vsl_ix_arg(const struct VSM_data *vd, const char *opt, int arg)
 
 
 static int
-vsl_m_arg(const struct VSM_data *vd, const char *opt)
+vsl_m_arg(struct VSM_data *vd, const char *opt)
 {
+	struct vsl *vsl = vsl_Setup(vd);
 	struct vsl_re_match *m;
 	const char *error;
 	char *o, *regex;
@@ -185,10 +184,9 @@ vsl_m_arg(const struct VSM_data *vd, const char *opt)
 
 	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
 
-	if (!strchr(opt, ':')) {
-		fprintf(stderr, "No : found in -m option %s\n", opt);
-		return (-1);
-	}
+	if (!strchr(opt, ':'))
+		return (vsm_diag(vd,
+		    "No : found in -m option %s\n", opt));
 
 	o = strdup(opt);
 	AN(o);
@@ -200,21 +198,21 @@ vsl_m_arg(const struct VSM_data *vd, const char *opt)
 	AN(m);
 	m->tag = VSL_Name2Tag(o, -1);
 	if (m->tag < 0) {
-		fprintf(stderr, "Illegal tag %s specified\n", o);
+		(void)vsm_diag(vd, "Illegal tag %s specified\n", o);
 		free(o);
 		FREE_OBJ(m);
 		return (-1);
 	}
 	/* Get tag, regex */
-	m->re = VRE_compile(regex, vd->vsl->regflags, &error, &erroroffset);
+	m->re = VRE_compile(regex, vsl->regflags, &error, &erroroffset);
 	if (m->re == NULL) {
-		fprintf(stderr, "Illegal regex: %s\n", error);
+		(void)vsm_diag(vd, "Illegal regex: %s\n", error);
 		free(o);
 		FREE_OBJ(m);
 		return (-1);
 	}
-	vd->vsl->num_matchers++;
-	VTAILQ_INSERT_TAIL(&vd->vsl->matchers, m, next);
+	vsl->num_matchers++;
+	VTAILQ_INSERT_TAIL(&vsl->matchers, m, next);
 	free(o);
 	return (1);
 }
@@ -222,40 +220,34 @@ vsl_m_arg(const struct VSM_data *vd, const char *opt)
 /*--------------------------------------------------------------------*/
 
 static int
-vsl_s_arg(const struct VSM_data *vd, const char *opt)
+vsl_s_arg(struct VSM_data *vd, const char *opt)
 {
+	struct vsl *vsl = vsl_Setup(vd);
 	char *end;
 
 	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
-	if (*opt == '\0') {
-		fprintf(stderr, "number required for -s\n");
-		return (-1);
-	}
-	vd->vsl->skip = strtoul(opt, &end, 10);
-	if (*end != '\0') {
-		fprintf(stderr, "invalid number for -s\n");
-		return (-1);
-	}
+	if (*opt == '\0')
+		return (vsm_diag(vd, "number required for -s\n"));
+	vsl->skip = strtoul(opt, &end, 10);
+	if (*end != '\0')
+		return (vsm_diag(vd, "invalid number for -k\n"));
 	return (1);
 }
 
 /*--------------------------------------------------------------------*/
 
 static int
-vsl_k_arg(const struct VSM_data *vd, const char *opt)
+vsl_k_arg(struct VSM_data *vd, const char *opt)
 {
+	struct vsl *vsl = vsl_Setup(vd);
 	char *end;
 
 	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
-	if (*opt == '\0') {
-		fprintf(stderr, "number required for -k\n");
-		return (-1);
-	}
-	vd->vsl->keep = strtoul(opt, &end, 10);
-	if (*end != '\0') {
-		fprintf(stderr, "invalid number for -k\n");
-		return (-1);
-	}
+	if (*opt == '\0') 
+		return (vsm_diag(vd, "number required for -k\n"));
+	vsl->keep = strtoul(opt, &end, 10);
+	if (*end != '\0') 
+		return (vsm_diag(vd, "invalid number for -k\n"));
 	return (1);
 }
 
@@ -264,14 +256,13 @@ vsl_k_arg(const struct VSM_data *vd, const char *opt)
 int
 VSL_Arg(struct VSM_data *vd, int arg, const char *opt)
 {
+	struct vsl *vsl = vsl_Setup(vd);
 
-	CHECK_OBJ_NOTNULL(vd, VSM_MAGIC);
 	switch (arg) {
-	case 'b': vd->vsl->b_opt = !vd->vsl->b_opt; return (1);
-	case 'c': vd->vsl->c_opt = !vd->vsl->c_opt; return (1);
+	case 'b': vsl->b_opt = !vsl->b_opt; return (1);
+	case 'c': vsl->c_opt = !vsl->c_opt; return (1);
 	case 'd':
-		vd->vsl->d_opt = !vd->vsl->d_opt;
-		vd->vsl->flags |= F_NON_BLOCKING;
+		vsl->d_opt = !vsl->d_opt;
 		return (1);
 	case 'i': case 'x': return (vsl_ix_arg(vd, opt, arg));
 	case 'k': return (vsl_k_arg(vd, opt));
@@ -280,7 +271,7 @@ VSL_Arg(struct VSM_data *vd, int arg, const char *opt)
 	case 's': return (vsl_s_arg(vd, opt));
 	case 'I': case 'X': return (vsl_IX_arg(vd, opt, arg));
 	case 'm': return (vsl_m_arg(vd, opt));
-	case 'C': vd->vsl->regflags = VRE_CASELESS; return (1);
+	case 'C': vsl->regflags = VRE_CASELESS; return (1);
 	default:
 		return (0);
 	}
diff --git a/lib/libvarnishapi/vsm.c b/lib/libvarnishapi/vsm.c
index d136c98..1d762e5 100644
--- a/lib/libvarnishapi/vsm.c
+++ b/lib/libvarnishapi/vsm.c
@@ -75,7 +75,7 @@ VSM_New(void)
 
 /*--------------------------------------------------------------------*/
 
-static int
+int
 vsm_diag(struct VSM_data *vd, const char *fmt, ...)
 {
 	va_list ap;
diff --git a/lib/libvarnishapi/vsm_api.h b/lib/libvarnishapi/vsm_api.h
index 6690ba6..79be982 100644
--- a/lib/libvarnishapi/vsm_api.h
+++ b/lib/libvarnishapi/vsm_api.h
@@ -47,14 +47,10 @@ struct VSM_data {
 	char			*b;
 	char			*e;
 
-	/* Stuff for backwards compat */
-	struct VSM_fantom	compat_vf;
-
-	/* Stuff relating the stats fields start here */
-
 	struct vsc		*vsc;
 	struct vsl		*vsl;
 };
 
+int vsm_diag(struct VSM_data *vd, const char *fmt, ...);
 void VSC_Delete(struct VSM_data *vd);
 void VSL_Delete(struct VSM_data *vd);



More information about the varnish-commit mailing list