[master] ba63e4e Introduce "Handle" symbols and "Global" symbols as a special case.

Poul-Henning Kamp phk at FreeBSD.org
Thu May 19 10:00:09 CEST 2016


commit ba63e4eb2051355c6639ad50c19240bf6da449da
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Thu May 19 07:51:11 2016 +0000

    Introduce "Handle" symbols and "Global" symbols as a special case.
    
    Handle symbols are ACL, BACKEND, PROBE and STEVEDORE, they are not
    variables, but "things which do stuff".
    
    The only real difference from variables (like resp.status) is that
    when they are stringified (resp.http.foo = BLA) they return the
    name of the thing (ie: backend, acl ... name) rather than a value,
    which they don't have.
    
    Handles are by definition available everywhere.
    
    Global symbols are handles available in any VCL (ie: STEVEDOREs).

diff --git a/bin/varnishtest/tests/r00916.vtc b/bin/varnishtest/tests/r00916.vtc
index 8057f1a..ac268ca 100644
--- a/bin/varnishtest/tests/r00916.vtc
+++ b/bin/varnishtest/tests/r00916.vtc
@@ -5,7 +5,7 @@ server s1 {
 	txresp -body "FOO"
 } -start
 
-varnish v1 -errvcl {Backend not found: 's-1'} {
+varnish v1 -errvcl {Symbol not found: 's-1' (expected type BACKEND):} {
 	backend b { .host = "127.0.0.1"; }
 	sub s1 {
 	}
diff --git a/bin/varnishtest/tests/v00016.vtc b/bin/varnishtest/tests/v00016.vtc
index 990f39e..009f17d 100644
--- a/bin/varnishtest/tests/v00016.vtc
+++ b/bin/varnishtest/tests/v00016.vtc
@@ -119,7 +119,7 @@ varnish v1 -errvcl {'bereq.between_bytes_timeout': cannot be set} {
 	}
 }
 
-varnish v1 -errvcl {Backend not found: 'c'} {
+varnish v1 -errvcl {Symbol not found: 'c' (expected type BACKEND):} {
 	backend b { .host = "127.0.0.1"; }
 	sub vcl_backend_response {
 		if (beresp.backend == c) {
diff --git a/lib/libvcc/vcc_acl.c b/lib/libvcc/vcc_acl.c
index f3e3488..c6f57fb 100644
--- a/lib/libvcc/vcc_acl.c
+++ b/lib/libvcc/vcc_acl.c
@@ -474,7 +474,6 @@ void
 vcc_ParseAcl(struct vcc *tl)
 {
 	struct token *an;
-	struct symbol *sym;
 	char *acln;
 
 	vcc_NextToken(tl);
@@ -492,15 +491,7 @@ vcc_ParseAcl(struct vcc *tl)
 
 	acln = TlDupTok(tl, an);
 
-	sym = VCC_GetSymbolTok(tl, an, SYM_ACL);
-	AN(sym);
-	if (sym->ndef > 0) {
-		VSB_printf(tl->sb, "ACL %.*s redefined\n", PF(an));
-		vcc_ErrWhere(tl, an);
-		return;
-	}
-	VCC_GenericSymbol(tl, sym, ACL, "&vrt_acl_named_%s", acln);
-	sym->ndef++;
+	(void)VCC_HandleSymbol(tl, an, ACL, "&vrt_acl_named_%s", acln);
 	ERRCHK(tl);
 
 	SkipToken(tl, '{');
diff --git a/lib/libvcc/vcc_backend.c b/lib/libvcc/vcc_backend.c
index c860dc2..6e9c498 100644
--- a/lib/libvcc/vcc_backend.c
+++ b/lib/libvcc/vcc_backend.c
@@ -249,7 +249,6 @@ void
 vcc_ParseProbe(struct vcc *tl)
 {
 	struct token *t_probe;
-	struct symbol *sym;
 	char *p;
 
 	vcc_NextToken(tl);		/* ID: probe */
@@ -259,15 +258,7 @@ vcc_ParseProbe(struct vcc *tl)
 	t_probe = tl->t;
 	vcc_NextToken(tl);
 
-	sym = VCC_GetSymbolTok(tl, t_probe, SYM_PROBE);
-	AN(sym);
-	if (sym->ndef > 0) {
-		VSB_printf(tl->sb, "Probe %.*s redefined\n", PF(t_probe));
-		vcc_ErrWhere(tl, t_probe);
-		return;
-	}
-	VCC_GenericSymbol(tl, sym, PROBE, "%s", sym->name);
-	sym->ndef++;
+	(void)VCC_HandleSymbol(tl, t_probe, PROBE, "%.s", PF(t_probe));
 	ERRCHK(tl);
 
 	vcc_ParseProbeSpec(tl, t_probe, &p);
@@ -489,15 +480,7 @@ vcc_ParseBackend(struct vcc *tl)
 	sprintf(vgcname, "vgc_backend_%.*s", PF(t_be));
 	Fh(tl, 0, "\nstatic struct director *%s;\n", vgcname);
 
-	sym = VCC_GetSymbolTok(tl, t_be, SYM_BACKEND);
-	AN(sym);
-	if (sym->ndef > 0) {
-		VSB_printf(tl->sb, "Backend %.*s redefined\n", PF(t_be));
-		vcc_ErrWhere(tl, t_be);
-		return;
-	}
-	VCC_GenericSymbol(tl, sym, BACKEND, "%s", vgcname);
-	sym->ndef++;
+	sym = VCC_HandleSymbol(tl, t_be, BACKEND, "%s", vgcname);
 	ERRCHK(tl);
 
 	vcc_ParseHostDef(tl, t_be, vgcname);
@@ -511,7 +494,7 @@ vcc_ParseBackend(struct vcc *tl)
 	}
 
 	if (tl->default_director == NULL || vcc_IdIs(t_be, "default")) {
-		tl->default_director = sym->eval_priv;
+		tl->default_director = sym->rname;
 		tl->t_default_director = t_be;
 	}
 }
diff --git a/lib/libvcc/vcc_compile.c b/lib/libvcc/vcc_compile.c
index fc5ccc1..bc22cad 100644
--- a/lib/libvcc/vcc_compile.c
+++ b/lib/libvcc/vcc_compile.c
@@ -692,11 +692,12 @@ vcc_CompileSource(const struct vcp * const vcp, struct vsb *sb,
 	vcc_Expr_Init(tl);
 
 	VTAILQ_FOREACH(sym, &vcp->symbols, list) {
-		assert(sym->eval == vcc_Eval_Generic);
 		sym2 = VCC_AddSymbolStr(tl, sym->name, sym->kind);
 		sym2->fmt = sym->fmt;
 		sym2->eval = sym->eval;
 		sym2->eval_priv = sym->eval_priv;
+		sym2->rname = sym->rname;
+		sym2->r_methods = sym->r_methods;
 		sym2->ndef = 1;
 		sym2->nref = 1;
 	}
@@ -951,8 +952,7 @@ VCP_Stevedore(struct vcp *vcp, const char *stv_name)
 	AN(sym);
 	REPLACE(sym->name, stv_name);		/* XXX storage.* ? */
 	sym->kind = SYM_STEVEDORE;
-	VCC_GenericSymbol(NULL, sym, STEVEDORE,
-	    "VRT_stevedore(\"%s\")", stv_name);
+	VCC_GlobalSymbol(sym, STEVEDORE, "VRT_stevedore(\"%s\")", stv_name);
 	VTAILQ_INSERT_TAIL(&vcp->symbols, sym, list);
 }
 
diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index d02029d..647c760 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -287,11 +287,14 @@ void vcc_Expr(struct vcc *tl, enum var_type typ);
 void vcc_Expr_Call(struct vcc *tl, const struct symbol *sym);
 void vcc_Expr_Init(struct vcc *tl);
 sym_expr_t vcc_Eval_Var;
-sym_expr_t vcc_Eval_Generic;
+sym_expr_t vcc_Eval_Handle;
 sym_expr_t vcc_Eval_SymFunc;
 void vcc_Eval_Func(struct vcc *tl, const char *cfunc, const char *extra,
     const char *name, const char *args);
 enum var_type VCC_arg_type(const char **p);
+enum symkind VCC_HandleKind(enum var_type fmt);
+struct symbol *VCC_HandleSymbol(struct vcc *, const struct token *,
+    enum var_type fmt, const char *str, ...);
 
 /* vcc_obj.c */
 extern const struct var vcc_vars[];
@@ -320,8 +323,7 @@ struct symbol *VCC_FindSymbol(struct vcc *tl,
 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);
-void VCC_GenericSymbol(struct vcc *, struct symbol *,
-    enum var_type, const char *str, ...);
+void VCC_GlobalSymbol(struct symbol *, enum var_type, const char *str, ...);
 
 /* vcc_token.c */
 void vcc_Coord(const struct vcc *tl, struct vsb *vsb,
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index 506f196..1d0108c 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -498,12 +498,12 @@ vcc_Eval_BoolConst(struct vcc *tl, struct expr **e, const struct symbol *sym,
  */
 
 void __match_proto__(sym_expr_t)
-vcc_Eval_Generic(struct vcc *tl, struct expr **e, const struct symbol *sym,
+vcc_Eval_Handle(struct vcc *tl, struct expr **e, const struct symbol *sym,
     enum var_type fmt)
 {
 
 	assert(sym->kind == sym->kind);
-	AN(sym->eval_priv);
+	AN(sym->rname);
 
 	if (sym->fmt != STRING && (fmt == STRING || fmt == STRING_LIST)) {
 		*e = vcc_mk_expr(STRING, "\"%s\"", sym->name);
@@ -511,7 +511,7 @@ vcc_Eval_Generic(struct vcc *tl, struct expr **e, const struct symbol *sym,
 	} else {
 		vcc_ExpectCid(tl);
 		vcc_AddRef(tl, tl->t, sym->kind);
-		*e = vcc_mk_expr(sym->fmt, "%s", (const char *)sym->eval_priv);
+		*e = vcc_mk_expr(sym->fmt, "%s", sym->rname);
 		(*e)->constant = EXPR_VAR;	/* XXX ? */
 	}
 	vcc_NextToken(tl);
@@ -817,13 +817,7 @@ vcc_expr4(struct vcc *tl, struct expr **e, enum var_type fmt)
 		 * XXX: look for SYM_VAR first for consistency ?
 		 */
 		sym = NULL;
-		switch (fmt) {
-		case ACL:	kind = SYM_ACL; break;
-		case BACKEND:	kind = SYM_BACKEND; break;
-		case PROBE:	kind = SYM_PROBE; break;
-		case STEVEDORE:	kind = SYM_STEVEDORE; break;
-		default:	kind = SYM_NONE; break;
-		}
+		kind = VCC_HandleKind(fmt);
 		if (kind != SYM_NONE)
 			sym = VCC_FindSymbol(tl, tl->t, kind);
 		if (sym == NULL)
@@ -1157,7 +1151,7 @@ vcc_expr_cmp(struct vcc *tl, struct expr **e, enum var_type fmt)
 	const char *re;
 	const char *not;
 	struct token *tk;
-	struct symbol *sym;
+	enum symkind kind;
 
 	*e = NULL;
 
@@ -1215,24 +1209,14 @@ vcc_expr_cmp(struct vcc *tl, struct expr **e, enum var_type fmt)
 		*e = vcc_expr_edit(BOOL, buf, *e, NULL);
 		return;
 	}
-	if ((*e)->fmt == BACKEND &&
-	    (tl->t->tok == T_EQ || tl->t->tok == T_NEQ)) {
-		// XXX: just ask for a BACKEND expression instead ?
-		vcc_NextToken(tl);
-		ExpectErr(tl, ID);
-		sym = VCC_FindSymbol(tl, tl->t, SYM_BACKEND);
-		if (sym == NULL) {
-			VSB_printf(tl->sb, "Backend not found: ");
-			vcc_ErrToken(tl, tl->t);
-			VSB_printf(tl->sb, "\n");
-			vcc_ErrWhere(tl, tl->t);
-			return;
-		}
-		vcc_AddRef(tl, tl->t, SYM_BACKEND);
-		bprintf(buf, "(\v1 %.*s %s)", PF(tk),
-		    (const char *)sym->eval_priv);
+	kind = VCC_HandleKind((*e)->fmt);
+	if (kind != SYM_NONE && (tl->t->tok == T_EQ || tl->t->tok == T_NEQ)) {
+		bprintf(buf, "(\v1 %.*s \v2)", PF(tk));
 		vcc_NextToken(tl);
-		*e = vcc_expr_edit(BOOL, buf, *e, NULL);
+		e2 = NULL;
+		vcc_expr0(tl, &e2, (*e)->fmt);
+		ERRCHK(tl);
+		*e = vcc_expr_edit(BOOL, buf, *e, e2);
 		return;
 	}
 	switch (tl->t->tok) {
diff --git a/lib/libvcc/vcc_symb.c b/lib/libvcc/vcc_symb.c
index 02e9fe0..762e27b 100644
--- a/lib/libvcc/vcc_symb.c
+++ b/lib/libvcc/vcc_symb.c
@@ -28,6 +28,7 @@
 
 #include "config.h"
 
+#include <ctype.h>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -37,6 +38,18 @@
 
 /*--------------------------------------------------------------------*/
 
+enum symkind
+VCC_HandleKind(enum var_type fmt)
+{
+	switch(fmt) {
+	case ACL:       return(SYM_ACL);
+	case BACKEND:   return(SYM_BACKEND);
+	case PROBE:     return(SYM_PROBE);
+	case STEVEDORE: return(SYM_STEVEDORE);
+	default:        return(SYM_NONE);
+	}
+}
+
 const char *
 VCC_SymKind(struct vcc *tl, const struct symbol *s)
 {
@@ -141,25 +154,68 @@ VCC_WalkSymbols(struct vcc *tl, symwalk_f *func, enum symkind kind)
 	}
 }
 
-void
-VCC_GenericSymbol(struct vcc *tl, struct symbol *sym,
-    enum var_type fmt, const char *str, ...)
+static void
+vcc_global(struct vcc *tl, struct symbol *sym,
+    enum var_type fmt, const char *str, va_list ap)
 {
 	struct vsb *vsb;
-	va_list ap;
 
 	vsb = VSB_new_auto();
 	AN(vsb);
-	va_start(ap, str);
 	VSB_vprintf(vsb, str, ap);
-	va_end(ap);
 	AZ(VSB_finish(vsb));
 	if (tl != NULL)
-		sym->eval_priv = TlDup(tl, VSB_data(vsb));
+		sym->rname = TlDup(tl, VSB_data(vsb));
 	else
-		sym->eval_priv = strdup(VSB_data(vsb));
-	AN(sym->eval_priv);
-	sym->eval = vcc_Eval_Generic;
-	sym->fmt = fmt;
+		sym->rname = strdup(VSB_data(vsb));
+	AN(sym->rname);
 	VSB_destroy(&vsb);
+	sym->fmt = fmt;
+	sym->kind = VCC_HandleKind(sym->fmt);
+	if (sym->kind != SYM_NONE)
+		sym->eval = vcc_Eval_Handle;
+	else
+		WRONG("Wrong kind of global symbol");
+
+#define VCL_MET_MAC(l,u,t,b)   sym->r_methods |= VCL_MET_##u;
+#include "tbl/vcl_returns.h"
+#undef VCL_MET_MAC
+}
+
+void
+VCC_GlobalSymbol(struct symbol *sym, enum var_type fmt, const char *str, ...)
+{
+	va_list ap;
+
+	va_start(ap, str);
+	vcc_global(NULL, sym, fmt, str, ap);
+	va_end(ap);
+}
+
+struct symbol *
+VCC_HandleSymbol(struct vcc *tl, const struct token *tk, enum var_type fmt,
+    const char *str, ...)
+{
+	struct symbol *sym;
+	enum symkind kind;
+	va_list ap;
+	const char *p;
+
+	kind = VCC_HandleKind(fmt);
+	assert(kind != SYM_NONE);
+
+	sym = VCC_GetSymbolTok(tl, tk, kind);
+	AN(sym);
+	if (sym->ndef > 0) {
+		p = VCC_SymKind(tl, sym);
+		VSB_printf(tl->sb, "%c%s %.*s redefined\n",
+		    toupper(*p), p+1, PF(tk));
+		vcc_ErrWhere(tl, tk);
+		return (sym);
+	}
+	va_start(ap, str);
+	vcc_global(tl, sym, fmt, str, ap);
+	va_end(ap);
+	sym->ndef = 1;
+	return (sym);
 }



More information about the varnish-commit mailing list