X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=generator%2Fnanopb_generator.py;h=973c7610fbea38337b9792838d0efc2f2987c5dc;hb=68a86e96481e6bea987df8de47027847b30c325b;hp=3c1f4341fea85defda13aaafa3538f58f58ecce4;hpb=4507b0066c1a75c4f85d8d595a2236d0c84cb312;p=apps%2Fagl-service-can-low-level.git diff --git a/generator/nanopb_generator.py b/generator/nanopb_generator.py index 3c1f4341..973c7610 100755 --- a/generator/nanopb_generator.py +++ b/generator/nanopb_generator.py @@ -3,7 +3,7 @@ from __future__ import unicode_literals '''Generate header file for nanopb from a ProtoBuf FileDescriptorSet.''' -nanopb_version = "nanopb-0.3.5-dev" +nanopb_version = "nanopb-0.3.7-dev" import sys import re @@ -197,6 +197,10 @@ class Enum: result += ' %s;' % self.names + result += '\n#define _%s_MIN %s' % (self.names, self.values[0][0]) + result += '\n#define _%s_MAX %s' % (self.names, self.values[-1][0]) + result += '\n#define _%s_ARRAYSIZE ((%s)(%s+1))' % (self.names, self.names, self.values[-1][0]) + if not self.options.long_names: # Define the long names always so that enum value references # from other files work properly. @@ -213,7 +217,7 @@ class FieldMaxSize: self.worst = worst self.worst_field = field_name - self.checks = checks + self.checks = list(checks) def extend(self, extend, field_name = None): self.worst = max(self.worst, extend.worst) @@ -237,6 +241,11 @@ class Field: self.enc_size = None self.ctype = None + self.inline = None + if field_options.type == nanopb_pb2.FT_INLINE: + field_options.type = nanopb_pb2.FT_STATIC + self.inline = nanopb_pb2.FT_INLINE + # Parse field options if field_options.HasField("max_size"): self.max_size = field_options.max_size @@ -315,7 +324,12 @@ class Field: elif desc.type == FieldD.TYPE_BYTES: self.pbtype = 'BYTES' if self.allocation == 'STATIC': - self.ctype = self.struct_name + self.name + 't' + # Inline STATIC for BYTES is like STATIC for STRING. + if self.inline: + self.ctype = 'pb_byte_t' + self.array_decl += '[%d]' % self.max_size + else: + self.ctype = self.struct_name + self.name + 't' self.enc_size = varint_max_size(self.max_size) + self.max_size elif self.allocation == 'POINTER': self.ctype = 'pb_bytes_array_t' @@ -355,7 +369,7 @@ class Field: 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' and not self.inline: result = 'typedef PB_BYTES_ARRAY_T(%d) %s;\n' % (self.max_size, self.ctype) else: result = '' @@ -384,7 +398,10 @@ class Field: if self.pbtype == 'STRING': inner_init = '""' elif self.pbtype == 'BYTES': - inner_init = '{0, {0}}' + if self.inline: + inner_init = '{0}' + else: + inner_init = '{0, {0}}' elif self.pbtype in ('ENUM', 'UENUM'): inner_init = '(%s)0' % self.ctype else: @@ -396,9 +413,15 @@ class Field: elif self.pbtype == 'BYTES': data = ['0x%02x' % ord(c) for c in self.default] if len(data) == 0: - inner_init = '{0, {0}}' + if self.inline: + inner_init = '{0}' + else: + inner_init = '{0, {0}}' else: - inner_init = '{%d, {%s}}' % (len(data), ','.join(data)) + if self.inline: + inner_init = '{%s}' % ','.join(data) + else: + inner_init = '{%d, {%s}}' % (len(data), ','.join(data)) elif self.pbtype in ['FIXED32', 'UINT32']: inner_init = str(self.default) + 'u' elif self.pbtype in ['FIXED64', 'UINT64']: @@ -450,6 +473,8 @@ class Field: elif self.pbtype == 'BYTES': if self.allocation != 'STATIC': return None # Not implemented + if self.inline: + array_decl = '[%d]' % self.max_size if declaration_only: return 'extern const %s %s_default%s;' % (ctype, self.struct_name + self.name, array_decl) @@ -477,7 +502,7 @@ class Field: result += '%3d, ' % self.tag result += '%-8s, ' % self.pbtype result += '%s, ' % self.rules - result += '%-8s, ' % self.allocation + result += '%-8s, ' % (self.allocation if not self.inline else "INLINE") result += '%s, ' % ("FIRST" if not prev_field_name else "OTHER") result += '%s, ' % self.struct_name result += '%s, ' % self.name @@ -590,6 +615,7 @@ class ExtensionRange(Field): self.default = None self.max_size = 0 self.max_count = 0 + self.inline = None def __str__(self): return ' pb_extension_t *extensions;' @@ -667,6 +693,7 @@ class OneOf(Field): self.default = None self.rules = 'ONEOF' self.anonymous = False + self.inline = None def add_field(self, field): if field.allocation == 'CALLBACK': @@ -1041,7 +1068,10 @@ class ProtoFile: else: yield '/* Generated by %s at %s. */\n\n' % (nanopb_version, time.asctime()) - symbol = make_identifier(headername) + if self.fdesc.package: + symbol = make_identifier(self.fdesc.package + '_' + headername) + else: + symbol = make_identifier(headername) yield '#ifndef PB_%s_INCLUDED\n' % symbol yield '#define PB_%s_INCLUDED\n' % symbol try: @@ -1055,7 +1085,7 @@ class ProtoFile: noext = os.path.splitext(incfile)[0] yield options.genformat % (noext + options.extension + '.h') yield '\n' - + yield '/* @@protoc_insertion_point(includes) */\n' yield '#if PB_PROTO_HEADER_VERSION != 30\n' @@ -1115,9 +1145,11 @@ class ProtoFile: yield '/* Maximum encoded size of messages (where known) */\n' for msg in self.messages: msize = msg.encoded_size(self.dependencies) + identifier = '%s_size' % msg.name if msize is not None: - identifier = '%s_size' % msg.name yield '#define %-40s %s\n' % (identifier, msize) + else: + yield '/* %s depends on runtime parameters */\n' % identifier yield '\n' yield '/* Message IDs (where set with "msgid" option) */\n' @@ -1363,6 +1395,9 @@ optparser.add_option("-f", "--options-file", dest="options_file", metavar="FILE" optparser.add_option("-I", "--options-path", dest="options_path", metavar="DIR", action="append", default = [], help="Search for .options files additionally in this path") +optparser.add_option("-D", "--output-dir", dest="output_dir", + metavar="OUTPUTDIR", default=None, + help="Output directory of .pb.h and .pb.c files") optparser.add_option("-Q", "--generated-include-format", dest="genformat", metavar="FORMAT", default='#include "%s"\n', help="Set format string to use for including other .pb.h files. [default: %default]") @@ -1479,17 +1514,29 @@ def main_cli(): if options.quiet: options.verbose = False - Globals.verbose_options = options.verbose + if options.output_dir and not os.path.exists(options.output_dir): + optparser.print_help() + sys.stderr.write("\noutput_dir does not exist: %s\n" % options.output_dir) + sys.exit(1) + + Globals.verbose_options = options.verbose for filename in filenames: results = process_file(filename, None, options) + base_dir = options.output_dir or '' + to_write = [ + (os.path.join(base_dir, results['headername']), results['headerdata']), + (os.path.join(base_dir, results['sourcename']), results['sourcedata']), + ] + if not options.quiet: - sys.stderr.write("Writing to " + results['headername'] + " and " - + results['sourcename'] + "\n") + paths = " and ".join([x[0] for x in to_write]) + sys.stderr.write("Writing to %s\n" % paths) - open(results['headername'], 'w').write(results['headerdata']) - open(results['sourcename'], 'w').write(results['sourcedata']) + for path, data in to_write: + with open(path, 'w') as f: + f.write(data) def main_plugin(): '''Main function when invoked as a protoc plugin.''' @@ -1553,4 +1600,3 @@ if __name__ == '__main__': main_plugin() else: main_cli() -