X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;ds=sidebyside;f=generator%2Fnanopb_generator.py;h=82602908233ebdff8a4e18a12a923f5dbf93d8ed;hb=5c16a116ec2db9d19e42c5682cbfbf4f2b87ad87;hp=2a9ae00842740b39c5579fcd816eb1226200cf2e;hpb=77a71ceb6d8da3995c72bf8cb0656254c77deb8d;p=apps%2Fagl-service-can-low-level.git diff --git a/generator/nanopb_generator.py b/generator/nanopb_generator.py index 2a9ae008..82602908 100755 --- a/generator/nanopb_generator.py +++ b/generator/nanopb_generator.py @@ -1,7 +1,7 @@ #!/usr/bin/python '''Generate header file for nanopb from a ProtoBuf FileDescriptorSet.''' -nanopb_version = "nanopb-0.3.2-dev" +nanopb_version = "nanopb-0.3.3-dev" import sys @@ -582,15 +582,19 @@ class ExtensionField(Field): # --------------------------------------------------------------------------- class OneOf(Field): - def __init__(self, oneof_desc): + def __init__(self, struct_name, oneof_desc): + self.struct_name = struct_name self.name = oneof_desc.name self.ctype = 'union' self.fields = [] + self.allocation = 'ONEOF' + self.default = None + self.rules = 'ONEOF' def add_field(self, field): if field.allocation == 'CALLBACK': raise Exception("Callback fields inside of oneof are not supported" - + " (field %s)" % field.fullname) + + " (field %s)" % field.name) field.union_name = self.name field.rules = 'ONEOF' @@ -632,7 +636,6 @@ class OneOf(Field): return '\n'.join([f.tags() for f in self.fields]) def pb_field_t(self, prev_field_name): - prev_field_name = prev_field_name or self.name result = ',\n'.join([f.pb_field_t(prev_field_name) for f in self.fields]) return result @@ -640,7 +643,17 @@ class OneOf(Field): return max([f.largest_field_value() for f in self.fields]) def encoded_size(self, allmsgs): - return max([f.encoded_size(allmsgs) for f in self.fields]) + largest = EncodedSize(0) + for f in self.fields: + size = f.encoded_size(allmsgs) + if size is None: + return None + elif size.symbols: + return None # Cannot resolve maximum of symbols + elif size.value > largest.value: + largest = size + + return largest # --------------------------------------------------------------------------- # Generation of messages (structures) @@ -651,13 +664,20 @@ class Message: def __init__(self, names, desc, message_options): self.name = names self.fields = [] - self.oneofs = [] + self.oneofs = {} + no_unions = [] if hasattr(desc, 'oneof_decl'): - for f in desc.oneof_decl: - oneof = OneOf(f) - self.oneofs.append(oneof) - self.fields.append(oneof) + for i, f in enumerate(desc.oneof_decl): + oneof_options = get_nanopb_suboptions(desc, message_options, self.name + f.name) + if oneof_options.no_unions: + no_unions.append(i) # No union, but add fields normally + elif oneof_options.type == nanopb_pb2.FT_IGNORE: + pass # No union and skip fields also + else: + oneof = OneOf(self.name, f) + self.oneofs[i] = oneof + self.fields.append(oneof) for f in desc.field: field_options = get_nanopb_suboptions(f, message_options, self.name + f.name) @@ -665,8 +685,11 @@ class Message: continue field = Field(self.name, f, field_options) - if hasattr(f, 'oneof_index') and f.HasField('oneof_index'): - self.oneofs[f.oneof_index].add_field(field) + if (hasattr(f, 'oneof_index') and + f.HasField('oneof_index') and + f.oneof_index not in no_unions): + if f.oneof_index in self.oneofs: + self.oneofs[f.oneof_index].add_field(field) else: self.fields.append(field) @@ -733,7 +756,7 @@ class Message: '''Returns number of required fields inside this message''' count = 0 for f in self.fields: - if f not in self.oneofs: + if not isinstance(f, OneOf): if f.rules == 'REQUIRED': count += 1 return count @@ -741,7 +764,7 @@ class Message: def count_all_fields(self): count = 0 for f in self.fields: - if f in self.oneofs: + if isinstance(f, OneOf): count += len(f.fields) else: count += 1 @@ -1103,14 +1126,28 @@ def read_options_file(infile): [(namemask, options), ...] ''' results = [] - for line in infile: + for i, line in enumerate(infile): line = line.strip() if not line or line.startswith('//') or line.startswith('#'): continue parts = line.split(None, 1) + + if len(parts) < 2: + sys.stderr.write("%s:%d: " % (infile.name, i + 1) + + "Option lines should have space between field name and options. " + + "Skipping line: '%s'\n" % line) + continue + opts = nanopb_pb2.NanoPBOptions() - text_format.Merge(parts[1], opts) + + try: + text_format.Merge(parts[1], opts) + except Exception, e: + sys.stderr.write("%s:%d: " % (infile.name, i + 1) + + "Unparseable option line: '%s'. " % line + + "Error: %s\n" % str(e)) + continue results.append((parts[0], opts)) return results