media/webrtc/trunk/testing/gtest/src/gtest-port.cc

Thu, 15 Jan 2015 21:03:48 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 15 Jan 2015 21:03:48 +0100
branch
TOR_BUG_9701
changeset 11
deefc01c0e14
permissions
-rw-r--r--

Integrate friendly tips from Tor colleagues to make (or not) 4.5 alpha 3;
This includes removal of overloaded (but unused) methods, and addition of
a overlooked call to DataStruct::SetData(nsISupports, uint32_t, bool.)

     1 // Copyright 2008, Google Inc.
     2 // All rights reserved.
     3 //
     4 // Redistribution and use in source and binary forms, with or without
     5 // modification, are permitted provided that the following conditions are
     6 // met:
     7 //
     8 //     * Redistributions of source code must retain the above copyright
     9 // notice, this list of conditions and the following disclaimer.
    10 //     * Redistributions in binary form must reproduce the above
    11 // copyright notice, this list of conditions and the following disclaimer
    12 // in the documentation and/or other materials provided with the
    13 // distribution.
    14 //     * Neither the name of Google Inc. nor the names of its
    15 // contributors may be used to endorse or promote products derived from
    16 // this software without specific prior written permission.
    17 //
    18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
    21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
    22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
    23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
    24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
    26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
    28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    29 //
    30 // Author: wan@google.com (Zhanyong Wan)
    32 #include "gtest/internal/gtest-port.h"
    34 #include <limits.h>
    35 #include <stdlib.h>
    36 #include <stdio.h>
    37 #include <string.h>
    39 #if GTEST_OS_WINDOWS_MOBILE
    40 # include <windows.h>  // For TerminateProcess()
    41 #elif GTEST_OS_WINDOWS
    42 # include <io.h>
    43 # include <sys/stat.h>
    44 #else
    45 # include <unistd.h>
    46 #endif  // GTEST_OS_WINDOWS_MOBILE
    48 #if GTEST_OS_MAC
    49 # include <mach/mach_init.h>
    50 # include <mach/task.h>
    51 # include <mach/vm_map.h>
    52 #endif  // GTEST_OS_MAC
    54 #if GTEST_OS_QNX
    55 # include <devctl.h>
    56 # include <sys/procfs.h>
    57 #endif  // GTEST_OS_QNX
    59 #include "gtest/gtest-spi.h"
    60 #include "gtest/gtest-message.h"
    61 #include "gtest/internal/gtest-internal.h"
    62 #include "gtest/internal/gtest-string.h"
    64 // Indicates that this translation unit is part of Google Test's
    65 // implementation.  It must come before gtest-internal-inl.h is
    66 // included, or there will be a compiler error.  This trick is to
    67 // prevent a user from accidentally including gtest-internal-inl.h in
    68 // his code.
    69 #define GTEST_IMPLEMENTATION_ 1
    70 #include "src/gtest-internal-inl.h"
    71 #undef GTEST_IMPLEMENTATION_
    73 namespace testing {
    74 namespace internal {
    76 #if defined(_MSC_VER) || defined(__BORLANDC__)
    77 // MSVC and C++Builder do not provide a definition of STDERR_FILENO.
    78 const int kStdOutFileno = 1;
    79 const int kStdErrFileno = 2;
    80 #else
    81 const int kStdOutFileno = STDOUT_FILENO;
    82 const int kStdErrFileno = STDERR_FILENO;
    83 #endif  // _MSC_VER
    85 #if GTEST_OS_MAC
    87 // Returns the number of threads running in the process, or 0 to indicate that
    88 // we cannot detect it.
    89 size_t GetThreadCount() {
    90   const task_t task = mach_task_self();
    91   mach_msg_type_number_t thread_count;
    92   thread_act_array_t thread_list;
    93   const kern_return_t status = task_threads(task, &thread_list, &thread_count);
    94   if (status == KERN_SUCCESS) {
    95     // task_threads allocates resources in thread_list and we need to free them
    96     // to avoid leaks.
    97     vm_deallocate(task,
    98                   reinterpret_cast<vm_address_t>(thread_list),
    99                   sizeof(thread_t) * thread_count);
   100     return static_cast<size_t>(thread_count);
   101   } else {
   102     return 0;
   103   }
   104 }
   106 #elif GTEST_OS_QNX
   108 // Returns the number of threads running in the process, or 0 to indicate that
   109 // we cannot detect it.
   110 size_t GetThreadCount() {
   111   const int fd = open("/proc/self/as", O_RDONLY);
   112   if (fd < 0) {
   113     return 0;
   114   }
   115   procfs_info process_info;
   116   const int status =
   117       devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL);
   118   close(fd);
   119   if (status == EOK) {
   120     return static_cast<size_t>(process_info.num_threads);
   121   } else {
   122     return 0;
   123   }
   124 }
   126 #else
   128 size_t GetThreadCount() {
   129   // There's no portable way to detect the number of threads, so we just
   130   // return 0 to indicate that we cannot detect it.
   131   return 0;
   132 }
   134 #endif  // GTEST_OS_MAC
   136 #if GTEST_USES_POSIX_RE
   138 // Implements RE.  Currently only needed for death tests.
   140 RE::~RE() {
   141   if (is_valid_) {
   142     // regfree'ing an invalid regex might crash because the content
   143     // of the regex is undefined. Since the regex's are essentially
   144     // the same, one cannot be valid (or invalid) without the other
   145     // being so too.
   146     regfree(&partial_regex_);
   147     regfree(&full_regex_);
   148   }
   149   free(const_cast<char*>(pattern_));
   150 }
   152 // Returns true iff regular expression re matches the entire str.
   153 bool RE::FullMatch(const char* str, const RE& re) {
   154   if (!re.is_valid_) return false;
   156   regmatch_t match;
   157   return regexec(&re.full_regex_, str, 1, &match, 0) == 0;
   158 }
   160 // Returns true iff regular expression re matches a substring of str
   161 // (including str itself).
   162 bool RE::PartialMatch(const char* str, const RE& re) {
   163   if (!re.is_valid_) return false;
   165   regmatch_t match;
   166   return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;
   167 }
   169 // Initializes an RE from its string representation.
   170 void RE::Init(const char* regex) {
   171   pattern_ = posix::StrDup(regex);
   173   // Reserves enough bytes to hold the regular expression used for a
   174   // full match.
   175   const size_t full_regex_len = strlen(regex) + 10;
   176   char* const full_pattern = new char[full_regex_len];
   178   snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
   179   is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
   180   // We want to call regcomp(&partial_regex_, ...) even if the
   181   // previous expression returns false.  Otherwise partial_regex_ may
   182   // not be properly initialized can may cause trouble when it's
   183   // freed.
   184   //
   185   // Some implementation of POSIX regex (e.g. on at least some
   186   // versions of Cygwin) doesn't accept the empty string as a valid
   187   // regex.  We change it to an equivalent form "()" to be safe.
   188   if (is_valid_) {
   189     const char* const partial_regex = (*regex == '\0') ? "()" : regex;
   190     is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
   191   }
   192   EXPECT_TRUE(is_valid_)
   193       << "Regular expression \"" << regex
   194       << "\" is not a valid POSIX Extended regular expression.";
   196   delete[] full_pattern;
   197 }
   199 #elif GTEST_USES_SIMPLE_RE
   201 // Returns true iff ch appears anywhere in str (excluding the
   202 // terminating '\0' character).
   203 bool IsInSet(char ch, const char* str) {
   204   return ch != '\0' && strchr(str, ch) != NULL;
   205 }
   207 // Returns true iff ch belongs to the given classification.  Unlike
   208 // similar functions in <ctype.h>, these aren't affected by the
   209 // current locale.
   210 bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; }
   211 bool IsAsciiPunct(char ch) {
   212   return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~");
   213 }
   214 bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); }
   215 bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); }
   216 bool IsAsciiWordChar(char ch) {
   217   return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||
   218       ('0' <= ch && ch <= '9') || ch == '_';
   219 }
   221 // Returns true iff "\\c" is a supported escape sequence.
   222 bool IsValidEscape(char c) {
   223   return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW"));
   224 }
   226 // Returns true iff the given atom (specified by escaped and pattern)
   227 // matches ch.  The result is undefined if the atom is invalid.
   228 bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
   229   if (escaped) {  // "\\p" where p is pattern_char.
   230     switch (pattern_char) {
   231       case 'd': return IsAsciiDigit(ch);
   232       case 'D': return !IsAsciiDigit(ch);
   233       case 'f': return ch == '\f';
   234       case 'n': return ch == '\n';
   235       case 'r': return ch == '\r';
   236       case 's': return IsAsciiWhiteSpace(ch);
   237       case 'S': return !IsAsciiWhiteSpace(ch);
   238       case 't': return ch == '\t';
   239       case 'v': return ch == '\v';
   240       case 'w': return IsAsciiWordChar(ch);
   241       case 'W': return !IsAsciiWordChar(ch);
   242     }
   243     return IsAsciiPunct(pattern_char) && pattern_char == ch;
   244   }
   246   return (pattern_char == '.' && ch != '\n') || pattern_char == ch;
   247 }
   249 // Helper function used by ValidateRegex() to format error messages.
   250 String FormatRegexSyntaxError(const char* regex, int index) {
   251   return (Message() << "Syntax error at index " << index
   252           << " in simple regular expression \"" << regex << "\": ").GetString();
   253 }
   255 // Generates non-fatal failures and returns false if regex is invalid;
   256 // otherwise returns true.
   257 bool ValidateRegex(const char* regex) {
   258   if (regex == NULL) {
   259     // TODO(wan@google.com): fix the source file location in the
   260     // assertion failures to match where the regex is used in user
   261     // code.
   262     ADD_FAILURE() << "NULL is not a valid simple regular expression.";
   263     return false;
   264   }
   266   bool is_valid = true;
   268   // True iff ?, *, or + can follow the previous atom.
   269   bool prev_repeatable = false;
   270   for (int i = 0; regex[i]; i++) {
   271     if (regex[i] == '\\') {  // An escape sequence
   272       i++;
   273       if (regex[i] == '\0') {
   274         ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
   275                       << "'\\' cannot appear at the end.";
   276         return false;
   277       }
   279       if (!IsValidEscape(regex[i])) {
   280         ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
   281                       << "invalid escape sequence \"\\" << regex[i] << "\".";
   282         is_valid = false;
   283       }
   284       prev_repeatable = true;
   285     } else {  // Not an escape sequence.
   286       const char ch = regex[i];
   288       if (ch == '^' && i > 0) {
   289         ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
   290                       << "'^' can only appear at the beginning.";
   291         is_valid = false;
   292       } else if (ch == '$' && regex[i + 1] != '\0') {
   293         ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
   294                       << "'$' can only appear at the end.";
   295         is_valid = false;
   296       } else if (IsInSet(ch, "()[]{}|")) {
   297         ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
   298                       << "'" << ch << "' is unsupported.";
   299         is_valid = false;
   300       } else if (IsRepeat(ch) && !prev_repeatable) {
   301         ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
   302                       << "'" << ch << "' can only follow a repeatable token.";
   303         is_valid = false;
   304       }
   306       prev_repeatable = !IsInSet(ch, "^$?*+");
   307     }
   308   }
   310   return is_valid;
   311 }
   313 // Matches a repeated regex atom followed by a valid simple regular
   314 // expression.  The regex atom is defined as c if escaped is false,
   315 // or \c otherwise.  repeat is the repetition meta character (?, *,
   316 // or +).  The behavior is undefined if str contains too many
   317 // characters to be indexable by size_t, in which case the test will
   318 // probably time out anyway.  We are fine with this limitation as
   319 // std::string has it too.
   320 bool MatchRepetitionAndRegexAtHead(
   321     bool escaped, char c, char repeat, const char* regex,
   322     const char* str) {
   323   const size_t min_count = (repeat == '+') ? 1 : 0;
   324   const size_t max_count = (repeat == '?') ? 1 :
   325       static_cast<size_t>(-1) - 1;
   326   // We cannot call numeric_limits::max() as it conflicts with the
   327   // max() macro on Windows.
   329   for (size_t i = 0; i <= max_count; ++i) {
   330     // We know that the atom matches each of the first i characters in str.
   331     if (i >= min_count && MatchRegexAtHead(regex, str + i)) {
   332       // We have enough matches at the head, and the tail matches too.
   333       // Since we only care about *whether* the pattern matches str
   334       // (as opposed to *how* it matches), there is no need to find a
   335       // greedy match.
   336       return true;
   337     }
   338     if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i]))
   339       return false;
   340   }
   341   return false;
   342 }
   344 // Returns true iff regex matches a prefix of str.  regex must be a
   345 // valid simple regular expression and not start with "^", or the
   346 // result is undefined.
   347 bool MatchRegexAtHead(const char* regex, const char* str) {
   348   if (*regex == '\0')  // An empty regex matches a prefix of anything.
   349     return true;
   351   // "$" only matches the end of a string.  Note that regex being
   352   // valid guarantees that there's nothing after "$" in it.
   353   if (*regex == '$')
   354     return *str == '\0';
   356   // Is the first thing in regex an escape sequence?
   357   const bool escaped = *regex == '\\';
   358   if (escaped)
   359     ++regex;
   360   if (IsRepeat(regex[1])) {
   361     // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so
   362     // here's an indirect recursion.  It terminates as the regex gets
   363     // shorter in each recursion.
   364     return MatchRepetitionAndRegexAtHead(
   365         escaped, regex[0], regex[1], regex + 2, str);
   366   } else {
   367     // regex isn't empty, isn't "$", and doesn't start with a
   368     // repetition.  We match the first atom of regex with the first
   369     // character of str and recurse.
   370     return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) &&
   371         MatchRegexAtHead(regex + 1, str + 1);
   372   }
   373 }
   375 // Returns true iff regex matches any substring of str.  regex must be
   376 // a valid simple regular expression, or the result is undefined.
   377 //
   378 // The algorithm is recursive, but the recursion depth doesn't exceed
   379 // the regex length, so we won't need to worry about running out of
   380 // stack space normally.  In rare cases the time complexity can be
   381 // exponential with respect to the regex length + the string length,
   382 // but usually it's must faster (often close to linear).
   383 bool MatchRegexAnywhere(const char* regex, const char* str) {
   384   if (regex == NULL || str == NULL)
   385     return false;
   387   if (*regex == '^')
   388     return MatchRegexAtHead(regex + 1, str);
   390   // A successful match can be anywhere in str.
   391   do {
   392     if (MatchRegexAtHead(regex, str))
   393       return true;
   394   } while (*str++ != '\0');
   395   return false;
   396 }
   398 // Implements the RE class.
   400 RE::~RE() {
   401   free(const_cast<char*>(pattern_));
   402   free(const_cast<char*>(full_pattern_));
   403 }
   405 // Returns true iff regular expression re matches the entire str.
   406 bool RE::FullMatch(const char* str, const RE& re) {
   407   return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str);
   408 }
   410 // Returns true iff regular expression re matches a substring of str
   411 // (including str itself).
   412 bool RE::PartialMatch(const char* str, const RE& re) {
   413   return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str);
   414 }
   416 // Initializes an RE from its string representation.
   417 void RE::Init(const char* regex) {
   418   pattern_ = full_pattern_ = NULL;
   419   if (regex != NULL) {
   420     pattern_ = posix::StrDup(regex);
   421   }
   423   is_valid_ = ValidateRegex(regex);
   424   if (!is_valid_) {
   425     // No need to calculate the full pattern when the regex is invalid.
   426     return;
   427   }
   429   const size_t len = strlen(regex);
   430   // Reserves enough bytes to hold the regular expression used for a
   431   // full match: we need space to prepend a '^', append a '$', and
   432   // terminate the string with '\0'.
   433   char* buffer = static_cast<char*>(malloc(len + 3));
   434   full_pattern_ = buffer;
   436   if (*regex != '^')
   437     *buffer++ = '^';  // Makes sure full_pattern_ starts with '^'.
   439   // We don't use snprintf or strncpy, as they trigger a warning when
   440   // compiled with VC++ 8.0.
   441   memcpy(buffer, regex, len);
   442   buffer += len;
   444   if (len == 0 || regex[len - 1] != '$')
   445     *buffer++ = '$';  // Makes sure full_pattern_ ends with '$'.
   447   *buffer = '\0';
   448 }
   450 #endif  // GTEST_USES_POSIX_RE
   452 const char kUnknownFile[] = "unknown file";
   454 // Formats a source file path and a line number as they would appear
   455 // in an error message from the compiler used to compile this code.
   456 GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {
   457   const char* const file_name = file == NULL ? kUnknownFile : file;
   459   if (line < 0) {
   460     return String::Format("%s:", file_name).c_str();
   461   }
   462 #ifdef _MSC_VER
   463   return String::Format("%s(%d):", file_name, line).c_str();
   464 #else
   465   return String::Format("%s:%d:", file_name, line).c_str();
   466 #endif  // _MSC_VER
   467 }
   469 // Formats a file location for compiler-independent XML output.
   470 // Although this function is not platform dependent, we put it next to
   471 // FormatFileLocation in order to contrast the two functions.
   472 // Note that FormatCompilerIndependentFileLocation() does NOT append colon
   473 // to the file location it produces, unlike FormatFileLocation().
   474 GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(
   475     const char* file, int line) {
   476   const char* const file_name = file == NULL ? kUnknownFile : file;
   478   if (line < 0)
   479     return file_name;
   480   else
   481     return String::Format("%s:%d", file_name, line).c_str();
   482 }
   485 GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)
   486     : severity_(severity) {
   487   const char* const marker =
   488       severity == GTEST_INFO ?    "[  INFO ]" :
   489       severity == GTEST_WARNING ? "[WARNING]" :
   490       severity == GTEST_ERROR ?   "[ ERROR ]" : "[ FATAL ]";
   491   GetStream() << ::std::endl << marker << " "
   492               << FormatFileLocation(file, line).c_str() << ": ";
   493 }
   495 // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
   496 GTestLog::~GTestLog() {
   497   GetStream() << ::std::endl;
   498   if (severity_ == GTEST_FATAL) {
   499     fflush(stderr);
   500     posix::Abort();
   501   }
   502 }
   503 // Disable Microsoft deprecation warnings for POSIX functions called from
   504 // this class (creat, dup, dup2, and close)
   505 #ifdef _MSC_VER
   506 # pragma warning(push)
   507 # pragma warning(disable: 4996)
   508 #endif  // _MSC_VER
   510 #if GTEST_HAS_STREAM_REDIRECTION
   512 // Object that captures an output stream (stdout/stderr).
   513 class CapturedStream {
   514  public:
   515   // The ctor redirects the stream to a temporary file.
   516   CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
   517 # if GTEST_OS_WINDOWS
   518     char temp_dir_path[MAX_PATH + 1] = { '\0' };  // NOLINT
   519     char temp_file_path[MAX_PATH + 1] = { '\0' };  // NOLINT
   521     ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);
   522     const UINT success = ::GetTempFileNameA(temp_dir_path,
   523                                             "gtest_redir",
   524                                             0,  // Generate unique file name.
   525                                             temp_file_path);
   526     GTEST_CHECK_(success != 0)
   527         << "Unable to create a temporary file in " << temp_dir_path;
   528     const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
   529     GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file "
   530                                     << temp_file_path;
   531     filename_ = temp_file_path;
   532 # else
   533     // There's no guarantee that a test has write access to the current
   534     // directory, so we create the temporary file in the /tmp directory instead.
   535     // We use /tmp on most systems, and /mnt/sdcard on Android. That's because
   536     // Android doesn't have /tmp.
   537 #  if GTEST_OS_LINUX_ANDROID
   538     char name_template[] = "/mnt/sdcard/gtest_captured_stream.XXXXXX";
   539 #  else
   540     char name_template[] = "/tmp/captured_stream.XXXXXX";
   541 #  endif  // GTEST_OS_LINUX_ANDROID
   542     const int captured_fd = mkstemp(name_template);
   543     filename_ = name_template;
   544 # endif  // GTEST_OS_WINDOWS
   545     fflush(NULL);
   546     dup2(captured_fd, fd_);
   547     close(captured_fd);
   548   }
   550   ~CapturedStream() {
   551     remove(filename_.c_str());
   552   }
   554   String GetCapturedString() {
   555     if (uncaptured_fd_ != -1) {
   556       // Restores the original stream.
   557       fflush(NULL);
   558       dup2(uncaptured_fd_, fd_);
   559       close(uncaptured_fd_);
   560       uncaptured_fd_ = -1;
   561     }
   563     FILE* const file = posix::FOpen(filename_.c_str(), "r");
   564     const String content = ReadEntireFile(file);
   565     posix::FClose(file);
   566     return content;
   567   }
   569  private:
   570   // Reads the entire content of a file as a String.
   571   static String ReadEntireFile(FILE* file);
   573   // Returns the size (in bytes) of a file.
   574   static size_t GetFileSize(FILE* file);
   576   const int fd_;  // A stream to capture.
   577   int uncaptured_fd_;
   578   // Name of the temporary file holding the stderr output.
   579   ::std::string filename_;
   581   GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
   582 };
   584 // Returns the size (in bytes) of a file.
   585 size_t CapturedStream::GetFileSize(FILE* file) {
   586   fseek(file, 0, SEEK_END);
   587   return static_cast<size_t>(ftell(file));
   588 }
   590 // Reads the entire content of a file as a string.
   591 String CapturedStream::ReadEntireFile(FILE* file) {
   592   const size_t file_size = GetFileSize(file);
   593   char* const buffer = new char[file_size];
   595   size_t bytes_last_read = 0;  // # of bytes read in the last fread()
   596   size_t bytes_read = 0;       // # of bytes read so far
   598   fseek(file, 0, SEEK_SET);
   600   // Keeps reading the file until we cannot read further or the
   601   // pre-determined file size is reached.
   602   do {
   603     bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);
   604     bytes_read += bytes_last_read;
   605   } while (bytes_last_read > 0 && bytes_read < file_size);
   607   const String content(buffer, bytes_read);
   608   delete[] buffer;
   610   return content;
   611 }
   613 # ifdef _MSC_VER
   614 #  pragma warning(pop)
   615 # endif  // _MSC_VER
   617 static CapturedStream* g_captured_stderr = NULL;
   618 static CapturedStream* g_captured_stdout = NULL;
   620 // Starts capturing an output stream (stdout/stderr).
   621 void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
   622   if (*stream != NULL) {
   623     GTEST_LOG_(FATAL) << "Only one " << stream_name
   624                       << " capturer can exist at a time.";
   625   }
   626   *stream = new CapturedStream(fd);
   627 }
   629 // Stops capturing the output stream and returns the captured string.
   630 String GetCapturedStream(CapturedStream** captured_stream) {
   631   const String content = (*captured_stream)->GetCapturedString();
   633   delete *captured_stream;
   634   *captured_stream = NULL;
   636   return content;
   637 }
   639 // Starts capturing stdout.
   640 void CaptureStdout() {
   641   CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout);
   642 }
   644 // Starts capturing stderr.
   645 void CaptureStderr() {
   646   CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr);
   647 }
   649 // Stops capturing stdout and returns the captured string.
   650 String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); }
   652 // Stops capturing stderr and returns the captured string.
   653 String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); }
   655 #endif  // GTEST_HAS_STREAM_REDIRECTION
   657 #if GTEST_HAS_DEATH_TEST
   659 // A copy of all command line arguments.  Set by InitGoogleTest().
   660 ::std::vector<testing::internal::string> g_argvs;
   662 static const ::std::vector<testing::internal::string>* g_injected_test_argvs =
   663                                         NULL;  // Owned.
   665 void SetInjectableArgvs(const ::std::vector<testing::internal::string>* argvs) {
   666   if (g_injected_test_argvs != argvs)
   667     delete g_injected_test_argvs;
   668   g_injected_test_argvs = argvs;
   669 }
   671 const ::std::vector<testing::internal::string>& GetInjectableArgvs() {
   672   if (g_injected_test_argvs != NULL) {
   673     return *g_injected_test_argvs;
   674   }
   675   return g_argvs;
   676 }
   677 #endif  // GTEST_HAS_DEATH_TEST
   679 #if GTEST_OS_WINDOWS_MOBILE
   680 namespace posix {
   681 void Abort() {
   682   DebugBreak();
   683   TerminateProcess(GetCurrentProcess(), 1);
   684 }
   685 }  // namespace posix
   686 #endif  // GTEST_OS_WINDOWS_MOBILE
   688 // Returns the name of the environment variable corresponding to the
   689 // given flag.  For example, FlagToEnvVar("foo") will return
   690 // "GTEST_FOO" in the open-source version.
   691 static String FlagToEnvVar(const char* flag) {
   692   const String full_flag =
   693       (Message() << GTEST_FLAG_PREFIX_ << flag).GetString();
   695   Message env_var;
   696   for (size_t i = 0; i != full_flag.length(); i++) {
   697     env_var << ToUpper(full_flag.c_str()[i]);
   698   }
   700   return env_var.GetString();
   701 }
   703 // Parses 'str' for a 32-bit signed integer.  If successful, writes
   704 // the result to *value and returns true; otherwise leaves *value
   705 // unchanged and returns false.
   706 bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
   707   // Parses the environment variable as a decimal integer.
   708   char* end = NULL;
   709   const long long_value = strtol(str, &end, 10);  // NOLINT
   711   // Has strtol() consumed all characters in the string?
   712   if (*end != '\0') {
   713     // No - an invalid character was encountered.
   714     Message msg;
   715     msg << "WARNING: " << src_text
   716         << " is expected to be a 32-bit integer, but actually"
   717         << " has value \"" << str << "\".\n";
   718     printf("%s", msg.GetString().c_str());
   719     fflush(stdout);
   720     return false;
   721   }
   723   // Is the parsed value in the range of an Int32?
   724   const Int32 result = static_cast<Int32>(long_value);
   725   if (long_value == LONG_MAX || long_value == LONG_MIN ||
   726       // The parsed value overflows as a long.  (strtol() returns
   727       // LONG_MAX or LONG_MIN when the input overflows.)
   728       result != long_value
   729       // The parsed value overflows as an Int32.
   730       ) {
   731     Message msg;
   732     msg << "WARNING: " << src_text
   733         << " is expected to be a 32-bit integer, but actually"
   734         << " has value " << str << ", which overflows.\n";
   735     printf("%s", msg.GetString().c_str());
   736     fflush(stdout);
   737     return false;
   738   }
   740   *value = result;
   741   return true;
   742 }
   744 // Reads and returns the Boolean environment variable corresponding to
   745 // the given flag; if it's not set, returns default_value.
   746 //
   747 // The value is considered true iff it's not "0".
   748 bool BoolFromGTestEnv(const char* flag, bool default_value) {
   749   const String env_var = FlagToEnvVar(flag);
   750   const char* const string_value = posix::GetEnv(env_var.c_str());
   751   return string_value == NULL ?
   752       default_value : strcmp(string_value, "0") != 0;
   753 }
   755 // Reads and returns a 32-bit integer stored in the environment
   756 // variable corresponding to the given flag; if it isn't set or
   757 // doesn't represent a valid 32-bit integer, returns default_value.
   758 Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
   759   const String env_var = FlagToEnvVar(flag);
   760   const char* const string_value = posix::GetEnv(env_var.c_str());
   761   if (string_value == NULL) {
   762     // The environment variable is not set.
   763     return default_value;
   764   }
   766   Int32 result = default_value;
   767   if (!ParseInt32(Message() << "Environment variable " << env_var,
   768                   string_value, &result)) {
   769     printf("The default value %s is used.\n",
   770            (Message() << default_value).GetString().c_str());
   771     fflush(stdout);
   772     return default_value;
   773   }
   775   return result;
   776 }
   778 // Reads and returns the string environment variable corresponding to
   779 // the given flag; if it's not set, returns default_value.
   780 const char* StringFromGTestEnv(const char* flag, const char* default_value) {
   781   const String env_var = FlagToEnvVar(flag);
   782   const char* const value = posix::GetEnv(env_var.c_str());
   783   return value == NULL ? default_value : value;
   784 }
   786 }  // namespace internal
   787 }  // namespace testing

mercurial