[master] bc3b93bcc Split the symbol-table into a naming and a content layer.

Poul-Henning Kamp phk at FreeBSD.org
Wed May 29 09:54:11 UTC 2019


commit bc3b93bcca6f5a573eb1344d8c374124b0e8aecb
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Wed May 29 09:53:03 2019 +0000

    Split the symbol-table into a naming and a content layer.

diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index 156ea816e..c9ea92d5d 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -58,6 +58,7 @@ struct vsb;
 struct token;
 struct sockaddr_storage;
 struct method;
+struct symtab;
 
 unsigned vcl_fixed_token(const char *p, const char **q);
 extern const char * const vcl_tnames[256];
@@ -135,15 +136,13 @@ struct symbol {
 #define SYMBOL_MAGIC			0x3368c9fb
 	VTAILQ_ENTRY(symbol)		list;
 	VTAILQ_ENTRY(symbol)		sideways;
-	VTAILQ_HEAD(,symbol)		children;
 
-	char				*name;
-	unsigned			nlen;
+	const char			*name;
 
 	int				lorev;
 	int				hirev;
 
-	struct symbol			*parent;
+	const struct symtab		*symtab;
 	const char			*vmod_name;
 
 	sym_wildcard_t			*wildcard;
@@ -222,7 +221,7 @@ struct vcc {
 	unsigned		allow_inline_c;
 	unsigned		unsafe_path;
 
-	struct symbol		*symbols;
+	struct symtab		*syms;
 
 	struct inifinhead	inifin;
 	unsigned		ninifin;
diff --git a/lib/libvcc/vcc_symb.c b/lib/libvcc/vcc_symb.c
index 032f9e97a..134599e6b 100644
--- a/lib/libvcc/vcc_symb.c
+++ b/lib/libvcc/vcc_symb.c
@@ -42,6 +42,17 @@
 #include "tbl/symbol_kind.h"
 /*--------------------------------------------------------------------*/
 
+struct symtab {
+	unsigned                        magic;
+#define SYMTAB_MAGIC                    0x084d9c8a
+	unsigned                        nlen;
+	char                            *name;
+	struct symtab			*parent;
+	VTAILQ_ENTRY(symtab)            list;
+	VTAILQ_HEAD(,symtab)            children;
+	VTAILQ_HEAD(,symbol)            symbols;
+};
+
 static vcc_kind_t
 VCC_HandleKind(vcc_type_t fmt)
 {
@@ -72,88 +83,140 @@ VCC_PrintCName(struct vsb *vsb, const char *b, const char *e)
 			VSB_printf(vsb, "_%02x_", *b);
 }
 
-void
-VCC_SymName(struct vsb *vsb, const struct symbol *sym)
+static void
+vcc_symtabname(struct vsb *vsb, const struct symtab *st)
 {
-	if (sym->parent != NULL && sym->parent->parent != NULL) {
-		VCC_SymName(vsb, sym->parent);
+	if (st->parent != NULL && st->parent->parent != NULL) {
+		vcc_symtabname(vsb, st->parent);
 		VSB_putc(vsb, '.');
 	}
-	VSB_cat(vsb, sym->name);
+	VSB_cat(vsb, st->name);
 }
 
-static struct symbol *
-vcc_new_symbol(struct vcc *tl, const char *b, const char *e)
+void
+VCC_SymName(struct vsb *vsb, const struct symbol *sym)
 {
-	struct symbol *sym;
+	AN(vsb);
+	CHECK_OBJ_NOTNULL(sym, SYMBOL_MAGIC);
+	CHECK_OBJ_NOTNULL(sym->symtab, SYMTAB_MAGIC);
+	vcc_symtabname(vsb, sym->symtab);
+}
+
+static char *
+vcc_dup_be(const char *b, const char *e)
+{
+	char *p;
 
 	AN(b);
 	if (e == NULL)
 		e = strchr(b, '\0');
 	AN(e);
-	assert(e > b);
+	assert(e >= b);
+
+	p = malloc((e - b) + 1);
+	AN(p);
+	memcpy(p, b, e - b);
+	p[e - b] = '\0';
+	return (p);
+}
+
+static struct symtab *
+vcc_symtab_new(const char *b, const char *e)
+{
+	struct symtab *st;
+
+	ALLOC_OBJ(st, SYMTAB_MAGIC);
+	AN(st);
+	st->name = vcc_dup_be(b, e);
+	st->nlen = strlen(st->name);
+	VTAILQ_INIT(&st->children);
+	VTAILQ_INIT(&st->symbols);
+	return (st);
+}
+
+static const char * const rootname = "";
+
+static struct symtab *
+vcc_symtab_str(struct vcc *tl, const char *b, const char *e)
+{
+	struct symtab *st1, *st2, *st3;
+	size_t l;
+	int i;
+	char *p, *q;
+
+	AN(tl);
+	p = vcc_dup_be(b, e);
+
+	if (tl->syms == NULL)
+		tl->syms = vcc_symtab_new(rootname, rootname);
+	st1 = tl->syms;
+
+	while (1) {
+		q = strchr(p, '.');
+		if (q == NULL)
+			q = strchr(p, '\0');
+		else
+			assert(q[1] != '.' && q[1] != '\0');
+		AN(q);
+		l = q - p;
+		VTAILQ_FOREACH(st2, &st1->children, list) {
+			i = strncasecmp(st2->name, p, l);
+			if (i < 0)
+				continue;
+			if (i == 0 && l == st2->nlen)
+				break;
+			st3 = vcc_symtab_new(p, q);
+			st3->parent = st1;
+			VTAILQ_INSERT_BEFORE(st2, st3, list);
+			st2 = st3;
+			break;
+		}
+		if (st2 == NULL) {
+			st2 = vcc_symtab_new(p, q);
+			st2->parent = st1;
+			VTAILQ_INSERT_TAIL(&st1->children, st2, list);
+		}
+		if (*q == '\0')
+			return (st2);
+		st1 = st2;
+		p = q + 1;
+	}
+}
+
+static struct symbol *
+vcc_new_symbol(struct vcc *tl, struct symtab *st)
+{
+	struct symbol *sym;
+
 	sym = TlAlloc(tl, sizeof *sym);
 	INIT_OBJ(sym, SYMBOL_MAGIC);
 	AN(sym);
-	sym->name = TlAlloc(tl, (e - b) + 1L);
-	AN(sym->name);
-	memcpy(sym->name, b, (e - b));
-	sym->name[e - b] = '\0';
-	sym->nlen = e - b;
-	VTAILQ_INIT(&sym->children);
+	sym->name = st->name;
+	sym->symtab = st;
 	sym->kind = SYM_NONE;
 	sym->type = VOID;
 	sym->lorev = VCL_LOW;
 	sym->hirev = VCL_HIGH;
+	VTAILQ_INSERT_TAIL(&st->symbols, sym, list);
 	return (sym);
 }
 
 static struct symbol *
-VCC_Symbol(struct vcc *tl, struct symbol *parent,
+VCC_Symbol(struct vcc *tl,
     const char *b, const char *e, vcc_kind_t kind,
     int create, int vlo, int vhi)
 {
-	const char *q;
-	struct symbol *sym, *sym2 = NULL;
-	size_t l;
-	int i;
+	struct symtab *st, *pst;
+	struct symbol *sym, *psym;
 
 	assert(vlo <= vhi);
-	if (tl->symbols == NULL)
-		tl->symbols = vcc_new_symbol(tl, "<root>", NULL);
-	if (parent == NULL)
-		parent = tl->symbols;
 
-	AN(b);
-	assert(e == NULL || b < e);
-	if (e == NULL)
-		e = strchr(b, '\0');
-	assert(e > b);
-	if (e[-1] == '.')
-		e--;
-	assert(e > b);
-
-	q = strchr(b, '.');
-	if (q == NULL || q > e)
-		q = e;
-	l = q - b;
-	assert(l > 0);
-
-	VTAILQ_FOREACH(sym, &parent->children, list) {
-		i = strncasecmp(sym->name, b, l);
-		if (i < 0)
-			continue;
-		if (i > 0 || l < sym->nlen) {
-			sym2 = sym;
-			sym = NULL;
-			break;
-		}
-		if (l > sym->nlen)
-			continue;
+	st = vcc_symtab_str(tl, b, e);
+	AN(st);
+
+	VTAILQ_FOREACH(sym, &st->symbols, list) {
 		if (sym->lorev > vhi || sym->hirev < vlo)
 			continue;
-		if (q < e)
-			break;
 		if ((kind == SYM_NONE && kind == sym->kind))
 			continue;
 		if (tl->syntax < VCL_41 && strcmp(sym->name, "default") &&
@@ -161,44 +224,30 @@ VCC_Symbol(struct vcc *tl, struct symbol *parent,
 			continue;
 		break;
 	}
-	if (sym == NULL && create == 0 && parent->wildcard != NULL) {
-		AN(parent->wildcard);
-		sym2 = vcc_new_symbol(tl, b, e);
-		sym2->parent = parent;
-		parent->wildcard(tl, parent, sym2);
-		if (tl->err)
-			return (NULL);
-		VTAILQ_FOREACH(sym, &parent->children, list) {
-			i = strncasecmp(sym->name, b, l);
-			if (i > 0 || (i == 0 && l < sym->nlen))
-				break;
-		}
-		sym2->lorev = vlo;
-		sym2->hirev = vhi;
-		if (sym == NULL)
-			VTAILQ_INSERT_TAIL(&parent->children, sym2, list);
-		else
-			VTAILQ_INSERT_BEFORE(sym, sym2, list);
-		return (VCC_Symbol(tl, parent, b, e, kind, -1, vlo, vhi));
-	}
-	if (sym == NULL && create < 1)
+	if (sym != NULL)
 		return (sym);
-	if (sym == NULL) {
-		sym = vcc_new_symbol(tl, b, q);
-		sym->parent = parent;
+	if (create) {
+		sym = vcc_new_symbol(tl, st);
 		sym->lorev = vlo;
 		sym->hirev = vhi;
-		if (sym2 != NULL)
-			VTAILQ_INSERT_BEFORE(sym2, sym, list);
-		else
-			VTAILQ_INSERT_TAIL(&parent->children, sym, list);
-		if (q == e)
-			sym->kind = kind;
+		sym->kind = kind;
 	}
-	if (q == e)
-		return (sym);
-	assert(*q == '.');
-	return (VCC_Symbol(tl, sym, ++q, e, kind, create, vlo, vhi));
+	pst = st->parent;
+	if (pst == NULL)
+		return(sym);
+	psym = VTAILQ_FIRST(&pst->symbols);
+	if (psym == NULL)
+		return(sym);
+	if (psym->wildcard != NULL) {
+		sym = vcc_new_symbol(tl, st);
+		sym->lorev = vlo;
+		sym->hirev = vhi;
+		sym->kind = kind;
+		psym->wildcard(tl, psym, sym);
+		if (tl->err)
+			return(NULL);
+	}
+	return(sym);
 }
 
 const char XREF_NONE[] = "xref_none";
@@ -225,14 +274,14 @@ VCC_SymbolGetTok(struct vcc *tl, vcc_kind_t kind, const char *e, const char *x,
 		return (NULL);
 	}
 
-	sym = VCC_Symbol(tl, NULL, t->b, t->e, kind,
+	sym = VCC_Symbol(tl, t->b, t->e, kind,
 	    e == SYMTAB_CREATE ? 1 : 0, tl->syntax, tl->syntax);
 	if (sym == NULL && e == SYMTAB_NOERR)
 		return (sym);
 	if (sym == NULL) {
 		VSB_printf(tl->sb, "%s: ", e);
 		vcc_ErrToken(tl, t);
-		sym = VCC_Symbol(tl, NULL, t->b, t->e, kind, 0,
+		sym = VCC_Symbol(tl, t->b, t->e, kind, 0,
 			VCL_LOW, VCL_HIGH);
 		if (sym != NULL) {
 			VSB_printf(tl->sb, " (Only available when");
@@ -283,6 +332,7 @@ struct symbol *
 VCC_SymbolGet(struct vcc *tl, vcc_kind_t kind, const char *e, const char *x)
 {
 	struct symbol *sym;
+
 	sym = VCC_SymbolGetTok(tl, kind, e, x, tl->t);
 	if (sym != NULL)
 		vcc_NextToken(tl);
@@ -294,26 +344,34 @@ VCC_MkSym(struct vcc *tl, const char *b, vcc_kind_t kind, int vlo, int vhi)
 {
 	struct symbol *sym;
 
-	sym = VCC_Symbol(tl, NULL, b, NULL, kind, 1, vlo, vhi);
+	AN(tl);
+	AN(b);
+	CHECK_OBJ_NOTNULL(kind, KIND_MAGIC);
+
+	sym = VCC_Symbol(tl, b, NULL, kind, 1, vlo, vhi);
+	AN(sym);
 	sym->noref = 1;
 	return (sym);
 }
 
 
 static void
-vcc_walksymbols(struct vcc *tl, const struct symbol *root,
+vcc_walksymbols(struct vcc *tl, const struct symtab *root,
     symwalk_f *func, vcc_kind_t kind)
 {
-	struct symbol *sym, *sym2 = NULL;
+	struct symbol *sym;
+	struct symtab *st1, *st2 = NULL;
 
-	VTAILQ_FOREACH(sym, &root->children, list) {
-		if (sym2 != NULL)
-			assert(strcasecmp(sym->name, sym2->name) >= 0);
-		sym2 = sym;
+	VTAILQ_FOREACH(sym, &root->symbols, list) {
 		if (kind == SYM_NONE || kind == sym->kind)
 			func(tl, sym);
 		ERRCHK(tl);
-		vcc_walksymbols(tl, sym, func, kind);
+	}
+	VTAILQ_FOREACH(st1, &root->children, list) {
+		if (st2 != NULL)
+			assert(strcasecmp(st1->name, st2->name) >= 0);
+		st2 = st1;
+		vcc_walksymbols(tl, st1, func, kind);
 	}
 }
 
@@ -321,7 +379,7 @@ void
 VCC_WalkSymbols(struct vcc *tl, symwalk_f *func, vcc_kind_t kind)
 {
 
-	vcc_walksymbols(tl, tl->symbols, func, kind);
+	vcc_walksymbols(tl, tl->syms, func, kind);
 }
 
 void
diff --git a/lib/libvcc/vcc_var.c b/lib/libvcc/vcc_var.c
index 273563c23..72931c6a0 100644
--- a/lib/libvcc/vcc_var.c
+++ b/lib/libvcc/vcc_var.c
@@ -43,7 +43,7 @@ vcc_Var_Wildcard(struct vcc *tl, struct symbol *parent, struct symbol *sym)
 
 	assert(parent->type == HEADER);
 
-	if (sym->nlen >= 127) {
+	if (strlen(sym->name) >= 127) {
 		VSB_printf(tl->sb, "HTTP header (%.20s..) is too long.\n",
 		    sym->name);
 		VSB_cat(tl->sb, "\nAt: ");
@@ -69,7 +69,7 @@ vcc_Var_Wildcard(struct vcc *tl, struct symbol *parent, struct symbol *sym)
 	/* Create the static identifier */
 	Fh(tl, 0, "static const struct gethdr_s %s =\n", VSB_data(vsb) + 1);
 	Fh(tl, 0, "    { %s, \"\\%03o%s:\"};\n",
-	    parent->rname, sym->nlen + 1, sym->name);
+	    parent->rname, (unsigned int)strlen(sym->name) + 1, sym->name);
 
 	/* Create the symbol r/l values */
 	sym->rname = TlDup(tl, VSB_data(vsb));


More information about the varnish-commit mailing list