[master] 502b7f143 Refactor vmodtoll and the .rst doc it produces.
Poul-Henning Kamp
phk at FreeBSD.org
Tue Jan 22 13:12:08 UTC 2019
commit 502b7f1434a19bc6c2b0123445c3a642bd645322
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date: Tue Jan 22 13:11:18 2019 +0000
Refactor vmodtoll and the .rst doc it produces.
Not what I came here for, but...
diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py
index 32d4e6f2e..17956311b 100755
--- a/lib/libvcc/vmodtool.py
+++ b/lib/libvcc/vmodtool.py
@@ -147,10 +147,11 @@ def write_rst_file_warning(fo):
def write_rst_hdr(fo, s, below="-", above=None):
- if above is not None:
+ fo.write('\n')
+ if above:
fo.write(above * len(s) + "\n")
fo.write(s + "\n")
- if below is not None:
+ if below:
fo.write(below * len(s) + "\n")
#######################################################################
@@ -245,19 +246,16 @@ class CType(object):
break
assert w == ","
- def vcl(self):
+ def vcl(self, terse=False):
if self.vt in ("STRING_LIST", "STRANDS"):
return "STRING"
+ if terse:
+ return self.vt
if self.spec is None:
return self.vt
return self.vt + " {" + ", ".join(self.spec) + "}"
- def synopsis(self):
- if self.vt in ("STRING_LIST", "STRANDS"):
- return "STRING"
- return self.vt
-
- def json(self, jl):
+ def jsonproto(self, jl):
jl.append([self.vt])
while jl[-1][-1] is None:
jl[-1].pop(-1)
@@ -294,7 +292,7 @@ class arg(CType):
x = unquote(x)
self.defval = x
- def json(self, jl):
+ def jsonproto(self, jl):
jl.append([self.vt, self.nm, self.defval, self.spec])
if self.opt:
jl[-1].append(True)
@@ -363,7 +361,7 @@ class ProtoType(object):
t.nm2 = t.nm
self.args.append(t)
- def vcl_proto(self, short, pfx=""):
+ def vcl_proto(self, terse, pfx=""):
if isinstance(self.st, MethodStanza):
pfx += pfx
s = pfx
@@ -380,22 +378,19 @@ class ProtoType(object):
s += self.name + "("
ll = []
for i in self.args:
- if short:
- t = i.synopsis()
- else:
- t = i.vcl()
+ t = i.vcl(terse)
if t in PRIVS:
continue
if i.nm is not None:
t += " " + i.nm
- if not short:
+ if not terse:
if i.defval is not None:
t += "=" + i.defval
if i.opt:
t = "[" + t + "]"
ll.append(t)
t = ",@".join(ll)
- if len(s + t) > 68 and not short:
+ if len(s + t) > 68 and not terse:
s += "\n" + pfx + pfx
s += t.replace("@", "\n" + pfx + pfx)
s += "\n" + pfx + ")"
@@ -409,15 +404,9 @@ class ProtoType(object):
write_rst_hdr(fo, s, '-')
else:
s = self.vcl_proto(True)
- if len(s) > 60:
- s = self.name + "(...)"
write_rst_hdr(fo, s, '-')
fo.write("\n::\n\n" + self.vcl_proto(False, pfx=" ") + "\n")
- def synopsis(self, fo, unused_man):
- fo.write(self.vcl_proto(True, pfx=" ") + "\n")
- fo.write(" \n")
-
def cname(self, pfx=False):
r = self.name.replace(".", "_")
if pfx:
@@ -458,44 +447,49 @@ class ProtoType(object):
s += "};\n"
return s
- def cstuff(self, args, where):
+ def cproto(self, eargs, where):
+ ''' Produce C language prototype '''
s = ""
if where == 'h':
if self.argstruct:
s += self.argstructure()
- s += lwrap(self.proto(args, self.cname(True)))
+ s += lwrap(self.proto(eargs, self.cname(True)))
elif where == 'c':
- s += lwrap(self.typedef(args))
+ s += lwrap(self.typedef(eargs))
elif where == 'o':
if self.argstruct:
s += self.argstructure()
- s += lwrap(self.typedef(args))
+ s += lwrap(self.typedef(eargs))
else:
assert False
return s
- def json(self, jl, cfunc):
+ def jsonproto(self, jl, cfunc):
+ ''' Produce VCL prototype as JSON '''
ll = []
- self.retval.json(ll)
+ self.retval.jsonproto(ll)
ll.append('Vmod_%s_Func.%s' % (self.st.vcc.modname, cfunc))
if self.argstruct:
ll.append(self.argstructname())
else:
ll.append("")
for i in self.args:
- i.json(ll)
+ i.jsonproto(ll)
jl.append(ll)
#######################################################################
class Stanza(object):
- def __init__(self, toks, l0, doc, vcc):
+
+ ''' Base class for all $-Stanzas '''
+
+ def __init__(self, vcc, toks, doc):
self.toks = toks
- self.line = l0
- while doc and doc[0] == '':
+ doc = doc.split('\n')
+ while doc and not doc[0].strip():
doc.pop(0)
- while doc and doc[-1] == '':
+ while doc and not doc[-1].strip():
doc.pop(-1)
self.doc = doc
self.vcc = vcc
@@ -507,9 +501,6 @@ class Stanza(object):
def parse(self):
assert "subclass should have defined" == "parse method"
- def dump(self):
- print(type(self), self.line)
-
def syntax(self):
err("Syntax error.\n" +
"\tShould be: " + self.__doc__.strip() + "\n" +
@@ -517,29 +508,26 @@ class Stanza(object):
warn=False)
def rstfile(self, fo, man):
- if self.rstlbl is not None:
- fo.write(".. _" + self.rstlbl + ":\n\n")
-
+ if self.rstlbl:
+ fo.write("\n.. _" + self.rstlbl + ":\n")
self.rsthead(fo, man)
- fo.write("\n")
- self.rstmid(fo, man)
- fo.write("\n")
- self.rsttail(fo, man)
- fo.write("\n")
+ self.rstdoc(fo, man)
def rsthead(self, fo, unused_man):
- if self.proto is not None:
+ ''' Emit the systematic part of the documentation '''
+ if self.proto:
self.proto.rsthead(fo)
+ fo.write("\n")
- def rstmid(self, fo, unused_man):
+ def rstdoc(self, fo, unused_man):
+ ''' Emit the explanatory part of the documentation '''
fo.write("\n".join(self.doc) + "\n")
- def rsttail(self, unused_fo, unused_man):
- return
-
def synopsis(self, fo, man):
- if self.proto is not None:
- self.proto.synopsis(fo, man)
+ if man and self.proto:
+ fo.write(self.proto.vcl_proto(True, pfx=" ") + '\n \n')
+ elif self.proto and self.rstlbl:
+ fo.write(' :ref:`%s`\n \n' % self.rstlbl)
def cstuff(self, unused_fo, unused_where):
return
@@ -548,6 +536,7 @@ class Stanza(object):
return
def json(self, unused_jl):
+ ''' Add to the json we hand VCC '''
return
#######################################################################
@@ -575,49 +564,25 @@ class ModuleStanza(Stanza):
def rsthead(self, fo, man):
- write_rst_hdr(fo, self.vcc.sympfx + self.vcc.modname, "=", "=")
- fo.write("\n")
-
- write_rst_hdr(fo, self.vcc.moddesc, "-", "-")
-
- fo.write("\n")
- fo.write(":Manual section: " + self.vcc.mansection + "\n")
+ if man:
+ write_rst_hdr(fo, self.vcc.sympfx + self.vcc.modname, "=", "=")
+ write_rst_hdr(fo, self.vcc.moddesc, "-", "-")
+ fo.write("\n")
+ fo.write(":Manual section: " + self.vcc.mansection + "\n")
+ else:
+ write_rst_hdr(fo,
+ self.vcc.sympfx + self.vcc.modname +
+ ' - ' + self.vcc.moddesc,
+ "=", "=")
if self.vcc.auto_synopsis:
- fo.write("\n")
write_rst_hdr(fo, "SYNOPSIS", "=")
fo.write("\n")
- fo.write("\n::\n\n")
- fo.write(' import %s [from "path"] ;\n' % self.vcc.modname)
- fo.write(" \n")
+ fo.write(".. parsed-literal::\n\n")
+ fo.write(' import %s [from "path"]\n' % self.vcc.modname)
+ fo.write(" \n")
for c in self.vcc.contents:
c.synopsis(fo, man)
- fo.write("\n")
-
- def rsttail(self, fo, man):
-
- if man:
- return
-
- write_rst_hdr(fo, "CONTENTS", "=")
- fo.write("\n")
-
- ll = []
- for i in self.vcc.contents[1:]:
- j = i.rstlbl
- if j is not None:
- ll.append([j.split("_", 1)[1], j])
- if i.methods is None:
- continue
- for x in i.methods:
- j = x.rstlbl
- ll.append([j.split("_", 1)[1], j])
-
- ll.sort()
- for i in ll:
- fo.write("* :ref:`%s`\n" % i[1])
- fo.write("\n")
-
class ABIStanza(Stanza):
@@ -699,13 +664,16 @@ class EventStanza(Stanza):
class FunctionStanza(Stanza):
+
+ ''' $Function TYPE name ( ARGUMENSTS ) '''
+
def parse(self):
self.proto = ProtoType(self)
self.rstlbl = "func_" + self.proto.name
self.vcc.contents.append(self)
def cstuff(self, fo, where):
- fo.write(self.proto.cstuff(['VRT_CTX'], where))
+ fo.write(self.proto.cproto(['VRT_CTX'], where))
def cstruct(self, fo, define):
if define:
@@ -715,10 +683,13 @@ class FunctionStanza(Stanza):
def json(self, jl):
jl.append(["$FUNC", "%s" % self.proto.name])
- self.proto.json(jl[-1], self.proto.cname())
+ self.proto.jsonproto(jl[-1], self.proto.cname())
class ObjectStanza(Stanza):
+
+ ''' $Object TYPE class ( ARGUMENSTS ) '''
+
def parse(self):
self.proto = ProtoType(self, retval=False)
self.proto.obj = "x" + self.proto.name
@@ -737,29 +708,34 @@ class ObjectStanza(Stanza):
def rsthead(self, fo, man):
self.proto.rsthead(fo)
-
- fo.write("\n" + "\n".join(self.doc) + "\n\n")
-
+ fo.write("\n" + "\n".join(self.doc) + "\n")
for i in self.methods:
i.rstfile(fo, man)
- def rstmid(self, unused_fo, unused_man):
+ def rstdoc(self, unused_fo, unused_man):
return
def synopsis(self, fo, man):
- self.proto.synopsis(fo, man)
- for i in self.methods:
- i.proto.synopsis(fo, man)
+ if man and self.proto:
+ fo.write(self.proto.vcl_proto(True, pfx=" ") + '\n \n')
+ for i in self.methods:
+ if i.proto:
+ fo.write(i.proto.vcl_proto(True, pfx=" ") + '\n \n')
+ elif self.proto and self.rstlbl:
+ fo.write(' :ref:`%s`\n \n' % self.rstlbl)
+ for i in self.methods:
+ if i.proto and i.rstlbl:
+ fo.write(' :ref:`%s`\n \n' % i.rstlbl)
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.cstuff(
+ fo.write(self.init.cproto(
['VRT_CTX', 'struct %s **' % sn, 'const char *'], w))
- fo.write(self.fini.cstuff(['struct %s **' % sn], w))
+ fo.write(self.fini.cproto(['struct %s **' % sn], w))
for i in self.methods:
- fo.write(i.proto.cstuff(['VRT_CTX', 'struct %s *' % sn], w))
+ fo.write(i.proto.cproto(['VRT_CTX', 'struct %s *' % sn], w))
fo.write("\n")
def cstruct(self, fo, define):
@@ -784,26 +760,24 @@ class ObjectStanza(Stanza):
l2 = ["$INIT"]
ll.append(l2)
- self.init.json(l2, self.init.name)
+ self.init.jsonproto(l2, self.init.name)
l2 = ["$FINI"]
ll.append(l2)
- self.fini.json(l2, self.fini.name)
+ self.fini.jsonproto(l2, self.fini.name)
for i in self.methods:
i.json(ll)
jl.append(ll)
- def dump(self):
- super(ObjectStanza, self).dump()
- for i in self.methods:
- i.dump()
-
#######################################################################
class MethodStanza(Stanza):
+
+ ''' $Method TYPE . method ( ARGUMENSTS ) '''
+
def parse(self):
p = self.vcc.contents[-1]
assert isinstance(p, ObjectStanza)
@@ -824,7 +798,7 @@ class MethodStanza(Stanza):
def json(self, jl):
jl.append(["$METHOD", self.proto.name[len(self.pfx)+1:]])
- self.proto.json(jl[-1], self.proto.cname())
+ self.proto.jsonproto(jl[-1], self.proto.cname())
#######################################################################
@@ -877,12 +851,11 @@ class vcc(object):
ss = re.split('\n([^\t ])', s.pop(0), maxsplit=1)
toks = self.tokenize(ss[0])
inputline = '$' + ' '.join(toks)
- c = ss[0].split()
- d = "".join(ss[1:])
- m = DISPATCH.get(toks[0])
- if m is None:
+ docstr = "".join(ss[1:])
+ stanzaclass = DISPATCH.get(toks[0])
+ if stanzaclass is None:
err("Unknown stanza $%s" % toks[0], warn=False)
- m(toks, [c[0], " ".join(c[1:])], d.split('\n'), self)
+ stanzaclass(self, toks, docstr)
inputline = None
def tokenize(self, txt, seps=None, quotes=None):
@@ -922,41 +895,43 @@ class vcc(object):
# print("\t", [i])
return out
-
- def rst_copyright(self, fo):
- write_rst_hdr(fo, "COPYRIGHT", "=")
- fo.write("\n::\n\n")
- a = self.copyright
- a = a.replace("\n#", "\n ")
- if a[:2] == "#\n":
- a = a[2:]
- if a[:3] == "#-\n":
- a = a[3:]
- fo.write(a + "\n")
-
def rstfile(self, man=False):
+ ''' Produce rst documentation '''
fn = os.path.join(self.rstdir, "vmod_" + self.modname)
if man:
fn += ".man"
fn += ".rst"
fo = self.openfile(fn)
write_rst_file_warning(fo)
- fo.write(".. role:: ref(emphasis)\n\n")
+ if man:
+ fo.write(".. role:: ref(emphasis)\n")
+ else:
+ fo.write('\n:tocdepth: 1\n')
for i in self.contents:
i.rstfile(fo, man)
if self.copyright:
- self.rst_copyright(fo)
+ write_rst_hdr(fo, "COPYRIGHT", "=")
+ fo.write("\n::\n\n")
+ a = self.copyright
+ a = a.replace("\n#", "\n ")
+ if a[:2] == "#\n":
+ a = a[2:]
+ if a[:3] == "#-\n":
+ a = a[3:]
+ fo.write(a + "\n")
fo.close()
def amboilerplate(self):
+ ''' Produce boilplate for autocrap tools '''
fo = self.openfile("automake_boilerplate.am")
fo.write(AMBOILERPLATE.replace("XXX", self.modname))
fo.close()
- def hfile(self):
+ def mkhfile(self):
+ ''' Produce vcc_if.h file '''
fn = self.pfx + ".h"
fo = self.openfile(fn)
write_c_file_warning(fo)
@@ -998,30 +973,23 @@ class vcc(object):
for j in self.contents:
j.json(jl)
- bz = bytearray(json.dumps(jl, separators=(",", ":")),
- encoding="ascii") + b"\0"
- fo.write("\nstatic const char Vmod_Json[%d] = {\n" % len(bz))
- t = "\t"
- for i in bz:
- t += "%d," % i
- if len(t) >= 69:
- fo.write(t + "\n")
- t = "\t"
- if len(t) > 1:
- fo.write(t[:-1])
- fo.write("\n};\n\n")
- for i in json.dumps(jl, indent=2, separators=(',', ': ')).split("\n"):
- j = "// " + i
- if len(j) > 72:
- fo.write(j[:72] + "[...]\n")
+ fo.write("\nstatic const char Vmod_Json[] = {\n")
+ t = '\t"'
+ for i in json.dumps(jl, indent=2, separators=(",", ": ")):
+ if i == '\n':
+ fo.write(t + '\\n"\n')
+ t = '\t"'
else:
- fo.write(j + "\n")
- fo.write("\n")
+ if i in '"\\':
+ t += '\\'
+ t += i
+ fo.write(t + '\\n"\n};\n')
def vmod_data(self, fo):
vmd = "Vmod_%s_Data" % self.modname
+ fo.write('\n')
for i in (714, 759, 765):
- fo.write("\n/*lint -esym(%d, %s) */\n" % (i, vmd))
+ fo.write("/*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:
@@ -1039,7 +1007,8 @@ class vcc(object):
fo.write("\t.file_id =\t\"%s\",\n" % self.file_id)
fo.write("};\n")
- def cfile(self):
+ def mkcfile(self):
+ ''' Produce vcc_if.c file '''
fno = self.pfx + ".c"
fo = self.openfile(fno)
fnx = fno + ".tmp2"
@@ -1102,8 +1071,8 @@ def runmain(inputvcc, rstdir, outputprefix):
v.rstfile(man=False)
v.rstfile(man=True)
- v.hfile()
- v.cfile()
+ v.mkhfile()
+ v.mkcfile()
if opts.boilerplate:
v.amboilerplate()
diff --git a/lib/libvmod_blob/vmod.vcc b/lib/libvmod_blob/vmod.vcc
index a5b6ae4fd..ab545480e 100644
--- a/lib/libvmod_blob/vmod.vcc
+++ b/lib/libvmod_blob/vmod.vcc
@@ -6,9 +6,8 @@
# Geoffrey Simmons <geoffrey.simmons at uplex.de>
#
-$Module blob 3 "Utilities for the VCL blob type, encoding and decoding"
-
$ABI strict
+$Module blob 3 "Utilities for the VCL blob type, encoding and decoding"
DESCRIPTION
===========
diff --git a/lib/libvmod_debug/vmod.vcc b/lib/libvmod_debug/vmod.vcc
index 5faa718bf..65464fd32 100644
--- a/lib/libvmod_debug/vmod.vcc
+++ b/lib/libvmod_debug/vmod.vcc
@@ -26,9 +26,9 @@
# SUCH DAMAGE.
#
-$Module debug 3 "Development, test and debug"
$ABI strict
$Prefix xyzzy
+$Module debug 3 "Development, test and debug"
$Synopsis auto
DESCRIPTION
===========
diff --git a/lib/libvmod_directors/vmod.vcc b/lib/libvmod_directors/vmod.vcc
index 54b111fba..a98352983 100644
--- a/lib/libvmod_directors/vmod.vcc
+++ b/lib/libvmod_directors/vmod.vcc
@@ -32,8 +32,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
-$Module directors 3 "Varnish Directors Module"
$ABI strict
+$Module directors 3 "Varnish Directors Module"
DESCRIPTION
===========
diff --git a/lib/libvmod_proxy/vmod.vcc b/lib/libvmod_proxy/vmod.vcc
index 79aa4b678..2d0663582 100644
--- a/lib/libvmod_proxy/vmod.vcc
+++ b/lib/libvmod_proxy/vmod.vcc
@@ -25,8 +25,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
-$Module proxy 3 "Varnish Module to extract TLV attributes from PROXYv2"
$ABI strict
+$Module proxy 3 "Varnish Module to extract TLV attributes from PROXYv2"
DESCRIPTION
===========
diff --git a/lib/libvmod_purge/vmod.vcc b/lib/libvmod_purge/vmod.vcc
index e158aac69..c8d8185cc 100644
--- a/lib/libvmod_purge/vmod.vcc
+++ b/lib/libvmod_purge/vmod.vcc
@@ -25,8 +25,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
-$Module purge 3 "Varnish Purge Module"
$ABI strict
+$Module purge 3 "Varnish Purge Module"
DESCRIPTION
===========
diff --git a/lib/libvmod_std/vmod.vcc b/lib/libvmod_std/vmod.vcc
index fc5ef3736..0ae941c12 100644
--- a/lib/libvmod_std/vmod.vcc
+++ b/lib/libvmod_std/vmod.vcc
@@ -25,8 +25,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
-$Module std 3 "Varnish Standard Module"
$ABI strict
+$Module std 3 "Varnish Standard Module"
DESCRIPTION
===========
diff --git a/lib/libvmod_unix/vmod.vcc b/lib/libvmod_unix/vmod.vcc
index e227e9f99..38e48a7d3 100644
--- a/lib/libvmod_unix/vmod.vcc
+++ b/lib/libvmod_unix/vmod.vcc
@@ -5,9 +5,8 @@
# Authors: Geoffrey Simmons <geoffrey.simmons at uplex.de>
#
-$Module unix 3 "Utilities for Unix domain sockets"
-
$ABI strict
+$Module unix 3 "Utilities for Unix domain sockets"
DESCRIPTION
===========
diff --git a/lib/libvmod_vtc/vmod.vcc b/lib/libvmod_vtc/vmod.vcc
index 248f4b2d6..e1644fffc 100644
--- a/lib/libvmod_vtc/vmod.vcc
+++ b/lib/libvmod_vtc/vmod.vcc
@@ -25,8 +25,8 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
-$Module vtc 3 "Utility module for varnishtest"
$ABI strict
+$Module vtc 3 "Utility module for varnishtest"
DESCRIPTION
===========
More information about the varnish-commit
mailing list