summaryrefslogtreecommitdiff
path: root/src/gtest-port.cc
diff options
context:
space:
mode:
authorzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2009-03-06 01:20:15 +0000
committerzhanyong.wan <zhanyong.wan@861a406c-534a-0410-8894-cb66d6ee9925>2009-03-06 01:20:15 +0000
commitc85c0c20322a1f36113cf4d6282908e16ca32669 (patch)
treeca3c2306a370dda3388a4cbd34d22331debaec87 /src/gtest-port.cc
parent4cd62602913a032a7aec091d4c8055ff9af95e37 (diff)
downloadgtest-c85c0c20322a1f36113cf4d6282908e16ca32669.tar.gz
gtest-c85c0c20322a1f36113cf4d6282908e16ca32669.tar.bz2
gtest-c85c0c20322a1f36113cf4d6282908e16ca32669.tar.xz
Implements death tests on Windows (by Vlad Losev); enables POSIX regex on Mac and Cygwin; fixes build issue on some Linux versions due to PATH_MAX.
git-svn-id: http://googletest.googlecode.com/svn/trunk@198 861a406c-534a-0410-8894-cb66d6ee9925
Diffstat (limited to 'src/gtest-port.cc')
-rw-r--r--src/gtest-port.cc66
1 files changed, 56 insertions, 10 deletions
diff --git a/src/gtest-port.cc b/src/gtest-port.cc
index 59a2230..aacb5e7 100644
--- a/src/gtest-port.cc
+++ b/src/gtest-port.cc
@@ -35,9 +35,9 @@
#include <stdlib.h>
#include <stdio.h>
-#if GTEST_HAS_DEATH_TEST
-#include <regex.h>
-#endif // GTEST_HAS_DEATH_TEST
+#if !GTEST_OS_WINDOWS
+#include <unistd.h>
+#endif // GTEST_OS_WINDOWS
#if GTEST_USES_SIMPLE_RE
#include <string.h>
@@ -63,6 +63,13 @@
namespace testing {
namespace internal {
+#if GTEST_OS_WINDOWS
+// Microsoft does not provide a definition of STDERR_FILENO.
+const int kStdErrFileno = 2;
+#else
+const int kStdErrFileno = STDERR_FILENO;
+#endif // GTEST_OS_WINDOWS
+
#if GTEST_USES_POSIX_RE
// Implements RE. Currently only needed for death tests.
@@ -105,7 +112,13 @@ void RE::Init(const char* regex) {
// previous expression returns false. Otherwise partial_regex_ may
// not be properly initialized can may cause trouble when it's
// freed.
- is_valid_ = (regcomp(&partial_regex_, regex, REG_EXTENDED) == 0) && is_valid_;
+ //
+ // Some implementation of POSIX regex (e.g. on at least some
+ // versions of Cygwin) doesn't accept the empty string as a valid
+ // regex. We change it to an equivalent form "()" to be safe.
+ const char* const partial_regex = (*regex == '\0') ? "()" : regex;
+ is_valid_ = (regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0)
+ && is_valid_;
EXPECT_TRUE(is_valid_)
<< "Regular expression \"" << regex
<< "\" is not a valid POSIX Extended regular expression.";
@@ -379,11 +392,19 @@ void GTestLog(GTestLogSeverity severity, const char* file,
severity == GTEST_ERROR ? "[ ERROR ]" : "[ FATAL ]";
fprintf(stderr, "\n%s %s:%d: %s\n", marker, file, line, msg);
if (severity == GTEST_FATAL) {
+ fflush(NULL); // abort() is not guaranteed to flush open file streams.
abort();
}
}
-#if GTEST_HAS_DEATH_TEST
+#if GTEST_HAS_STD_STRING
+
+// Disable Microsoft deprecation warnings for POSIX functions called from
+// this class (creat, dup, dup2, and close)
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4996)
+#endif // _MSC_VER
// Defines the stderr capturer.
@@ -391,16 +412,26 @@ class CapturedStderr {
public:
// The ctor redirects stderr to a temporary file.
CapturedStderr() {
- uncaptured_fd_ = dup(STDERR_FILENO);
+ uncaptured_fd_ = dup(kStdErrFileno);
+
+#if GTEST_OS_WINDOWS
+ char temp_dir_path[MAX_PATH + 1] = { '\0' }; // NOLINT
+ char temp_file_path[MAX_PATH + 1] = { '\0' }; // NOLINT
+ ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);
+ ::GetTempFileNameA(temp_dir_path, "gtest_redir", 0, temp_file_path);
+ const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
+ filename_ = temp_file_path;
+#else
// There's no guarantee that a test has write access to the
// current directory, so we create the temporary file in the /tmp
// directory instead.
char name_template[] = "/tmp/captured_stderr.XXXXXX";
const int captured_fd = mkstemp(name_template);
filename_ = name_template;
+#endif // GTEST_OS_WINDOWS
fflush(NULL);
- dup2(captured_fd, STDERR_FILENO);
+ dup2(captured_fd, kStdErrFileno);
close(captured_fd);
}
@@ -412,7 +443,7 @@ class CapturedStderr {
void StopCapture() {
// Restores the original stream.
fflush(NULL);
- dup2(uncaptured_fd_, STDERR_FILENO);
+ dup2(uncaptured_fd_, kStdErrFileno);
close(uncaptured_fd_);
uncaptured_fd_ = -1;
}
@@ -427,6 +458,10 @@ class CapturedStderr {
::std::string filename_;
};
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif // _MSC_VER
+
static CapturedStderr* g_captured_stderr = NULL;
// Returns the size (in bytes) of a file.
@@ -436,8 +471,6 @@ static size_t GetFileSize(FILE * file) {
}
// Reads the entire content of a file as a string.
-// GTEST_HAS_DEATH_TEST implies that we have ::std::string, so we can
-// use it here.
static ::std::string ReadEntireFile(FILE * file) {
const size_t file_size = GetFileSize(file);
char* const buffer = new char[file_size];
@@ -473,9 +506,18 @@ void CaptureStderr() {
// use it here.
::std::string GetCapturedStderr() {
g_captured_stderr->StopCapture();
+
+// Disables Microsoft deprecation warning for fopen and fclose.
+#ifdef _MSC_VER
+#pragma warning(push)
+#pragma warning(disable: 4996)
+#endif // _MSC_VER
FILE* const file = fopen(g_captured_stderr->filename().c_str(), "r");
const ::std::string content = ReadEntireFile(file);
fclose(file);
+#ifdef _MSC_VER
+#pragma warning(pop)
+#endif // _MSC_VER
delete g_captured_stderr;
g_captured_stderr = NULL;
@@ -483,6 +525,10 @@ void CaptureStderr() {
return content;
}
+#endif // GTEST_HAS_STD_STRING
+
+#if GTEST_HAS_DEATH_TEST
+
// A copy of all command line arguments. Set by InitGoogleTest().
::std::vector<String> g_argvs;