diff options
author | Petteri Aimonen <jpa@git.mail.kapsi.fi> | 2015-09-12 13:04:22 +0300 |
---|---|---|
committer | Petteri Aimonen <jpa@git.mail.kapsi.fi> | 2015-09-12 13:07:34 +0300 |
commit | 708084e7883a95dd7fd315cdc909f6664491c043 (patch) | |
tree | c6ec5ffa5478dd2913ee875f7cdde74cb8b9fed8 | |
parent | 1582038e37771ade214f0627c3ecbf6e1ba69946 (diff) |
Fix handling of unsigned 8- or 16-bit enums.
Previously unsigned enums would throw errors on decoding if the value
went outside the signed range (issue #164).
Currently only helps for enums defined within the same file, but solving
issue #165 will make it work for multiple files also.
-rwxr-xr-x | generator/nanopb_generator.py | 17 | ||||
-rw-r--r-- | pb.h | 3 |
2 files changed, 18 insertions, 2 deletions
diff --git a/generator/nanopb_generator.py b/generator/nanopb_generator.py index aaa0d2f1..2b1d63e5 100755 --- a/generator/nanopb_generator.py +++ b/generator/nanopb_generator.py @@ -162,6 +162,12 @@ class Enum: self.value_longnames = [self.names + x.name for x in desc.value] self.packed = enum_options.packed_enum + def has_negative(self): + for n, v in self.values: + if v < 0: + return True + return False + def __str__(self): result = 'typedef enum _%s {\n' % self.names result += ',\n'.join([" %s = %d" % x for x in self.values]) @@ -342,7 +348,7 @@ class Field: inner_init = '""' elif self.pbtype == 'BYTES': inner_init = '{0, {0}}' - elif self.pbtype == 'ENUM': + elif self.pbtype in ('ENUM', 'UENUM'): inner_init = '(%s)0' % self.ctype else: inner_init = '0' @@ -600,6 +606,7 @@ class OneOf(Field): self.struct_name = struct_name self.name = oneof_desc.name self.ctype = 'union' + self.pbtype = 'oneof' self.fields = [] self.allocation = 'ONEOF' self.default = None @@ -891,6 +898,14 @@ def parse_file(fdesc, file_options): idx = enum.value_longnames.index(field.default) field.default = enum.values[idx][0] + # Fix field data types where enums have negative values. + for enum in enums: + if not enum.has_negative(): + for message in messages: + for field in message.fields: + if field.pbtype == 'ENUM' and field.ctype == enum.names: + field.pbtype = 'UENUM' + return enums, messages, extensions def toposort2(data): @@ -468,6 +468,7 @@ struct pb_extension_s { #define PB_LTYPE_MAP_BYTES PB_LTYPE_BYTES #define PB_LTYPE_MAP_DOUBLE PB_LTYPE_FIXED64 #define PB_LTYPE_MAP_ENUM PB_LTYPE_VARINT +#define PB_LTYPE_MAP_UENUM PB_LTYPE_UVARINT #define PB_LTYPE_MAP_FIXED32 PB_LTYPE_FIXED32 #define PB_LTYPE_MAP_FIXED64 PB_LTYPE_FIXED64 #define PB_LTYPE_MAP_FLOAT PB_LTYPE_FIXED32 @@ -486,7 +487,7 @@ struct pb_extension_s { /* This is the actual macro used in field descriptions. * It takes these arguments: * - Field tag number - * - Field type: BOOL, BYTES, DOUBLE, ENUM, FIXED32, FIXED64, + * - Field type: BOOL, BYTES, DOUBLE, ENUM, UENUM, FIXED32, FIXED64, * FLOAT, INT32, INT64, MESSAGE, SFIXED32, SFIXED64 * SINT32, SINT64, STRING, UINT32, UINT64 or EXTENSION * - Field rules: REQUIRED, OPTIONAL or REPEATED |