[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