r5386 - in trunk/varnish-cache: bin/varnishd lib/libvcl

phk at varnish-cache.org phk at varnish-cache.org
Sat Oct 2 20:32:40 CEST 2010


Author: phk
Date: 2010-10-02 20:32:40 +0200 (Sat, 02 Oct 2010)
New Revision: 5386

Added:
   trunk/varnish-cache/lib/libvcl/symbol_kind.h
Modified:
   trunk/varnish-cache/bin/varnishd/flint.lnt
   trunk/varnish-cache/lib/libvcl/vcc_acl.c
   trunk/varnish-cache/lib/libvcl/vcc_action.c
   trunk/varnish-cache/lib/libvcl/vcc_backend.c
   trunk/varnish-cache/lib/libvcl/vcc_compile.c
   trunk/varnish-cache/lib/libvcl/vcc_compile.h
   trunk/varnish-cache/lib/libvcl/vcc_expr.c
   trunk/varnish-cache/lib/libvcl/vcc_parse.c
   trunk/varnish-cache/lib/libvcl/vcc_symb.c
   trunk/varnish-cache/lib/libvcl/vcc_var.c
   trunk/varnish-cache/lib/libvcl/vcc_vmod.c
   trunk/varnish-cache/lib/libvcl/vcc_xref.c
Log:
Rework the x-ref code in VCC to use the One and Only symbol table, rather
than have three different ones.



Modified: trunk/varnish-cache/bin/varnishd/flint.lnt
===================================================================
--- trunk/varnish-cache/bin/varnishd/flint.lnt	2010-10-02 18:14:09 UTC (rev 5385)
+++ trunk/varnish-cache/bin/varnishd/flint.lnt	2010-10-02 18:32:40 UTC (rev 5386)
@@ -74,6 +74,7 @@
 -efile(451, "http_headers.h")	// No include guard
 -efile(451, "acct_fields.h")	// No include guard
 -efile(451, "vcc_types.h")	// No include guard
+-efile(451, "symbol_kind.h")	// No include guard
 -efile(451, "config.h")	// No include guard
 //////////////
 // -e458			// unprotected access

Added: trunk/varnish-cache/lib/libvcl/symbol_kind.h
===================================================================
--- trunk/varnish-cache/lib/libvcl/symbol_kind.h	                        (rev 0)
+++ trunk/varnish-cache/lib/libvcl/symbol_kind.h	2010-10-02 18:32:40 UTC (rev 5386)
@@ -0,0 +1,41 @@
+/*-
+ * 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_types.h 5163 2010-08-31 10:59:07Z phk $
+ */
+
+/*lint -save -e525 -e539 */
+VCC_SYMB(NONE,		none,		"undefined")
+VCC_SYMB(VAR,		var,		"variable")
+VCC_SYMB(FUNC,		func,		"function")	/* VMOD function */
+VCC_SYMB(PROC,		proc,		"procedure")	/* VMOD procedure */
+VCC_SYMB(VMOD,		vmod,		"vmod")
+VCC_SYMB(ACL,		acl,		"acl")
+VCC_SYMB(SUB,		sub,		"sub")		/* VCL subroutine */
+VCC_SYMB(BACKEND,	backend,	"backend")
+VCC_SYMB(PROBE,		probe,		"probe")
+/*lint -restore */

Modified: trunk/varnish-cache/lib/libvcl/vcc_acl.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_acl.c	2010-10-02 18:14:09 UTC (rev 5385)
+++ trunk/varnish-cache/lib/libvcl/vcc_acl.c	2010-10-02 18:32:40 UTC (rev 5386)
@@ -477,7 +477,7 @@
 	an = tl->t;
 	vcc_NextToken(tl);
 
-	vcc_AddDef(tl, an, R_ACL);
+	vcc_AddDef(tl, an, SYM_ACL);
 	bprintf(acln, "%.*s", PF(an));
 
 	SkipToken(tl, '{');

Modified: trunk/varnish-cache/lib/libvcl/vcc_action.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_action.c	2010-10-02 18:14:09 UTC (rev 5385)
+++ trunk/varnish-cache/lib/libvcl/vcc_action.c	2010-10-02 18:32:40 UTC (rev 5386)
@@ -53,7 +53,7 @@
 	vcc_NextToken(tl);
 	ExpectErr(tl, ID);
 	vcc_AddCall(tl, tl->t);
