configure.ac: Allow user to disable gflags
[platform/upstream/glog.git] / src / googletest.h
index 4a4475b..b4677b2 100644 (file)
@@ -1,8 +1,42 @@
+// Copyright (c) 2009, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+//     * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Author: Shinichiro Hamaji
+//   (based on googletest: http://code.google.com/p/googletest/)
+
 #ifdef GOOGLETEST_H__
 #error You must not include this file twice.
 #endif
 #define GOOGLETEST_H__
 
+#include "utilities.h"
+
 #include <ctype.h>
 #include <setjmp.h>
 #include <time.h>
@@ -12,6 +46,9 @@
 #include <string>
 #include <vector>
 
+#include <stdio.h>
+#include <stdlib.h>
+
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
@@ -34,7 +71,7 @@ _END_GOOGLE_NAMESPACE_
 #undef GOOGLE_GLOG_DLL_DECL
 #define GOOGLE_GLOG_DLL_DECL
 
-static string GetTempDir() {
+static inline string GetTempDir() {
 #ifndef OS_WINDOWS
   return "/tmp";
 #else
@@ -44,17 +81,19 @@ static string GetTempDir() {
 #endif
 }
 
-#ifdef OS_WINDOWS
+#if defined(OS_WINDOWS) && defined(_MSC_VER) && !defined(TEST_SRC_DIR)
 // The test will run in glog/vsproject/<project name>
 // (e.g., glog/vsproject/logging_unittest).
 static const char TEST_SRC_DIR[] = "../..";
-#else
+#elif !defined(TEST_SRC_DIR)
+# warning TEST_SRC_DIR should be defined in config.h
 static const char TEST_SRC_DIR[] = ".";
 #endif
 
 DEFINE_string(test_tmpdir, GetTempDir(), "Dir we use for temp files");
 DEFINE_string(test_srcdir, TEST_SRC_DIR,
               "Source-dir root, needed to find glog_unittest_flagfile");
+DEFINE_bool(run_benchmark, false, "If true, run benchmarks");
 #ifdef NDEBUG
 DEFINE_int32(benchmark_iters, 100000000, "Number of iterations per benchmark");
 #else
@@ -71,7 +110,7 @@ using testing::InitGoogleTest;
 
 _START_GOOGLE_NAMESPACE_
 
-void InitGoogleTest(int* argc, char** argv) {}
+void InitGoogleTest(int*, char**) {}
 
 // The following is some bare-bones testing infrastructure
 
@@ -142,7 +181,7 @@ vector<void (*)()> g_testlist;  // the tests to run
   void Test_##a##_##b::RunTest()
 
 
-static int RUN_ALL_TESTS() {
+static inline int RUN_ALL_TESTS() {
   vector<void (*)()>::const_iterator it;
   for (it = g_testlist.begin(); it != g_testlist.end(); ++it) {
     (*it)();
@@ -159,7 +198,7 @@ _START_GOOGLE_NAMESPACE_
 
 static bool g_called_abort;
 static jmp_buf g_jmp_buf;
-static void CalledAbort() {
+static inline void CalledAbort() {
   g_called_abort = true;
   longjmp(g_jmp_buf, 1);
 }
@@ -203,7 +242,11 @@ class BenchmarkRegisterer {
   }
 };
 
-static void RunSpecifiedBenchmarks() {
+static inline void RunSpecifiedBenchmarks() {
+  if (!FLAGS_run_benchmark) {
+    return;
+  }
+
   int iter_cnt = FLAGS_benchmark_iters;
   puts("Benchmark\tTime(ns)\tIterations");
   for (map<string, void (*)(int)>::const_iterator iter = g_benchlist.begin();
@@ -277,21 +320,21 @@ static CapturedStream * s_captured_streams[STDERR_FILENO+1];
 // Redirect a file descriptor to a file.
 //   fd       - Should be STDOUT_FILENO or STDERR_FILENO
 //   filename - File where output should be stored
-static void CaptureTestOutput(int fd, const string & filename) {
+static inline void CaptureTestOutput(int fd, const string & filename) {
   CHECK((fd == STDOUT_FILENO) || (fd == STDERR_FILENO));
   CHECK(s_captured_streams[fd] == NULL);
   s_captured_streams[fd] = new CapturedStream(fd, filename);
 }
-static void CaptureTestStderr() {
+static inline void CaptureTestStderr() {
   CaptureTestOutput(STDERR_FILENO, FLAGS_test_tmpdir + "/captured.err");
 }
 // Return the size (in bytes) of a file
-static size_t GetFileSize(FILE * file) {
+static inline size_t GetFileSize(FILE * file) {
   fseek(file, 0, SEEK_END);
   return static_cast<size_t>(ftell(file));
 }
 // Read the entire content of a file as a string
-static string ReadEntireFile(FILE * file) {
+static inline string ReadEntireFile(FILE * file) {
   const size_t file_size = GetFileSize(file);
   char * const buffer = new char[file_size];
 
@@ -314,7 +357,7 @@ static string ReadEntireFile(FILE * file) {
 }
 // Get the captured stdout (when fd is STDOUT_FILENO) or stderr (when
 // fd is STDERR_FILENO) as a string
-static string GetCapturedTestOutput(int fd) {
+static inline string GetCapturedTestOutput(int fd) {
   CHECK(fd == STDOUT_FILENO || fd == STDERR_FILENO);
   CapturedStream * const cap = s_captured_streams[fd];
   CHECK(cap)
@@ -334,12 +377,12 @@ static string GetCapturedTestOutput(int fd) {
   return content;
 }
 // Get the captured stderr of a test as a string.
-static string GetCapturedTestStderr() {
+static inline string GetCapturedTestStderr() {
   return GetCapturedTestOutput(STDERR_FILENO);
 }
 
 // Check if the string is [IWEF](\d{4}|DATE)
-static bool IsLoggingPrefix(const string& s) {
+static inline bool IsLoggingPrefix(const string& s) {
   if (s.size() != 5) return false;
   if (!strchr("IWEF", s[0])) return false;
   for (int i = 1; i <= 4; ++i) {
@@ -353,7 +396,7 @@ static bool IsLoggingPrefix(const string& s) {
 // Example:
 //     I0102 030405 logging_unittest.cc:345] RAW: vlog -1
 //  => IDATE TIME__ logging_unittest.cc:LINE] RAW: vlog -1
-static string MungeLine(const string& line) {
+static inline string MungeLine(const string& line) {
   std::istringstream iss(line);
   string before, logcode_date, time, thread_lineinfo;
   iss >> logcode_date;
@@ -385,7 +428,7 @@ static string MungeLine(const string& line) {
           MungeLine(rest));
 }
 
-static void StringReplace(string* str,
+static inline void StringReplace(string* str,
                           const string& oldsub,
                           const string& newsub) {
   size_t pos = str->find(oldsub);
@@ -394,7 +437,7 @@ static void StringReplace(string* str,
   }
 }
 
-static string Munge(const string& filename) {
+static inline string Munge(const string& filename) {
   FILE* fp = fopen(filename.c_str(), "rb");
   CHECK(fp != NULL) << filename << ": couldn't open";
   char buf[4096];
@@ -402,37 +445,29 @@ static string Munge(const string& filename) {
   while (fgets(buf, 4095, fp)) {
     string line = MungeLine(buf);
     char null_str[256];
-    sprintf(null_str, "%p", NULL);
+    sprintf(null_str, "%p", static_cast<void*>(NULL));
     StringReplace(&line, "__NULLP__", null_str);
     // Remove 0x prefix produced by %p. VC++ doesn't put the prefix.
     StringReplace(&line, " 0x", " ");
 
-    char errmsg_buf[100];
-    posix_strerror_r(0, errmsg_buf, sizeof(errmsg_buf));
-    if (*errmsg_buf == '\0') {
-      // MacOSX 10.4 and FreeBSD return empty string for errno=0.
-      // In such case, the we need to remove an extra space.
-      StringReplace(&line, "__SUCCESS__ ", "");
-    } else {
-      StringReplace(&line, "__SUCCESS__", errmsg_buf);
-    }
-    StringReplace(&line, "__ENOENT__", strerror(ENOENT));
-    StringReplace(&line, "__EINTR__", strerror(EINTR));
-    StringReplace(&line, "__ENXIO__", strerror(ENXIO));
-    StringReplace(&line, "__ENOEXEC__", strerror(ENOEXEC));
+    StringReplace(&line, "__SUCCESS__", StrError(0));
+    StringReplace(&line, "__ENOENT__", StrError(ENOENT));
+    StringReplace(&line, "__EINTR__", StrError(EINTR));
+    StringReplace(&line, "__ENXIO__", StrError(ENXIO));
+    StringReplace(&line, "__ENOEXEC__", StrError(ENOEXEC));
     result += line + "\n";
   }
   fclose(fp);
   return result;
 }
 
-static void WriteToFile(const string& body, const string& file) {
+static inline void WriteToFile(const string& body, const string& file) {
   FILE* fp = fopen(file.c_str(), "wb");
   fwrite(body.data(), 1, body.size(), fp);
   fclose(fp);
 }
 
-static bool MungeAndDiffTestStderr(const string& golden_filename) {
+static inline bool MungeAndDiffTestStderr(const string& golden_filename) {
   CapturedStream* cap = s_captured_streams[STDERR_FILENO];
   CHECK(cap) << ": did you forget CaptureTestStderr()?";
 
@@ -483,15 +518,10 @@ struct FlagSaver {
 
 class Thread {
  public:
-  void SetJoinable(bool joinable) {}
-#if defined(HAVE_PTHREAD)
-  void Start() {
-    pthread_create(&th_, NULL, &Thread::InvokeThread, this);
-  }
-  void Join() {
-    pthread_join(th_, NULL);
-  }
-#elif defined(OS_WINDOWS)
+  virtual ~Thread() {}
+
+  void SetJoinable(bool) {}
+#if defined(OS_WINDOWS) || defined(OS_CYGWIN)
   void Start() {
     handle_ = CreateThread(NULL,
                            0,
@@ -504,6 +534,13 @@ class Thread {
   void Join() {
     WaitForSingleObject(handle_, INFINITE);
   }
+#elif defined(HAVE_PTHREAD)
+  void Start() {
+    pthread_create(&th_, NULL, &Thread::InvokeThread, this);
+  }
+  void Join() {
+    pthread_join(th_, NULL);
+  }
 #else
 # error No thread implementation.
 #endif
@@ -517,13 +554,15 @@ class Thread {
     return NULL;
   }
 
-  pthread_t th_;
-#ifdef OS_WINDOWS
+#if defined(OS_WINDOWS) || defined(OS_CYGWIN)
   HANDLE handle_;
+  DWORD th_;
+#else
+  pthread_t th_;
 #endif
 };
 
-static void SleepForMilliseconds(int t) {
+static inline void SleepForMilliseconds(int t) {
 #ifndef OS_WINDOWS
   usleep(t * 1000);
 #else
@@ -537,21 +576,21 @@ void (*g_new_hook)() = NULL;
 
 _END_GOOGLE_NAMESPACE_
 
-void* operator new(size_t size) {
+void* operator new(size_t size) throw(std::bad_alloc) {
   if (GOOGLE_NAMESPACE::g_new_hook) {
     GOOGLE_NAMESPACE::g_new_hook();
   }
   return malloc(size);
 }
 
-void* operator new[](size_t size) {
+void* operator new[](size_t size) throw(std::bad_alloc) {
   return ::operator new(size);
 }
 
-void operator delete(void* p) {
+void operator delete(void* p) throw() {
   free(p);
 }
 
-void operator delete[](void* p) {
+void operator delete[](void* p) throw() {
   ::operator delete(p);
 }