Fix compilation error with fixed size array and FT_POINTER (#630)

Wrong order of conditions in generator caused the fixed size constraint
to be ignored in data type declaration. Fixed and added unit test coverage.
diff --git a/generator/nanopb_generator.py b/generator/nanopb_generator.py
index fbedb86..5a94746 100755
--- a/generator/nanopb_generator.py
+++ b/generator/nanopb_generator.py
@@ -716,16 +716,20 @@
                     result += '    pb_callback_t cb_' + var_name + ';\n'
                 result += '    pb_size_t ' + var_name + '_count;\n'
 
-            if self.pbtype in ['MESSAGE', 'MSG_W_CB']:
-                # Use struct definition, so recursive submessages are possible
-                result += '    struct %s *%s;' % (Globals.naming_style.struct_name(self.ctype), var_name)
+            if self.rules == 'FIXARRAY' and self.pbtype in ['STRING', 'BYTES']:
+                # Pointer to fixed size array of pointers
+                result += '    %s* (*%s)%s;' % (type_name, var_name, self.array_decl)
             elif self.pbtype == 'FIXED_LENGTH_BYTES' or self.rules == 'FIXARRAY':
-                # Pointer to fixed size array
+                # Pointer to fixed size array of items
                 result += '    %s (*%s)%s;' % (type_name, var_name, self.array_decl)
-            elif self.rules in ['REPEATED', 'FIXARRAY'] and self.pbtype in ['STRING', 'BYTES']:
+            elif self.rules == 'REPEATED' and self.pbtype in ['STRING', 'BYTES']:
                 # String/bytes arrays need to be defined as pointers to pointers
                 result += '    %s **%s;' % (type_name, var_name)
+            elif self.pbtype in ['MESSAGE', 'MSG_W_CB']:
+                # Use struct definition, so recursive submessages are possible
+                result += '    struct %s *%s;' % (Globals.naming_style.struct_name(self.ctype), var_name)
             else:
+                # Normal case, just a pointer to single item
                 result += '    %s *%s;' % (type_name, var_name)
         elif self.allocation == 'CALLBACK':
             result += '    %s %s;' % (self.callback_datatype, var_name)
@@ -758,6 +762,8 @@
         '''Get list of type names used by this field.'''
         if self.allocation == 'STATIC':
             return [str(self.ctype)]
+        elif self.allocation == 'POINTER' and self.rules == 'FIXARRAY':
+            return [str(self.ctype)]
         else:
             return []
 
diff --git a/tests/fixed_count/SConscript b/tests/fixed_count/SConscript
index 3cecb12..31380ad 100644
--- a/tests/fixed_count/SConscript
+++ b/tests/fixed_count/SConscript
@@ -1,14 +1,15 @@
 # Test that fixed count option works.
 
-Import("env")
+Import("malloc_env")
 
-env.NanopbProto("fixed_count")
-env.Object("fixed_count.pb.c")
+malloc_env.NanopbProto("fixed_count")
+malloc_env.Object("fixed_count.pb.c")
 
-p = env.Program(["fixed_count_unittests.c",
+p = malloc_env.Program(["fixed_count_unittests.c",
                  "fixed_count.pb.c",
-                 "$COMMON/pb_encode.o",
-                 "$COMMON/pb_decode.o",
-                 "$COMMON/pb_common.o"])
+                 "$COMMON/pb_encode_with_malloc.o",
+                 "$COMMON/pb_decode_with_malloc.o",
+                 "$COMMON/pb_common_with_malloc.o",
+                 "$COMMON/malloc_wrappers.o"])
 
-env.RunTest(p)
+malloc_env.RunTest(p)
diff --git a/tests/fixed_count/fixed_count.proto b/tests/fixed_count/fixed_count.proto
index e96d1ec..29fadd2 100644
--- a/tests/fixed_count/fixed_count.proto
+++ b/tests/fixed_count/fixed_count.proto
@@ -19,3 +19,12 @@
     repeated Message2 data1 = 1 [(nanopb).max_count = 2, (nanopb).fixed_count = true];
     repeated Message2 data2 = 2 [(nanopb).max_count = 2, (nanopb).fixed_count = true];
 }
+
+message SubMessage {
+  required int32 a = 1;
+}
+
+message Message4 {
+  repeated SubMessage submsgs = 1 [(nanopb).type = FT_POINTER, (nanopb).max_count = 5, (nanopb).fixed_count = true];
+  repeated string strings = 2 [(nanopb).type = FT_POINTER, (nanopb).max_count = 4, (nanopb).fixed_count = true];
+}
diff --git a/tests/fixed_count/fixed_count_unittests.c b/tests/fixed_count/fixed_count_unittests.c
index b039c9b..f1c7c51 100644
--- a/tests/fixed_count/fixed_count_unittests.c
+++ b/tests/fixed_count/fixed_count_unittests.c
@@ -2,6 +2,7 @@
 #include <string.h>
 #include <pb_decode.h>
 #include <pb_encode.h>
+#include <malloc_wrappers.h>
 #include "unittests.h"
 #include "fixed_count.pb.h"
 
@@ -134,6 +135,54 @@
       TEST(memcmp(&msg_b, &msg_a, sizeof(msg_a)) == 0);
     }
 
+    {
+      pb_byte_t buffer[256];
+      Message4 msg_a = Message4_init_zero;
+      Message4 msg_b = Message4_init_zero;
+
+      pb_ostream_t ostream;
+      pb_istream_t istream;
+      size_t message_length;
+
+      COMMENT("Test encode and decode with pointer type fixarray");
+
+      SubMessage submsgs[pb_arraysize(Message4, submsgs[0])] = {SubMessage_init_zero};
+      submsgs[0].a = 1;
+      submsgs[1].a = 5;
+      submsgs[2].a = 999;
+
+      char a[5] = "a";
+      char b[5] = "b";
+      char abc[5] = "abc";
+      char *strings[pb_arraysize(Message4, strings[0])] = {a, b, abc};
+
+      msg_a.submsgs = &submsgs;
+      msg_a.strings = &strings;
+
+      ostream = pb_ostream_from_buffer(buffer, Message3_size);
+      TEST(pb_encode(&ostream, Message4_fields, &msg_a));
+      message_length = ostream.bytes_written;
+
+      TEST(get_alloc_count() == 0);
+
+      istream = pb_istream_from_buffer(buffer, message_length);
+      TEST(pb_decode(&istream, Message4_fields, &msg_b));
+
+      TEST(istream.bytes_left == 0);
+
+      TEST((*msg_b.submsgs)[0].a == 1);
+      TEST((*msg_b.submsgs)[1].a == 5);
+      TEST((*msg_b.submsgs)[2].a == 999);
+
+      TEST(strcmp((*msg_b.strings)[0], "a") == 0);
+      TEST(strcmp((*msg_b.strings)[1], "b") == 0);
+      TEST(strcmp((*msg_b.strings)[2], "abc") == 0);
+
+      pb_release(Message4_fields, &msg_b);
+
+      TEST(get_alloc_count() == 0);
+    }
+
     if (status != 0)
         fprintf(stdout, "\n\nSome tests FAILED!\n");