-	vcc_AddRef(tl, tl->t, R_SUB);
+	vcc_AddRef(tl, tl->t, SYM_SUB);
 	Fb(tl, 1, "if (VGC_function_%.*s(sp))\n", PF(tl->t));
 	Fb(tl, 1, "\treturn (1);\n");
 	vcc_NextToken(tl);
@@ -447,7 +447,7 @@
 			return (1);
 		}
 	}
-	sym = VCC_FindSymbol(tl, tl->t);
+	sym = VCC_FindSymbol(tl, tl->t, SYM_NONE);
 	if (sym != NULL && sym->kind == SYM_PROC) {
 		vcc_Expr_Call(tl, sym);
 		return (1);

Modified: trunk/varnish-cache/lib/libvcl/vcc_backend.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_backend.c	2010-10-02 18:14:09 UTC (rev 5385)
+++ trunk/varnish-cache/lib/libvcl/vcc_backend.c	2010-10-02 18:32:40 UTC (rev 5386)
@@ -422,7 +422,7 @@
 	ERRCHK(tl);
 	t_probe = tl->t;
 	vcc_NextToken(tl);
-	vcc_AddDef(tl, t_probe, R_PROBE);
+	vcc_AddDef(tl, t_probe, SYM_PROBE);
 
 	Fh(tl, 0, "\n#define vgc_probe_%.*s\tvgc_probe__%d\n",
 	    PF(t_probe), tl->nprobe);
@@ -554,7 +554,7 @@
 			ERRCHK(tl);
 		} else if (vcc_IdIs(t_field, "probe") && tl->t->tok == ID) {
 			Fb(tl, 0, "\t.probe = &vgc_probe_%.*s,\n", PF(tl->t));
-			vcc_AddRef(tl, tl->t, R_PROBE);
+			vcc_AddRef(tl, tl->t, SYM_PROBE);
 			vcc_NextToken(tl);
 			SkipToken(tl, ';');
 		} else if (vcc_IdIs(t_field, "probe")) {
@@ -646,7 +646,7 @@
 			vcc_ErrWhere(tl, tl->t);
 			return;
 		}
-		vcc_AddRef(tl, h->name, R_BACKEND);
+		vcc_AddRef(tl, h->name, SYM_BACKEND);
 		vcc_NextToken(tl);
 		SkipToken(tl, ';');
 		*nm = h->vgcname;
@@ -687,7 +687,7 @@
 
 	h = TlAlloc(tl, sizeof *h);
 	h->name = tl->t_dir;
-	vcc_AddDef(tl, tl->t_dir, R_BACKEND);
+	vcc_AddDef(tl, tl->t_dir, SYM_BACKEND);
 	sprintf(vgcname, "_%.*s", PF(h->name));
 	h->vgcname = TlAlloc(tl, strlen(vgcname) + 1);
 	strcpy(h->vgcname, vgcname);
