Code-style consistency improvement:

Apply clang-format-all.sh using the _clang-format file through all the cpp/.h files.
make sure not to apply it to certain serialization structures, since some parser expects the * as part of the name, instead of type.
This commit contains no other changes aside from adding and applying clang-format-all.sh
This commit is contained in:
erwincoumans
2018-09-23 14:17:31 -07:00
parent b73b05e9fb
commit ab8f16961e
1773 changed files with 1081087 additions and 474249 deletions

View File

@@ -41,9 +41,10 @@
#include <stdio.h>
namespace testing {
namespace internal {
namespace testing
{
namespace internal
{
GTEST_DECLARE_string_(internal_run_death_test);
// Names of the flags (needed for parsing Google Test flags).
@@ -66,89 +67,99 @@ const char kInternalRunDeathTestFlag[] = "internal_run_death_test";
// by wait(2)
// exit code: The integer code passed to exit(3), _exit(2), or
// returned from main()
class GTEST_API_ DeathTest {
public:
// Create returns false if there was an error determining the
// appropriate action to take for the current death test; for example,
// if the gtest_death_test_style flag is set to an invalid value.
// The LastMessage method will return a more detailed message in that
// case. Otherwise, the DeathTest pointer pointed to by the "test"
// argument is set. If the death test should be skipped, the pointer
// is set to NULL; otherwise, it is set to the address of a new concrete
// DeathTest object that controls the execution of the current test.
static bool Create(const char* statement, const RE* regex,
const char* file, int line, DeathTest** test);
DeathTest();
virtual ~DeathTest() { }
class GTEST_API_ DeathTest
{
public:
// Create returns false if there was an error determining the
// appropriate action to take for the current death test; for example,
// if the gtest_death_test_style flag is set to an invalid value.
// The LastMessage method will return a more detailed message in that
// case. Otherwise, the DeathTest pointer pointed to by the "test"
// argument is set. If the death test should be skipped, the pointer
// is set to NULL; otherwise, it is set to the address of a new concrete
// DeathTest object that controls the execution of the current test.
static bool Create(const char* statement, const RE* regex,
const char* file, int line, DeathTest** test);
DeathTest();
virtual ~DeathTest() {}
// A helper class that aborts a death test when it's deleted.
class ReturnSentinel {
public:
explicit ReturnSentinel(DeathTest* test) : test_(test) { }
~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
private:
DeathTest* const test_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel);
} GTEST_ATTRIBUTE_UNUSED_;
// A helper class that aborts a death test when it's deleted.
class ReturnSentinel
{
public:
explicit ReturnSentinel(DeathTest* test) : test_(test) {}
~ReturnSentinel() { test_->Abort(TEST_ENCOUNTERED_RETURN_STATEMENT); }
// An enumeration of possible roles that may be taken when a death
// test is encountered. EXECUTE means that the death test logic should
// be executed immediately. OVERSEE means that the program should prepare
// the appropriate environment for a child process to execute the death
// test, then wait for it to complete.
enum TestRole { OVERSEE_TEST, EXECUTE_TEST };
private:
DeathTest* const test_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(ReturnSentinel);
} GTEST_ATTRIBUTE_UNUSED_;
// An enumeration of the three reasons that a test might be aborted.
enum AbortReason {
TEST_ENCOUNTERED_RETURN_STATEMENT,
TEST_THREW_EXCEPTION,
TEST_DID_NOT_DIE
};
// An enumeration of possible roles that may be taken when a death
// test is encountered. EXECUTE means that the death test logic should
// be executed immediately. OVERSEE means that the program should prepare
// the appropriate environment for a child process to execute the death
// test, then wait for it to complete.
enum TestRole
{
OVERSEE_TEST,
EXECUTE_TEST
};
// Assumes one of the above roles.
virtual TestRole AssumeRole() = 0;
// An enumeration of the three reasons that a test might be aborted.
enum AbortReason
{
TEST_ENCOUNTERED_RETURN_STATEMENT,
TEST_THREW_EXCEPTION,
TEST_DID_NOT_DIE
};
// Waits for the death test to finish and returns its status.
virtual int Wait() = 0;
// Assumes one of the above roles.
virtual TestRole AssumeRole() = 0;
// Returns true if the death test passed; that is, the test process
// exited during the test, its exit status matches a user-supplied
// predicate, and its stderr output matches a user-supplied regular
// expression.
// The user-supplied predicate may be a macro expression rather
// than a function pointer or functor, or else Wait and Passed could
// be combined.
virtual bool Passed(bool exit_status_ok) = 0;
// Waits for the death test to finish and returns its status.
virtual int Wait() = 0;
// Signals that the death test did not die as expected.
virtual void Abort(AbortReason reason) = 0;
// Returns true if the death test passed; that is, the test process
// exited during the test, its exit status matches a user-supplied
// predicate, and its stderr output matches a user-supplied regular
// expression.
// The user-supplied predicate may be a macro expression rather
// than a function pointer or functor, or else Wait and Passed could
// be combined.
virtual bool Passed(bool exit_status_ok) = 0;
// Returns a human-readable outcome message regarding the outcome of
// the last death test.
static const char* LastMessage();
// Signals that the death test did not die as expected.
virtual void Abort(AbortReason reason) = 0;
static void set_last_death_test_message(const std::string& message);
// Returns a human-readable outcome message regarding the outcome of
// the last death test.
static const char* LastMessage();
private:
// A string containing a description of the outcome of the last death test.
static std::string last_death_test_message_;
static void set_last_death_test_message(const std::string& message);
GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);
private:
// A string containing a description of the outcome of the last death test.
static std::string last_death_test_message_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(DeathTest);
};
// Factory interface for death tests. May be mocked out for testing.
class DeathTestFactory {
public:
virtual ~DeathTestFactory() { }
virtual bool Create(const char* statement, const RE* regex,
const char* file, int line, DeathTest** test) = 0;
class DeathTestFactory
{
public:
virtual ~DeathTestFactory() {}
virtual bool Create(const char* statement, const RE* regex,
const char* file, int line, DeathTest** test) = 0;
};
// A concrete DeathTestFactory implementation for normal use.
class DefaultDeathTestFactory : public DeathTestFactory {
public:
virtual bool Create(const char* statement, const RE* regex,
const char* file, int line, DeathTest** test);
class DefaultDeathTestFactory : public DeathTestFactory
{
public:
virtual bool Create(const char* statement, const RE* regex,
const char* file, int line, DeathTest** test);
};
// Returns true if exit_status describes a process that was terminated
@@ -157,63 +168,74 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// Traps C++ exceptions escaping statement and reports them as test
// failures. Note that trapping SEH exceptions is not implemented here.
# if GTEST_HAS_EXCEPTIONS
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
try { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} catch (const ::std::exception& gtest_exception) { \
fprintf(\
stderr, \
"\n%s: Caught std::exception-derived exception escaping the " \
"death test statement. Exception message: %s\n", \
::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \
gtest_exception.what()); \
fflush(stderr); \
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
} catch (...) { \
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
}
#if GTEST_HAS_EXCEPTIONS
#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
try \
{ \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} \
catch (const ::std::exception& gtest_exception) \
{ \
fprintf( \
stderr, \
"\n%s: Caught std::exception-derived exception escaping the " \
"death test statement. Exception message: %s\n", \
::testing::internal::FormatFileLocation(__FILE__, __LINE__).c_str(), \
gtest_exception.what()); \
fflush(stderr); \
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
} \
catch (...) \
{ \
death_test->Abort(::testing::internal::DeathTest::TEST_THREW_EXCEPTION); \
}
# else
# define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
#else
#define GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, death_test) \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement)
# endif
#endif
// This macro is for implementing ASSERT_DEATH*, EXPECT_DEATH*,
// ASSERT_EXIT*, and EXPECT_EXIT*.
# define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
const ::testing::internal::RE& gtest_regex = (regex); \
::testing::internal::DeathTest* gtest_dt; \
if (!::testing::internal::DeathTest::Create(#statement, &gtest_regex, \
__FILE__, __LINE__, &gtest_dt)) { \
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
} \
if (gtest_dt != NULL) { \
::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \
gtest_dt_ptr(gtest_dt); \
switch (gtest_dt->AssumeRole()) { \
case ::testing::internal::DeathTest::OVERSEE_TEST: \
if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) { \
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
} \
break; \
case ::testing::internal::DeathTest::EXECUTE_TEST: { \
::testing::internal::DeathTest::ReturnSentinel \
gtest_sentinel(gtest_dt); \
GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
break; \
} \
default: \
break; \
} \
} \
} else \
GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__): \
fail(::testing::internal::DeathTest::LastMessage())
#define GTEST_DEATH_TEST_(statement, predicate, regex, fail) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) \
{ \
const ::testing::internal::RE& gtest_regex = (regex); \
::testing::internal::DeathTest* gtest_dt; \
if (!::testing::internal::DeathTest::Create(#statement, &gtest_regex, \
__FILE__, __LINE__, &gtest_dt)) \
{ \
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
} \
if (gtest_dt != NULL) \
{ \
::testing::internal::scoped_ptr< ::testing::internal::DeathTest> \
gtest_dt_ptr(gtest_dt); \
switch (gtest_dt->AssumeRole()) \
{ \
case ::testing::internal::DeathTest::OVERSEE_TEST: \
if (!gtest_dt->Passed(predicate(gtest_dt->Wait()))) \
{ \
goto GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__); \
} \
break; \
case ::testing::internal::DeathTest::EXECUTE_TEST: \
{ \
::testing::internal::DeathTest::ReturnSentinel \
gtest_sentinel(gtest_dt); \
GTEST_EXECUTE_DEATH_TEST_STATEMENT_(statement, gtest_dt); \
gtest_dt->Abort(::testing::internal::DeathTest::TEST_DID_NOT_DIE); \
break; \
} \
default: \
break; \
} \
} \
} \
else \
GTEST_CONCAT_TOKEN_(gtest_label_, __LINE__) : fail(::testing::internal::DeathTest::LastMessage())
// The symbol "fail" here expands to something into which a message
// can be streamed.
@@ -221,42 +243,45 @@ GTEST_API_ bool ExitedUnsuccessfully(int exit_status);
// NDEBUG mode. In this case we need the statements to be executed, the regex is
// ignored, and the macro must accept a streamed message even though the message
// is never printed.
# define GTEST_EXECUTE_STATEMENT_(statement, regex) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} else \
::testing::Message()
#define GTEST_EXECUTE_STATEMENT_(statement, regex) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) \
{ \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
} \
else \
::testing::Message()
// A class representing the parsed contents of the
// --gtest_internal_run_death_test flag, as it existed when
// RUN_ALL_TESTS was called.
class InternalRunDeathTestFlag {
public:
InternalRunDeathTestFlag(const std::string& a_file,
int a_line,
int an_index,
int a_write_fd)
: file_(a_file), line_(a_line), index_(an_index),
write_fd_(a_write_fd) {}
class InternalRunDeathTestFlag
{
public:
InternalRunDeathTestFlag(const std::string& a_file,
int a_line,
int an_index,
int a_write_fd)
: file_(a_file), line_(a_line), index_(an_index), write_fd_(a_write_fd) {}
~InternalRunDeathTestFlag() {
if (write_fd_ >= 0)
posix::Close(write_fd_);
}
~InternalRunDeathTestFlag()
{
if (write_fd_ >= 0)
posix::Close(write_fd_);
}
const std::string& file() const { return file_; }
int line() const { return line_; }
int index() const { return index_; }
int write_fd() const { return write_fd_; }
const std::string& file() const { return file_; }
int line() const { return line_; }
int index() const { return index_; }
int write_fd() const { return write_fd_; }
private:
std::string file_;
int line_;
int index_;
int write_fd_;
private:
std::string file_;
int line_;
int index_;
int write_fd_;
GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
GTEST_DISALLOW_COPY_AND_ASSIGN_(InternalRunDeathTestFlag);
};
// Returns a newly created InternalRunDeathTestFlag object with fields
@@ -298,18 +323,22 @@ InternalRunDeathTestFlag* ParseInternalRunDeathTestFlag();
// statement unconditionally returns or throws. The Message constructor at
// the end allows the syntax of streaming additional messages into the
// macro, for compilational compatibility with EXPECT_DEATH/ASSERT_DEATH.
# define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) { \
GTEST_LOG_(WARNING) \
<< "Death tests are not supported on this platform.\n" \
<< "Statement '" #statement "' cannot be verified."; \
} else if (::testing::internal::AlwaysFalse()) { \
::testing::internal::RE::PartialMatch(".*", (regex)); \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
terminator; \
} else \
::testing::Message()
#define GTEST_UNSUPPORTED_DEATH_TEST_(statement, regex, terminator) \
GTEST_AMBIGUOUS_ELSE_BLOCKER_ \
if (::testing::internal::AlwaysTrue()) \
{ \
GTEST_LOG_(WARNING) \
<< "Death tests are not supported on this platform.\n" \
<< "Statement '" #statement "' cannot be verified."; \
} \
else if (::testing::internal::AlwaysFalse()) \
{ \
::testing::internal::RE::PartialMatch(".*", (regex)); \
GTEST_SUPPRESS_UNREACHABLE_CODE_WARNING_BELOW_(statement); \
terminator; \
} \
else \
::testing::Message()
#endif // GTEST_HAS_DEATH_TEST

View File

@@ -42,9 +42,10 @@
#include "gtest/internal/gtest-string.h"
namespace testing {
namespace internal {
namespace testing
{
namespace internal
{
// FilePath - a class for file and directory pathname manipulation which
// handles platform-specific conventions (like the pathname separator).
// Used for helper functions for naming files in a directory for xml output.
@@ -56,148 +57,152 @@ namespace internal {
// Names are NOT checked for syntax correctness -- no checking for illegal
// characters, malformed paths, etc.
class GTEST_API_ FilePath {
public:
FilePath() : pathname_("") { }
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) { }
class GTEST_API_ FilePath
{
public:
FilePath() : pathname_("") {}
FilePath(const FilePath& rhs) : pathname_(rhs.pathname_) {}
explicit FilePath(const std::string& pathname) : pathname_(pathname) {
Normalize();
}
explicit FilePath(const std::string& pathname) : pathname_(pathname)
{
Normalize();
}
FilePath& operator=(const FilePath& rhs) {
Set(rhs);
return *this;
}
FilePath& operator=(const FilePath& rhs)
{
Set(rhs);
return *this;
}
void Set(const FilePath& rhs) {
pathname_ = rhs.pathname_;
}
void Set(const FilePath& rhs)
{
pathname_ = rhs.pathname_;
}
const std::string& string() const { return pathname_; }
const char* c_str() const { return pathname_.c_str(); }
const std::string& string() const { return pathname_; }
const char* c_str() const { return pathname_.c_str(); }
// Returns the current working directory, or "" if unsuccessful.
static FilePath GetCurrentDir();
// Returns the current working directory, or "" if unsuccessful.
static FilePath GetCurrentDir();
// Given directory = "dir", base_name = "test", number = 0,
// extension = "xml", returns "dir/test.xml". If number is greater
// than zero (e.g., 12), returns "dir/test_12.xml".
// On Windows platform, uses \ as the separator rather than /.
static FilePath MakeFileName(const FilePath& directory,
const FilePath& base_name,
int number,
const char* extension);
// Given directory = "dir", base_name = "test", number = 0,
// extension = "xml", returns "dir/test.xml". If number is greater
// than zero (e.g., 12), returns "dir/test_12.xml".
// On Windows platform, uses \ as the separator rather than /.
static FilePath MakeFileName(const FilePath& directory,
const FilePath& base_name,
int number,
const char* extension);
// Given directory = "dir", relative_path = "test.xml",
// returns "dir/test.xml".
// On Windows, uses \ as the separator rather than /.
static FilePath ConcatPaths(const FilePath& directory,
const FilePath& relative_path);
// Given directory = "dir", relative_path = "test.xml",
// returns "dir/test.xml".
// On Windows, uses \ as the separator rather than /.
static FilePath ConcatPaths(const FilePath& directory,
const FilePath& relative_path);
// Returns a pathname for a file that does not currently exist. The pathname
// will be directory/base_name.extension or
// directory/base_name_<number>.extension if directory/base_name.extension
// already exists. The number will be incremented until a pathname is found
// that does not already exist.
// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
// There could be a race condition if two or more processes are calling this
// function at the same time -- they could both pick the same filename.
static FilePath GenerateUniqueFileName(const FilePath& directory,
const FilePath& base_name,
const char* extension);
// Returns a pathname for a file that does not currently exist. The pathname
// will be directory/base_name.extension or
// directory/base_name_<number>.extension if directory/base_name.extension
// already exists. The number will be incremented until a pathname is found
// that does not already exist.
// Examples: 'dir/foo_test.xml' or 'dir/foo_test_1.xml'.
// There could be a race condition if two or more processes are calling this
// function at the same time -- they could both pick the same filename.
static FilePath GenerateUniqueFileName(const FilePath& directory,
const FilePath& base_name,
const char* extension);
// Returns true iff the path is "".
bool IsEmpty() const { return pathname_.empty(); }
// Returns true iff the path is "".
bool IsEmpty() const { return pathname_.empty(); }
// If input name has a trailing separator character, removes it and returns
// the name, otherwise return the name string unmodified.
// On Windows platform, uses \ as the separator, other platforms use /.
FilePath RemoveTrailingPathSeparator() const;
// If input name has a trailing separator character, removes it and returns
// the name, otherwise return the name string unmodified.
// On Windows platform, uses \ as the separator, other platforms use /.
FilePath RemoveTrailingPathSeparator() const;
// Returns a copy of the FilePath with the directory part removed.
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
// the FilePath unmodified. If there is no file part ("just_a_dir/") it
// returns an empty FilePath ("").
// On Windows platform, '\' is the path separator, otherwise it is '/'.
FilePath RemoveDirectoryName() const;
// Returns a copy of the FilePath with the directory part removed.
// Example: FilePath("path/to/file").RemoveDirectoryName() returns
// FilePath("file"). If there is no directory part ("just_a_file"), it returns
// the FilePath unmodified. If there is no file part ("just_a_dir/") it
// returns an empty FilePath ("").
// On Windows platform, '\' is the path separator, otherwise it is '/'.
FilePath RemoveDirectoryName() const;
// RemoveFileName returns the directory path with the filename removed.
// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
// On Windows platform, '\' is the path separator, otherwise it is '/'.
FilePath RemoveFileName() const;
// RemoveFileName returns the directory path with the filename removed.
// Example: FilePath("path/to/file").RemoveFileName() returns "path/to/".
// If the FilePath is "a_file" or "/a_file", RemoveFileName returns
// FilePath("./") or, on Windows, FilePath(".\\"). If the filepath does
// not have a file, like "just/a/dir/", it returns the FilePath unmodified.
// On Windows platform, '\' is the path separator, otherwise it is '/'.
FilePath RemoveFileName() const;
// Returns a copy of the FilePath with the case-insensitive extension removed.
// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
// FilePath("dir/file"). If a case-insensitive extension is not
// found, returns a copy of the original FilePath.
FilePath RemoveExtension(const char* extension) const;
// Returns a copy of the FilePath with the case-insensitive extension removed.
// Example: FilePath("dir/file.exe").RemoveExtension("EXE") returns
// FilePath("dir/file"). If a case-insensitive extension is not
// found, returns a copy of the original FilePath.
FilePath RemoveExtension(const char* extension) const;
// Creates directories so that path exists. Returns true if successful or if
// the directories already exist; returns false if unable to create
// directories for any reason. Will also return false if the FilePath does
// not represent a directory (that is, it doesn't end with a path separator).
bool CreateDirectoriesRecursively() const;
// Creates directories so that path exists. Returns true if successful or if
// the directories already exist; returns false if unable to create
// directories for any reason. Will also return false if the FilePath does
// not represent a directory (that is, it doesn't end with a path separator).
bool CreateDirectoriesRecursively() const;
// Create the directory so that path exists. Returns true if successful or
// if the directory already exists; returns false if unable to create the
// directory for any reason, including if the parent directory does not
// exist. Not named "CreateDirectory" because that's a macro on Windows.
bool CreateFolder() const;
// Create the directory so that path exists. Returns true if successful or
// if the directory already exists; returns false if unable to create the
// directory for any reason, including if the parent directory does not
// exist. Not named "CreateDirectory" because that's a macro on Windows.
bool CreateFolder() const;
// Returns true if FilePath describes something in the file-system,
// either a file, directory, or whatever, and that something exists.
bool FileOrDirectoryExists() const;
// Returns true if FilePath describes something in the file-system,
// either a file, directory, or whatever, and that something exists.
bool FileOrDirectoryExists() const;
// Returns true if pathname describes a directory in the file-system
// that exists.
bool DirectoryExists() const;
// Returns true if pathname describes a directory in the file-system
// that exists.
bool DirectoryExists() const;
// Returns true if FilePath ends with a path separator, which indicates that
// it is intended to represent a directory. Returns false otherwise.
// This does NOT check that a directory (or file) actually exists.
bool IsDirectory() const;
// Returns true if FilePath ends with a path separator, which indicates that
// it is intended to represent a directory. Returns false otherwise.
// This does NOT check that a directory (or file) actually exists.
bool IsDirectory() const;
// Returns true if pathname describes a root directory. (Windows has one
// root directory per disk drive.)
bool IsRootDirectory() const;
// Returns true if pathname describes a root directory. (Windows has one
// root directory per disk drive.)
bool IsRootDirectory() const;
// Returns true if pathname describes an absolute path.
bool IsAbsolutePath() const;
// Returns true if pathname describes an absolute path.
bool IsAbsolutePath() const;
private:
// Replaces multiple consecutive separators with a single separator.
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
// redundancies that might be in a pathname involving "." or "..".
//
// A pathname with multiple consecutive separators may occur either through
// user error or as a result of some scripts or APIs that generate a pathname
// with a trailing separator. On other platforms the same API or script
// may NOT generate a pathname with a trailing "/". Then elsewhere that
// pathname may have another "/" and pathname components added to it,
// without checking for the separator already being there.
// The script language and operating system may allow paths like "foo//bar"
// but some of the functions in FilePath will not handle that correctly. In
// particular, RemoveTrailingPathSeparator() only removes one separator, and
// it is called in CreateDirectoriesRecursively() assuming that it will change
// a pathname from directory syntax (trailing separator) to filename syntax.
//
// On Windows this method also replaces the alternate path separator '/' with
// the primary path separator '\\', so that for example "bar\\/\\foo" becomes
// "bar\\foo".
private:
// Replaces multiple consecutive separators with a single separator.
// For example, "bar///foo" becomes "bar/foo". Does not eliminate other
// redundancies that might be in a pathname involving "." or "..".
//
// A pathname with multiple consecutive separators may occur either through
// user error or as a result of some scripts or APIs that generate a pathname
// with a trailing separator. On other platforms the same API or script
// may NOT generate a pathname with a trailing "/". Then elsewhere that
// pathname may have another "/" and pathname components added to it,
// without checking for the separator already being there.
// The script language and operating system may allow paths like "foo//bar"
// but some of the functions in FilePath will not handle that correctly. In
// particular, RemoveTrailingPathSeparator() only removes one separator, and
// it is called in CreateDirectoriesRecursively() assuming that it will change
// a pathname from directory syntax (trailing separator) to filename syntax.
//
// On Windows this method also replaces the alternate path separator '/' with
// the primary path separator '\\', so that for example "bar\\/\\foo" becomes
// "bar\\foo".
void Normalize();
void Normalize();
// Returns a pointer to the last occurence of a valid path separator in
// the FilePath. On Windows, for example, both '/' and '\' are valid path
// separators. Returns NULL if no path separator was found.
const char* FindLastPathSeparator() const;
// Returns a pointer to the last occurence of a valid path separator in
// the FilePath. On Windows, for example, both '/' and '\' are valid path
// separators. Returns NULL if no path separator was found.
const char* FindLastPathSeparator() const;
std::string pathname_;
std::string pathname_;
}; // class FilePath
} // namespace internal

File diff suppressed because it is too large Load Diff

View File

@@ -73,9 +73,10 @@
#include "gtest/internal/gtest-port.h"
namespace testing {
namespace internal {
namespace testing
{
namespace internal
{
// Protects copying of all linked_ptr objects.
GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);
@@ -86,145 +87,169 @@ GTEST_API_ GTEST_DECLARE_STATIC_MUTEX_(g_linked_ptr_mutex);
// in the same circular linked list, so we need a single class type here.
//
// DO NOT USE THIS CLASS DIRECTLY YOURSELF. Use linked_ptr<T>.
class linked_ptr_internal {
public:
// Create a new circle that includes only this instance.
void join_new() {
next_ = this;
}
class linked_ptr_internal
{
public:
// Create a new circle that includes only this instance.
void join_new()
{
next_ = this;
}
// Many linked_ptr operations may change p.link_ for some linked_ptr
// variable p in the same circle as this object. Therefore we need
// to prevent two such operations from occurring concurrently.
//
// Note that different types of linked_ptr objects can coexist in a
// circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and
// linked_ptr<Derived2>). Therefore we must use a single mutex to
// protect all linked_ptr objects. This can create serious
// contention in production code, but is acceptable in a testing
// framework.
// Many linked_ptr operations may change p.link_ for some linked_ptr
// variable p in the same circle as this object. Therefore we need
// to prevent two such operations from occurring concurrently.
//
// Note that different types of linked_ptr objects can coexist in a
// circle (e.g. linked_ptr<Base>, linked_ptr<Derived1>, and
// linked_ptr<Derived2>). Therefore we must use a single mutex to
// protect all linked_ptr objects. This can create serious
// contention in production code, but is acceptable in a testing
// framework.
// Join an existing circle.
void join(linked_ptr_internal const* ptr)
GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
MutexLock lock(&g_linked_ptr_mutex);
// Join an existing circle.
void join(linked_ptr_internal const* ptr)
GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex)
{
MutexLock lock(&g_linked_ptr_mutex);
linked_ptr_internal const* p = ptr;
while (p->next_ != ptr) p = p->next_;
p->next_ = this;
next_ = ptr;
}
linked_ptr_internal const* p = ptr;
while (p->next_ != ptr) p = p->next_;
p->next_ = this;
next_ = ptr;
}
// Leave whatever circle we're part of. Returns true if we were the
// last member of the circle. Once this is done, you can join() another.
bool depart()
GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex) {
MutexLock lock(&g_linked_ptr_mutex);
// Leave whatever circle we're part of. Returns true if we were the
// last member of the circle. Once this is done, you can join() another.
bool depart()
GTEST_LOCK_EXCLUDED_(g_linked_ptr_mutex)
{
MutexLock lock(&g_linked_ptr_mutex);
if (next_ == this) return true;
linked_ptr_internal const* p = next_;
while (p->next_ != this) p = p->next_;
p->next_ = next_;
return false;
}
if (next_ == this) return true;
linked_ptr_internal const* p = next_;
while (p->next_ != this) p = p->next_;
p->next_ = next_;
return false;
}
private:
mutable linked_ptr_internal const* next_;
private:
mutable linked_ptr_internal const* next_;
};
template <typename T>
class linked_ptr {
public:
typedef T element_type;
class linked_ptr
{
public:
typedef T element_type;
// Take over ownership of a raw pointer. This should happen as soon as
// possible after the object is created.
explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
~linked_ptr() { depart(); }
// Take over ownership of a raw pointer. This should happen as soon as
// possible after the object is created.
explicit linked_ptr(T* ptr = NULL) { capture(ptr); }
~linked_ptr() { depart(); }
// Copy an existing linked_ptr<>, adding ourselves to the list of references.
template <typename U> linked_ptr(linked_ptr<U> const& ptr) { copy(&ptr); }
linked_ptr(linked_ptr const& ptr) { // NOLINT
assert(&ptr != this);
copy(&ptr);
}
// Copy an existing linked_ptr<>, adding ourselves to the list of references.
template <typename U>
linked_ptr(linked_ptr<U> const& ptr)
{
copy(&ptr);
}
linked_ptr(linked_ptr const& ptr)
{ // NOLINT
assert(&ptr != this);
copy(&ptr);
}
// Assignment releases the old value and acquires the new.
template <typename U> linked_ptr& operator=(linked_ptr<U> const& ptr) {
depart();
copy(&ptr);
return *this;
}
// Assignment releases the old value and acquires the new.
template <typename U>
linked_ptr& operator=(linked_ptr<U> const& ptr)
{
depart();
copy(&ptr);
return *this;
}
linked_ptr& operator=(linked_ptr const& ptr) {
if (&ptr != this) {
depart();
copy(&ptr);
}
return *this;
}
linked_ptr& operator=(linked_ptr const& ptr)
{
if (&ptr != this)
{
depart();
copy(&ptr);
}
return *this;
}
// Smart pointer members.
void reset(T* ptr = NULL) {
depart();
capture(ptr);
}
T* get() const { return value_; }
T* operator->() const { return value_; }
T& operator*() const { return *value_; }
// Smart pointer members.
void reset(T* ptr = NULL)
{
depart();
capture(ptr);
}
T* get() const { return value_; }
T* operator->() const { return value_; }
T& operator*() const { return *value_; }
bool operator==(T* p) const { return value_ == p; }
bool operator!=(T* p) const { return value_ != p; }
template <typename U>
bool operator==(linked_ptr<U> const& ptr) const {
return value_ == ptr.get();
}
template <typename U>
bool operator!=(linked_ptr<U> const& ptr) const {
return value_ != ptr.get();
}
bool operator==(T* p) const { return value_ == p; }
bool operator!=(T* p) const { return value_ != p; }
template <typename U>
bool operator==(linked_ptr<U> const& ptr) const
{
return value_ == ptr.get();
}
template <typename U>
bool operator!=(linked_ptr<U> const& ptr) const
{
return value_ != ptr.get();
}
private:
template <typename U>
friend class linked_ptr;
private:
template <typename U>
friend class linked_ptr;
T* value_;
linked_ptr_internal link_;
T* value_;
linked_ptr_internal link_;
void depart() {
if (link_.depart()) delete value_;
}
void depart()
{
if (link_.depart()) delete value_;
}
void capture(T* ptr) {
value_ = ptr;
link_.join_new();
}
void capture(T* ptr)
{
value_ = ptr;
link_.join_new();
}
template <typename U> void copy(linked_ptr<U> const* ptr) {
value_ = ptr->get();
if (value_)
link_.join(&ptr->link_);
else
link_.join_new();
}
template <typename U>
void copy(linked_ptr<U> const* ptr)
{
value_ = ptr->get();
if (value_)
link_.join(&ptr->link_);
else
link_.join_new();
}
};
template<typename T> inline
bool operator==(T* ptr, const linked_ptr<T>& x) {
return ptr == x.get();
template <typename T>
inline bool operator==(T* ptr, const linked_ptr<T>& x)
{
return ptr == x.get();
}
template<typename T> inline
bool operator!=(T* ptr, const linked_ptr<T>& x) {
return ptr != x.get();
template <typename T>
inline bool operator!=(T* ptr, const linked_ptr<T>& x)
{
return ptr != x.get();
}
// A function to convert T* into linked_ptr<T>
// Doing e.g. make_linked_ptr(new FooBarBaz<type>(arg)) is a shorter notation
// for linked_ptr<FooBarBaz<type> >(new FooBarBaz<type>(arg))
template <typename T>
linked_ptr<T> make_linked_ptr(T* ptr) {
return linked_ptr<T>(ptr);
linked_ptr<T> make_linked_ptr(T* ptr)
{
return linked_ptr<T>(ptr);
}
} // namespace internal

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -43,7 +43,7 @@
#ifdef __BORLANDC__
// string.h is not guaranteed to provide strcpy on C++ Builder.
# include <mem.h>
#include <mem.h>
#endif
#include <string.h>
@@ -51,111 +51,113 @@
#include "gtest/internal/gtest-port.h"
namespace testing {
namespace internal {
namespace testing
{
namespace internal
{
// String - an abstract class holding static string utilities.
class GTEST_API_ String {
public:
// Static utility methods
class GTEST_API_ String
{
public:
// Static utility methods
// Clones a 0-terminated C string, allocating memory using new. The
// caller is responsible for deleting the return value using
// delete[]. Returns the cloned string, or NULL if the input is
// NULL.
//
// This is different from strdup() in string.h, which allocates
// memory using malloc().
static const char* CloneCString(const char* c_str);
// Clones a 0-terminated C string, allocating memory using new. The
// caller is responsible for deleting the return value using
// delete[]. Returns the cloned string, or NULL if the input is
// NULL.
//
// This is different from strdup() in string.h, which allocates
// memory using malloc().
static const char* CloneCString(const char* c_str);
#if GTEST_OS_WINDOWS_MOBILE
// Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
// able to pass strings to Win32 APIs on CE we need to convert them
// to 'Unicode', UTF-16.
// Windows CE does not have the 'ANSI' versions of Win32 APIs. To be
// able to pass strings to Win32 APIs on CE we need to convert them
// to 'Unicode', UTF-16.
// Creates a UTF-16 wide string from the given ANSI string, allocating
// memory using new. The caller is responsible for deleting the return
// value using delete[]. Returns the wide string, or NULL if the
// input is NULL.
//
// The wide string is created using the ANSI codepage (CP_ACP) to
// match the behaviour of the ANSI versions of Win32 calls and the
// C runtime.
static LPCWSTR AnsiToUtf16(const char* c_str);
// Creates a UTF-16 wide string from the given ANSI string, allocating
// memory using new. The caller is responsible for deleting the return
// value using delete[]. Returns the wide string, or NULL if the
// input is NULL.
//
// The wide string is created using the ANSI codepage (CP_ACP) to
// match the behaviour of the ANSI versions of Win32 calls and the
// C runtime.
static LPCWSTR AnsiToUtf16(const char* c_str);
// Creates an ANSI string from the given wide string, allocating
// memory using new. The caller is responsible for deleting the return
// value using delete[]. Returns the ANSI string, or NULL if the
// input is NULL.
//
// The returned string is created using the ANSI codepage (CP_ACP) to
// match the behaviour of the ANSI versions of Win32 calls and the
// C runtime.
static const char* Utf16ToAnsi(LPCWSTR utf16_str);
// Creates an ANSI string from the given wide string, allocating
// memory using new. The caller is responsible for deleting the return
// value using delete[]. Returns the ANSI string, or NULL if the
// input is NULL.
//
// The returned string is created using the ANSI codepage (CP_ACP) to
// match the behaviour of the ANSI versions of Win32 calls and the
// C runtime.
static const char* Utf16ToAnsi(LPCWSTR utf16_str);
#endif
// Compares two C strings. Returns true iff they have the same content.
//
// Unlike strcmp(), this function can handle NULL argument(s). A
// NULL C string is considered different to any non-NULL C string,
// including the empty string.
static bool CStringEquals(const char* lhs, const char* rhs);
// Compares two C strings. Returns true iff they have the same content.
//
// Unlike strcmp(), this function can handle NULL argument(s). A
// NULL C string is considered different to any non-NULL C string,
// including the empty string.
static bool CStringEquals(const char* lhs, const char* rhs);
// Converts a wide C string to a String using the UTF-8 encoding.
// NULL will be converted to "(null)". If an error occurred during
// the conversion, "(failed to convert from wide string)" is
// returned.
static std::string ShowWideCString(const wchar_t* wide_c_str);
// Converts a wide C string to a String using the UTF-8 encoding.
// NULL will be converted to "(null)". If an error occurred during
// the conversion, "(failed to convert from wide string)" is
// returned.
static std::string ShowWideCString(const wchar_t* wide_c_str);
// Compares two wide C strings. Returns true iff they have the same
// content.
//
// Unlike wcscmp(), this function can handle NULL argument(s). A
// NULL C string is considered different to any non-NULL C string,
// including the empty string.
static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);
// Compares two wide C strings. Returns true iff they have the same
// content.
//
// Unlike wcscmp(), this function can handle NULL argument(s). A
// NULL C string is considered different to any non-NULL C string,
// including the empty string.
static bool WideCStringEquals(const wchar_t* lhs, const wchar_t* rhs);
// Compares two C strings, ignoring case. Returns true iff they
// have the same content.
//
// Unlike strcasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL C string,
// including the empty string.
static bool CaseInsensitiveCStringEquals(const char* lhs,
const char* rhs);
// Compares two C strings, ignoring case. Returns true iff they
// have the same content.
//
// Unlike strcasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL C string,
// including the empty string.
static bool CaseInsensitiveCStringEquals(const char* lhs,
const char* rhs);
// Compares two wide C strings, ignoring case. Returns true iff they
// have the same content.
//
// Unlike wcscasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL wide C string,
// including the empty string.
// NB: The implementations on different platforms slightly differ.
// On windows, this method uses _wcsicmp which compares according to LC_CTYPE
// environment variable. On GNU platform this method uses wcscasecmp
// which compares according to LC_CTYPE category of the current locale.
// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
// current locale.
static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
const wchar_t* rhs);
// Compares two wide C strings, ignoring case. Returns true iff they
// have the same content.
//
// Unlike wcscasecmp(), this function can handle NULL argument(s).
// A NULL C string is considered different to any non-NULL wide C string,
// including the empty string.
// NB: The implementations on different platforms slightly differ.
// On windows, this method uses _wcsicmp which compares according to LC_CTYPE
// environment variable. On GNU platform this method uses wcscasecmp
// which compares according to LC_CTYPE category of the current locale.
// On MacOS X, it uses towlower, which also uses LC_CTYPE category of the
// current locale.
static bool CaseInsensitiveWideCStringEquals(const wchar_t* lhs,
const wchar_t* rhs);
// Returns true iff the given string ends with the given suffix, ignoring
// case. Any string is considered to end with an empty suffix.
static bool EndsWithCaseInsensitive(
const std::string& str, const std::string& suffix);
// Returns true iff the given string ends with the given suffix, ignoring
// case. Any string is considered to end with an empty suffix.
static bool EndsWithCaseInsensitive(
const std::string& str, const std::string& suffix);
// Formats an int value as "%02d".
static std::string FormatIntWidth2(int value); // "%02d" for width == 2
// Formats an int value as "%02d".
static std::string FormatIntWidth2(int value); // "%02d" for width == 2
// Formats an int value as "%X".
static std::string FormatHexInt(int value);
// Formats an int value as "%X".
static std::string FormatHexInt(int value);
// Formats a byte as "%02X".
static std::string FormatByte(unsigned char value);
// Formats a byte as "%02X".
static std::string FormatByte(unsigned char value);
private:
String(); // Not meant to be instantiated.
}; // class String
private:
String(); // Not meant to be instantiated.
}; // class String
// Gets the content of the stringstream's buffer as an std::string. Each '\0'
// character in the buffer is replaced with "\\0".

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff