protoc-c: add const_strings option

Keep default as false to preserve backwards compatibility.

Fixes #239
parent cebe3d03
...@@ -45,6 +45,9 @@ message ProtobufCFileOptions { ...@@ -45,6 +45,9 @@ message ProtobufCFileOptions {
// Generate helper init message functions? // Generate helper init message functions?
optional bool gen_init_helpers = 3 [default = true]; optional bool gen_init_helpers = 3 [default = true];
// Use const char * instead of char * for string fields
optional bool const_strings = 4 [default = false];
} }
extend google.protobuf.FileOptions { extend google.protobuf.FileOptions {
......
...@@ -93,13 +93,19 @@ StringFieldGenerator::~StringFieldGenerator() {} ...@@ -93,13 +93,19 @@ StringFieldGenerator::~StringFieldGenerator() {}
void StringFieldGenerator::GenerateStructMembers(io::Printer* printer) const void StringFieldGenerator::GenerateStructMembers(io::Printer* printer) const
{ {
const ProtobufCFileOptions opt = descriptor_->file()->options().GetExtension(pb_c_file);
switch (descriptor_->label()) { switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED: case FieldDescriptor::LABEL_REQUIRED:
case FieldDescriptor::LABEL_OPTIONAL: case FieldDescriptor::LABEL_OPTIONAL:
if (opt.const_strings())
printer->Print(variables_, "const ");
printer->Print(variables_, "char *$name$$deprecated$;\n"); printer->Print(variables_, "char *$name$$deprecated$;\n");
break; break;
case FieldDescriptor::LABEL_REPEATED: case FieldDescriptor::LABEL_REPEATED:
printer->Print(variables_, "size_t n_$name$$deprecated$;\n"); printer->Print(variables_, "size_t n_$name$$deprecated$;\n");
if (opt.const_strings())
printer->Print(variables_, "const ");
printer->Print(variables_, "char **$name$$deprecated$;\n"); printer->Print(variables_, "char **$name$$deprecated$;\n");
break; break;
} }
...@@ -123,10 +129,13 @@ std::string StringFieldGenerator::GetDefaultValue(void) const ...@@ -123,10 +129,13 @@ std::string StringFieldGenerator::GetDefaultValue(void) const
void StringFieldGenerator::GenerateStaticInit(io::Printer* printer) const void StringFieldGenerator::GenerateStaticInit(io::Printer* printer) const
{ {
std::map<std::string, std::string> vars; std::map<std::string, std::string> vars;
const ProtobufCFileOptions opt = descriptor_->file()->options().GetExtension(pb_c_file);
if (descriptor_->has_default_value()) { if (descriptor_->has_default_value()) {
vars["default"] = GetDefaultValue(); vars["default"] = GetDefaultValue();
} else if (FieldSyntax(descriptor_) == 2) { } else if (FieldSyntax(descriptor_) == 2) {
vars["default"] = "NULL"; vars["default"] = "NULL";
} else if (opt.const_strings()) {
vars["default"] = "(const char *)protobuf_c_empty_string";
} else { } else {
vars["default"] = "(char *)protobuf_c_empty_string"; vars["default"] = "(char *)protobuf_c_empty_string";
} }
......
...@@ -56,7 +56,7 @@ TEST_ENUM_TYPE_NAME enum_random[] = { ...@@ -56,7 +56,7 @@ TEST_ENUM_TYPE_NAME enum_random[] = {
T(0), T(2097152), T(268435455), T(127), T(16383), T(16384) }; T(0), T(2097152), T(268435455), T(127), T(16383), T(16384) };
#undef T #undef T
char *repeated_strings_0[] = { (char*)"onestring" }; const char *repeated_strings_0[] = { "onestring" };
char *repeated_strings_1[] = { (char*)"two", (char*)"string" }; const char *repeated_strings_1[] = { "two", "string" };
char *repeated_strings_2[] = { (char*)"many", (char*)"tiny", (char*)"little", (char*)"strings", (char*)"should", (char*)"be", (char*)"handled" }; const char *repeated_strings_2[] = { "many", "tiny", "little", "strings", "should", "be", "handled" };
char *repeated_strings_3[] = { (char*)"one very long strings XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" }; const char *repeated_strings_3[] = { "one very long strings XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" };
...@@ -1274,7 +1274,7 @@ static void test_repeated_string (void) ...@@ -1274,7 +1274,7 @@ static void test_repeated_string (void)
{ {
#define DO_TEST(static_array, example_packed_data) \ #define DO_TEST(static_array, example_packed_data) \
DO_TEST_REPEATED(test_string, (char **), \ DO_TEST_REPEATED(test_string, (const char **), \
static_array, example_packed_data, \ static_array, example_packed_data, \
STRING_EQUALS) STRING_EQUALS)
...@@ -2109,8 +2109,8 @@ test_message_check(void) ...@@ -2109,8 +2109,8 @@ test_message_check(void)
Foo__TestMessageCheck__SubMessage sm = FOO__TEST_MESSAGE_CHECK__SUB_MESSAGE__INIT; Foo__TestMessageCheck__SubMessage sm = FOO__TEST_MESSAGE_CHECK__SUB_MESSAGE__INIT;
Foo__TestMessageCheck__SubMessage sm2 = FOO__TEST_MESSAGE_CHECK__SUB_MESSAGE__INIT; Foo__TestMessageCheck__SubMessage sm2 = FOO__TEST_MESSAGE_CHECK__SUB_MESSAGE__INIT;
Foo__TestMessageCheck m = FOO__TEST_MESSAGE_CHECK__INIT; Foo__TestMessageCheck m = FOO__TEST_MESSAGE_CHECK__INIT;
char *null = NULL; const char *null = NULL;
char *str = ""; const char *str = "";
Foo__TestMessageCheck__SubMessage *sm_p; Foo__TestMessageCheck__SubMessage *sm_p;
ProtobufCBinaryData bd; ProtobufCBinaryData bd;
......
...@@ -2,6 +2,8 @@ package foo; ...@@ -2,6 +2,8 @@ package foo;
import "protobuf-c/protobuf-c.proto"; import "protobuf-c/protobuf-c.proto";
option (pb_c_file).const_strings = true;
message SubMess { message SubMess {
required int32 test = 4; required int32 test = 4;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment