mirror of
https://github.com/protobuf-c/protobuf-c.git
synced 2024-12-27 13:31:02 +08:00
many bug fixes, and lots of test code
git-svn-id: https://protobuf-c.googlecode.com/svn/trunk@36 00440858-1255-0410-a3e6-75ea37f81c3a
This commit is contained in:
parent
6ffe171d9f
commit
1265baa325
1
TODO
1
TODO
@ -1,7 +1,6 @@
|
||||
- check over documentation again
|
||||
- handle unknown fields when packing
|
||||
- test code
|
||||
- ensure enums are 32-bit
|
||||
- make services derive from ProtobufCService;
|
||||
be usable with a cast.
|
||||
- provide example rpc
|
||||
|
@ -1,6 +1,21 @@
|
||||
#include <stdio.h> /* for occasional printf()s */
|
||||
#include <stdlib.h> /* for abort(), malloc() etc */
|
||||
#include <string.h> /* for strlen(), memcpy(), memmove() */
|
||||
#include <endian.h>
|
||||
|
||||
#define DO_LITTLE_ENDIAN_OPTIMIZATIONS 0
|
||||
#define PRINT_UNPACK_ERRORS 1
|
||||
|
||||
#if DO_LITTLE_ENDIAN_OPTIMIZATIONS
|
||||
# if (__LITTLE_ENDIAN == __BYTE_ORDER)
|
||||
# define IS_LITTLE_ENDIAN 1
|
||||
# else
|
||||
# define IS_LITTLE_ENDIAN 0
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/* This file defines `__BYTE_ORDER' for the particular machine. */
|
||||
|
||||
#include "protobuf-c.h"
|
||||
|
||||
@ -123,6 +138,23 @@ uint32_size (uint32_t v)
|
||||
else
|
||||
return 5;
|
||||
}
|
||||
static inline size_t
|
||||
int32_size (int32_t v)
|
||||
{
|
||||
if (v < 0)
|
||||
return 10;
|
||||
else
|
||||
if (v < (1<<7))
|
||||
return 1;
|
||||
else if (v < (1<<14))
|
||||
return 2;
|
||||
else if (v < (1<<21))
|
||||
return 3;
|
||||
else if (v < (1<<28))
|
||||
return 4;
|
||||
else
|
||||
return 5;
|
||||
}
|
||||
static inline uint32_t
|
||||
zigzag32 (int32_t v)
|
||||
{
|
||||
@ -164,7 +196,7 @@ zigzag64 (int64_t v)
|
||||
return v * 2;
|
||||
}
|
||||
static inline size_t
|
||||
sint64_size (int32_t v)
|
||||
sint64_size (int64_t v)
|
||||
{
|
||||
return uint64_size(zigzag64(v));
|
||||
}
|
||||
@ -179,10 +211,11 @@ required_field_get_packed_size (const ProtobufCFieldDescriptor *field,
|
||||
case PROTOBUF_C_TYPE_SINT32:
|
||||
return rv + sint32_size (*(int32_t *) member);
|
||||
case PROTOBUF_C_TYPE_INT32:
|
||||
return rv + int32_size (*(uint32_t *) member);
|
||||
case PROTOBUF_C_TYPE_UINT32:
|
||||
return rv + uint32_size (*(uint32_t *) member);
|
||||
case PROTOBUF_C_TYPE_SINT64:
|
||||
return rv + sint64_size (*(int32_t *) member);
|
||||
return rv + sint64_size (*(int64_t *) member);
|
||||
case PROTOBUF_C_TYPE_INT64:
|
||||
case PROTOBUF_C_TYPE_UINT64:
|
||||
return rv + uint64_size (*(uint64_t *) member);
|
||||
@ -256,6 +289,9 @@ repeated_field_get_packed_size (const ProtobufCFieldDescriptor *field,
|
||||
rv += sint32_size (((int32_t*)array)[i]);
|
||||
break;
|
||||
case PROTOBUF_C_TYPE_INT32:
|
||||
for (i = 0; i < count; i++)
|
||||
rv += int32_size (((uint32_t*)array)[i]);
|
||||
break;
|
||||
case PROTOBUF_C_TYPE_UINT32:
|
||||
case PROTOBUF_C_TYPE_ENUM:
|
||||
for (i = 0; i < count; i++)
|
||||
@ -355,6 +391,23 @@ uint32_pack (uint32_t value, BYTE *out)
|
||||
out[rv++] = value;
|
||||
return rv;
|
||||
}
|
||||
static inline size_t
|
||||
int32_pack (int32_t value, BYTE *out)
|
||||
{
|
||||
if (value < 0)
|
||||
{
|
||||
out[0] = value | 0x80;
|
||||
out[1] = (value>>7) | 0x80;
|
||||
out[2] = (value>>14) | 0x80;
|
||||
out[3] = (value>>21) | 0x80;
|
||||
out[4] = (value>>28) | 0x80;
|
||||
out[5] = out[6] = out[7] = out[8] = 0xff;
|
||||
out[9] = 0x01;
|
||||
return 10;
|
||||
}
|
||||
else
|
||||
return uint32_pack (value, out);
|
||||
}
|
||||
static inline size_t sint32_pack (int32_t value, BYTE *out)
|
||||
{
|
||||
return uint32_pack (zigzag32 (value), out);
|
||||
@ -367,7 +420,7 @@ uint64_pack (uint64_t value, BYTE *out)
|
||||
unsigned rv;
|
||||
if (hi == 0)
|
||||
return uint32_pack ((uint32_t)lo, out);
|
||||
out[0] = (lo) & 0x7f;
|
||||
out[0] = (lo) | 0x80;
|
||||
out[1] = (lo>>7) | 0x80;
|
||||
out[2] = (lo>>14) | 0x80;
|
||||
out[3] = (lo>>21) | 0x80;
|
||||
@ -466,13 +519,15 @@ required_field_pack (const ProtobufCFieldDescriptor *field,
|
||||
out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
|
||||
return rv + sint32_pack (*(int32_t *) member, out + rv);
|
||||
case PROTOBUF_C_TYPE_INT32:
|
||||
out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
|
||||
return rv + int32_pack (*(uint32_t *) member, out + rv);
|
||||
case PROTOBUF_C_TYPE_UINT32:
|
||||
case PROTOBUF_C_TYPE_ENUM:
|
||||
out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
|
||||
return rv + uint32_pack (*(uint32_t *) member, out + rv);
|
||||
case PROTOBUF_C_TYPE_SINT64:
|
||||
out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
|
||||
return rv + sint64_pack (*(int32_t *) member, out + rv);
|
||||
return rv + sint64_pack (*(int64_t *) member, out + rv);
|
||||
case PROTOBUF_C_TYPE_INT64:
|
||||
case PROTOBUF_C_TYPE_UINT64:
|
||||
out[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
|
||||
@ -622,6 +677,10 @@ required_field_pack_to_buffer (const ProtobufCFieldDescriptor *field,
|
||||
buffer->append (buffer, rv, scratch);
|
||||
break;
|
||||
case PROTOBUF_C_TYPE_INT32:
|
||||
scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
|
||||
rv += int32_pack (*(uint32_t *) member, scratch + rv);
|
||||
buffer->append (buffer, rv, scratch);
|
||||
break;
|
||||
case PROTOBUF_C_TYPE_UINT32:
|
||||
case PROTOBUF_C_TYPE_ENUM:
|
||||
scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
|
||||
@ -630,7 +689,7 @@ required_field_pack_to_buffer (const ProtobufCFieldDescriptor *field,
|
||||
break;
|
||||
case PROTOBUF_C_TYPE_SINT64:
|
||||
scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
|
||||
rv += sint64_pack (*(int32_t *) member, scratch + rv);
|
||||
rv += sint64_pack (*(int64_t *) member, scratch + rv);
|
||||
buffer->append (buffer, rv, scratch);
|
||||
break;
|
||||
case PROTOBUF_C_TYPE_INT64:
|
||||
@ -766,6 +825,12 @@ protobuf_c_message_pack_to_buffer (const ProtobufCMessage *message,
|
||||
}
|
||||
|
||||
/* === unpacking === */
|
||||
#if PRINT_UNPACK_ERRORS
|
||||
# define UNPACK_ERROR(args) do { printf args;printf("\n"); }while(0)
|
||||
#else
|
||||
# define UNPACK_ERROR(args) do { } while (0)
|
||||
#endif
|
||||
|
||||
static inline int
|
||||
int_range_lookup (unsigned n_ranges,
|
||||
const ProtobufCIntRange *ranges,
|
||||
@ -866,11 +931,18 @@ scan_length_prefixed_data (size_t len, const BYTE *data, size_t *prefix_len_out)
|
||||
break;
|
||||
}
|
||||
if (i == hdr_max)
|
||||
{
|
||||
UNPACK_ERROR (("error parsing length for length-prefixed data"));
|
||||
return 0;
|
||||
}
|
||||
hdr_len = i + 1;
|
||||
*prefix_len_out = hdr_len;
|
||||
if (hdr_len + val > len)
|
||||
{
|
||||
UNPACK_ERROR (("data too short after length-prefix of %u",
|
||||
val));
|
||||
return 0;
|
||||
}
|
||||
return hdr_len + val;
|
||||
}
|
||||
|
||||
@ -894,6 +966,11 @@ parse_uint32 (unsigned len, const BYTE *data)
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
static inline uint32_t
|
||||
parse_int32 (unsigned len, const BYTE *data)
|
||||
{
|
||||
return parse_uint32 (len, data);
|
||||
}
|
||||
static inline int32_t
|
||||
unzigzag32 (uint32_t v)
|
||||
{
|
||||
@ -972,6 +1049,10 @@ parse_required_member (ScannedMember *scanned_member,
|
||||
switch (scanned_member->field->type)
|
||||
{
|
||||
case PROTOBUF_C_TYPE_INT32:
|
||||
if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT)
|
||||
return 0;
|
||||
*(uint32_t*)member = parse_int32 (len, data);
|
||||
return 1;
|
||||
case PROTOBUF_C_TYPE_UINT32:
|
||||
if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT)
|
||||
return 0;
|
||||
@ -988,7 +1069,7 @@ parse_required_member (ScannedMember *scanned_member,
|
||||
if (wire_type != PROTOBUF_C_WIRE_TYPE_32BIT)
|
||||
return 0;
|
||||
*(uint32_t*)member = parse_fixed_uint32 (data);
|
||||
break;
|
||||
return 1;
|
||||
|
||||
case PROTOBUF_C_TYPE_INT64:
|
||||
case PROTOBUF_C_TYPE_UINT64:
|
||||
@ -1167,7 +1248,11 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
|
||||
const ProtobufCFieldDescriptor *field;
|
||||
ScannedMember tmp;
|
||||
if (used == 0)
|
||||
{
|
||||
UNPACK_ERROR (("error parsing tag/wiretype at offset %u",
|
||||
(unsigned)(at-data)));
|
||||
goto error_cleanup;
|
||||
}
|
||||
/* XXX: consider optimizing for field[1].id == tag, if field[1] exists! */
|
||||
if (last_field->id != tag)
|
||||
{
|
||||
@ -1205,13 +1290,21 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
|
||||
if ((at[i] & 0x80) == 0)
|
||||
break;
|
||||
if (i == max_len)
|
||||
{
|
||||
UNPACK_ERROR (("unterminated varint at offset %u",
|
||||
(unsigned)(at-data)));
|
||||
goto error_cleanup;
|
||||
}
|
||||
tmp.len = i + 1;
|
||||
}
|
||||
break;
|
||||
case PROTOBUF_C_WIRE_TYPE_64BIT:
|
||||
if (rem < 8)
|
||||
{
|
||||
UNPACK_ERROR (("too short after 64bit wiretype at offset %u",
|
||||
(unsigned)(at-data)));
|
||||
goto error_cleanup;
|
||||
}
|
||||
tmp.len = 8;
|
||||
break;
|
||||
case PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED:
|
||||
@ -1219,7 +1312,10 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
|
||||
size_t pref_len;
|
||||
tmp.len = scan_length_prefixed_data (rem, at, &pref_len);
|
||||
if (tmp.len == 0)
|
||||
{
|
||||
/* NOTE: scan_length_prefixed_data calls UNPACK_ERROR */
|
||||
goto error_cleanup;
|
||||
}
|
||||
tmp.length_prefix_len = pref_len;
|
||||
break;
|
||||
}
|
||||
@ -1228,7 +1324,11 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
|
||||
PROTOBUF_C_ASSERT_NOT_REACHED ();
|
||||
case PROTOBUF_C_WIRE_TYPE_32BIT:
|
||||
if (rem < 4)
|
||||
{
|
||||
UNPACK_ERROR (("too short after 32bit wiretype at offset %u",
|
||||
(unsigned)(at-data)));
|
||||
goto error_cleanup;
|
||||
}
|
||||
tmp.len = 4;
|
||||
break;
|
||||
}
|
||||
@ -1285,9 +1385,13 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
|
||||
for (j = 0; j < max; j++)
|
||||
{
|
||||
if (!parse_member (slab + j, rv, allocator))
|
||||
{
|
||||
UNPACK_ERROR (("error parsing member %s of %s",
|
||||
slab->field->name, desc->name));
|
||||
goto error_cleanup;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* cleanup */
|
||||
if (allocator->tmp_alloc == NULL)
|
||||
|
@ -68,7 +68,18 @@ void BytesFieldGenerator::GenerateStructMembers(io::Printer* printer) const
|
||||
}
|
||||
void BytesFieldGenerator::GenerateStaticInit(io::Printer* printer) const
|
||||
{
|
||||
printer->Print("{0,NULL}");
|
||||
switch (descriptor_->label()) {
|
||||
case FieldDescriptor::LABEL_REQUIRED:
|
||||
printer->Print(variables_, "{0,NULL}");
|
||||
break;
|
||||
case FieldDescriptor::LABEL_OPTIONAL:
|
||||
printer->Print(variables_, "0,{0,NULL}");
|
||||
break;
|
||||
case FieldDescriptor::LABEL_REPEATED:
|
||||
// no support for default?
|
||||
printer->Print("0,NULL");
|
||||
break;
|
||||
}
|
||||
}
|
||||
void BytesFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const
|
||||
{
|
||||
|
32
src/test/common-test-arrays.h
Normal file
32
src/test/common-test-arrays.h
Normal file
@ -0,0 +1,32 @@
|
||||
|
||||
#define THOUSAND 1000
|
||||
#define MILLION 1000000
|
||||
#define BILLION 1000000000
|
||||
#define TRILLION 1000000000000LL
|
||||
#define QUADRILLION 1000000000000000LL
|
||||
#define QUINTILLION 1000000000000000000LL
|
||||
|
||||
int64_t int64_roundnumbers[15] = { -QUINTILLION, -QUADRILLION, -TRILLION,
|
||||
-BILLION, -MILLION, -THOUSAND,
|
||||
1,
|
||||
THOUSAND, MILLION, BILLION,
|
||||
TRILLION, QUADRILLION, QUINTILLION };
|
||||
int64_t int64_min_max[2] = { INT64_MIN, INT64_MAX };
|
||||
|
||||
uint64_t uint64_roundnumbers[9] = { 1,
|
||||
THOUSAND, MILLION, BILLION,
|
||||
TRILLION, QUADRILLION, QUINTILLION };
|
||||
uint64_t uint64_0_1_max[3] = { 0, 1, UINT64_MAX };
|
||||
uint64_t uint64_random[] = {0,
|
||||
666,
|
||||
4200000000ULL,
|
||||
16ULL * (uint64_t) QUINTILLION + 33 };
|
||||
|
||||
#define FLOATING_POINT_RANDOM \
|
||||
-1000.0, -100.0, -42.0, 0, 666, 131313
|
||||
float float_random[] = { FLOATING_POINT_RANDOM };
|
||||
double double_random[] = { FLOATING_POINT_RANDOM };
|
||||
|
||||
protobuf_c_boolean boolean_0[] = {0 };
|
||||
protobuf_c_boolean boolean_1[] = {1 };
|
||||
protobuf_c_boolean boolean_random[] = {0,1,1,0,0,1,1,1,0,0,0,0,0,1,1,1,1,1,1,0,1,1,0,1,1,0 };
|
@ -1,10 +1,16 @@
|
||||
/* generate byte arrays that match the constructs in test-generated-code2.c.
|
||||
* these are tested against eachother to make sure the c and c++ agree. */
|
||||
|
||||
#define __STDC_LIMIT_MACROS
|
||||
#include "generated-code/test-full.pb.h"
|
||||
#include <inttypes.h>
|
||||
|
||||
using namespace foo;
|
||||
|
||||
#define protobuf_c_boolean bool
|
||||
#include "common-test-arrays.h"
|
||||
#define N_ELEMENTS(arr) (sizeof(arr)/sizeof((arr)[0]))
|
||||
|
||||
static void
|
||||
dump_message_bytes(google::protobuf::Message *message,
|
||||
const char *label)
|
||||
@ -66,10 +72,254 @@ dump_test_field_numbers (void)
|
||||
DUMP_ONE (33554432)
|
||||
#undef DUMP_ONE
|
||||
}
|
||||
static void dump_test_repeated_int32 (void)
|
||||
{
|
||||
TestMess mess;
|
||||
|
||||
mess.clear_test_int32 ();
|
||||
dump_message_bytes(&mess, "test_repeated_int32__empty");
|
||||
mess.add_test_int32(-1);
|
||||
dump_message_bytes(&mess, "test_repeated_int32_m1");
|
||||
mess.add_test_int32(1);
|
||||
dump_message_bytes(&mess, "test_repeated_int32_m1_1");
|
||||
mess.clear_test_int32 ();
|
||||
mess.add_test_int32(1);
|
||||
dump_message_bytes(&mess, "test_repeated_int32_1");
|
||||
mess.clear_test_int32 ();
|
||||
mess.add_test_int32(42);
|
||||
mess.add_test_int32(666);
|
||||
mess.add_test_int32(-1123123);
|
||||
mess.add_test_int32(0);
|
||||
mess.add_test_int32(47);
|
||||
dump_message_bytes(&mess, "test_repeated_int32_42_666_m1123123_0_47");
|
||||
mess.clear_test_int32 ();
|
||||
mess.add_test_int32(INT32_MIN);
|
||||
dump_message_bytes(&mess, "test_repeated_int32_min");
|
||||
mess.clear_test_int32 ();
|
||||
mess.add_test_int32(INT32_MAX);
|
||||
dump_message_bytes(&mess, "test_repeated_int32_max");
|
||||
}
|
||||
static void dump_test_repeated_sint32 (void)
|
||||
{
|
||||
TestMess mess;
|
||||
|
||||
mess.clear_test_sint32 ();
|
||||
dump_message_bytes(&mess, "test_repeated_sint32__empty");
|
||||
mess.add_test_sint32(-1);
|
||||
dump_message_bytes(&mess, "test_repeated_sint32_m1");
|
||||
mess.add_test_sint32(1);
|
||||
dump_message_bytes(&mess, "test_repeated_sint32_m1_1");
|
||||
mess.clear_test_sint32 ();
|
||||
mess.add_test_sint32(1);
|
||||
dump_message_bytes(&mess, "test_repeated_sint32_1");
|
||||
mess.clear_test_sint32 ();
|
||||
mess.add_test_sint32(42);
|
||||
mess.add_test_sint32(666);
|
||||
mess.add_test_sint32(-1123123);
|
||||
mess.add_test_sint32(0);
|
||||
mess.add_test_sint32(47);
|
||||
dump_message_bytes(&mess, "test_repeated_sint32_42_666_m1123123_0_47");
|
||||
mess.clear_test_sint32 ();
|
||||
mess.add_test_sint32(INT32_MIN);
|
||||
dump_message_bytes(&mess, "test_repeated_sint32_min");
|
||||
mess.clear_test_sint32 ();
|
||||
mess.add_test_sint32(INT32_MAX);
|
||||
dump_message_bytes(&mess, "test_repeated_sint32_max");
|
||||
}
|
||||
static void dump_test_repeated_uint32 (void)
|
||||
{
|
||||
TestMess mess;
|
||||
mess.add_test_uint32(BILLION);
|
||||
mess.add_test_uint32(MILLION);
|
||||
mess.add_test_uint32(1);
|
||||
mess.add_test_uint32(0);
|
||||
dump_message_bytes (&mess, "test_repeated_uint32_bil_mil_1_0");
|
||||
mess.clear_test_uint32();
|
||||
mess.add_test_uint32(0);
|
||||
dump_message_bytes (&mess, "test_repeated_uint32_0");
|
||||
mess.clear_test_uint32();
|
||||
mess.add_test_uint32(UINT32_MAX);
|
||||
dump_message_bytes (&mess, "test_repeated_uint32_max");
|
||||
}
|
||||
static void dump_test_repeated_sfixed32 (void)
|
||||
{
|
||||
TestMess mess;
|
||||
|
||||
mess.clear_test_sfixed32 ();
|
||||
dump_message_bytes(&mess, "test_repeated_sfixed32__empty");
|
||||
mess.add_test_sfixed32(-1);
|
||||
dump_message_bytes(&mess, "test_repeated_sfixed32_m1");
|
||||
mess.add_test_sfixed32(1);
|
||||
dump_message_bytes(&mess, "test_repeated_sfixed32_m1_1");
|
||||
mess.clear_test_sfixed32 ();
|
||||
mess.add_test_sfixed32(1);
|
||||
dump_message_bytes(&mess, "test_repeated_sfixed32_1");
|
||||
mess.clear_test_sfixed32 ();
|
||||
mess.add_test_sfixed32(42);
|
||||
mess.add_test_sfixed32(666);
|
||||
mess.add_test_sfixed32(-1123123);
|
||||
mess.add_test_sfixed32(0);
|
||||
mess.add_test_sfixed32(47);
|
||||
dump_message_bytes(&mess, "test_repeated_sfixed32_42_666_m1123123_0_47");
|
||||
mess.clear_test_sfixed32 ();
|
||||
mess.add_test_sfixed32(INT32_MIN);
|
||||
dump_message_bytes(&mess, "test_repeated_sfixed32_min");
|
||||
mess.clear_test_sfixed32 ();
|
||||
mess.add_test_sfixed32(INT32_MAX);
|
||||
dump_message_bytes(&mess, "test_repeated_sfixed32_max");
|
||||
}
|
||||
static void dump_test_repeated_fixed32 (void)
|
||||
{
|
||||
TestMess mess;
|
||||
mess.add_test_fixed32(BILLION);
|
||||
mess.add_test_fixed32(MILLION);
|
||||
mess.add_test_fixed32(1);
|
||||
mess.add_test_fixed32(0);
|
||||
dump_message_bytes (&mess, "test_repeated_fixed32_bil_mil_1_0");
|
||||
mess.clear_test_fixed32();
|
||||
mess.add_test_fixed32(0);
|
||||
dump_message_bytes (&mess, "test_repeated_fixed32_0");
|
||||
mess.clear_test_fixed32();
|
||||
mess.add_test_fixed32(UINT32_MAX);
|
||||
dump_message_bytes (&mess, "test_repeated_fixed32_max");
|
||||
}
|
||||
static void dump_test_repeated_int64 (void)
|
||||
{
|
||||
TestMess mess;
|
||||
for (unsigned i = 0; i < N_ELEMENTS (int64_roundnumbers); i++)
|
||||
mess.add_test_int64(int64_roundnumbers[i]);
|
||||
dump_message_bytes(&mess, "test_repeated_int64_roundnumbers");
|
||||
mess.clear_test_int64();
|
||||
for (unsigned i = 0; i < N_ELEMENTS (int64_min_max); i++)
|
||||
mess.add_test_int64(int64_min_max[i]);
|
||||
dump_message_bytes(&mess, "test_repeated_int64_min_max");
|
||||
}
|
||||
|
||||
static void dump_test_repeated_sint64 (void)
|
||||
{
|
||||
TestMess mess;
|
||||
for (unsigned i = 0; i < N_ELEMENTS (int64_roundnumbers); i++)
|
||||
mess.add_test_sint64(int64_roundnumbers[i]);
|
||||
dump_message_bytes(&mess, "test_repeated_sint64_roundnumbers");
|
||||
mess.clear_test_sint64();
|
||||
for (unsigned i = 0; i < N_ELEMENTS (int64_min_max); i++)
|
||||
mess.add_test_sint64(int64_min_max[i]);
|
||||
dump_message_bytes(&mess, "test_repeated_sint64_min_max");
|
||||
}
|
||||
|
||||
static void dump_test_repeated_sfixed64 (void)
|
||||
{
|
||||
TestMess mess;
|
||||
for (unsigned i = 0; i < N_ELEMENTS (int64_roundnumbers); i++)
|
||||
mess.add_test_sfixed64(int64_roundnumbers[i]);
|
||||
dump_message_bytes(&mess, "test_repeated_sfixed64_roundnumbers");
|
||||
mess.clear_test_sfixed64();
|
||||
for (unsigned i = 0; i < N_ELEMENTS (int64_min_max); i++)
|
||||
mess.add_test_sfixed64(int64_min_max[i]);
|
||||
dump_message_bytes(&mess, "test_repeated_sfixed64_min_max");
|
||||
}
|
||||
static void dump_test_repeated_uint64 (void)
|
||||
{
|
||||
TestMess mess;
|
||||
#define DUMP_STATIC_ARRAY(static_array, output_array_name) \
|
||||
do{ \
|
||||
mess.clear_test_uint64(); \
|
||||
for (unsigned i = 0; i < N_ELEMENTS (static_array); i++) \
|
||||
mess.add_test_uint64(static_array[i]); \
|
||||
dump_message_bytes(&mess, output_array_name); \
|
||||
}while(0)
|
||||
|
||||
DUMP_STATIC_ARRAY(uint64_roundnumbers, "test_repeated_uint64_roundnumbers");
|
||||
DUMP_STATIC_ARRAY(uint64_0_1_max, "test_repeated_uint64_0_1_max");
|
||||
DUMP_STATIC_ARRAY(uint64_random, "test_repeated_uint64_random");
|
||||
|
||||
#undef DUMP_STATIC_ARRAY
|
||||
}
|
||||
static void dump_test_repeated_fixed64 (void)
|
||||
{
|
||||
TestMess mess;
|
||||
#define DUMP_STATIC_ARRAY(static_array, output_array_name) \
|
||||
do{ \
|
||||
mess.clear_test_fixed64(); \
|
||||
for (unsigned i = 0; i < N_ELEMENTS (static_array); i++) \
|
||||
mess.add_test_fixed64(static_array[i]); \
|
||||
dump_message_bytes(&mess, output_array_name); \
|
||||
}while(0)
|
||||
|
||||
DUMP_STATIC_ARRAY(uint64_roundnumbers, "test_repeated_fixed64_roundnumbers");
|
||||
DUMP_STATIC_ARRAY(uint64_0_1_max, "test_repeated_fixed64_0_1_max");
|
||||
DUMP_STATIC_ARRAY(uint64_random, "test_repeated_fixed64_random");
|
||||
|
||||
#undef DUMP_STATIC_ARRAY
|
||||
}
|
||||
|
||||
static void dump_test_repeated_float (void)
|
||||
{
|
||||
TestMess mess;
|
||||
#define DUMP_STATIC_ARRAY(static_array, output_array_name) \
|
||||
do{ \
|
||||
mess.clear_test_float(); \
|
||||
for (unsigned i = 0; i < N_ELEMENTS (static_array); i++) \
|
||||
mess.add_test_float(static_array[i]); \
|
||||
dump_message_bytes(&mess, output_array_name); \
|
||||
}while(0)
|
||||
|
||||
DUMP_STATIC_ARRAY(float_random, "test_repeated_float_random");
|
||||
|
||||
#undef DUMP_STATIC_ARRAY
|
||||
}
|
||||
|
||||
static void dump_test_repeated_double (void)
|
||||
{
|
||||
TestMess mess;
|
||||
#define DUMP_STATIC_ARRAY(static_array, output_array_name) \
|
||||
do{ \
|
||||
mess.clear_test_double(); \
|
||||
for (unsigned i = 0; i < N_ELEMENTS (static_array); i++) \
|
||||
mess.add_test_double(static_array[i]); \
|
||||
dump_message_bytes(&mess, output_array_name); \
|
||||
}while(0)
|
||||
|
||||
DUMP_STATIC_ARRAY(double_random, "test_repeated_double_random");
|
||||
|
||||
#undef DUMP_STATIC_ARRAY
|
||||
}
|
||||
static void dump_test_repeated_boolean (void)
|
||||
{
|
||||
TestMess mess;
|
||||
#define DUMP_STATIC_ARRAY(static_array, output_array_name) \
|
||||
do{ \
|
||||
mess.clear_test_boolean(); \
|
||||
for (unsigned i = 0; i < N_ELEMENTS (static_array); i++) \
|
||||
mess.add_test_boolean(static_array[i]); \
|
||||
dump_message_bytes(&mess, output_array_name); \
|
||||
}while(0)
|
||||
|
||||
DUMP_STATIC_ARRAY(boolean_0, "test_repeated_boolean_0");
|
||||
DUMP_STATIC_ARRAY(boolean_1, "test_repeated_boolean_1");
|
||||
DUMP_STATIC_ARRAY(boolean_random, "test_repeated_boolean_random");
|
||||
|
||||
#undef DUMP_STATIC_ARRAY
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
dump_test_enum_small ();
|
||||
dump_test_enum_big ();
|
||||
dump_test_field_numbers ();
|
||||
dump_test_repeated_int32 ();
|
||||
dump_test_repeated_sint32 ();
|
||||
dump_test_repeated_uint32 ();
|
||||
dump_test_repeated_sfixed32 ();
|
||||
dump_test_repeated_fixed32 ();
|
||||
dump_test_repeated_int64 ();
|
||||
dump_test_repeated_sint64 ();
|
||||
dump_test_repeated_sfixed64 ();
|
||||
dump_test_repeated_uint64 ();
|
||||
dump_test_repeated_fixed64 ();
|
||||
dump_test_repeated_float ();
|
||||
dump_test_repeated_double ();
|
||||
dump_test_repeated_boolean ();
|
||||
return 0;
|
||||
}
|
||||
|
@ -58,7 +58,7 @@ message TestMess {
|
||||
repeated fixed64 test_fixed64 = 10;
|
||||
repeated float test_float = 11;
|
||||
repeated double test_double = 12;
|
||||
repeated bool test_bool = 13;
|
||||
repeated bool test_boolean = 13;
|
||||
repeated TestEnumSmall test_enum_small = 14;
|
||||
repeated TestEnum test_enum = 15;
|
||||
repeated string test_string = 16;
|
||||
@ -79,7 +79,7 @@ message TestMessOptional {
|
||||
optional fixed64 test_fixed64 = 10;
|
||||
optional float test_float = 11;
|
||||
optional double test_double = 12;
|
||||
optional bool test_bool = 13;
|
||||
optional bool test_boolean = 13;
|
||||
optional TestEnum test_enum = 14;
|
||||
optional string test_string = 15;
|
||||
optional bytes test_bytes = 16;
|
||||
|
@ -4,6 +4,9 @@
|
||||
#include "generated-code/test-full.pb-c.h"
|
||||
#include "generated-code/test-full-cxx-output.inc"
|
||||
|
||||
#include "common-test-arrays.h"
|
||||
#define N_ELEMENTS(arr) (sizeof(arr)/sizeof((arr)[0]))
|
||||
|
||||
/* ==== helper functions ==== */
|
||||
static protobuf_c_boolean
|
||||
are_bytes_equal (unsigned actual_len,
|
||||
@ -15,9 +18,39 @@ are_bytes_equal (unsigned actual_len,
|
||||
return 0;
|
||||
return memcmp (actual_data, expected_data, actual_len) == 0;
|
||||
}
|
||||
static void
|
||||
dump_bytes_stderr (size_t len, const uint8_t *data)
|
||||
{
|
||||
size_t i;
|
||||
for (i = 0; i < len; i++)
|
||||
fprintf(stderr," %02x", data[i]);
|
||||
fprintf(stderr,"\n");
|
||||
}
|
||||
static void
|
||||
test_versus_static_array(unsigned actual_len,
|
||||
const uint8_t *actual_data,
|
||||
unsigned expected_len,
|
||||
const uint8_t *expected_data,
|
||||
const char *static_buf_name,
|
||||
const char *filename,
|
||||
unsigned lineno)
|
||||
{
|
||||
if (are_bytes_equal (actual_len, actual_data, expected_len, expected_data))
|
||||
return;
|
||||
|
||||
fprintf (stderr, "test_versus_static_array failed:\n"
|
||||
"actual: [length=%u]\n", actual_len);
|
||||
dump_bytes_stderr (actual_len, actual_data);
|
||||
fprintf (stderr, "expected: [length=%u] [buffer %s]\n",
|
||||
expected_len, static_buf_name);
|
||||
dump_bytes_stderr (expected_len, expected_data);
|
||||
fprintf (stderr, "at line %u of %s.\n", lineno, filename);
|
||||
abort();
|
||||
}
|
||||
|
||||
#define TEST_VERSUS_STATIC_ARRAY(actual_len, actual_data, buf) \
|
||||
assert(are_bytes_equal(actual_len,actual_data, \
|
||||
sizeof(buf), buf))
|
||||
test_versus_static_array(actual_len,actual_data, \
|
||||
sizeof(buf), buf, #buf, __FILE__, __LINE__)
|
||||
|
||||
/* rv is unpacked message */
|
||||
static void *
|
||||
@ -46,30 +79,52 @@ test_compare_pack_methods (ProtobufCMessage *message,
|
||||
return rv;
|
||||
}
|
||||
|
||||
#define NUMERIC_EQUALS(a,b) ((a) == (b))
|
||||
#define STRING_EQUALS(a,b) (strcmp((a),(b))==0)
|
||||
#define DO_TEST_REPEATED(lc_member_name, static_array, example_packed_data, \
|
||||
equals_macro) \
|
||||
do{ \
|
||||
Foo__TestMess mess = FOO__TEST_MESS__INIT; \
|
||||
Foo__TestMess *mess2; \
|
||||
size_t len; \
|
||||
uint8_t *data; \
|
||||
unsigned i; \
|
||||
mess.n_##lc_member_name = N_ELEMENTS (static_array); \
|
||||
mess.lc_member_name = static_array; \
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); \
|
||||
assert(mess2->n_##lc_member_name == N_ELEMENTS (static_array)); \
|
||||
for (i = 0; i < N_ELEMENTS (static_array); i++) \
|
||||
assert(equals_macro(mess2->lc_member_name[i], static_array[i])); \
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, example_packed_data); \
|
||||
free (data); \
|
||||
foo__test_mess__free_unpacked (mess2, NULL); \
|
||||
}while(0)
|
||||
|
||||
/* === the actual tests === */
|
||||
|
||||
static void test_enum_small (void)
|
||||
{
|
||||
Foo__TestMessRequiredEnumSmall small = FOO__TEST_MESS_REQUIRED_ENUM_SMALL__INIT;
|
||||
size_t len;
|
||||
uint8_t *data;
|
||||
Foo__TestMessRequiredEnumSmall *unpacked;
|
||||
|
||||
#define DO_TEST(UC_VALUE) \
|
||||
do{ \
|
||||
Foo__TestMessRequiredEnumSmall small = FOO__TEST_MESS_REQUIRED_ENUM_SMALL__INIT; \
|
||||
size_t len; \
|
||||
uint8_t *data; \
|
||||
Foo__TestMessRequiredEnumSmall *unpacked; \
|
||||
small.test = FOO__TEST_ENUM_SMALL__##UC_VALUE; \
|
||||
unpacked = test_compare_pack_methods ((ProtobufCMessage*)&small, &len, &data); \
|
||||
assert (unpacked->test == FOO__TEST_ENUM_SMALL__##UC_VALUE); \
|
||||
foo__test_mess_required_enum_small__free_unpacked (unpacked, NULL); \
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_enum_small_##UC_VALUE); \
|
||||
free (data); \
|
||||
}while(0)
|
||||
|
||||
assert (sizeof (Foo__TestEnumSmall) == 4);
|
||||
|
||||
small.test = FOO__TEST_ENUM_SMALL__VALUE;
|
||||
unpacked = test_compare_pack_methods ((ProtobufCMessage*)&small, &len, &data);
|
||||
assert (unpacked->test == FOO__TEST_ENUM_SMALL__VALUE);
|
||||
foo__test_mess_required_enum_small__free_unpacked (unpacked, NULL);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_enum_small_VALUE);
|
||||
free (data);
|
||||
DO_TEST(VALUE);
|
||||
DO_TEST(OTHER_VALUE);
|
||||
|
||||
small.test = FOO__TEST_ENUM_SMALL__OTHER_VALUE;
|
||||
unpacked = test_compare_pack_methods ((ProtobufCMessage*)&small, &len, &data);
|
||||
assert (unpacked->test == FOO__TEST_ENUM_SMALL__OTHER_VALUE);
|
||||
foo__test_mess_required_enum_small__free_unpacked (unpacked, NULL);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_enum_small_OTHER_VALUE);
|
||||
free (data);
|
||||
#undef DO_TEST
|
||||
}
|
||||
|
||||
static void test_enum_big (void)
|
||||
@ -132,6 +187,492 @@ static void test_field_numbers (void)
|
||||
DO_ONE_TEST (33554432, 5 + 1 + 3);
|
||||
#undef DO_ONE_TEST
|
||||
}
|
||||
static void test_repeated_int32 (void)
|
||||
{
|
||||
Foo__TestMess mess = FOO__TEST_MESS__INIT;
|
||||
Foo__TestMess *mess2;
|
||||
int32_t arr0[2] = { -1, 1 };
|
||||
int32_t arr1[5] = { 42, 666, -1123123, 0, 47 };
|
||||
int32_t arr_min[1] = { INT32_MIN };
|
||||
int32_t arr_max[1] = { INT32_MAX };
|
||||
size_t len;
|
||||
uint8_t *data;
|
||||
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_int32 == 0);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_int32__empty);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_int32 = 1;
|
||||
mess.test_int32 = arr0;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_int32 == 1);
|
||||
assert(mess2->test_int32[0] == -1);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_int32_m1);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_int32 = 1;
|
||||
mess.test_int32 = arr0+1;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_int32 == 1);
|
||||
assert(mess2->test_int32[0] == 1);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_int32_1);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_int32 = 2;
|
||||
mess.test_int32 = arr0;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_int32 == 2);
|
||||
assert(mess2->test_int32[0] == -1);
|
||||
assert(mess2->test_int32[1] == 1);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_int32_m1_1);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_int32 = 5;
|
||||
mess.test_int32 = arr1;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_int32 == 5);
|
||||
assert(memcmp (mess2->test_int32, arr1, 4*5)==0);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_int32_42_666_m1123123_0_47);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_int32 = 1;
|
||||
mess.test_int32 = arr_min;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_int32 == 1);
|
||||
assert(mess2->test_int32[0] == INT32_MIN);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_int32_min);
|
||||
free (data);
|
||||
|
||||
mess.n_test_int32 = 1;
|
||||
mess.test_int32 = arr_max;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_int32 == 1);
|
||||
assert(mess2->test_int32[0] == INT32_MAX);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_int32_max);
|
||||
free (data);
|
||||
}
|
||||
|
||||
static void test_repeated_sint32 (void)
|
||||
{
|
||||
Foo__TestMess mess = FOO__TEST_MESS__INIT;
|
||||
Foo__TestMess *mess2;
|
||||
int32_t arr0[2] = { -1, 1 };
|
||||
int32_t arr1[5] = { 42, 666, -1123123, 0, 47 };
|
||||
int32_t arr_min[1] = { INT32_MIN };
|
||||
int32_t arr_max[1] = { INT32_MAX };
|
||||
size_t len;
|
||||
uint8_t *data;
|
||||
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_sint32 == 0);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sint32__empty);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_sint32 = 1;
|
||||
mess.test_sint32 = arr0;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_sint32 == 1);
|
||||
assert(mess2->test_sint32[0] == -1);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sint32_m1);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_sint32 = 1;
|
||||
mess.test_sint32 = arr0+1;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_sint32 == 1);
|
||||
assert(mess2->test_sint32[0] == 1);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sint32_1);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_sint32 = 2;
|
||||
mess.test_sint32 = arr0;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_sint32 == 2);
|
||||
assert(mess2->test_sint32[0] == -1);
|
||||
assert(mess2->test_sint32[1] == 1);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sint32_m1_1);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_sint32 = 5;
|
||||
mess.test_sint32 = arr1;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_sint32 == 5);
|
||||
assert(memcmp (mess2->test_sint32, arr1, 4*5)==0);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sint32_42_666_m1123123_0_47);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_sint32 = 1;
|
||||
mess.test_sint32 = arr_min;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_sint32 == 1);
|
||||
assert(mess2->test_sint32[0] == INT32_MIN);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sint32_min);
|
||||
free (data);
|
||||
|
||||
mess.n_test_sint32 = 1;
|
||||
mess.test_sint32 = arr_max;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_sint32 == 1);
|
||||
assert(mess2->test_sint32[0] == INT32_MAX);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sint32_max);
|
||||
free (data);
|
||||
}
|
||||
|
||||
static void test_repeated_sfixed32 (void)
|
||||
{
|
||||
Foo__TestMess mess = FOO__TEST_MESS__INIT;
|
||||
Foo__TestMess *mess2;
|
||||
int32_t arr0[2] = { -1, 1 };
|
||||
int32_t arr1[5] = { 42, 666, -1123123, 0, 47 };
|
||||
int32_t arr_min[1] = { INT32_MIN };
|
||||
int32_t arr_max[1] = { INT32_MAX };
|
||||
size_t len;
|
||||
uint8_t *data;
|
||||
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_sfixed32 == 0);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sfixed32__empty);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_sfixed32 = 1;
|
||||
mess.test_sfixed32 = arr0;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_sfixed32 == 1);
|
||||
assert(mess2->test_sfixed32[0] == -1);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sfixed32_m1);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_sfixed32 = 1;
|
||||
mess.test_sfixed32 = arr0+1;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_sfixed32 == 1);
|
||||
assert(mess2->test_sfixed32[0] == 1);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sfixed32_1);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_sfixed32 = 2;
|
||||
mess.test_sfixed32 = arr0;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_sfixed32 == 2);
|
||||
assert(mess2->test_sfixed32[0] == -1);
|
||||
assert(mess2->test_sfixed32[1] == 1);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sfixed32_m1_1);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_sfixed32 = 5;
|
||||
mess.test_sfixed32 = arr1;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_sfixed32 == 5);
|
||||
assert(memcmp (mess2->test_sfixed32, arr1, 4*5)==0);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sfixed32_42_666_m1123123_0_47);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_sfixed32 = 1;
|
||||
mess.test_sfixed32 = arr_min;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_sfixed32 == 1);
|
||||
assert(mess2->test_sfixed32[0] == INT32_MIN);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sfixed32_min);
|
||||
free (data);
|
||||
|
||||
mess.n_test_sfixed32 = 1;
|
||||
mess.test_sfixed32 = arr_max;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_sfixed32 == 1);
|
||||
assert(mess2->test_sfixed32[0] == INT32_MAX);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sfixed32_max);
|
||||
free (data);
|
||||
}
|
||||
|
||||
static void test_repeated_uint32 (void)
|
||||
{
|
||||
Foo__TestMess mess = FOO__TEST_MESS__INIT;
|
||||
Foo__TestMess *mess2;
|
||||
uint32_t arr0[4] = { BILLION, MILLION, 1, 0 };
|
||||
uint32_t arr_zero[1] = { 0 };
|
||||
uint32_t arr_max[1] = { UINT32_MAX };
|
||||
size_t len;
|
||||
uint8_t *data;
|
||||
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_uint32 == 0);
|
||||
assert(len == 0);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_uint32 = 4;
|
||||
mess.test_uint32 = arr0;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_uint32 == 4);
|
||||
assert(mess2->test_uint32[0] == BILLION);
|
||||
assert(mess2->test_uint32[1] == MILLION);
|
||||
assert(mess2->test_uint32[2] == 1);
|
||||
assert(mess2->test_uint32[3] == 0);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_uint32_bil_mil_1_0);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_uint32 = 1;
|
||||
mess.test_uint32 = arr_zero;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_uint32 == 1);
|
||||
assert(mess2->test_uint32[0] == 0);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_uint32_0);
|
||||
free (data);
|
||||
|
||||
mess.n_test_uint32 = 1;
|
||||
mess.test_uint32 = arr_max;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_uint32 == 1);
|
||||
assert(mess2->test_uint32[0] == UINT32_MAX);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_uint32_max);
|
||||
free (data);
|
||||
}
|
||||
|
||||
static void test_repeated_fixed32 (void)
|
||||
{
|
||||
Foo__TestMess mess = FOO__TEST_MESS__INIT;
|
||||
Foo__TestMess *mess2;
|
||||
uint32_t arr0[4] = { BILLION, MILLION, 1, 0 };
|
||||
uint32_t arr_zero[1] = { 0 };
|
||||
uint32_t arr_max[1] = { UINT32_MAX };
|
||||
size_t len;
|
||||
uint8_t *data;
|
||||
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_fixed32 == 0);
|
||||
assert(len == 0);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_fixed32 = 4;
|
||||
mess.test_fixed32 = arr0;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_fixed32 == 4);
|
||||
assert(mess2->test_fixed32[0] == BILLION);
|
||||
assert(mess2->test_fixed32[1] == MILLION);
|
||||
assert(mess2->test_fixed32[2] == 1);
|
||||
assert(mess2->test_fixed32[3] == 0);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_fixed32_bil_mil_1_0);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_fixed32 = 1;
|
||||
mess.test_fixed32 = arr_zero;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_fixed32 == 1);
|
||||
assert(mess2->test_fixed32[0] == 0);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_fixed32_0);
|
||||
free (data);
|
||||
|
||||
mess.n_test_fixed32 = 1;
|
||||
mess.test_fixed32 = arr_max;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_fixed32 == 1);
|
||||
assert(mess2->test_fixed32[0] == UINT32_MAX);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_fixed32_max);
|
||||
free (data);
|
||||
}
|
||||
|
||||
static void test_repeated_int64 (void)
|
||||
{
|
||||
Foo__TestMess mess = FOO__TEST_MESS__INIT;
|
||||
Foo__TestMess *mess2;
|
||||
size_t len;
|
||||
uint8_t *data;
|
||||
unsigned i;
|
||||
|
||||
mess.n_test_int64 = N_ELEMENTS (int64_roundnumbers);
|
||||
mess.test_int64 = int64_roundnumbers;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_int64 == N_ELEMENTS (int64_roundnumbers));
|
||||
for (i = 0; i < N_ELEMENTS (int64_roundnumbers); i++)
|
||||
assert(mess2->test_int64[i] == int64_roundnumbers[i]);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_int64_roundnumbers);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_int64 = N_ELEMENTS (int64_min_max);
|
||||
mess.test_int64 = int64_min_max;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_int64 == N_ELEMENTS (int64_min_max));
|
||||
assert(mess2->test_int64[0] == INT64_MIN);
|
||||
assert(mess2->test_int64[1] == INT64_MAX);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_int64_min_max);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
}
|
||||
|
||||
static void test_repeated_sint64 (void)
|
||||
{
|
||||
Foo__TestMess mess = FOO__TEST_MESS__INIT;
|
||||
Foo__TestMess *mess2;
|
||||
size_t len;
|
||||
uint8_t *data;
|
||||
unsigned i;
|
||||
|
||||
mess.n_test_sint64 = N_ELEMENTS (int64_roundnumbers);
|
||||
mess.test_sint64 = int64_roundnumbers;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_sint64 == N_ELEMENTS (int64_roundnumbers));
|
||||
for (i = 0; i < N_ELEMENTS (int64_roundnumbers); i++)
|
||||
assert(mess2->test_sint64[i] == int64_roundnumbers[i]);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sint64_roundnumbers);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_sint64 = N_ELEMENTS (int64_min_max);
|
||||
mess.test_sint64 = int64_min_max;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_sint64 == N_ELEMENTS (int64_min_max));
|
||||
assert(mess2->test_sint64[0] == INT64_MIN);
|
||||
assert(mess2->test_sint64[1] == INT64_MAX);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sint64_min_max);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
}
|
||||
|
||||
static void test_repeated_sfixed64 (void)
|
||||
{
|
||||
Foo__TestMess mess = FOO__TEST_MESS__INIT;
|
||||
Foo__TestMess *mess2;
|
||||
size_t len;
|
||||
uint8_t *data;
|
||||
unsigned i;
|
||||
|
||||
mess.n_test_sfixed64 = N_ELEMENTS (int64_roundnumbers);
|
||||
mess.test_sfixed64 = int64_roundnumbers;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_sfixed64 == N_ELEMENTS (int64_roundnumbers));
|
||||
for (i = 0; i < N_ELEMENTS (int64_roundnumbers); i++)
|
||||
assert(mess2->test_sfixed64[i] == int64_roundnumbers[i]);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sfixed64_roundnumbers);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
|
||||
mess.n_test_sfixed64 = N_ELEMENTS (int64_min_max);
|
||||
mess.test_sfixed64 = int64_min_max;
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data);
|
||||
assert(mess2->n_test_sfixed64 == N_ELEMENTS (int64_min_max));
|
||||
assert(mess2->test_sfixed64[0] == INT64_MIN);
|
||||
assert(mess2->test_sfixed64[1] == INT64_MAX);
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, test_repeated_sfixed64_min_max);
|
||||
free (data);
|
||||
foo__test_mess__free_unpacked (mess2, NULL);
|
||||
}
|
||||
|
||||
static void test_repeated_uint64 (void)
|
||||
{
|
||||
Foo__TestMess mess = FOO__TEST_MESS__INIT;
|
||||
Foo__TestMess *mess2;
|
||||
size_t len;
|
||||
uint8_t *data;
|
||||
unsigned i;
|
||||
|
||||
#define DO_TEST(static_array, example_packed_data) \
|
||||
do{ \
|
||||
mess.n_test_uint64 = N_ELEMENTS (static_array); \
|
||||
mess.test_uint64 = static_array; \
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); \
|
||||
assert(mess2->n_test_uint64 == N_ELEMENTS (static_array)); \
|
||||
for (i = 0; i < N_ELEMENTS (static_array); i++) \
|
||||
assert(mess2->test_uint64[i] == static_array[i]); \
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, example_packed_data); \
|
||||
free (data); \
|
||||
foo__test_mess__free_unpacked (mess2, NULL); \
|
||||
}while(0)
|
||||
|
||||
DO_TEST(uint64_roundnumbers, test_repeated_uint64_roundnumbers);
|
||||
DO_TEST(uint64_0_1_max, test_repeated_uint64_0_1_max);
|
||||
DO_TEST(uint64_random, test_repeated_uint64_random);
|
||||
|
||||
#undef DO_TEST
|
||||
}
|
||||
|
||||
static void test_repeated_fixed64 (void)
|
||||
{
|
||||
Foo__TestMess mess = FOO__TEST_MESS__INIT;
|
||||
Foo__TestMess *mess2;
|
||||
size_t len;
|
||||
uint8_t *data;
|
||||
unsigned i;
|
||||
|
||||
#define DO_TEST(static_array, example_packed_data) \
|
||||
do{ \
|
||||
mess.n_test_fixed64 = N_ELEMENTS (static_array); \
|
||||
mess.test_fixed64 = static_array; \
|
||||
mess2 = test_compare_pack_methods ((ProtobufCMessage*)(&mess), &len, &data); \
|
||||
assert(mess2->n_test_fixed64 == N_ELEMENTS (static_array)); \
|
||||
for (i = 0; i < N_ELEMENTS (static_array); i++) \
|
||||
assert(mess2->test_fixed64[i] == static_array[i]); \
|
||||
TEST_VERSUS_STATIC_ARRAY (len, data, example_packed_data); \
|
||||
free (data); \
|
||||
foo__test_mess__free_unpacked (mess2, NULL); \
|
||||
}while(0)
|
||||
|
||||
DO_TEST(uint64_roundnumbers, test_repeated_fixed64_roundnumbers);
|
||||
DO_TEST(uint64_0_1_max, test_repeated_fixed64_0_1_max);
|
||||
DO_TEST(uint64_random, test_repeated_fixed64_random);
|
||||
|
||||
#undef DO_TEST
|
||||
}
|
||||
|
||||
static void test_repeated_float (void)
|
||||
{
|
||||
|
||||
#define DO_TEST(static_array, example_packed_data) \
|
||||
DO_TEST_REPEATED(test_float, \
|
||||
static_array, example_packed_data, \
|
||||
NUMERIC_EQUALS)
|
||||
|
||||
DO_TEST(float_random, test_repeated_float_random);
|
||||
|
||||
#undef DO_TEST
|
||||
}
|
||||
|
||||
static void test_repeated_double (void)
|
||||
{
|
||||
|
||||
#define DO_TEST(static_array, example_packed_data) \
|
||||
DO_TEST_REPEATED(test_double, \
|
||||
static_array, example_packed_data, \
|
||||
NUMERIC_EQUALS)
|
||||
|
||||
DO_TEST(double_random, test_repeated_double_random);
|
||||
|
||||
#undef DO_TEST
|
||||
}
|
||||
|
||||
static void test_repeated_boolean (void)
|
||||
{
|
||||
|
||||
#define DO_TEST(static_array, example_packed_data) \
|
||||
DO_TEST_REPEATED(test_boolean, \
|
||||
static_array, example_packed_data, \
|
||||
NUMERIC_EQUALS)
|
||||
|
||||
DO_TEST(boolean_0, test_repeated_boolean_0);
|
||||
DO_TEST(boolean_1, test_repeated_boolean_1);
|
||||
DO_TEST(boolean_random, test_repeated_boolean_random);
|
||||
|
||||
#undef DO_TEST
|
||||
}
|
||||
|
||||
/* === simple testing framework === */
|
||||
|
||||
@ -147,60 +688,60 @@ static Test tests[] =
|
||||
{ "small enums", test_enum_small },
|
||||
{ "big enums", test_enum_big },
|
||||
{ "test field numbers", test_field_numbers },
|
||||
//{ "test repeated int32" ,test_repeated_int32 },
|
||||
//{ "test repeated sint32" ,test_repeated_sint32 },
|
||||
//{ "test repeated sfixed32" ,test_repeated_sfixed32 },
|
||||
//{ "test repeated int64" ,test_repeated_int64 },
|
||||
//{ "test repeated sint64" ,test_repeated_sint64 },
|
||||
//{ "test repeated sfixed64" ,test_repeated_sfixed64 },
|
||||
//{ "test repeated uint32" ,test_repeated_uint32 },
|
||||
//{ "test repeated fixed32" ,test_repeated_fixed32 },
|
||||
//{ "test repeated uint64" ,test_repeated_uint64 },
|
||||
//{ "test repeated fixed64" ,test_repeated_fixed64 },
|
||||
//{ "test repeated float" ,test_repeated_float },
|
||||
//{ "test repeated double" ,test_repeated_double },
|
||||
//{ "test repeated bool" ,test_repeated_bool },
|
||||
//{ "test repeated TestEnumSmall" ,test_repeated_TestEnumSmall },
|
||||
//{ "test repeated TestEnum" ,test_repeated_TestEnum },
|
||||
//{ "test repeated string" ,test_repeated_string },
|
||||
//{ "test repeated bytes" ,test_repeated_bytes },
|
||||
//{ "test repeated SubMess" ,test_repeated_SubMess },
|
||||
//{ "test optional int32" ,test_optional_int32 },
|
||||
//{ "test optional sint32" ,test_optional_sint32 },
|
||||
//{ "test optional sfixed32" ,test_optional_sfixed32 },
|
||||
//{ "test optional int64" ,test_optional_int64 },
|
||||
//{ "test optional sint64" ,test_optional_sint64 },
|
||||
//{ "test optional sfixed64" ,test_optional_sfixed64 },
|
||||
//{ "test optional uint32" ,test_optional_uint32 },
|
||||
//{ "test optional fixed32" ,test_optional_fixed32 },
|
||||
//{ "test optional uint64" ,test_optional_uint64 },
|
||||
//{ "test optional fixed64" ,test_optional_fixed64 },
|
||||
//{ "test optional float" ,test_optional_float },
|
||||
//{ "test optional double" ,test_optional_double },
|
||||
//{ "test optional bool" ,test_optional_bool },
|
||||
//{ "test optional TestEnumSmall" ,test_optional_TestEnumSmall },
|
||||
//{ "test optional TestEnum" ,test_optional_TestEnum },
|
||||
//{ "test optional string" ,test_optional_string },
|
||||
//{ "test optional bytes" ,test_optional_bytes },
|
||||
//{ "test optional SubMess" ,test_optional_SubMess },
|
||||
//{ "test required int32" ,test_required_int32 },
|
||||
//{ "test required sint32" ,test_required_sint32 },
|
||||
//{ "test required sfixed32" ,test_required_sfixed32 },
|
||||
//{ "test required int64" ,test_required_int64 },
|
||||
//{ "test required sint64" ,test_required_sint64 },
|
||||
//{ "test required sfixed64" ,test_required_sfixed64 },
|
||||
//{ "test required uint32" ,test_required_uint32 },
|
||||
//{ "test required fixed32" ,test_required_fixed32 },
|
||||
//{ "test required uint64" ,test_required_uint64 },
|
||||
//{ "test required fixed64" ,test_required_fixed64 },
|
||||
//{ "test required float" ,test_required_float },
|
||||
//{ "test required double" ,test_required_double },
|
||||
//{ "test required bool" ,test_required_bool },
|
||||
//{ "test required TestEnumSmall" ,test_required_TestEnumSmall },
|
||||
//{ "test required TestEnum" ,test_required_TestEnum },
|
||||
//{ "test required string" ,test_required_string },
|
||||
//{ "test required bytes" ,test_required_bytes },
|
||||
//{ "test required SubMess" ,test_required_SubMess },
|
||||
{ "test repeated int32" ,test_repeated_int32 },
|
||||
{ "test repeated sint32" ,test_repeated_sint32 },
|
||||
{ "test repeated sfixed32" ,test_repeated_sfixed32 },
|
||||
{ "test repeated uint32", test_repeated_uint32 },
|
||||
{ "test repeated int64", test_repeated_int64 },
|
||||
{ "test repeated sint64", test_repeated_sint64 },
|
||||
{ "test repeated sfixed64", test_repeated_sfixed64 },
|
||||
{ "test repeated fixed32", test_repeated_fixed32 },
|
||||
{ "test repeated uint64", test_repeated_uint64 },
|
||||
{ "test repeated fixed64", test_repeated_fixed64 },
|
||||
{ "test repeated float", test_repeated_float },
|
||||
{ "test repeated double", test_repeated_double },
|
||||
{ "test repeated boolean", test_repeated_boolean },
|
||||
//{ "test repeated TestEnumSmall", test_repeated_TestEnumSmall },
|
||||
//{ "test repeated TestEnum", test_repeated_TestEnum },
|
||||
//{ "test repeated string", test_repeated_string },
|
||||
//{ "test repeated bytes", test_repeated_bytes },
|
||||
//{ "test repeated SubMess", test_repeated_SubMess },
|
||||
//{ "test optional int32", test_optional_int32 },
|
||||
//{ "test optional sint32", test_optional_sint32 },
|
||||
//{ "test optional sfixed32", test_optional_sfixed32 },
|
||||
//{ "test optional int64", test_optional_int64 },
|
||||
//{ "test optional sint64", test_optional_sint64 },
|
||||
//{ "test optional sfixed64", test_optional_sfixed64 },
|
||||
//{ "test optional uint32", test_optional_uint32 },
|
||||
//{ "test optional fixed32", test_optional_fixed32 },
|
||||
//{ "test optional uint64", test_optional_uint64 },
|
||||
//{ "test optional fixed64", test_optional_fixed64 },
|
||||
//{ "test optional float", test_optional_float },
|
||||
//{ "test optional double", test_optional_double },
|
||||
//{ "test optional bool", test_optional_bool },
|
||||
//{ "test optional TestEnumSmall", test_optional_TestEnumSmall },
|
||||
//{ "test optional TestEnum", test_optional_TestEnum },
|
||||
//{ "test optional string", test_optional_string },
|
||||
//{ "test optional bytes", test_optional_bytes },
|
||||
//{ "test optional SubMess", test_optional_SubMess },
|
||||
//{ "test required int32", test_required_int32 },
|
||||
//{ "test required sint32", test_required_sint32 },
|
||||
//{ "test required sfixed32", test_required_sfixed32 },
|
||||
//{ "test required int64", test_required_int64 },
|
||||
//{ "test required sint64", test_required_sint64 },
|
||||
//{ "test required sfixed64", test_required_sfixed64 },
|
||||
//{ "test required uint32", test_required_uint32 },
|
||||
//{ "test required fixed32", test_required_fixed32 },
|
||||
//{ "test required uint64", test_required_uint64 },
|
||||
//{ "test required fixed64", test_required_fixed64 },
|
||||
//{ "test required float", test_required_float },
|
||||
//{ "test required double", test_required_double },
|
||||
//{ "test required bool", test_required_bool },
|
||||
//{ "test required TestEnumSmall", test_required_TestEnumSmall },
|
||||
//{ "test required TestEnum", test_required_TestEnum },
|
||||
//{ "test required string", test_required_string },
|
||||
//{ "test required bytes", test_required_bytes },
|
||||
//{ "test required SubMess", test_required_SubMess },
|
||||
};
|
||||
#define n_tests (sizeof(tests)/sizeof(Test))
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user