Commit c946ae60 by zhanyong.wan

Implements a simple regex matcher (to be used by death tests on Windows).

parent a32fc79c
......@@ -86,6 +86,57 @@ GTEST_DECLARE_string_(death_test_style);
//
// ASSERT_EXIT(client.HangUpServer(), KilledBySIGHUP, "Hanging up!");
//
// 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), 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.
//
// Known caveats:
//
// A "threadsafe" style death test obtains the path to the test
......
......@@ -97,6 +97,9 @@
// GTEST_HAS_TYPED_TEST - defined iff typed tests are supported.
// GTEST_HAS_TYPED_TEST_P - defined iff type-parameterized tests are
// supported.
// GTEST_USES_POSIX_RE - defined iff enhanced POSIX regex is used.
// GTEST_USES_SIMPLE_RE - defined iff our own simple regex is used;
// the above two are mutually exclusive.
//
// Macros for basic C++ coding:
// GTEST_AMBIGUOUS_ELSE_BLOCKER_ - for disabling a gcc warning.
......@@ -187,6 +190,23 @@
#define GTEST_OS_SOLARIS
#endif // _MSC_VER
#if defined(GTEST_OS_LINUX)
// On some platforms, <regex.h> needs someone to define size_t, and
// won't compile otherwise. We can #include it here as we already
// included <stdlib.h>, which is guaranteed to define size_t through
// <stddef.h>.
#include <regex.h> // NOLINT
#define GTEST_USES_POSIX_RE 1
#else
// We are not on Linux, so <regex.h> may not be available. Use our
// own simple regex implementation instead.
#define GTEST_USES_SIMPLE_RE 1
#endif // GTEST_OS_LINUX
// Determines whether ::std::string and ::string are available.
#ifndef GTEST_HAS_STD_STRING
......@@ -352,11 +372,6 @@
// Determines whether to support death tests.
#if GTEST_HAS_STD_STRING && GTEST_HAS_CLONE
#define GTEST_HAS_DEATH_TEST
// On some platforms, <regex.h> needs someone to define size_t, and
// won't compile otherwise. We can #include it here as we already
// included <stdlib.h>, which is guaranteed to define size_t through
// <stddef.h>.
#include <regex.h>
#include <vector>
#include <fcntl.h>
#include <sys/mman.h>
......@@ -375,8 +390,8 @@
// Typed tests need <typeinfo> and variadic macros, which gcc and VC
// 8.0+ support.
#if defined(__GNUC__) || (_MSC_VER >= 1400)
#define GTEST_HAS_TYPED_TEST
#define GTEST_HAS_TYPED_TEST_P
#define GTEST_HAS_TYPED_TEST 1
#define GTEST_HAS_TYPED_TEST_P 1
#endif // defined(__GNUC__) || (_MSC_VER >= 1400)
// Determines whether to support Combine(). This only makes sense when
......@@ -490,8 +505,6 @@ class scoped_ptr {
GTEST_DISALLOW_COPY_AND_ASSIGN_(scoped_ptr);
};
#ifdef GTEST_HAS_DEATH_TEST
// Defines RE.
// A simple C++ wrapper for <regex.h>. It uses the POSIX Enxtended
......@@ -549,12 +562,16 @@ class RE {
// String type here, in order to simplify dependencies between the
// files.
const char* pattern_;
bool is_valid_;
#if GTEST_USES_POSIX_RE
regex_t full_regex_; // For FullMatch().
regex_t partial_regex_; // For PartialMatch().
bool is_valid_;
};
#else // GTEST_USES_SIMPLE_RE
const char* full_pattern_; // For FullMatch();
#endif
#endif // GTEST_HAS_DEATH_TEST
GTEST_DISALLOW_COPY_AND_ASSIGN_(RE);
};
// Defines logging utilities:
// GTEST_LOG_() - logs messages at the specified severity level.
......
......@@ -215,7 +215,6 @@ bool FilePath::DirectoryExists() const {
// root directory per disk drive.)
bool FilePath::IsRootDirectory() const {
#ifdef GTEST_OS_WINDOWS
const char* const name = pathname_.c_str();
// TODO(wan@google.com): on Windows a network share like
// \\server\share can be a root directory, although it cannot be the
// current directory. Handle this properly.
......
......@@ -1266,6 +1266,22 @@ inline UnitTestImpl* GetUnitTestImpl() {
return UnitTest::GetInstance()->impl();
}
// Internal helper functions for implementing the simple regular
// expression matcher.
bool IsInSet(char ch, const char* str);
bool IsDigit(char ch);
bool IsPunct(char ch);
bool IsRepeat(char ch);
bool IsWhiteSpace(char ch);
bool IsWordChar(char ch);
bool IsValidEscape(char ch);
bool AtomMatchesChar(bool escaped, char pattern, char ch);
bool ValidateRegex(const char* regex);
bool MatchRegexAtHead(const char* regex, const char* str);
bool MatchRepetitionAndRegexAtHead(
bool escaped, char ch, char repeat, const char* regex, const char* str);
bool MatchRegexAnywhere(const char* regex, const char* str);
// Parses the command line for Google Test flags, without initializing
// other parts of Google Test.
void ParseGoogleTestFlagsOnly(int* argc, char** argv);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment