From fcf30e6d499e5215d38fecf81613bdac842106fc Mon Sep 17 00:00:00 2001 From: temporal Date: Mon, 21 Jul 2008 20:28:30 +0000 Subject: misc. stuff: - Improved readmes. - Fixed incorrect definition of kint32min. - Fixed absolute output paths on Windows. - Added info to Java POM that will be required when we upload the package to a Maven repo. git-svn-id: http://protobuf.googlecode.com/svn/trunk@22 630680e5-0e50-0410-840e-4b1c322b438d --- .../protobuf/compiler/command_line_interface.cc | 33 ++++++---- .../compiler/command_line_interface_unittest.cc | 71 +++++++++++++++++++++- src/google/protobuf/stubs/common.h | 2 +- src/google/protobuf/stubs/common_unittest.cc | 11 ++++ 4 files changed, 104 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc index 68e88a8..6c2c9e8 100644 --- a/src/google/protobuf/compiler/command_line_interface.cc +++ b/src/google/protobuf/compiler/command_line_interface.cc @@ -29,6 +29,7 @@ #endif #include #include +#include #include #include @@ -67,6 +68,20 @@ static const char* kPathSeparator = ";"; #else static const char* kPathSeparator = ":"; #endif + +// Returns true if the text looks like a Windows-style absolute path, starting +// with a drive letter. Example: "C:\foo". +static bool IsWindowsAbsolutePath(const string& text) { +#if defined(_WIN32) || defined(__CYGWIN__) + return text.size() >= 3 && text[1] == ':' && + isalpha(text[0]) && + (text[2] == '/' || text[2] == '\\') && + text.find_last_of(':') == 1; +#else + return false; +#endif +} + } // namespace // A MultiFileErrorCollector that prints errors to stderr. @@ -502,18 +517,14 @@ bool CommandLineInterface::InterpretArgument(const string& name, directive.generator = iter->second.generator; // Split value at ':' to separate the generator parameter from the - // filename. - vector parts; - SplitStringUsing(value, ":", &parts); - - if (parts.size() == 1) { - directive.output_location = parts[0]; - } else if (parts.size() == 2) { - directive.parameter = parts[0]; - directive.output_location = parts[1]; + // filename. However, avoid doing this if the colon is part of a valid + // Windows-style absolute path. + string::size_type colon_pos = value.find_first_of(':'); + if (colon_pos == string::npos || IsWindowsAbsolutePath(value)) { + directive.output_location = value; } else { - cerr << "Invalid value for flag " << name << "." << endl; - return false; + directive.parameter = value.substr(0, colon_pos); + directive.output_location = value.substr(colon_pos + 1); } output_directives_.push_back(directive); diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc index 1b1458d..0964446 100644 --- a/src/google/protobuf/compiler/command_line_interface_unittest.cc +++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc @@ -51,6 +51,7 @@ class CommandLineInterfaceTest : public testing::Test { // Methods to set up the test (called before Run()). class MockCodeGenerator; + class NullCodeGenerator; // Registers a MockCodeGenerator with the given name. MockCodeGenerator* RegisterGenerator(const string& generator_name, @@ -63,6 +64,10 @@ class CommandLineInterfaceTest : public testing::Test { const string& filename, const string& help_text); + // Registers a CodeGenerator which will not actually generate anything, + // but records the parameter passed to the generator. + NullCodeGenerator* RegisterNullGenerator(const string& flag_name); + // Create a temp file within temp_directory_ with the given name. // The containing directory is also created if necessary. void CreateTempFile(const string& name, const string& contents); @@ -122,7 +127,7 @@ class CommandLineInterfaceTest : public testing::Test { string error_text_; // Pointers which need to be deleted later. - vector mock_generators_to_delete_; + vector mock_generators_to_delete_; }; // A mock CodeGenerator which outputs information about the context in which @@ -159,6 +164,25 @@ class CommandLineInterfaceTest::MockCodeGenerator : public CodeGenerator { bool expect_write_error_; }; +class CommandLineInterfaceTest::NullCodeGenerator : public CodeGenerator { + public: + NullCodeGenerator() : called_(false) {} + ~NullCodeGenerator() {} + + mutable bool called_; + mutable string parameter_; + + // implements CodeGenerator ---------------------------------------- + bool Generate(const FileDescriptor* file, + const string& parameter, + OutputDirectory* output_directory, + string* error) const { + called_ = true; + parameter_ = parameter; + return true; + } +}; + // =================================================================== void CommandLineInterfaceTest::SetUp() { @@ -239,6 +263,15 @@ CommandLineInterfaceTest::RegisterErrorGenerator( return generator; } +CommandLineInterfaceTest::NullCodeGenerator* +CommandLineInterfaceTest::RegisterNullGenerator( + const string& flag_name) { + NullCodeGenerator* generator = new NullCodeGenerator; + mock_generators_to_delete_.push_back(generator); + cli_.RegisterGenerator(flag_name, generator, ""); + return generator; +} + void CommandLineInterfaceTest::CreateTempFile( const string& name, const string& contents) { @@ -424,6 +457,42 @@ TEST_F(CommandLineInterfaceTest, GeneratorParameters) { "foo.proto", "Foo", "output.test"); } +#if defined(_WIN32) || defined(__CYGWIN__) + +TEST_F(CommandLineInterfaceTest, WindowsOutputPath) { + // Test that the output path can be a Windows-style path. + + NullCodeGenerator* generator = RegisterNullGenerator("--test_out"); + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n"); + + Run("protocol_compiler --test_out=C:\\ " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + EXPECT_TRUE(generator->called_); + EXPECT_EQ("", generator->parameter_); +} + +TEST_F(CommandLineInterfaceTest, WindowsOutputPathAndParameter) { + // Test that we can have a windows-style output path and a parameter. + + NullCodeGenerator* generator = RegisterNullGenerator("--test_out"); + + CreateTempFile("foo.proto", + "syntax = \"proto2\";\n"); + + Run("protocol_compiler --test_out=bar:C:\\ " + "--proto_path=$tmpdir foo.proto"); + + ExpectNoErrors(); + EXPECT_TRUE(generator->called_); + EXPECT_EQ("bar", generator->parameter_); +} + +#endif // defined(_WIN32) || defined(__CYGWIN__) + TEST_F(CommandLineInterfaceTest, PathLookup) { // Test that specifying multiple directories in the proto search path works. diff --git a/src/google/protobuf/stubs/common.h b/src/google/protobuf/stubs/common.h index 03b176a..f0d55b5 100644 --- a/src/google/protobuf/stubs/common.h +++ b/src/google/protobuf/stubs/common.h @@ -147,7 +147,7 @@ typedef uint64_t uint64; #endif static const int32 kint32max = 0x7FFFFFFF; -static const int32 kint32min = -kint32min - 1; +static const int32 kint32min = -kint32max - 1; static const int64 kint64max = GOOGLE_LONGLONG(0x7FFFFFFFFFFFFFFF); static const int64 kint64min = -kint64max - 1; static const uint32 kuint32max = 0xFFFFFFFFu; diff --git a/src/google/protobuf/stubs/common_unittest.cc b/src/google/protobuf/stubs/common_unittest.cc index f12422b..c339c5f 100644 --- a/src/google/protobuf/stubs/common_unittest.cc +++ b/src/google/protobuf/stubs/common_unittest.cc @@ -50,6 +50,17 @@ TEST(VersionTest, VersionMatchesConfig) { #endif // PACKAGE_VERSION +TEST(CommonTest, IntMinMaxConstants) { + // kint32min was declared incorrectly in the first release of protobufs. + // Ugh. + EXPECT_LT(kint32min, kint32max); + EXPECT_EQ(static_cast(kint32min), static_cast(kint32max) + 1); + EXPECT_LT(kint64min, kint64max); + EXPECT_EQ(static_cast(kint64min), static_cast(kint64max) + 1); + EXPECT_EQ(0, kuint32max + 1); + EXPECT_EQ(0, kuint64max + 1); +} + vector captured_messages_; void CaptureLog(LogLevel level, const char* filename, int line, -- cgit v1.2.3