@@ -735,7 +735,7 @@
 		tl->t_policy = t_first;
 		vcc_ParseSimpleDirector(tl);
 	} else {
-		vcc_AddDef(tl, tl->t_dir, R_BACKEND);
+		vcc_AddDef(tl, tl->t_dir, SYM_BACKEND);
 		ExpectErr(tl, ID);		/* ID: policy */
 		tl->t_policy = tl->t;
 		vcc_NextToken(tl);

Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_compile.c	2010-10-02 18:14:09 UTC (rev 5385)
+++ trunk/varnish-cache/lib/libvcl/vcc_compile.c	2010-10-02 18:32:40 UTC (rev 5386)
@@ -477,8 +477,6 @@
 	VTAILQ_INIT(&tl->hosts);
 	VTAILQ_INIT(&tl->membits);
 	VTAILQ_INIT(&tl->tokens);
-	VTAILQ_INIT(&tl->refs);
-	VTAILQ_INIT(&tl->procs);
 	VTAILQ_INIT(&tl->sources);
 
 	tl->nsources = 0;
@@ -564,7 +562,7 @@
 	tl->sb = sb;
 
 	for (v = tl->vars; v->name != NULL; v++) {
-		sym = VCC_AddSymbol(tl, v->name, SYM_VAR);
+		sym = VCC_AddSymbolStr(tl, v->name, SYM_VAR);
 		sym->var = v;
 		sym->fmt = v->fmt;
 		sym->r_methods = v->r_methods;
@@ -623,7 +621,7 @@
 	/* Configure the default director */
 	Fi(tl, 0, "\tVCL_conf.director[0] = VCL_conf.director[%d];\n",
 	    tl->defaultdir);
-	vcc_AddRef(tl, tl->t_defaultdir, R_BACKEND);
+	vcc_AddRef(tl, tl->t_defaultdir, SYM_BACKEND);
 
 	/* Check for orphans */
 	if (vcc_CheckReferences(tl))

Modified: trunk/varnish-cache/lib/libvcl/vcc_compile.h
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_compile.h	2010-10-02 18:14:09 UTC (rev 5385)
+++ trunk/varnish-cache/lib/libvcl/vcc_compile.h	2010-10-02 18:32:40 UTC (rev 5386)
@@ -37,6 +37,7 @@
 #define INDENT		2
 
 struct acl_e;
+struct proc;
 
 enum var_type {
 #define VCC_TYPE(foo)		foo,
@@ -69,11 +70,9 @@
 };
 
 enum symkind {
-	SYM_NONE,
-	SYM_VAR,
-	SYM_FUNC,
-	SYM_PROC,
-	SYM_VMOD
+#define VCC_SYMB(uu, ll, dd)	SYM_##uu,
+#include "symbol_kind.h"
+#undef VCC_SYMB
 };
 
 struct symbol {
@@ -84,11 +83,14 @@
 	char				*name;
 	unsigned			nlen;
 	unsigned			wildcard;
-
 	enum symkind			kind;
+
+	unsigned			nref, ndef;
+	const struct token		*def_b, *def_e;
+
 	enum var_type			fmt;
 
-	struct token			*def_b, *def_e;
+	struct proc			*proc;
 
 	const char			*cfunc;
 	const char			*args;
@@ -132,11 +134,9 @@
 						 * NULL otherwise
 						 */
 	struct vsb		*fm[VCL_MET_MAX];	/* Method bodies */
-	VTAILQ_HEAD(, ref)	refs;
 	struct vsb		*sb;
 	int			err;
 	int			ndirector;
-	VTAILQ_HEAD(, proc)	procs;
 	struct proc		*curproc;
 	struct proc		*mprocs[VCL_MET_MAX];
 
@@ -154,21 +154,6 @@
 	unsigned		nvmodpriv;
 };
 
-enum ref_type {
-	R_SUB,
-	R_ACL,
-	R_BACKEND,
-	R_PROBE
-};
-
-struct ref {
-	enum ref_type		type;
-	struct token		*name;
-	unsigned		defcnt;
-	unsigned		refcnt;
-	VTAILQ_ENTRY(ref)	list;
-};
-
 struct var {
 	const char		*name;
 	enum var_type		fmt;
@@ -260,9 +245,14 @@
 void vcc_ExpectedStringval(struct vcc *tl);
 
 /* vcc_symbol */
-struct symbol *VCC_AddSymbol(struct vcc *tl, const char *name, enum symkind);
-const struct symbol *VCC_FindSymbol(const struct vcc *tl,
-    const struct token *t);
+struct symbol *VCC_AddSymbolStr(struct vcc *tl, const char *name, enum symkind);
+struct symbol *VCC_GetSymbolTok(struct vcc *tl, const struct token *tok,
+    enum symkind);
+struct symbol *VCC_FindSymbol(const struct vcc *tl,
+    const struct token *t, enum symkind kind);
+const char * VCC_SymKind(struct vcc *tl, const struct symbol *s);
+typedef void symwalk_f(struct vcc *tl, const struct symbol *s);
+void VCC_WalkSymbols(struct vcc *tl, symwalk_f *func, enum symkind kind);
 
 /* vcc_token.c */
 void vcc_Coord(const struct vcc *tl, struct vsb *vsb,
@@ -292,8 +282,8 @@
 void vcc_ParseImport(struct vcc *tl);
 
 /* vcc_xref.c */
-void vcc_AddDef(struct vcc *tl, struct token *t, enum ref_type type);
-void vcc_AddRef(struct vcc *tl, struct token *t, enum ref_type type);
+void vcc_AddDef(struct vcc *tl, const struct token *t, enum symkind type);
+void vcc_AddRef(struct vcc *tl, const struct token *t, enum symkind type);
 int vcc_CheckReferences(struct vcc *tl);
 
 void vcc_AddCall(struct vcc *tl, struct token *t);

Modified: trunk/varnish-cache/lib/libvcl/vcc_expr.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_expr.c	2010-10-02 18:14:09 UTC (rev 5385)
+++ trunk/varnish-cache/lib/libvcl/vcc_expr.c	2010-10-02 18:32:40 UTC (rev 5386)
@@ -540,13 +540,13 @@
 		}
 		if (fmt == BACKEND) {
 			vcc_ExpectCid(tl);
-			vcc_AddRef(tl, tl->t, R_BACKEND);
+			vcc_AddRef(tl, tl->t, SYM_BACKEND);
 			vsb_printf(e1->vsb, "VGCDIR(_%.*s)", PF(tl->t));
 			e1->fmt = BACKEND;
 			vcc_NextToken(tl);
 			break;
 		}
-		sym = VCC_FindSymbol(tl, tl->t);
+		sym = VCC_FindSymbol(tl, tl->t, SYM_NONE);
 		if (sym == NULL) {
 			vsb_printf(tl->sb, "Symbol not found: ");
 			vcc_ErrToken(tl, tl->t);
@@ -687,9 +687,10 @@
 		while (tl->t->tok == '+') {
 			vcc_NextToken(tl);
 			vcc_expr_mul(tl, &e2, STRING);
+			ERRCHK(tl);
 			if (e2->fmt != STRING && e2->fmt != STRING_LIST)
 				vcc_expr_tostring(&e2, f2);
-				ERRCHK(tl);
+			ERRCHK(tl);
 			assert(e2->fmt == STRING || e2->fmt == STRING_LIST);
 			if ((*e)->constant &&  e2->constant) {
 				assert((*e)->fmt == STRING);
@@ -833,7 +834,7 @@
 	        not = tl->t->tok == '~' ? "" : "!";
 		vcc_NextToken(tl);
 		ExpectErr(tl, ID);
-		vcc_AddRef(tl, tl->t, R_ACL);
+		vcc_AddRef(tl, tl->t, SYM_ACL);
 		bprintf(buf, "%smatch_acl_named_%.*s(sp, \v1)", not, PF(tl->t));
 		vcc_NextToken(tl);
 		*e = vcc_expr_edit(BOOL, buf, *e, NULL);
@@ -848,7 +849,7 @@
 	    (tl->t->tok == T_EQ || tl->t->tok == T_NEQ)) {
 		vcc_NextToken(tl);
 		ExpectErr(tl, ID);
-		vcc_AddRef(tl, tl->t, R_BACKEND);
+		vcc_AddRef(tl, tl->t, SYM_BACKEND);
 		bprintf(buf, "(\v1 %.*s VGCDIR(_%.*s))", PF(tk), PF(tl->t));
 		vcc_NextToken(tl);
 		*e = vcc_expr_edit(BOOL, buf, *e, NULL);
@@ -867,6 +868,8 @@
 		    PF(tl->t), vcc_Type((*e)->fmt));
 		vcc_ErrWhere(tl, tl->t);
 		return;
+	default:
+		break;
 	}
 	if (fmt == BOOL && (*e)->fmt == STRING) {
 		*e = vcc_expr_edit(BOOL, "(\v1 != 0)", *e, NULL);

Modified: trunk/varnish-cache/lib/libvcl/vcc_parse.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_parse.c	2010-10-02 18:14:09 UTC (rev 5385)
+++ trunk/varnish-cache/lib/libvcl/vcc_parse.c	2010-10-02 18:32:40 UTC (rev 5386)
@@ -207,9 +207,9 @@
 		assert(m < VCL_MET_MAX);
 		tl->fb = tl->fm[m];
 		if (tl->mprocs[m] == NULL) {
+			vcc_AddDef(tl, tl->t, SYM_SUB);
+			vcc_AddRef(tl, tl->t, SYM_SUB);
 			tl->mprocs[m] = vcc_AddProc(tl, tl->t);
-			vcc_AddDef(tl, tl->t, R_SUB);
-			vcc_AddRef(tl, tl->t, R_SUB);
 		}
 		tl->curproc = tl->mprocs[m];
 		Fb(tl, 1, "  /* ... from ");
@@ -217,8 +217,8 @@
 		Fb(tl, 0, " */\n");
 	} else {
 		tl->fb = tl->fc;
+		vcc_AddDef(tl, tl->t, SYM_SUB);
 		tl->curproc = vcc_AddProc(tl, tl->t);
-		vcc_AddDef(tl, tl->t, R_SUB);
 		Fh(tl, 0, "static int VGC_function_%.*s (struct sess *sp);\n",
 		    PF(tl->t));
 		Fc(tl, 1, "\nstatic int\n");

Modified: trunk/varnish-cache/lib/libvcl/vcc_symb.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_symb.c	2010-10-02 18:14:09 UTC (rev 5385)
+++ trunk/varnish-cache/lib/libvcl/vcc_symb.c	2010-10-02 18:32:40 UTC (rev 5386)
@@ -43,35 +43,80 @@
 
 /*--------------------------------------------------------------------*/
 
+const char *
+VCC_SymKind(struct vcc *tl, const struct symbol *s)
+{
+	switch(s->kind) {
+#define VCC_SYMB(uu, ll, dd)	case SYM_##uu: return(dd);
+#include "symbol_kind.h"
+#undef VCC_SYMB
+	default:
+		ErrInternal(tl);
+		vsb_printf(tl->sb, "Symbol Kind 0x%x\n", s->kind);
+		return("INTERNALERROR");
+	}
+}
 
-struct symbol *
-VCC_AddSymbol(struct vcc *tl, const char *name, enum symkind kind)
+
+static struct symbol *
+vcc_AddSymbol(struct vcc *tl, const char *nb, int l, enum symkind kind)
 {
 	struct symbol *sym;
 
 	VTAILQ_FOREACH(sym, &tl->symbols, list) {
-		if (strcmp(name, sym->name))
+		if (sym->nlen != l)
 			continue;
-		printf("%s <> %s\n", name, sym->name);
-		WRONG("name collision");
+		if (memcmp(nb, sym->name, l))
+			continue;
+		if (kind != sym->kind)
+			continue;
+		vsb_printf(tl->sb, "Name Collision: <%.*s> <%s>\n",
+		    l, nb, VCC_SymKind(tl, sym));
+		ErrInternal(tl);
+		return (NULL);
 	}
 	ALLOC_OBJ(sym, SYMBOL_MAGIC);
 	AN(sym);
-	REPLACE(sym->name, name);
-	AN(name);
-	sym->nlen = strlen(name);
+	sym->name = malloc(l + 1);
+	AN(sym->name);
+	memcpy(sym->name, nb, l);
+	sym->name[l] = '\0';
+	sym->nlen = l;
 	VTAILQ_INSERT_TAIL(&tl->symbols, sym, list);
 	sym->kind = kind;
 	return (sym);
 }
 
-const struct symbol *
-VCC_FindSymbol(const struct vcc *tl, const struct token *t)
+struct symbol *
+VCC_AddSymbolStr(struct vcc *tl, const char *name, enum symkind kind)
 {
+
+	return (vcc_AddSymbol(tl, name, strlen(name), kind));
+}
+
+struct symbol *
+VCC_GetSymbolTok(struct vcc *tl, const struct token *tok, enum symkind kind)
+{
 	struct symbol *sym;
 
+	sym = VCC_FindSymbol(tl, tok, kind);
+	if (sym == NULL) {
+		sym = vcc_AddSymbol(tl, tok->b, tok->e - tok->b, kind);
+		AN(sym);
+		sym->def_b = tok;
+	}
+	return (sym);
+}
+
+struct symbol *
+VCC_FindSymbol(const struct vcc *tl, const struct token *t, enum symkind kind)
+{
+	struct symbol *sym;
+
 	assert(t->tok == ID);
 	VTAILQ_FOREACH(sym, &tl->symbols, list) {
+		if (kind != SYM_NONE && kind != sym->kind)
+			continue;
 		if (!sym->wildcard) {
 			if (vcc_IdIs(t, sym->name))
 				return (sym);
@@ -84,3 +129,15 @@
 	}
 	return (NULL);
 }
+
+void
+VCC_WalkSymbols(struct vcc *tl, symwalk_f *func, enum symkind kind)
+{
+	struct symbol *sym;
+
+	VTAILQ_FOREACH(sym, &tl->symbols, list) {
+		if (kind == SYM_NONE || kind == sym->kind)
+			func(tl, sym);
+		ERRCHK(tl);
+	}
+}

Modified: trunk/varnish-cache/lib/libvcl/vcc_var.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_var.c	2010-10-02 18:14:09 UTC (rev 5385)
+++ trunk/varnish-cache/lib/libvcl/vcc_var.c	2010-10-02 18:32:40 UTC (rev 5386)
@@ -94,7 +94,7 @@
 	const struct symbol *sym;
 
 	AN(tl->vars);
-	sym = VCC_FindSymbol(tl, t);
+	sym = VCC_FindSymbol(tl, t, SYM_NONE);
 	if (sym != NULL) {
 		v = sym->var;
 		AN(v);

Modified: trunk/varnish-cache/lib/libvcl/vcc_vmod.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_vmod.c	2010-10-02 18:14:09 UTC (rev 5385)
+++ trunk/varnish-cache/lib/libvcl/vcc_vmod.c	2010-10-02 18:32:40 UTC (rev 5386)
@@ -63,7 +63,7 @@
 
 	vcc_NextToken(tl);
 
-	osym = VCC_FindSymbol(tl, mod);
+	osym = VCC_FindSymbol(tl, mod, SYM_NONE);
 	if (osym != NULL && osym->kind != SYM_VMOD) {
 		vsb_printf(tl->sb, "Module %.*s conflics with other symbol.\n",
 		    PF(mod));
@@ -80,7 +80,9 @@
 	}
 
 	bprintf(fn, "%.*s", PF(mod));
-	sym = VCC_AddSymbol(tl, fn, SYM_VMOD);
+	sym = VCC_AddSymbolStr(tl, fn, SYM_VMOD);
+	ERRCHK(tl);
+	AN(sym);
 	sym->def_b = t1;
 	sym->def_e = tl->t;
 
@@ -150,7 +152,9 @@
 			p += strlen(p) + 1;
 			Fi(tl, 0, "\t%s(&vmod_priv_%.*s, &VCL_conf);\n", p, PF(mod));
 		} else {
-			sym = VCC_AddSymbol(tl, p, SYM_FUNC);
+			sym = VCC_AddSymbolStr(tl, p, SYM_FUNC);
+			ERRCHK(tl);
+			AN(sym);
 			p += strlen(p) + 1;
 			sym->cfunc = p;
 			p += strlen(p) + 1;

Modified: trunk/varnish-cache/lib/libvcl/vcc_xref.c
===================================================================
--- trunk/varnish-cache/lib/libvcl/vcc_xref.c	2010-10-02 18:14:09 UTC (rev 5385)
+++ trunk/varnish-cache/lib/libvcl/vcc_xref.c	2010-10-02 18:32:40 UTC (rev 5386)
@@ -66,7 +66,6 @@
 };
 
 struct proc {
-	VTAILQ_ENTRY(proc)	list;
 	VTAILQ_HEAD(,proccall)	calls;
 	VTAILQ_HEAD(,procuse)	uses;
 	struct token		*name;
@@ -77,106 +76,53 @@
 	struct token		*return_tok[VCL_RET_MAX];
 };
 
-/*--------------------------------------------------------------------*/
-
-static const char *
-vcc_typename(struct vcc *tl, const struct ref *r)
-{
-	switch (r->type) {
-	case R_SUB: return ("subroutine");
-	case R_ACL: return ("acl");
-	case R_BACKEND: return ("backend");
-	case R_PROBE: return ("probe");
-	default:
-		ErrInternal(tl);
-		vsb_printf(tl->sb, "Ref ");
-		vcc_ErrToken(tl, r->name);
-		vsb_printf(tl->sb, " has unknown type %d\n",
-		    r->type);
-		return "?";
-	}
-}
-
 /*--------------------------------------------------------------------
  * Keep track of definitions and references
  */
 
-static struct ref *
-vcc_findref(struct vcc *tl, struct token *t, enum ref_type type)
+void
+vcc_AddRef(struct vcc *tl, const struct token *t, enum symkind kind)
 {
-	struct ref *r;
+	struct symbol *sym;
 
-	VTAILQ_FOREACH(r, &tl->refs, list) {
-		if (r->type != type)
-			continue;
-		if (vcc_Teq(r->name, t))
-			return (r);
-	}
-	r = TlAlloc(tl, sizeof *r);
-	assert(r != NULL);
-	r->name = t;
-	r->type = type;
-	VTAILQ_INSERT_TAIL(&tl->refs, r, list);
-	return (r);
+	sym = VCC_GetSymbolTok(tl, t, kind);
+	AN(sym);
+	sym->nref++;
 }
 
 void
-vcc_AddRef(struct vcc *tl, struct token *t, enum ref_type type)
+vcc_AddDef(struct vcc *tl, const struct token *t, enum symkind kind)
 {
+	struct symbol *sym;
 
-	vcc_findref(tl, t, type)->refcnt++;
+	sym = VCC_GetSymbolTok(tl, t, kind);
+	AN(sym);
+	sym->ndef++;
 }
 
-void
-vcc_AddDef(struct vcc *tl, struct token *t, enum ref_type type)
+/*--------------------------------------------------------------------*/
+
+static void
+vcc_checkref(struct vcc *tl, const struct symbol *sym)
 {
-	struct ref *r;
-	const char *tp;
 
-	r = vcc_findref(tl, t, type);
-	if (r->defcnt > 0) {
-		tp = vcc_typename(tl, r);
-		vsb_printf(tl->sb, "Multiple definitions of %s \"%.*s\"\n",
-		    tp, PF(t));
-		vcc_ErrWhere(tl, r->name);
-		vsb_printf(tl->sb, "...and\n");
-		vcc_ErrWhere(tl, t);
+	if (sym->ndef == 0 && sym->nref != 0) {
+		vsb_printf(tl->sb, "Undefined %s %.*s, first reference:\n",
+		    VCC_SymKind(tl, sym), PF(sym->def_b));
+		vcc_ErrWhere(tl, sym->def_b);
+	} else if (sym->ndef != 0 && sym->nref == 0) {
+		vsb_printf(tl->sb, "Unused %s %.*s, defined:\n",
+		    VCC_SymKind(tl, sym), PF(sym->def_b));
+		vcc_ErrWhere(tl, sym->def_b);
 	}
-	r->defcnt++;
-	r->name = t;
 }
 
-/*--------------------------------------------------------------------*/
-
 int
 vcc_CheckReferences(struct vcc *tl)
 {
-	struct ref *r;
-	const char *type;
-	int nerr = 0;
-	const char *sep = "";
 
-	VTAILQ_FOREACH(r, &tl->refs, list) {
-		if (r->defcnt != 0 && r->refcnt != 0)
-			continue;
-		nerr++;
-
-		type = vcc_typename(tl, r);
-
-		if (r->defcnt == 0) {
-			vsb_printf(tl->sb,
-			    "%sUndefined %s %.*s, first reference:\n",
-			    sep, type, PF(r->name));
-			vcc_ErrWhere(tl, r->name);
-			continue;
-		}
-
-		vsb_printf(tl->sb, "%sUnused %s %.*s, defined:\n",
-		    sep, type, PF(r->name));
-		vcc_ErrWhere(tl, r->name);
-		sep = "\n";
-	}
-	return (nerr);
+	VCC_WalkSymbols(tl, vcc_checkref, SYM_NONE);
+	return (tl->err);
 }
 
 /*--------------------------------------------------------------------
@@ -186,17 +132,21 @@
 static struct proc *
 vcc_findproc(struct vcc *tl, struct token *t)
 {
+	struct symbol *sym;
 	struct proc *p;
 
-	VTAILQ_FOREACH(p, &tl->procs, list)
-		if (vcc_Teq(p->name, t))
-			return (p);
+
+	sym = VCC_GetSymbolTok(tl, t, SYM_SUB);
+	AN(sym);
+	if (sym->proc != NULL)
+		return (sym->proc);
+
 	p = TlAlloc(tl, sizeof *p);
 	assert(p != NULL);
 	VTAILQ_INIT(&p->calls);
 	VTAILQ_INIT(&p->uses);
-	VTAILQ_INSERT_TAIL(&tl->procs, p, list);
 	p->name = t;
+	sym->proc = p;
 	return (p);
 }
 
@@ -298,42 +248,64 @@
 	return (0);
 }
 
-int
-vcc_CheckAction(struct vcc *tl)
+/*--------------------------------------------------------------------*/
+
+static void
+vcc_checkaction1(struct vcc *tl, const struct symbol *sym)
 {
 	struct proc *p;
 	struct method *m;
 	int i;
 
-	VTAILQ_FOREACH(p, &tl->procs, list) {
-		i = IsMethod(p->name);
-		if (i < 0)
-			continue;
-		m = method_tab + i;
-		if (vcc_CheckActionRecurse(tl, p, m->ret_bitmap)) {
-			vsb_printf(tl->sb,
-			    "\n...which is the \"%s\" method\n", m->name);
-			vsb_printf(tl->sb, "Legal returns are:");
+	p = sym->proc;
+	AN(p);
+	i = IsMethod(p->name);
+	if (i < 0)
+		return;
+	m = method_tab + i;
+	if (vcc_CheckActionRecurse(tl, p, m->ret_bitmap)) {
+		vsb_printf(tl->sb,
+		    "\n...which is the \"%s\" method\n", m->name);
+		vsb_printf(tl->sb, "Legal returns are:");
 #define VCL_RET_MAC(l, U, B)						\
-			if (m->ret_bitmap & ((1 << VCL_RET_##U)))	\
-				vsb_printf(tl->sb, " \"%s\"", #l);
+		if (m->ret_bitmap & ((1 << VCL_RET_##U)))	\
+			vsb_printf(tl->sb, " \"%s\"", #l);
 
 #include "vcl_returns.h"
 #undef VCL_RET_MAC
-			vsb_printf(tl->sb, "\n");
-			return (1);
-		}
+		vsb_printf(tl->sb, "\n");
+		tl->err = 1;
 	}
-	VTAILQ_FOREACH(p, &tl->procs, list) {
-		if (p->called)
-			continue;
-		vsb_printf(tl->sb, "Function unused\n");
-		vcc_ErrWhere(tl, p->name);
-		return (1);
-	}
-	return (0);
+
 }
 
+static void
+vcc_checkaction2(struct vcc *tl, const struct symbol *sym)
+{
+	struct proc *p;
+
+	p = sym->proc;
+	AN(p);
+
+	if (p->called)
+		return;
+	vsb_printf(tl->sb, "Function unused\n");
+	vcc_ErrWhere(tl, p->name);
+}
+
+int
+vcc_CheckAction(struct vcc *tl)
+{
+
+	VCC_WalkSymbols(tl, vcc_checkaction1, SYM_SUB);
+	if (tl->err)
+		return (tl->err);
+	VCC_WalkSymbols(tl, vcc_checkaction2, SYM_SUB);
+	return (tl->err);
+}
+
+/*--------------------------------------------------------------------*/
+
 static struct procuse *
 vcc_FindIllegalUse(const struct proc *p, const struct method *m)
 {
@@ -374,34 +346,41 @@
 	return (0);
 }
 
-int
-vcc_CheckUses(struct vcc *tl)
+static void
+vcc_checkuses(struct vcc *tl, const struct symbol *sym)
 {
 	struct proc *p;
 	struct method *m;
 	struct procuse *pu;
 	int i;
 
-	VTAILQ_FOREACH(p, &tl->procs, list) {
-		i = IsMethod(p->name);
-		if (i < 0)
-			continue;
-		m = method_tab + i;
-		pu = vcc_FindIllegalUse(p, m);
-		if (pu != NULL) {
-			vsb_printf(tl->sb,
-			    "'%.*s': %s in method '%.*s'.",
-			    PF(pu->t), pu->use, PF(p->name));
-			vsb_cat(tl->sb, "\nAt: ");
-			vcc_ErrWhere(tl, pu->t);
-			return (1);
-		}
-		if (vcc_CheckUseRecurse(tl, p, m)) {
-			vsb_printf(tl->sb,
-			    "\n...which is the \"%s\" method\n", m->name);
-			return (1);
-		}
+	p = sym->proc;
+	AN(p);
+
+	i = IsMethod(p->name);
+	if (i < 0)
+		return;
+	m = method_tab + i;
+	pu = vcc_FindIllegalUse(p, m);
+	if (pu != NULL) {
+		vsb_printf(tl->sb,
+		    "'%.*s': %s in method '%.*s'.",
+		    PF(pu->t), pu->use, PF(p->name));
+		vsb_cat(tl->sb, "\nAt: ");
+		vcc_ErrWhere(tl, pu->t);
+		return;
 	}
-	return (0);
+	if (vcc_CheckUseRecurse(tl, p, m)) {
+		vsb_printf(tl->sb,
+		    "\n...which is the \"%s\" method\n", m->name);
+		return;
+	}
 }
 
+int
+vcc_CheckUses(struct vcc *tl)
+{
+
+	VCC_WalkSymbols(tl, vcc_checkuses, SYM_SUB);
+	return (tl->err);
+}




More information about the varnish-commit mailing list