mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-21 16:14:23 +01:00
tools/generate-wire.py: support for optional fields, with ? before typename.
We already work around this by using an array with a 0/1 length convention, but better to be explicit. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
Christian Decker
parent
070aa08709
commit
ac4c6b1a82
@@ -115,9 +115,14 @@ class Field(object):
|
|||||||
self.is_len_var = False
|
self.is_len_var = False
|
||||||
self.lenvar = None
|
self.lenvar = None
|
||||||
self.num_elems = 1
|
self.num_elems = 1
|
||||||
|
self.optional = False
|
||||||
|
|
||||||
|
# ? means optional field (not supported for arrays)
|
||||||
|
if size.startswith('?'):
|
||||||
|
self.optional = True
|
||||||
|
size = size[1:]
|
||||||
# If it's an arraysize, swallow prefix.
|
# If it's an arraysize, swallow prefix.
|
||||||
if '*' in size:
|
elif '*' in size:
|
||||||
number = size.split('*')[0]
|
number = size.split('*')[0]
|
||||||
if number == prevname:
|
if number == prevname:
|
||||||
self.lenvar = number
|
self.lenvar = number
|
||||||
@@ -164,8 +169,14 @@ class Field(object):
|
|||||||
def is_variable_size(self):
|
def is_variable_size(self):
|
||||||
return self.lenvar is not None
|
return self.lenvar is not None
|
||||||
|
|
||||||
|
def needs_ptr_to_ptr(self):
|
||||||
|
return self.is_variable_size() or self.optional
|
||||||
|
|
||||||
|
def is_optional(self):
|
||||||
|
return self.optional
|
||||||
|
|
||||||
def is_assignable(self):
|
def is_assignable(self):
|
||||||
if self.is_array() or self.is_variable_size():
|
if self.is_array() or self.needs_ptr_to_ptr():
|
||||||
return False
|
return False
|
||||||
return self.fieldtype.is_assignable()
|
return self.fieldtype.is_assignable()
|
||||||
|
|
||||||
@@ -248,13 +259,16 @@ class Message(object):
|
|||||||
self.has_variable_fields = False
|
self.has_variable_fields = False
|
||||||
|
|
||||||
def checkLenField(self, field):
|
def checkLenField(self, field):
|
||||||
|
# Optional fields don't have a len.
|
||||||
|
if field.is_optional():
|
||||||
|
return
|
||||||
for f in self.fields:
|
for f in self.fields:
|
||||||
if f.name == field.lenvar:
|
if f.name == field.lenvar:
|
||||||
if f.fieldtype.name != 'u16':
|
if f.fieldtype.name != 'u16':
|
||||||
raise ValueError('Field {} has non-u16 length variable {} (type {})'
|
raise ValueError('Field {} has non-u16 length variable {} (type {})'
|
||||||
.format(field.name, field.lenvar, f.fieldtype.name))
|
.format(field.name, field.lenvar, f.fieldtype.name))
|
||||||
|
|
||||||
if f.is_array() or f.is_variable_size():
|
if f.is_array() or f.needs_ptr_to_ptr():
|
||||||
raise ValueError('Field {} has non-simple length variable {}'
|
raise ValueError('Field {} has non-simple length variable {}'
|
||||||
.format(field.name, field.lenvar))
|
.format(field.name, field.lenvar))
|
||||||
f.is_len_var = True
|
f.is_len_var = True
|
||||||
@@ -271,6 +285,8 @@ class Message(object):
|
|||||||
self.has_variable_fields = True
|
self.has_variable_fields = True
|
||||||
elif field.basetype() in varlen_structs:
|
elif field.basetype() in varlen_structs:
|
||||||
self.has_variable_fields = True
|
self.has_variable_fields = True
|
||||||
|
elif field.is_optional():
|
||||||
|
self.has_variable_fields = True
|
||||||
self.fields.append(field)
|
self.fields.append(field)
|
||||||
|
|
||||||
def print_fromwire_array(self, subcalls, basetype, f, name, num_elems):
|
def print_fromwire_array(self, subcalls, basetype, f, name, num_elems):
|
||||||
@@ -303,7 +319,7 @@ class Message(object):
|
|||||||
else:
|
else:
|
||||||
ptrs = '*'
|
ptrs = '*'
|
||||||
# If we're handing a variable array, we need a ptr-to-ptr.
|
# If we're handing a variable array, we need a ptr-to-ptr.
|
||||||
if f.is_variable_size():
|
if f.needs_ptr_to_ptr():
|
||||||
ptrs += '*'
|
ptrs += '*'
|
||||||
# If each type is a variable length, we need a ptr to that.
|
# If each type is a variable length, we need a ptr to that.
|
||||||
if f.basetype() in varlen_structs:
|
if f.basetype() in varlen_structs:
|
||||||
@@ -338,6 +354,16 @@ class Message(object):
|
|||||||
|
|
||||||
self.print_fromwire_array(subcalls, basetype, f, '*' + f.name,
|
self.print_fromwire_array(subcalls, basetype, f, '*' + f.name,
|
||||||
f.lenvar)
|
f.lenvar)
|
||||||
|
else:
|
||||||
|
if f.is_optional():
|
||||||
|
subcalls.append("\tif (!fromwire_bool(&cursor, &plen))\n"
|
||||||
|
"\t\t*{} = NULL;\n"
|
||||||
|
"\telse {{\n"
|
||||||
|
"\t\t*{} = tal(ctx, {});\n"
|
||||||
|
"\t\tfromwire_{}(&cursor, &plen, *{});\n"
|
||||||
|
"\t}}"
|
||||||
|
.format(f.name, f.name, f.fieldtype.name,
|
||||||
|
basetype, f.name))
|
||||||
elif f.is_assignable():
|
elif f.is_assignable():
|
||||||
subcalls.append("\t//3th case {name}".format(name=f.name))
|
subcalls.append("\t//3th case {name}".format(name=f.name))
|
||||||
if f.is_len_var:
|
if f.is_len_var:
|
||||||
@@ -416,6 +442,14 @@ class Message(object):
|
|||||||
self.print_towire_array(subcalls, basetype, f, f.num_elems)
|
self.print_towire_array(subcalls, basetype, f, f.num_elems)
|
||||||
elif f.is_variable_size():
|
elif f.is_variable_size():
|
||||||
self.print_towire_array(subcalls, basetype, f, f.lenvar)
|
self.print_towire_array(subcalls, basetype, f, f.lenvar)
|
||||||
|
else:
|
||||||
|
if f.is_optional():
|
||||||
|
subcalls.append("\tif (!{})\n"
|
||||||
|
"\t\ttowire_bool(&p, false);\n"
|
||||||
|
"\telse {{\n"
|
||||||
|
"\t\ttowire_bool(&p, true);\n"
|
||||||
|
"\t\ttowire_{}(&p, {});\n"
|
||||||
|
"\t}}".format(f.name, basetype, f.name))
|
||||||
else:
|
else:
|
||||||
subcalls.append('\ttowire_{}(&p, {});'
|
subcalls.append('\ttowire_{}(&p, {});'
|
||||||
.format(basetype, f.name))
|
.format(basetype, f.name))
|
||||||
@@ -490,20 +524,29 @@ class Message(object):
|
|||||||
self.print_printwire_array(subcalls, basetype, f, f.lenvar)
|
self.print_printwire_array(subcalls, basetype, f, f.lenvar)
|
||||||
self.add_truncate_check(subcalls)
|
self.add_truncate_check(subcalls)
|
||||||
else:
|
else:
|
||||||
|
indent = '\t'
|
||||||
|
if f.is_optional():
|
||||||
|
subcalls.append("\tif (fromwire_bool(&cursor, &plen)) {")
|
||||||
|
indent += '\t'
|
||||||
|
|
||||||
if f.is_assignable():
|
if f.is_assignable():
|
||||||
subcalls.append('\t{} {} = fromwire_{}(&cursor, &plen);'
|
subcalls.append(indent + '{} {} = fromwire_{}(&cursor, &plen);'
|
||||||
.format(f.fieldtype.name, f.name, basetype))
|
.format(f.fieldtype.name, f.name, basetype))
|
||||||
else:
|
else:
|
||||||
# Don't handle these yet.
|
# Don't handle these yet.
|
||||||
assert(basetype not in varlen_structs)
|
assert(basetype not in varlen_structs)
|
||||||
subcalls.append('\t{} {};'.
|
subcalls.append(indent + '{} {};'.
|
||||||
format(f.fieldtype.name, f.name))
|
format(f.fieldtype.name, f.name))
|
||||||
subcalls.append('\tfromwire_{}(&cursor, &plen, &{});'
|
subcalls.append(indent + 'fromwire_{}(&cursor, &plen, &{});'
|
||||||
.format(basetype, f.name))
|
.format(basetype, f.name))
|
||||||
|
|
||||||
self.add_truncate_check(subcalls)
|
self.add_truncate_check(subcalls, indent=indent)
|
||||||
subcalls.append('\tprintwire_{}(tal_fmt(NULL, "%s.{}", fieldname), &{});'
|
subcalls.append(indent + 'printwire_{}(tal_fmt(NULL, "%s.{}", fieldname), &{});'
|
||||||
.format(basetype, f.name, f.name))
|
.format(basetype, f.name, f.name))
|
||||||
|
if f.is_optional():
|
||||||
|
subcalls.append("\t} else {")
|
||||||
|
self.add_truncate_check(subcalls, indent='\t\t')
|
||||||
|
subcalls.append("\t}")
|
||||||
|
|
||||||
return template.format(
|
return template.format(
|
||||||
name=self.name,
|
name=self.name,
|
||||||
|
|||||||
Reference in New Issue
Block a user