diff options
Diffstat (limited to 'generator/nanopb_generator.py')
-rwxr-xr-x | generator/nanopb_generator.py | 62 |
1 files changed, 44 insertions, 18 deletions
diff --git a/generator/nanopb_generator.py b/generator/nanopb_generator.py index 468c0d2e..69548ad6 100755 --- a/generator/nanopb_generator.py +++ b/generator/nanopb_generator.py @@ -200,19 +200,27 @@ class Field: self.enc_size = 5 # protoc rejects enum values > 32 bits elif desc.type == FieldD.TYPE_STRING: self.pbtype = 'STRING' - if self.max_size is None: - can_be_static = False - else: + if field_options.type == nanopb_pb2.FT_POINTER: self.ctype = 'char' - self.array_decl += '[%d]' % self.max_size - self.enc_size = varint_max_size(self.max_size) + self.max_size + self.enc_size = None + else: + if self.max_size is None: + can_be_static = False + else: + self.ctype = 'char' + self.array_decl += '[%d]' % self.max_size + self.enc_size = varint_max_size(self.max_size) + self.max_size elif desc.type == FieldD.TYPE_BYTES: self.pbtype = 'BYTES' - if self.max_size is None: - can_be_static = False - else: + if field_options.type == nanopb_pb2.FT_POINTER: self.ctype = self.struct_name + self.name + 't' - self.enc_size = varint_max_size(self.max_size) + self.max_size + self.enc_size = None + else: + if self.max_size is None: + can_be_static = False + else: + self.ctype = self.struct_name + self.name + 't' + self.enc_size = varint_max_size(self.max_size) + self.max_size elif desc.type == FieldD.TYPE_MESSAGE: self.pbtype = 'MESSAGE' self.ctype = self.submsgname = names_from_type_name(desc.type_name) @@ -231,6 +239,8 @@ class Field: if field_options.type == nanopb_pb2.FT_STATIC: self.allocation = 'STATIC' + elif field_options.type == nanopb_pb2.FT_POINTER: + self.allocation = 'POINTER' elif field_options.type == nanopb_pb2.FT_CALLBACK: self.allocation = 'CALLBACK' self.ctype = 'pb_callback_t' @@ -242,21 +252,37 @@ class Field: return cmp(self.tag, other.tag) def __str__(self): - if self.rules == 'OPTIONAL' and self.allocation == 'STATIC': - result = ' bool has_' + self.name + ';\n' - elif self.rules == 'REPEATED' and self.allocation == 'STATIC': - result = ' size_t ' + self.name + '_count;\n' + result = '' + if self.allocation == 'POINTER': + if self.rules == 'REPEATED': + result += ' size_t ' + self.name + '_count;\n' + + # Use struct definition, so recursive submessages are possible + if self.pbtype == 'MESSAGE': + result += ' struct _%s *%s;' % (self.ctype, self.name) + + # String arrays need to be defined as pointers to pointers + elif self.rules == 'REPEATED' and self.pbtype == 'STRING': + result += ' %s **%s;' % (self.ctype, self.name) + else: + result += ' %s *%s;' % (self.ctype, self.name) else: - result = '' - result += ' %s %s%s;' % (self.ctype, self.name, self.array_decl) + if self.rules == 'OPTIONAL' and self.allocation == 'STATIC': + result += ' bool has_' + self.name + ';\n' + elif self.rules == 'REPEATED' and self.allocation == 'STATIC': + result += ' size_t ' + self.name + '_count;\n' + result += ' %s %s%s;' % (self.ctype, self.name, self.array_decl) return result def types(self): '''Return definitions for any special types this field might need.''' - if self.pbtype == 'BYTES' and self.allocation == 'STATIC': + if self.pbtype == 'BYTES' and (self.allocation == 'STATIC' or self.allocation == 'POINTER'): result = 'typedef struct {\n' result += ' size_t size;\n' - result += ' uint8_t bytes[%d];\n' % self.max_size + if self.allocation == 'POINTER': + result += ' uint8_t *bytes;\n' + else: + result += ' uint8_t bytes[%d];\n' % self.max_size result += '} %s;\n' % self.ctype else: result = None @@ -303,7 +329,7 @@ class Field: result = ' PB_FIELD2(%3d, ' % self.tag result += '%-8s, ' % self.pbtype result += '%s, ' % self.rules - result += '%s, ' % self.allocation + result += '%-8s, ' % self.allocation result += '%s, ' % ("FIRST" if not prev_field_name else "OTHER") result += '%s, ' % self.struct_name result += '%s, ' % self.name |