Separate field iterator logic from pb_decode to pb_common.
authorPetteri Aimonen <jpa@git.mail.kapsi.fi>
Sun, 10 Aug 2014 09:42:01 +0000 (12:42 +0300)
committerPetteri Aimonen <jpa@git.mail.kapsi.fi>
Sun, 10 Aug 2014 09:42:01 +0000 (12:42 +0300)
22 files changed:
pb_common.c [new file with mode: 0644]
pb_common.h [new file with mode: 0644]
pb_decode.c
tests/alltypes/SConscript
tests/alltypes_callback/SConscript
tests/alltypes_pointer/SConscript
tests/backwards_compatibility/SConscript
tests/basic_buffer/SConscript
tests/basic_stream/SConscript
tests/buffer_only/SConscript
tests/callbacks/SConscript
tests/common/SConscript
tests/cxx_main_program/SConscript
tests/decode_unittests/decode_unittests.c
tests/encode_unittests/encode_unittests.c
tests/extensions/SConscript
tests/field_size_16/SConscript
tests/field_size_32/SConscript
tests/missing_fields/SConscript
tests/no_errmsg/SConscript
tests/package_name/SConscript
tests/splint/SConscript

diff --git a/pb_common.c b/pb_common.c
new file mode 100644 (file)
index 0000000..de21769
--- /dev/null
@@ -0,0 +1,88 @@
+/* pb_common.c: Common support functions for pb_encode.c and pb_decode.c.
+ *
+ * 2014 Petteri Aimonen <jpa@kapsi.fi>
+ */
+
+#include "pb_common.h"
+
+void pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct)
+{
+    iter->start = fields;
+    iter->pos = fields;
+    iter->required_field_index = 0;
+    iter->dest_struct = dest_struct;
+    iter->pData = (char*)dest_struct + iter->pos->data_offset;
+    iter->pSize = (char*)iter->pData + iter->pos->size_offset;
+}
+
+bool pb_field_iter_next(pb_field_iter_t *iter)
+{
+    const pb_field_t *prev_field = iter->pos;
+
+    if (prev_field->tag == 0)
+    {
+        /* Handle empty message types, where the first field is already the terminator.
+         * In other cases, the iter->pos never points to the terminator. */
+        return false;
+    }
+    
+    iter->pos++;
+    
+    if (iter->pos->tag == 0)
+    {
+        /* Wrapped back to beginning, reinitialize */
+        pb_field_iter_begin(iter, iter->start, iter->dest_struct);
+        return false;
+    }
+    else
+    {
+        /* Increment the pointers based on previous field size */
+        size_t prev_size = prev_field->data_size;
+    
+        if (PB_ATYPE(prev_field->type) == PB_ATYPE_STATIC &&
+            PB_HTYPE(prev_field->type) == PB_HTYPE_REPEATED)
+        {
+            /* In static arrays, the data_size tells the size of a single entry and
+             * array_size is the number of entries */
+            prev_size *= prev_field->array_size;
+        }
+        else if (PB_ATYPE(prev_field->type) == PB_ATYPE_POINTER)
+        {
+            /* Pointer fields always have a constant size in the main structure.
+             * The data_size only applies to the dynamically allocated area. */
+            prev_size = sizeof(void*);
+        }
+        
+        if (PB_HTYPE(prev_field->type) == PB_HTYPE_REQUIRED)
+        {
+            /* Count the required fields, in order to check their presence in the
+             * decoder. */
+            iter->required_field_index++;
+        }
+    
+        iter->pData = (char*)iter->pData + prev_size + iter->pos->data_offset;
+        iter->pSize = (char*)iter->pData + iter->pos->size_offset;
+        return true;
+    }
+}
+
+bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag)
+{
+    const pb_field_t *start = iter->pos;
+    
+    do {
+        if (iter->pos->tag == tag &&
+            PB_LTYPE(iter->pos->type) != PB_LTYPE_EXTENSION)
+        {
+            /* Found the wanted field */
+            return true;
+        }
+        
+        (void)pb_field_iter_next(iter);
+    } while (iter->pos != start);
+    
+    /* Searched all the way back to start, and found nothing. */
+    return false;
+}
+
+
diff --git a/pb_common.h b/pb_common.h
new file mode 100644 (file)
index 0000000..e85f000
--- /dev/null
@@ -0,0 +1,40 @@
+/* pb_common.h: Common support functions for pb_encode.c and pb_decode.c.
+ * These functions are rarely needed by applications directly.
+ */
+
+#ifndef _PB_COMMON_H_
+#define _PB_COMMON_H_
+
+#include "pb.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Iterator for pb_field_t list */
+typedef struct {
+    const pb_field_t *start;       /* Start of the pb_field_t array */
+    const pb_field_t *pos;         /* Current position of the iterator */
+    unsigned required_field_index; /* Zero-based index that counts only the required fields */
+    void *dest_struct;             /* Pointer to the destination structure to decode to */
+    void *pData;                   /* Pointer where to store current field value */
+    void *pSize;                   /* Pointer where to store the size of current array field */
+} pb_field_iter_t;
+
+/* Initialize the field iterator structure to beginning. */
+void pb_field_iter_begin(pb_field_iter_t *iter, const pb_field_t *fields, void *dest_struct);
+
+/* Advance the iterator to the next field.
+ * Returns false when the iterator wraps back to the first field. */
+bool pb_field_iter_next(pb_field_iter_t *iter);
+
+/* Advance the iterator until it points at a field with the given tag.
+ * Returns false if no such field exists. */
+bool pb_field_iter_find(pb_field_iter_t *iter, uint32_t tag);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif
+
index 4e18725..40da1aa 100644 (file)
 
 #include "pb.h"
 #include "pb_decode.h"
