[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