aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPetteri Aimonen <jpa@git.mail.kapsi.fi>2020-11-25 09:36:01 +0200
committerPetteri Aimonen <jpa@git.mail.kapsi.fi>2020-11-25 13:06:33 +0200
commit2db67de2e8e0385ed3c2c838b9ec156b3c42c4e2 (patch)
treec40e36af12c0fbe414ff30e085f9ea9ff293ff08
parentf96d99fe55d60a0601c949f78a306de68a28f33b (diff)
downloadnanopb-c-2db67de2e8e0385ed3c2c838b9ec156b3c42c4e2.tar.gz
Fix unsigned enums not working correctly inside OneOf (#611)
Fixed also a few smaller issues where generator didn't consider fields inside oneof for field name mangling.
-rwxr-xr-xgenerator/nanopb_generator.py15
-rw-r--r--tests/regression/issue_611/SConscript8
-rw-r--r--tests/regression/issue_611/uenum.expected3
-rw-r--r--tests/regression/issue_611/uenum.proto28
4 files changed, 51 insertions, 3 deletions
diff --git a/generator/nanopb_generator.py b/generator/nanopb_generator.py
index 0d0a112..e1add38 100755
--- a/generator/nanopb_generator.py
+++ b/generator/nanopb_generator.py
@@ -1010,6 +1010,15 @@ class Message:
result += default + '\n'
return result
+ def all_fields(self):
+ '''Iterate over all fields in this message, including nested OneOfs.'''
+ for f in self.fields:
+ if isinstance(f, OneOf):
+ for f2 in f.fields:
+ yield f2
+ else:
+ yield f
+
def count_required_fields(self):
'''Returns number of required fields inside this message'''
count = 0
@@ -1220,7 +1229,7 @@ class ProtoFile:
for enum in other.enums:
if not enum.options.long_names:
for message in self.messages:
- for field in message.fields:
+ for field in message.all_fields():
if field.default in enum.value_longnames:
idx = enum.value_longnames.index(field.default)
field.default = enum.values[idx][0]
@@ -1229,7 +1238,7 @@ class ProtoFile:
for enum in other.enums:
if not enum.has_negative():
for message in self.messages:
- for field in message.fields:
+ for field in message.all_fields():
if field.pbtype == 'ENUM' and field.ctype == enum.names:
field.pbtype = 'UENUM'
@@ -1458,7 +1467,7 @@ class ProtoFile:
# Add check for sizeof(double)
has_double = False
for msg in self.messages:
- for field in msg.fields:
+ for field in msg.all_fields():
if field.ctype == 'double':
has_double = True
diff --git a/tests/regression/issue_611/SConscript b/tests/regression/issue_611/SConscript
new file mode 100644
index 0000000..6295107
--- /dev/null
+++ b/tests/regression/issue_611/SConscript
@@ -0,0 +1,8 @@
+# Regression test for #611:
+# Enum messages inside OneOf generated as ENUM instead of UENUM
+
+Import("env")
+
+env.NanopbProto("uenum.proto")
+env.Match(["uenum.pb.c", "uenum.expected"])
+env.Object("uenum.pb.c")
diff --git a/tests/regression/issue_611/uenum.expected b/tests/regression/issue_611/uenum.expected
new file mode 100644
index 0000000..0806f24
--- /dev/null
+++ b/tests/regression/issue_611/uenum.expected
@@ -0,0 +1,3 @@
+[^U]ENUM.*ONEOF.*MyEnum
+UENUM.*ONEOF.*MyUEnum
+
diff --git a/tests/regression/issue_611/uenum.proto b/tests/regression/issue_611/uenum.proto
new file mode 100644
index 0000000..f6df218
--- /dev/null
+++ b/tests/regression/issue_611/uenum.proto
@@ -0,0 +1,28 @@
+syntax = "proto2";
+
+enum my_enum {
+ E0 = 0;
+ E240 = 240;
+ E1 = -1;
+}
+
+enum my_uenum {
+ U0 = 0;
+ U240 = 240;
+}
+
+message my_message_regular {
+ required my_enum MyEnum = 1;
+ required my_uenum MyUEnum = 2;
+}
+
+message my_message_oneof {
+ required uint32 Data1 = 1;
+ oneof Data {
+ bool null = 2;
+ my_enum MyEnum = 3;
+ my_uenum MyUEnum = 4;
+ }
+}
+
+