add static init

add test code (beginnings of very thorough test)


git-svn-id: https://protobuf-c.googlecode.com/svn/trunk@33 00440858-1255-0410-a3e6-75ea37f81c3a
This commit is contained in:
lahiker42 2008-08-23 19:59:17 +00:00
parent 8542d664b2
commit ee774e97ad
22 changed files with 514 additions and 17 deletions

9
TODO
View File

@ -1,8 +1,15 @@
- check over documentation again
- handle unknown fields when packing
- test code
- ensure enums are 32-bit
- make messages derive from ProtobufCMessage,
which should have the unknown field array
- make services derive from ProtobufCService;
be usable with a cast.
- provide example rpc
- use size_t wherever appropriate in generated code, and in uses of that code (eg
pack and unpack)
- ensure enums are 32-bit
- support Group (whatever it is)
- almost no code generator options are obeyed
- ISSUE: strings may not contain NULs

View File

@ -1,5 +1,5 @@
AC_INIT(src/google/protobuf-c/protobuf-c.h)
PROTOBUF_C_VERSION=0.0
PROTOBUF_C_VERSION=0.1
AM_INIT_AUTOMAKE(protobuf-c, $PROTOBUF_C_VERSION)
PACKAGE=protobuf-c

View File

@ -33,6 +33,7 @@ void (*protobuf_c_out_of_memory) (void) = protobuf_c_out_of_memory_default;
static void *system_alloc(void *allocator_data, size_t size)
{
void *rv;
(void) allocator_data;
if (size == 0)
return NULL;
rv = malloc (size);
@ -43,6 +44,7 @@ static void *system_alloc(void *allocator_data, size_t size)
static void system_free (void *allocator_data, void *data)
{
(void) allocator_data;
if (data)
free (data);
}
@ -621,6 +623,7 @@ required_field_pack_to_buffer (const ProtobufCFieldDescriptor *field,
break;
case PROTOBUF_C_TYPE_INT32:
case PROTOBUF_C_TYPE_UINT32:
case PROTOBUF_C_TYPE_ENUM:
scratch[0] |= PROTOBUF_C_WIRE_TYPE_VARINT;
rv += uint32_pack (*(uint32_t *) member, scratch + rv);
buffer->append (buffer, rv, scratch);
@ -780,7 +783,7 @@ int_range_lookup (unsigned n_ranges,
{
n = mid - start;
}
else if (value >= ranges[mid].start_value + (ranges[mid+1].orig_index-ranges[mid].orig_index))
else if (value >= ranges[mid].start_value + (int)(ranges[mid+1].orig_index-ranges[mid].orig_index))
{
unsigned new_start = mid + 1;
n = start + n - new_start;
@ -795,7 +798,7 @@ int_range_lookup (unsigned n_ranges,
unsigned range_size = ranges[start+1].orig_index - start_orig_index;
if (ranges[start].start_value <= value
&& value < ranges[start].start_value + range_size)
&& value < (int)(ranges[start].start_value + range_size))
return (value - ranges[start].start_value) + start_orig_index;
}
return -1;
@ -1011,9 +1014,9 @@ parse_required_member (ScannedMember *scanned_member,
return 1;
case PROTOBUF_C_TYPE_ENUM:
if (wire_type != PROTOBUF_C_WIRE_TYPE_32BIT)
if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT)
return 0;
*(uint32_t*)member = parse_fixed_uint32 (data);
*(uint32_t*)member = parse_uint32 (len, data);
return 1;
case PROTOBUF_C_TYPE_STRING:
@ -1159,7 +1162,7 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
while (rem > 0)
{
size_t tag;
uint32_t tag;
ProtobufCWireType wire_type;
size_t used = parse_tag_and_wiretype (rem, at, &tag, &wire_type);
const ProtobufCFieldDescriptor *field;
@ -1230,7 +1233,7 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
tmp.len = 4;
break;
}
if (in_slab_index == (1<<(which_slab+4)))
if (in_slab_index == (1U<<(which_slab+4)))
{
size_t size;
in_slab_index = 0;
@ -1278,7 +1281,7 @@ protobuf_c_message_unpack (const ProtobufCMessageDescriptor *desc,
/* do real parsing */
for (i_slab = 0; i_slab <= which_slab; i_slab++)
{
unsigned max = (i_slab == which_slab) ? in_slab_index : (1<<(i_slab+4));
unsigned max = (i_slab == which_slab) ? in_slab_index : (1U<<(i_slab+4));
ScannedMember *slab = scanned_member_slabs[i_slab];
unsigned j;
for (j = 0; j < max; j++)

View File

@ -106,7 +106,7 @@ typedef struct _ProtobufCFieldDescriptor ProtobufCFieldDescriptor;
struct _ProtobufCFieldDescriptor
{
const char *name;
int id;
uint32_t id;
ProtobufCLabel label;
ProtobufCType type;
unsigned quantifier_offset;

View File

@ -66,6 +66,10 @@ void BytesFieldGenerator::GenerateStructMembers(io::Printer* printer) const
break;
}
}
void BytesFieldGenerator::GenerateStaticInit(io::Printer* printer) const
{
printer->Print("{0,NULL}");
}
void BytesFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const
{
GenerateDescriptorInitializerGeneric(printer, true, "BYTES", "NULL");

View File

@ -40,6 +40,7 @@ class BytesFieldGenerator : public FieldGenerator {
// implements FieldGenerator ---------------------------------------
void GenerateStructMembers(io::Printer* printer) const;
void GenerateDescriptorInitializer(io::Printer* printer) const;
void GenerateStaticInit(io::Printer* printer) const;
private:
map<string, string> variables_;

View File

@ -71,6 +71,20 @@ void EnumFieldGenerator::GenerateStructMembers(io::Printer* printer) const
break;
}
}
void EnumFieldGenerator::GenerateStaticInit(io::Printer* printer) const
{
// TODO: use symbolic name
switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED:
case FieldDescriptor::LABEL_OPTIONAL:
printer->Print(variables_, "$default$");
break;
case FieldDescriptor::LABEL_REPEATED:
// no support for default?
printer->Print("0,NULL");
break;
}
}
void EnumFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const
{

View File

@ -40,6 +40,7 @@ class EnumFieldGenerator : public FieldGenerator {
// implements FieldGenerator ---------------------------------------
void GenerateStructMembers(io::Printer* printer) const;
void GenerateDescriptorInitializer(io::Printer* printer) const;
void GenerateStaticInit(io::Printer* printer) const;
private:
map<string, string> variables_;

View File

@ -48,6 +48,10 @@ class FieldGenerator {
// Generate a static initializer for this field.
virtual void GenerateDescriptorInitializer(io::Printer* printer) const = 0;
// Generate members to initialize this field from a static initializer
virtual void GenerateStaticInit(io::Printer* printer) const = 0;
protected:
void GenerateDescriptorInitializerGeneric(io::Printer* printer,
bool optional_uses_has,

View File

@ -127,6 +127,9 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
for (int i = 0; i < file_->message_type_count(); i++) {
message_generators_[i]->GenerateEnumDefinitions(printer);
}
for (int i = 0; i < file_->enum_type_count(); i++) {
enum_generators_[i]->GenerateDefinition(printer);
}
// Generate class definitions.
printer->Print("\n/* --- messages --- */\n\n");
@ -156,7 +159,7 @@ void FileGenerator::GenerateHeader(io::Printer* printer) {
printer->Print("\n/* --- descriptors --- */\n\n");
for (int i = 0; i < file_->enum_type_count(); i++) {
enum_generators_[i]->GenerateDefinition(printer);
enum_generators_[i]->GenerateDescriptorDeclarations(printer);
}
for (int i = 0; i < file_->message_type_count(); i++) {
message_generators_[i]->GenerateDescriptorDeclarations(printer);

View File

@ -98,6 +98,8 @@ GenerateStructDefinition(io::Printer* printer) {
std::map<string, string> vars;
vars["classname"] = FullNameToC(descriptor_->full_name());
vars["lcclassname"] = FullNameToLower(descriptor_->full_name());
vars["ucclassname"] = FullNameToUpper(descriptor_->full_name());
vars["field_count"] = SimpleItoa(descriptor_->field_count());
if (dllexport_decl_.empty()) {
vars["dllexport"] = "";
@ -121,6 +123,16 @@ GenerateStructDefinition(io::Printer* printer) {
printer->Print(vars, " /* private */\n");
printer->Print(vars, " ProtobufCMessageUnknownFieldArray unknown_field_array;\n");
printer->Print(vars, "};\n\n");
printer->Print(vars, "#define $ucclassname$__INIT \\\n"
" { &$lcclassname$__descriptor");
for (int i = 0; i < descriptor_->field_count(); i++) {
const FieldDescriptor *field = descriptor_->field(i);
printer->Print(", ");
field_generators_.get(field).GenerateStaticInit(printer);
}
printer->Print(" }\n");
}
void MessageGenerator::

View File

@ -66,6 +66,9 @@ class MessageGenerator {
// Generate definitions for this class and all its nested types.
void GenerateStructDefinition(io::Printer* printer);
// Generate __INIT macro for populating this structure
void GenerateStructStaticInitMacro(io::Printer* printer);
// Generate standard helper functions declarations for this message.
void GenerateHelperFunctionDeclarations(io::Printer* printer);

View File

@ -57,6 +57,18 @@ void MessageFieldGenerator::GenerateStructMembers(io::Printer* printer) const
break;
}
}
void MessageFieldGenerator::GenerateStaticInit(io::Printer* printer) const
{
switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED:
case FieldDescriptor::LABEL_OPTIONAL:
printer->Print("NULL");
break;
case FieldDescriptor::LABEL_REPEATED:
printer->Print("0,NULL");
break;
}
}
void MessageFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const
{
string addr = "&" + FullNameToLower(descriptor_->message_type()->full_name()) + "__descriptor";

View File

@ -40,6 +40,7 @@ class MessageFieldGenerator : public FieldGenerator {
// implements FieldGenerator ---------------------------------------
void GenerateStructMembers(io::Printer* printer) const;
void GenerateDescriptorInitializer(io::Printer* printer) const;
void GenerateStaticInit(io::Printer* printer) const;
private:

View File

@ -81,6 +81,18 @@ void PrimitiveFieldGenerator::GenerateStructMembers(io::Printer* printer) const
break;
}
}
void PrimitiveFieldGenerator::GenerateStaticInit(io::Printer* printer) const
{
switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED:
case FieldDescriptor::LABEL_OPTIONAL:
printer->Print("0");
break;
case FieldDescriptor::LABEL_REPEATED:
printer->Print("0,NULL");
break;
}
}
void PrimitiveFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const
{

View File

@ -40,6 +40,7 @@ class PrimitiveFieldGenerator : public FieldGenerator {
// implements FieldGenerator ---------------------------------------
void GenerateStructMembers(io::Printer* printer) const;
void GenerateDescriptorInitializer(io::Printer* printer) const;
void GenerateStaticInit(io::Printer* printer) const;
private:

View File

@ -63,6 +63,19 @@ void StringFieldGenerator::GenerateStructMembers(io::Printer* printer) const
break;
}
}
void StringFieldGenerator::GenerateStaticInit(io::Printer* printer) const
{
// TODO: no support for defaults?
switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED:
case FieldDescriptor::LABEL_OPTIONAL:
printer->Print("NULL");
break;
case FieldDescriptor::LABEL_REPEATED:
printer->Print("0,NULL");
break;
}
}
void StringFieldGenerator::GenerateDescriptorInitializer(io::Printer* printer) const
{
GenerateDescriptorInitializerGeneric(printer, false, "STRING", "NULL");

View File

@ -40,6 +40,7 @@ class StringFieldGenerator : public FieldGenerator {
// implements FieldGenerator ---------------------------------------
void GenerateStructMembers(io::Printer* printer) const;
void GenerateDescriptorInitializer(io::Printer* printer) const;
void GenerateStaticInit(io::Printer* printer) const;
private:
map<string, string> variables_;

View File

@ -1,17 +1,36 @@
check_PROGRAMS = test-generated-code
check_PROGRAMS = test-generated-code test-generated-code2
noinst_PROGRAMS = cxx-generate-packed-data
INCLUDES = -I$(srcdir)/..
test_generated_code_SOURCES = \
test-generated-code.c \
generated-code/test.pb-c.c
test_generated_code_LDADD = \
../libprotobuf-c.la
test_generated_code2_SOURCES = \
test-generated-code2.c \
generated-code/test-full.pb-c.c
test_generated_code2_LDADD = \
../libprotobuf-c.la
cxx_generate_packed_data_SOURCES = \
cxx-generate-packed-data.cc generated-code/test-full.pb.cc
cxx_generate_packed_data_LDADD = -lprotobuf
generated-code/test.pb-c.c generated-code/test.pb-c.h: ../protoc-c $(srcdir)/test.proto
rm -rf generated-code
mkdir generated-code
mkdir -p generated-code
../protoc-c -I$(srcdir) --c_out=generated-code $(srcdir)/test.proto
generated-code/test-full.pb-c.c generated-code/test-full.pb-c.h: ../protoc-c $(srcdir)/test-full.proto
mkdir -p generated-code
../protoc-c -I$(srcdir) --c_out=generated-code $(srcdir)/test-full.proto
generated-code/test-full.pb.cc generated-code/test-full.pb.h: $(srcdir)/test-full.proto
mkdir -p generated-code
protoc -I$(srcdir) --cpp_out=generated-code $(srcdir)/test-full.proto
generated-code/test-full-cxx-output.inc: cxx-generate-packed-data
./cxx-generate-packed-data > generated-code/test-full-cxx-output.inc
BUILT_SOURCES = generated-code/test.pb-c.c generated-code/test.pb-c.h
BUILT_SOURCES = generated-code/test.pb-c.c generated-code/test.pb-c.h \
generated-code/test-full.pb-c.c generated-code/test-full.pb-c.h \
generated-code/test-full.pb.cc generated-code/test-full.pb.h \
generated-code/test-full-cxx-output.inc
DISTCLEANFILES = $(BUILT_SOURCES)
TESTS = test-generated-code
EXTRA_DIST = test.proto
TESTS = test-generated-code test-generated-code2
EXTRA_DIST = test.proto test-full.proto

View File

@ -0,0 +1,57 @@
/* 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. */
#include "generated-code/test-full.pb.h"
using namespace foo;
static void
dump_message_bytes(google::protobuf::Message *message,
const char *label)
{
std::string rv;
unsigned char *bytes;
unsigned len;
if (!message->SerializeToString(&rv))
assert(0);
bytes = (unsigned char *) rv.data();
len = rv.size();
printf ("static const uint8_t %s[%u] = { ", label, len);
for (unsigned i = 0; i < len; i++) {
if (i)
printf (", ");
printf ("0x%02x", bytes[i]);
}
printf (" };\n");
}
static void
dump_test_enum_small (void)
{
TestMessRequiredEnumSmall es;
es.set_test(VALUE);
dump_message_bytes(&es, "test_enum_small_VALUE");
es.set_test(OTHER_VALUE);
dump_message_bytes(&es, "test_enum_small_OTHER_VALUE");
}
static void
dump_test_enum_big (void)
{
TestMessRequiredEnum eb;
eb.set_test(VALUE0); dump_message_bytes(&eb, "test_enum_big_VALUE0");
eb.set_test(VALUE127); dump_message_bytes(&eb, "test_enum_big_VALUE127");
eb.set_test(VALUE128); dump_message_bytes(&eb, "test_enum_big_VALUE128");
eb.set_test(VALUE16383); dump_message_bytes(&eb, "test_enum_big_VALUE16383");
eb.set_test(VALUE16384); dump_message_bytes(&eb, "test_enum_big_VALUE16384");
eb.set_test(VALUE2097151); dump_message_bytes(&eb, "test_enum_big_VALUE2097151");
eb.set_test(VALUE2097152); dump_message_bytes(&eb, "test_enum_big_VALUE2097152");
eb.set_test(VALUE268435455); dump_message_bytes(&eb, "test_enum_big_VALUE268435455");
eb.set_test(VALUE268435456); dump_message_bytes(&eb, "test_enum_big_VALUE268435456");
}
int main(int argc, char **argv)
{
dump_test_enum_small ();
dump_test_enum_big ();
return 0;
}

143
src/test/test-full.proto Normal file
View File

@ -0,0 +1,143 @@
package foo;
message SubMess {
required int32 test = 4;
};
enum TestEnumSmall {
VALUE = 0;
OTHER_VALUE = 1;
}
enum TestEnum {
VALUE0 = 0;
VALUE127 = 127;
VALUE128 = 128;
VALUE16383 = 16383;
VALUE16384 = 16384;
VALUE2097151 = 2097151;
VALUE2097152 = 2097152;
VALUE268435455 = 268435455;
VALUE268435456 = 268435456;
};
message TestFieldNo15 { // should use 1 byte header
required string test = 15;
}
message TestFieldNo16 { // requires 2 byte header
required string test = 16;
}
message TestFieldNo2047 { // should use 2 byte header
required string test = 2047;
}
message TestFieldNo2048 { // requires 3 byte header
required string test = 2048;
}
message TestFieldNo262143 { // should use 3 byte header
required string test = 262143;
}
message TestFieldNo262144 { // requires 4 byte header
required string test = 262144;
}
message TestFieldNo33554431 { // should use 4 byte header
required string test = 33554431;
}
message TestFieldNo33554432 { // requires 5 byte header
required string test = 33554432;
}
message TestMess {
repeated int32 test_int32 = 1;
repeated sint32 test_sint32 = 2;
repeated sfixed32 test_sfixed32 = 3;
repeated int64 test_int64 = 4;
repeated sint64 test_sint64 = 5;
repeated sfixed64 test_sfixed64 = 6;
repeated uint32 test_uint32 = 7;
repeated fixed32 test_fixed32 = 8;
repeated uint64 test_uint64 = 9;
repeated fixed64 test_fixed64 = 10;
repeated float test_float = 11;
repeated double test_double = 12;
repeated bool test_bool = 13;
repeated TestEnumSmall test_enum_small = 14;
repeated TestEnum test_enum = 15;
repeated string test_string = 16;
repeated bytes test_bytes = 17;
repeated SubMess test_message = 18;
}
message TestMessOptional {
optional int32 test_int32 = 1;
optional sint32 test_sint32 = 2;
optional sfixed32 test_sfixed32 = 3;
optional int64 test_int64 = 4;
optional sint64 test_sint64 = 5;
optional sfixed64 test_sfixed64 = 6;
optional uint32 test_uint32 = 7;
optional fixed32 test_fixed32 = 8;
optional uint64 test_uint64 = 9;
optional fixed64 test_fixed64 = 10;
optional float test_float = 11;
optional double test_double = 12;
optional bool test_bool = 13;
optional TestEnum test_enum = 14;
optional string test_string = 15;
optional bytes test_bytes = 16;
optional SubMess test_message = 17;
}
message TestMessRequiredInt32 {
required int32 test = 42;
}
message TestMessRequiredSInt32 {
required sint32 test = 43;
}
message TestMessRequiredSFixed32 {
required sfixed32 test = 100;
}
message TestMessRequiredInt64 {
required int64 test = 1;
}
message TestMessRequiredSInt64 {
required sint64 test = 11;
}
message TestMessRequiredSFixed64 {
required sfixed64 test = 12;
}
message TestMessRequiredUInt32 {
required uint32 test = 1;
}
message TestMessRequiredFixed32 {
required fixed32 test = 1;
}
message TestMessRequiredUInt64 {
required uint64 test = 1;
}
message TestMessRequiredFixed64 {
required fixed64 test = 1;
}
message TestMessRequiredFloat {
required float test = 1;
}
message TestMessRequiredDouble {
required double test = 1;
}
message TestMessRequiredBool {
required bool test = 1;
}
message TestMessRequiredEnum {
required TestEnum test = 1;
}
message TestMessRequiredEnumSmall {
required TestEnumSmall test = 1;
}
message TestMessRequiredString {
required string test = 1;
}
message TestMessRequiredBytes {
required bytes test = 1;
}
message TestMessRequiredMessage {
required SubMess test = 1;
}

View File

@ -0,0 +1,186 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "generated-code/test-full.pb-c.h"
#include "generated-code/test-full-cxx-output.inc"
/* ==== helper functions ==== */
static protobuf_c_boolean
are_bytes_equal (unsigned actual_len,
const uint8_t *actual_data,
unsigned expected_len,
const uint8_t *expected_data)
{
if (actual_len != expected_len)
return 0;
return memcmp (actual_data, expected_data, actual_len) == 0;
}
#define TEST_VERSUS_STATIC_ARRAY(actual_len, actual_data, buf) \
assert(are_bytes_equal(actual_len,actual_data, \
sizeof(buf), buf))
/* rv is unpacked message */
static void *
test_compare_pack_methods (ProtobufCMessage *message,
size_t *packed_len_out,
uint8_t **packed_out)
{
unsigned char scratch[16];
ProtobufCBufferSimple bs = PROTOBUF_C_BUFFER_SIMPLE_INIT (scratch);
size_t siz1 = protobuf_c_message_get_packed_size (message);
size_t siz2;
size_t siz3 = protobuf_c_message_pack_to_buffer (message, &bs.base);
void *packed1 = malloc (siz1);
void *rv;
assert (packed1 != NULL);
assert (siz1 == siz3);
siz2 = protobuf_c_message_pack (message, packed1);
assert (siz1 == siz2);
assert (bs.len == siz1);
assert (memcmp (bs.data, packed1, siz1) == 0);
rv = protobuf_c_message_unpack (message->descriptor, NULL, siz1, packed1);
assert (rv != NULL);
PROTOBUF_C_BUFFER_SIMPLE_CLEAR (&bs);
*packed_len_out = siz1;
*packed_out = packed1;
return rv;
}
/* === 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;
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);
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);
}
static void test_enum_big (void)
{
Foo__TestMessRequiredEnum big = FOO__TEST_MESS_REQUIRED_ENUM__INIT;
size_t len;
uint8_t *data;
Foo__TestMessRequiredEnumSmall *unpacked;
#define DO_ONE_TEST(shortname, numeric_value, encoded_len) \
do{ \
big.test = FOO__TEST_ENUM__##shortname; \
unpacked = test_compare_pack_methods ((ProtobufCMessage*)&big, &len, &data); \
assert (unpacked->test == FOO__TEST_ENUM__##shortname); \
foo__test_mess_required_enum__free_unpacked (unpacked, NULL); \
TEST_VERSUS_STATIC_ARRAY (len, data, test_enum_big_##shortname); \
assert (encoded_len + 1 == len); \
assert (big.test == numeric_value); \
free (data); \
}while(0)
DO_ONE_TEST(VALUE0, 0, 1);
DO_ONE_TEST(VALUE127, 127, 1);
DO_ONE_TEST(VALUE128, 128, 2);
DO_ONE_TEST(VALUE16383, 16383, 2);
DO_ONE_TEST(VALUE16384, 16384, 3);
DO_ONE_TEST(VALUE2097151, 2097151, 3);
DO_ONE_TEST(VALUE2097152, 2097152, 4);
DO_ONE_TEST(VALUE268435455, 268435455, 4);
DO_ONE_TEST(VALUE268435456, 268435456, 5);
#undef DO_ONE_TEST
}
/* === simple testing framework === */
typedef void (*TestFunc) (void);
typedef struct {
const char *name;
TestFunc func;
} Test;
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 },
};
#define n_tests (sizeof(tests)/sizeof(Test))
int main (int argc, char **argv)
{
unsigned i;
for (i = 0; i < n_tests; i++)
{
fprintf (stderr, "Test: %s... ", tests[i].name);
tests[i].func ();
fprintf (stderr, " done.\n");
}
return 0;
}