aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--java/src/test/java/com/google/protobuf/GeneratedMessageTest.java1
-rwxr-xr-xpython/google/protobuf/internal/generator_test.py1
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_file.cc2
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_helpers.cc8
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_helpers.h3
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_string_field.cc3
-rw-r--r--src/google/protobuf/compiler/cpp/cpp_unittest.cc7
-rw-r--r--src/google/protobuf/unittest.proto7
8 files changed, 28 insertions, 4 deletions
diff --git a/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java b/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java
index 3675e003..b9dd40bf 100644
--- a/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java
+++ b/java/src/test/java/com/google/protobuf/GeneratedMessageTest.java
@@ -410,6 +410,7 @@ public class GeneratedMessageTest extends TestCase {
assertEquals(Float.POSITIVE_INFINITY, message.getInfFloat());
assertEquals(Float.NEGATIVE_INFINITY, message.getNegInfFloat());
assertTrue(Float.isNaN(message.getNanFloat()));
+ assertEquals("? ? ?? ?? ??? ??/ ??-", message.getCppTrigraph());
}
public void testClear() throws Exception {
diff --git a/python/google/protobuf/internal/generator_test.py b/python/google/protobuf/internal/generator_test.py
index e4387c85..b3f7d9b1 100755
--- a/python/google/protobuf/internal/generator_test.py
+++ b/python/google/protobuf/internal/generator_test.py
@@ -100,6 +100,7 @@ class GeneratorTest(unittest.TestCase):
self.assertTrue(isinf(message.neg_inf_float))
self.assertTrue(message.neg_inf_float < 0)
self.assertTrue(isnan(message.nan_float))
+ self.assertEqual("? ? ?? ?? ??? ??/ ??-", message.cpp_trigraph)
def testHasDefaultValues(self):
desc = unittest_pb2.TestAllTypes.DESCRIPTOR
diff --git a/src/google/protobuf/compiler/cpp/cpp_file.cc b/src/google/protobuf/compiler/cpp/cpp_file.cc
index 22d6fdba..312ebc86 100644
--- a/src/google/protobuf/compiler/cpp/cpp_file.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_file.cc
@@ -541,7 +541,7 @@ void FileGenerator::GenerateBuildDescriptors(io::Printer* printer) {
static const int kBytesPerLine = 40;
for (int i = 0; i < file_data.size(); i += kBytesPerLine) {
printer->Print("\n \"$data$\"",
- "data", CEscape(file_data.substr(i, kBytesPerLine)));
+ "data", EscapeTrigraphs(CEscape(file_data.substr(i, kBytesPerLine))));
}
printer->Print(
", $size$);\n",
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.cc b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
index e3df88b0..25b05a85 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.cc
@@ -292,7 +292,8 @@ string DefaultValue(const FieldDescriptor* field) {
ClassName(field->enum_type(), true),
field->default_value_enum()->number());
case FieldDescriptor::CPPTYPE_STRING:
- return "\"" + CEscape(field->default_value_string()) + "\"";
+ return "\"" + EscapeTrigraphs(CEscape(field->default_value_string())) +
+ "\"";
case FieldDescriptor::CPPTYPE_MESSAGE:
return FieldMessageTypeName(field) + "::default_instance()";
}
@@ -335,6 +336,11 @@ string GlobalShutdownFileName(const string& filename) {
return "protobuf_ShutdownFile_" + FilenameIdentifier(filename);
}
+// Escape C++ trigraphs by escaping question marks to \?
+string EscapeTrigraphs(const string& to_escape) {
+ return StringReplace(to_escape, "?", "\\?", true);
+}
+
} // namespace cpp
} // namespace compiler
} // namespace protobuf
diff --git a/src/google/protobuf/compiler/cpp/cpp_helpers.h b/src/google/protobuf/compiler/cpp/cpp_helpers.h
index f99b5fe8..b13d53be 100644
--- a/src/google/protobuf/compiler/cpp/cpp_helpers.h
+++ b/src/google/protobuf/compiler/cpp/cpp_helpers.h
@@ -112,6 +112,9 @@ string GlobalAssignDescriptorsName(const string& filename);
// Return the name of the ShutdownFile() function for a given file.
string GlobalShutdownFileName(const string& filename);
+// Escape C++ trigraphs by escaping question marks to \?
+string EscapeTrigraphs(const string& to_escape);
+
// Do message classes in this file keep track of unknown fields?
inline bool HasUnknownFields(const FileDescriptor *file) {
return file->options().optimize_for() != FileOptions::LITE_RUNTIME;
diff --git a/src/google/protobuf/compiler/cpp/cpp_string_field.cc b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
index 67d7eae6..8d611b69 100644
--- a/src/google/protobuf/compiler/cpp/cpp_string_field.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_string_field.cc
@@ -48,8 +48,7 @@ namespace {
void SetStringVariables(const FieldDescriptor* descriptor,
map<string, string>* variables) {
SetCommonFieldVariables(descriptor, variables);
- (*variables)["default"] =
- "\"" + CEscape(descriptor->default_value_string()) + "\"";
+ (*variables)["default"] = DefaultValue(descriptor);
(*variables)["default_variable"] = descriptor->default_value_string().empty()
? "::google::protobuf::internal::kEmptyString"
: "_default_" + FieldName(descriptor) + "_";
diff --git a/src/google/protobuf/compiler/cpp/cpp_unittest.cc b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
index a950583e..301a7ce6 100644
--- a/src/google/protobuf/compiler/cpp/cpp_unittest.cc
+++ b/src/google/protobuf/compiler/cpp/cpp_unittest.cc
@@ -167,6 +167,13 @@ TEST(GeneratedMessageTest, FloatingPointDefaults) {
EXPECT_TRUE(extreme_default.nan_float() != extreme_default.nan_float());
}
+TEST(GeneratedMessageTest, Trigraph) {
+ const unittest::TestExtremeDefaultValues& extreme_default =
+ unittest::TestExtremeDefaultValues::default_instance();
+
+ EXPECT_EQ("? ? ?? ?? ??? ?\?/ ?\?-", extreme_default.cpp_trigraph());
+}
+
TEST(GeneratedMessageTest, Accessors) {
// Set every field to a unique value then go back and check all those
// values.
diff --git a/src/google/protobuf/unittest.proto b/src/google/protobuf/unittest.proto
index de4425be..97ec6747 100644
--- a/src/google/protobuf/unittest.proto
+++ b/src/google/protobuf/unittest.proto
@@ -493,6 +493,13 @@ message TestExtremeDefaultValues {
optional float inf_float = 17 [default = inf];
optional float neg_inf_float = 18 [default = -inf];
optional float nan_float = 19 [default = nan];
+
+ // Tests for C++ trigraphs.
+ // Trigraphs should be escaped in C++ generated files, but they should not be
+ // escaped for other languages.
+ // Note that in .proto file, "\?" is a valid way to escape ? in string
+ // literals.
+ optional string cpp_trigraph = 20 [default = "? \? ?? \?? \??? ??/ ?\?-"];
}
message SparseEnumMessage {