[master] c91a6ce Canonize VMOD argument ENUM values to replace strcmp(3) or more involved versions of same with a simple pointer comparison.

Poul-Henning Kamp phk at FreeBSD.org
Fri Dec 1 22:34:09 UTC 2017


commit c91a6cedf2dfffc84344554a206fc75f57ee6177
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Fri Dec 1 22:32:51 2017 +0000

    Canonize VMOD argument ENUM values to replace strcmp(3) or more
    involved versions of same with a simple pointer comparison.

diff --git a/bin/varnishd/mgt/mgt_main.c b/bin/varnishd/mgt/mgt_main.c
index f460f5e..cf9c454 100644
--- a/bin/varnishd/mgt/mgt_main.c
+++ b/bin/varnishd/mgt/mgt_main.c
@@ -66,7 +66,7 @@ int			exit_status = 0;
 struct vsb		*vident;
 struct VSC_mgt		*VSC_C_mgt;
 static int		I_fd = -1;
-static char 		*Cn_arg;
+static char		*Cn_arg;
 
 static struct vpf_fh *pfh1 = NULL;
 static struct vpf_fh *pfh2 = NULL;
diff --git a/bin/varnishtest/tests/m00000.vtc b/bin/varnishtest/tests/m00000.vtc
index 6200b80..1690a78 100644
--- a/bin/varnishtest/tests/m00000.vtc
+++ b/bin/varnishtest/tests/m00000.vtc
@@ -22,7 +22,8 @@ varnish v1 -vcl+backend {
 	sub vcl_deliver {
 		set resp.http.foo = std.toupper(resp.http.foo);
 		set resp.http.bar = std.tolower(resp.http.bar);
-		set resp.http.who = debug.author(phk);
+		set resp.http.who = debug.author(mithrandir);
+		set resp.http.really = debug.author();
 		set resp.http.what = vtc.typesize("dfijlopsz");
 		set resp.http.not = vtc.typesize("*");
 		debug.test_priv_call();
@@ -42,6 +43,8 @@ client c1 {
 	expect resp.bodylen == "4"
 	expect resp.http.foo == "BAR"
 	expect resp.http.bar == "foo"
+	expect resp.http.who == "Tollef"
+	expect resp.http.really == "Poul-Henning"
 	expect resp.http.encrypted == "ROT52"
 	expect resp.http.what >= 16
 	expect resp.http.not == -1
@@ -53,7 +56,8 @@ logexpect l1 -v v1 -g raw -d 1 {
 	expect 0 =    RespHeader	{^foo: BAR}
 	expect 0 =    RespUnset	{^bar: fOo}
 	expect 0 =    RespHeader	{^bar: foo}
-	expect 0 =    RespHeader	{^who: Poul-Henning}
+	expect 0 =    RespHeader	{^who: Tollef}
+	expect 0 =    RespHeader	{^really: Poul-Henning}
 	expect 0 =    RespHeader	{^what: [1-9][0-9]}
 	expect 0 =    RespHeader	{^not: -1}
 	expect 0 =    VCL_Log		{^VCL initiated log}
diff --git a/flint.lnt b/flint.lnt
index 5f57bef..4727891 100644
--- a/flint.lnt
+++ b/flint.lnt
@@ -81,6 +81,13 @@
 
 
 ///////////////////////////////////////////////////////////////////////
+// Vmod/vmodtool.py
+
+-esym(14, vmod_enum_*)		// Symbol '___' previously defined (___)
+-esym(759, vmod_enum_*)		// header declaration for symbol '___' defined at (___)
+-esym(765, vmod_enum_*)		// external '___' (___) could be made static
+
+///////////////////////////////////////////////////////////////////////
 // <vas.h>
 
 -sem(VAS_Fail, r_no)		// does not return
diff --git a/lib/libvcc/vcc_expr.c b/lib/libvcc/vcc_expr.c
index a36932f..10854f5 100644
--- a/lib/libvcc/vcc_expr.c
+++ b/lib/libvcc/vcc_expr.c
@@ -528,6 +528,7 @@ vcc_priv_arg(struct vcc *tl, const char *p, const char *name, const char *vmod)
 struct func_arg {
 	vcc_type_t		type;
 	const char		*enum_bits;
+	const char		*cname;
 	const char		*name;
 	const char		*val;
 	struct expr		*result;
@@ -535,6 +536,18 @@ struct func_arg {
 };
 
 static void
+vcc_do_enum(struct vcc *tl, struct func_arg *fa, int len, const char *ptr)
+{
+	const char *r;
+
+	(void)tl;
+	r = strchr(fa->cname, '.');
+	AN(r);
+	fa->result = vcc_mk_expr(VOID, "*%.*s.enum_%.*s",
+	    (int)(r - fa->cname), fa->cname, len, ptr);
+}
+
+static void
 vcc_do_arg(struct vcc *tl, struct func_arg *fa)
 {
 	const char *p, *r;
@@ -559,7 +572,7 @@ vcc_do_arg(struct vcc *tl, struct func_arg *fa)
 			vcc_ErrWhere(tl, tl->t);
 			return;
 		}
-		fa->result = vcc_mk_expr(VOID, "\"%.*s\"", PF(tl->t));
+		vcc_do_enum(tl, fa, PF(tl->t));
 		SkipToken(tl, ID);
 	} else {
 		vcc_expr0(tl, &e2, fa->type);
@@ -610,6 +623,7 @@ vcc_func(struct vcc *tl, struct expr **e, const char *spec,
 	while (*p != '\0') {
 		fa = calloc(1, sizeof *fa);
 		AN(fa);
+		fa->cname = cfunc;
 		VTAILQ_INSERT_TAIL(&head, fa, list);
 		if (!memcmp(p, "PRIV_", 5)) {
 			fa->result = vcc_priv_arg(tl, p, sym->name, sym->vmod);
@@ -685,6 +699,8 @@ vcc_func(struct vcc *tl, struct expr **e, const char *spec,
 
 	e1 = vcc_mk_expr(rfmt, "%s(ctx%s\v+", cfunc, extra);
 	VTAILQ_FOREACH_SAFE(fa, &head, list, fa2) {
+		if (fa->result == NULL && fa->type == ENUM && fa->val != NULL)
+			vcc_do_enum(tl, fa, strlen(fa->val), fa->val);
 		if (fa->result == NULL && fa->val != NULL)
 			fa->result = vcc_mk_expr(fa->type, "%s", fa->val);
 		if (fa->result != NULL)
diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py
index d271a2c..50bfea3 100755
--- a/lib/libvcc/vmodtool.py
+++ b/lib/libvcc/vmodtool.py
@@ -86,6 +86,7 @@ CLEANFILES = $(builddir)/vcc_if.c $(builddir)/vcc_if.h \\
 \t$(builddir)/vmod_XXX.man.rst
 
 '''
+
 privs = {
     'PRIV_CALL':   "struct vmod_priv *",
     'PRIV_VCL':    "struct vmod_priv *",
@@ -196,6 +197,9 @@ def fmt_cstruct(fo, mn, x):
 #######################################################################
 
 
+enum_values = {}
+
+
 class ctype(object):
     def __init__(self, vt, ct):
         self.vt = vt
@@ -259,7 +263,9 @@ def vtype(txt):
     e = e[0].split(',')
     ct.spec = []
     for i in e:
-        ct.spec.append(i.strip())
+        j = i.strip()
+        enum_values[j] = True
+        ct.spec.append(j)
     return ct, r
 
 
@@ -289,6 +295,8 @@ def arg(txt):
         if not m:
             err("Unbalanced quote")
         a.defval = s[:m.end()]
+        if a.vt == "ENUM":
+            a.defval = a.defval[1:-1]
         s = s[m.end():]
     else:
         i = s.find(',')
@@ -296,6 +304,8 @@ def arg(txt):
             i = len(s)
         a.defval = s[:i].rstrip()
         s = s[i:]
+    if a.vt == "ENUM" and a.defval not in a.spec:
+        err("ENUM default value <%s> not valid" % a.defval, warn=False)
 
     return a, s
 
@@ -701,13 +711,13 @@ class s_method(stanza):
 #######################################################################
 
 dispatch = {
-    "Module":	s_module,
-    "Prefix":	s_prefix,
-    "ABI":	s_abi,
-    "Event":	s_event,
-    "Function":	s_function,
-    "Object":	s_object,
-    "Method":	s_method,
+    "Module":   s_module,
+    "Prefix":   s_prefix,
+    "ABI":      s_abi,
+    "Event":    s_event,
+    "Function": s_function,
+    "Object":   s_object,
+    "Method":   s_method,
 }
 
 
@@ -782,11 +792,20 @@ class vcc(object):
         fn = self.pfx + ".h"
         fo = self.openfile(fn)
         write_c_file_warning(fo)
+        fo.write("#ifndef VDEF_H_INCLUDED\n")
+        fo.write('#  error "Include vdef.h first"\n')
+        fo.write("#endif\n")
         fo.write("#ifndef VRT_H_INCLUDED\n")
         fo.write('#  error "Include vrt.h first"\n')
         fo.write("#endif\n")
         fo.write("\n")
 
+        l = enum_values.keys()
+        l.sort()
+        for j in l:
+            fo.write("extern VCL_ENUM %senum_%s;\n" % (self.sympfx, j))
+        fo.write("\n")
+
         for j in self.contents:
             j.hfile(fo)
         fo.close()
@@ -796,12 +815,22 @@ class vcc(object):
         fo.write("\n%s {\n" % csn)
         for j in self.contents:
             j.cstruct(fo)
+        fo.write("\n")
+        l = enum_values.keys()
+        l.sort()
+        for j in l:
+            fo.write("\tVCL_ENUM\t\t\t*enum_%s;\n" % j)
         fo.write("};\n")
 
     def cstruct_init(self, fo, csn):
         fo.write("\nstatic const %s Vmod_Func = {\n" % csn)
         for j in self.contents:
             j.cstruct_init(fo)
+        fo.write("\n")
+        l = enum_values.keys()
+        l.sort()
+        for j in l:
+            fo.write("\t&%senum_%s,\n" % (self.sympfx, j))
         fo.write("};\n")
 
     def specstr(self, fo):
@@ -857,6 +886,12 @@ class vcc(object):
 
         fo.write("\n")
 
+        l = enum_values.keys()
+        l.sort()
+        for j in l:
+            fo.write('VCL_ENUM %senum_%s = "%s";\n' % (self.sympfx, j, j))
+        fo.write("\n")
+
         fx = open(fn2, "w")
 
         for i in self.contents:
diff --git a/lib/libvmod_debug/flint.lnt b/lib/libvmod_debug/flint.lnt
index e69de29..36d2255 100644
--- a/lib/libvmod_debug/flint.lnt
+++ b/lib/libvmod_debug/flint.lnt
@@ -0,0 +1,3 @@
+-esym(759, xyzzy_enum_*)         // header declaration for symbol '___' defined at (___)
+-esym(765, xyzzy_enum_*)         // external '___' (___) could be made static
+
diff --git a/lib/libvmod_debug/vmod.vcc b/lib/libvmod_debug/vmod.vcc
index bb12df3..5933d52 100644
--- a/lib/libvmod_debug/vmod.vcc
+++ b/lib/libvmod_debug/vmod.vcc
@@ -45,7 +45,7 @@ $Function VOID panic(STRING_LIST)
 Don't.
 
 $Function STRING author(ENUM { phk, des, kristian, mithrandir } person="phk",
-			ENUM { phk, slink, geoff } someone="phk")
+			ENUM { phk, slink, geoff } someone='phk')
 
 Test function for ENUM arguments
 
@@ -73,7 +73,7 @@ $Function STEVEDORE no_stevedore()
 
 Fails at storage selection.
 
-$Object obj(STRING string="default", ENUM { one, two, three } number="one")
+$Object obj(STRING string="default", ENUM { one, two, three } number=one)
 
 Test object
 
diff --git a/lib/libvmod_debug/vmod_debug.c b/lib/libvmod_debug/vmod_debug.c
index f094fc9..c24d78a 100644
--- a/lib/libvmod_debug/vmod_debug.c
+++ b/lib/libvmod_debug/vmod_debug.c
@@ -88,14 +88,18 @@ xyzzy_author(VRT_CTX, VCL_ENUM person, VCL_ENUM someone)
 	(void)someone;
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
-	if (!strcmp(person, "phk"))
+	if (person == xyzzy_enum_phk)
 		return ("Poul-Henning");
-	if (!strcmp(person, "des"))
+	assert(strcmp(person, "phk"));
+	if (person == xyzzy_enum_des)
 		return ("Dag-Erling");
-	if (!strcmp(person, "kristian"))
+	assert(strcmp(person, "des"));
+	if (person == xyzzy_enum_kristian)
 		return ("Kristian");
-	if (!strcmp(person, "mithrandir"))
+	assert(strcmp(person, "kristian"));
+	if (person == xyzzy_enum_mithrandir)
 		return ("Tollef");
+	assert(strcmp(person, "mithrandir"));
 	WRONG("Illegal VMOD enum");
 }
 


More information about the varnish-commit mailing list