Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

tools: update CSV generator to output fields for tlv's and subtypes #597

Closed
wants to merge 5 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 71 additions & 21 deletions tools/extract-formats.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,30 @@ def main(options, args=None, output=sys.stdout, lines=None):
# * [`8`:`channel_id`]
# * [`4`:`len`]
# * [`len`:`data`] (optionXXX)
# * [`2`:`num_inputs`]
# * [`num_inputs*input_info`]
#
# 1. type: PERM|NODE|3 (`required_node_feature_missing`)
#
# 1. tlv: `tlv_name`
# 2. types:
# 1. type: 1 (`tlv_option_one`)
# 2. data:
# * [`2`:`option_one_len`]
# * [`option_one_len`:`option_one`]
#
# 1. subtype: `input_info`
# 2. data:
# * [`8`:`satoshis`]
# * [`32`:`prevtx_txid`]
message = None
havedata = None
tlv = None
tlv_msg_count = 0
typeline = re.compile(
'1\. type: (?P<value>[-0-9A-Za-z_|]+) \(`(?P<name>[A-Za-z_]+)`\)( \(`?(?P<option>[^)`]*)`?\))?')
'(?P<leading>\s*)1\. (?P<type>((sub)*?type|tlv)):( (?P<value>[-0-9A-Za-z_|]+))? \(?`(?P<name>[A-Za-z2_]+)`\)?( \(`?(?P<option>[^)`]*)`?\))?')
dataline = re.compile(
'\s+\* \[`(?P<size>[_a-z0-9*+]+)`:`(?P<name>[_a-z0-9]+)`\]( \(`?(?P<option>[^)`]*)`?\))?')
'\s+\* \[`((?P<size>[_a-z0-9*+]+)`:`(?P<name>[_a-z0-9]+)|(?P<count>[_a-z0-9+]+)(?P<multi>\*)(?P<subtype>[_a-z0-9]+))`\]( \(`?(?P<option>[^)`]*)`?\))?')

if lines is None:
lines = fileinput.input(args)
Expand All @@ -34,42 +50,76 @@ def main(options, args=None, output=sys.stdout, lines=None):

match = typeline.fullmatch(line)
if match:
if message is not None:
if match.group('type') == 'tlv':
if tlv:
raise ValueError('{}:Found a tlv while I was already in a tlv'
.format(linenum))
tlv = match.group('name')
tlv_msg_count = 0
continue

if message and not tlv:
raise ValueError('{}:Found a message while I was already in a '
'message'.format(linenum))

message = match.group('name')
if tlv is not None and len(match.group('leading')) == 0:
tlv = None
if options.output_types:
print("{},{}".format(
match.group('name'),
match.group('value')), file=output)
if tlv:
print("{},{},{}".format(
match.group('name'),
match.group('value'),
tlv), file=output)
else:
print("{},{}".format(
match.group('name'),
str(match.group('value') or '$')), file=output)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think subtypes should just be a single field, ie. no value. Rather than a double field with a magic '$' sign?

havedata = None
if tlv:
tlv_msg_count += 1
elif tlv and tlv_msg_count == 0:
if line != '2. types:':
tlv = None
elif message is not None and havedata is None:
if line != '2. data:':
if line.lstrip() != '2. data:':
message = None
havedata = True
dataoff = 0
off_extraterms = ""
prev_field = ""
elif message is not None and havedata is not None:
match = dataline.fullmatch(line)
if match:
if options.output_fields:
print("{},{}{},{},{}".format(
if match.group('multi'):
print("{},{}{},{},${}".format(
message,
dataoff,
off_extraterms,
match.group('name'),
match.group('size')), file=output, end='')
if match.group('option'):
print(",{}".format(match.group('option')), file=output)
else:
print('', file=output)
match.group('subtype'),
prev_field))
off_extraterms += "+$"
prev_field = match.group('subtype')
else:
if options.output_fields:
print("{},{}{},{},{}".format(
message,
dataoff,
off_extraterms,
match.group('name'),
match.group('size')), file=output, end='')
if match.group('option'):
print(",{}".format(match.group('option')), file=output)
else:
print('', file=output)

# Size can be variable.
try:
dataoff += int(match.group('size'))
except ValueError:
# Offset has variable component.
off_extraterms = off_extraterms + "+" + match.group('size')
prev_field = match.group('name')
# Size can be variable.
try:
dataoff += int(match.group('size'))
except ValueError:
# Offset has variable component.
off_extraterms = off_extraterms + "+" + match.group('size')
else:
message = None

Expand Down