+#include "pb_common.h"
 
 /**************************************
  * Declarations internal to this file *
  **************************************/
 
-/* Iterator for pb_field_t list */
-typedef struct {
-    const pb_field_t *start; /* Start of the pb_field_t array */
-    const pb_field_t *pos; /* Current position of the iterator */
-    unsigned field_index; /* Zero-based index of the field. */
-    unsigned required_field_index; /* Zero-based index that counts only the required fields */
-    void *dest_struct; /* Pointer to the destination structure to decode to */
-    void *pData; /* Pointer where to store current field value */
-    void *pSize; /* Pointer where to store the size of current array field */
-} pb_field_iterator_t;
-
 typedef bool (*pb_decoder_t)(pb_istream_t *stream, const pb_field_t *field, void *dest) checkreturn;
 
 static bool checkreturn buf_read(pb_istream_t *stream, uint8_t *buf, size_t count);
 static bool checkreturn pb_decode_varint32(pb_istream_t *stream, uint32_t *dest);
 static bool checkreturn read_raw_value(pb_istream_t *stream, pb_wire_type_t wire_type, uint8_t *buf, size_t *size);
-static void pb_field_init(pb_field_iterator_t *iter, const pb_field_t *fields, void *dest_struct);
-static bool pb_field_next(pb_field_iterator_t *iter);
-static bool checkreturn pb_field_find(pb_field_iterator_t *iter, uint32_t tag);
-static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter);
-static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter);
-static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter);
+static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter);
+static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter);
+static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter);
 static bool checkreturn default_extension_decoder(pb_istream_t *stream, pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type);
-static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_field_iterator_t *iter);
-static bool checkreturn find_extension_field(pb_field_iterator_t *iter);
+static bool checkreturn decode_extension(pb_istream_t *stream, uint32_t tag, pb_wire_type_t wire_type, pb_field_iter_t *iter);
+static bool checkreturn find_extension_field(pb_field_iter_t *iter);
 static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct);
 static bool checkreturn pb_dec_varint(pb_istream_t *stream, const pb_field_t *field, void *dest);
 static bool checkreturn pb_dec_uvarint(pb_istream_t *stream, const pb_field_t *field, void *dest);
@@ -338,75 +325,11 @@ void pb_close_string_substream(pb_istream_t *stream, pb_istream_t *substream)
 #endif
 }
 
