From e33c2b24ca3e13df961ed369f7ed21e4cfcf9eec Mon Sep 17 00:00:00 2001 From: Derek Mauro Date: Tue, 26 Apr 2022 13:26:45 -0700 Subject: [PATCH] Use RE2 for the regex implementation when building with Bazel and using Abseil bazel build --define=absl=1 ... A dependency on RE2 is now required when building GoogleTest with Abseil. Using RE2 will provide a consistent cross-platform regex experience. Users will need to add the com_googlesource_code_re2, bazel_skylib, and platforms repository to their WORKSPACE files. See our WORKSPACE file in the root directory of this project for an example of how to add the dependencies. Please note that the com_googlesource_code_re2 dependency must use a commit from the `abseil` branch of the project: https://github.com/google/re2/tree/abseil PiperOrigin-RevId: 444650118 Change-Id: I45c55b26684c0c50d721a05b81c5f8a0c092400f --- BUILD.bazel | 1 + WORKSPACE | 28 +++++++- .../include/gtest/internal/gtest-port.h | 70 +++++++++++-------- googletest/test/googletest-port-test.cc | 10 +-- 4 files changed, 71 insertions(+), 38 deletions(-) diff --git a/BUILD.bazel b/BUILD.bazel index 192f18e6..ac62251e 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -143,6 +143,7 @@ cc_library( "@com_google_absl//absl/types:any", "@com_google_absl//absl/types:optional", "@com_google_absl//absl/types:variant", + "@com_googlesource_code_re2//:re2", ], "//conditions:default": [], }), diff --git a/WORKSPACE b/WORKSPACE index 842f1339..318b9088 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -4,9 +4,18 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") http_archive( name = "com_google_absl", - sha256 = "93451aaccbf6a9618df7182fdf9ecf281284d6418a0d66eff33ae0cf05eba417", - strip_prefix = "abseil-cpp-ec33f404bb16564a9aea3044cd8504d6885165b0", - urls = ["https://github.com/abseil/abseil-cpp/archive/ec33f404bb16564a9aea3044cd8504d6885165b0.zip"], # 2022-03-03T14:43:16Z + sha256 = "f88c0030547281e8283ff183db61564ff08d3322a8c2e2de4c40e38c03c69aea", + strip_prefix = "abseil-cpp-c27ab06897f330267bed99061ed3e523e2606bf1", + urls = ["https://github.com/abseil/abseil-cpp/archive/c27ab06897f330267bed99061ed3e523e2606bf1.zip"], # 2022-04-18T19:51:27Z +) + +# Note this must use a commit from the `abseil` branch of the RE2 project. +# https://github.com/google/re2/tree/abseil +http_archive( + name = "com_googlesource_code_re2", + sha256 = "906d0df8ff48f8d3a00a808827f009a840190f404559f649cb8e4d7143255ef9", + strip_prefix = "re2-a276a8c738735a0fe45a6ee590fe2df69bcf4502", + urls = ["https://github.com/google/re2/archive/a276a8c738735a0fe45a6ee590fe2df69bcf4502.zip"], # 2022-04-08 ) http_archive( @@ -15,3 +24,16 @@ http_archive( strip_prefix = "rules_python-ed6cc8f2c3692a6a7f013ff8bc185ba77eb9b4d2", urls = ["https://github.com/bazelbuild/rules_python/archive/ed6cc8f2c3692a6a7f013ff8bc185ba77eb9b4d2.zip"], # 2021-05-17T00:24:16Z ) + +http_archive( + name = "bazel_skylib", + urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.2.1/bazel-skylib-1.2.1.tar.gz"], + sha256 = "f7be3474d42aae265405a592bb7da8e171919d74c16f082a5457840f06054728", +) + +http_archive( + name = "platforms", + sha256 = "b601beaf841244de5c5a50d2b2eddd34839788000fa1be4260ce6603ca0d8eb7", + strip_prefix = "platforms-98939346da932eef0b54cf808622f5bb0928f00b", + urls = ["https://github.com/bazelbuild/platforms/archive/98939346da932eef0b54cf808622f5bb0928f00b.zip"], +) diff --git a/googletest/include/gtest/internal/gtest-port.h b/googletest/include/gtest/internal/gtest-port.h index 5d9220bd..b1cae906 100644 --- a/googletest/include/gtest/internal/gtest-port.h +++ b/googletest/include/gtest/internal/gtest-port.h @@ -170,6 +170,7 @@ // GTEST_HAS_TYPED_TEST - typed tests // GTEST_HAS_TYPED_TEST_P - type-parameterized tests // GTEST_IS_THREADSAFE - Google Test is thread-safe. +// GTEST_USES_RE2 - the RE2 regular expression library is used // GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with // GTEST_HAS_POSIX_RE (see above) which users can // define themselves. @@ -215,10 +216,13 @@ // - synchronization primitives. // // Regular expressions: -// RE - a simple regular expression class using the POSIX -// Extended Regular Expression syntax on UNIX-like platforms -// or a reduced regular exception syntax on other -// platforms, including Windows. +// RE - a simple regular expression class using +// 1) the RE2 syntax on all platforms when built with RE2 +// and Abseil as dependencies +// 2) the POSIX Extended Regular Expression syntax on +// UNIX-like platforms, +// 3) A reduced regular exception syntax on other platforms, +// including Windows. // Logging: // GTEST_LOG_() - logs messages at the specified severity level. // LogToStderr() - directs all log messages to stderr. @@ -385,32 +389,19 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION; #endif #endif -#if GTEST_USES_PCRE -// The appropriate headers have already been included. - +// Select the regular expression implementation. +#if GTEST_HAS_ABSL +// When using Abseil, RE2 is required. +#include "absl/strings/string_view.h" +#include "re2/re2.h" +#define GTEST_USES_RE2 1 #elif GTEST_HAS_POSIX_RE - -// On some platforms, needs someone to define size_t, and -// won't compile otherwise. We can #include it here as we already -// included , which is guaranteed to define size_t through -// . #include // NOLINT - #define GTEST_USES_POSIX_RE 1 - -#elif GTEST_OS_WINDOWS - -// is not available on Windows. Use our own simple regex -// implementation instead. -#define GTEST_USES_SIMPLE_RE 1 - #else - -// may not be available on this platform. Use our own -// simple regex implementation instead. +// Use our own simple regex implementation. #define GTEST_USES_SIMPLE_RE 1 - -#endif // GTEST_USES_PCRE +#endif #ifndef GTEST_HAS_EXCEPTIONS // The user didn't tell us whether exceptions are enabled, so we need @@ -868,8 +859,31 @@ GTEST_API_ bool IsTrue(bool condition); // Defines RE. -#if GTEST_USES_PCRE -// if used, PCRE is injected by custom/gtest-port.h +#if GTEST_USES_RE2 + +// This is almost `using RE = ::RE2`, except it is copy-constructible, and it +// needs to disambiguate the `std::string`, `absl::string_view`, and `const +// char*` constructors. +class GTEST_API_ RE { + public: + RE(absl::string_view regex) : regex_(regex) {} // NOLINT + RE(const char* regex) : RE(absl::string_view(regex)) {} // NOLINT + RE(const std::string& regex) : RE(absl::string_view(regex)) {} // NOLINT + RE(const RE& other) : RE(other.pattern()) {} + + const std::string& pattern() const { return regex_.pattern(); } + + static bool FullMatch(absl::string_view str, const RE& re) { + return RE2::FullMatch(str, re.regex_); + } + static bool PartialMatch(absl::string_view str, const RE& re) { + return RE2::PartialMatch(str, re.regex_); + } + + private: + RE2 regex_; +}; + #elif GTEST_USES_POSIX_RE || GTEST_USES_SIMPLE_RE // A simple C++ wrapper for . It uses the POSIX Extended @@ -920,7 +934,7 @@ class GTEST_API_ RE { #endif }; -#endif // GTEST_USES_PCRE +#endif // ::testing::internal::RE implementation // Formats a source file path and a line number as they would appear // in an error message from the compiler used to compile this code. diff --git a/googletest/test/googletest-port-test.cc b/googletest/test/googletest-port-test.cc index fb139c3c..c20dfa4c 100644 --- a/googletest/test/googletest-port-test.cc +++ b/googletest/test/googletest-port-test.cc @@ -387,17 +387,13 @@ TEST(GtestCheckDeathTest, LivesSilentlyOnSuccess) { // the platform. The test will produce compiler errors in case of failure. // For simplicity, we only cover the most important platforms here. TEST(RegexEngineSelectionTest, SelectsCorrectRegexEngine) { -#if !GTEST_USES_PCRE -#if GTEST_HAS_POSIX_RE - +#if GTEST_HAS_ABSL + EXPECT_TRUE(GTEST_USES_RE2); +#elif GTEST_HAS_POSIX_RE EXPECT_TRUE(GTEST_USES_POSIX_RE); - #else - EXPECT_TRUE(GTEST_USES_SIMPLE_RE); - #endif -#endif // !GTEST_USES_PCRE } #if GTEST_USES_POSIX_RE