[master] 5e8c00f Renovate the comparison part of VCL expressions

Poul-Henning Kamp phk at FreeBSD.org
Tue Dec 12 09:38:06 UTC 2017


commit 5e8c00f43e80a3c694ae9af06ec454d96c194ac6
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Tue Dec 12 09:36:53 2017 +0000

    Renovate the comparison part of VCL expressions

diff --git a/lib/libvcc/vcc_acl.c b/lib/libvcc/vcc_acl.c
index 374c886..d11f926 100644
--- a/lib/libvcc/vcc_acl.c
+++ b/lib/libvcc/vcc_acl.c
@@ -460,22 +460,6 @@ vcc_acl_emit(struct vcc *tl, const char *name, const char *rname, int anon)
 }
 
 void
-vcc_Acl_Hack(struct vcc *tl, char *b, size_t bl)
-{
-	char name[32];
-	unsigned tcond;
-
-	VTAILQ_INIT(&tl->acl);
-	tcond = tl->t->tok;
-	vcc_NextToken(tl);
-	bprintf(name, "%u", tl->unique++);
-	vcc_acl_entry(tl);
-	vcc_acl_emit(tl, name, name, 1);
-	assert(snprintf(b, bl - 1, "%smatch_acl_anon_%s(ctx, \v1)",
-	    (tcond == T_NEQ ? "!" : ""), name) < bl - 1);
-}
-
-void
 vcc_ParseAcl(struct vcc *tl)
 {
 	struct token *an;
diff --git a/lib/libvcc/vcc_compile.h b/lib/libvcc/vcc_compile.h
index d19e64f..2209f23 100644
--- a/lib/libvcc/vcc_compile.h
+++ b/lib/libvcc/vcc_compile.h
@@ -245,7 +245,6 @@ struct method {
 /* vcc_acl.c */
 
 void vcc_ParseAcl(struct vcc *tl);
-void vcc_Acl_Hack(struct vcc *tl, char *b, size_t bl);
 
 /* vcc_action.c */
 int vcc_ParseAction(struct vcc *tl);
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index ec3d1d4..b55f4ba 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -939,23 +939,6 @@ vcc_expr_add(struct vcc *tl, struct expr **e, vcc_type_t fmt)
 }
 
 /*--------------------------------------------------------------------
- * Fold the STRING types correctly
- */
-
-static void
-vcc_expr_strfold(struct vcc *tl, struct expr **e, vcc_type_t fmt)
-{
-
-	vcc_expr_add(tl, e, fmt);
-	ERRCHK(tl);
-
-	if (fmt != STRING_LIST && (*e)->fmt == STRING_LIST)
-		vcc_expr_tostring(tl, e, STRING);
-	else if (fmt == STRING_LIST && (*e)->fmt == STRING)
-		(*e)->fmt = STRING_LIST;
-}
-
-/*--------------------------------------------------------------------
  * SYNTAX:
  *    ExprCmp:
  *	ExprAdd
@@ -966,34 +949,113 @@ vcc_expr_strfold(struct vcc *tl, struct expr **e, vcc_type_t fmt)
  *	ExprAdd(IP) '!~' IP
  */
 
-#define NUM_REL(typ)					\
-	{typ,		T_EQ,	"(\v1 == \v2)" },	\
-	{typ,		T_NEQ,	"(\v1 != \v2)" },	\
-	{typ,		T_LEQ,	"(\v1 <= \v2)" },	\
-	{typ,		T_GEQ,	"(\v1 >= \v2)" },	\
-	{typ,		'<',	"(\v1 < \v2)" },	\
-	{typ,		'>',	"(\v1 > \v2)" }
-
-static const struct cmps {
+struct cmps;
+
+typedef void cmp_f(struct vcc *, struct expr **, const struct cmps *);
+
+struct cmps {
 	vcc_type_t		fmt;
 	unsigned		token;
 	const char		*emit;
-} vcc_cmps[] = {
+	cmp_f			*func;
+};
+
+static void v_matchproto_(cmp_f)
+cmp_simple(struct vcc *tl, struct expr **e, const struct cmps *cp)
+{
+	struct expr *e2;
+	struct token *tk;
+
+	tk = tl->t;
+	vcc_NextToken(tl);
+	if ((*e)->fmt == STRING_LIST)
+		vcc_expr_tostring(tl, e, STRING);
+	vcc_expr_add(tl, &e2, (*e)->fmt);
+	ERRCHK(tl);
+
+	if (e2->fmt != (*e)->fmt) { /* XXX */
+		VSB_printf(tl->sb, "Comparison of different types: ");
+		VSB_printf(tl->sb, "%s ", vcc_utype((*e)->fmt));
+		vcc_ErrToken(tl, tk);
+		VSB_printf(tl->sb, " %s\n", vcc_utype(e2->fmt));
+		vcc_ErrWhere(tl, tk);
+		return;
+	}
+	*e = vcc_expr_edit(BOOL, cp->emit, *e, e2);
+}
+
+static void v_matchproto_(cmp_f)
+cmp_regexp(struct vcc *tl, struct expr **e, const struct cmps *cp)
+{
+	char buf[128];
+	const char *re;
+
+	if ((*e)->fmt != STRING)
+		vcc_expr_tostring(tl, e, STRING);
+	vcc_NextToken(tl);
+	ExpectErr(tl, CSTR);
+	re = vcc_regexp(tl);
+	ERRCHK(tl);
+	vcc_NextToken(tl);
+	bprintf(buf, "%sVRT_re_match(ctx, \v1, %s)", cp->emit, re);
+	*e = vcc_expr_edit(BOOL, buf, *e, NULL);
+}
+
+static void v_matchproto_(cmp_f)
+cmp_acl(struct vcc *tl, struct expr **e, const struct cmps *cp)
+{
+	struct symbol *sym;
+	char buf[256];
+
+	vcc_NextToken(tl);
+	vcc_ExpectVid(tl, "ACL");
+	sym = vcc_AddRef(tl, tl->t, SYM_ACL);
+	vcc_NextToken(tl);
+	VCC_GlobalSymbol(sym, ACL, ACL_SYMBOL_PREFIX);
+	bprintf(buf, "%sVRT_acl_match(ctx, %s, \v1)", cp->emit, sym->rname);
+	*e = vcc_expr_edit(BOOL, buf, *e, NULL);
+}
+
+#define IDENT_REL(typ)						\
+	{typ,		T_EQ,	"(\v1 == \v2)",	cmp_simple },	\
+	{typ,		T_NEQ,	"(\v1 != \v2)",	cmp_simple }
+
+#define NUM_REL(typ)					\
+	{typ,		T_EQ,	"(\v1 == \v2)",	cmp_simple },	\
+	{typ,		T_NEQ,	"(\v1 != \v2)",	cmp_simple },	\
+	{typ,		T_LEQ,	"(\v1 <= \v2)",	cmp_simple },	\
+	{typ,		T_GEQ,	"(\v1 >= \v2)",	cmp_simple },	\
+	{typ,		'<',	"(\v1 < \v2)",	cmp_simple },	\
+	{typ,		'>',	"(\v1 > \v2)",	cmp_simple }
+
+static const struct cmps vcc_cmps[] = {
 	NUM_REL(INT),
 	NUM_REL(DURATION),
 	NUM_REL(BYTES),
 	NUM_REL(REAL),
 	NUM_REL(TIME),
-
-	{IP,		T_EQ,	"!VRT_ipcmp(\v1, \v2)" },
-	{IP,		T_NEQ,	"VRT_ipcmp(\v1, \v2)" },
-
-	{STRING,	T_EQ,	"!VRT_strcmp(\v1, \v2)" },
-	{STRING,	T_NEQ,	"VRT_strcmp(\v1, \v2)" },
-	{STRING_LIST,	T_EQ,	"!VRT_strcmp(\v1, \v2)" },
-	{STRING_LIST,	T_NEQ,	"VRT_strcmp(\v1, \v2)" },
-
-	{VOID, 0, NULL}
+	IDENT_REL(BACKEND),
+	IDENT_REL(ACL),
+	IDENT_REL(PROBE),
+	IDENT_REL(STEVEDORE),
+	IDENT_REL(SUB),
+	IDENT_REL(INSTANCE),
+
+	{IP,		T_EQ,	"!VRT_ipcmp(\v1, \v2)",		cmp_simple },
+	{IP,		T_NEQ,	"VRT_ipcmp(\v1, \v2)",		cmp_simple },
+	{IP,		'~',	"",				cmp_acl },
+	{IP,		T_NOMATCH, "!",				cmp_acl },
+
+	{STRING,	T_EQ,	"!VRT_strcmp(\v1, \v2)",	cmp_simple },
+	{STRING_LIST,	T_EQ,	"!VRT_strcmp(\v1, \v2)",	cmp_simple },
+	{STRING,	T_NEQ,	"VRT_strcmp(\v1, \v2)",		cmp_simple },
+	{STRING_LIST,	T_NEQ,	"VRT_strcmp(\v1, \v2)",		cmp_simple },
+	{STRING,	'~',	"",				cmp_regexp },
+	{STRING_LIST,	'~',	"",				cmp_regexp },
+	{STRING,	T_NOMATCH, "!",				cmp_regexp },
+	{STRING_LIST,	T_NOMATCH, "!",				cmp_regexp },
+
+	{VOID, 0, NULL, NULL}
 };
 
 #undef NUM_REL
@@ -1001,14 +1063,8 @@ static const struct cmps {
 static void
 vcc_expr_cmp(struct vcc *tl, struct expr **e, vcc_type_t fmt)
 {
-	struct expr *e2;
 	const struct cmps *cp;
-	char buf[256];
-	const char *re;
-	const char *not;
 	struct token *tk;
-	struct symbol *sym;
-	enum symkind kind;
 
 	*e = NULL;
 
@@ -1022,76 +1078,11 @@ vcc_expr_cmp(struct vcc *tl, struct expr **e, vcc_type_t fmt)
 	for (cp = vcc_cmps; cp->fmt != VOID; cp++)
 		if ((*e)->fmt == cp->fmt && tl->t->tok == cp->token)
 			break;
-	if (cp->fmt != VOID) {
-		vcc_NextToken(tl);
-		if ((*e)->fmt == STRING_LIST) {
-			// XXX: This is not optimal, but we can't pass two
-			// STRING_LIST's to a function anyway...
-			vcc_expr_tostring(tl, e, STRING);
-		}
-		vcc_expr_strfold(tl, &e2, (*e)->fmt);
-		ERRCHK(tl);
-		if (e2->fmt != (*e)->fmt) { /* XXX */
-			VSB_printf(tl->sb, "Comparison of different types: ");
-			VSB_printf(tl->sb, "%s ", vcc_utype((*e)->fmt));
-			vcc_ErrToken(tl, tk);
-			VSB_printf(tl->sb, " %s\n", vcc_utype(e2->fmt));
-			vcc_ErrWhere(tl, tk);
-			return;
-		}
-		*e = vcc_expr_edit(BOOL, cp->emit, *e, e2);
-		return;
-	}
-	if (((*e)->fmt == STRING || (*e)->fmt == STRING_LIST) &&
-	    (tl->t->tok == '~' || tl->t->tok == T_NOMATCH)) {
-		if ((*e)->fmt == STRING_LIST)
-			vcc_expr_tostring(tl, e, STRING);
-		not = tl->t->tok == '~' ? "" : "!";
-		vcc_NextToken(tl);
-		ExpectErr(tl, CSTR);
-		re = vcc_regexp(tl);
-		ERRCHK(tl);
-		vcc_NextToken(tl);
-		bprintf(buf, "%sVRT_re_match(ctx, \v1, %s)", not, re);
-		*e = vcc_expr_edit(BOOL, buf, *e, NULL);
+	if (cp->func != NULL) {
+		cp->func(tl, e, cp);
 		return;
 	}
-	if ((*e)->fmt == IP &&
-	    (tl->t->tok == '~' || tl->t->tok == T_NOMATCH)) {
-		not = tl->t->tok == '~' ? "" : "!";
-		vcc_NextToken(tl);
-		vcc_ExpectVid(tl, "ACL");
-		sym = vcc_AddRef(tl, tl->t, SYM_ACL);
-		VCC_GlobalSymbol(sym, ACL, ACL_SYMBOL_PREFIX);
-		bprintf(buf, "%sVRT_acl_match(ctx, %s, \v1)", not, sym->rname);
-		vcc_NextToken(tl);
-		*e = vcc_expr_edit(BOOL, buf, *e, NULL);
-		return;
-	}
-	if ((*e)->fmt == IP && (tl->t->tok == T_EQ || tl->t->tok == T_NEQ)) {
-		vcc_Acl_Hack(tl, buf, sizeof buf);
-		*e = vcc_expr_edit(BOOL, buf, *e, NULL);
-		return;
-	}
-	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);
-		e2 = NULL;
-		vcc_expr0(tl, &e2, (*e)->fmt);
-		ERRCHK(tl);
-		if (e2->fmt != (*e)->fmt) {
-			VSB_printf(tl->sb, "Comparison of different types: ");
-			VSB_printf(tl->sb, "%s ", vcc_utype((*e)->fmt));
-			vcc_ErrToken(tl, tk);
-			VSB_printf(tl->sb, " %s\n", vcc_utype(e2->fmt));
-			vcc_ErrWhere(tl, tk);
-			return;
-		}
-		*e = vcc_expr_edit(BOOL, buf, *e, e2);
-		return;
-	}
-	switch (tl->t->tok) {
+	switch (tk->tok) {
 	case T_EQ:
 	case T_NEQ:
 	case '<':
@@ -1113,6 +1104,8 @@ vcc_expr_cmp(struct vcc *tl, struct expr **e, vcc_type_t fmt)
 		*e = vcc_expr_edit(BOOL, "(\v1 != 0)", *e, NULL);
 	else if ((*e)->fmt == DURATION)
 		*e = vcc_expr_edit(BOOL, "(\v1 > 0)", *e, NULL);
+	else
+		INCOMPL();
 }
 
 /*--------------------------------------------------------------------


More information about the varnish-commit mailing list