-static void pb_field_init(pb_field_iterator_t *iter, const pb_field_t *fields, void *dest_struct)
-{
-    iter->start = iter->pos = fields;
-    iter->field_index = 0;
-    iter->required_field_index = 0;
-    iter->pData = (char*)dest_struct + iter->pos->data_offset;
-    iter->pSize = (char*)iter->pData + iter->pos->size_offset;
-    iter->dest_struct = dest_struct;
-}
-
-static bool pb_field_next(pb_field_iterator_t *iter)
-{
-    bool notwrapped = true;
-    size_t prev_size = iter->pos->data_size;
-    
-    if (PB_ATYPE(iter->pos->type) == PB_ATYPE_STATIC &&
-        PB_HTYPE(iter->pos->type) == PB_HTYPE_REPEATED)
-    {
-        prev_size *= iter->pos->array_size;
-    }
-    else if (PB_ATYPE(iter->pos->type) == PB_ATYPE_POINTER)
-    {
-        prev_size = sizeof(void*);
-    }
-    
-    if (iter->pos->tag == 0)
-        return false; /* Only happens with empty message types */
-    
-    if (PB_HTYPE(iter->pos->type) == PB_HTYPE_REQUIRED)
-        iter->required_field_index++;
-    
-    iter->pos++;
-    iter->field_index++;
-    if (iter->pos->tag == 0)
-    {
-        iter->pos = iter->start;
-        iter->field_index = 0;
-        iter->required_field_index = 0;
-        iter->pData = iter->dest_struct;
-        prev_size = 0;
-        notwrapped = false;
-    }
-    
-    iter->pData = (char*)iter->pData + prev_size + iter->pos->data_offset;
-    iter->pSize = (char*)iter->pData + iter->pos->size_offset;
-    return notwrapped;
-}
-
-static bool checkreturn pb_field_find(pb_field_iterator_t *iter, uint32_t tag)
-{
-    unsigned start = iter->field_index;
-    
-    do {
-        if (iter->pos->tag == tag &&
-            PB_LTYPE(iter->pos->type) != PB_LTYPE_EXTENSION)
-        {
-            return true;
-        }
-        (void)pb_field_next(iter);
-    } while (iter->field_index != start);
-    
-    return false;
-}
-
 /*************************
  * Decode a single field *
  *************************/
 
-static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
+static bool checkreturn decode_static_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter)
 {
     pb_type_t type;
     pb_decoder_t func;
@@ -504,7 +427,7 @@ static bool checkreturn allocate_field(pb_istream_t *stream, void *pData, size_t
 }
 
 /* Clear a newly allocated item in case it contains a pointer, or is a submessage. */
-static void initialize_pointer_field(void *pItem, pb_field_iterator_t *iter)
+static void initialize_pointer_field(void *pItem, pb_field_iter_t *iter)
 {
     if (PB_LTYPE(iter->pos->type) == PB_LTYPE_STRING ||
         PB_LTYPE(iter->pos->type) == PB_LTYPE_BYTES)
@@ -518,7 +441,7 @@ static void initialize_pointer_field(void *pItem, pb_field_iterator_t *iter)
 }
 #endif
 
-static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
+static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter)
 {
 #ifndef PB_ENABLE_MALLOC
     UNUSED(wire_type);
@@ -614,7 +537,7 @@ static bool checkreturn decode_pointer_field(pb_istream_t *stream, pb_wire_type_
 #endif
 }
 
-static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
+static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter)
 {
     pb_callback_t *pCallback = (pb_callback_t*)iter->pData;
     
@@ -661,7 +584,7 @@ static bool checkreturn decode_callback_field(pb_istream_t *stream, pb_wire_type
     }
 }
 
-static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
+static bool checkreturn decode_field(pb_istream_t *stream, pb_wire_type_t wire_type, pb_field_iter_t *iter)
 {
     switch (PB_ATYPE(iter->pos->type))
     {
@@ -685,16 +608,15 @@ static bool checkreturn default_extension_decoder(pb_istream_t *stream,
     pb_extension_t *extension, uint32_t tag, pb_wire_type_t wire_type)
 {
     const pb_field_t *field = (const pb_field_t*)extension->type->arg;
-    pb_field_iterator_t iter;
+    pb_field_iter_t iter;
     
     if (field->tag != tag)
         return true;
     
-    iter.start = field;
-    iter.pos = field;
-    iter.field_index = 0;
-    iter.required_field_index = 0;
-    iter.dest_struct = extension->dest;
+    /* Fake a field iterator for the extension field.
+     * It is not actually safe to advance this iterator, but decode_field
+     * will not even try to. */
+    pb_field_iter_begin(&iter, field, extension->dest);
     iter.pData = extension->dest;
     iter.pSize = &extension->found;
     
@@ -704,7 +626,7 @@ static bool checkreturn default_extension_decoder(pb_istream_t *stream,
 /* Try to decode an unknown field as an extension field. Tries each extension
  * decoder in turn, until one of them handles the field or loop ends. */
 static bool checkreturn decode_extension(pb_istream_t *stream,
-    uint32_t tag, pb_wire_type_t wire_type, pb_field_iterator_t *iter)
+    uint32_t tag, pb_wire_type_t wire_type, pb_field_iter_t *iter)
 {
     pb_extension_t *extension = *(pb_extension_t* const *)iter->pData;
     size_t pos = stream->bytes_left;
@@ -729,15 +651,15 @@ static bool checkreturn decode_extension(pb_istream_t *stream,
 /* Step through the iterator until an extension field is found or until all
  * entries have been checked. There can be only one extension field per
  * message. Returns false if no extension field is found. */
-static bool checkreturn find_extension_field(pb_field_iterator_t *iter)
+static bool checkreturn find_extension_field(pb_field_iter_t *iter)
 {
-    unsigned start = iter->field_index;
+    const pb_field_t *start = iter->pos;
     
     do {
         if (PB_LTYPE(iter->pos->type) == PB_LTYPE_EXTENSION)
             return true;
-        (void)pb_field_next(iter);
-    } while (iter->field_index != start);
+        (void)pb_field_iter_next(iter);
+    } while (iter->pos != start);
     
     return false;
 }
@@ -745,8 +667,8 @@ static bool checkreturn find_extension_field(pb_field_iterator_t *iter)
 /* Initialize message fields to default values, recursively */
 static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_struct)
 {
-    pb_field_iterator_t iter;
-    pb_field_init(&iter, fields, dest_struct);
+    pb_field_iter_t iter;
+    pb_field_iter_begin(&iter, fields, dest_struct);
     
     do
     {
@@ -803,7 +725,7 @@ static void pb_message_set_to_defaults(const pb_field_t fields[], void *dest_str
         {
             /* Don't overwrite callback */
         }
-    } while (pb_field_next(&iter));
+    } while (pb_field_iter_next(&iter));
 }
 
 /*********************
@@ -814,9 +736,9 @@ bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[
 {
     uint8_t fields_seen[(PB_MAX_REQUIRED_FIELDS + 7) / 8] = {0, 0, 0, 0, 0, 0, 0, 0};
     uint32_t extension_range_start = 0;
-    pb_field_iterator_t iter;
+    pb_field_iter_t iter;
     
-    pb_field_init(&iter, fields, dest_struct);
+    pb_field_iter_begin(&iter, fields, dest_struct);
     
     while (stream->bytes_left)
     {
@@ -832,7 +754,7 @@ bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[
                 return false;
         }
         
-        if (!pb_field_find(&iter, tag))
+        if (!pb_field_iter_find(&iter, tag))
         {
             /* No match found, check if it matches an extension. */
             if (tag >= extension_range_start)
@@ -885,7 +807,7 @@ bool checkreturn pb_decode_noinit(pb_istream_t *stream, const pb_field_t fields[
         do {
             req_field_count = iter.required_field_index;
             last_type = iter.pos->type;
-        } while (pb_field_next(&iter));
+        } while (pb_field_iter_next(&iter));
         
         /* Fixup if last field was also required. */
         if (PB_HTYPE(last_type) == PB_HTYPE_REQUIRED && iter.pos->tag != 0)
@@ -936,8 +858,8 @@ bool pb_decode_delimited(pb_istream_t *stream, const pb_field_t fields[], void *
 #ifdef PB_ENABLE_MALLOC
 void pb_release(const pb_field_t fields[], void *dest_struct)
 {
-    pb_field_iterator_t iter;
-    pb_field_init(&iter, fields, dest_struct);
+    pb_field_iter_t iter;
+    pb_field_iter_begin(&iter, fields, dest_struct);
     
     do
     {
@@ -985,7 +907,7 @@ void pb_release(const pb_field_t fields[], void *dest_struct)
             pb_free(*(void**)iter.pData);
             *(void**)iter.pData = NULL;
         }
-    } while (pb_field_next(&iter));
+    } while (pb_field_iter_next(&iter));
 }
 #endif
 
index 9c9072b..6c6238c 100644 (file)
@@ -4,8 +4,8 @@
 Import("env")
 
 env.NanopbProto(["alltypes", "alltypes.options"])
-enc = env.Program(["encode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_encode.o"])
-dec = env.Program(["decode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_decode.o"])
+enc = env.Program(["encode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
+dec = env.Program(["decode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
 
 # Test the round-trip from nanopb encoder to nanopb decoder
 env.RunTest(enc)
index 71b0160..a241f24 100644 (file)
@@ -6,8 +6,8 @@ c = Copy("$TARGET", "$SOURCE")
 env.Command("alltypes.proto", "#alltypes/alltypes.proto", c)
 
 env.NanopbProto(["alltypes", "alltypes.options"])
-enc = env.Program(["encode_alltypes_callback.c", "alltypes.pb.c", "$COMMON/pb_encode.o"])
-dec = env.Program(["decode_alltypes_callback.c", "alltypes.pb.c", "$COMMON/pb_decode.o"])
+enc = env.Program(["encode_alltypes_callback.c", "alltypes.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
+dec = env.Program(["decode_alltypes_callback.c", "alltypes.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
 
 refdec = "$BUILD/alltypes/decode_alltypes$PROGSUFFIX"
 
index e48d6aa..8fcf197 100644 (file)
@@ -18,13 +18,14 @@ strict = env.Clone()
 strict.Append(CFLAGS = strict['CORECFLAGS'])
 strict.Object("pb_decode_with_malloc.o", "$NANOPB/pb_decode.c")
 strict.Object("pb_encode_with_malloc.o", "$NANOPB/pb_encode.c")
+strict.Object("pb_common_with_malloc.o", "$NANOPB/pb_common.c")
 
 c = Copy("$TARGET", "$SOURCE")
 env.Command("alltypes.proto", "#alltypes/alltypes.proto", c)
 
 env.NanopbProto(["alltypes", "alltypes.options"])
-enc = env.Program(["encode_alltypes_pointer.c", "alltypes.pb.c", "pb_encode_with_malloc.o"])
-dec = env.Program(["decode_alltypes_pointer.c", "alltypes.pb.c", "pb_decode_with_malloc.o"])
+enc = env.Program(["encode_alltypes_pointer.c", "alltypes.pb.c", "pb_encode_with_malloc.o", "pb_common_with_malloc.o"])
+dec = env.Program(["decode_alltypes_pointer.c", "alltypes.pb.c", "pb_decode_with_malloc.o", "pb_common_with_malloc.o"])
 
 # Encode and compare results to non-pointer alltypes test case
 env.RunTest(enc)
index 777ef40..81b0318 100644 (file)
@@ -3,8 +3,8 @@
 
 Import("env")
 
-enc = env.Program(["encode_legacy.c", "alltypes_legacy.c", "$COMMON/pb_encode.o"])
-dec = env.Program(["decode_legacy.c", "alltypes_legacy.c", "$COMMON/pb_decode.o"])
+enc = env.Program(["encode_legacy.c", "alltypes_legacy.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
+dec = env.Program(["decode_legacy.c", "alltypes_legacy.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_legacy.output"])
index 2546aaa..acaf5ff 100644 (file)
@@ -2,8 +2,8 @@
 
 Import("env")
 
-enc = env.Program(["encode_buffer.c", "$COMMON/person.pb.c", "$COMMON/pb_encode.o"])
-dec = env.Program(["decode_buffer.c", "$COMMON/person.pb.c", "$COMMON/pb_decode.o"])
+enc = env.Program(["encode_buffer.c", "$COMMON/person.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
+dec = env.Program(["decode_buffer.c", "$COMMON/person.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_buffer.output"])
index 46db8c4..7d66856 100644 (file)
@@ -2,8 +2,8 @@
 
 Import("env")
 
-enc = env.Program(["encode_stream.c", "$COMMON/person.pb.c", "$COMMON/pb_encode.o"])
-dec = env.Program(["decode_stream.c", "$COMMON/person.pb.c", "$COMMON/pb_decode.o"])
+enc = env.Program(["encode_stream.c", "$COMMON/person.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
+dec = env.Program(["decode_stream.c", "$COMMON/person.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_stream.output"])
index cddbb04..55b747b 100644 (file)
@@ -18,10 +18,11 @@ strict = opts.Clone()
 strict.Append(CFLAGS = strict['CORECFLAGS'])
 strict.Object("pb_decode_bufonly.o", "$NANOPB/pb_decode.c")
 strict.Object("pb_encode_bufonly.o", "$NANOPB/pb_encode.c")
+strict.Object("pb_common_bufonly.o", "$NANOPB/pb_common.c")
 
 # Now build and run the test normally.
-enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_bufonly.o"])
-dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_bufonly.o"])
+enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_bufonly.o", "pb_common_bufonly.o"])
+dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_bufonly.o", "pb_common_bufonly.o"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_alltypes.output"])
index 9ec8a43..4452143 100644 (file)
@@ -3,8 +3,8 @@
 Import("env")
 
 env.NanopbProto("callbacks")
-enc = env.Program(["encode_callbacks.c", "callbacks.pb.c", "$COMMON/pb_encode.o"])
-dec = env.Program(["decode_callbacks.c", "callbacks.pb.c", "$COMMON/pb_decode.o"])
+enc = env.Program(["encode_callbacks.c", "callbacks.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
+dec = env.Program(["decode_callbacks.c", "callbacks.pb.c", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_callbacks.output"])
index 144f149..f1dee0e 100644 (file)
@@ -14,4 +14,4 @@ strict = env.Clone()
 strict.Append(CFLAGS = strict['CORECFLAGS'])
 strict.Object("pb_decode.o", "$NANOPB/pb_decode.c")
 strict.Object("pb_encode.o", "$NANOPB/pb_encode.c")
-
+strict.Object("pb_common.o", "$NANOPB/pb_common.c")
index e78c6b3..edb8812 100644 (file)
@@ -11,14 +11,15 @@ env.Append(CPPDEFINES = ['__STDC_LIMIT_MACROS'])
 c = Copy("$TARGET", "$SOURCE")
 env.Command("pb_encode.cxx", "#../pb_encode.c", c)
 env.Command("pb_decode.cxx", "#../pb_decode.c", c)
+env.Command("pb_common.cxx", "#../pb_common.c", c)
 env.Command("alltypes.pb.h", "$BUILD/alltypes/alltypes.pb.h", c)
 env.Command("alltypes.pb.cxx", "$BUILD/alltypes/alltypes.pb.c", c)
 env.Command("encode_alltypes.cxx", "$BUILD/alltypes/encode_alltypes.c", c)
 env.Command("decode_alltypes.cxx", "$BUILD/alltypes/decode_alltypes.c", c)
 
 # Now build and run the test normally.
-enc = env.Program(["encode_alltypes.cxx", "alltypes.pb.cxx", "pb_encode.cxx"])
-dec = env.Program(["decode_alltypes.cxx", "alltypes.pb.cxx", "pb_decode.cxx"])
+enc = env.Program(["encode_alltypes.cxx", "alltypes.pb.cxx", "pb_encode.cxx", "pb_common.cxx"])
+dec = env.Program(["decode_alltypes.cxx", "alltypes.pb.cxx", "pb_decode.cxx", "pb_common.cxx"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_alltypes.output"])
index 98055df..59c4a07 100644 (file)
@@ -1,5 +1,6 @@
 /* This includes the whole .c file to get access to static functions. */
 #define PB_ENABLE_MALLOC
+#include "pb_common.c"
 #include "pb_decode.c"
 
 #include <stdio.h>
index 06935f9..a5f868c 100644 (file)
@@ -1,4 +1,5 @@
 /* This includes the whole .c file to get access to static functions. */
+#include "pb_common.c"
 #include "pb_encode.c"
 
 #include <stdio.h>
index 26fc5a3..cf2e096 100644 (file)
@@ -8,8 +8,8 @@ incpath.Append(PROTOCPATH = '$BUILD/alltypes')
 incpath.Append(CPPPATH = '$BUILD/alltypes')
 
 incpath.NanopbProto(["extensions", "extensions.options"])
-enc = incpath.Program(["encode_extensions.c", "extensions.pb.c", "$BUILD/alltypes/alltypes.pb$OBJSUFFIX", "$COMMON/pb_encode.o"])
-dec = incpath.Program(["decode_extensions.c", "extensions.pb.c", "$BUILD/alltypes/alltypes.pb$OBJSUFFIX", "$COMMON/pb_decode.o"])
+enc = incpath.Program(["encode_extensions.c", "extensions.pb.c", "$BUILD/alltypes/alltypes.pb.o", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
+dec = incpath.Program(["decode_extensions.c", "extensions.pb.c", "$BUILD/alltypes/alltypes.pb.o", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_extensions.output"])
index 8fee004..ffb29c4 100644 (file)
@@ -19,10 +19,11 @@ strict = opts.Clone()
 strict.Append(CFLAGS = strict['CORECFLAGS'])
 strict.Object("pb_decode_fields16.o", "$NANOPB/pb_decode.c")
 strict.Object("pb_encode_fields16.o", "$NANOPB/pb_encode.c")
+strict.Object("pb_common_fields16.o", "$NANOPB/pb_common.c")
 
 # Now build and run the test normally.
-enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_fields16.o"])
-dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_fields16.o"])
+enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_fields16.o", "pb_common_fields16.o"])
+dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_fields16.o", "pb_common_fields16.o"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_alltypes.output"])
index 2a64c6c..0b8dc0e 100644 (file)
@@ -19,10 +19,11 @@ strict = opts.Clone()
 strict.Append(CFLAGS = strict['CORECFLAGS'])
 strict.Object("pb_decode_fields32.o", "$NANOPB/pb_decode.c")
 strict.Object("pb_encode_fields32.o", "$NANOPB/pb_encode.c")
+strict.Object("pb_common_fields32.o", "$NANOPB/pb_common.c")
 
 # Now build and run the test normally.
-enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_fields32.o"])
-dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_fields32.o"])
+enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_fields32.o", "pb_common_fields32.o"])
+dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_fields32.o", "pb_common_fields32.o"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_alltypes.output"])
index 9926efa..86ba083 100644 (file)
@@ -3,6 +3,6 @@
 Import("env")
 
 env.NanopbProto("missing_fields")
-test = env.Program(["missing_fields.c", "missing_fields.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_decode.o"])
+test = env.Program(["missing_fields.c", "missing_fields.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_decode.o", "$COMMON/pb_common.o"])
 env.RunTest(test)
 
index ed46705..629bfa6 100644 (file)
@@ -18,10 +18,11 @@ strict = opts.Clone()
 strict.Append(CFLAGS = strict['CORECFLAGS'])
 strict.Object("pb_decode_noerr.o", "$NANOPB/pb_decode.c")
 strict.Object("pb_encode_noerr.o", "$NANOPB/pb_encode.c")
+strict.Object("pb_common_noerr.o", "$NANOPB/pb_common.c")
 
 # Now build and run the test normally.
-enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_noerr.o"])
-dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_noerr.o"])
+enc = opts.Program(["encode_alltypes.c", "alltypes.pb.c", "pb_encode_noerr.o", "pb_common_noerr.o"])
+dec = opts.Program(["decode_alltypes.c", "alltypes.pb.c", "pb_decode_noerr.o", "pb_common_noerr.o"])
 
 env.RunTest(enc)
 env.RunTest([dec, "encode_alltypes.output"])
index 8f1b902..897bc99 100644 (file)
@@ -29,7 +29,7 @@ def modify_c(target, source, env):
 env.Command("encode_alltypes.c", "#alltypes/encode_alltypes.c", modify_c)
 
 # Encode and compare results to original alltypes testcase
-enc = env.Program(["encode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_encode.o"])
+enc = env.Program(["encode_alltypes.c", "alltypes.pb.c", "$COMMON/pb_encode.o", "$COMMON/pb_common.o"])
 refdec = "$BUILD/alltypes/decode_alltypes$PROGSUFFIX"
 env.RunTest(enc)
 env.Compare(["encode_alltypes.output", "$BUILD/alltypes/encode_alltypes.output"])
index c1432dd..cd4b5b9 100644 (file)
@@ -11,3 +11,6 @@ if p:
     env.Command('pb_encode.splint', '$NANOPB/pb_encode.c',
         'splint -f splint/splint.rc $SOURCE 2> $TARGET')
 
+    env.Command('pb_common.splint', '$NANOPB/pb_common.c',
+        'splint -f splint/splint.rc $SOURCE 2> $TARGET')
+