mirror of
https://github.com/nodejs/node.git
synced 2026-10-28 18:25:13 +08:00
deps: update googletest to 8eff9e336692fc95961e096564f1044c600b881d
PR-URL: https://github.com/nodejs/node/pull/66009 Reviewed-By: Filip Skokan <panva.ip@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
This commit is contained in:
1 parent
3a69cc1bf4
commit
e8edeffe2d
5 files changed
+42
-306
No files matched your search
+4
-48
@@ -105,54 +105,10 @@ GTEST_API_ bool InDeathTestChild();
|
||||
//
|
||||
// On the regular expressions used in death tests:
|
||||
//
|
||||
// On POSIX-compliant systems (*nix), we use the <regex.h> library,
|
||||
// which uses the POSIX extended regex syntax.
|
||||
//
|
||||
// On other platforms (e.g. Windows or Mac), we only support a simple regex
|
||||
// syntax implemented as part of Google Test. This limited
|
||||
// implementation should be enough most of the time when writing
|
||||
// death tests; though it lacks many features you can find in PCRE
|
||||
// or POSIX extended regex syntax. For example, we don't support
|
||||
// union ("x|y"), grouping ("(xy)"), brackets ("[xy]"), and
|
||||
// repetition count ("x{5,7}"), among others.
|
||||
//
|
||||
// Below is the syntax that we do support. We chose it to be a
|
||||
// subset of both PCRE and POSIX extended regex, so it's easy to
|
||||
// learn wherever you come from. In the following: 'A' denotes a
|
||||
// literal character, period (.), or a single \\ escape sequence;
|
||||
// 'x' and 'y' denote regular expressions; 'm' and 'n' are for
|
||||
// natural numbers.
|
||||
//
|
||||
// c matches any literal character c
|
||||
// \\d matches any decimal digit
|
||||
// \\D matches any character that's not a decimal digit
|
||||
// \\f matches \f
|
||||
// \\n matches \n
|
||||
// \\r matches \r
|
||||
// \\s matches any ASCII whitespace, including \n
|
||||
// \\S matches any character that's not a whitespace
|
||||
// \\t matches \t
|
||||
// \\v matches \v
|
||||
// \\w matches any letter, _, or decimal digit
|
||||
// \\W matches any character that \\w doesn't match
|
||||
// \\c matches any literal character c, which must be a punctuation
|
||||
// . matches any single character except \n
|
||||
// A? matches 0 or 1 occurrences of A
|
||||
// A* matches 0 or many occurrences of A
|
||||
// A+ matches 1 or many occurrences of A
|
||||
// ^ matches the beginning of a string (not that of each line)
|
||||
// $ matches the end of a string (not that of each line)
|
||||
// xy matches x followed by y
|
||||
//
|
||||
// If you accidentally use PCRE or POSIX extended regex features
|
||||
// not implemented by us, you will get a run-time failure. In that
|
||||
// case, please try to rewrite your regular expression within the
|
||||
// above syntax.
|
||||
//
|
||||
// This implementation is *not* meant to be as highly tuned or robust
|
||||
// as a compiled regex library, but should perform well enough for a
|
||||
// death test, which already incurs significant overhead by launching
|
||||
// a child process.
|
||||
// Depending on the platform, this may use RE2, the POSIX <regex.h> library,
|
||||
// the C++11 standard library's <regex> engine with ECMAScript syntax, or
|
||||
// another similar engine. Regular expressions should be simple and portable
|
||||
// enough to work across the engines of interest.
|
||||
//
|
||||
// Known caveats:
|
||||
//
|
||||
|
||||
+17
-15
@@ -176,7 +176,7 @@
|
||||
// GTEST_USES_POSIX_RE - enhanced POSIX regex is used. Do not confuse with
|
||||
// GTEST_HAS_POSIX_RE (see above) which users can
|
||||
// define themselves.
|
||||
// GTEST_USES_SIMPLE_RE - our own simple regex is used;
|
||||
// GTEST_USES_STD_RE - std::regex from the C++ standard library is used;
|
||||
// the above RE\b(s) are mutually exclusive.
|
||||
// GTEST_HAS_ABSL - Google Test is compiled with Abseil.
|
||||
|
||||
@@ -438,8 +438,9 @@ typedef struct _RTL_CRITICAL_SECTION GTEST_CRITICAL_SECTION;
|
||||
#include <regex.h> // NOLINT
|
||||
#define GTEST_USES_POSIX_RE 1
|
||||
#else
|
||||
// Use our own simple regex implementation.
|
||||
#define GTEST_USES_SIMPLE_RE 1
|
||||
// Use std::regex from the C++ standard library.
|
||||
#include <regex> // NOLINT
|
||||
#define GTEST_USES_STD_RE 1
|
||||
#endif
|
||||
|
||||
#ifndef GTEST_HAS_EXCEPTIONS
|
||||
@@ -992,12 +993,11 @@ class GTEST_API_ [[nodiscard]] RE {
|
||||
RE2 regex_;
|
||||
};
|
||||
|
||||
#elif defined(GTEST_USES_POSIX_RE) || defined(GTEST_USES_SIMPLE_RE)
|
||||
#elif defined(GTEST_USES_POSIX_RE) || defined(GTEST_USES_STD_RE)
|
||||
GTEST_DISABLE_MSC_WARNINGS_PUSH_(4251 \
|
||||
/* class A needs to have dll-interface to be used by clients of class B */)
|
||||
|
||||
// A simple C++ wrapper for <regex.h>. It uses the POSIX Extended
|
||||
// Regular Expression syntax.
|
||||
// A simple C++ wrapper for <regex.h> or <regex>.
|
||||
class GTEST_API_ [[nodiscard]] RE {
|
||||
public:
|
||||
// A copy constructor is required by the Standard to initialize object
|
||||
@@ -1037,9 +1037,9 @@ class GTEST_API_ [[nodiscard]] RE {
|
||||
regex_t full_regex_; // For FullMatch().
|
||||
regex_t partial_regex_; // For PartialMatch().
|
||||
|
||||
#else // GTEST_USES_SIMPLE_RE
|
||||
#else // GTEST_USES_STD_RE
|
||||
|
||||
std::string full_pattern_; // For FullMatch();
|
||||
std::regex regex_;
|
||||
|
||||
#endif
|
||||
};
|
||||
@@ -1755,14 +1755,16 @@ class [[nodiscard]] MutexBase {
|
||||
#define GTEST_DECLARE_STATIC_MUTEX_(mutex) \
|
||||
extern ::testing::internal::MutexBase mutex
|
||||
|
||||
#if defined(PTHREAD_NULL)
|
||||
#define GTEST_INTERNAL_PTHREAD_NULL PTHREAD_NULL
|
||||
#else
|
||||
#define GTEST_INTERNAL_PTHREAD_NULL (pthread_t{})
|
||||
#endif
|
||||
|
||||
// Defines and statically (i.e. at link time) initializes a static mutex.
|
||||
// The initialization list here does not explicitly initialize each field,
|
||||
// instead relying on default initialization for the unspecified fields. In
|
||||
// particular, the owner_ field (a pthread_t) is not explicitly initialized.
|
||||
// This allows initialization to work whether pthread_t is a scalar or struct.
|
||||
// The flag -Wmissing-field-initializers must not be specified for this to work.
|
||||
#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
|
||||
::testing::internal::MutexBase mutex = {PTHREAD_MUTEX_INITIALIZER, false, 0}
|
||||
#define GTEST_DEFINE_STATIC_MUTEX_(mutex) \
|
||||
::testing::internal::MutexBase mutex = {PTHREAD_MUTEX_INITIALIZER, false, \
|
||||
GTEST_INTERNAL_PTHREAD_NULL}
|
||||
|
||||
// The Mutex class can only be used for mutexes created at runtime. It
|
||||
// shares its API with MutexBase otherwise.
|
||||
|
||||
-19
@@ -980,26 +980,7 @@ inline UnitTestImpl* GetUnitTestImpl() {
|
||||
return UnitTest::GetInstance()->impl();
|
||||
}
|
||||
|
||||
#ifdef GTEST_USES_SIMPLE_RE
|
||||
|
||||
// Internal helper functions for implementing the simple regular
|
||||
// expression matcher.
|
||||
GTEST_API_ bool IsInSet(char ch, const char* str);
|
||||
GTEST_API_ bool IsAsciiDigit(char ch);
|
||||
GTEST_API_ bool IsAsciiPunct(char ch);
|
||||
GTEST_API_ bool IsRepeat(char ch);
|
||||
GTEST_API_ bool IsAsciiWhiteSpace(char ch);
|
||||
GTEST_API_ bool IsAsciiWordChar(char ch);
|
||||
GTEST_API_ bool IsValidEscape(char ch);
|
||||
GTEST_API_ bool AtomMatchesChar(bool escaped, char pattern, char ch);
|
||||
GTEST_API_ bool ValidateRegex(const char* regex);
|
||||
GTEST_API_ bool MatchRegexAtHead(const char* regex, const char* str);
|
||||
GTEST_API_ bool MatchRepetitionAndRegexAtHead(bool escaped, char ch,
|
||||
char repeat, const char* regex,
|
||||
const char* str);
|
||||
GTEST_API_ bool MatchRegexAnywhere(const char* regex, const char* str);
|
||||
|
||||
#endif // GTEST_USES_SIMPLE_RE
|
||||
|
||||
// Parses the command line for Google Test flags, without initializing
|
||||
// other parts of Google Test.
|
||||
|
||||
Vendored
+20
-223
@@ -766,249 +766,46 @@ void RE::Init(const char* regex) {
|
||||
delete[] full_pattern;
|
||||
}
|
||||
|
||||
#elif defined(GTEST_USES_SIMPLE_RE)
|
||||
|
||||
// Returns true if and only if ch appears anywhere in str (excluding the
|
||||
// terminating '\0' character).
|
||||
bool IsInSet(char ch, const char* str) {
|
||||
return ch != '\0' && strchr(str, ch) != nullptr;
|
||||
}
|
||||
|
||||
// Returns true if and only if ch belongs to the given classification.
|
||||
// Unlike similar functions in <ctype.h>, these aren't affected by the
|
||||
// current locale.
|
||||
bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; }
|
||||
bool IsAsciiPunct(char ch) {
|
||||
return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~");
|
||||
}
|
||||
bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); }
|
||||
bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); }
|
||||
bool IsAsciiWordChar(char ch) {
|
||||
return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||
|
||||
('0' <= ch && ch <= '9') || ch == '_';
|
||||
}
|
||||
|
||||
// Returns true if and only if "\\c" is a supported escape sequence.
|
||||
bool IsValidEscape(char c) {
|
||||
return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW"));
|
||||
}
|
||||
|
||||
// Returns true if and only if the given atom (specified by escaped and
|
||||
// pattern) matches ch. The result is undefined if the atom is invalid.
|
||||
bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
|
||||
if (escaped) { // "\\p" where p is pattern_char.
|
||||
switch (pattern_char) {
|
||||
case 'd':
|
||||
return IsAsciiDigit(ch);
|
||||
case 'D':
|
||||
return !IsAsciiDigit(ch);
|
||||
case 'f':
|
||||
return ch == '\f';
|
||||
case 'n':
|
||||
return ch == '\n';
|
||||
case 'r':
|
||||
return ch == '\r';
|
||||
case 's':
|
||||
return IsAsciiWhiteSpace(ch);
|
||||
case 'S':
|
||||
return !IsAsciiWhiteSpace(ch);
|
||||
case 't':
|
||||
return ch == '\t';
|
||||
case 'v':
|
||||
return ch == '\v';
|
||||
case 'w':
|
||||
return IsAsciiWordChar(ch);
|
||||
case 'W':
|
||||
return !IsAsciiWordChar(ch);
|
||||
}
|
||||
return IsAsciiPunct(pattern_char) && pattern_char == ch;
|
||||
}
|
||||
|
||||
return (pattern_char == '.' && ch != '\n') || pattern_char == ch;
|
||||
}
|
||||
|
||||
// Helper function used by ValidateRegex() to format error messages.
|
||||
static std::string FormatRegexSyntaxError(const char* regex, int index) {
|
||||
return (Message() << "Syntax error at index " << index
|
||||
<< " in simple regular expression \"" << regex << "\": ")
|
||||
.GetString();
|
||||
}
|
||||
|
||||
// Generates non-fatal failures and returns false if regex is invalid;
|
||||
// otherwise returns true.
|
||||
bool ValidateRegex(const char* regex) {
|
||||
if (regex == nullptr) {
|
||||
ADD_FAILURE() << "NULL is not a valid simple regular expression.";
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_valid = true;
|
||||
|
||||
// True if and only if ?, *, or + can follow the previous atom.
|
||||
bool prev_repeatable = false;
|
||||
for (int i = 0; regex[i]; i++) {
|
||||
if (regex[i] == '\\') { // An escape sequence
|
||||
i++;
|
||||
if (regex[i] == '\0') {
|
||||
ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
|
||||
<< "'\\' cannot appear at the end.";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!IsValidEscape(regex[i])) {
|
||||
ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
|
||||
<< "invalid escape sequence \"\\" << regex[i] << "\".";
|
||||
is_valid = false;
|
||||
}
|
||||
prev_repeatable = true;
|
||||
} else { // Not an escape sequence.
|
||||
const char ch = regex[i];
|
||||
|
||||
if (ch == '^' && i > 0) {
|
||||
ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
|
||||
<< "'^' can only appear at the beginning.";
|
||||
is_valid = false;
|
||||
} else if (ch == '$' && regex[i + 1] != '\0') {
|
||||
ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
|
||||
<< "'$' can only appear at the end.";
|
||||
is_valid = false;
|
||||
} else if (IsInSet(ch, "()[]{}|")) {
|
||||
ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch
|
||||
<< "' is unsupported.";
|
||||
is_valid = false;
|
||||
} else if (IsRepeat(ch) && !prev_repeatable) {
|
||||
ADD_FAILURE() << FormatRegexSyntaxError(regex, i) << "'" << ch
|
||||
<< "' can only follow a repeatable token.";
|
||||
is_valid = false;
|
||||
}
|
||||
|
||||
prev_repeatable = !IsInSet(ch, "^$?*+");
|
||||
}
|
||||
}
|
||||
|
||||
return is_valid;
|
||||
}
|
||||
|
||||
// Matches a repeated regex atom followed by a valid simple regular
|
||||
// expression. The regex atom is defined as c if escaped is false,
|
||||
// or \c otherwise. repeat is the repetition meta character (?, *,
|
||||
// or +). The behavior is undefined if str contains too many
|
||||
// characters to be indexable by size_t, in which case the test will
|
||||
// probably time out anyway. We are fine with this limitation as
|
||||
// std::string has it too.
|
||||
bool MatchRepetitionAndRegexAtHead(bool escaped, char c, char repeat,
|
||||
const char* regex, const char* str) {
|
||||
const size_t min_count = (repeat == '+') ? 1 : 0;
|
||||
const size_t max_count = (repeat == '?') ? 1 : static_cast<size_t>(-1) - 1;
|
||||
// We cannot call numeric_limits::max() as it conflicts with the
|
||||
// max() macro on Windows.
|
||||
|
||||
for (size_t i = 0; i <= max_count; ++i) {
|
||||
// We know that the atom matches each of the first i characters in str.
|
||||
if (i >= min_count && MatchRegexAtHead(regex, str + i)) {
|
||||
// We have enough matches at the head, and the tail matches too.
|
||||
// Since we only care about *whether* the pattern matches str
|
||||
// (as opposed to *how* it matches), there is no need to find a
|
||||
// greedy match.
|
||||
return true;
|
||||
}
|
||||
if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i])) return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns true if and only if regex matches a prefix of str. regex must
|
||||
// be a valid simple regular expression and not start with "^", or the
|
||||
// result is undefined.
|
||||
bool MatchRegexAtHead(const char* regex, const char* str) {
|
||||
if (*regex == '\0') // An empty regex matches a prefix of anything.
|
||||
return true;
|
||||
|
||||
// "$" only matches the end of a string. Note that regex being
|
||||
// valid guarantees that there's nothing after "$" in it.
|
||||
if (*regex == '$') return *str == '\0';
|
||||
|
||||
// Is the first thing in regex an escape sequence?
|
||||
const bool escaped = *regex == '\\';
|
||||
if (escaped) ++regex;
|
||||
if (IsRepeat(regex[1])) {
|
||||
// MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so
|
||||
// here's an indirect recursion. It terminates as the regex gets
|
||||
// shorter in each recursion.
|
||||
return MatchRepetitionAndRegexAtHead(escaped, regex[0], regex[1], regex + 2,
|
||||
str);
|
||||
} else {
|
||||
// regex isn't empty, isn't "$", and doesn't start with a
|
||||
// repetition. We match the first atom of regex with the first
|
||||
// character of str and recurse.
|
||||
return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) &&
|
||||
MatchRegexAtHead(regex + 1, str + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Returns true if and only if regex matches any substring of str. regex must
|
||||
// be a valid simple regular expression, or the result is undefined.
|
||||
//
|
||||
// The algorithm is recursive, but the recursion depth doesn't exceed
|
||||
// the regex length, so we won't need to worry about running out of
|
||||
// stack space normally. In rare cases the time complexity can be
|
||||
// exponential with respect to the regex length + the string length,
|
||||
// but usually it's must faster (often close to linear).
|
||||
bool MatchRegexAnywhere(const char* regex, const char* str) {
|
||||
if (regex == nullptr || str == nullptr) return false;
|
||||
|
||||
if (*regex == '^') return MatchRegexAtHead(regex + 1, str);
|
||||
|
||||
// A successful match can be anywhere in str.
|
||||
do {
|
||||
if (MatchRegexAtHead(regex, str)) return true;
|
||||
} while (*str++ != '\0');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Implements the RE class.
|
||||
#elif defined(GTEST_USES_STD_RE)
|
||||
|
||||
RE::~RE() = default;
|
||||
|
||||
// Returns true if and only if regular expression re matches the entire str.
|
||||
bool RE::FullMatch(const char* str, const RE& re) {
|
||||
return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_.c_str(), str);
|
||||
if (!re.is_valid_ || str == nullptr) return false;
|
||||
return std::regex_match(str, re.regex_);
|
||||
}
|
||||
|
||||
// Returns true if and only if regular expression re matches a substring of
|
||||
// str (including str itself).
|
||||
bool RE::PartialMatch(const char* str, const RE& re) {
|
||||
return re.is_valid_ && MatchRegexAnywhere(re.pattern_.c_str(), str);
|
||||
if (!re.is_valid_ || str == nullptr) return false;
|
||||
return std::regex_search(str, re.regex_);
|
||||
}
|
||||
|
||||
// Initializes an RE from its string representation.
|
||||
void RE::Init(const char* regex) {
|
||||
full_pattern_.clear();
|
||||
pattern_.clear();
|
||||
pattern_ = regex == nullptr ? "" : regex;
|
||||
is_valid_ = false;
|
||||
|
||||
if (regex != nullptr) {
|
||||
pattern_ = regex;
|
||||
}
|
||||
|
||||
is_valid_ = ValidateRegex(regex);
|
||||
if (!is_valid_) {
|
||||
// No need to calculate the full pattern when the regex is invalid.
|
||||
if (regex == nullptr) {
|
||||
ADD_FAILURE() << "NULL is not a valid regular expression.";
|
||||
return;
|
||||
}
|
||||
|
||||
// Reserves enough bytes to hold the regular expression used for a
|
||||
// full match: we need space to prepend a '^' and append a '$'.
|
||||
full_pattern_.reserve(pattern_.size() + 2);
|
||||
|
||||
if (pattern_.empty() || pattern_.front() != '^') {
|
||||
full_pattern_.push_back('^'); // Makes sure full_pattern_ starts with '^'.
|
||||
#if GTEST_HAS_EXCEPTIONS
|
||||
try {
|
||||
regex_ = std::regex(regex, std::regex_constants::ECMAScript);
|
||||
} catch (const std::regex_error& e) {
|
||||
ADD_FAILURE() << "Regular expression \"" << regex
|
||||
<< "\" is not a valid regular expression: " << e.what();
|
||||
return;
|
||||
}
|
||||
#else
|
||||
regex_ = std::regex(regex, std::regex_constants::ECMAScript);
|
||||
#endif
|
||||
|
||||
full_pattern_.append(pattern_);
|
||||
|
||||
if (pattern_.empty() || pattern_.back() != '$') {
|
||||
full_pattern_.push_back('$'); // Makes sure full_pattern_ ends with '$'.
|
||||
}
|
||||
is_valid_ = true;
|
||||
}
|
||||
|
||||
#endif // GTEST_USES_POSIX_RE
|
||||
|
||||
Vendored
+1
-1
@@ -4648,7 +4648,7 @@ std::string JsonUnitTestResultPrinter::EscapeJson(const std::string& str) {
|
||||
m << "\\r";
|
||||
break;
|
||||
default:
|
||||
if (ch < ' ') {
|
||||
if (static_cast<unsigned char>(ch) < ' ' || ch == '\x7F') {
|
||||
m << "\\u00" << String::FormatByte(static_cast<unsigned char>(ch));
|
||||
} else {
|
||||
m << ch;
|
||||
|
||||
Reference in new issue
Block a user