summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetteri Aimonen <jpa@git.mail.kapsi.fi>2015-09-12 13:04:22 +0300
committerPetteri Aimonen <jpa@git.mail.kapsi.fi>2015-09-12 13:07:34 +0300
commit708084e7883a95dd7fd315cdc909f6664491c043 (patch)
treec6ec5ffa5478dd2913ee875f7cdde74cb8b9fed8
parent1582038e37771ade214f0627c3ecbf6e1ba69946 (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-xgenerator/nanopb_generator.py17
-rw-r--r--pb.h3
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):
diff --git a/pb.h b/pb.h
index 649a25e9..ef2a166f 100644
--- a/pb.h
+++ b/pb.h
@@ -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