From 9d7455f9844e293dff8b7902f0c2553094f2f976 Mon Sep 17 00:00:00 2001 From: vladlosev Date: Wed, 2 Feb 2011 10:07:04 +0000 Subject: Adds null check for file locations in XML output printer. --- include/gtest/internal/gtest-internal.h | 14 ------------ include/gtest/internal/gtest-port.h | 10 +++++++++ src/gtest-port.cc | 32 +++++++++++++++++++++++++++ src/gtest.cc | 5 +++-- test/gtest-port_test.cc | 38 +++++++++++++++++++++++++++++++++ 5 files changed, 83 insertions(+), 16 deletions(-) diff --git a/include/gtest/internal/gtest-internal.h b/include/gtest/internal/gtest-internal.h index 23fcef7..9f890fa 100644 --- a/include/gtest/internal/gtest-internal.h +++ b/include/gtest/internal/gtest-internal.h @@ -536,20 +536,6 @@ GTEST_API_ AssertionResult IsHRESULTFailure(const char* expr, #endif // GTEST_OS_WINDOWS -// Formats a source file path and a line number as they would appear -// in a compiler error message. -inline String FormatFileLocation(const char* file, int line) { - const char* const file_name = file == NULL ? "unknown file" : file; - if (line < 0) { - return String::Format("%s:", file_name); - } -#ifdef _MSC_VER - return String::Format("%s(%d):", file_name, line); -#else - return String::Format("%s:%d:", file_name, line); -#endif // _MSC_VER -} - // Types of SetUpTestCase() and TearDownTestCase() functions. typedef void (*SetUpTestCaseFunc)(); typedef void (*TearDownTestCaseFunc)(); diff --git a/include/gtest/internal/gtest-port.h b/include/gtest/internal/gtest-port.h index be2297e..228c468 100644 --- a/include/gtest/internal/gtest-port.h +++ b/include/gtest/internal/gtest-port.h @@ -848,6 +848,16 @@ class GTEST_API_ RE { GTEST_DISALLOW_ASSIGN_(RE); }; +// Formats a source file path and a line number as they would appear +// in an error message from the compiler used to compile this code. +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line); + +// Formats a file location for compiler-independent XML output. +// Although this function is not platform dependent, we put it next to +// FormatFileLocation in order to contrast the two functions. +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(const char* file, + int line); + // Defines logging utilities: // GTEST_LOG_(severity) - logs messages at the specified severity level. The // message itself is streamed into the macro. diff --git a/src/gtest-port.cc b/src/gtest-port.cc index da62fba..4310a73 100644 --- a/src/gtest-port.cc +++ b/src/gtest-port.cc @@ -424,6 +424,38 @@ void RE::Init(const char* regex) { #endif // GTEST_USES_POSIX_RE +const char kUnknownFile[] = "unknown file"; + +// Formats a source file path and a line number as they would appear +// in an error message from the compiler used to compile this code. +GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) { + const char* const file_name = file == NULL ? kUnknownFile : file; + + if (line < 0) { + return String::Format("%s:", file_name).c_str(); + } +#ifdef _MSC_VER + return String::Format("%s(%d):", file_name, line).c_str(); +#else + return String::Format("%s:%d:", file_name, line).c_str(); +#endif // _MSC_VER +} + +// Formats a file location for compiler-independent XML output. +// Although this function is not platform dependent, we put it next to +// FormatFileLocation in order to contrast the two functions. +// Note that FormatCompilerIndependentFileLocation() does NOT append colon +// to the file location it produces, unlike FormatFileLocation(). +GTEST_API_ ::std::string FormatCompilerIndependentFileLocation( + const char* file, int line) { + const char* const file_name = file == NULL ? kUnknownFile : file; + + if (line < 0) + return file_name; + else + return String::Format("%s:%d", file_name, line).c_str(); +} + GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line) : severity_(severity) { diff --git a/src/gtest.cc b/src/gtest.cc index 575a8a5..1c58c6f 100644 --- a/src/gtest.cc +++ b/src/gtest.cc @@ -3245,8 +3245,9 @@ void XmlUnitTestResultPrinter::OutputXmlTestInfo(::std::ostream* stream, << EscapeXmlAttribute(part.summary()).c_str() << "\" type=\"\">"; const String message = RemoveInvalidXmlCharacters(String::Format( - "%s:%d\n%s", - part.file_name(), part.line_number(), + "%s\n%s", + internal::FormatCompilerIndependentFileLocation( + part.file_name(), part.line_number()).c_str(), part.message()).c_str()); OutputXmlCDataSection(stream, message.c_str()); *stream << "\n"; diff --git a/test/gtest-port_test.cc b/test/gtest-port_test.cc index 5afba2d..be0f8b0 100644 --- a/test/gtest-port_test.cc +++ b/test/gtest-port_test.cc @@ -209,6 +209,44 @@ TEST(GtestCheckSyntaxTest, WorksWithSwitch) { GTEST_CHECK_(true) << "Check failed in switch case"; } +// Verifies behavior of FormatFileLocation. +TEST(FormatFileLocationTest, FormatsFileLocation) { + EXPECT_PRED_FORMAT2(IsSubstring, "foo.cc", FormatFileLocation("foo.cc", 42)); + EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation("foo.cc", 42)); +} + +TEST(FormatFileLocationTest, FormatsUnknownFile) { + EXPECT_PRED_FORMAT2( + IsSubstring, "unknown file", FormatFileLocation(NULL, 42)); + EXPECT_PRED_FORMAT2(IsSubstring, "42", FormatFileLocation(NULL, 42)); +} + +TEST(FormatFileLocationTest, FormatsUknownLine) { + EXPECT_EQ("foo.cc:", FormatFileLocation("foo.cc", -1)); +} + +TEST(FormatFileLocationTest, FormatsUknownFileAndLine) { + EXPECT_EQ("unknown file:", FormatFileLocation(NULL, -1)); +} + +// Verifies behavior of FormatCompilerIndependentFileLocation. +TEST(FormatCompilerIndependentFileLocationTest, FormatsFileLocation) { + EXPECT_EQ("foo.cc:42", FormatCompilerIndependentFileLocation("foo.cc", 42)); +} + +TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFile) { + EXPECT_EQ("unknown file:42", + FormatCompilerIndependentFileLocation(NULL, 42)); +} + +TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownLine) { + EXPECT_EQ("foo.cc", FormatCompilerIndependentFileLocation("foo.cc", -1)); +} + +TEST(FormatCompilerIndependentFileLocationTest, FormatsUknownFileAndLine) { + EXPECT_EQ("unknown file", FormatCompilerIndependentFileLocation(NULL, -1)); +} + #if GTEST_OS_MAC void* ThreadFunc(void* data) { pthread_mutex_t* mutex = static_cast(data); -- cgit v0.12