[master] e446c07 More restructuring
Poul-Henning Kamp
phk at FreeBSD.org
Fri Mar 2 14:16:08 UTC 2018
commit e446c076a8ccbc8db7832add1776748b7b6fc5b0
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Fri Mar 2 10:59:34 2018 +0000
More restructuring
diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py
index e995ab3..aee9756 100755
--- a/lib/libvcc/vmodtool.py
+++ b/lib/libvcc/vmodtool.py
@@ -45,8 +45,6 @@ import random
import copy
import json
-strict_abi = True
-
AMBOILERPLATE = '''
# Boilerplate generated by vmodtool.py - changes will be overwritten
@@ -166,9 +164,18 @@ def lwrap(s, width=64):
p = " "
if len(s) > 0:
ll.append(p + s)
- return ll
+ return "\n".join(ll) + "\n"
+def fmt_cstruct(fo, mn, x):
+ """
+ Align fields in C struct
+ """
+ a = "\ttd_" + mn + "_" + x
+ while len(a.expandtabs()) < 40:
+ a += "\t"
+ fo.write("%s*%s;\n" % (a, x))
+
#######################################################################
@@ -184,21 +191,11 @@ def err(str, warn=True):
else:
print("WARNING: " + str, file=sys.stderr)
-
-def fmt_cstruct(fo, mn, x):
- a = "\ttd_" + mn + "_" + x
- while len(a.expandtabs()) < 40:
- a += "\t"
- fo.write("%s*%s;\n" % (a, x))
-
#######################################################################
-enum_values = {}
-
-
class ctype(object):
- def __init__(self, wl):
+ def __init__(self, wl, enums):
self.nm = None
self.defval = None
self.spec = None
@@ -210,7 +207,7 @@ class ctype(object):
if len(wl) > 0 and wl[0] == "{":
if self.vt != "ENUM":
err("Only ENUMs take {...} specs", warn=False)
- self.add_spec(wl)
+ self.add_spec(wl, enums)
def __str__(self):
s = "<" + self.vt
@@ -222,15 +219,7 @@ class ctype(object):
s += " SPEC=" + str(self.spec)
return s + ">"
- def set_defval(self, x):
- if self.vt == "ENUM":
- if x[0] == '"' and x[-1] == '"':
- x = x[1:-1]
- elif x[0] == "'" and x[-1] == "'":
- x = x[1:-1]
- self.defval = x
-
- def add_spec(self, wl):
+ def add_spec(self, wl, enums):
assert self.vt == "ENUM"
assert wl.pop(0) == "{"
self.spec = []
@@ -242,7 +231,7 @@ class ctype(object):
x = x[1:-1]
assert len(x) > 0
self.spec.append(x)
- enum_values[x] = True
+ enums[x] = True
w = wl.pop(0)
if w == "}":
break
@@ -261,10 +250,48 @@ class ctype(object):
return self.vt
def json(self, jl):
- jl.append([self.vt, self.nm, self.defval, self.spec])
+ jl.append([self.vt])
while jl[-1][-1] is None:
jl[-1].pop(-1)
+#######################################################################
+
+
+class arg(ctype):
+ def __init__(self, wl, argnames, enums, end):
+ super(arg, self).__init__(wl, enums)
+
+ if wl[0] == end:
+ return
+
+ x = wl.pop(0)
+ if x in argnames:
+ err("Duplicate argument name '%s'" % x, warn=False)
+ argnames[x] = True
+ self.nm = x
+
+ if wl[0] == end:
+ return
+
+ x = wl.pop(0)
+ if x != "=":
+ err("Expected '=' got '%s'" % x, warn=False)
+
+ x = wl.pop(0)
+ if self.vt == "ENUM":
+ if x[0] == '"' and x[-1] == '"':
+ x = x[1:-1]
+ elif x[0] == "'" and x[-1] == "'":
+ x = x[1:-1]
+ self.defval = x
+
+ def json(self, jl):
+ jl.append([self.vt, self.nm, self.defval, self.spec])
+ while jl[-1][-1] is None:
+ jl[-1].pop(-1)
+
+#######################################################################
+
def lex(l):
wl = []
@@ -309,65 +336,49 @@ def lex(l):
err("Syntax error at char", i, "'%s'" % c, warn=False)
return wl
+#######################################################################
+
class prototype(object):
def __init__(self, st, retval=True, prefix=""):
- global inputline
self.st = st
self.obj = None
- inputline = st.line[1]
+ self.args = []
wl = lex(st.line[1])
if retval:
- self.retval = ctype(wl)
+ self.retval = ctype(wl, st.vcc.enums)
+ else:
+ self.retval = ctype(['VOID'], st.vcc.enums)
self.bname = wl.pop(0)
if not re.match("^[a-zA-Z.][a-zA-Z0-9_]*$", self.bname):
err("%s(): Illegal name\n" % self.nname, warn=False)
- self.prefix = prefix
- self.name = self.prefix + self.bname
- self.vcc = st.vcc
+ self.name = prefix + self.bname
if not re.match('^[a-zA-Z_][a-zA-Z0-9_]*$', self.cname()):
err("%s(): Illegal C-name\n" % self.cname(), warn=False)
- x = wl.pop(0)
- if x != "(":
- err("Syntax error: Expected '(', got '%s'" % x, warn=False)
+ if len(wl) == 2 and wl[0] == '(' and wl[1] == ')':
+ return
- x = wl.pop(-1)
- if x != ")":
- err("Syntax error: Expected ')', got '%s'" % x, warn=False)
+ if wl[0] != "(":
+ err("Syntax error: Expected '(', got '%s'" % wl[0], warn=False)
+ wl[0] = ','
+
+ if wl[-1] != ")":
+ err("Syntax error: Expected ')', got '%s'" % wl[-1], warn=False)
+ wl[-1] = ','
names = {}
- self.args = []
while len(wl) > 0:
- t = ctype(wl)
- self.args.append(t)
- if not len(wl):
- break
x = wl.pop(0)
- if x == ",":
- continue
- if x in names:
- err("%s(): Duplicate argument name" % x, warn=False)
- names[x] = True
- t.nm = x
- if not len(wl):
- break
- if wl[0] == "=":
- wl.pop(0)
- t.set_defval(wl.pop(0))
- if not len(wl):
+ if x != ',':
+ err("Expected ',' found '%s'" % x, warn=False)
+ if len(wl) == 0:
break
- assert wl.pop(0) == ","
- inputline = None
-
- def cname(self, pfx=False):
- r = self.name.replace(".", "_")
- if pfx:
- return self.vcc.sympfx + r
- return r
+ t = arg(wl, names, st.vcc.enums, ',')
+ self.args.append(t)
def vcl_proto(self, short, pfx=""):
if type(self.st) == s_method:
@@ -420,28 +431,39 @@ class prototype(object):
fo.write(self.vcl_proto(True, pfx=" ") + "\n")
fo.write(" \n")
- def c_ret(self):
- return self.retval.ct
+ def cname(self, pfx=False):
+ r = self.name.replace(".", "_")
+ if pfx:
+ return self.st.vcc.sympfx + r
+ return r
- def c_args(self, a=[]):
- ll = list(a)
+ def proto(self, args, name):
+ s = self.retval.ct + " " + name + '('
+ ll = args
for i in self.args:
ll.append(i.ct)
- return ", ".join(ll)
-
- def c_fn(self, args=[], h=False):
- s = fn = ''
- if not h:
- s += 'typedef '
- fn += 'td_' + self.vcc.modname + '_'
- fn += self.cname(pfx=h)
- s += '%s %s(%s);' % (self.c_ret(), fn, self.c_args(args))
- return "\n".join(lwrap(s)) + "\n"
+ s += ", ".join(ll)
+ return s + ');'
+
+ def typedef(self, args):
+ tn = 'td_' + self.st.vcc.modname + '_' + self.cname()
+ return "typedef " + self.proto(args, name=tn)
+
+ def cstuff(self, args, where):
+ if where == 'h':
+ s = self.proto(args, self.cname(True))
+ elif where == 'c':
+ s = self.typedef(args)
+ elif where == 'o':
+ s = self.typedef(args)
+ else:
+ assert False
+ return lwrap(s)
def json(self, jl, cfunc):
ll = []
self.retval.json(ll)
- ll.append('Vmod_%s_Func.%s' % (self.vcc.modname, cfunc))
+ ll.append('Vmod_%s_Func.%s' % (self.st.vcc.modname, cfunc))
for i in self.args:
i.json(ll)
jl.append(ll)
@@ -492,13 +514,10 @@ class stanza(object):
if self.proto is not None:
self.proto.synopsis(fo, man)
- def hfile(self, fo):
+ def cstuff(self, fo, where):
return
- def cstruct(self, fo):
- return
-
- def cstruct_init(self, fo):
+ def cstruct(self, fo, define):
return
def json(self, jl):
@@ -566,11 +585,10 @@ class s_module(stanza):
class s_abi(stanza):
def parse(self):
- global strict_abi
if self.line[1] not in ('strict', 'vrt'):
err("Valid ABI types are 'strict' or 'vrt', got '%s'\n" %
self.line[1])
- strict_abi = self.line[1] == 'strict'
+ self.vcc.strict_abi = self.line[1] == 'strict'
self.vcc.contents.append(self)
@@ -590,14 +608,15 @@ class s_event(stanza):
err("Not emitting .RST for $Event %s\n" %
self.event_func)
- def hfile(self, fo):
- fo.write("vmod_event_f %s;\n" % self.event_func)
-
- def cstruct(self, fo):
- fo.write("\tvmod_event_f\t\t\t*_event;\n")
+ def cstuff(self, fo, where):
+ if where == 'h':
+ fo.write("vmod_event_f %s;\n" % self.event_func)
- def cstruct_init(self, fo):
- fo.write("\t%s,\n" % self.event_func)
+ def cstruct(self, fo, define):
+ if define:
+ fo.write("\tvmod_event_f\t\t\t*_event;\n")
+ else:
+ fo.write("\t%s,\n" % self.event_func)
def json(self, jl):
jl.append([
@@ -612,17 +631,15 @@ class s_function(stanza):
self.rstlbl = "func_" + self.proto.name
self.vcc.contents.append(self)
- def hfile(self, fo):
- fo.write(self.proto.c_fn(['VRT_CTX'], True))
-
- def cfile(self, fo):
- fo.write(self.proto.c_fn(['VRT_CTX']))
+ def cstuff(self, fo, where):
+ if where in ('h', 'c'):
+ fo.write(self.proto.cstuff(['VRT_CTX'], where))
- def cstruct(self, fo):
- fmt_cstruct(fo, self.vcc.modname, self.proto.cname())
-
- def cstruct_init(self, fo):
- fo.write("\t" + self.proto.cname(pfx=True) + ",\n")
+ def cstruct(self, fo, define):
+ if define:
+ fmt_cstruct(fo, self.vcc.modname, self.proto.cname())
+ else:
+ fo.write("\t" + self.proto.cname(pfx=True) + ",\n")
def json(self, jl):
jl.append(["$FUNC", "%s" % self.proto.name])
@@ -632,7 +649,6 @@ class s_function(stanza):
class s_object(stanza):
def parse(self):
self.proto = prototype(self, retval=False)
- self.proto.retval = ctype(['VOID'])
self.proto.obj = "x" + self.proto.name
self.init = copy.copy(self.proto)
@@ -662,35 +678,27 @@ class s_object(stanza):
for i in self.methods:
i.proto.synopsis(fo, man)
- def chfile(self, fo, h):
+ def cstuff(self, fo, w):
sn = self.vcc.sympfx + self.vcc.modname + "_" + self.proto.name
fo.write("struct %s;\n" % sn)
- fo.write(self.init.c_fn(
- ['VRT_CTX', 'struct %s **' % sn, 'const char *'], h))
- fo.write(self.fini.c_fn(['struct %s **' % sn], h))
+ fo.write(self.init.cstuff(
+ ['VRT_CTX', 'struct %s **' % sn, 'const char *'], w))
+ fo.write(self.fini.cstuff(['struct %s **' % sn], w))
for i in self.methods:
- fo.write(i.proto.c_fn(['VRT_CTX', 'struct %s *' % sn], h))
+ fo.write(i.proto.cstuff(['VRT_CTX', 'struct %s *' % sn], w))
fo.write("\n")
- def hfile(self, fo):
- self.chfile(fo, True)
-
- def cfile(self, fo):
- self.chfile(fo, False)
-
- def cstruct(self, fo):
- fmt_cstruct(fo, self.vcc.modname, self.init.name)
- fmt_cstruct(fo, self.vcc.modname, self.fini.name)
- for i in self.methods:
- i.cstruct(fo)
-
- def cstruct_init(self, fo):
- p = "\t" + self.vcc.sympfx
- fo.write(p + self.init.name + ",\n")
- fo.write(p + self.fini.name + ",\n")
+ def cstruct(self, fo, define):
+ if define:
+ fmt_cstruct(fo, self.vcc.modname, self.init.name)
+ fmt_cstruct(fo, self.vcc.modname, self.fini.name)
+ else:
+ p = "\t" + self.vcc.sympfx
+ fo.write(p + self.init.name + ",\n")
+ fo.write(p + self.fini.name + ",\n")
for i in self.methods:
- i.cstruct_init(fo)
+ i.cstruct(fo, define)
fo.write("\n")
def json(self, jl):
@@ -719,6 +727,8 @@ class s_object(stanza):
for i in self.methods:
i.dump()
+#######################################################################
+
class s_method(stanza):
def parse(self):
@@ -730,11 +740,11 @@ class s_method(stanza):
self.rstlbl = "func_" + self.proto.name
p.methods.append(self)
- def cstruct(self, fo):
- fmt_cstruct(fo, self.vcc.modname, self.proto.cname())
-
- def cstruct_init(self, fo):
- fo.write('\t' + self.proto.cname(pfx=True) + ",\n")
+ def cstruct(self, fo, define):
+ if define:
+ fmt_cstruct(fo, self.vcc.modname, self.proto.cname())
+ else:
+ fo.write('\t' + self.proto.cname(pfx=True) + ",\n")
def json(self, jl):
jl.append(["$METHOD", self.proto.name[len(self.pfx)+1:]])
@@ -763,6 +773,8 @@ class vcc(object):
self.contents = []
self.commit_files = []
self.copyright = ""
+ self.enums = {}
+ self.strict_abi = True
def openfile(self, fn):
self.commit_files.append(fn)
@@ -773,6 +785,7 @@ class vcc(object):
os.rename(i + ".tmp", i)
def parse(self):
+ global inputline
a = "\n" + open(self.inputfile, "r").read()
s = a.split("\n$")
self.copyright = s.pop(0).strip()
@@ -783,11 +796,13 @@ class vcc(object):
i += 1
else:
i = len(ss)
+ inputline = ss[:i]
c = ss[:i].split()
m = dispatch.get(c[0])
if m is None:
err("Unknown stanze $%s" % ss[:i])
m([c[0], " ".join(c[1:])], ss[i:].split('\n'), self)
+ inputline = None
def rst_copyright(self, fo):
write_rst_hdr(fo, "COPYRIGHT", "=")
@@ -818,8 +833,7 @@ class vcc(object):
fo.close()
def amboilerplate(self):
- fn = "automake_boilerplate.am"
- fo = self.openfile(fn)
+ fo = self.openfile("automake_boilerplate.am")
fo.write(AMBOILERPLATE.replace("XXX", self.modname))
fo.close()
@@ -835,30 +849,28 @@ class vcc(object):
fo.write("#endif\n")
fo.write("\n")
- for j in sorted(enum_values):
+ for j in sorted(self.enums):
fo.write("extern VCL_ENUM %senum_%s;\n" % (self.sympfx, j))
fo.write("\n")
for j in self.contents:
- j.hfile(fo)
+ j.cstuff(fo, 'h')
fo.close()
def cstruct(self, fo, csn):
-
fo.write("\n%s {\n" % csn)
for j in self.contents:
- j.cstruct(fo)
- fo.write("\n")
- for j in sorted(enum_values):
+ j.cstruct(fo, True)
+ for j in sorted(self.enums):
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)
+ j.cstruct(fo, False)
fo.write("\n")
- for j in sorted(enum_values):
+ for j in sorted(self.enums):
fo.write("\t&%senum_%s,\n" % (self.sympfx, j))
fo.write("};\n")
@@ -887,14 +899,13 @@ class vcc(object):
fo.write(j + "\n")
fo.write("\n")
- def api(self, fo):
+ def vmod_data(self, fo):
+ vmd = "Vmod_%s_Data" % self.modname
for i in (714, 759, 765):
- fo.write("\n/*lint -esym(%d, Vmod_%s_Data) */\n" %
- (i, self.modname))
- fo.write("\nextern const struct vmod_data Vmod_%s_Data;\n" %
- (self.modname))
- fo.write("\nconst struct vmod_data Vmod_%s_Data = {\n" % self.modname)
- if strict_abi:
+ fo.write("\n/*lint -esym(%d, %s) */\n" % (i, vmd))
+ fo.write("\nextern const struct vmod_data %s;\n" % vmd)
+ fo.write("\nconst struct vmod_data %s = {\n" % vmd)
+ if self.strict_abi:
fo.write("\t.vrt_major =\t0,\n")
fo.write("\t.vrt_minor =\t0,\n")
else:
@@ -917,59 +928,55 @@ class vcc(object):
fo.write("};\n")
def cfile(self):
- fn = self.pfx + ".c"
- fo = self.openfile(fn)
- write_c_file_warning(fo)
+ fno = self.pfx + ".c"
+ fo = self.openfile(fno)
+ fnx = fno + ".tmp2"
+ fx = open(fnx, "w")
- fn2 = fn + ".tmp2"
+ write_c_file_warning(fo)
fo.write('#include "config.h"\n')
fo.write('#include <stdio.h>\n')
for i in ["vdef", "vrt", self.pfx, "vmod_abi"]:
fo.write('#include "%s.h"\n' % i)
-
fo.write("\n")
- for j in sorted(enum_values):
+ for j in sorted(self.enums):
fo.write('VCL_ENUM %senum_%s = "%s";\n' % (self.sympfx, j, j))
fo.write("\n")
- fx = open(fn2, "w")
-
for i in self.contents:
if type(i) == s_object:
- i.cfile(fo)
- i.cfile(fx)
+ i.cstuff(fo, 'c')
+ i.cstuff(fx, 'c')
fx.write("/* Functions */\n")
for i in self.contents:
if type(i) == s_function:
- i.cfile(fo)
- i.cfile(fx)
+ i.cstuff(fo, 'c')
+ i.cstuff(fx, 'c')
csn = "Vmod_%s_Func" % self.modname
+ scsn = "struct " + csn
- self.cstruct(fo, "struct " + csn)
-
- self.cstruct(fx, "struct " + csn)
+ self.cstruct(fo, scsn)
+ self.cstruct(fx, scsn)
- fo.write("\n/*lint -esym(754, Vmod_" + self.modname + "_Func::*) */\n")
- self.cstruct_init(fo, "struct " + csn)
+ fo.write("\n/*lint -esym(754, " + csn + "::*) */\n")
+ self.cstruct_init(fo, scsn)
fx.close()
fo.write("\nstatic const char Vmod_Proto[] =\n")
- fi = open(fn2)
- for i in fi:
+ for i in open(fnx):
fo.write('\t"%s\\n"\n' % i.rstrip())
- fi.close()
fo.write('\t"static struct %s %s;";\n' % (csn, csn))
- os.remove(fn2)
+ os.remove(fnx)
self.json(fo)
- self.api(fo)
+ self.vmod_data(fo)
fo.close()
More information about the varnish-commit
mailing list