[6.1] 41f7b093b A train-trip worth of python3 migration and other polishing

hermunn hermunn at varnish-software.com
Wed Oct 24 09:29:15 UTC 2018


commit 41f7b093bdccdd23d8113c1e636ff7296f0b68e6
Author: Poul-Henning Kamp <phk at FreeBSD.org>
Date:   Mon Sep 24 07:26:11 2018 +0000

    A train-trip worth of python3 migration and other polishing

diff --git a/bin/varnishtest/huffman_gen.py b/bin/varnishtest/huffman_gen.py
index 8da37b2ee..b89bbb43e 100755
--- a/bin/varnishtest/huffman_gen.py
+++ b/bin/varnishtest/huffman_gen.py
@@ -7,50 +7,50 @@ import sys
 regex = re.compile("^HPH\((.{4}), (.{10}), +(.{1,3})\)")
 
 if len(sys.argv) != 2:
-	print("{} takes one and only one argument".format(sys.argv[0]))
-	sys.exit(2)
+    print("{} takes one and only one argument".format(sys.argv[0]))
+    sys.exit(2)
 
 class sym:
-	def __init__(self, bigval, bigvall, chr = 0, esc = None):
-		self.vall = bigvall % 8 if bigvall % 8 else 8
-		self.val = bigval & ((1 << self.vall) - 1)
-		self.pfx = (bigval >> self.vall)# & 0xff
-		self.chr = chr
-		self.esc = esc
+    def __init__(self, bigval, bigvall, chr=0, esc=None):
+        self.vall = bigvall % 8 if bigvall % 8 else 8
+        self.val = bigval & ((1 << self.vall) - 1)
+        self.pfx = (bigval >> self.vall)# & 0xff
+        self.chr = chr
+        self.esc = esc
 
 tbls = {}
 msl = {} # max sym length
 
 f = open(sys.argv[1])
 for l in f:
-	grp = 1
-	match = regex.match(l)
-	if not match:
-		continue
-
-	chr = int(match.group(grp), 16)
-	grp += 1
-
-	val = int(match.group(grp), 16)
-	grp += 1
-
-	vall = int(match.group(grp))
-
-	s = sym(val, vall, chr)
-	if s.pfx not in tbls:
-		tbls[s.pfx] = {}
-
-	if (s.val in tbls[s.pfx]):
-		assert(tbls[s.pfx][s.val].e)
-	tbls[s.pfx][s.val] = s
-
-	# add the escape entry in the "previous" table
-	if s.pfx:
-		pp = s.pfx >> 8
-		pv = s.pfx & 0xff
-		if pp not in tbls:
-			tbls[pp] = {}
-		tbls[pp][pv] = sym(pv, 8, 0, "&tbl_{:x}".format(s.pfx))
+    grp = 1
+    match = regex.match(l)
+    if not match:
+        continue
+
+    char = int(match.group(grp), 16)
+    grp += 1
+
+    val = int(match.group(grp), 16)
+    grp += 1
+
+    vall = int(match.group(grp))
+
+    s = sym(val, vall, char)
+    if s.pfx not in tbls:
+        tbls[s.pfx] = {}
+
+    if s.val in tbls[s.pfx]:
+        assert tbls[s.pfx][s.val].e
+    tbls[s.pfx][s.val] = s
+
+    # add the escape entry in the "previous" table
+    if s.pfx:
+        pp = s.pfx >> 8
+        pv = s.pfx & 0xff
+        if pp not in tbls:
+            tbls[pp] = {}
+        tbls[pp][pv] = sym(pv, 8, 0, "&tbl_{:x}".format(s.pfx))
 f.close()
 
 # add the EOS case
@@ -64,33 +64,33 @@ print('''/* NB:  This file is machine generated, DO NOT EDIT!
 struct stbl;
 
 struct ssym {
-	uint8_t csm;		/* bits consumed */
-	uint8_t	chr;		/* character */
-	struct stbl *nxt;	/* next table */
+    uint8_t csm;        /* bits consumed */
+    uint8_t chr;        /* character */
+    struct stbl *nxt;       /* next table */
 };
 
 struct stbl {
-	int msk;
-	struct ssym *syms;
+    int msk;
+    struct ssym *syms;
 };
 ''')
 
 for pfx in sorted(tbls.keys(), reverse=True):
-	msl = max([ x.vall for x in tbls[pfx].values() ])
-	for s in tbls[pfx].values():
-		s.val = s.val << (msl - s.vall)
-
-	tbl = sorted(tbls[pfx].values(), key= lambda x: x.val)
-	print("\nstatic struct ssym sym_{:x}_array[] = {{".format(pfx))
-	for s in tbl:
-		for j in range(2 ** (msl - s.vall)):
-			print("	{} {{{}, {:3d}, {}}},".format(
-				"\t     " if j else "/* idx {:3d} */".format(s.val + j),
-				s.vall, s.chr % 256,
-				s.esc if s.esc else "NULL"))
-	print('''}};
+    msl = max([x.vall for x in tbls[pfx].values()])
+    for s in tbls[pfx].values():
+        s.val = s.val << (msl - s.vall)
+
+    tbl = sorted(tbls[pfx].values(), key=lambda x: x.val)
+    print("\nstatic struct ssym sym_{:x}_array[] = {{".format(pfx))
+    for s in tbl:
+        for j in range(2 ** (msl - s.vall)):
+            print("{} {{{}, {:3d}, {}}},".format(
+                "\t     " if j else "/* idx {:3d} */".format(s.val + j),
+                s.vall, s.chr % 256,
+                s.esc if s.esc else "NULL"))
+    print('''}};
 
 static struct stbl tbl_{:x} = {{
-	{},
-	sym_{:x}_array
+    {},
+    sym_{:x}_array
 }};'''.format(pfx, msl, pfx))
diff --git a/bin/varnishtest/witness.py b/bin/varnishtest/witness.py
index f57fdf221..a4f0fffa6 100644
--- a/bin/varnishtest/witness.py
+++ b/bin/varnishtest/witness.py
@@ -3,9 +3,9 @@
 # This script is in the public domain
 #
 # Run instructions:
-#	varnishtest -W -iv -j <pick_a_number> > _.w
-#	python witness.py
-#	dot -Tpng /tmp/_.dot > /tmp/_.png
+#       varnishtest -W -iv -j <pick_a_number> > _.w
+#       python witness.py
+#       dot -Tpng /tmp/_.dot > /tmp/_.png
 
 from __future__ import print_function
 
@@ -16,37 +16,37 @@ fi = open("_.w")
 fo = open("/tmp/_.dot", "w")
 
 fo.write('''digraph {
-	#rotate="90"
-	#page="8.2,11.7"
-	size="8.2,11.7"
-	rankdir="LR"
-	node [fontname="Inconsolata", fontsize="10"]
-	edge [fontname="Inconsolata", fontsize="10"]
+    #rotate="90"
+    #page="8.2,11.7"
+    size="8.2,11.7"
+    rankdir="LR"
+    node [fontname="Inconsolata", fontsize="10"]
+    edge [fontname="Inconsolata", fontsize="10"]
 ''')
 
 for i in fi:
-	l = "ROOT"
-	j = i.split()
-	if len(j) < 8:
-		continue
-	if j[1][0] != 'v':
-		continue
-	if j[3] != "vsl|":
-		continue
-	if j[5] != "Witness":
-		continue
-	t = j[7:]
-	tt = str(t)
-	if tt in d:
-		continue
-	d[tt] = True
-	for e in t:
-		f = e.split(",")
-		x = '"%s" -> "%s" [label="%s(%s)"]\n' % (l, f[0], f[1], f[2])
-		if not x in a:
-			a[x] = True
-			fo.write(x)
-		l = f[0]
+    l = "ROOT"
+    j = i.split()
+    if len(j) < 8:
+        continue
+    if j[1][0] != 'v':
+        continue
+    if j[3] != "vsl|":
+        continue
+    if j[5] != "Witness":
+        continue
+    t = j[7:]
+    tt = str(t)
+    if tt in d:
+        continue
+    d[tt] = True
+    for e in t:
+        f = e.split(",")
+        x = '"%s" -> "%s" [label="%s(%s)"]\n' % (l, f[0], f[1], f[2])
+        if not x in a:
+            a[x] = True
+            fo.write(x)
+        l = f[0]
 
 fo.write("}\n")
 
diff --git a/doc/sphinx/vtc-syntax.py b/doc/sphinx/vtc-syntax.py
index 298f4bb01..ba7bd6bd7 100644
--- a/doc/sphinx/vtc-syntax.py
+++ b/doc/sphinx/vtc-syntax.py
@@ -35,50 +35,49 @@ import re
 
 
 def parse_file(fn, cl, tl, sl):
-	p = False
-	section = ""
-	resec = re.compile("[ /]\* SECTION: ")
+    p = False
+    section = ""
+    resec = re.compile("[ /]\* SECTION: ")
 
-	f = open(fn, "r")
+    f = open(fn, "r")
 
-	for l in f:
-		if "*/" in l:
-			p = 0
-		if resec.match(l):
-			a = l.split()
-			section = a[2]
-			sl.append(section)
-			cl[section] = []
-			if len(a) > 3:
-				tl[section] = re.sub(
-					r"^[\t ]*\/?\* SECTION: [^ ]+ +",
-					"", l)
-			else:
-				tl[section] = ""
-			p = 1
-		elif p:
-			cl[section].append(re.sub(r"^ \* ?", "", l))
-	f.close()
+    for l in f:
+        if "*/" in l:
+            p = 0
+        if resec.match(l):
+            a = l.split()
+            section = a[2]
+            sl.append(section)
+            cl[section] = []
+            if len(a) > 3:
+                tl[section] = re.sub(
+                    r"^[\t ]*\/?\* SECTION: [^ ]+ +",
+                    "", l)
+            else:
+                tl[section] = ""
+            p = 1
+        elif p:
+            cl[section].append(re.sub(r"^ \* ?", "", l))
+    f.close()
 
 if __name__ == "__main__":
-	cl = {}
-	tl = {}
-	sl = []
-	for fn in sys.argv[1:]:
-		parse_file(fn, cl, tl, sl)
-	sl.sort()
-	for section in sl:
-		print(tl[section], end="")
-		a = section
-		c = section.count(".")
-		if c == 0:
-			r = "-"
-		elif c == 1:
-			r = "~"
-		elif c == 2:
-			r = "."
-		else:
-			r = "*"
-		print(re.sub(r".", r, tl[section]), end="")
-		print("".join(cl[section]))
-
+    cl = {}
+    tl = {}
+    sl = []
+    for fn in sys.argv[1:]:
+        parse_file(fn, cl, tl, sl)
+    sl.sort()
+    for section in sl:
+        print(tl[section], end="")
+        a = section
+        c = section.count(".")
+        if c == 0:
+            r = "-"
+        elif c == 1:
+            r = "~"
+        elif c == 2:
+            r = "."
+        else:
+            r = "*"
+        print(re.sub(r".", r, tl[section]), end="")
+        print("".join(cl[section]))
diff --git a/include/Makefile.am b/include/Makefile.am
index 27f40ec86..98050fd78 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -108,7 +108,7 @@ vcl.h: \
 	    $(top_srcdir)/include/vrt.h \
 	    $(top_srcdir)/doc/sphinx/reference/vcl_var.rst
 	mkdir -p $(top_builddir)/include/tbl
-	@PYTHON@ $(top_srcdir)/lib/libvcc/generate.py \
+	${PYTHON} $(top_srcdir)/lib/libvcc/generate.py \
 	    $(top_srcdir) $(top_builddir)
 
 GEN_H = \
@@ -128,7 +128,7 @@ vcs_version.h:
 	@if test -e $(top_srcdir)/.git || \
 	  ! test -f $(srcdir)/vmod_abi.h || \
 	  ! test -f $(srcdir)/vcs_version.h ; then \
-	    @PYTHON@ $(srcdir)/generate.py \
+	    ${PYTHON} $(srcdir)/generate.py \
 		$(top_srcdir) $(top_builddir) ; \
 	fi
 
diff --git a/include/generate.py b/include/generate.py
index 0d9d9b32b..e7d547593 100755
--- a/include/generate.py
+++ b/include/generate.py
@@ -32,22 +32,21 @@
 from __future__ import print_function
 
 import subprocess
-import collections
 import os
 import sys
 
 srcroot = "../.."
 buildroot = "../.."
 if len(sys.argv) == 3:
-	srcroot = sys.argv[1]
-	buildroot = sys.argv[2]
+    srcroot = sys.argv[1]
+    buildroot = sys.argv[2]
 elif len(sys.argv) != 1:
-	print("Two arguments or none")
-	exit(2)
+    print("Two arguments or none")
+    exit(2)
 
 #######################################################################
 def file_header(fo):
-	fo.write("""/*
+    fo.write("""/*
  * NB:  This file is machine generated, DO NOT EDIT!
  *
  * Edit and run include/generate.py instead.
@@ -66,25 +65,25 @@ v = subprocess.check_output([
 vcsfn = os.path.join(srcroot, "include", "vcs_version.h")
 
 try:
-	i = open(vcsfn).readline()
+    i = open(vcsfn).readline()
 except IOError:
-	i = ""
+    i = ""
 
 ident = "/* " + v + " */\n"
 
 if i != ident:
-	fo = open(vcsfn, "w")
-	fo.write(ident)
-	file_header(fo)
-	fo.write('#define VCS_Version "%s"\n' % v)
-	fo.close()
+    fo = open(vcsfn, "w")
+    fo.write(ident)
+    file_header(fo)
+    fo.write('#define VCS_Version "%s"\n' % v)
+    fo.close()
 
-	for i in open(os.path.join(buildroot, "Makefile")):
-		if i[:14] == "PACKAGE_STRING":
-			break
-	i = i.split("=")[1].strip()
+    for i in open(os.path.join(buildroot, "Makefile")):
+        if i[:14] == "PACKAGE_STRING":
+            break
+    i = i.split("=")[1].strip()
 
-	fo = open(os.path.join(srcroot, "include", "vmod_abi.h"), "w")
-	file_header(fo)
-	fo.write('#define VMOD_ABI_Version "%s %s"\n' % (i, v))
-	fo.close()
+    fo = open(os.path.join(srcroot, "include", "vmod_abi.h"), "w")
+    file_header(fo)
+    fo.write('#define VMOD_ABI_Version "%s %s"\n' % (i, v))
+    fo.close()
diff --git a/include/tbl/h2_settings.h b/include/tbl/h2_settings.h
index adfb416d4..c382e862d 100644
--- a/include/tbl/h2_settings.h
+++ b/include/tbl/h2_settings.h
@@ -47,6 +47,7 @@ H2_SETTING(					// rfc7540,l,2097,2103
 	0xffffffff,
 	0
 )
+
 #ifndef H2_SETTINGS_PARAM_ONLY
 H2_SETTING(					// rfc7540,l,2105,2114
 	ENABLE_PUSH,
@@ -58,6 +59,7 @@ H2_SETTING(					// rfc7540,l,2105,2114
 	H2CE_PROTOCOL_ERROR
 )
 #endif
+
 H2_SETTING(					// rfc7540,l,2116,2121
 	MAX_CONCURRENT_STREAMS,
 	max_concurrent_streams,
@@ -67,6 +69,7 @@ H2_SETTING(					// rfc7540,l,2116,2121
 	0xffffffff,
 	0
 )
+
 H2_SETTING(					// rfc7540,l,2139,2148
 	INITIAL_WINDOW_SIZE,
 	initial_window_size,
@@ -76,6 +79,7 @@ H2_SETTING(					// rfc7540,l,2139,2148
 	0x7fffffff,
 	H2CE_FLOW_CONTROL_ERROR
 )
+
 H2_SETTING(					// rfc7540,l,2150,2157
 	MAX_FRAME_SIZE,
 	max_frame_size,
@@ -85,6 +89,7 @@ H2_SETTING(					// rfc7540,l,2150,2157
 	0x00ffffff,
 	H2CE_PROTOCOL_ERROR
 )
+
 H2_SETTING(					// rfc7540,l,2159,2167
 	MAX_HEADER_LIST_SIZE,
 	max_header_list_size,
diff --git a/include/tbl/htc.h b/include/tbl/htc.h
index a93c0e520..4e9695491 100644
--- a/include/tbl/htc.h
+++ b/include/tbl/htc.h
@@ -36,10 +36,11 @@ HTC_STATUS(JUNK,	-5,	"junk",		"Received unexpected data")
 HTC_STATUS(CLOSE,	-4,	"close",	"Connection closed") // unused?
 HTC_STATUS(TIMEOUT,	-3,	"timeout",	"Timed out")
 HTC_STATUS(OVERFLOW,	-2,	"overflow",	"Buffer/workspace too small")
-HTC_STATUS(EOF,	-1,	"eof",		"Unexpected end of input")
+HTC_STATUS(EOF,		-1,	"eof",		"Unexpected end of input")
 HTC_STATUS(EMPTY,	 0,	"empty",	"Empty response")
-HTC_STATUS(MORE,	 1,	"more",	"More data required")
+HTC_STATUS(MORE,	 1,	"more",		"More data required")
 HTC_STATUS(COMPLETE,	 2,	"complete",	"Data complete (no error)")
-HTC_STATUS(IDLE,	 3,	"idle",	"Connection was closed while idle")
+HTC_STATUS(IDLE,	 3,	"idle",		"Connection was closed while idle")
 #undef HTC_STATUS
+
 /*lint -restore */
diff --git a/include/tbl/style.py b/include/tbl/style.py
index a29459c0a..a88c475a3 100644
--- a/include/tbl/style.py
+++ b/include/tbl/style.py
@@ -7,66 +7,68 @@ from __future__ import print_function
 import glob
 
 def check_file(fn):
-	s = 0
-	ll = []
-	for l in open(fn):
-		ll.append(l)
+    print("Check", fn)
+    ll = []
+    for l in open(fn):
+        ll.append(l)
 
-	assert ll.pop(0)[:2] == "/*"
+    assert ll.pop(0)[:2] == "/*"
 
-	while ll.pop(0) != " */\n":
-		continue
+    while ll.pop(0) != " */\n":
+        continue
 
-	assert len(ll) > 5
+    assert len(ll) > 5
 
-	assert ll.pop(0) == "\n"
-	assert ll.pop(0) == "/*lint -save -e525 -e539 */\n"
-	assert ll.pop(0) == "\n"
+    assert ll.pop(0) == "\n"
+    i = ll.pop(0)
+    assert i == "/*lint -save -e525 -e539 */\n" or \
+           i == "/*lint -save -e525 -e539 -e835 */\n"
+    assert ll.pop(0) == "\n"
 
-	assert ll.pop(-1) == "/*lint -restore */\n"
-	assert ll.pop(-1) == "\n"
+    assert ll.pop(-1) == "/*lint -restore */\n"
+    assert ll.pop(-1) == "\n"
 
-	for i in range(0, len(ll) -1):
-		assert ll[i] != "\n" or ll[i+1] != "\n"
-		assert ll[i] != ")\n" or ll[i+1] == "\n" or ll[i+1][0] == "#"
+    for i in range(0, len(ll) -1):
+        assert ll[i] != "\n" or ll[i+1] != "\n"
+        assert ll[i] != ")\n" or ll[i+1] == "\n" or ll[i+1][0] == "#"
 
-	m = {}
-	while len(ll) > 0:
-		i = ll.pop(0)
-		if i == "\n":
-			continue
-		l = i.lstrip()
-		if l[0] >= 'A' and l[0] <= 'Z':
-			j = l.split('(')
-			m[j[0]] = "Called"
-			l = l.split('//')[0]
-			l = l.split('/*')[0]
-			l = l.rstrip()
-			if l[-1] != ')':
-				while ll.pop(0) != ')\n':
-					continue
-		elif l[0] == "#":
-			j = l[1:].lstrip().split()
-			# print("#", j[0])
-			if j[0] == "define":
-				m[j[1].split("(")[0].strip()] = "Defined"
-			if j[0] == "undef":
-				m[j[1]] = "Undef"
-			while l[-2:] == "\\\n":
-				l = ll.pop(0)
-		else:
-			pass
-			# print(l)
-	rv = 0
-	for i in m:
-		if m[i] != "Undef":
-			print("ERROR", fn, i, m[i])
-			rv += 1
-	return rv
+    m = {}
+    while ll:
+        i = ll.pop(0)
+        if i == "\n":
+            continue
+        l = i.lstrip()
+        if l[0] >= 'A' and l[0] <= 'Z':
+            j = l.split('(')
+            m[j[0]] = "Called"
+            l = l.split('//')[0]
+            l = l.split('/*')[0]
+            l = l.rstrip()
+            if l[-1] != ')':
+                while ll.pop(0).strip() != ')':
+                    continue
+        elif l[0] == "#":
+            j = l[1:].lstrip().split()
+            # print("#", j[0])
+            if j[0] == "define":
+                m[j[1].split("(")[0].strip()] = "Defined"
+            if j[0] == "undef":
+                m[j[1]] = "Undef"
+            while l[-2:] == "\\\n":
+                l = ll.pop(0)
+        else:
+            pass
+            # print(l)
+    rv = 0
+    for i in m:
+        if m[i] != "Undef":
+            print("ERROR", fn, i, m[i])
+            rv += 1
+    return rv
 
 rv = 0
 for fn in glob.glob("*.h"):
-	rv += check_file(fn)
+    rv += check_file(fn)
 if rv != 0:
-	print(rv, "Errors")
+    print(rv, "Errors")
 exit(rv)
diff --git a/include/tbl/vsl_tags.h b/include/tbl/vsl_tags.h
index 0997d72f8..294da9431 100644
--- a/include/tbl/vsl_tags.h
+++ b/include/tbl/vsl_tags.h
@@ -181,16 +181,17 @@ SLTM(Length, 0, "Size of object body",
 	"Logs the size of a fetch object body.\n\n"
 )
 
-/* XXX generate HTC info from tbl include */
-#if 0
-#include <stdio.h>
-int main(void) {
-#define HTC_STATUS(e, n, s, l) \
-	printf("\t\"\\t* %s (%d): %s\\n\"\n", s, n, l);
-#include "include/tbl/htc.h"
-	return (0);
-}
-#endif
+/*
+ * XXX generate HTC info below from tbl include
+ *
+ * #include <stdio.h>
+ * int main(void) {
+ * #define HTC_STATUS(e, n, s, l) \
+ *	printf("\t\"\\t* %s (%d): %s\\n\"\n", s, n, l);
+ * #include "include/tbl/htc.h"
+ *	return (0);
+ * }
+ */
 
 SLTM(FetchError, 0, "Error while fetching object",
 	"Logs the error message of a failed fetch operation.\n\n"
diff --git a/include/tbl/waiters.h b/include/tbl/waiters.h
index f1f1d4900..f2fcf6446 100644
--- a/include/tbl/waiters.h
+++ b/include/tbl/waiters.h
@@ -44,3 +44,5 @@
 
 WAITER(poll)
 #undef WAITER
+
+/*lint -restore */
diff --git a/lib/libvarnishapi/generate.py b/lib/libvarnishapi/generate.py
index a7b505c74..d1357c985 100755
--- a/lib/libvarnishapi/generate.py
+++ b/lib/libvarnishapi/generate.py
@@ -37,122 +37,121 @@ import copy
 srcroot = "../.."
 buildroot = "../.."
 if len(sys.argv) == 3:
-	srcroot = sys.argv[1]
-	buildroot = sys.argv[2]
+    srcroot = sys.argv[1]
+    buildroot = sys.argv[2]
 
 #######################################################################
 # These are our tokens
 
 tokens = {
-	# Numerical comparisons
-	"T_EQ":         "==",
-	"T_NEQ":        "!=",
-	"T_LEQ":        "<=",
-	"T_GEQ":        ">=",
-
-	# String comparisons
-	"T_SEQ":        "eq",
-	"T_SNEQ":       "ne",
-
-	# Regular expression matching
-	"T_NOMATCH":    "!~",
-
-	# Boolean operators
-	"T_AND":        "and",
-	"T_OR":         "or",
-	"T_NOT":        "not",
-
-	# Miscellaneous
-	None:           "<>~[]{}():,",
-
-	# These have handwritten recognizers
-	"VAL":          None,
-	"EOI":          None,
-
-	# Special
-	"T_TRUE":       None,
-	"VXID":         "vxid",
+    # Numerical comparisons
+    "T_EQ":     "==",
+    "T_NEQ":    "!=",
+    "T_LEQ":    "<=",
+    "T_GEQ":    ">=",
+
+    # String comparisons
+    "T_SEQ":    "eq",
+    "T_SNEQ":       "ne",
+
+    # Regular expression matching
+    "T_NOMATCH":    "!~",
+
+    # Boolean operators
+    "T_AND":    "and",
+    "T_OR":     "or",
+    "T_NOT":    "not",
+
+    # Miscellaneous
+    None:       "<>~[]{}():,",
+
+    # These have handwritten recognizers
+    "VAL":      None,
+    "EOI":      None,
+
+    # Special
+    "T_TRUE":       None,
+    "VXID":     "vxid",
 }
 
 #######################################################################
 # Emit a function to recognize tokens in a string
 
 def emit_vxp_fixed_token(fo, tokens):
-	recog = list()
-	emit = dict()
-	for i in tokens:
-		j = tokens[i]
-		if (j != None):
-			recog.append(j)
-			emit[j] = i
-
-	recog.sort()
-	rrecog = copy.copy(recog)
-	rrecog.sort(key = lambda x: -len(x))
-
-	fo.write("""
+    recog = list()
+    emit = dict()
+    for i in tokens:
+        j = tokens[i]
+        if j is not None:
+            recog.append(j)
+            emit[j] = i
+
+    recog.sort()
+    rrecog = copy.copy(recog)
+    rrecog.sort(key=lambda x: -len(x))
+
+    fo.write("""
 unsigned
 vxp_fixed_token(const char *p, const char **q)
 {
 
 \tswitch (p[0]) {
 """)
-	last_initial = None
-	for i in recog:
-		if (i[0] == last_initial):
-			continue
-		last_initial = i[0]
-		fo.write("\tcase '%s':\n" % last_initial)
-		for j in rrecog:
-			if (j[0] != last_initial):
-				continue
-
-			fo.write("\t\tif (")
-			k = 1
-			l = len(j)
-			while (k < l):
-				fo.write("p[%d] == '%s'" % (k, j[k]))
-				fo.write(" &&\n\t\t    ")
-				k += 1
-			fo.write("(isword(p[%d]) ? !isword(p[%d]) : 1)) {\n" %
-				(l - 1, l))
-			fo.write("\t\t\t*q = p + %d;\n" % l)
-			fo.write("\t\t\treturn (%s);\n" % emit[j])
-			fo.write("\t\t}\n")
-		fo.write("\t\treturn (0);\n")
-
-	fo.write("\tdefault:\n\t\treturn (0);\n\t}\n}\n")
+    last_initial = None
+    for i in recog:
+        if i[0] == last_initial:
+            continue
+        last_initial = i[0]
+        fo.write("\tcase '%s':\n" % last_initial)
+        for j in rrecog:
+            if j[0] != last_initial:
+                continue
+
+            fo.write("\t\tif (")
+            k = 1
+            l = len(j)
+            while k < l:
+                fo.write("p[%d] == '%s'" % (k, j[k]))
+                fo.write(" &&\n\t\t    ")
+                k += 1
+            fo.write("(isword(p[%d]) ? !isword(p[%d]) : 1)) {\n" % (l - 1, l))
+            fo.write("\t\t\t*q = p + %d;\n" % l)
+            fo.write("\t\t\treturn (%s);\n" % emit[j])
+            fo.write("\t\t}\n")
+        fo.write("\t\treturn (0);\n")
+
+    fo.write("\tdefault:\n\t\treturn (0);\n\t}\n}\n")
 
 #######################################################################
 # Emit the vxp_tnames (token->string) conversion array
 
 def emit_vxp_tnames(fo, tokens):
-	fo.write("\nconst char * const vxp_tnames[256] = {\n")
-	l = list(tokens.keys())
-	l.sort()
-	for i in l:
-		j = tokens[i]
-		if j == None:
-			j = i
-		if i[0] == "'":
-			j = i
-		fo.write("\t[%s] = \"%s\",\n" % (i, j))
-	fo.write("};\n")
+    fo.write("\nconst char * const vxp_tnames[256] = {\n")
+    l = list(tokens.keys())
+    l.sort()
+    for i in l:
+        j = tokens[i]
+        if j is None:
+            j = i
+        if i[0] == "'":
+            j = i
+        fo.write("\t[%s] = \"%s\",\n" % (i, j))
+    fo.write("};\n")
 
 #######################################################################
 
 def polish_tokens(tokens):
-	# Expand single char tokens
-	st = tokens[None]
-	del tokens[None]
+    # Expand single char tokens
+    st = tokens[None]
+    del tokens[None]
 
-	for i in st:
-		tokens["'" + i + "'"] = i
+    for i in st:
+        tokens["'" + i + "'"] = i
 
 #######################################################################
 
 def file_header(fo):
-	fo.write("""/*
+    fo.write("""/*
  * NB:  This file is machine generated, DO NOT EDIT!
  *
  * Edit and run lib/libvarnishapi/generate.py instead
@@ -171,11 +170,11 @@ j = 128
 l = list(tokens.keys())
 l.sort()
 for i in l:
-	if i[0] == "'":
-		continue
-	fo.write("#define\t%s %d\n" % (i, j))
-	j += 1
-	assert j < 256
+    if i[0] == "'":
+        continue
+    fo.write("#define\t%s %d\n" % (i, j))
+    j += 1
+    assert j < 256
 
 fo.close()
 
diff --git a/lib/libvcc/generate.py b/lib/libvcc/generate.py
index 4328c7072..5dba1a37a 100755
--- a/lib/libvcc/generate.py
+++ b/lib/libvcc/generate.py
@@ -32,10 +32,6 @@
 
 from __future__ import print_function
 
-import subprocess
-import collections
-import os
-
 #######################################################################
 # These are our tokens
 
@@ -51,112 +47,112 @@ from os.path import join
 srcroot = "../.."
 buildroot = "../.."
 if len(sys.argv) == 3:
-	srcroot = sys.argv[1]
-	buildroot = sys.argv[2]
+    srcroot = sys.argv[1]
+    buildroot = sys.argv[2]
 elif len(sys.argv) != 1:
-	print("Two arguments or none")
-	exit(2)
+    print("Two arguments or none")
+    exit(2)
 
 tokens = {
-	"T_INC":	"++",
-	"T_DEC":	"--",
-	"T_CAND":	"&&",
-	"T_COR":	"||",
-	"T_LEQ":	"<=",
-	"T_EQ":		"==",
-	"T_NEQ":	"!=",
-	"T_GEQ":	">=",
-	"T_SHR":	">>",
-	"T_SHL":	"<<",
-	"T_INCR":	"+=",
-	"T_DECR":	"-=",
-	"T_MUL":	"*=",
-	"T_DIV":	"/=",
-	"T_NOMATCH":	"!~",
-
-	# Single char tokens, for convenience on one line
-	None:		"{}()*+-/%><=;!&.|~,",
-
-	# These have handwritten recognizers
-	"ID":		None,
-	"CNUM":		None,
-	"FNUM":		None,
-	"CSTR":		None,
-	"EOI":		None,
-	"CSRC":		None,
+    "T_INC":    "++",
+    "T_DEC":    "--",
+    "T_CAND":       "&&",
+    "T_COR":    "||",
+    "T_LEQ":    "<=",
+    "T_EQ":     "==",
+    "T_NEQ":    "!=",
+    "T_GEQ":    ">=",
+    "T_SHR":    ">>",
+    "T_SHL":    "<<",
+    "T_INCR":       "+=",
+    "T_DECR":       "-=",
+    "T_MUL":    "*=",
+    "T_DIV":    "/=",
+    "T_NOMATCH":    "!~",
+
+    # Single char tokens, for convenience on one line
+    None:       "{}()*+-/%><=;!&.|~,",
+
+    # These have handwritten recognizers
+    "ID":       None,
+    "CNUM":     None,
+    "FNUM":     None,
+    "CSTR":     None,
+    "EOI":      None,
+    "CSRC":     None,
 }
 
 #######################################################################
 # Our methods and actions
 
 returns = (
-	###############################################################
-	# Client side
-
-	('recv',
-		"C",
-		('fail', 'synth', 'restart', 'pass', 'pipe', 'hash', 'purge', 'vcl')
-	),
-	('pipe',
-		"C",
-		('fail', 'synth', 'pipe',)
-	),
-	('pass',
-		"C",
-		('fail', 'synth', 'restart', 'fetch',)
-	),
-	('hash',
-		"C",
-		('fail', 'lookup',)
-	),
-	('purge',
-		"C",
-		('fail', 'synth', 'restart',)
-	),
-	('miss',
-		"C",
-		('fail', 'synth', 'restart', 'pass', 'fetch',)
-	),
-	('hit',
-		"C",
-		('fail', 'synth', 'restart', 'pass', 'miss', 'deliver',)
-	),
-	('deliver',
-		"C",
-		('fail', 'synth', 'restart', 'deliver',)
-	),
-	('synth',
-		"C",
-		('fail', 'restart', 'deliver',)
-	),
-
-	###############################################################
-	# Backend-fetch
-
-	('backend_fetch',
-		"B",
-		('fail', 'fetch', 'abandon')
-	),
-	('backend_response',
-		"B",
-		('fail', 'deliver', 'retry', 'abandon', 'pass')
-	),
-	('backend_error',
-		"B",
-		('fail', 'deliver', 'retry', 'abandon')
-	),
-
-	###############################################################
-	# Housekeeping
-
-	('init',
-		"H",
-		('ok', 'fail')
-	),
-	('fini',
-		"H",
-		('ok',)
-	),
+    ###############################################################
+    # Client side
+
+    ('recv',
+     "C",
+     ('fail', 'synth', 'restart', 'pass', 'pipe', 'hash', 'purge', 'vcl')
+    ),
+    ('pipe',
+     "C",
+     ('fail', 'synth', 'pipe',)
+    ),
+    ('pass',
+     "C",
+     ('fail', 'synth', 'restart', 'fetch',)
+    ),
+    ('hash',
+     "C",
+     ('fail', 'lookup',)
+    ),
+    ('purge',
+     "C",
+     ('fail', 'synth', 'restart',)
+    ),
+    ('miss',
+     "C",
+     ('fail', 'synth', 'restart', 'pass', 'fetch',)
+    ),
+    ('hit',
+     "C",
+     ('fail', 'synth', 'restart', 'pass', 'miss', 'deliver',)
+    ),
+    ('deliver',
+     "C",
+     ('fail', 'synth', 'restart', 'deliver',)
+    ),
+    ('synth',
+     "C",
+     ('fail', 'restart', 'deliver',)
+    ),
+
+    ###############################################################
+    # Backend-fetch
+
+    ('backend_fetch',
+     "B",
+     ('fail', 'fetch', 'abandon')
+    ),
+    ('backend_response',
+     "B",
+     ('fail', 'deliver', 'retry', 'abandon', 'pass')
+    ),
+    ('backend_error',
+     "B",
+     ('fail', 'deliver', 'retry', 'abandon')
+    ),
+
+    ###############################################################
+    # Housekeeping
+
+    ('init',
+     "H",
+     ('ok', 'fail')
+    ),
+    ('fini',
+     "H",
+     ('ok',)
+    ),
 )
 
 #######################################################################
@@ -170,152 +166,151 @@ returns = (
 varprotos = {}
 
 def varproto(s):
-	if not s in varprotos:
-		fh.write(s + ";\n")
-		varprotos[s] = True
+    if not s in varprotos:
+        fh.write(s + ";\n")
+        varprotos[s] = True
 
 class vardef(object):
-	def __init__(self, nam, typ, rd, wr, wu, vlo, vhi):
-		self.nam = nam
-		self.typ = typ
-		self.rd = rd
-		self.wr = wr
-		self.uns = wu
-		self.vlo = vlo
-		self.vhi = vhi
-
-		self.emit()
-
-	def emit(self):
-		fh.write("\n")
-		fo.write("\n")
-		cnam = self.nam.replace(".", "_")
-		ctyp = vcltypes[self.typ]
-
-		# fo.write("\t{ \"%s\", %s,\n" % (nm, self.typ))
-		fo.write("\tsym = VCC_MkSym(tl, \"%s\", " % self.nam)
-		if (self.typ == "HEADER"):
-			fo.write(" SYM_NONE, %d, %d);\n" % (self.vlo, self.vhi))
-			fo.write("\tAN(sym);\n");
-			fo.write("\tsym->wildcard = vcc_Var_Wildcard;\n")
-		else:
-			fo.write(" SYM_VAR, %d, %d);\n" % (self.vlo, self.vhi))
-		fo.write("\tAN(sym);\n")
-		fo.write("\tsym->type = %s;\n" % self.typ)
-		fo.write("\tsym->eval = vcc_Eval_Var;\n")
-
-		if self.typ == "HEADER":
-			fo.write('\tsym->rname = "HDR_')
-			fo.write(self.nam.split(".")[0].upper())
-			fo.write('";\n')
-		elif len(self.rd):
-			fo.write('\tsym->rname = "VRT_r_%s(ctx)";\n' % cnam)
-			varproto("VCL_" + self.typ + " VRT_r_%s(VRT_CTX)" % cnam)
-		fo.write("\tsym->r_methods =\n")
-		restrict(fo, self.rd)
-		fo.write(";\n")
-
-		if self.typ == "HEADER":
-			fo.write('\tsym->lname = "HDR_')
-			fo.write(self.nam.split(".")[0].upper())
-			fo.write('";\n')
-		elif len(self.wr):
-			fo.write('\tsym->lname = "VRT_l_%s(ctx, ";\n' % cnam)
-			s = "void VRT_l_%s(VRT_CTX, " % cnam
-			if self.typ != "STRING" and self.typ != "BODY":
-				s += "VCL_" + self.typ + ")"
-			else:
-				s += ctyp.c + ", ...)"
-			varproto(s);
-		fo.write("\tsym->w_methods =\n")
-		restrict(fo, self.wr)
-		fo.write(";\n")
-
-		if len(self.uns):
-			varproto("void VRT_u_%s(VRT_CTX)" % cnam)
-			fo.write('\tsym->uname = "VRT_u_%s(ctx)";\n' % cnam)
-		fo.write('\tsym->u_methods =\n')
-		restrict(fo, self.uns)
-		fo.write(";\n")
+    def __init__(self, nam, typ, rd, wr, wu, vlo, vhi):
+        self.nam = nam
+        self.typ = typ
+        self.rd = rd
+        self.wr = wr
+        self.uns = wu
+        self.vlo = vlo
+        self.vhi = vhi
+
+        self.emit()
+
+    def emit(self):
+        fh.write("\n")
+        fo.write("\n")
+        cnam = self.nam.replace(".", "_")
+        ctyp = vcltypes[self.typ]
+
+        # fo.write("\t{ \"%s\", %s,\n" % (nm, self.typ))
+        fo.write("\tsym = VCC_MkSym(tl, \"%s\", " % self.nam)
+        if self.typ == "HEADER":
+            fo.write(" SYM_NONE, %d, %d);\n" % (self.vlo, self.vhi))
+            fo.write("\tAN(sym);\n")
+            fo.write("\tsym->wildcard = vcc_Var_Wildcard;\n")
+        else:
+            fo.write(" SYM_VAR, %d, %d);\n" % (self.vlo, self.vhi))
+        fo.write("\tAN(sym);\n")
+        fo.write("\tsym->type = %s;\n" % self.typ)
+        fo.write("\tsym->eval = vcc_Eval_Var;\n")
+
+        if self.typ == "HEADER":
+            fo.write('\tsym->rname = "HDR_')
+            fo.write(self.nam.split(".")[0].upper())
+            fo.write('";\n')
+        elif self.rd:
+            fo.write('\tsym->rname = "VRT_r_%s(ctx)";\n' % cnam)
+            varproto("VCL_" + self.typ + " VRT_r_%s(VRT_CTX)" % cnam)
+        fo.write("\tsym->r_methods =\n")
+        restrict(fo, self.rd)
+        fo.write(";\n")
+
+        if self.typ == "HEADER":
+            fo.write('\tsym->lname = "HDR_')
+            fo.write(self.nam.split(".")[0].upper())
+            fo.write('";\n')
+        elif self.wr:
+            fo.write('\tsym->lname = "VRT_l_%s(ctx, ";\n' % cnam)
+            s = "void VRT_l_%s(VRT_CTX, " % cnam
+            if self.typ != "STRING" and self.typ != "BODY":
+                s += "VCL_" + self.typ + ")"
+            else:
+                s += ctyp.c + ", ...)"
+            varproto(s)
+        fo.write("\tsym->w_methods =\n")
+        restrict(fo, self.wr)
+        fo.write(";\n")
+
+        if self.uns:
+            varproto("void VRT_u_%s(VRT_CTX)" % cnam)
+            fo.write('\tsym->uname = "VRT_u_%s(ctx)";\n' % cnam)
+        fo.write('\tsym->u_methods =\n')
+        restrict(fo, self.uns)
+        fo.write(";\n")
 
 def parse_vcl(x):
-	vlo,vhi = (0,99)
-	x = x.split()
-	if x[0] == "VCL" and x[1] == "<=":
-		vhi = int(float(x[2]) * 10)
-	elif x[0] == "VCL" and x[1] == ">=":
-		vlo = int(float(x[2]) * 10)
-	else:
-		print("Unknown variable version spec")
-		print("XXX", x, vlo, vhi)
-		exit(2)
-	return vlo,vhi
+    vlo, vhi = (0, 99)
+    x = x.split()
+    if x[0] == "VCL" and x[1] == "<=":
+        vhi = int(float(x[2]) * 10)
+    elif x[0] == "VCL" and x[1] == ">=":
+        vlo = int(float(x[2]) * 10)
+    else:
+        print("Unknown variable version spec")
+        print("XXX", x, vlo, vhi)
+        exit(2)
+    return vlo, vhi
 
 def parse_var(ln):
-	l1 = ln.pop(0).split("``")
-	assert len(l1) in (1,3)
-	vn = l1[0].strip()
-	if vn[-1] == '*':
-		vn = vn[:-1]
-	if len(l1) == 3:
-		vlo,vhi = parse_vcl(l1[1])
-	else:
-		vlo,vhi = 0,99
-	vr = []
-	vw = []
-	vu = []
-	while True:
-		l = ln.pop(0)
-		if l == "":
-			continue
-		j = l.split()
-		if j[0] == "Type:":
-			assert len(j) == 2
-			vt = j[1]
-			continue
-		if j[0] == "Readable" and j[1] == "from:":
-			for i in j[2:]:
-				vr.append(i.strip(",."))
-			continue
-		if j[0] == "Writable" and j[1] == "from:":
-			for i in j[2:]:
-				vw.append(i.strip(",."))
-			continue
-		if j[0] == "Unsetable" and j[1] == "from:":
-			for i in j[2:]:
-				vu.append(i.strip(",."))
-			continue
-		break
-	if vn[:8] != "storage.":
-		vardef(vn, vt, vr, vw, vu, vlo, vhi)
+    l1 = ln.pop(0).split("``")
+    assert len(l1) in (1, 3)
+    vn = l1[0].strip()
+    if vn[-1] == '*':
+        vn = vn[:-1]
+    if len(l1) == 3:
+        vlo, vhi = parse_vcl(l1[1])
+    else:
+        vlo, vhi = 0, 99
+    vr = []
+    vw = []
+    vu = []
+    while True:
+        l = ln.pop(0)
+        if l == "":
+            continue
+        j = l.split()
+        if j[0] == "Type:":
+            assert len(j) == 2
+            vt = j[1]
+            continue
+        if j[0] == "Readable" and j[1] == "from:":
+            for i in j[2:]:
+                vr.append(i.strip(",."))
+            continue
+        if j[0] == "Writable" and j[1] == "from:":
+            for i in j[2:]:
+                vw.append(i.strip(",."))
+            continue
+        if j[0] == "Unsetable" and j[1] == "from:":
+            for i in j[2:]:
+                vu.append(i.strip(",."))
+            continue
+        break
+    if vn[:8] != "storage.":
+        vardef(vn, vt, vr, vw, vu, vlo, vhi)
 
 def parse_var_doc(fn):
-	s = 0
-	l = []
-	for i in open(fn):
-		l.append(i.rstrip())
-	for n in range(0, len(l)):
-		j = l[n].split()
-		if len(j) != 2 or j[0] != "Type:" or not l[n][0].isspace():
-			continue
-		m = n
-		while m < len(l) and ( l[m] == "" or l[m][0].isspace() ):
-			m += 1
-		parse_var(l[n-2:m-1])
+    l = []
+    for i in open(fn):
+        l.append(i.rstrip())
+    for n in range(0, len(l)):
+        j = l[n].split()
+        if len(j) != 2 or j[0] != "Type:" or not l[n][0].isspace():
+            continue
+        m = n
+        while m < len(l) and (l[m] == "" or l[m][0].isspace()):
+            m += 1
+        parse_var(l[n-2:m-1])
 
 stv_variables = (
-	('free_space',	'BYTES',	"0.", 'storage.<name>.free_space', """
-	Free space available in the named stevedore. Only available for
-	the malloc stevedore.
-	"""),
-	('used_space',	'BYTES',	"0.", 'storage.<name>.used_space', """
-	Used space in the named stevedore. Only available for the malloc
-	stevedore.
-	"""),
-	('happy',	'BOOL',		"0", 'storage.<name>.happy', """
-	Health status for the named stevedore. Not available in any of the
-	current stevedores.
-	"""),
+    ('free_space', 'BYTES', "0.", 'storage.<name>.free_space', """
+    Free space available in the named stevedore. Only available for
+    the malloc stevedore.
+    """),
+    ('used_space', 'BYTES', "0.", 'storage.<name>.used_space', """
+    Used space in the named stevedore. Only available for the malloc
+    stevedore.
+    """),
+    ('happy', 'BOOL', "0", 'storage.<name>.happy', """
+    Health status for the named stevedore. Not available in any of the
+    current stevedores.
+    """),
 )
 
 #######################################################################
@@ -324,11 +319,11 @@ stv_variables = (
 vcltypes = {}
 
 class vcltype(object):
-	def __init__(self, name, ctype, internal=False):
-		self.name = name
-		self.c = ctype
-		self.internal = internal
-		vcltypes[name] = self
+    def __init__(self, name, ctype, internal=False):
+        self.name = name
+        self.c = ctype
+        self.internal = internal
+        vcltypes[name] = self
 
 
 vcltype("STRINGS", "void", True)
@@ -338,19 +333,19 @@ vcltype("SUB", "void*", True)
 fi = open(join(srcroot, "include/vrt.h"))
 
 for i in fi:
-	j = i.split()
-	if len(j) < 3:
-		continue
-	if j[0] != "typedef":
-		continue
-	if j[-1][-1] != ";":
-		continue
-	if j[-1][-2] == ")":
-		continue
-	if j[-1][:4] != "VCL_":
-		continue
-	d = " ".join(j[1:-1])
-	vcltype(j[-1][4:-1], d)
+    j = i.split()
+    if len(j) < 3:
+        continue
+    if j[0] != "typedef":
+        continue
+    if j[-1][-1] != ";":
+        continue
+    if j[-1][-2] == ")":
+        continue
+    if j[-1][:4] != "VCL_":
+        continue
+    d = " ".join(j[1:-1])
+    vcltype(j[-1][4:-1], d)
 fi.close()
 
 #######################################################################
@@ -360,20 +355,20 @@ fi.close()
 
 #######################################################################
 def emit_vcl_fixed_token(fo, tokens):
-	"Emit a function to recognize tokens in a string"
-	recog = list()
-	emit = dict()
-	for i in tokens:
-		j = tokens[i]
-		if j is not None:
-			recog.append(j)
-			emit[j] = i
-
-	recog.sort()
-	rrecog = copy.copy(recog)
-	rrecog.sort(key=lambda x: -len(x))
-
-	fo.write("""
+    "Emit a function to recognize tokens in a string"
+    recog = list()
+    emit = dict()
+    for i in tokens:
+        j = tokens[i]
+        if j is not None:
+            recog.append(j)
+            emit[j] = i
+
+    recog.sort()
+    rrecog = copy.copy(recog)
+    rrecog.sort(key=lambda x: -len(x))
+
+    fo.write("""
 #define M1()\tdo {*q = p + 1; return (p[0]); } while (0)
 #define M2(c,t)\tdo {if (p[1] == (c)) { *q = p + 2; return (t); }} while (0)
 
@@ -383,131 +378,130 @@ vcl_fixed_token(const char *p, const char **q)
 
 \tswitch (p[0]) {
 """)
-	last_initial = None
-	for i in recog:
-		if (i[0] == last_initial):
-			continue
-		last_initial = i[0]
-		fo.write("\tcase '%s':\n" % last_initial)
-		need_ret = True
-		for j in rrecog:
-			if (j[0] != last_initial):
-				continue
-			if len(j) == 2:
-				fo.write("\t\tM2('%s', %s);\n" %
-				    (j[1], emit[j]))
-			elif len(j) == 1:
-				fo.write("\t\tM1();\n")
-				need_ret = False
-			else:
-				fo.write("\t\tif (")
-				k = 1
-				l = len(j)
-				while (k < l):
-					fo.write("p[%d] == '%s'" % (k, j[k]))
-					fo.write(" &&")
-					if (k % 3) == 0:
-						fo.write("\n\t\t    ")
-					else:
-						fo.write(" ")
-					k += 1
-				fo.write("!isvar(p[%d])) {\n" % l)
-				fo.write("\t\t\t*q = p + %d;\n" % l)
-				fo.write("\t\t\treturn (%s);\n" % emit[j])
-				fo.write("\t\t}\n")
-		if need_ret:
-			fo.write("\t\treturn (0);\n")
-	fo.write("\tdefault:\n\t\treturn (0);\n\t}\n}\n")
+    last_initial = None
+    for i in recog:
+        if i[0] == last_initial:
+            continue
+        last_initial = i[0]
+        fo.write("\tcase '%s':\n" % last_initial)
+        need_ret = True
+        for j in rrecog:
+            if j[0] != last_initial:
+                continue
+            if len(j) == 2:
+                fo.write("\t\tM2('%s', %s);\n" % (j[1], emit[j]))
+            elif len(j) == 1:
+                fo.write("\t\tM1();\n")
+                need_ret = False
+            else:
+                fo.write("\t\tif (")
+                k = 1
+                l = len(j)
+                while k < l:
+                    fo.write("p[%d] == '%s'" % (k, j[k]))
+                    fo.write(" &&")
+                    if (k % 3) == 0:
+                        fo.write("\n\t\t    ")
+                    else:
+                        fo.write(" ")
+                    k += 1
+                fo.write("!isvar(p[%d])) {\n" % l)
+                fo.write("\t\t\t*q = p + %d;\n" % l)
+                fo.write("\t\t\treturn (%s);\n" % emit[j])
+                fo.write("\t\t}\n")
+        if need_ret:
+            fo.write("\t\treturn (0);\n")
+    fo.write("\tdefault:\n\t\treturn (0);\n\t}\n}\n")
 
 
 #######################################################################
 def emit_vcl_tnames(fo, tokens):
-	"Emit the vcl_tnames (token->string) conversion array"
-	fo.write("\nconst char * const vcl_tnames[256] = {\n")
-	l = list(tokens.keys())
-	l.sort()
-	for i in l:
-		j = tokens[i]
-		if j is None:
-			j = i
-		if i[0] == "'":
-			j = i
-		fo.write("\t[%s] = \"%s\",\n" % (i, j))
-	fo.write("};\n")
+    "Emit the vcl_tnames (token->string) conversion array"
+    fo.write("\nconst char * const vcl_tnames[256] = {\n")
+    l = list(tokens.keys())
+    l.sort()
+    for i in l:
+        j = tokens[i]
+        if j is None:
+            j = i
+        if i[0] == "'":
+            j = i
+        fo.write("\t[%s] = \"%s\",\n" % (i, j))
+    fo.write("};\n")
 
 
 #######################################################################
 def emit_file(fo, fd, bn):
-	"Read a C-source file and spit out code that outputs it with VSB_cat()"
-	fn = join(fd, bn)
-
-	fi = open(fn)
-	fc = fi.read()
-	fi.close()
-
-	w = 66		# Width of lines, after white space prefix
-	maxlen = 10240  # Max length of string literal
-
-	x = 0
-	l = 0
-	fo.write("\n\t/* %s */\n\n" % fn)
-	fo.write('\tVSB_cat(sb, "/* ---===### %s ###===--- */\\n\\n");\n' % bn)
-	for c in fc:
-		if l == 0:
-			fo.write("\tVSB_cat(sb, \"")
-			l += 12
-			x += 12
-		if x == 0:
-			fo.write("\t    \"")
-		d = c
-		if c == '\n':
-			d = "\\n"
-		elif c == '\t':
-			d = "\\t"
-		elif c == '"':
-			d = "\\\""
-		elif c == '\\':
-			d = "\\\\"
-
-		if c == '\n' and x > w - 20:
-			fo.write(d + "\"\n")
-			x = 0
-			continue
-		if c.isspace() and x > w - 10:
-			fo.write(d + "\"\n")
-			x = 0
-			continue
-
-		fo.write(d)
-		x += len(d)
-		l += len(d)
-		if l > maxlen:
-			fo.write("\");\n")
-			l = 0
-			x = 0
-		if x > w - 3:
-			fo.write("\"\n")
-			x = 0
-	if x != 0:
-		fo.write("\"\n")
-	if l != 0:
-		fo.write("\t);\n")
-	fo.write('\tVSB_cat(sb, "\\n");\n')
+    "Read a C-source file and spit out code that outputs it with VSB_cat()"
+    fn = join(fd, bn)
+
+    fi = open(fn)
+    fc = fi.read()
+    fi.close()
+
+    w = 66      # Width of lines, after white space prefix
+    maxlen = 10240  # Max length of string literal
+
+    x = 0
+    l = 0
+    fo.write("\n\t/* %s */\n\n" % fn)
+    fo.write('\tVSB_cat(sb, "/* ---===### %s ###===--- */\\n\\n");\n' % bn)
+    for c in fc:
+        if l == 0:
+            fo.write("\tVSB_cat(sb, \"")
+            l += 12
+            x += 12
+        if x == 0:
+            fo.write("\t    \"")
+        d = c
+        if c == '\n':
+            d = "\\n"
+        elif c == '\t':
+            d = "\\t"
+        elif c == '"':
+            d = "\\\""
+        elif c == '\\':
+            d = "\\\\"
+
+        if c == '\n' and x > w - 20:
+            fo.write(d + "\"\n")
+            x = 0
+            continue
+        if c.isspace() and x > w - 10:
+            fo.write(d + "\"\n")
+            x = 0
+            continue
+
+        fo.write(d)
+        x += len(d)
+        l += len(d)
+        if l > maxlen:
+            fo.write("\");\n")
+            l = 0
+            x = 0
+        if x > w - 3:
+            fo.write("\"\n")
+            x = 0
+    if x != 0:
+        fo.write("\"\n")
+    if l != 0:
+        fo.write("\t);\n")
+    fo.write('\tVSB_cat(sb, "\\n");\n')
 
 #######################################################################
 
 
 def polish_tokens(tokens):
-	"Expand single char tokens"
-	st = tokens[None]
-	del tokens[None]
-	for i in st:
-		tokens["'" + i + "'"] = i
+    "Expand single char tokens"
+    st = tokens[None]
+    del tokens[None]
+    for i in st:
+        tokens["'" + i + "'"] = i
 
 
 #######################################################################
 def file_header(fo):
-	fo.write("""/*
+    fo.write("""/*
  * NB:  This file is machine generated, DO NOT EDIT!
  *
  * Edit and run lib/libvcc/generate.py instead.
@@ -516,10 +510,10 @@ def file_header(fo):
 """)
 
 def lint_start(fo):
-	fo.write('/*lint -save -e525 -e539 */\n\n')
+    fo.write('/*lint -save -e525 -e539 */\n\n')
 
 def lint_end(fo):
-	fo.write('\n/*lint -restore */\n')
+    fo.write('\n/*lint -restore */\n')
 
 #######################################################################
 
@@ -531,11 +525,11 @@ file_header(fo)
 
 j = 128
 for i in sorted(tokens.keys()):
-	if i[0] == "'":
-		continue
-	fo.write("#define\t%s %d\n" % (i, j))
-	j += 1
-	assert j < 256
+    if i[0] == "'":
+        continue
+    fo.write("#define\t%s %d\n" % (i, j))
+    j += 1
+    assert j < 256
 
 fo.close()
 
@@ -546,14 +540,14 @@ vcls = list()
 vcls_client = list()
 vcls_backend = list()
 for i in returns:
-	vcls.append(i[0])
-	for j in i[1]:
-		if j == "B":
-			vcls_backend.append(i[0])
-		elif j == "C":
-			vcls_client.append(i[0])
-	for j in i[2]:
-		rets[j] = True
+    vcls.append(i[0])
+    for j in i[1]:
+        if j == "B":
+            vcls_backend.append(i[0])
+        elif j == "C":
+            vcls_client.append(i[0])
+    for j in i[2]:
+        rets[j] = True
 
 #######################################################################
 
@@ -566,25 +560,25 @@ lint_start(fo)
 fo.write("#ifdef VCL_RET_MAC\n")
 ll = sorted(returns)
 for i in sorted(rets.keys()):
-	fo.write("VCL_RET_MAC(%s, %s" % (i.lower(), i.upper()))
-	s = ",\n\t"
-	for j in ll:
-		if i in j[2]:
-			fo.write("%sVCL_MET_%s" % (s, j[0].upper()))
-			s = " |\n\t"
-	fo.write("\n)\n\n")
+    fo.write("VCL_RET_MAC(%s, %s" % (i.lower(), i.upper()))
+    s = ",\n\t"
+    for j in ll:
+        if i in j[2]:
+            fo.write("%sVCL_MET_%s" % (s, j[0].upper()))
+            s = " |\n\t"
+    fo.write("\n)\n\n")
 fo.write("#undef VCL_RET_MAC\n")
 fo.write("#endif\n")
 
 fo.write("\n#ifdef VCL_MET_MAC\n")
 for i in ll:
-	fo.write("VCL_MET_MAC(%s, %s, %s," %
-	    (i[0].lower(), i[0].upper(), i[1]))
-	p = " (\n\t"
-	for j in sorted(i[2]):
-		fo.write("%s(1U << VCL_RET_%s)" % (p, j.upper()))
-		p = " |\n\t"
-	fo.write(")\n)\n\n")
+    fo.write("VCL_MET_MAC(%s, %s, %s," %
+             (i[0].lower(), i[0].upper(), i[1]))
+    p = " (\n\t"
+    for j in sorted(i[2]):
+        fo.write("%s(1U << VCL_RET_%s)" % (p, j.upper()))
+        p = " |\n\t"
+    fo.write(")\n)\n\n")
 fo.write("#undef VCL_MET_MAC\n")
 fo.write("#endif\n")
 lint_end(fo)
@@ -609,40 +603,40 @@ fo.write("""
 
 
 def tbl40(a, b):
-	while len(a.expandtabs()) < 40:
-		a += "\t"
-	return a + b
+    while len(a.expandtabs()) < 40:
+        a += "\t"
+    return a + b
 
 fo.write("\n/* VCL Methods */\n")
 task = {}
 n = 1
 for i in returns:
-	fo.write(tbl40("#define VCL_MET_%s" % i[0].upper(), "(1U << %d)\n" % n))
-	if not i[1] in task:
-		task[i[1]] = []
-	task[i[1]].append("VCL_MET_" + i[0].upper())
-	n += 1
+    fo.write(tbl40("#define VCL_MET_%s" % i[0].upper(), "(1U << %d)\n" % n))
+    if not i[1] in task:
+        task[i[1]] = []
+    task[i[1]].append("VCL_MET_" + i[0].upper())
+    n += 1
 
 fo.write("\n" + tbl40("#define VCL_MET_MAX", "%d\n" % n))
 fo.write("\n" + tbl40("#define VCL_MET_MASK", "0x%x\n" % ((1 << n) - 1)))
 
 fo.write("\n")
 for i in sorted(task.keys()):
-	fo.write(tbl40("#define VCL_MET_TASK_%s" % i.upper(),
-		       "( " + (" | \\\n\t\t\t\t\t  ").join(task[i]) + " )\n"))
+    fo.write(tbl40("#define VCL_MET_TASK_%s" % i.upper(),
+                   "( " + (" | \\\n\t\t\t\t\t  ").join(task[i]) + " )\n"))
 
 
 fo.write("\n/* VCL Returns */\n")
 n = 1
 for i in sorted(rets.keys()):
-	fo.write(tbl40("#define VCL_RET_%s" % i.upper(), "%d\n" % n))
-	n += 1
+    fo.write(tbl40("#define VCL_RET_%s" % i.upper(), "%d\n" % n))
+    n += 1
 
 fo.write("\n" + tbl40("#define VCL_RET_MAX", "%d\n" % n))
 
 fo.write("\n/* VCL Types */\n")
 for vcltype in sorted(vcltypes.keys()):
-	fo.write("extern const struct vrt_type VCL_TYPE_%s[1];\n" % vcltype)
+    fo.write("extern const struct vrt_type VCL_TYPE_%s[1];\n" % vcltype)
 
 
 fo.write("""
@@ -653,26 +647,26 @@ typedef void vcl_fini_f(VRT_CTX);
 typedef void vcl_func_f(VRT_CTX);
 
 struct VCL_conf {
-	unsigned			magic;
-#define VCL_CONF_MAGIC			0x7406c509	/* from /dev/random */
+    unsigned            magic;
+#define VCL_CONF_MAGIC          0x7406c509      /* from /dev/random */
 
-	unsigned			syntax;
-	VCL_BACKEND			*default_director;
-	const struct vrt_backend_probe	*default_probe;
-	unsigned			nref;
-	const struct vrt_ref		*ref;
+    unsigned            syntax;
+    VCL_BACKEND             *default_director;
+    const struct vrt_backend_probe  *default_probe;
+    unsigned            nref;
+    const struct vrt_ref        *ref;
 
-	unsigned			nsrc;
-	const char			**srcname;
-	const char			**srcbody;
+    unsigned            nsrc;
+    const char              **srcname;
+    const char              **srcbody;
 
-	unsigned			nvmod;
+    unsigned            nvmod;
 
-	vcl_event_f			*event_vcl;
+    vcl_event_f             *event_vcl;
 """)
 
 for i in returns:
-	fo.write("\tvcl_func_f\t\t\t*" + i[0] + "_func;\n")
+    fo.write("\tvcl_func_f\t\t\t*" + i[0] + "_func;\n")
 
 fo.write("\n};\n")
 fo.close()
@@ -681,44 +675,44 @@ fo.close()
 
 
 def restrict(fo, spec):
-	d = dict()
-	for j in spec:
-		if j[:4] == "vcl_":
-			j = j[4:]
-		if j == 'all':
-			for i in vcls:
-				d[i] = True
-		elif j == 'backend':
-			for i in vcls_backend:
-				d[i] = True
-		elif j == 'client':
-			for i in vcls_client:
-				d[i] = True
-		elif j == 'both':
-			for i in vcls_client:
-				d[i] = True
-			for i in vcls_backend:
-				d[i] = True
-		else:
-			if not j in vcls:
-				print("JJ", j)
-			assert j in vcls
-			d[j] = True
-	p = ""
-	l = list(d.keys())
-	l.sort()
-	w = 0
-	fo.write("\t\t")
-	for j in l:
-		x = p + "VCL_MET_" + j.upper()
-		if w + len(x) > 60:
-			fo.write("\n\t\t")
-			w = 0
-		fo.write(x)
-		w += len(x)
-		p = " | "
-	if len(d) == 0:
-		fo.write("0")
+    d = dict()
+    for j in spec:
+        if j[:4] == "vcl_":
+            j = j[4:]
+        if j == 'all':
+            for i in vcls:
+                d[i] = True
+        elif j == 'backend':
+            for i in vcls_backend:
+                d[i] = True
+        elif j == 'client':
+            for i in vcls_client:
+                d[i] = True
+        elif j == 'both':
+            for i in vcls_client:
+                d[i] = True
+            for i in vcls_backend:
+                d[i] = True
+        else:
+            if not j in vcls:
+                print("JJ", j)
+            assert j in vcls
+            d[j] = True
+    p = ""
+    l = list(d.keys())
+    l.sort()
+    w = 0
+    fo.write("\t\t")
+    for j in l:
+        x = p + "VCL_MET_" + j.upper()
+        if w + len(x) > 60:
+            fo.write("\n\t\t")
+            w = 0
+        fo.write(x)
+        w += len(x)
+        p = " | "
+    if not d:
+        fo.write("0")
 
 #######################################################################
 
@@ -736,7 +730,7 @@ fo.write("""
 void
 vcc_Var_Init(struct vcc *tl)
 {
-	struct symbol *sym;
+    struct symbol *sym;
 """)
 
 
@@ -744,22 +738,22 @@ parse_var_doc(join(srcroot, "doc/sphinx/reference/vcl_var.rst"))
 fo.write("}\n")
 
 for i in stv_variables:
-	fh.write(vcltypes[i[1]].c + " VRT_Stv_" + i[0] + "(const char *);\n")
+    fh.write(vcltypes[i[1]].c + " VRT_Stv_" + i[0] + "(const char *);\n")
 
 fo.write("\n/* VCL type identifiers */\n")
 
 for vn in sorted(vcltypes.keys()):
-	v = vcltypes[vn]
-	if v.internal:
-		continue
-	fo.write("const struct vrt_type VCL_TYPE_%s[1] = { {\n" % v.name)
-	fo.write("\t.magic = VRT_TYPE_MAGIC,\n")
-	fo.write('\t.lname = "%s",\n' % v.name.lower())
-	fo.write('\t.uname = "%s",\n' % v.name)
-	fo.write('\t.ctype = "%s",\n' % v.c)
-	if v.c != "void":
-		fo.write('\t.szof = sizeof(VCL_%s),\n' % v.name)
-	fo.write("}};\n")
+    v = vcltypes[vn]
+    if v.internal:
+        continue
+    fo.write("const struct vrt_type VCL_TYPE_%s[1] = { {\n" % v.name)
+    fo.write("\t.magic = VRT_TYPE_MAGIC,\n")
+    fo.write('\t.lname = "%s",\n' % v.name.lower())
+    fo.write('\t.uname = "%s",\n' % v.name)
+    fo.write('\t.ctype = "%s",\n' % v.c)
+    if v.c != "void":
+        fo.write('\t.szof = sizeof(VCL_%s),\n' % v.name)
+    fo.write("}};\n")
 
 fo.close()
 fh.close()
@@ -800,7 +794,7 @@ file_header(ft)
 lint_start(ft)
 
 for vcltype in sorted(vcltypes.keys()):
-	ft.write("VCC_TYPE(" + vcltype + ")\n")
+    ft.write("VCC_TYPE(" + vcltype + ")\n")
 ft.write("#undef VCC_TYPE\n")
 lint_end(ft)
 ft.close()
@@ -813,10 +807,10 @@ file_header(fo)
 lint_start(fo)
 
 for i in stv_variables:
-	ct = vcltypes[i[1]]
-	fo.write("VRTSTVVAR(" + i[0] + ",\t" + i[1] + ",\t")
-	fo.write(ct.c + ",\t" + i[2] + ")")
-	fo.write("\n")
+    ct = vcltypes[i[1]]
+    fo.write("VRTSTVVAR(" + i[0] + ",\t" + i[1] + ",\t")
+    fo.write(ct.c + ",\t" + i[2] + ")")
+    fo.write("\n")
 
 fo.write("#undef VRTSTVVAR\n")
 lint_end(fo)
diff --git a/lib/libvcc/vmodtool.py b/lib/libvcc/vmodtool.py
index 25b8cc621..dd157449f 100755
--- a/lib/libvcc/vmodtool.py
+++ b/lib/libvcc/vmodtool.py
@@ -41,7 +41,6 @@ import sys
 import re
 import optparse
 import unittest
-import random
 import copy
 import json
 import hashlib
@@ -254,7 +253,7 @@ class CType(object):
     def json(self, jl):
         jl.append([self.vt])
         while jl[-1][-1] is None:
-                jl[-1].pop(-1)
+            jl[-1].pop(-1)
 
 #######################################################################
 
@@ -290,7 +289,7 @@ class arg(CType):
     def json(self, jl):
         jl.append([self.vt, self.nm, self.defval, self.spec])
         if self.opt:
-                jl[-1].append(True)
+            jl[-1].append(True)
         while jl[-1][-1] is None:
             jl[-1].pop(-1)
 
@@ -366,7 +365,7 @@ class ProtoType(object):
             err("%s(): Illegal C-name\n" % self.cname(), warn=False)
 
         if len(wl) == 2 and wl[0] == '(' and wl[1] == ')':
-                return
+            return
 
         if wl[0] != "(":
             err("Syntax error: Expected '(', got '%s'" % wl[0], warn=False)
@@ -386,17 +385,17 @@ class ProtoType(object):
             if not wl:
                 break
             if wl[0] == '[':
-                    wl.pop(0)
-                    t = arg(wl, names, st.vcc.enums, ']')
-                    if t.nm is None:
-                        err("Optional arguments must have names", warn=False)
-                    t.opt = True
-                    x = wl.pop(0)
-                    if x != ']':
-                        err("Expected ']' found '%s'" % x, warn=False)
-                    self.argstruct = True
+                wl.pop(0)
+                t = arg(wl, names, st.vcc.enums, ']')
+                if t.nm is None:
+                    err("Optional arguments must have names", warn=False)
+                t.opt = True
+                x = wl.pop(0)
+                if x != ']':
+                    err("Expected ']' found '%s'" % x, warn=False)
+                self.argstruct = True
             else:
-                    t = arg(wl, names, st.vcc.enums, ',')
+                t = arg(wl, names, st.vcc.enums, ',')
             if t.nm is None:
                 t.nm2 = "arg%d" % n
             else:
@@ -466,10 +465,10 @@ class ProtoType(object):
         s = self.retval.ct + " " + name + '('
         ll = args
         if self.argstruct:
-                ll.append(self.argstructname() + "*")
+            ll.append(self.argstructname() + "*")
         else:
-                for i in self.args:
-                    ll.append(i.ct)
+            for i in self.args:
+                ll.append(i.ct)
         s += ", ".join(ll)
         return s + ');'
 
@@ -483,31 +482,31 @@ class ProtoType(object):
     def argstructure(self):
         s = "\n" + self.argstructname() + " {\n"
         for i in self.args:
-                if i.opt:
-                        assert i.nm is not None
-                        s += "\tchar\t\t\tvalid_%s;\n" % i.nm
+            if i.opt:
+                assert i.nm is not None
+                s += "\tchar\t\t\tvalid_%s;\n" % i.nm
         for i in self.args:
-                s += "\t" + i.ct
-                if len(i.ct) < 8:
-                        s += "\t"
-                if len(i.ct) < 16:
-                        s += "\t"
-                s += "\t" + i.nm2 + ";\n"
+            s += "\t" + i.ct
+            if len(i.ct) < 8:
+                s += "\t"
+            if len(i.ct) < 16:
+                s += "\t"
+            s += "\t" + i.nm2 + ";\n"
         s += "};\n"
         return s
 
     def cstuff(self, args, where):
         s = ""
         if where == 'h':
-                if self.argstruct:
-                        s += self.argstructure()
-                s += lwrap(self.proto(args, self.cname(True)))
+            if self.argstruct:
+                s += self.argstructure()
+            s += lwrap(self.proto(args, self.cname(True)))
         elif where == 'c':
-                s += lwrap(self.typedef(args))
+            s += lwrap(self.typedef(args))
         elif where == 'o':
-                if self.argstruct:
-                        s += self.argstructure()
-                s += lwrap(self.typedef(args))
+            if self.argstruct:
+                s += self.argstructure()
+            s += lwrap(self.typedef(args))
         else:
             assert False
         return s
@@ -517,9 +516,9 @@ class ProtoType(object):
         self.retval.json(ll)
         ll.append('Vmod_%s_Func.%s' % (self.st.vcc.modname, cfunc))
         if self.argstruct:
-                ll.append(self.argstructname())
+            ll.append(self.argstructname())
         else:
-                ll.append("")
+            ll.append("")
         for i in self.args:
             i.json(ll)
         jl.append(ll)
diff --git a/lib/libvcc/vsctool.py b/lib/libvcc/vsctool.py
index a665dff20..6c96388e5 100644
--- a/lib/libvcc/vsctool.py
+++ b/lib/libvcc/vsctool.py
@@ -27,9 +27,13 @@
 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 # SUCH DAMAGE.
 
-"""
-This program compiles a .vsc file to C language constructs.
-"""
+'''
+This program compiles a `.vsc` file to `.c`, `.h` and `.rst` formats.
+
+Note: A `.vsc` file is *almost* a `.rst` file, or at last *almost*
+the same general syntax as a `.rst` file, but for now we process
+it with this program to get a *real* `.rst` file.
+'''
 
 from __future__ import print_function
 
@@ -37,385 +41,386 @@ import getopt
 import json
 import sys
 import collections
-import struct
 
-TYPES = [ "counter", "gauge", "bitmap" ]
-CTYPES = [ "uint64_t" ]
-LEVELS = [ "info", "diag", "debug" ]
-FORMATS = [ "integer", "bytes", "bitmap", "duration" ]
+# Parameters of 'varnish_vsc_begin', first element is default
+TYPES = ["counter", "gauge", "bitmap"]
+CTYPES = ["uint64_t"]
+LEVELS = ["info", "diag", "debug"]
+FORMATS = ["integer", "bytes", "bitmap", "duration"]
 
 PARAMS = {
-	"type":		["counter", TYPES],
-	"ctype":	["uint64_t", CTYPES],
-	"level":	["info", LEVELS],
-	"oneliner":	True,
-	"format":	[ "integer", FORMATS],
+    "type": TYPES,
+    "ctype": CTYPES,
+    "level": LEVELS,
+    "oneliner": None,
+    "format": FORMATS,
 }
 
-# http://python3porting.com/problems.html#bytes-strings-and-unicode
-if sys.version_info < (3,):
-	def b(x):
-		return x
-else:
-	import codecs
-	def b(x):
-		return codecs.latin_1_encode(x)[0]
-
 def genhdr(fo, name):
-	fo.write('/*\n')
-	fo.write(' * NB:  This file is machine generated, DO NOT EDIT!\n')
-	fo.write(' *\n')
-	fo.write(' * Edit ' + name +
-	    '.vsc and run lib/libvcc/vsctool.py instead.\n')
-	fo.write(' */\n')
-	fo.write('\n')
 
-#######################################################################
+    '''Emit .[ch] file boiler-plate warning'''
 
-class vscset(object):
-	def __init__(self, name, m):
-		self.name = name
-		self.struct = "struct VSC_" + name
-		self.mbrs = []
-		self.head = m
-		self.completed = False
-		self.off = 0
-
-	def addmbr(self, m):
-		assert not self.completed
-		self.mbrs.append(m)
-		m.param["index"] = self.off
-		self.off += 8
-
-	def complete(self):
-		self.completed = True
-
-	def emit_json(self, fo):
-		dd = collections.OrderedDict()
-		dd["version"] = "1"
-		dd["name"] = self.name
-		dd["oneliner"] = self.head.param["oneliner"].strip()
-		dd["order"] = int(self.head.param["order"])
-		dd["docs"] = "\n".join(self.head.getdoc())
-		dd["elements"] = len(self.mbrs)
-		el = collections.OrderedDict()
-		dd["elem"] = el
-		for i in self.mbrs:
-			ed = collections.OrderedDict()
-			el[i.arg] = ed
-			for j in PARAMS:
-				if j in i.param:
-					ed[j] = i.param[j]
-			ed["index"] = i.param["index"]
-			ed["name"] = i.arg
-			ed["docs"] = "\n".join(i.getdoc())
-		s=json.dumps(dd, separators=(",",":")) + "\0"
-		fo.write("\nstatic const unsigned char")
-		fo.write(" vsc_%s_json[%d] = {\n" % (self.name, len(s)))
-		bz = bytearray(s, encoding="ascii")
-		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")
-		s = json.dumps(dd, indent=2, separators=(',', ': '))
-		fo.write("\n")
-		for i in s.split("\n"):
-			j = "// " + i
-			if len(j) > 72:
-				fo.write(j[:72] + "[...]\n")
-			else:
-				fo.write(j + "\n")
-		fo.write("\n")
-
-
-	def emit_h(self):
-		fon="VSC_" + self.name + ".h"
-		fo = open(fon, "w")
-		genhdr(fo, self.name)
-		fo.write(self.struct + " {\n")
-		for i in self.mbrs:
-			fo.write("\tuint64_t\t%s;\n" % i.arg)
-		fo.write("};\n")
-		fo.write("\n")
-
-		fo.write("#define VSC_" + self.name +
-		    "_size PRNDUP(sizeof(" + self.struct + "))\n\n")
-
-		fo.write(self.struct + " *VSC_" + self.name + "_New")
-		fo.write("(struct vsmw_cluster *,\n")
-		fo.write("    struct vsc_seg **, const char *fmt, ...);\n")
-
-		fo.write("void VSC_" + self.name + "_Destroy")
-		fo.write("(struct vsc_seg **);\n")
-
-		if 'sumfunction' in self.head.param:
-			fo.write("void VSC_" + self.name + "_Summ")
-			fo.write("(" + self.struct + " *, ")
-			fo.write("const " + self.struct + " *);\n")
-
-	def emit_c(self):
-		fon="VSC_" + self.name + ".c"
-		fo = open(fon, "w")
-		genhdr(fo, self.name)
-		fo.write('#include "config.h"\n')
-		fo.write('#include <stdio.h>\n')
-		fo.write('#include <stdarg.h>\n')
-		fo.write('#include "vdef.h"\n')
-		fo.write('#include "vas.h"\n')
-		fo.write('#include "vrt.h"\n')
-		fo.write('#include "VSC_%s.h"\n' % self.name)
-
-		fo.write("\n")
-		fo.write('static const char vsc_%s_name[] = "%s";\n' %
-		    (self.name, self.name.upper()))
-
-		fo.write("\n")
-		fo.write("#define PARANOIA(a,n)\t\t\t\t\\\n")
-		fo.write("    _Static_assert(\t\t\t\t\\\n")
-		fo.write("\toffsetof(" + self.struct + ", a) == n,\t\\\n")
-		fo.write("\t\"VSC element '\" #a \"' at wrong offset\")\n\n")
-
-		for i in self.mbrs:
-			fo.write("PARANOIA(" + i.arg)
-			fo.write(", %d);\n" % (i.param["index"]))
-
-		fo.write("#undef PARANOIA\n")
-
-		self.emit_json(fo)
-
-		fo.write("\n")
-		fo.write(self.struct + "*\n")
-		fo.write("VSC_" + self.name + "_New")
-		fo.write("(struct vsmw_cluster *vc,\n")
-		fo.write("    struct vsc_seg **sg, const char *fmt, ...)\n")
-		fo.write("{\n")
-		fo.write("\tva_list ap;\n")
-		fo.write("\t" + self.struct + " *retval;\n")
-		fo.write("\n")
-		fo.write("\tva_start(ap, fmt);\n")
-		fo.write("\tretval = VRT_VSC_Alloc")
-		fo.write("(vc, sg, vsc_" + self.name + "_name, ")
-		fo.write("VSC_" + self.name + "_size,\n")
-		fo.write("\t    vsc_" + self.name + "_json, ")
-		fo.write("sizeof vsc_" + self.name + "_json, fmt, ap);\n")
-		fo.write("\tva_end(ap);\n")
-		fo.write("\treturn(retval);\n")
-		fo.write("}\n")
-
-		fo.write("\n")
-		fo.write("void\n")
-		fo.write("VSC_" + self.name + "_Destroy")
-		fo.write("(struct vsc_seg **sg)\n")
-		fo.write("{\n")
-		fo.write("\tstruct vsc_seg *p;\n")
-		fo.write("\n")
-		fo.write("\tAN(sg);\n")
-		fo.write("\tp = *sg;\n")
-		fo.write("\t*sg = NULL;\n")
-		fo.write('\tVRT_VSC_Destroy(vsc_%s_name, p);\n' % self.name)
-		fo.write("}\n")
-
-		if 'sumfunction' in self.head.param:
-			fo.write("\n")
-			fo.write("void\n")
-			fo.write("VSC_" + self.name + "_Summ")
-			fo.write("(" + self.struct + " *dst, ")
-			fo.write("const " + self.struct + " *src)\n")
-			fo.write("{\n")
-			fo.write("\n")
-			fo.write("\tAN(dst);\n")
-			fo.write("\tAN(src);\n")
-			for i in self.mbrs:
-				s1 = "\tdst->" + i.arg + " +="
-				s2 = "src->" + i.arg + ";"
-				if len((s1 + " " + s2).expandtabs()) < 79:
-					fo.write(s1 + " " + s2 + "\n")
-				else:
-					fo.write(s1 + "\n\t    " + s2 + "\n")
-			fo.write("}\n")
+    fo.write('/*\n')
+    fo.write(' * NB:  This file is machine generated, DO NOT EDIT!\n')
+    fo.write(' *\n')
+    fo.write(' * Edit ' + name +
+             '.vsc and run lib/libvcc/vsctool.py instead.\n')
+    fo.write(' */\n')
+    fo.write('\n')
 
 #######################################################################
 
-class directive(object):
-	def __init__(self, s):
-		ll = s.split("\n")
-		i = ll.pop(0).split("::", 2)
-		self.cmd = i[0]
-		self.arg = i[1].strip()
-		assert len(self.arg.split()) == 1
-
-		self.param = {}
-		while len(ll):
-			j = ll[0].split(":",2)
-			if len(j) != 3 or not j[0].isspace():
-				break
-			self.param[j[1]] = j[2].strip()
-			ll.pop(0)
-		self.ldoc = ll
-
-	def getdoc(self):
-		while len(self.ldoc) and self.ldoc[0].strip() == "":
-			self.ldoc.pop(0)
-		while len(self.ldoc) and self.ldoc[-1].strip() == "":
-			self.ldoc.pop(-1)
-		return self.ldoc
-
-	def moredoc(self, s):
-		self.getdoc()
-		self.ldoc += s.split("\n")
-
-	def emit_rst(self, fo):
-		fo.write("\n.. " + self.cmd + ":: " + self.arg + "\n")
-		self.emit_rst_doc(fo)
-
-	def emit_rst_doc(self, fo):
-		fo.write("\n".join(self.ldoc))
-
-	def emit_h(self, fo):
-		return
-
-class rst_vsc_begin(directive):
-	def __init__(self, s):
-		super(rst_vsc_begin, self).__init__(s)
-
-	def vscset(self, ss):
-		ss.append(vscset(self.arg, self))
-
-	def emit_rst(self, fo):
-		fo.write("\n..\n\t" + self.cmd + ":: " + self.arg + "\n")
-
-		s = self.arg.upper() + " – " + self.param["oneliner"]
-		fo.write("\n")
-		fo.write(s + "\n")
-		fo.write("=" * len(s) + "\n")
-
-		self.emit_rst_doc(fo)
-
-class rst_vsc(directive):
-	def __init__(self, s):
-		super(rst_vsc, self).__init__(s)
-
-		for i,v in PARAMS.items():
-			if v is not True:
-				self.do_default(i, v[0], v[1])
-
-		for p in self.param:
-			if p in PARAMS:
-				continue
-			sys.stderr.write("Unknown parameter ")
-			sys.stderr.write("'" + p + "'")
-			sys.stderr.write(" on field '" + self.arg + "'\n")
-			exit(2)
-
-	def do_default(self, p, v, s):
-		if p not in self.param:
-			self.param[p] = v
-		if self.param[p] not in s:
-			sys.stderr.write("Wrong " + p + " '" + self.param[p])
-			sys.stderr.write("' on field '" + self.arg + "'\n")
-			exit(2)
-
-
-	def emit_rst(self, fo):
-		fo.write("\n``%s`` – " % self.arg)
-		fo.write("`%s` - " % self.param["type"])
-		fo.write("%s\n\n" % self.param["level"])
-
-		fo.write("\t" + self.param["oneliner"] + "\n")
-		self.emit_rst_doc(fo)
-
-	def vscset(self, ss):
-		ss[-1].addmbr(self)
-
-
-class rst_vsc_end(directive):
-	def __init__(self, s):
-		super(rst_vsc_end, self).__init__(s)
-
-	def vscset(self, ss):
-		ss[-1].complete()
-
-	def emit_rst(self, fo):
-		fo.write("\n..\n\t" + self.cmd + ":: " + self.arg + "\n")
-		self.emit_rst_doc(fo)
-
-class other(object):
-	def __init__(self, s):
-		self.s = s
-
-	def emit_rst(self, fo):
-		fo.write(self.s)
-
-	def emit_h(self, fo):
-		return
-
-	def vscset(self, ss):
-		return
+class CounterSet(object):
+
+    '''
+        A set of counters
+
+        In the `.vsc` file a CounterSet is everything between a
+
+            .. varnish_vsc_begin::
+
+        and the subsequent
+
+            .. varnish_vsc_end::
+    '''
+
+    def __init__(self, name, m):
+        self.name = name
+        self.struct = "struct VSC_" + name
+        self.mbrs = []
+        self.head = m
+        self.completed = False
+        self.off = 0
+
+    def addmbr(self, m):
+        '''Add a counter'''
+        assert not self.completed
+        self.mbrs.append(m)
+        retval = self.off
+        self.off += 8
+        return retval
+
+    def complete(self, arg):
+        '''Mark set completed'''
+        assert arg == self.name
+        self.completed = True
+
+    def emit_json(self, fo):
+        '''Emit JSON as compact C byte-array and as readable C-comments'''
+        assert self.completed
+        dd = collections.OrderedDict()
+        dd["version"] = "1"
+        dd["name"] = self.name
+        dd["oneliner"] = self.head.param["oneliner"].strip()
+        dd["order"] = int(self.head.param["order"])
+        dd["docs"] = "\n".join(self.head.getdoc())
+        dd["elements"] = len(self.mbrs)
+        el = collections.OrderedDict()
+        dd["elem"] = el
+        for i in self.mbrs:
+            ed = collections.OrderedDict()
+            el[i.arg] = ed
+            for j in PARAMS:
+                if j in i.param:
+                    ed[j] = i.param[j]
+            ed["index"] = i.param["index"]
+            ed["name"] = i.arg
+            ed["docs"] = "\n".join(i.getdoc())
+        s = json.dumps(dd, separators=(",", ":")) + "\0"
+        fo.write("\nstatic const unsigned char")
+        fo.write(" vsc_%s_json[%d] = {\n" % (self.name, len(s)))
+        bz = bytearray(s, encoding="ascii")
+        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")
+        s = json.dumps(dd, indent=2, separators=(',', ': '))
+        fo.write("\n")
+        for i in s.split("\n"):
+            j = "// " + i
+            if len(j) > 72:
+                fo.write(j[:72] + "[...]\n")
+            else:
+                fo.write(j + "\n")
+        fo.write("\n")
+
+    def emit_h(self):
+        '''Emit .h file'''
+        assert self.completed
+        fon = "VSC_" + self.name + ".h"
+        fo = open(fon, "w")
+        genhdr(fo, self.name)
+        fo.write(self.struct + " {\n")
+        for i in self.mbrs:
+            fo.write("\tuint64_t\t%s;\n" % i.arg)
+        fo.write("};\n")
+        fo.write("\n")
+
+        fo.write("#define VSC_" + self.name +
+                 "_size PRNDUP(sizeof(" + self.struct + "))\n\n")
+
+        fo.write(self.struct + " *VSC_" + self.name + "_New")
+        fo.write("(struct vsmw_cluster *,\n")
+        fo.write("    struct vsc_seg **, const char *fmt, ...);\n")
+
+        fo.write("void VSC_" + self.name + "_Destroy")
+        fo.write("(struct vsc_seg **);\n")
+
+        if 'sumfunction' in self.head.param:
+            fo.write("void VSC_" + self.name + "_Summ")
+            fo.write("(" + self.struct + " *, ")
+            fo.write("const " + self.struct + " *);\n")
+
+    def emit_c_paranoia(self, fo):
+        '''Emit asserts to make sure compiler gets same byte index'''
+        fo.write("#define PARANOIA(a,n)\t\t\t\t\\\n")
+        fo.write("    _Static_assert(\t\t\t\t\\\n")
+        fo.write("\toffsetof(" + self.struct + ", a) == n,\t\\\n")
+        fo.write("\t\"VSC element '\" #a \"' at wrong offset\")\n\n")
+
+        for i in self.mbrs:
+            fo.write("PARANOIA(" + i.arg)
+            fo.write(", %d);\n" % (i.param["index"]))
+
+        fo.write("#undef PARANOIA\n")
+
+    def emit_c_sumfunc(self, fo):
+        '''Emit a function summ up countersets'''
+        fo.write("\n")
+        fo.write("void\n")
+        fo.write("VSC_" + self.name + "_Summ")
+        fo.write("(" + self.struct + " *dst, ")
+        fo.write("const " + self.struct + " *src)\n")
+        fo.write("{\n")
+        fo.write("\n")
+        fo.write("\tAN(dst);\n")
+        fo.write("\tAN(src);\n")
+        for i in self.mbrs:
+            s1 = "\tdst->" + i.arg + " +="
+            s2 = "src->" + i.arg + ";"
+            if len((s1 + " " + s2).expandtabs()) < 79:
+                fo.write(s1 + " " + s2 + "\n")
+            else:
+                fo.write(s1 + "\n\t    " + s2 + "\n")
+        fo.write("}\n")
+
+    def emit_c_newfunc(self, fo):
+        '''Emit New function'''
+        fo.write("\n")
+        fo.write(self.struct + "*\n")
+        fo.write("VSC_" + self.name + "_New")
+        fo.write("(struct vsmw_cluster *vc,\n")
+        fo.write("    struct vsc_seg **sg, const char *fmt, ...)\n")
+        fo.write("{\n")
+        fo.write("\tva_list ap;\n")
+        fo.write("\t" + self.struct + " *retval;\n")
+        fo.write("\n")
+        fo.write("\tva_start(ap, fmt);\n")
+        fo.write("\tretval = VRT_VSC_Alloc")
+        fo.write("(vc, sg, vsc_" + self.name + "_name, ")
+        fo.write("VSC_" + self.name + "_size,\n")
+        fo.write("\t    vsc_" + self.name + "_json, ")
+        fo.write("sizeof vsc_" + self.name + "_json, fmt, ap);\n")
+        fo.write("\tva_end(ap);\n")
+        fo.write("\treturn(retval);\n")
+        fo.write("}\n")
+
+    def emit_c_destroyfunc(self, fo):
+        '''Emit Destroy function'''
+        fo.write("\n")
+        fo.write("void\n")
+        fo.write("VSC_" + self.name + "_Destroy")
+        fo.write("(struct vsc_seg **sg)\n")
+        fo.write("{\n")
+        fo.write("\tstruct vsc_seg *p;\n")
+        fo.write("\n")
+        fo.write("\tAN(sg);\n")
+        fo.write("\tp = *sg;\n")
+        fo.write("\t*sg = NULL;\n")
+        fo.write('\tVRT_VSC_Destroy(vsc_%s_name, p);\n' % self.name)
+        fo.write("}\n")
+
+    def emit_c(self):
+        '''Emit .c file'''
+        assert self.completed
+        fon = "VSC_" + self.name + ".c"
+        fo = open(fon, "w")
+        genhdr(fo, self.name)
+        fo.write('#include "config.h"\n')
+        fo.write('#include <stdio.h>\n')
+        fo.write('#include <stdarg.h>\n')
+        fo.write('#include "vdef.h"\n')
+        fo.write('#include "vas.h"\n')
+        fo.write('#include "vrt.h"\n')
+        fo.write('#include "VSC_%s.h"\n' % self.name)
+
+        fo.write("\n")
+        fo.write('static const char vsc_%s_name[] = "%s";\n' %
+                 (self.name, self.name.upper()))
+
+        fo.write("\n")
+
+        self.emit_c_paranoia(fo)
+        self.emit_json(fo)
+        self.emit_c_newfunc(fo)
+        self.emit_c_destroyfunc(fo)
+        if 'sumfunction' in self.head.param:
+            self.emit_c_sumfunc(fo)
 
 #######################################################################
 
-class vsc_file(object):
-	def __init__(self, fin):
-		self.c = []
-		scs = open(fin).read().split("\n.. ")
-		self.c.append(other(scs[0]))
-		ld = None
-		for i in scs[1:]:
-			j = i.split(None, 1)
-			f = {
-				"varnish_vsc_begin::":	rst_vsc_begin,
-				"varnish_vsc::":	rst_vsc,
-				"varnish_vsc_end::":	rst_vsc_end,
-			}.get(j[0])
-			if f is None:
-				s = "\n.. " + i
-				o = other(s)
-				if ld is not None:
-					ld.moredoc(s)
-			else:
-				o = f(i)
-				ld = o
-			self.c.append(o)
-
-		self.vscset = []
-		for i in self.c:
-			i.vscset(self.vscset)
-
-	def emit_h(self):
-		for i in self.vscset:
-			i.emit_h()
-
-	def emit_c(self):
-		for i in self.vscset:
-			i.emit_c()
-
-	def emit_rst(self):
-		fo = sys.stdout
-		for i in self.c:
-			i.emit_rst(fo)
+class OurDirective(object):
+
+    '''
+        One of our `.. blablabla::` directives in the source file
+    '''
+
+    def __init__(self, s):
+        ll = s.split("\n")
+        i = ll.pop(0).split("::", 2)
+        self.cmd = i[0]
+        self.arg = i[1].strip()
+        assert len(self.arg.split()) == 1
+
+        self.param = {}
+        while ll:
+            j = ll[0].split(":", 2)
+            if len(j) != 3 or not j[0].isspace():
+                break
+            self.param[j[1]] = j[2].strip()
+            ll.pop(0)
+        self.ldoc = ll
+
+    def getdoc(self):
+        '''
+        Get docs for JSON
+
+        Note that these docs end with the first '\n.. ' sequence
+        in the .vsc file, so that we can put a longer and more
+        complex description into the .RST docs than the "long"
+        explanation varnishstat(1) and similar programs provide.
+        '''
+        while self.ldoc and self.ldoc[0].strip() == "":
+            self.ldoc.pop(0)
+        while self.ldoc and self.ldoc[-1].strip() == "":
+            self.ldoc.pop(-1)
+        return self.ldoc
+
+    def emit_rst(self, fo):
+        '''Emit the documentation as .rst'''
+        assert False
+
+class RstVscDirectiveBegin(OurDirective):
+
+    '''
+        `varnish_vsc_begin` directive
+    '''
+
+    def __init__(self, s, vsc_set, fo):
+        super(RstVscDirectiveBegin, self).__init__(s)
+        vsc_set.append(CounterSet(self.arg, self))
+        if fo:
+            fo.write("\n..\n\t" + self.cmd + ":: " + self.arg + "\n")
+
+            s = self.arg.upper() + " – " + self.param["oneliner"]
+            fo.write("\n")
+            fo.write(s + "\n")
+            fo.write("=" * len(s) + "\n")
+            fo.write("\n".join(self.ldoc))
+
+class RstVscDirective(OurDirective):
+
+    '''
+        `varnish_vsc` directive - one counter
+    '''
+
+    def __init__(self, s, vsc_set, fo):
+        assert not vsc_set or vsc_set[-1].complete
+        super(RstVscDirective, self).__init__(s)
+
+        for i, v in PARAMS.items():
+            if v is not None:
+                if i not in self.param:
+                    self.param[i] = v[0]
+                if self.param[i] not in v:
+                    sys.stderr.write("Wrong " + i + " '" + self.param[i])
+                    sys.stderr.write("' on field '" + self.arg + "'\n")
+                    exit(2)
+
+        for p in self.param:
+            if p in PARAMS:
+                continue
+            sys.stderr.write("Unknown parameter ")
+            sys.stderr.write("'" + p + "'")
+            sys.stderr.write(" on field '" + self.arg + "'\n")
+            exit(2)
+        self.param["index"] = vsc_set[-1].addmbr(self)
+        if fo:
+            fo.write("\n``%s`` – " % self.arg)
+            fo.write("`%s` - " % self.param["type"])
+            fo.write("%s\n\n" % self.param["level"])
+
+            fo.write("\t" + self.param["oneliner"] + "\n")
+            fo.write("\n".join(self.ldoc))
+
+class RstVscDirectiveEnd(OurDirective):
+
+    '''
+        `varnish_vsc_end` directive
+    '''
+
+    def __init__(self, s, vsc_set, fo):
+        super(RstVscDirectiveEnd, self).__init__(s)
+        vsc_set[-1].complete(self.arg)
+        if fo:
+            fo.write("\n..\n\t" + self.cmd + ":: " + self.arg + "\n")
+            fo.write("\n".join(self.ldoc))
 
 #######################################################################
 
-if __name__ == "__main__":
-
-	optlist, args = getopt.getopt(sys.argv[1:], "chr")
+def mainfunc(argv):
+
+    '''Process a .vsc file'''
+
+    optlist, args = getopt.getopt(argv[1:], "chr")
+
+    if len(args) != 1:
+        sys.stderr.write("Need exactly one filename argument\n")
+        exit(2)
+
+    rstfile = None
+    for f, v in optlist:
+        if f == '-r':
+            rstfile = sys.stdout
+
+    vscset = []
+    scs = open(args[0]).read().split("\n.. ")
+    if rstfile:
+        rstfile.write(scs[0])
+    for i in scs[1:]:
+        j = i.split(None, 1)
+        f = {
+            "varnish_vsc_begin::":  RstVscDirectiveBegin,
+            "varnish_vsc::":        RstVscDirective,
+            "varnish_vsc_end::":    RstVscDirectiveEnd,
+        }.get(j[0])
+        if f is not None:
+            f(i, vscset, rstfile)
+        elif rstfile:
+            rstfile.write("\n.. " + i)
+
+    for i in vscset:
+        for f, v in optlist:
+            if f == '-h':
+                i.emit_h()
+            if f == '-c':
+                i.emit_c()
 
-	fo = sys.stdout
-
-	if len(args) != 1:
-		sys.stderr.write("Need exactly one filename argument\n")
-		exit(2)
+if __name__ == "__main__":
 
-	vf = vsc_file(args[0])
-	for f,v in optlist:
-		if f == '-r':
-			vf.emit_rst()
-		if f == '-h':
-			vf.emit_h()
-		if f == '-c':
-			vf.emit_c()
+    mainfunc(sys.argv)
diff --git a/tools/gcov_digest.py b/tools/gcov_digest.py
index 138f7e8cf..188fb499d 100644
--- a/tools/gcov_digest.py
+++ b/tools/gcov_digest.py
@@ -32,19 +32,19 @@ found in a subdirectory tree.
 
 Options:
 
-	-g gcov-program
-		default:gcov6
+    -g gcov-program
+        default:gcov6
 
-	-o output-filename
-		default: stdout
+    -o output-filename
+        default: stdout
 
-	-x exclude-subdir
-		default ".git" and ".deps"
+    -x exclude-subdir
+        default ".git" and ".deps"
 
  Arguments:
 
-	directories to process.
-	default: .
+    directories to process.
+    default: .
 
 """
 
@@ -61,141 +61,141 @@ lengths = {}
 exclude = [".git", ".deps",]
 
 def process_gcov(fn, sn):
-	""" Sum .gcov file into counts, then delete it """
-	dd = counts.get(sn)
-	if dd is None:
-		dd = {}
-	for ln in open(fn):
-		d = ln.split(":")
-		cnt = d[0].strip()
-		ll = d[1]
-		if cnt == "-":
-			continue
-		if cnt == "#####":
-			cnt = 0
-		else:
-			cnt = int(cnt)
-		lno = int(d[1])
-		if lno not in dd:
-			dd[lno] = 0
-		dd[lno] += cnt
-	counts[sn] = dd
-	pl = lengths.get(sn)
-	ll = ll.strip()
-	if d[2] == "/*EOF*/\n":
-		ll = pl
-	elif pl != ll and not pl is None:
-		print("CONFLICT", fn, ll, pl)
-		ll = "-1"
-	lengths[sn] = ll
-	os.remove(fn)
+    """ Sum .gcov file into counts, then delete it """
+    dd = counts.get(sn)
+    if dd is None:
+        dd = {}
+    for ln in open(fn):
+        d = ln.split(":")
+        cnt = d[0].strip()
+        ll = d[1]
+        if cnt == "-":
+            continue
+        if cnt == "#####":
+            cnt = 0
+        else:
+            cnt = int(cnt)
+        lno = int(d[1])
+        if lno not in dd:
+            dd[lno] = 0
+        dd[lno] += cnt
+    counts[sn] = dd
+    pl = lengths.get(sn)
+    ll = ll.strip()
+    if d[2] == "/*EOF*/\n":
+        ll = pl
+    elif pl != ll and not pl is None:
+        print("CONFLICT", fn, ll, pl)
+        ll = "-1"
+    lengths[sn] = ll
+    os.remove(fn)
 
 def run_gcov(prog, subdir):
-	""" Walk tree, run gcov, process output """
-	for root, dirs, files in os.walk(subdir):
-		for i in exclude:
-			if i in dirs:
-				dirs.remove(i)
-		if " ".join(files).find(".gcda") == -1:
-			continue
-		for fn in files:
-			if fn[-2:] != ".o":
-				continue
-
-			# if we find the .o file in a .../.libs the sources
-			# must be found relative to the parent directory
-
-			if root[-6:] == "/.libs":
-				x = subprocess.check_output(
-				    ["cd " + root + "/.. && " +
-				     "exec " + prog + " -r .libs/" + fn],
-				    stderr=subprocess.STDOUT, shell=True,
-				    universal_newlines=True)
-				pf = ".."
-			else:
-				x = subprocess.check_output(
-				    ["cd " + root + " && " +
-				     "exec " + prog + " -r " + fn],
-				    stderr=subprocess.STDOUT, shell=True,
-				    universal_newlines=True)
-				pf = ""
-
-			for ln in x.split("\n"):
-				ln = ln.split()
-				if len(ln) == 0:
-					continue
-				if ln[0] == "Creating":
-					gn = ln[1].strip("'")
-					assert gn[-5:] == ".gcov"
-					sn = gn[:-5]
-					process_gcov(
-					    os.path.join(root, pf, gn), sn)
+    """ Walk tree, run gcov, process output """
+    for root, dirs, files in os.walk(subdir):
+        for i in exclude:
+            if i in dirs:
+                dirs.remove(i)
+        if " ".join(files).find(".gcda") == -1:
+            continue
+        for fn in files:
+            if fn[-2:] != ".o":
+                continue
+
+            # if we find the .o file in a .../.libs the sources
+            # must be found relative to the parent directory
+
+            if root[-6:] == "/.libs":
+                x = subprocess.check_output(
+                    ["cd " + root + "/.. && " +
+                     "exec " + prog + " -r .libs/" + fn],
+                    stderr=subprocess.STDOUT, shell=True,
+                    universal_newlines=True)
+                pf = ".."
+            else:
+                x = subprocess.check_output(
+                    ["cd " + root + " && " +
+                     "exec " + prog + " -r " + fn],
+                    stderr=subprocess.STDOUT, shell=True,
+                    universal_newlines=True)
+                pf = ""
+
+            for ln in x.split("\n"):
+                ln = ln.split()
+                if not ln:
+                    continue
+                if ln[0] == "Creating":
+                    gn = ln[1].strip("'")
+                    assert gn[-5:] == ".gcov"
+                    sn = gn[:-5]
+                    process_gcov(
+                        os.path.join(root, pf, gn), sn)
 
 def produce_output(fdo):
-	"""
-	Produce compact output file
-
-	Format:
-		linefm [lineto] count
-
-		"+" in linefm means "previous line + 1"
-		"." in count means "same as previous count"
-	"""
-
-	for sn, cnt in counts.items():
-		fdo.write("/" + sn + " " + str(lengths[sn]) + "\n")
-		lnos = list(cnt.items())
-		lnos.sort()
-		pln = -1
-		pcn = -1
-		while len(lnos) > 0:
-			ln, cn = lnos.pop(0)
-			lnl = ln
-			while len(lnos) > 0:
-				lnn, cnn = lnos[0]
-				if lnl + 1 != lnn or cnn != cn:
-					break
-				lnos.pop(0)
-				lnl = lnn
-			if ln == pln + 1:
-				s = "+ "
-			else:
-				s = "%d " % ln
-
-			if ln != lnl:
-				s += "%d " % lnl
-				pln = lnl
-			else:
-				pln = ln
-
-			if cn == pcn:
-				s += "."
-			else:
-				s += "%d" % cn
-				pcn = cn
-			fdo.write(s + "\n")
+    """
+    Produce compact output file
+
+    Format:
+        linefm [lineto] count
+
+        "+" in linefm means "previous line + 1"
+        "." in count means "same as previous count"
+    """
+
+    for sn, cnt in counts.items():
+        fdo.write("/" + sn + " " + str(lengths[sn]) + "\n")
+        lnos = list(cnt.items())
+        lnos.sort()
+        pln = -1
+        pcn = -1
+        while lnos:
+            ln, cn = lnos.pop(0)
+            lnl = ln
+            while lnos:
+                lnn, cnn = lnos[0]
+                if lnl + 1 != lnn or cnn != cn:
+                    break
+                lnos.pop(0)
+                lnl = lnn
+            if ln == pln + 1:
+                s = "+ "
+            else:
+                s = "%d " % ln
+
+            if ln != lnl:
+                s += "%d " % lnl
+                pln = lnl
+            else:
+                pln = ln
+
+            if cn == pcn:
+                s += "."
+            else:
+                s += "%d" % cn
+                pcn = cn
+            fdo.write(s + "\n")
 
 if __name__ == "__main__":
 
-	optlist, args = getopt.getopt(sys.argv[1:], "g:o:x:")
-
-	fo = sys.stdout
-	gcovprog = "gcov6"
-
-	for f, v in optlist:
-		if f == '-o' and v == '-':
-			fo = sys.stdout
-		elif f == '-o':
-			fo = open(v, "w")
-		elif f == '-g':
-			gcovprog = v
-		elif f == '-x':
-			exclude.append(v)
-		else:
-			assert False
-	if len(args) == 0:
-		args = ["."]
-	for dn in args:
-		run_gcov(gcovprog, dn)
-
-	produce_output(fo)
+    optlist, args = getopt.getopt(sys.argv[1:], "g:o:x:")
+
+    fo = sys.stdout
+    gcovprog = "gcov6"
+
+    for f, v in optlist:
+        if f == '-o' and v == '-':
+            fo = sys.stdout
+        elif f == '-o':
+            fo = open(v, "w")
+        elif f == '-g':
+            gcovprog = v
+        elif f == '-x':
+            exclude.append(v)
+        else:
+            assert False
+    if not args:
+        args = ["."]
+    for dn in args:
+        run_gcov(gcovprog, dn)
+
+    produce_output(fo)
diff --git a/tools/include_wash.py b/tools/include_wash.py
index 1284e30e1..4df6eeaf3 100644
--- a/tools/include_wash.py
+++ b/tools/include_wash.py
@@ -5,41 +5,39 @@ from __future__ import print_function
 import os
 
 def check(fn):
-	l = []
-	for i in open(fn):
-		i = i.strip()
-		if len(i) == 0:
-			continue
-		if i[0] != "#":
-			continue
-		if i.find("include") == -1:
-			continue
-		if i.find('"') == -1:
-			l.append(i.split('<')[1].split('>')[0])
-		else:
-			l.append(i.split('"')[1])
-	if "vrt.h" in l:
-		vrt = l.index("vrt.h")
-		if not "vdef.h" in l:
-			print(fn, "vdef.h not included with vrt.h")
-		vdef = l.index("vdef.h")
-		if vdef > vrt:
-			print(fn, "vdef.h included after vrt.h")
-		for i in ("stddef.h", "stdint.h", "cache/cache.h", "cache.h"):
-			if i in l:
-				print(fn, i + " included with vrt.h")
+    l = []
+    for i in open(fn):
+        i = i.strip()
+        if not i:
+            continue
+        if i[0] != "#":
+            continue
+        if i.find("include") == -1:
+            continue
+        if i.find('"') == -1:
+            l.append(i.split('<')[1].split('>')[0])
+        else:
+            l.append(i.split('"')[1])
+    if "vrt.h" in l:
+        vrt = l.index("vrt.h")
+        if "vdef.h" not in l:
+            print(fn, "vdef.h not included with vrt.h")
+        vdef = l.index("vdef.h")
+        if vdef > vrt:
+            print(fn, "vdef.h included after vrt.h")
+        for i in ("stddef.h", "stdint.h", "cache/cache.h", "cache.h"):
+            if i in l:
+                print(fn, i + " included with vrt.h")
 
-	for i in ("cache/cache.h", "cache.h"):
-		if i in l:
-			for i in (
-			    "stddef.h", "stdint.h", "vrt.h",
-			    "math.h", "pthread.h", "stdarg.h", "sys/types.h",
-			    "vdef.h", "miniobj.h", "vas.h", "vqueue.h",
-			):
-				if i in l:
-					print(fn, i + " included with cache.h")
+    for i in ("cache/cache.h", "cache.h"):
+        if i in l:
+            for i in ("stddef.h", "stdint.h", "vrt.h",
+                      "math.h", "pthread.h", "stdarg.h", "sys/types.h",
+                      "vdef.h", "miniobj.h", "vas.h", "vqueue.h"):
+                if i in l:
+                    print(fn, i + " included with cache.h")
 
 for (dir, dns, fns) in os.walk("."):
-	for f in fns:
-		if f[-2:] == ".c":
-			check(dir + "/" + f)
+    for f in fns:
+        if f[-2:] == ".c":
+            check(dir + "/" + f)


More information about the varnish-commit mailing list