protoc-c: add const_strings option

Keep default as false to preserve backwards compatibility.

Fixes #239
This commit is contained in:
Ilya Lipnitskiy 2021-03-21 14:57:27 -07:00
parent cebe3d03f9
commit dfb6e300fa
No known key found for this signature in database
GPG Key ID: 435C02AAE7CF2014
5 changed files with 21 additions and 7 deletions

View File

@ -45,6 +45,9 @@ message ProtobufCFileOptions {
// Generate helper init message functions?
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 {

View File

@ -93,13 +93,19 @@ StringFieldGenerator::~StringFieldGenerator() {}
void StringFieldGenerator::GenerateStructMembers(io::Printer* printer) const
{
const ProtobufCFileOptions opt = descriptor_->file()->options().GetExtension(pb_c_file);
switch (descriptor_->label()) {
case FieldDescriptor::LABEL_REQUIRED:
case FieldDescriptor::LABEL_OPTIONAL:
if (opt.const_strings())
printer->Print(variables_, "const ");
printer->Print(variables_, "char *$name$$deprecated$;\n");
break;
case FieldDescriptor::LABEL_REPEATED:
printer->Print(variables_, "size_t n_$name$$deprecated$;\n");
if (opt.const_strings())
printer->Print(variables_, "const ");
printer->Print(variables_, "char **$name$$deprecated$;\n");
break;
}
@ -123,10 +129,13 @@ std::string StringFieldGenerator::GetDefaultValue(void) const
void StringFieldGenerator::GenerateStaticInit(io::Printer* printer) const
{
std::map<std::string, std::string> vars;
const ProtobufCFileOptions opt = descriptor_->file()->options().GetExtension(pb_c_file);
if (descriptor_->has_default_value()) {
vars["default"] = GetDefaultValue();
} else if (FieldSyntax(descriptor_) == 2) {
vars["default"] = "NULL";
} else if (opt.const_strings()) {
vars["default"] = "(const char *)protobuf_c_empty_string";
} else {
vars["default"] = "(char *)protobuf_c_empty_string";
}

View File

@ -56,7 +56,7 @@ TEST_ENUM_TYPE_NAME enum_random[] = {
T(0), T(2097152), T(268435455), T(127), T(16383), T(16384) };
#undef T
char *repeated_strings_0[] = { (char*)"onestring" };
char *repeated_strings_1[] = { (char*)"two", (char*)"string" };
char *repeated_strings_2[] = { (char*)"many", (char*)"tiny", (char*)"little", (char*)"strings", (char*)"should", (char*)"be", (char*)"handled" };
char *repeated_strings_3[] = { (char*)"one very long strings XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" };
const char *repeated_strings_0[] = { "onestring" };
const char *repeated_strings_1[] = { "two", "string" };
const char *repeated_strings_2[] = { "many", "tiny", "little", "strings", "should", "be", "handled" };
const char *repeated_strings_3[] = { "one very long strings XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" };

View File

@ -1274,7 +1274,7 @@ static void test_repeated_string (void)
{
#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, \
STRING_EQUALS)
@ -2109,8 +2109,8 @@ test_message_check(void)
Foo__TestMessageCheck__SubMessage sm = 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;
char *null = NULL;
char *str = "";
const char *null = NULL;
const char *str = "";
Foo__TestMessageCheck__SubMessage *sm_p;
ProtobufCBinaryData bd;

View File

@ -2,6 +2,8 @@ package foo;
import "protobuf-c/protobuf-c.proto";
option (pb_c_file).const_strings = true;
message SubMess {
required int32 test = 4;