From 56875007abe208b08f63fcf3ac77a2b9ab57ff6d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?D=C5=BEenan=20Zuki=C4=87?= Date: Wed, 29 Mar 2023 12:31:55 -0400 Subject: [PATCH 1/2] ENH: Use latest stable GTest v1.13.0 --- Modules/ThirdParty/GoogleTest/UpdateFromUpstream.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/ThirdParty/GoogleTest/UpdateFromUpstream.sh b/Modules/ThirdParty/GoogleTest/UpdateFromUpstream.sh index 8dd66025810..7985fe95c2c 100755 --- a/Modules/ThirdParty/GoogleTest/UpdateFromUpstream.sh +++ b/Modules/ThirdParty/GoogleTest/UpdateFromUpstream.sh @@ -8,7 +8,7 @@ readonly name="GoogleTest" readonly ownership="GoogleTest Upstream " readonly subtree="Modules/ThirdParty/GoogleTest/src/itkgoogletest" readonly repo="https://github.com/google/googletest.git" -readonly tag="release-1.12.1" +readonly tag="v1.13.0" readonly shortlog=false readonly paths=" CMakeLists.txt From 1a5c2de01758d78751305b5625c57be96052cc79 Mon Sep 17 00:00:00 2001 From: GoogleTest Upstream Date: Tue, 17 Jan 2023 10:36:43 -0800 Subject: [PATCH 2/2] GoogleTest 2023-01-17 (b796f7d4) Code extracted from: https://github.com/google/googletest.git at commit b796f7d44681514f58a683a3a71ff17c94edb0c1 (v1.13.0). --- CMakeLists.txt | 7 +- googletest/CMakeLists.txt | 16 ++ googletest/cmake/internal_utils.cmake | 24 +- googletest/include/gtest/gtest-matchers.h | 2 +- googletest/include/gtest/gtest-message.h | 2 + googletest/include/gtest/gtest-param-test.h | 47 +++- googletest/include/gtest/gtest-printers.h | 87 ++++++- googletest/include/gtest/gtest-spi.h | 2 + googletest/include/gtest/gtest-test-part.h | 2 + googletest/include/gtest/gtest.h | 41 ++- .../internal/gtest-death-test-internal.h | 3 +- .../include/gtest/internal/gtest-filepath.h | 17 ++ .../include/gtest/internal/gtest-internal.h | 9 +- .../include/gtest/internal/gtest-param-util.h | 75 ++++++ .../include/gtest/internal/gtest-port-arch.h | 2 + .../include/gtest/internal/gtest-port.h | 245 +++++++++++------- .../include/gtest/internal/gtest-string.h | 1 + .../include/gtest/internal/gtest-type-util.h | 4 + googletest/src/gtest-death-test.cc | 4 +- googletest/src/gtest-filepath.cc | 83 ++++-- googletest/src/gtest-internal-inl.h | 13 +- googletest/src/gtest-printers.cc | 2 +- googletest/src/gtest.cc | 193 +++++++++----- googletest/src/gtest_main.cc | 12 + 24 files changed, 665 insertions(+), 228 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 102e28cd49e..6af414371f7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,12 +7,16 @@ if (POLICY CMP0048) cmake_policy(SET CMP0048 NEW) endif (POLICY CMP0048) +if (POLICY CMP0069) + cmake_policy(SET CMP0069 NEW) +endif (POLICY CMP0069) + if (POLICY CMP0077) cmake_policy(SET CMP0077 NEW) endif (POLICY CMP0077) project(googletest-distribution) -set(GOOGLETEST_VERSION 1.12.1) +set(GOOGLETEST_VERSION 1.13.0) if(NOT CYGWIN AND NOT MSYS AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL QNX) set(CMAKE_CXX_EXTENSIONS OFF) @@ -26,6 +30,7 @@ include(GNUInstallDirs) #Note that googlemock target already builds googletest option(BUILD_GMOCK "Builds the googlemock subproject" ON) option(INSTALL_GTEST "Enable installation of googletest. (Projects embedding googletest may want to turn this OFF.)" ON) +option(GTEST_HAS_ABSL "Use Abseil and RE2. Requires Abseil and RE2 to be separately added to the build." OFF) if(BUILD_GMOCK) add_subdirectory( googlemock ) diff --git a/googletest/CMakeLists.txt b/googletest/CMakeLists.txt index aa00a5f3d27..95bfa442048 100644 --- a/googletest/CMakeLists.txt +++ b/googletest/CMakeLists.txt @@ -125,6 +125,22 @@ include_directories(${gtest_build_include_dirs}) # aggressive about warnings. cxx_library(gtest "${cxx_strict}" src/gtest-all.cc) set_target_properties(gtest PROPERTIES VERSION ${GOOGLETEST_VERSION}) +if(GTEST_HAS_ABSL) + target_compile_definitions(gtest PUBLIC GTEST_HAS_ABSL=1) + target_link_libraries(gtest PUBLIC + absl::failure_signal_handler + absl::stacktrace + absl::symbolize + absl::flags_parse + absl::flags_reflection + absl::flags_usage + absl::strings + absl::any + absl::optional + absl::variant + re2::re2 + ) +endif() cxx_library(gtest_main "${cxx_strict}" src/gtest_main.cc) set_target_properties(gtest_main PROPERTIES VERSION ${GOOGLETEST_VERSION}) # If the CMake version supports it, attach header directory information diff --git a/googletest/cmake/internal_utils.cmake b/googletest/cmake/internal_utils.cmake index 5a34c07a1b9..41405587fdd 100644 --- a/googletest/cmake/internal_utils.cmake +++ b/googletest/cmake/internal_utils.cmake @@ -21,8 +21,9 @@ endif (POLICY CMP0054) # This must be a macro(), as inside a function string() can only # update variables in the function scope. macro(fix_default_compiler_settings_) - if (MSVC) - # For MSVC, CMake sets certain flags to defaults we want to override. + if (CMAKE_CXX_COMPILER_ID MATCHES "MSVC|Clang") + # For MSVC and Clang, CMake sets certain flags to defaults we want to + # override. # This replacement code is taken from sample in the CMake Wiki at # https://gitlab.kitware.com/cmake/community/wikis/FAQ#dynamic-replace. foreach (flag_var @@ -39,6 +40,10 @@ macro(fix_default_compiler_settings_) # on CRT DLLs being available. CMake always defaults to using shared # CRT libraries, so we override that default here. string(REPLACE "/MD" "-MT" ${flag_var} "${${flag_var}}") + + # When using Ninja with Clang, static builds pass -D_DLL on Windows. + # This is incorrect and should not happen, so we fix that here. + string(REPLACE "-D_DLL" "" ${flag_var} "${${flag_var}}") endif() # We prefer more strict warning checking for building Google Test. @@ -82,7 +87,9 @@ macro(config_compiler_and_linker) # http://stackoverflow.com/questions/3232669 explains the issue. set(cxx_base_flags "${cxx_base_flags} -wd4702") # Ensure MSVC treats source files as UTF-8 encoded. - set(cxx_base_flags "${cxx_base_flags} -utf-8") + if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") + set(cxx_base_flags "${cxx_base_flags} -utf-8") + endif() elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") set(cxx_base_flags "-Wall -Wshadow -Wconversion") set(cxx_exception_flags "-fexceptions") @@ -160,7 +167,8 @@ function(cxx_library_with_type name type cxx_flags) RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" - PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin") + PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" + COMPILE_PDB_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib") # make PDBs match library name get_target_property(pdb_debug_postfix ${name} DEBUG_POSTFIX) set_target_properties(${name} @@ -189,7 +197,7 @@ function(cxx_library_with_type name type cxx_flags) endif() if (NOT "${CMAKE_VERSION}" VERSION_LESS "3.8") - target_compile_features(${name} PUBLIC cxx_std_11) + target_compile_features(${name} PUBLIC cxx_std_14) endif() endfunction() @@ -242,6 +250,12 @@ function(cxx_executable name dir libs) ${name} "${cxx_default}" "${libs}" "${dir}/${name}.cc" ${ARGN}) endfunction() +# CMP0094 policy enables finding a Python executable in the LOCATION order, as +# specified by the PATH environment variable. +if (POLICY CMP0094) + cmake_policy(SET CMP0094 NEW) +endif() + # Sets PYTHONINTERP_FOUND and PYTHON_EXECUTABLE. if ("${CMAKE_VERSION}" VERSION_LESS "3.12.0") find_package(PythonInterp) diff --git a/googletest/include/gtest/gtest-matchers.h b/googletest/include/gtest/gtest-matchers.h index bffa00c5338..4a60b0d0b8d 100644 --- a/googletest/include/gtest/gtest-matchers.h +++ b/googletest/include/gtest/gtest-matchers.h @@ -842,7 +842,7 @@ class MatchesRegexMatcher { template bool MatchAndExplain(const MatcheeStringType& s, MatchResultListener* /* listener */) const { - const std::string& s2(s); + const std::string s2(s); return full_match_ ? RE::FullMatch(s2, *regex_) : RE::PartialMatch(s2, *regex_); } diff --git a/googletest/include/gtest/gtest-message.h b/googletest/include/gtest/gtest-message.h index 6c8bf900094..4d4b152b1d8 100644 --- a/googletest/include/gtest/gtest-message.h +++ b/googletest/include/gtest/gtest-message.h @@ -50,7 +50,9 @@ #include #include +#include #include +#include #include "gtest/internal/gtest-port.h" diff --git a/googletest/include/gtest/gtest-param-test.h b/googletest/include/gtest/gtest-param-test.h index b55119ac62f..1adb9a72520 100644 --- a/googletest/include/gtest/gtest-param-test.h +++ b/googletest/include/gtest/gtest-param-test.h @@ -407,9 +407,49 @@ internal::CartesianProductHolder Combine(const Generator&... g) { return internal::CartesianProductHolder(g...); } +// ConvertGenerator() wraps a parameter generator in order to cast each produced +// value through a known type before supplying it to the test suite +// +// Synopsis: +// ConvertGenerator(gen) +// - returns a generator producing the same elements as generated by gen, but +// each element is static_cast to type T before being returned +// +// It is useful when using the Combine() function to get the generated +// parameters in a custom type instead of std::tuple +// +// Example: +// +// This will instantiate tests in test suite AnimalTest each one with +// the parameter values tuple("cat", BLACK), tuple("cat", WHITE), +// tuple("dog", BLACK), and tuple("dog", WHITE): +// +// enum Color { BLACK, GRAY, WHITE }; +// struct ParamType { +// using TupleT = std::tuple; +// std::string animal; +// Color color; +// ParamType(TupleT t) : animal(std::get<0>(t)), color(std::get<1>(t)) {} +// }; +// class AnimalTest +// : public testing::TestWithParam {...}; +// +// TEST_P(AnimalTest, AnimalLooksNice) {...} +// +// INSTANTIATE_TEST_SUITE_P(AnimalVariations, AnimalTest, +// ConvertGenerator( +// Combine(Values("cat", "dog"), +// Values(BLACK, WHITE)))); +// +template +internal::ParamConverterGenerator ConvertGenerator( + internal::ParamGenerator gen) { + return internal::ParamConverterGenerator(gen); +} + #define TEST_P(test_suite_name, test_name) \ class GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ - : public test_suite_name { \ + : public test_suite_name, private ::testing::internal::GTestNonCopyable {\ public: \ GTEST_TEST_CLASS_NAME_(test_suite_name, test_name)() {} \ void TestBody() override; \ @@ -429,11 +469,6 @@ internal::CartesianProductHolder Combine(const Generator&... g) { return 0; \ } \ static int gtest_registering_dummy_ GTEST_ATTRIBUTE_UNUSED_; \ - GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) \ - (const GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) &) = delete; \ - GTEST_TEST_CLASS_NAME_(test_suite_name, test_name) & operator=( \ - const GTEST_TEST_CLASS_NAME_(test_suite_name, \ - test_name) &) = delete; /* NOLINT */ \ }; \ int GTEST_TEST_CLASS_NAME_(test_suite_name, \ test_name)::gtest_registering_dummy_ = \ diff --git a/googletest/include/gtest/gtest-printers.h b/googletest/include/gtest/gtest-printers.h index a91e8b8b10e..0055e37ffa7 100644 --- a/googletest/include/gtest/gtest-printers.h +++ b/googletest/include/gtest/gtest-printers.h @@ -108,6 +108,7 @@ #include #include #include +#include #include #include @@ -384,7 +385,7 @@ GTEST_IMPL_FORMAT_C_STRING_AS_POINTER_(const char32_t); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char, ::std::string); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char, ::std::string); -#ifdef __cpp_char8_t +#ifdef __cpp_lib_char8_t GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(char8_t, ::std::u8string); GTEST_IMPL_FORMAT_C_STRING_AS_STRING_(const char8_t, ::std::u8string); #endif @@ -484,6 +485,81 @@ GTEST_API_ void PrintTo(__uint128_t v, ::std::ostream* os); GTEST_API_ void PrintTo(__int128_t v, ::std::ostream* os); #endif // __SIZEOF_INT128__ +// The default resolution used to print floating-point values uses only +// 6 digits, which can be confusing if a test compares two values whose +// difference lies in the 7th digit. So we'd like to print out numbers +// in full precision. +// However if the value is something simple like 1.1, full will print a +// long string like 1.100000001 due to floating-point numbers not using +// a base of 10. This routiune returns an appropriate resolution for a +// given floating-point number, that is, 6 if it will be accurate, or a +// max_digits10 value (full precision) if it won't, for values between +// 0.0001 and one million. +// It does this by computing what those digits would be (by multiplying +// by an appropriate power of 10), then dividing by that power again to +// see if gets the original value back. +// A similar algorithm applies for values larger than one million; note +// that for those values, we must divide to get a six-digit number, and +// then multiply to possibly get the original value again. +template +int AppropriateResolution(FloatType val) { + int full = std::numeric_limits::max_digits10; + if (val < 0) val = -val; + + if (val < 1000000) { + FloatType mulfor6 = 1e10; + if (val >= 100000.0) { // 100,000 to 999,999 + mulfor6 = 1.0; + } else if (val >= 10000.0) { + mulfor6 = 1e1; + } else if (val >= 1000.0) { + mulfor6 = 1e2; + } else if (val >= 100.0) { + mulfor6 = 1e3; + } else if (val >= 10.0) { + mulfor6 = 1e4; + } else if (val >= 1.0) { + mulfor6 = 1e5; + } else if (val >= 0.1) { + mulfor6 = 1e6; + } else if (val >= 0.01) { + mulfor6 = 1e7; + } else if (val >= 0.001) { + mulfor6 = 1e8; + } else if (val >= 0.0001) { + mulfor6 = 1e9; + } + if (static_cast(val * mulfor6 + 0.5) / mulfor6 == val) return 6; + } else if (val < 1e10) { + FloatType divfor6 = 1.0; + if (val >= 1e9) { // 1,000,000,000 to 9,999,999,999 + divfor6 = 10000; + } else if (val >= 1e8) { // 100,000,000 to 999,999,999 + divfor6 = 1000; + } else if (val >= 1e7) { // 10,000,000 to 99,999,999 + divfor6 = 100; + } else if (val >= 1e6) { // 1,000,000 to 9,999,999 + divfor6 = 10; + } + if (static_cast(val / divfor6 + 0.5) * divfor6 == val) return 6; + } + return full; +} + +inline void PrintTo(float f, ::std::ostream* os) { + auto old_precision = os->precision(); + os->precision(AppropriateResolution(f)); + *os << f; + os->precision(old_precision); +} + +inline void PrintTo(double d, ::std::ostream* os) { + auto old_precision = os->precision(); + os->precision(AppropriateResolution(d)); + *os << d; + os->precision(old_precision); +} + // Overloads for C strings. GTEST_API_ void PrintTo(const char* s, ::std::ostream* os); inline void PrintTo(char* s, ::std::ostream* os) { @@ -556,7 +632,7 @@ inline void PrintTo(const ::std::string& s, ::std::ostream* os) { } // Overloads for ::std::u8string -#ifdef __cpp_char8_t +#ifdef __cpp_lib_char8_t GTEST_API_ void PrintU8StringTo(const ::std::u8string& s, ::std::ostream* os); inline void PrintTo(const ::std::u8string& s, ::std::ostream* os) { PrintU8StringTo(s, os); @@ -891,6 +967,13 @@ class UniversalTersePrinter { UniversalPrint(value, os); } }; +template +class UniversalTersePrinter> { + public: + static void Print(std::reference_wrapper value, ::std::ostream* os) { + UniversalTersePrinter::Print(value.get(), os); + } +}; template class UniversalTersePrinter { public: diff --git a/googletest/include/gtest/gtest-spi.h b/googletest/include/gtest/gtest-spi.h index bec8c4810bb..c0613b69595 100644 --- a/googletest/include/gtest/gtest-spi.h +++ b/googletest/include/gtest/gtest-spi.h @@ -33,6 +33,8 @@ #ifndef GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_ #define GOOGLETEST_INCLUDE_GTEST_GTEST_SPI_H_ +#include + #include "gtest/gtest.h" GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ diff --git a/googletest/include/gtest/gtest-test-part.h b/googletest/include/gtest/gtest-test-part.h index 09cc8c34f04..8290b4d653d 100644 --- a/googletest/include/gtest/gtest-test-part.h +++ b/googletest/include/gtest/gtest-test-part.h @@ -35,6 +35,8 @@ #define GOOGLETEST_INCLUDE_GTEST_GTEST_TEST_PART_H_ #include +#include +#include #include #include "gtest/internal/gtest-internal.h" diff --git a/googletest/include/gtest/gtest.h b/googletest/include/gtest/gtest.h index d19a587a18c..3e452a503f8 100644 --- a/googletest/include/gtest/gtest.h +++ b/googletest/include/gtest/gtest.h @@ -50,9 +50,14 @@ #define GOOGLETEST_INCLUDE_GTEST_GTEST_H_ #include +#include +#include #include #include #include +#include +#include +#include #include #include @@ -190,6 +195,17 @@ void ReportFailureInUnknownLocation(TestPartResult::Type result_type, const std::string& message); std::set* GetIgnoredParameterizedTestSuites(); +// A base class that prevents subclasses from being copyable. +// We do this instead of using '= delete' so as to avoid triggering warnings +// inside user code regarding any of our declarations. +class GTestNonCopyable { + public: + GTestNonCopyable() = default; + GTestNonCopyable(const GTestNonCopyable &) = delete; + GTestNonCopyable &operator=(const GTestNonCopyable &) = delete; + ~GTestNonCopyable() = default; +}; + } // namespace internal // The friend relationship of some of these classes is cyclic. @@ -285,7 +301,7 @@ class GTEST_API_ Test { // SetUp/TearDown method of Environment objects registered with Google // Test) will be output as attributes of the element. static void RecordProperty(const std::string& key, const std::string& value); - static void RecordProperty(const std::string& key, int value); + static void RecordProperty(const std::string& key, int64_t value); protected: // Creates a Test object. @@ -1625,7 +1641,7 @@ class GTEST_API_ AssertHelper { // the GetParam() method. // // Use it with one of the parameter generator defining functions, like Range(), -// Values(), ValuesIn(), Bool(), and Combine(). +// Values(), ValuesIn(), Bool(), Combine(), and ConvertGenerator(). // // class FooTest : public ::testing::TestWithParam { // protected: @@ -1723,9 +1739,9 @@ class TestWithParam : public Test, public WithParamInterface {}; #define GTEST_FAIL() GTEST_FATAL_FAILURE_("Failed") // Like GTEST_FAIL(), but at the given source file location. -#define GTEST_FAIL_AT(file, line) \ - GTEST_MESSAGE_AT_(file, line, "Failed", \ - ::testing::TestPartResult::kFatalFailure) +#define GTEST_FAIL_AT(file, line) \ + return GTEST_MESSAGE_AT_(file, line, "Failed", \ + ::testing::TestPartResult::kFatalFailure) // Define this macro to 1 to omit the definition of FAIL(), which is a // generic name and clashes with some other libraries. @@ -2063,9 +2079,7 @@ class GTEST_API_ ScopedTrace { ScopedTrace(const ScopedTrace&) = delete; ScopedTrace& operator=(const ScopedTrace&) = delete; -} GTEST_ATTRIBUTE_UNUSED_; // A ScopedTrace object does its job in its - // c'tor and d'tor. Therefore it doesn't - // need to be used otherwise. +}; // Causes a trace (including the source file path, the current line // number, and the given message) to be included in every test failure @@ -2189,10 +2203,17 @@ constexpr bool StaticAssertTypeEq() noexcept { #define TEST_F(test_fixture, test_name) GTEST_TEST_F(test_fixture, test_name) #endif -// Returns a path to temporary directory. -// Tries to determine an appropriate directory for the platform. +// Returns a path to a temporary directory, which should be writable. It is +// implementation-dependent whether or not the path is terminated by the +// directory-separator character. GTEST_API_ std::string TempDir(); +// Returns a path to a directory that contains ancillary data files that might +// be used by tests. It is implementation dependent whether or not the path is +// terminated by the directory-separator character. The directory and the files +// in it should be considered read-only. +GTEST_API_ std::string SrcDir(); + #ifdef _MSC_VER #pragma warning(pop) #endif diff --git a/googletest/include/gtest/internal/gtest-death-test-internal.h b/googletest/include/gtest/internal/gtest-death-test-internal.h index 45580ae805c..4687dae2b46 100644 --- a/googletest/include/gtest/internal/gtest-death-test-internal.h +++ b/googletest/include/gtest/internal/gtest-death-test-internal.h @@ -42,6 +42,7 @@ #include #include +#include #include "gtest/gtest-matchers.h" #include "gtest/internal/gtest-internal.h" @@ -99,7 +100,7 @@ class GTEST_API_ DeathTest { DeathTest* const test_; ReturnSentinel(const ReturnSentinel&) = delete; ReturnSentinel& operator=(const ReturnSentinel&) = delete; - } GTEST_ATTRIBUTE_UNUSED_; + }; // An enumeration of possible roles that may be taken when a death // test is encountered. EXECUTE means that the death test logic should diff --git a/googletest/include/gtest/internal/gtest-filepath.h b/googletest/include/gtest/internal/gtest-filepath.h index a2a60a962b8..5189c81dabf 100644 --- a/googletest/include/gtest/internal/gtest-filepath.h +++ b/googletest/include/gtest/internal/gtest-filepath.h @@ -42,11 +42,16 @@ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ +#include + +#include "gtest/internal/gtest-port.h" #include "gtest/internal/gtest-string.h" GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \ /* class A needs to have dll-interface to be used by clients of class B */) +#if GTEST_HAS_FILE_SYSTEM + namespace testing { namespace internal { @@ -199,6 +204,16 @@ class GTEST_API_ FilePath { // separators. Returns NULL if no path separator was found. const char* FindLastPathSeparator() const; + // Returns the length of the path root, including the directory separator at + // the end of the prefix. Returns zero by definition if the path is relative. + // Examples: + // - [Windows] "..\Sibling" => 0 + // - [Windows] "\Windows" => 1 + // - [Windows] "C:/Windows\Notepad.exe" => 3 + // - [Windows] "\\Host\Share\C$/Windows" => 13 + // - [UNIX] "/bin" => 1 + size_t CalculateRootLength() const; + std::string pathname_; }; // class FilePath @@ -207,4 +222,6 @@ class GTEST_API_ FilePath { GTEST_DISABLE_MSC_WARNINGS_POP_() // 4251 +#endif // GTEST_HAS_FILE_SYSTEM + #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_FILEPATH_H_ diff --git a/googletest/include/gtest/internal/gtest-internal.h b/googletest/include/gtest/internal/gtest-internal.h index 9b04e4c85fa..3121d428b39 100644 --- a/googletest/include/gtest/internal/gtest-internal.h +++ b/googletest/include/gtest/internal/gtest-internal.h @@ -57,12 +57,14 @@ #include #include +#include #include #include #include #include #include #include +#include #include #include "gtest/gtest-message.h" @@ -461,7 +463,7 @@ class TestFactoryBase { TestFactoryBase& operator=(const TestFactoryBase&) = delete; }; -// This class provides implementation of TeastFactoryBase interface. +// This class provides implementation of TestFactoryBase interface. // It is used in TEST and TEST_F macros. template class TestFactoryImpl : public TestFactoryBase { @@ -631,7 +633,7 @@ class GTEST_API_ TypedTestSuitePState { const char* registered_tests); private: - typedef ::std::map RegisteredTestsMap; + typedef ::std::map> RegisteredTestsMap; bool registered_; RegisteredTestsMap registered_tests_; @@ -829,8 +831,7 @@ class TypeParameterizedTestSuite { // For example, if Foo() calls Bar(), which in turn calls // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. -GTEST_API_ std::string GetCurrentOsStackTraceExceptTop(UnitTest* unit_test, - int skip_count); +GTEST_API_ std::string GetCurrentOsStackTraceExceptTop(int skip_count); // Helpers for suppressing warnings on unreachable code or constant // condition. diff --git a/googletest/include/gtest/internal/gtest-param-util.h b/googletest/include/gtest/internal/gtest-param-util.h index e7af2f904a4..7092d10e677 100644 --- a/googletest/include/gtest/internal/gtest-param-util.h +++ b/googletest/include/gtest/internal/gtest-param-util.h @@ -40,8 +40,11 @@ #include #include +#include #include +#include #include +#include #include #include #include @@ -950,6 +953,78 @@ class CartesianProductHolder { std::tuple generators_; }; +template +class ParamGeneratorConverter : public ParamGeneratorInterface { + public: + ParamGeneratorConverter(ParamGenerator gen) // NOLINT + : generator_(std::move(gen)) {} + + ParamIteratorInterface* Begin() const override { + return new Iterator(this, generator_.begin(), generator_.end()); + } + ParamIteratorInterface* End() const override { + return new Iterator(this, generator_.end(), generator_.end()); + } + + private: + class Iterator : public ParamIteratorInterface { + public: + Iterator(const ParamGeneratorInterface* base, ParamIterator it, + ParamIterator end) + : base_(base), it_(it), end_(end) { + if (it_ != end_) value_ = std::make_shared(static_cast(*it_)); + } + ~Iterator() override {} + + const ParamGeneratorInterface* BaseGenerator() const override { + return base_; + } + void Advance() override { + ++it_; + if (it_ != end_) value_ = std::make_shared(static_cast(*it_)); + } + ParamIteratorInterface* Clone() const override { + return new Iterator(*this); + } + const To* Current() const override { return value_.get(); } + bool Equals(const ParamIteratorInterface& other) const override { + // Having the same base generator guarantees that the other + // iterator is of the same type and we can downcast. + GTEST_CHECK_(BaseGenerator() == other.BaseGenerator()) + << "The program attempted to compare iterators " + << "from different generators." << std::endl; + const ParamIterator other_it = + CheckedDowncastToActualType(&other)->it_; + return it_ == other_it; + } + + private: + Iterator(const Iterator& other) = default; + + const ParamGeneratorInterface* const base_; + ParamIterator it_; + ParamIterator end_; + std::shared_ptr value_; + }; // class ParamGeneratorConverter::Iterator + + ParamGenerator generator_; +}; // class ParamGeneratorConverter + +template +class ParamConverterGenerator { + public: + ParamConverterGenerator(ParamGenerator g) // NOLINT + : generator_(std::move(g)) {} + + template + operator ParamGenerator() const { // NOLINT + return ParamGenerator(new ParamGeneratorConverter(generator_)); + } + + private: + ParamGenerator generator_; +}; + } // namespace internal } // namespace testing diff --git a/googletest/include/gtest/internal/gtest-port-arch.h b/googletest/include/gtest/internal/gtest-port-arch.h index f025db76ad3..04064606f5d 100644 --- a/googletest/include/gtest/internal/gtest-port-arch.h +++ b/googletest/include/gtest/internal/gtest-port-arch.h @@ -111,6 +111,8 @@ #define GTEST_OS_ESP32 1 #elif defined(__XTENSA__) #define GTEST_OS_XTENSA 1 +#elif defined(__hexagon__) +#define GTEST_OS_QURT 1 #endif // __CYGWIN__ #endif // GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_PORT_ARCH_H_ diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index 0003d276589..6db191b7a06 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -83,6 +83,8 @@ // GTEST_HAS_STD_WSTRING - Define it to 1/0 to indicate that // std::wstring does/doesn't work (Google Test can // be used where std::wstring is unavailable). +// GTEST_HAS_FILE_SYSTEM - Define it to 1/0 to indicate whether or not a +// file system is/isn't available. // GTEST_HAS_SEH - Define it to 1/0 to indicate whether the // compiler supports Microsoft's "Structured // Exception Handling". @@ -255,6 +257,19 @@ // deprecated; calling a marked function // should generate a compiler warning +// The definition of GTEST_INTERNAL_CPLUSPLUS_LANG comes first because it can +// potentially be used as an #include guard. +#if defined(_MSVC_LANG) +#define GTEST_INTERNAL_CPLUSPLUS_LANG _MSVC_LANG +#elif defined(__cplusplus) +#define GTEST_INTERNAL_CPLUSPLUS_LANG __cplusplus +#endif + +#if !defined(GTEST_INTERNAL_CPLUSPLUS_LANG) || \ + GTEST_INTERNAL_CPLUSPLUS_LANG < 201402L +#error C++ versions less than C++14 are not supported. +#endif + #include // for isspace, etc #include // for ptrdiff_t #include @@ -268,6 +283,7 @@ #include #include #include +#include #include // #include // Guarded by GTEST_IS_THREADSAFE below #include @@ -385,7 +401,8 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // On Android, is only available starting with Gingerbread. #define GTEST_HAS_POSIX_RE (__ANDROID_API__ >= 9) #else -#define GTEST_HAS_POSIX_RE (!GTEST_OS_WINDOWS && !GTEST_OS_XTENSA) +#define GTEST_HAS_POSIX_RE \ + !(GTEST_OS_WINDOWS || GTEST_OS_XTENSA || GTEST_OS_QURT) #endif #endif @@ -457,10 +474,16 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // no support for it at least as recent as Froyo (2.2). #define GTEST_HAS_STD_WSTRING \ (!(GTEST_OS_LINUX_ANDROID || GTEST_OS_CYGWIN || GTEST_OS_SOLARIS || \ - GTEST_OS_HAIKU || GTEST_OS_ESP32 || GTEST_OS_ESP8266 || GTEST_OS_XTENSA)) + GTEST_OS_HAIKU || GTEST_OS_ESP32 || GTEST_OS_ESP8266 || \ + GTEST_OS_XTENSA || GTEST_OS_QURT)) #endif // GTEST_HAS_STD_WSTRING +#ifndef GTEST_HAS_FILE_SYSTEM +// Most platforms support a file system. +#define GTEST_HAS_FILE_SYSTEM 1 +#endif // GTEST_HAS_FILE_SYSTEM + // Determines whether RTTI is available. #ifndef GTEST_HAS_RTTI // The user didn't tell us whether RTTI is enabled, so we need to @@ -578,9 +601,11 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // output correctness and to implement death tests. #ifndef GTEST_HAS_STREAM_REDIRECTION // By default, we assume that stream redirection is supported on all -// platforms except known mobile ones. -#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ - GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA +// platforms except known mobile / embedded ones. Also, if the port doesn't have +// a file system, stream redirection is not supported. +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ + GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA || \ + GTEST_OS_QURT || !GTEST_HAS_FILE_SYSTEM #define GTEST_HAS_STREAM_REDIRECTION 0 #else #define GTEST_HAS_STREAM_REDIRECTION 1 @@ -596,7 +621,10 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; GTEST_OS_FREEBSD || GTEST_OS_NETBSD || GTEST_OS_FUCHSIA || \ GTEST_OS_DRAGONFLY || GTEST_OS_GNU_KFREEBSD || GTEST_OS_HAIKU || \ GTEST_OS_GNU_HURD) +// Death tests require a file system to work properly. +#if GTEST_HAS_FILE_SYSTEM #define GTEST_HAS_DEATH_TEST 1 +#endif // GTEST_HAS_FILE_SYSTEM #endif // Determines whether to support type-driven tests. @@ -639,41 +667,53 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; default: // NOLINT #endif -// Use this annotation at the end of a struct/class definition to -// prevent the compiler from optimizing away instances that are never -// used. This is useful when all interesting logic happens inside the -// c'tor and / or d'tor. Example: +// GTEST_HAVE_ATTRIBUTE_ // -// struct Foo { -// Foo() { ... } -// } GTEST_ATTRIBUTE_UNUSED_; +// A function-like feature checking macro that is a wrapper around +// `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a +// nonzero constant integer if the attribute is supported or 0 if not. // -// Also use it after a variable or parameter declaration to tell the -// compiler the variable/parameter does not have to be used. -#if defined(__GNUC__) && !defined(COMPILER_ICC) -#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused)) -#elif defined(__clang__) -#if __has_attribute(unused) -#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused)) +// It evaluates to zero if `__has_attribute` is not defined by the compiler. +// +// GCC: https://gcc.gnu.org/gcc-5/changes.html +// Clang: https://clang.llvm.org/docs/LanguageExtensions.html +#ifdef __has_attribute +#define GTEST_HAVE_ATTRIBUTE_(x) __has_attribute(x) +#else +#define GTEST_HAVE_ATTRIBUTE_(x) 0 #endif + +// GTEST_HAVE_FEATURE_ +// +// A function-like feature checking macro that is a wrapper around +// `__has_feature`. +#ifdef __has_feature +#define GTEST_HAVE_FEATURE_(x) __has_feature(x) +#else +#define GTEST_HAVE_FEATURE_(x) 0 #endif -#ifndef GTEST_ATTRIBUTE_UNUSED_ + +// Use this annotation after a variable or parameter declaration to tell the +// compiler the variable/parameter does not have to be used. +// Example: +// +// GTEST_ATTRIBUTE_UNUSED_ int foo = bar(); +#if GTEST_HAVE_ATTRIBUTE_(unused) +#define GTEST_ATTRIBUTE_UNUSED_ __attribute__((unused)) +#else #define GTEST_ATTRIBUTE_UNUSED_ #endif // Use this annotation before a function that takes a printf format string. -#if (defined(__GNUC__) || defined(__clang__)) && !defined(COMPILER_ICC) -#if defined(__MINGW_PRINTF_FORMAT) +#if GTEST_HAVE_ATTRIBUTE_(format) && defined(__MINGW_PRINTF_FORMAT) // MinGW has two different printf implementations. Ensure the format macro // matches the selected implementation. See // https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/. #define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \ - __attribute__(( \ - __format__(__MINGW_PRINTF_FORMAT, string_index, first_to_check))) -#else -#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \ - __attribute__((__format__(__printf__, string_index, first_to_check))) -#endif + __attribute__((format(__MINGW_PRINTF_FORMAT, string_index, first_to_check))) +#elif GTEST_HAVE_ATTRIBUTE_(format) +#define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) \ + __attribute__((format(printf, string_index, first_to_check))) #else #define GTEST_ATTRIBUTE_PRINTF_(string_index, first_to_check) #endif @@ -683,11 +723,11 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // following the argument list: // // Sprocket* AllocateSprocket() GTEST_MUST_USE_RESULT_; -#if defined(__GNUC__) && !defined(COMPILER_ICC) +#if GTEST_HAVE_ATTRIBUTE_(warn_unused_result) #define GTEST_MUST_USE_RESULT_ __attribute__((warn_unused_result)) #else #define GTEST_MUST_USE_RESULT_ -#endif // __GNUC__ && !COMPILER_ICC +#endif // MS C++ compiler emits warning when a conditional expression is compile time // constant. In some contexts this warning is false positive and needs to be @@ -743,7 +783,7 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; #elif GTEST_CREATE_SHARED_LIBRARY #define GTEST_API_ __declspec(dllexport) #endif -#elif __GNUC__ >= 4 || defined(__clang__) +#elif GTEST_HAVE_ATTRIBUTE_(visibility) #define GTEST_API_ __attribute__((visibility("default"))) #endif // _MSC_VER @@ -757,20 +797,17 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; #define GTEST_DEFAULT_DEATH_TEST_STYLE "fast" #endif // GTEST_DEFAULT_DEATH_TEST_STYLE -#ifdef __GNUC__ +#if GTEST_HAVE_ATTRIBUTE_(noinline) // Ask the compiler to never inline a given function. #define GTEST_NO_INLINE_ __attribute__((noinline)) #else #define GTEST_NO_INLINE_ #endif -#if defined(__clang__) -// Nested ifs to avoid triggering MSVC warning. -#if __has_attribute(disable_tail_calls) +#if GTEST_HAVE_ATTRIBUTE_(disable_tail_calls) // Ask the compiler not to perform tail call optimization inside // the marked function. #define GTEST_NO_TAIL_CALL_ __attribute__((disable_tail_calls)) -#endif #elif __GNUC__ #define GTEST_NO_TAIL_CALL_ \ __attribute__((optimize("no-optimize-sibling-calls"))) @@ -789,50 +826,35 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; // A function level attribute to disable checking for use of uninitialized // memory when built with MemorySanitizer. -#if defined(__clang__) -#if __has_feature(memory_sanitizer) +#if GTEST_HAVE_ATTRIBUTE_(no_sanitize_memory) #define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ __attribute__((no_sanitize_memory)) #else #define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ -#endif // __has_feature(memory_sanitizer) -#else -#define GTEST_ATTRIBUTE_NO_SANITIZE_MEMORY_ -#endif // __clang__ +#endif // A function level attribute to disable AddressSanitizer instrumentation. -#if defined(__clang__) -#if __has_feature(address_sanitizer) +#if GTEST_HAVE_ATTRIBUTE_(no_sanitize_address) #define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ \ __attribute__((no_sanitize_address)) #else #define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ -#endif // __has_feature(address_sanitizer) -#else -#define GTEST_ATTRIBUTE_NO_SANITIZE_ADDRESS_ -#endif // __clang__ +#endif // A function level attribute to disable HWAddressSanitizer instrumentation. -#if defined(__clang__) -#if __has_feature(hwaddress_sanitizer) +#if GTEST_HAVE_FEATURE_(hwaddress_sanitizer) && \ + GTEST_HAVE_ATTRIBUTE_(no_sanitize) #define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ \ __attribute__((no_sanitize("hwaddress"))) #else #define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ -#endif // __has_feature(hwaddress_sanitizer) -#else -#define GTEST_ATTRIBUTE_NO_SANITIZE_HWADDRESS_ -#endif // __clang__ +#endif // A function level attribute to disable ThreadSanitizer instrumentation. -#if defined(__clang__) -#if __has_feature(thread_sanitizer) -#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ __attribute__((no_sanitize_thread)) -#else -#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ -#endif // __has_feature(thread_sanitizer) +#if GTEST_HAVE_ATTRIBUTE_(no_sanitize_thread) +#define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ __attribute((no_sanitize_thread)) #else #define GTEST_ATTRIBUTE_NO_SANITIZE_THREAD_ -#endif // __clang__ +#endif namespace testing { @@ -1710,7 +1732,7 @@ typedef GTestMutexLock MutexLock; // C-linkage. Therefore it cannot be templatized to access // ThreadLocal. Hence the need for class // ThreadLocalValueHolderBase. -class ThreadLocalValueHolderBase { +class GTEST_API_ ThreadLocalValueHolderBase { public: virtual ~ThreadLocalValueHolderBase() {} }; @@ -1956,12 +1978,55 @@ inline std::string StripTrailingSpaces(std::string str) { namespace posix { -// Functions with a different name on Windows. - +// File system porting. +#if GTEST_HAS_FILE_SYSTEM #if GTEST_OS_WINDOWS typedef struct _stat StatStruct; +#if GTEST_OS_WINDOWS_MOBILE +inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } +// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this +// time and thus not defined there. +#else +inline int FileNo(FILE* file) { return _fileno(file); } +inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } +inline int RmDir(const char* dir) { return _rmdir(dir); } +inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; } +#endif // GTEST_OS_WINDOWS_MOBILE + +#elif GTEST_OS_ESP8266 +typedef struct stat StatStruct; + +inline int FileNo(FILE* file) { return fileno(file); } +inline int Stat(const char* path, StatStruct* buf) { + // stat function not implemented on ESP8266 + return 0; +} +inline int RmDir(const char* dir) { return rmdir(dir); } +inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } + +#else + +typedef struct stat StatStruct; + +inline int FileNo(FILE* file) { return fileno(file); } +inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } +#if GTEST_OS_QURT +// QuRT doesn't support any directory functions, including rmdir +inline int RmDir(const char*) { return 0; } +#else +inline int RmDir(const char* dir) { return rmdir(dir); } +#endif +inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } + +#endif // GTEST_OS_WINDOWS +#endif // GTEST_HAS_FILE_SYSTEM + +// Other functions with a different name on Windows. + +#if GTEST_OS_WINDOWS + #ifdef __BORLANDC__ inline int DoIsATTY(int fd) { return isatty(fd); } inline int StrCaseCmp(const char* s1, const char* s2) { @@ -1981,46 +2046,21 @@ inline int StrCaseCmp(const char* s1, const char* s2) { inline char* StrDup(const char* src) { return _strdup(src); } #endif // __BORLANDC__ -#if GTEST_OS_WINDOWS_MOBILE -inline int FileNo(FILE* file) { return reinterpret_cast(_fileno(file)); } -// Stat(), RmDir(), and IsDir() are not needed on Windows CE at this -// time and thus not defined there. -#else -inline int FileNo(FILE* file) { return _fileno(file); } -inline int Stat(const char* path, StatStruct* buf) { return _stat(path, buf); } -inline int RmDir(const char* dir) { return _rmdir(dir); } -inline bool IsDir(const StatStruct& st) { return (_S_IFDIR & st.st_mode) != 0; } -#endif // GTEST_OS_WINDOWS_MOBILE - #elif GTEST_OS_ESP8266 -typedef struct stat StatStruct; -inline int FileNo(FILE* file) { return fileno(file); } inline int DoIsATTY(int fd) { return isatty(fd); } -inline int Stat(const char* path, StatStruct* buf) { - // stat function not implemented on ESP8266 - return 0; -} inline int StrCaseCmp(const char* s1, const char* s2) { return strcasecmp(s1, s2); } inline char* StrDup(const char* src) { return strdup(src); } -inline int RmDir(const char* dir) { return rmdir(dir); } -inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } #else -typedef struct stat StatStruct; - -inline int FileNo(FILE* file) { return fileno(file); } inline int DoIsATTY(int fd) { return isatty(fd); } -inline int Stat(const char* path, StatStruct* buf) { return stat(path, buf); } inline int StrCaseCmp(const char* s1, const char* s2) { return strcasecmp(s1, s2); } inline char* StrDup(const char* src) { return strdup(src); } -inline int RmDir(const char* dir) { return rmdir(dir); } -inline bool IsDir(const StatStruct& st) { return S_ISDIR(st.st_mode); } #endif // GTEST_OS_WINDOWS @@ -2042,9 +2082,10 @@ GTEST_DISABLE_MSC_DEPRECATED_PUSH_() // ChDir(), FReopen(), FDOpen(), Read(), Write(), Close(), and // StrError() aren't needed on Windows CE at this time and thus not // defined there. - -#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && \ - !GTEST_OS_WINDOWS_RT && !GTEST_OS_ESP8266 && !GTEST_OS_XTENSA +#if GTEST_HAS_FILE_SYSTEM +#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_WINDOWS_PHONE && \ + !GTEST_OS_WINDOWS_RT && !GTEST_OS_ESP8266 && !GTEST_OS_XTENSA && \ + !GTEST_OS_QURT inline int ChDir(const char* dir) { return chdir(dir); } #endif inline FILE* FOpen(const char* path, const char* mode) { @@ -2058,14 +2099,14 @@ inline FILE* FOpen(const char* path, const char* mode) { return fopen(path, mode); #endif // GTEST_OS_WINDOWS && !GTEST_OS_WINDOWS_MINGW } -#if !GTEST_OS_WINDOWS_MOBILE +#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT inline FILE* FReopen(const char* path, const char* mode, FILE* stream) { return freopen(path, mode, stream); } inline FILE* FDOpen(int fd, const char* mode) { return fdopen(fd, mode); } -#endif +#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT inline int FClose(FILE* fp) { return fclose(fp); } -#if !GTEST_OS_WINDOWS_MOBILE +#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT inline int Read(int fd, void* buf, unsigned int count) { return static_cast(read(fd, buf, count)); } @@ -2073,11 +2114,17 @@ inline int Write(int fd, const void* buf, unsigned int count) { return static_cast(write(fd, buf, count)); } inline int Close(int fd) { return close(fd); } +#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT +#endif // GTEST_HAS_FILE_SYSTEM + +#if !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT inline const char* StrError(int errnum) { return strerror(errnum); } -#endif +#endif // !GTEST_OS_WINDOWS_MOBILE && !GTEST_OS_QURT + inline const char* GetEnv(const char* name) { -#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ - GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA +#if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ + GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_XTENSA || \ + GTEST_OS_QURT // We are on an embedded platform, which has no environment variables. static_cast(name); // To prevent 'unused argument' warning. return nullptr; @@ -2109,7 +2156,7 @@ GTEST_DISABLE_MSC_DEPRECATED_POP_() // MSVC-based platforms. We map the GTEST_SNPRINTF_ macro to the appropriate // function in order to achieve that. We use macro definition here because // snprintf is a variadic function. -#if _MSC_VER && !GTEST_OS_WINDOWS_MOBILE +#if defined(_MSC_VER) && !GTEST_OS_WINDOWS_MOBILE // MSVC 2005 and above support variadic macros. #define GTEST_SNPRINTF_(buffer, size, format, ...) \ _snprintf_s(buffer, size, size, format, __VA_ARGS__) diff --git a/googletest/include/gtest/internal/gtest-string.h b/googletest/include/gtest/internal/gtest-string.h index cca2e1f2ad9..cc0dd7529c1 100644 --- a/googletest/include/gtest/internal/gtest-string.h +++ b/googletest/include/gtest/internal/gtest-string.h @@ -51,6 +51,7 @@ #include #include +#include #include #include "gtest/internal/gtest-port.h" diff --git a/googletest/include/gtest/internal/gtest-type-util.h b/googletest/include/gtest/internal/gtest-type-util.h index 6bc02a7de30..17a470b6265 100644 --- a/googletest/include/gtest/internal/gtest-type-util.h +++ b/googletest/include/gtest/internal/gtest-type-util.h @@ -37,6 +37,10 @@ #ifndef GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ #define GOOGLETEST_INCLUDE_GTEST_INTERNAL_GTEST_TYPE_UTIL_H_ +#include +#include +#include + #include "gtest/internal/gtest-port.h" // #ifdef __GNUC__ is too general here. It is possible to use gcc without using diff --git a/googletest/src/gtest-death-test.cc b/googletest/src/gtest-death-test.cc index e6abc6278ae..b6968a9c949 100644 --- a/googletest/src/gtest-death-test.cc +++ b/googletest/src/gtest-death-test.cc @@ -249,7 +249,7 @@ static std::string DeathTestThreadWarning(size_t thread_count) { msg << "detected " << thread_count << " threads."; } msg << " See " - "https://github.com/google/googletest/blob/master/docs/" + "https://github.com/google/googletest/blob/main/docs/" "advanced.md#death-tests-and-threads" << " for more explanation and suggested solutions, especially if" << " this is the last message you see before your test times out."; @@ -284,7 +284,7 @@ enum DeathTestOutcome { IN_PROGRESS, DIED, LIVED, RETURNED, THREW }; // message is propagated back to the parent process. Otherwise, the // message is simply printed to stderr. In either case, the program // then exits with status 1. -static void DeathTestAbort(const std::string& message) { +[[noreturn]] static void DeathTestAbort(const std::string& message) { // On a POSIX system, this function may be called from a threadsafe-style // death test child process, which operates on a very small stack. Use // the heap for any additional non-minuscule memory requirements. diff --git a/googletest/src/gtest-filepath.cc b/googletest/src/gtest-filepath.cc index f6ee90cdb7c..9d79ea49d8a 100644 --- a/googletest/src/gtest-filepath.cc +++ b/googletest/src/gtest-filepath.cc @@ -57,6 +57,8 @@ #define GTEST_PATH_MAX_ _POSIX_PATH_MAX #endif // GTEST_OS_WINDOWS +#if GTEST_HAS_FILE_SYSTEM + namespace testing { namespace internal { @@ -96,7 +98,7 @@ static bool IsPathSeparator(char c) { FilePath FilePath::GetCurrentDir() { #if GTEST_OS_WINDOWS_MOBILE || GTEST_OS_WINDOWS_PHONE || \ GTEST_OS_WINDOWS_RT || GTEST_OS_ESP8266 || GTEST_OS_ESP32 || \ - GTEST_OS_XTENSA + GTEST_OS_XTENSA || GTEST_OS_QURT // These platforms do not have a current directory, so we just return // something reasonable. return FilePath(kCurrentDirectoryString); @@ -145,6 +147,45 @@ const char* FilePath::FindLastPathSeparator() const { return last_sep; } +size_t FilePath::CalculateRootLength() const { + const auto &path = pathname_; + auto s = path.begin(); + auto end = path.end(); +#if GTEST_OS_WINDOWS + if (end - s >= 2 && s[1] == ':' && + (end - s == 2 || IsPathSeparator(s[2])) && + (('A' <= s[0] && s[0] <= 'Z') || ('a' <= s[0] && s[0] <= 'z'))) { + // A typical absolute path like "C:\Windows" or "D:" + s += 2; + if (s != end) { + ++s; + } + } else if (end - s >= 3 && IsPathSeparator(*s) && IsPathSeparator(*(s + 1)) + && !IsPathSeparator(*(s + 2))) { + // Move past the "\\" prefix in a UNC path like "\\Server\Share\Folder" + s += 2; + // Skip 2 components and their following separators ("Server\" and "Share\") + for (int i = 0; i < 2; ++i) { + while (s != end) { + bool stop = IsPathSeparator(*s); + ++s; + if (stop) { + break; + } + } + } + } else if (s != end && IsPathSeparator(*s)) { + // A drive-rooted path like "\Windows" + ++s; + } +#else + if (s != end && IsPathSeparator(*s)) { + ++s; + } +#endif + return static_cast(s - path.begin()); +} + // 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 @@ -246,26 +287,16 @@ bool FilePath::DirectoryExists() const { } // Returns true if pathname describes a root directory. (Windows has one -// root directory per disk drive.) +// root directory per disk drive. UNC share roots are also included.) bool FilePath::IsRootDirectory() const { -#if GTEST_OS_WINDOWS - return pathname_.length() == 3 && IsAbsolutePath(); -#else - return pathname_.length() == 1 && IsPathSeparator(pathname_.c_str()[0]); -#endif + size_t root_length = CalculateRootLength(); + return root_length > 0 && root_length == pathname_.size() && + IsPathSeparator(pathname_[root_length - 1]); } // Returns true if pathname describes an absolute path. bool FilePath::IsAbsolutePath() const { - const char* const name = pathname_.c_str(); -#if GTEST_OS_WINDOWS - return pathname_.length() >= 3 && - ((name[0] >= 'a' && name[0] <= 'z') || - (name[0] >= 'A' && name[0] <= 'Z')) && - name[1] == ':' && IsPathSeparator(name[2]); -#else - return IsPathSeparator(name[0]); -#endif + return CalculateRootLength() > 0; } // Returns a pathname for a file that does not currently exist. The pathname @@ -323,7 +354,7 @@ bool FilePath::CreateFolder() const { delete[] unicode; #elif GTEST_OS_WINDOWS int result = _mkdir(pathname_.c_str()); -#elif GTEST_OS_ESP8266 || GTEST_OS_XTENSA +#elif GTEST_OS_ESP8266 || GTEST_OS_XTENSA || GTEST_OS_QURT // do nothing int result = 0; #else @@ -347,17 +378,27 @@ FilePath FilePath::RemoveTrailingPathSeparator() const { // Removes any redundant separators that might be in the pathname. // For example, "bar///foo" becomes "bar/foo". Does not eliminate other // redundancies that might be in a pathname involving "." or "..". +// Note that "\\Host\Share" does not contain a redundancy on Windows! void FilePath::Normalize() { auto out = pathname_.begin(); - for (const char character : pathname_) { + auto i = pathname_.cbegin(); +#if GTEST_OS_WINDOWS + // UNC paths are treated specially + if (pathname_.end() - i >= 3 && IsPathSeparator(*i) && + IsPathSeparator(*(i + 1)) && !IsPathSeparator(*(i + 2))) { + *(out++) = kPathSeparator; + *(out++) = kPathSeparator; + } +#endif + while (i != pathname_.end()) { + const char character = *i; if (!IsPathSeparator(character)) { *(out++) = character; } else if (out == pathname_.begin() || *std::prev(out) != kPathSeparator) { *(out++) = kPathSeparator; - } else { - continue; } + ++i; } pathname_.erase(out, pathname_.end()); @@ -365,3 +406,5 @@ void FilePath::Normalize() { } // namespace internal } // namespace testing + +#endif // GTEST_HAS_FILE_SYSTEM diff --git a/googletest/src/gtest-internal-inl.h b/googletest/src/gtest-internal-inl.h index 0b9e929c689..2c9db4f2078 100644 --- a/googletest/src/gtest-internal-inl.h +++ b/googletest/src/gtest-internal-inl.h @@ -44,6 +44,7 @@ #include #include #include +#include #include #include @@ -212,7 +213,7 @@ class GTestFlagSaver { int32_t stack_trace_depth_; std::string stream_result_to_; bool throw_on_failure_; -} GTEST_ATTRIBUTE_UNUSED_; +}; // Converts a Unicode code point to a narrow string in UTF-8 encoding. // code_point parameter is of type UInt32 because wchar_t may not be @@ -396,9 +397,11 @@ class GTEST_API_ UnitTestOptions { static bool MatchesFilter(const std::string& name, const char* filter); }; +#if GTEST_HAS_FILE_SYSTEM // Returns the current application's name, removing directory path if that // is present. Used by UnitTestOptions::GetOutputFile. GTEST_API_ FilePath GetCurrentExecutableName(); +#endif // GTEST_HAS_FILE_SYSTEM // The role interface for getting the OS stack trace as a string. class OsStackTraceGetterInterface { @@ -507,9 +510,9 @@ class GTEST_API_ UnitTestImpl { virtual ~UnitTestImpl(); // There are two different ways to register your own TestPartResultReporter. - // You can register your own repoter to listen either only for test results + // You can register your own reporter to listen either only for test results // from the current thread or for results from all threads. - // By default, each per-thread test result repoter just passes a new + // By default, each per-thread test result reporter just passes a new // TestPartResult to the global test result reporter, which registers the // test part result for the currently running test. @@ -840,9 +843,11 @@ class GTEST_API_ UnitTestImpl { // The UnitTest object that owns this implementation object. UnitTest* const parent_; +#if GTEST_HAS_FILE_SYSTEM // The working directory when the first TEST() or TEST_F() was // executed. internal::FilePath original_working_dir_; +#endif // GTEST_HAS_FILE_SYSTEM // The default test part result reporters. DefaultGlobalTestPartResultReporter default_global_test_part_result_reporter_; @@ -850,7 +855,7 @@ class GTEST_API_ UnitTestImpl { default_per_thread_test_part_result_reporter_; // Points to (but doesn't own) the global test part result reporter. - TestPartResultReporterInterface* global_test_part_result_repoter_; + TestPartResultReporterInterface* global_test_part_result_reporter_; // Protects read and write access to global_test_part_result_reporter_. internal::Mutex global_test_part_result_reporter_mutex_; diff --git a/googletest/src/gtest-printers.cc b/googletest/src/gtest-printers.cc index f3976d230da..d475ad36f5e 100644 --- a/googletest/src/gtest-printers.cc +++ b/googletest/src/gtest-printers.cc @@ -315,7 +315,7 @@ void PrintTo(__uint128_t v, ::std::ostream* os) { low = low / 10 + high_mod * 1844674407370955161 + carry / 10; char digit = static_cast(carry % 10); - *--p = '0' + digit; + *--p = static_cast('0' + digit); } *os << p; } diff --git a/googletest/src/gtest.cc b/googletest/src/gtest.cc index 6f31dd22603..a64e887c969 100644 --- a/googletest/src/gtest.cc +++ b/googletest/src/gtest.cc @@ -58,6 +58,7 @@ #include "gtest/gtest-assertion-result.h" #include "gtest/gtest-spi.h" #include "gtest/internal/custom/gtest.h" +#include "gtest/internal/gtest-port.h" #if GTEST_OS_LINUX @@ -143,6 +144,14 @@ #include "absl/strings/str_replace.h" #endif // GTEST_HAS_ABSL +// Checks builtin compiler feature |x| while avoiding an extra layer of #ifdefs +// at the callsite. +#if defined(__has_builtin) +#define GTEST_HAS_BUILTIN(x) __has_builtin(x) +#else +#define GTEST_HAS_BUILTIN(x) 0 +#endif // defined(__has_builtin) + namespace testing { using internal::CountIf; @@ -186,6 +195,7 @@ const char kStackTraceMarker[] = "\nStack trace:\n"; // is specified on the command line. bool g_help_flag = false; +#if GTEST_HAS_FILE_SYSTEM // Utility function to Open File for Writing static FILE* OpenFileForWriting(const std::string& output_file) { FILE* fileout = nullptr; @@ -200,6 +210,7 @@ static FILE* OpenFileForWriting(const std::string& output_file) { } return fileout; } +#endif // GTEST_HAS_FILE_SYSTEM } // namespace internal @@ -372,6 +383,8 @@ GTEST_DEFINE_string_( namespace testing { namespace internal { +const uint32_t Random::kMaxRange; + // Generates a random number from [0, range), using a Linear // Congruential Generator (LCG). Crashes if 'range' is 0 or greater // than kMaxRange. @@ -610,6 +623,7 @@ ::std::vector GetArgvs() { #endif // defined(GTEST_CUSTOM_GET_ARGVS_) } +#if GTEST_HAS_FILE_SYSTEM // Returns the current application's name, removing directory path if that // is present. FilePath GetCurrentExecutableName() { @@ -623,6 +637,7 @@ FilePath GetCurrentExecutableName() { return result.RemoveDirectoryName(); } +#endif // GTEST_HAS_FILE_SYSTEM // Functions for processing the gtest_output flag. @@ -637,6 +652,7 @@ std::string UnitTestOptions::GetOutputFormat() { static_cast(colon - gtest_output_flag)); } +#if GTEST_HAS_FILE_SYSTEM // Returns the name of the requested output file, or the default if none // was explicitly specified. std::string UnitTestOptions::GetAbsolutePathToOutputFile() { @@ -667,6 +683,7 @@ std::string UnitTestOptions::GetAbsolutePathToOutputFile() { GetOutputFormat().c_str())); return result.string(); } +#endif // GTEST_HAS_FILE_SYSTEM // Returns true if and only if the wildcard pattern matches the string. Each // pattern consists of regular characters, single-character wildcards (?), and @@ -1008,14 +1025,14 @@ void DefaultPerThreadTestPartResultReporter::ReportTestPartResult( TestPartResultReporterInterface* UnitTestImpl::GetGlobalTestPartResultReporter() { internal::MutexLock lock(&global_test_part_result_reporter_mutex_); - return global_test_part_result_repoter_; + return global_test_part_result_reporter_; } // Sets the global test part result reporter. void UnitTestImpl::SetGlobalTestPartResultReporter( TestPartResultReporterInterface* reporter) { internal::MutexLock lock(&global_test_part_result_reporter_mutex_); - global_test_part_result_repoter_ = reporter; + global_test_part_result_reporter_ = reporter; } // Returns the test part result reporter for the current thread. @@ -1113,17 +1130,24 @@ std::string UnitTestImpl::CurrentOsStackTraceExceptTop(int skip_count) { // A helper class for measuring elapsed times. class Timer { public: - Timer() : start_(std::chrono::steady_clock::now()) {} + Timer() : start_(clock::now()) {} // Return time elapsed in milliseconds since the timer was created. TimeInMillis Elapsed() { return std::chrono::duration_cast( - std::chrono::steady_clock::now() - start_) + clock::now() - start_) .count(); } private: - std::chrono::steady_clock::time_point start_; + // Fall back to the system_clock when building with newlib on a system + // without a monotonic clock. +#if defined(_NEWLIB_VERSION) && !defined(CLOCK_MONOTONIC) + using clock = std::chrono::system_clock; +#else + using clock = std::chrono::steady_clock; +#endif + clock::time_point start_; }; // Returns a timestamp as milliseconds since the epoch. Note this time may jump @@ -2434,12 +2458,10 @@ void Test::TearDown() {} void Test::RecordProperty(const std::string& key, const std::string& value) { UnitTest::GetInstance()->RecordProperty(key, value); } - -// Allows user supplied key value pairs to be recorded for later output. -void Test::RecordProperty(const std::string& key, int value) { - Message value_message; - value_message << value; - RecordProperty(key, value_message.GetString().c_str()); +// We do not define a customary serialization except for integers, +// but other values could be logged in this way. +void Test::RecordProperty(const std::string& key, int64_t value) { + RecordProperty(key, (Message() << value).GetString()); } namespace internal { @@ -2711,7 +2733,8 @@ TestInfo::TestInfo(const std::string& a_test_suite_name, internal::TypeId fixture_class_id, internal::TestFactoryBase* factory) : test_suite_name_(a_test_suite_name), - name_(a_name), + // begin()/end() is MSVC 17.3.3 ASAN crash workaround (GitHub issue #3997) + name_(a_name.begin(), a_name.end()), type_param_(a_type_param ? new std::string(a_type_param) : nullptr), value_param_(a_value_param ? new std::string(a_value_param) : nullptr), location_(a_code_location), @@ -2775,37 +2798,6 @@ void ReportInvalidTestSuiteType(const char* test_suite_name, code_location.line) << " " << errors.GetString(); } -} // namespace internal - -namespace { - -// A predicate that checks the test name of a TestInfo against a known -// value. -// -// This is used for implementation of the TestSuite class only. We put -// it in the anonymous namespace to prevent polluting the outer -// namespace. -// -// TestNameIs is copyable. -class TestNameIs { - public: - // Constructor. - // - // TestNameIs has NO default constructor. - explicit TestNameIs(const char* name) : name_(name) {} - - // Returns true if and only if the test name of test_info matches name_. - bool operator()(const TestInfo* test_info) const { - return test_info && test_info->name() == name_; - } - - private: - std::string name_; -}; - -} // namespace - -namespace internal { // This method expands all parameterized tests registered with macros TEST_P // and INSTANTIATE_TEST_SUITE_P into regular tests and registers those. @@ -3244,17 +3236,15 @@ bool ShouldUseColor(bool stdout_is_tty) { // On non-Windows platforms, we rely on the TERM variable. const char* const term = posix::GetEnv("TERM"); const bool term_supports_color = - String::CStringEquals(term, "xterm") || - String::CStringEquals(term, "xterm-color") || - String::CStringEquals(term, "xterm-256color") || - String::CStringEquals(term, "screen") || - String::CStringEquals(term, "screen-256color") || - String::CStringEquals(term, "tmux") || - String::CStringEquals(term, "tmux-256color") || - String::CStringEquals(term, "rxvt-unicode") || - String::CStringEquals(term, "rxvt-unicode-256color") || - String::CStringEquals(term, "linux") || - String::CStringEquals(term, "cygwin"); + term != nullptr && (String::CStringEquals(term, "xterm") || + String::CStringEquals(term, "xterm-color") || + String::CStringEquals(term, "xterm-kitty") || + String::CStringEquals(term, "screen") || + String::CStringEquals(term, "tmux") || + String::CStringEquals(term, "rxvt-unicode") || + String::CStringEquals(term, "linux") || + String::CStringEquals(term, "cygwin") || + String::EndsWithCaseInsensitive(term, "-256color")); return stdout_is_tty && term_supports_color; #endif // GTEST_OS_WINDOWS } @@ -3279,7 +3269,12 @@ static void ColoredPrintf(GTestColor color, const char* fmt, ...) { va_start(args, fmt); static const bool in_color_mode = +#if GTEST_HAS_FILE_SYSTEM ShouldUseColor(posix::IsATTY(posix::FileNo(stdout)) != 0); +#else + false; +#endif // GTEST_HAS_FILE_SYSTEM + const bool use_color = in_color_mode && (color != GTestColor::kDefault); if (!use_color) { @@ -3884,6 +3879,7 @@ void TestEventRepeater::OnTestIterationEnd(const UnitTest& unit_test, // End TestEventRepeater +#if GTEST_HAS_FILE_SYSTEM // This class generates an XML output file. class XmlUnitTestResultPrinter : public EmptyTestEventListener { public: @@ -4431,7 +4427,9 @@ void XmlUnitTestResultPrinter::OutputXmlTestProperties( } // End XmlUnitTestResultPrinter +#endif // GTEST_HAS_FILE_SYSTEM +#if GTEST_HAS_FILE_SYSTEM // This class generates an JSON output file. class JsonUnitTestResultPrinter : public EmptyTestEventListener { public: @@ -4821,6 +4819,9 @@ void JsonUnitTestResultPrinter::PrintJsonUnitTest(std::ostream* stream, // If there was a test failure outside of one of the test suites (like in a // test environment) include that in the output. if (unit_test.ad_hoc_test_result().Failed()) { + if (comma) { + *stream << ",\n"; + } OutputJsonTestSuiteForTestResult(stream, unit_test.ad_hoc_test_result()); } @@ -4869,6 +4870,7 @@ std::string JsonUnitTestResultPrinter::TestPropertiesAsJson( } // End JsonUnitTestResultPrinter +#endif // GTEST_HAS_FILE_SYSTEM #if GTEST_CAN_STREAM_RESULTS_ @@ -4886,7 +4888,8 @@ std::string StreamingListener::UrlEncode(const char* str) { case '=': case '&': case '\n': - result.append("%" + String::FormatByte(static_cast(ch))); + result.push_back('%'); + result.append(String::FormatByte(static_cast(ch))); break; default: result.push_back(ch); @@ -5007,6 +5010,7 @@ void OsStackTraceGetter::UponLeavingGTest() GTEST_LOCK_EXCLUDED_(mutex_) { #endif // GTEST_HAS_ABSL } +#if GTEST_HAS_DEATH_TEST // A helper class that creates the premature-exit file in its // constructor and deletes the file in its destructor. class ScopedPrematureExitFile { @@ -5026,7 +5030,7 @@ class ScopedPrematureExitFile { } ~ScopedPrematureExitFile() { -#if !defined GTEST_OS_ESP8266 +#if !GTEST_OS_ESP8266 if (!premature_exit_filepath_.empty()) { int retval = remove(premature_exit_filepath_.c_str()); if (retval) { @@ -5044,6 +5048,7 @@ class ScopedPrematureExitFile { ScopedPrematureExitFile(const ScopedPrematureExitFile&) = delete; ScopedPrematureExitFile& operator=(const ScopedPrematureExitFile&) = delete; }; +#endif // GTEST_HAS_DEATH_TEST } // namespace internal @@ -5331,6 +5336,10 @@ void UnitTest::AddTestPartResult(TestPartResult::Type result_type, (defined(__x86_64__) || defined(__i386__))) // with clang/gcc we can achieve the same effect on x86 by invoking int3 asm("int3"); +#elif GTEST_HAS_BUILTIN(__builtin_trap) + __builtin_trap(); +#elif defined(SIGTRAP) + raise(SIGTRAP); #else // Dereference nullptr through a volatile pointer to prevent the compiler // from removing. We use this rather than abort() or __builtin_trap() for @@ -5365,6 +5374,7 @@ void UnitTest::RecordProperty(const std::string& key, // We don't protect this under mutex_, as we only support calling it // from the main thread. int UnitTest::Run() { +#if GTEST_HAS_DEATH_TEST const bool in_death_test_child_process = GTEST_FLAG_GET(internal_run_death_test).length() > 0; @@ -5393,6 +5403,7 @@ int UnitTest::Run() { in_death_test_child_process ? nullptr : internal::posix::GetEnv("TEST_PREMATURE_EXIT_FILE")); +#endif // GTEST_HAS_DEATH_TEST // Captures the value of GTEST_FLAG(catch_exceptions). This value will be // used for the duration of the program. @@ -5448,11 +5459,13 @@ int UnitTest::Run() { : 1; } +#if GTEST_HAS_FILE_SYSTEM // Returns the working directory when the first TEST() or TEST_F() was // executed. const char* UnitTest::original_working_dir() const { return impl_->original_working_dir_.c_str(); } +#endif // GTEST_HAS_FILE_SYSTEM // Returns the TestSuite object for the test that's currently running, // or NULL if no test is running. @@ -5516,7 +5529,7 @@ UnitTestImpl::UnitTestImpl(UnitTest* parent) GTEST_DISABLE_MSC_WARNINGS_PUSH_(4355 /* using this in initializer */) default_global_test_part_result_reporter_(this), default_per_thread_test_part_result_reporter_(this), - GTEST_DISABLE_MSC_WARNINGS_POP_() global_test_part_result_repoter_( + GTEST_DISABLE_MSC_WARNINGS_POP_() global_test_part_result_reporter_( &default_global_test_part_result_reporter_), per_thread_test_part_result_reporter_( &default_per_thread_test_part_result_reporter_), @@ -5585,6 +5598,7 @@ void UnitTestImpl::SuppressTestEventsIfInSubprocess() { // UnitTestOptions. Must not be called before InitGoogleTest. void UnitTestImpl::ConfigureXmlOutput() { const std::string& output_format = UnitTestOptions::GetOutputFormat(); +#if GTEST_HAS_FILE_SYSTEM if (output_format == "xml") { listeners()->SetDefaultXmlGenerator(new XmlUnitTestResultPrinter( UnitTestOptions::GetAbsolutePathToOutputFile().c_str())); @@ -5595,6 +5609,10 @@ void UnitTestImpl::ConfigureXmlOutput() { GTEST_LOG_(WARNING) << "WARNING: unrecognized output format \"" << output_format << "\" ignored."; } +#else + GTEST_LOG_(ERROR) << "ERROR: alternative output formats require " + << "GTEST_HAS_FILE_SYSTEM to be enabled"; +#endif // GTEST_HAS_FILE_SYSTEM } #if GTEST_CAN_STREAM_RESULTS_ @@ -5757,10 +5775,12 @@ bool UnitTestImpl::RunAllTests() { // user didn't call InitGoogleTest. PostFlagParsingInit(); +#if GTEST_HAS_FILE_SYSTEM // Even if sharding is not on, test runners may want to use the // GTEST_SHARD_STATUS_FILE to query whether the test supports the sharding // protocol. internal::WriteToShardStatusFileIfNeeded(); +#endif // GTEST_HAS_FILE_SYSTEM // True if and only if we are in a subprocess for running a thread-safe-style // death test. @@ -5940,6 +5960,7 @@ bool UnitTestImpl::RunAllTests() { return !failed; } +#if GTEST_HAS_FILE_SYSTEM // Reads the GTEST_SHARD_STATUS_FILE environment variable, and creates the file // if the variable is present. If a file already exists at this location, this // function will write over it. If the variable is present, but the file cannot @@ -5959,6 +5980,7 @@ void WriteToShardStatusFileIfNeeded() { fclose(file); } } +#endif // GTEST_HAS_FILE_SYSTEM // Checks whether sharding is enabled by examining the relevant // environment variable values. If the variables are present, @@ -6037,7 +6059,7 @@ bool ShouldRunTestOnShard(int total_shards, int shard_index, int test_id) { // each TestSuite and TestInfo object. // If shard_tests == true, further filters tests based on sharding // variables in the environment - see -// https://github.com/google/googletest/blob/master/googletest/docs/advanced.md +// https://github.com/google/googletest/blob/main/docs/advanced.md // . Returns the number of tests that should run. int UnitTestImpl::FilterTests(ReactionToSharding shard_tests) { const int32_t total_shards = shard_tests == HONOR_SHARDING_PROTOCOL @@ -6150,6 +6172,7 @@ void UnitTestImpl::ListTestsMatchingFilter() { } } fflush(stdout); + #if GTEST_HAS_FILE_SYSTEM const std::string& output_format = UnitTestOptions::GetOutputFormat(); if (output_format == "xml" || output_format == "json") { FILE* fileout = OpenFileForWriting( @@ -6167,6 +6190,7 @@ void UnitTestImpl::ListTestsMatchingFilter() { fprintf(fileout, "%s", StringStreamToString(&stream).c_str()); fclose(fileout); } +#endif // GTEST_HAS_FILE_SYSTEM } // Sets the OS stack trace getter. @@ -6245,7 +6269,7 @@ void UnitTestImpl::UnshuffleTests() { // GetCurrentOsStackTraceExceptTop(..., 1), Foo() will be included in // the trace but Bar() and GetCurrentOsStackTraceExceptTop() won't. GTEST_NO_INLINE_ GTEST_NO_TAIL_CALL_ std::string -GetCurrentOsStackTraceExceptTop(UnitTest* /*unit_test*/, int skip_count) { +GetCurrentOsStackTraceExceptTop(int skip_count) { // We pass skip_count + 1 to skip this wrapper function in addition // to what the user really wants to skip. return GetUnitTestImpl()->CurrentOsStackTraceExceptTop(skip_count + 1); @@ -6555,7 +6579,7 @@ static bool ParseGoogleTestFlag(const char* const arg) { return false; } -#if GTEST_USE_OWN_FLAGFILE_FLAG_ +#if GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM static void LoadFlagsFromFile(const std::string& path) { FILE* flagfile = posix::FOpen(path.c_str(), "r"); if (!flagfile) { @@ -6571,7 +6595,7 @@ static void LoadFlagsFromFile(const std::string& path) { if (!ParseGoogleTestFlag(lines[i].c_str())) g_help_flag = true; } } -#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM // Parses the command line for Google Test flags, without initializing // other parts of Google Test. The type parameter CharType can be @@ -6588,12 +6612,12 @@ void ParseGoogleTestFlagsOnlyImpl(int* argc, CharType** argv) { bool remove_flag = false; if (ParseGoogleTestFlag(arg)) { remove_flag = true; -#if GTEST_USE_OWN_FLAGFILE_FLAG_ +#if GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM } else if (ParseFlag(arg, "flagfile", &flagfile_value)) { GTEST_FLAG_SET(flagfile, flagfile_value); LoadFlagsFromFile(flagfile_value); remove_flag = true; -#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ +#endif // GTEST_USE_OWN_FLAGFILE_FLAG_ && GTEST_HAS_FILE_SYSTEM } else if (arg_string == "--help" || HasGoogleTestFlagPrefix(arg)) { // Both help flag and unrecognized Google Test flags (excluding // internal ones) trigger help display. @@ -6741,12 +6765,13 @@ void InitGoogleTest() { #endif // defined(GTEST_CUSTOM_INIT_GOOGLE_TEST_FUNCTION_) } -#if !defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_) -// Return value of first environment variable that is set and contains -// a non-empty string. If there are none, return the "fallback" string. -// Since we like the temporary directory to have a directory separator suffix, -// add it if not provided in the environment variable value. -static std::string GetTempDirFromEnv( +#if !defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_) || \ + !defined(GTEST_CUSTOM_SRCDIR_FUNCTION_) +// Returns the value of the first environment variable that is set and contains +// a non-empty string. If there are none, returns the "fallback" string. Adds +// the director-separator character as a suffix if not provided in the +// environment variable value. +static std::string GetDirFromEnv( std::initializer_list environment_variables, const char* fallback, char separator) { for (const char* variable_name : environment_variables) { @@ -6766,11 +6791,35 @@ std::string TempDir() { #if defined(GTEST_CUSTOM_TEMPDIR_FUNCTION_) return GTEST_CUSTOM_TEMPDIR_FUNCTION_(); #elif GTEST_OS_WINDOWS || GTEST_OS_WINDOWS_MOBILE - return GetTempDirFromEnv({"TEST_TMPDIR", "TEMP"}, "\\temp\\", '\\'); + return GetDirFromEnv({"TEST_TMPDIR", "TEMP"}, "\\temp\\", '\\'); +#elif GTEST_OS_LINUX_ANDROID + return GetDirFromEnv({"TEST_TMPDIR", "TMPDIR"}, "/data/local/tmp/", '/'); +#else + return GetDirFromEnv({"TEST_TMPDIR", "TMPDIR"}, "/tmp/", '/'); +#endif +} + +#if !defined(GTEST_CUSTOM_SRCDIR_FUNCTION_) +// Returns the directory path (including terminating separator) of the current +// executable as derived from argv[0]. +static std::string GetCurrentExecutableDirectory() { + internal::FilePath argv_0(internal::GetArgvs()[0]); + return argv_0.RemoveFileName().string(); +} +#endif + +std::string SrcDir() { +#if defined(GTEST_CUSTOM_SRCDIR_FUNCTION_) + return GTEST_CUSTOM_SRCDIR_FUNCTION_(); +#elif GTEST_OS_WINDOWS || GTEST_OS_WINDOWS_MOBILE + return GetDirFromEnv({"TEST_SRCDIR"}, GetCurrentExecutableDirectory().c_str(), + '\\'); #elif GTEST_OS_LINUX_ANDROID - return GetTempDirFromEnv({"TEST_TMPDIR", "TMPDIR"}, "/data/local/tmp/", '/'); + return GetDirFromEnv({"TEST_SRCDIR"}, GetCurrentExecutableDirectory().c_str(), + '/'); #else - return GetTempDirFromEnv({"TEST_TMPDIR", "TMPDIR"}, "/tmp/", '/'); + return GetDirFromEnv({"TEST_SRCDIR"}, GetCurrentExecutableDirectory().c_str(), + '/'); #endif } diff --git a/googletest/src/gtest_main.cc b/googletest/src/gtest_main.cc index 44976375c99..5abaa29fa11 100644 --- a/googletest/src/gtest_main.cc +++ b/googletest/src/gtest_main.cc @@ -32,9 +32,12 @@ #include "gtest/gtest.h" #if GTEST_OS_ESP8266 || GTEST_OS_ESP32 +// Arduino-like platforms: program entry points are setup/loop instead of main. + #if GTEST_OS_ESP8266 extern "C" { #endif + void setup() { testing::InitGoogleTest(); } void loop() { RUN_ALL_TESTS(); } @@ -43,7 +46,16 @@ void loop() { RUN_ALL_TESTS(); } } #endif +#elif GTEST_OS_QURT +// QuRT: program entry point is main, but argc/argv are unusable. + +GTEST_API_ int main() { + printf("Running main() from %s\n", __FILE__); + testing::InitGoogleTest(); + return RUN_ALL_TESTS(); +} #else +// Normal platforms: program entry point is main, argc/argv are initialized. GTEST_API_ int main(int argc, char **argv) { printf("Running main() from %s\n", __FILE__);