mirror of
https://github.com/lightning/bolts.git
synced 2024-11-19 01:50:03 +01:00
tools: Update formatting of python tools
This commit is contained in:
parent
22544d7789
commit
d67a28227c
@ -1,19 +1,20 @@
|
|||||||
#! /usr/bin/python3
|
#! /usr/bin/python3
|
||||||
# Simple script to parse specs and produce CSV files.
|
# Simple script to parse specs and produce CSV files.
|
||||||
# Released by Rusty Russell under CC0: https://creativecommons.org/publicdomain/zero/1.0/
|
# Released by Rusty Russell under CC0:
|
||||||
|
# https://creativecommons.org/publicdomain/zero/1.0/
|
||||||
|
|
||||||
from optparse import OptionParser
|
from optparse import OptionParser
|
||||||
import sys
|
import sys
|
||||||
import re
|
import re
|
||||||
import fileinput
|
import fileinput
|
||||||
|
|
||||||
# Figure out if we can determine type from size.
|
|
||||||
def guess_alignment(message,name,sizestr):
|
|
||||||
|
|
||||||
|
# Figure out if we can determine type from size.
|
||||||
|
def guess_alignment(message, name, sizestr):
|
||||||
# Exceptions:
|
# Exceptions:
|
||||||
# - Padding has no alignment requirements.
|
# - Padding has no alignment requirements.
|
||||||
# - channel-id is size 8, but has alignment 4.
|
# - channel-id is size 8, but has alignment 4.
|
||||||
# - node_announcement.ipv6 has size 16, but alignment 4 (to align IPv4 addr).
|
# - node_announcement.ipv6 has size 16, but alignment 4 (to align IPv4).
|
||||||
# - node_announcement.alias is a string, so alignment 1
|
# - node_announcement.alias is a string, so alignment 1
|
||||||
# - signatures have no alignment requirement.
|
# - signatures have no alignment requirement.
|
||||||
if name.startswith('pad'):
|
if name.startswith('pad'):
|
||||||
@ -29,7 +30,7 @@ def guess_alignment(message,name,sizestr):
|
|||||||
return 1
|
return 1
|
||||||
|
|
||||||
if 'signature' in name:
|
if 'signature' in name:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
# Size can be variable.
|
# Size can be variable.
|
||||||
try:
|
try:
|
||||||
@ -51,6 +52,7 @@ def guess_alignment(message,name,sizestr):
|
|||||||
|
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
def main(options, args=None, output=sys.stdout, lines=None):
|
def main(options, args=None, output=sys.stdout, lines=None):
|
||||||
# Example inputs:
|
# Example inputs:
|
||||||
# 1. type: 17 (`error`)
|
# 1. type: 17 (`error`)
|
||||||
@ -62,23 +64,28 @@ def main(options, args=None, output=sys.stdout, lines=None):
|
|||||||
# 1. type: PERM|NODE|3 (`required_node_feature_missing`)
|
# 1. type: PERM|NODE|3 (`required_node_feature_missing`)
|
||||||
message = None
|
message = None
|
||||||
havedata = None
|
havedata = None
|
||||||
typeline = re.compile('1\. type: (?P<value>[-0-9A-Za-z_|]+) \(`(?P<name>[A-Za-z_]+)`\)')
|
typeline = re.compile(
|
||||||
dataline = re.compile('\s+\* \[`(?P<size>[_a-z0-9*+]+)`:`(?P<name>[_a-z0-9]+)`\]')
|
'1\. type: (?P<value>[-0-9A-Za-z_|]+) \(`(?P<name>[A-Za-z_]+)`\)')
|
||||||
|
dataline = re.compile(
|
||||||
|
'\s+\* \[`(?P<size>[_a-z0-9*+]+)`:`(?P<name>[_a-z0-9]+)`\]')
|
||||||
|
|
||||||
if lines is None:
|
if lines is None:
|
||||||
lines = fileinput.input(args)
|
lines = fileinput.input(args)
|
||||||
|
|
||||||
for i,line in enumerate(lines):
|
for i, line in enumerate(lines):
|
||||||
line = line.rstrip()
|
line = line.rstrip()
|
||||||
linenum = i+1
|
linenum = i+1
|
||||||
|
|
||||||
match = typeline.fullmatch(line)
|
match = typeline.fullmatch(line)
|
||||||
if match:
|
if match:
|
||||||
if message is not None:
|
if message is not None:
|
||||||
raise ValueError('{}:Found a message while I was already in a message'.format(linenum))
|
raise ValueError('{}:Found a message while I was already in a '
|
||||||
|
'message'.format(linenum))
|
||||||
message = match.group('name')
|
message = match.group('name')
|
||||||
if options.output_types:
|
if options.output_types:
|
||||||
print("{},{}".format(match.group('name'), match.group('value')), file=output)
|
print("{},{}".format(
|
||||||
|
match.group('name'),
|
||||||
|
match.group('value')), file=output)
|
||||||
havedata = None
|
havedata = None
|
||||||
alignoff = False
|
alignoff = False
|
||||||
elif message is not None and havedata is None:
|
elif message is not None and havedata is None:
|
||||||
@ -87,11 +94,11 @@ def main(options, args=None, output=sys.stdout, lines=None):
|
|||||||
havedata = True
|
havedata = True
|
||||||
dataoff = 0
|
dataoff = 0
|
||||||
off_extraterms = ""
|
off_extraterms = ""
|
||||||
maxalign = 1
|
|
||||||
elif message is not None and havedata is not None:
|
elif message is not None and havedata is not None:
|
||||||
match = dataline.fullmatch(line)
|
match = dataline.fullmatch(line)
|
||||||
if match:
|
if match:
|
||||||
align = guess_alignment(message, match.group('name'), match.group('size'))
|
align = guess_alignment(message, match.group('name'),
|
||||||
|
match.group('size'))
|
||||||
|
|
||||||
# Do not check alignment if we previously had a variable
|
# Do not check alignment if we previously had a variable
|
||||||
# length field in the message
|
# length field in the message
|
||||||
@ -99,10 +106,21 @@ def main(options, args=None, output=sys.stdout, lines=None):
|
|||||||
alignoff = True
|
alignoff = True
|
||||||
|
|
||||||
if not alignoff and options.check_alignment and dataoff % align != 0:
|
if not alignoff and options.check_alignment and dataoff % align != 0:
|
||||||
raise ValueError('{}:message {} field {} Offset {} not aligned on {} boundary:'.format(linenum, message, match.group('name'), dataoff, align))
|
raise ValueError('{}:message {} field {} Offset {} not '
|
||||||
|
'aligned on {} boundary:'.format(
|
||||||
|
linenum,
|
||||||
|
message,
|
||||||
|
match.group('name'),
|
||||||
|
dataoff,
|
||||||
|
align))
|
||||||
|
|
||||||
if options.output_fields:
|
if options.output_fields:
|
||||||
print("{},{}{},{},{}".format(message,dataoff,off_extraterms,match.group('name'),match.group('size')), file=output)
|
print("{},{}{},{},{}".format(
|
||||||
|
message,
|
||||||
|
dataoff,
|
||||||
|
off_extraterms,
|
||||||
|
match.group('name'),
|
||||||
|
match.group('size')), file=output)
|
||||||
|
|
||||||
# Size can be variable.
|
# Size can be variable.
|
||||||
try:
|
try:
|
||||||
@ -113,17 +131,30 @@ def main(options, args=None, output=sys.stdout, lines=None):
|
|||||||
else:
|
else:
|
||||||
message = None
|
message = None
|
||||||
|
|
||||||
if __name__=="__main__":
|
|
||||||
|
if __name__ == "__main__":
|
||||||
parser = OptionParser()
|
parser = OptionParser()
|
||||||
parser.add_option("--message-types",
|
parser.add_option(
|
||||||
action="store_true", dest="output_types", default=False,
|
"--message-types",
|
||||||
help="Output MESSAGENAME,VALUE for every message")
|
action="store_true",
|
||||||
parser.add_option("--check-alignment",
|
dest="output_types",
|
||||||
action="store_true", dest="check_alignment", default=False,
|
default=False,
|
||||||
help="Check alignment for every member of each message")
|
help="Output MESSAGENAME,VALUE for every message"
|
||||||
parser.add_option("--message-fields",
|
)
|
||||||
action="store_true", dest="output_fields", default=False,
|
parser.add_option(
|
||||||
help="Output MESSAGENAME,OFFSET,FIELDNAME,SIZE for every message")
|
"--check-alignment",
|
||||||
|
action="store_true",
|
||||||
|
dest="check_alignment",
|
||||||
|
default=False,
|
||||||
|
help="Check alignment for every member of each message"
|
||||||
|
)
|
||||||
|
parser.add_option(
|
||||||
|
"--message-fields",
|
||||||
|
action="store_true",
|
||||||
|
dest="output_fields",
|
||||||
|
default=False,
|
||||||
|
help="Output MESSAGENAME,OFFSET,FIELDNAME,SIZE for every message"
|
||||||
|
)
|
||||||
|
|
||||||
(options, args) = parser.parse_args()
|
(options, args) = parser.parse_args()
|
||||||
|
|
||||||
|
@ -1,24 +1,28 @@
|
|||||||
formats = __import__("extract-formats")
|
|
||||||
from io import StringIO
|
from io import StringIO
|
||||||
import glob
|
import glob
|
||||||
import collections
|
import collections
|
||||||
import json
|
import json
|
||||||
|
|
||||||
|
formats = __import__("extract-formats")
|
||||||
|
|
||||||
|
|
||||||
class Options(object):
|
class Options(object):
|
||||||
output_types = True
|
output_types = True
|
||||||
output_fields = True
|
output_fields = True
|
||||||
check_alignment = False
|
check_alignment = False
|
||||||
|
|
||||||
|
|
||||||
options = Options()
|
options = Options()
|
||||||
csv = []
|
csv = []
|
||||||
|
|
||||||
output = StringIO()
|
output = StringIO()
|
||||||
for i in sorted(glob.glob("../??-*.md")):
|
for i in sorted(glob.glob("../??-*.md")):
|
||||||
with open(i) as f:
|
with open(i) as f:
|
||||||
formats.main(options, output=output, lines=f.readlines())
|
formats.main(options, output=output, lines=f.readlines())
|
||||||
csvstr = output.getvalue().strip()
|
csvstr = output.getvalue().strip()
|
||||||
if csvstr == "": continue
|
if csvstr == "":
|
||||||
csv += csvstr.split("\n")
|
continue
|
||||||
|
csv += csvstr.split("\n")
|
||||||
|
|
||||||
resmap = collections.OrderedDict()
|
resmap = collections.OrderedDict()
|
||||||
|
|
||||||
@ -26,20 +30,21 @@ currentmsgname = None
|
|||||||
currentmsgfields = {}
|
currentmsgfields = {}
|
||||||
typenum = None
|
typenum = None
|
||||||
for line in csv:
|
for line in csv:
|
||||||
parts = line.split(",")
|
parts = line.split(",")
|
||||||
if len(parts) == 2:
|
if len(parts) == 2:
|
||||||
if currentmsgname is not None:
|
if currentmsgname is not None:
|
||||||
resmap[currentmsgname] = collections.OrderedDict([("type", typenum), ("payload", currentmsgfields)])
|
resmap[currentmsgname] = collections.OrderedDict(
|
||||||
currentmsgfields = collections.OrderedDict()
|
[("type", typenum), ("payload", currentmsgfields)])
|
||||||
currentmsgname = parts[0]
|
currentmsgfields = collections.OrderedDict()
|
||||||
typenum = parts[1]
|
currentmsgname = parts[0]
|
||||||
continue
|
typenum = parts[1]
|
||||||
assert currentmsgname == parts[0], line
|
continue
|
||||||
assert len(parts) == 4, line
|
assert currentmsgname == parts[0], line
|
||||||
position = parts[1]
|
assert len(parts) == 4, line
|
||||||
length = parts[3]
|
position = parts[1]
|
||||||
fieldname = parts[2]
|
length = parts[3]
|
||||||
currentmsgfields[fieldname] = {"position": position, "length": length}
|
fieldname = parts[2]
|
||||||
|
currentmsgfields[fieldname] = {"position": position, "length": length}
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
print(json.dumps(resmap, indent=True))
|
print(json.dumps(resmap, indent=True))
|
||||||
|
Loading…
Reference in New Issue
Block a user