From 5c20ca1fccbf0b4d19f5823517fde2869101f921 Mon Sep 17 00:00:00 2001 From: "liujisi@google.com" Date: Tue, 21 Dec 2010 05:33:13 +0000 Subject: Escape C++ Trigraphs. --- java/src/test/java/com/google/protobuf/GeneratedMessageTest.java | 1 + python/google/protobuf/internal/generator_test.py | 1 + src/google/protobuf/compiler/cpp/cpp_file.cc | 2 +- src/google/protobuf/compiler/cpp/cpp_helpers.cc | 8 +++++++- src/google/protobuf/compiler/cpp/cpp_helpers.h | 3 +++ src/google/protobuf/compiler/cpp/cpp_string_field.cc | 3 +-- src/google/protobuf/compiler/cpp/cpp_unittest.cc | 7 +++++++ src/google/protobuf/unittest.proto | 7 +++++++ 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* 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 { -- cgit v1.2.3