aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2009-04-15 19:50:54 +0000
committerGravatar kenton@google.com <kenton@google.com@630680e5-0e50-0410-840e-4b1c322b438d>2009-04-15 19:50:54 +0000
commitf663b1602d2675b1ab91d76dd739070d34e01291 (patch)
tree04bc78516c9539b65bd4c74cc6ff31a544ee89bf
parent90bdae226eecf5a97fc7b86078baf055f0702871 (diff)
Adds a flag to protoc called --error_format which specifies what
convention to use when printing errors. Default is GCC, but Microsoft Visual Studio is another option. This allows errors to be clickable in the MSVS error log.
-rw-r--r--CHANGES.txt5
-rw-r--r--CONTRIBUTORS.txt2
-rw-r--r--src/google/protobuf/compiler/command_line_interface.cc40
-rw-r--r--src/google/protobuf/compiler/command_line_interface.h7
-rw-r--r--src/google/protobuf/compiler/command_line_interface_unittest.cc53
5 files changed, 101 insertions, 6 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index 2a86a63c..94fe94e1 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -9,6 +9,11 @@
be normally except without a tag before each value (thus, they are
tightly "packed").
+ protoc
+ * --error_format=msvs option causes errors to be printed in Visual Studio
+ format, which should allow them to be clicked on in the build log to go
+ directly to the error location.
+
C++
* UnknownFieldSet now supports STL-like iteration.
* Message interface has method ParseFromBoundedZeroCopyStream() which parses
diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt
index e212467e..3755f743 100644
--- a/CONTRIBUTORS.txt
+++ b/CONTRIBUTORS.txt
@@ -55,3 +55,5 @@ Non-Google patch contributors:
* Solaris 10 + Sun Studio fix.
Alek Storm <alek.storm@gmail.com>
* Slicing support for repeated scalar fields for the Python API.
+ Oleg Smolsky <oleg.smolsky@gmail.com>
+ * MS Visual Studio error format option.
diff --git a/src/google/protobuf/compiler/command_line_interface.cc b/src/google/protobuf/compiler/command_line_interface.cc
index 09473ec7..3629f682 100644
--- a/src/google/protobuf/compiler/command_line_interface.cc
+++ b/src/google/protobuf/compiler/command_line_interface.cc
@@ -132,18 +132,29 @@ void SetFdToBinaryMode(int fd) {
class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector,
public io::ErrorCollector {
public:
- ErrorPrinter() {}
+ ErrorPrinter(ErrorFormat format) : format_(format) {}
~ErrorPrinter() {}
// implements MultiFileErrorCollector ------------------------------
void AddError(const string& filename, int line, int column,
const string& message) {
+
+ cerr << filename;
+
// Users typically expect 1-based line/column numbers, so we add 1
// to each here.
- cerr << filename;
if (line != -1) {
- cerr << ":" << (line + 1) << ":" << (column + 1);
+ // Allow for both GCC- and Visual-Studio-compatible output.
+ switch (format_) {
+ case CommandLineInterface::ERROR_FORMAT_GCC:
+ cerr << ":" << (line + 1) << ":" << (column + 1);
+ break;
+ case CommandLineInterface::ERROR_FORMAT_MSVS:
+ cerr << "(" << (line + 1) << ") : error in column=" << (column + 1);
+ break;
+ }
}
+
cerr << ": " << message << endl;
}
@@ -151,6 +162,9 @@ class CommandLineInterface::ErrorPrinter : public MultiFileErrorCollector,
void AddError(int line, int column, const string& message) {
AddError("input", line, column, message);
}
+
+ private:
+ const ErrorFormat format_;
};
// -------------------------------------------------------------------
@@ -294,6 +308,7 @@ CommandLineInterface::ErrorReportingFileOutput::~ErrorReportingFileOutput() {
CommandLineInterface::CommandLineInterface()
: mode_(MODE_COMPILE),
+ error_format_(ERROR_FORMAT_GCC),
imports_in_descriptor_set_(false),
disallow_services_(false),
inputs_are_proto_path_relative_(false) {}
@@ -326,7 +341,7 @@ int CommandLineInterface::Run(int argc, const char* const argv[]) {
}
// Allocate the Importer.
- ErrorPrinter error_collector;
+ ErrorPrinter error_collector(error_format_);
Importer importer(&source_tree, &error_collector);
vector<const FileDescriptor*> parsed_files;
@@ -657,6 +672,16 @@ bool CommandLineInterface::InterpretArgument(const string& name,
codec_type_ = value;
+ } else if (name == "--error_format") {
+ if (value == "gcc") {
+ error_format_ = ERROR_FORMAT_GCC;
+ } else if (value == "msvs") {
+ error_format_ = ERROR_FORMAT_MSVS;
+ } else {
+ cerr << "Unknown error format: " << value << endl;
+ return false;
+ }
+
} else {
// Some other flag. Look it up in the generators list.
GeneratorMap::const_iterator iter = generators_.find(name);
@@ -722,7 +747,10 @@ void CommandLineInterface::PrintHelpText() {
" the input files to FILE.\n"
" --include_imports When using --descriptor_set_out, also include\n"
" all dependencies of the input files in the\n"
-" set, so that the set is self-contained." << endl;
+" set, so that the set is self-contained.\n"
+" --error_format=FORMAT Set the format in which to print errors.\n"
+" FORMAT may be 'gcc' (the default) or 'msvs'\n"
+" (Microsoft Visual Studio format)." << endl;
for (GeneratorMap::iterator iter = generators_.begin();
iter != generators_.end(); ++iter) {
@@ -788,7 +816,7 @@ bool CommandLineInterface::EncodeOrDecode(const DescriptorPool* pool) {
if (mode_ == MODE_ENCODE) {
// Input is text.
- ErrorPrinter error_collector;
+ ErrorPrinter error_collector(error_format_);
TextFormat::Parser parser;
parser.RecordErrorsTo(&error_collector);
parser.AllowPartialMessage(true);
diff --git a/src/google/protobuf/compiler/command_line_interface.h b/src/google/protobuf/compiler/command_line_interface.h
index 86eeba53..ec658636 100644
--- a/src/google/protobuf/compiler/command_line_interface.h
+++ b/src/google/protobuf/compiler/command_line_interface.h
@@ -210,6 +210,13 @@ class LIBPROTOC_EXPORT CommandLineInterface {
Mode mode_;
+ enum ErrorFormat {
+ ERROR_FORMAT_GCC, // GCC error output format (default).
+ ERROR_FORMAT_MSVS // Visual Studio output (--error_format=msvs).
+ };
+
+ ErrorFormat error_format_;
+
vector<pair<string, string> > proto_path_; // Search path for proto files.
vector<string> input_files_; // Names of the input proto files.
diff --git a/src/google/protobuf/compiler/command_line_interface_unittest.cc b/src/google/protobuf/compiler/command_line_interface_unittest.cc
index 0780729d..af765b87 100644
--- a/src/google/protobuf/compiler/command_line_interface_unittest.cc
+++ b/src/google/protobuf/compiler/command_line_interface_unittest.cc
@@ -1047,6 +1047,59 @@ TEST_F(CommandLineInterfaceTest, HelpText) {
ExpectErrorSubstring("Test error output.");
}
+TEST_F(CommandLineInterfaceTest, GccFormatErrors) {
+ // Test --error_format=gcc (which is the default, but we want to verify
+ // that it can be set explicitly).
+
+ RegisterGenerator("test_generator", "--test_out",
+ "output.test", "Test output.");
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "badsyntax\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir --error_format=gcc foo.proto");
+
+ ExpectErrorText(
+ "foo.proto:2:1: Expected top-level statement (e.g. \"message\").\n");
+}
+
+TEST_F(CommandLineInterfaceTest, MsvsFormatErrors) {
+ // Test --error_format=msvs
+
+ RegisterGenerator("test_generator", "--test_out",
+ "output.test", "Test output.");
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "badsyntax\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir --error_format=msvs foo.proto");
+
+ ExpectErrorText(
+ "foo.proto(2) : error in column=1: Expected top-level statement "
+ "(e.g. \"message\").\n");
+}
+
+TEST_F(CommandLineInterfaceTest, InvalidErrorFormat) {
+ // Test --error_format=msvs
+
+ RegisterGenerator("test_generator", "--test_out",
+ "output.test", "Test output.");
+
+ CreateTempFile("foo.proto",
+ "syntax = \"proto2\";\n"
+ "badsyntax\n");
+
+ Run("protocol_compiler --test_out=$tmpdir "
+ "--proto_path=$tmpdir --error_format=invalid foo.proto");
+
+ ExpectErrorText(
+ "Unknown error format: invalid\n");
+}
+
// -------------------------------------------------------------------
// Flag parsing tests