[master] 2c8c2d9 Simplify the wildcard symbol-lookups
Poul-Henning Kamp
phk at FreeBSD.org
Tue Jan 30 11:01:08 UTC 2018
commit 2c8c2d981b34242e95f1075cd05f28c182e0d19d
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Tue Jan 30 11:00:18 2018 +0000
Simplify the wildcard symbol-lookups
diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index 756a92f..84e849e 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -106,8 +106,7 @@ enum symkind {
typedef void sym_expr_t(struct vcc *tl, struct expr **,
struct symbol *sym, vcc_type_t);
-typedef void sym_wildcard_t(struct vcc *, struct symbol *,
- const char *, const char *);
+typedef void sym_wildcard_t(struct vcc *, struct symbol *, struct symbol *);
typedef void sym_act_f(struct vcc *tl);
@@ -315,8 +314,6 @@ void vcc_stevedore(struct vcc *vcc, const char *stv_name);
/* vcc_symb.c */
void VCC_PrintCName(struct vsb *vsb, const char *b, const char *e);
struct symbol *VCC_MkSym(struct vcc *tl, const char *b, enum symkind kind);
-struct symbol *VCC_Symbol(struct vcc *, struct symbol *,
- const char *, const char *, enum symkind, int);
extern const char XREF_NONE[];
extern const char XREF_DEF[];
extern const char XREF_REF[];
diff --git a/lib/libvcc/vcc_symb.c b/lib/libvcc/vcc_symb.c
index b083191..0e58c4c 100644
--- a/lib/libvcc/vcc_symb.c
+++ b/lib/libvcc/vcc_symb.c
@@ -104,50 +104,7 @@ vcc_new_symbol(struct vcc *tl, const char *b, const char *e)
return (sym);
}
-const char XREF_NONE[] = "xref_none";
-const char XREF_DEF[] = "xref_def";
-const char XREF_REF[] = "xref_ref";
-const char SYMTAB_NOERR[] = "sym_noerror";
-const char SYMTAB_CREATE[] = "sym_create";
-
-struct symbol *
-VCC_SymbolGet(struct vcc *tl, enum symkind kind, const char *e, const char *x)
-{
- struct symbol *sym;
-
- AN(e);
- sym = VCC_Symbol(tl, NULL, tl->t->b, tl->t->e, kind,
- e == SYMTAB_CREATE ? 1 : 0);
- if (sym == NULL && e == SYMTAB_NOERR)
- return (sym);
- if (sym == NULL || (kind != SYM_NONE && sym->kind != kind)) {
- VSB_printf(tl->sb, "%s: ", e);
- vcc_ErrToken(tl, tl->t);
- VSB_cat(tl->sb, "\nAt: ");
- vcc_ErrWhere(tl, tl->t);
- return (NULL);
- }
- if (x == XREF_DEF) {
- if (sym->def_b == NULL)
- sym->def_b = tl->t;
- sym->ndef++;
- } else if (x == XREF_REF) {
- if (sym->ref_b == NULL)
- sym->ref_b = tl->t;
- sym->nref++;
- } else {
- assert (x == XREF_NONE);
- }
- return (sym);
-}
-
-struct symbol *
-VCC_MkSym(struct vcc *tl, const char *b, enum symkind kind)
-{
- return (VCC_Symbol(tl, NULL, b, NULL, kind, 1));
-}
-
-struct symbol *
+static struct symbol *
VCC_Symbol(struct vcc *tl, struct symbol *parent,
const char *b, const char *e, enum symkind kind, int create)
{
@@ -196,9 +153,20 @@ VCC_Symbol(struct vcc *tl, struct symbol *parent,
}
if (sym == NULL && create == 0 && parent->wildcard != NULL) {
AN(parent->wildcard);
- parent->wildcard(tl, parent, b, e);
+ 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;
+ }
+ 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));
}
if (sym == NULL && create < 1)
@@ -219,6 +187,50 @@ VCC_Symbol(struct vcc *tl, struct symbol *parent,
return (VCC_Symbol(tl, sym, ++q, e, kind, create));
}
+const char XREF_NONE[] = "xref_none";
+const char XREF_DEF[] = "xref_def";
+const char XREF_REF[] = "xref_ref";
+const char SYMTAB_NOERR[] = "sym_noerror";
+const char SYMTAB_CREATE[] = "sym_create";
+
+struct symbol *
+VCC_SymbolGet(struct vcc *tl, enum symkind kind, const char *e, const char *x)
+{
+ struct symbol *sym;
+
+ AN(e);
+ sym = VCC_Symbol(tl, NULL, tl->t->b, tl->t->e, kind,
+ e == SYMTAB_CREATE ? 1 : 0);
+ if (sym == NULL && e == SYMTAB_NOERR)
+ return (sym);
+ if (sym == NULL || (kind != SYM_NONE && sym->kind != kind)) {
+ VSB_printf(tl->sb, "%s: ", e);
+ vcc_ErrToken(tl, tl->t);
+ VSB_cat(tl->sb, "\nAt: ");
+ vcc_ErrWhere(tl, tl->t);
+ return (NULL);
+ }
+ if (x == XREF_DEF) {
+ if (sym->def_b == NULL)
+ sym->def_b = tl->t;
+ sym->ndef++;
+ } else if (x == XREF_REF) {
+ if (sym->ref_b == NULL)
+ sym->ref_b = tl->t;
+ sym->nref++;
+ } else {
+ assert (x == XREF_NONE);
+ }
+ return (sym);
+}
+
+struct symbol *
+VCC_MkSym(struct vcc *tl, const char *b, enum symkind kind)
+{
+ return (VCC_Symbol(tl, NULL, b, NULL, kind, 1));
+}
+
+
static void
vcc_walksymbols(struct vcc *tl, const struct symbol *root,
symwalk_f *func, enum symkind kind)
diff --git a/lib/libvcc/vcc_var.c b/lib/libvcc/vcc_var.c
index 0c9af8c..ce09c4b 100644
--- a/lib/libvcc/vcc_var.c
+++ b/lib/libvcc/vcc_var.c
@@ -37,24 +37,21 @@
/*--------------------------------------------------------------------*/
void v_matchproto_(sym_wildcard_t)
-vcc_Var_Wildcard(struct vcc *tl, struct symbol *parent,
- const char *b, const char *e)
+vcc_Var_Wildcard(struct vcc *tl, struct symbol *parent, struct symbol *sym)
{
- struct symbol *sym;
struct vsb *vsb;
- unsigned len;
assert(parent->fmt == HEADER);
- if (b + 127 <= e) {
- VSB_printf(tl->sb, "HTTP header (%.20s..) is too long.\n", b);
+ if (sym->nlen >= 127) {
+ VSB_printf(tl->sb, "HTTP header (%.20s..) is too long.\n",
+ sym->name);
VSB_cat(tl->sb, "\nAt: ");
vcc_ErrWhere(tl, tl->t);
- return;
}
- sym = VCC_Symbol(tl, parent, b, e, SYM_VAR, 1);
AN(sym);
+ sym->kind = SYM_VAR;
sym->fmt = parent->fmt;
sym->eval = vcc_Eval_Var;
sym->r_methods = parent->r_methods;
@@ -65,14 +62,13 @@ vcc_Var_Wildcard(struct vcc *tl, struct symbol *parent,
vsb = VSB_new_auto();
AN(vsb);
VSB_printf(vsb, "&VGC_%s_", parent->rname);
- VCC_PrintCName(vsb, b, e);
+ VCC_PrintCName(vsb, sym->name, NULL);
AZ(VSB_finish(vsb));
/* Create the static identifier */
- len = (unsigned)(e - b);
Fh(tl, 0, "static const struct gethdr_s %s =\n", VSB_data(vsb) + 1);
- Fh(tl, 0, " { %s, \"\\%03o%.*s:\"};\n",
- parent->rname, len + 1, len, b);
+ Fh(tl, 0, " { %s, \"\\%03o%s:\"};\n",
+ parent->rname, sym->nlen + 1, sym->name);
/* Create the symbol r/l values */
sym->rname = TlDup(tl, VSB_data(vsb));
More information about the varnish-commit
mailing list