Add fallback_type option (#772, #773)
This option sets the type used by FT_DEFAULT when static allocation is not possible.
Co-authored-by: Conrad Wood <cnw@singingcat.net>
diff --git a/generator/nanopb_generator.py b/generator/nanopb_generator.py
index 8ebab21..902b884 100755
--- a/generator/nanopb_generator.py
+++ b/generator/nanopb_generator.py
@@ -488,7 +488,7 @@
self.callback_datatype = field_options.callback_datatype
self.math_include_required = False
self.sort_by_tag = field_options.sort_by_tag
-
+
if field_options.type == nanopb_pb2.FT_INLINE:
# Before nanopb-0.3.8, fixed length bytes arrays were specified
# by setting type to FT_INLINE. But to handle pointer typed fields,
@@ -554,7 +554,7 @@
if can_be_static:
field_options.type = nanopb_pb2.FT_STATIC
else:
- field_options.type = nanopb_pb2.FT_CALLBACK
+ field_options.type = field_options.fallback_type
if field_options.type == nanopb_pb2.FT_STATIC and not can_be_static:
raise Exception("Field '%s' is defined as static, but max_size or "
diff --git a/generator/proto/nanopb.proto b/generator/proto/nanopb.proto
index 88ac2f6..b79267c 100644
--- a/generator/proto/nanopb.proto
+++ b/generator/proto/nanopb.proto
@@ -147,6 +147,12 @@
// instead of the order in .proto. Set this to false to keep the .proto order.
// The default value will probably change to false in nanopb-0.5.0.
optional bool sort_by_tag = 28 [default = true];
+
+ // this affects the FT_DEFAULT (the default) field conversion strategy. A field
+ // that can become a static member of a c struct (e.g. int, bool, etc) will be a
+ // a static field. Fields with dynamic length are converted, to either a pointer or a callback.
+ // this defines wether it becomes a pointer or a callback.
+ optional FieldType fallback_type = 29 [default = FT_CALLBACK];
}
// Extensions to protoc 'Descriptor' type in order to define options
diff --git a/tests/fallback_type/SConscript b/tests/fallback_type/SConscript
new file mode 100644
index 0000000..22a7b1e
--- /dev/null
+++ b/tests/fallback_type/SConscript
@@ -0,0 +1,11 @@
+# Test fallback type
+
+Import("env")
+# the scons version on ubuntu honours this env - debians version does not
+# env['NANOPB_GENERATOR'] = env['NANOPB_GENERATOR'] + "-sfallback_type:FT_POINTER"
+# env.SetDefault(PROTOCFLAGS = "--plugin=protoc-gen-nanopb=foo")
+
+# so we also use an options file:
+env.NanopbProto(["fallback_type","fallback_type.options"])
+env.Object("fallback_type.pb.c")
+env.Match(['fallback_type.pb.h', 'fallback_type.expected'])
diff --git a/tests/fallback_type/fallback_type.expected b/tests/fallback_type/fallback_type.expected
new file mode 100644
index 0000000..3eff62b
--- /dev/null
+++ b/tests/fallback_type/fallback_type.expected
@@ -0,0 +1,2 @@
+int32_t member1;
+char \*member2
diff --git a/tests/fallback_type/fallback_type.options b/tests/fallback_type/fallback_type.options
new file mode 100644
index 0000000..29eddfa
--- /dev/null
+++ b/tests/fallback_type/fallback_type.options
@@ -0,0 +1 @@
+fallback_type.proto fallback_type:FT_POINTER
\ No newline at end of file
diff --git a/tests/fallback_type/fallback_type.proto b/tests/fallback_type/fallback_type.proto
new file mode 100644
index 0000000..97d069b
--- /dev/null
+++ b/tests/fallback_type/fallback_type.proto
@@ -0,0 +1,8 @@
+syntax = "proto2";
+
+message Message1
+{
+ required int32 member1 = 1; // must remain as int
+ required string member2 = 2; // must become a pointer
+}
+