Home | History | Annotate | Download | only in src
      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 (at) google.com (Zhanyong Wan)
     31 
     32 #include "gtest/internal/gtest-port.h"
     33 
     34 #include <limits.h>
     35 #include <stdlib.h>
     36 #include <stdio.h>
     37 #include <string.h>
     38 
     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
     47 
     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
     53 
     54 #include "gtest/gtest-spi.h"
     55 #include "gtest/gtest-message.h"
     56 #include "gtest/internal/gtest-internal.h"
     57 #include "gtest/internal/gtest-string.h"
     58 
     59 // Indicates that this translation unit is part of Google Test's
     60 // implementation.  It must come before gtest-internal-inl.h is
     61 // included, or there will be a compiler error.  This trick is to
     62 // prevent a user from accidentally including gtest-internal-inl.h in
     63 // his code.
     64 #define GTEST_IMPLEMENTATION_ 1
     65 #include "src/gtest-internal-inl.h"
     66 #undef GTEST_IMPLEMENTATION_
     67 
     68 namespace testing {
     69 namespace internal {
     70 
     71 #if defined(_MSC_VER) || defined(__BORLANDC__)
     72 // MSVC and C++Builder do not provide a definition of STDERR_FILENO.
     73 const int kStdOutFileno = 1;
     74 const int kStdErrFileno = 2;
     75 #else
     76 const int kStdOutFileno = STDOUT_FILENO;
     77 const int kStdErrFileno = STDERR_FILENO;
     78 #endif  // _MSC_VER
     79 
     80 #if GTEST_OS_MAC
     81 
     82 // Returns the number of threads running in the process, or 0 to indicate that
     83 // we cannot detect it.
     84 size_t GetThreadCount() {
     85   const task_t task = mach_task_self();
     86   mach_msg_type_number_t thread_count;
     87   thread_act_array_t thread_list;
     88   const kern_return_t status = task_threads(task, &thread_list, &thread_count);
     89   if (status == KERN_SUCCESS) {
     90     // task_threads allocates resources in thread_list and we need to free them
     91     // to avoid leaks.
     92     vm_deallocate(task,
     93                   reinterpret_cast<vm_address_t>(thread_list),
     94                   sizeof(thread_t) * thread_count);
     95     return static_cast<size_t>(thread_count);
     96   } else {
     97     return 0;
     98   }
     99 }
    100 
    101 #else
    102 
    103 size_t GetThreadCount() {
    104   // There's no portable way to detect the number of threads, so we just
    105   // return 0 to indicate that we cannot detect it.
    106   return 0;
    107 }
    108 
    109 #endif  // GTEST_OS_MAC
    110 
    111 #if GTEST_USES_POSIX_RE
    112 
    113 // Implements RE.  Currently only needed for death tests.
    114 
    115 RE::~RE() {
    116   if (is_valid_) {
    117     // regfree'ing an invalid regex might crash because the content
    118     // of the regex is undefined. Since the regex's are essentially
    119     // the same, one cannot be valid (or invalid) without the other
    120     // being so too.
    121     regfree(&partial_regex_);
    122     regfree(&full_regex_);
    123   }
    124   free(const_cast<char*>(pattern_));
    125 }
    126 
    127 // Returns true iff regular expression re matches the entire str.
    128 bool RE::FullMatch(const char* str, const RE& re) {
    129   if (!re.is_valid_) return false;
    130 
    131   regmatch_t match;
    132   return regexec(&re.full_regex_, str, 1, &match, 0) == 0;
    133 }
    134 
    135 // Returns true iff regular expression re matches a substring of str
    136 // (including str itself).
    137 bool RE::PartialMatch(const char* str, const RE& re) {
    138   if (!re.is_valid_) return false;
    139 
    140   regmatch_t match;
    141   return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;
    142 }
    143 
    144 // Initializes an RE from its string representation.
    145 void RE::Init(const char* regex) {
    146   pattern_ = posix::StrDup(regex);
    147 
    148   // Reserves enough bytes to hold the regular expression used for a
    149   // full match.
    150   const size_t full_regex_len = strlen(regex) + 10;
    151   char* const full_pattern = new char[full_regex_len];
    152 
    153   snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
    154   is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
    155   // We want to call regcomp(&partial_regex_, ...) even if the
    156   // previous expression returns false.  Otherwise partial_regex_ may
    157   // not be properly initialized can may cause trouble when it's
    158   // freed.
    159   //
    160   // Some implementation of POSIX regex (e.g. on at least some
    161   // versions of Cygwin) doesn't accept the empty string as a valid
    162   // regex.  We change it to an equivalent form "()" to be safe.
    163   if (is_valid_) {
    164     const char* const partial_regex = (*regex == '\0') ? "()" : regex;
    165     is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
    166   }
    167   EXPECT_TRUE(is_valid_)
    168       << "Regular expression \"" << regex
    169       << "\" is not a valid POSIX Extended regular expression.";
    170 
    171   delete[] full_pattern;
    172 }
    173 
    174 #elif GTEST_USES_SIMPLE_RE
    175 
    176 // Returns true iff ch appears anywhere in str (excluding the
    177 // terminating '\0' character).
    178 bool IsInSet(char ch, const char* str) {
    179   return ch != '\0' && strchr(str, ch) != NULL;
    180 }
    181 
    182 // Returns true iff ch belongs to the given classification.  Unlike
    183 // similar functions in <ctype.h>, these aren't affected by the
    184 // current locale.
    185 bool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; }
    186 bool IsAsciiPunct(char ch) {
    187   return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~");
    188 }
    189 bool IsRepeat(char ch) { return IsInSet(ch, "?*+"); }
    190 bool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); }
    191 bool IsAsciiWordChar(char ch) {
    192   return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||
    193       ('0' <= ch && ch <= '9') || ch == '_';
    194 }
    195 
    196 // Returns true iff "\\c" is a supported escape sequence.
    197 bool IsValidEscape(char c) {
    198   return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW"));
    199 }
    200 
    201 // Returns true iff the given atom (specified by escaped and pattern)
    202 // matches ch.  The result is undefined if the atom is invalid.
    203 bool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
    204   if (escaped) {  // "\\p" where p is pattern_char.
    205     switch (pattern_char) {
    206       case 'd': return IsAsciiDigit(ch);
    207       case 'D': return !IsAsciiDigit(ch);
    208       case 'f': return ch == '\f';
    209       case 'n': return ch == '\n';
    210       case 'r': return ch == '\r';
    211       case 's': return IsAsciiWhiteSpace(ch);
    212       case 'S': return !IsAsciiWhiteSpace(ch);
    213       case 't': return ch == '\t';
    214       case 'v': return ch == '\v';
    215       case 'w': return IsAsciiWordChar(ch);
    216       case 'W': return !IsAsciiWordChar(ch);
    217     }
    218     return IsAsciiPunct(pattern_char) && pattern_char == ch;
    219   }
    220 
    221   return (pattern_char == '.' && ch != '\n') || pattern_char == ch;
    222 }
    223 
    224 // Helper function used by ValidateRegex() to format error messages.
    225 String FormatRegexSyntaxError(const char* regex, int index) {
    226   return (Message() << "Syntax error at index " << index
    227           << " in simple regular expression \"" << regex << "\": ").GetString();
    228 }
    229 
    230 // Generates non-fatal failures and returns false if regex is invalid;
    231 // otherwise returns true.
    232 bool ValidateRegex(const char* regex) {
    233   if (regex == NULL) {
    234     // TODO(wan (at) google.com): fix the source file location in the
    235     // assertion failures to match where the regex is used in user
    236     // code.
    237     ADD_FAILURE() << "NULL is not a valid simple regular expression.";
    238     return false;
    239   }
    240 
    241   bool is_valid = true;
    242 
    243   // True iff ?, *, or + can follow the previous atom.
    244   bool prev_repeatable = false;
    245   for (int i = 0; regex[i]; i++) {
    246     if (regex[i] == '\\') {  // An escape sequence
    247       i++;
    248       if (regex[i] == '\0') {
    249         ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
    250                       << "'\\' cannot appear at the end.";
    251         return false;
    252       }
    253 
    254       if (!IsValidEscape(regex[i])) {
    255         ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
    256                       << "invalid escape sequence \"\\" << regex[i] << "\".";
    257         is_valid = false;
    258       }
    259       prev_repeatable = true;
    260     } else {  // Not an escape sequence.
    261       const char ch = regex[i];
    262 
    263       if (ch == '^' && i > 0) {
    264         ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
    265                       << "'^' can only appear at the beginning.";
    266         is_valid = false;
    267       } else if (ch == '$' && regex[i + 1] != '\0') {
    268         ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
    269                       << "'$' can only appear at the end.";
    270         is_valid = false;
    271       } else if (IsInSet(ch, "()[]{}|")) {
    272         ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
    273                       << "'" << ch << "' is unsupported.";
    274         is_valid = false;
    275       } else if (IsRepeat(ch) && !prev_repeatable) {
    276         ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
    277                       << "'" << ch << "' can only follow a repeatable token.";
    278         is_valid = false;
    279       }
    280 
    281       prev_repeatable = !IsInSet(ch, "^$?*+");
    282     }
    283   }
    284 
    285   return is_valid;
    286 }
    287 
    288 // Matches a repeated regex atom followed by a valid simple regular
    289 // expression.  The regex atom is defined as c if escaped is false,
    290 // or \c otherwise.  repeat is the repetition meta character (?, *,
    291 // or +).  The behavior is undefined if str contains too many
    292 // characters to be indexable by size_t, in which case the test will
    293 // probably time out anyway.  We are fine with this limitation as
    294 // std::string has it too.
    295 bool MatchRepetitionAndRegexAtHead(
    296     bool escaped, char c, char repeat, const char* regex,
    297     const char* str) {
    298   const size_t min_count = (repeat == '+') ? 1 : 0;
    299   const size_t max_count = (repeat == '?') ? 1 :
    300       static_cast<size_t>(-1) - 1;
    301   // We cannot call numeric_limits::max() as it conflicts with the
    302   // max() macro on Windows.
    303 
    304   for (size_t i = 0; i <= max_count; ++i) {
    305     // We know that the atom matches each of the first i characters in str.
    306     if (i >= min_count && MatchRegexAtHead(regex, str + i)) {
    307       // We have enough matches at the head, and the tail matches too.
    308       // Since we only care about *whether* the pattern matches str
    309       // (as opposed to *how* it matches), there is no need to find a
    310       // greedy match.
    311       return true;
    312     }
    313     if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i]))
    314       return false;
    315   }
    316   return false;
    317 }
    318 
    319 // Returns true iff regex matches a prefix of str.  regex must be a
    320 // valid simple regular expression and not start with "^", or the
    321 // result is undefined.
    322 bool MatchRegexAtHead(const char* regex, const char* str) {
    323   if (*regex == '\0')  // An empty regex matches a prefix of anything.
    324     return true;
    325 
    326   // "$" only matches the end of a string.  Note that regex being
    327   // valid guarantees that there's nothing after "$" in it.
    328   if (*regex == '$')
    329     return *str == '\0';
    330 
    331   // Is the first thing in regex an escape sequence?
    332   const bool escaped = *regex == '\\';
    333   if (escaped)
    334     ++regex;
    335   if (IsRepeat(regex[1])) {
    336     // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so
    337     // here's an indirect recursion.  It terminates as the regex gets
    338     // shorter in each recursion.
    339     return MatchRepetitionAndRegexAtHead(
    340         escaped, regex[0], regex[1], regex + 2, str);
    341   } else {
    342     // regex isn't empty, isn't "$", and doesn't start with a
    343     // repetition.  We match the first atom of regex with the first
    344     // character of str and recurse.
    345     return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) &&
    346         MatchRegexAtHead(regex + 1, str + 1);
    347   }
    348 }
    349 
    350 // Returns true iff regex matches any substring of str.  regex must be
    351 // a valid simple regular expression, or the result is undefined.
    352 //
    353 // The algorithm is recursive, but the recursion depth doesn't exceed
    354 // the regex length, so we won't need to worry about running out of
    355 // stack space normally.  In rare cases the time complexity can be
    356 // exponential with respect to the regex length + the string length,
    357 // but usually it's must faster (often close to linear).
    358 bool MatchRegexAnywhere(const char* regex, const char* str) {
    359   if (regex == NULL || str == NULL)
    360     return false;
    361 
    362   if (*regex == '^')
    363     return MatchRegexAtHead(regex + 1, str);
    364 
    365   // A successful match can be anywhere in str.
    366   do {
    367     if (MatchRegexAtHead(regex, str))
    368       return true;
    369   } while (*str++ != '\0');
    370   return false;
    371 }
    372 
    373 // Implements the RE class.
    374 
    375 RE::~RE() {
    376   free(const_cast<char*>(pattern_));
    377   free(const_cast<char*>(full_pattern_));
    378 }
    379 
    380 // Returns true iff regular expression re matches the entire str.
    381 bool RE::FullMatch(const char* str, const RE& re) {
    382   return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str);
    383 }
    384 
    385 // Returns true iff regular expression re matches a substring of str
    386 // (including str itself).
    387 bool RE::PartialMatch(const char* str, const RE& re) {
    388   return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str);
    389 }
    390 
    391 // Initializes an RE from its string representation.
    392 void RE::Init(const char* regex) {
    393   pattern_ = full_pattern_ = NULL;
    394   if (regex != NULL) {
    395     pattern_ = posix::StrDup(regex);
    396   }
    397 
    398   is_valid_ = ValidateRegex(regex);
    399   if (!is_valid_) {
    400     // No need to calculate the full pattern when the regex is invalid.
    401     return;
    402   }
    403 
    404   const size_t len = strlen(regex);
    405   // Reserves enough bytes to hold the regular expression used for a
    406   // full match: we need space to prepend a '^', append a '$', and
    407   // terminate the string with '\0'.
    408   char* buffer = static_cast<char*>(malloc(len + 3));
    409   full_pattern_ = buffer;
    410 
    411   if (*regex != '^')
    412     *buffer++ = '^';  // Makes sure full_pattern_ starts with '^'.
    413 
    414   // We don't use snprintf or strncpy, as they trigger a warning when
    415   // compiled with VC++ 8.0.
    416   memcpy(buffer, regex, len);
    417   buffer += len;
    418 
    419   if (len == 0 || regex[len - 1] != '$')
    420     *buffer++ = '$';  // Makes sure full_pattern_ ends with '$'.
    421 
    422   *buffer = '\0';
    423 }
    424 
    425 #endif  // GTEST_USES_POSIX_RE
    426 
    427 const char kUnknownFile[] = "unknown file";
    428 
    429 // Formats a source file path and a line number as they would appear
    430 // in an error message from the compiler used to compile this code.
    431 GTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {
    432   const char* const file_name = file == NULL ? kUnknownFile : file;
    433 
    434   if (line < 0) {
    435     return String::Format("%s:", file_name).c_str();
    436   }
    437 #ifdef _MSC_VER
    438   return String::Format("%s(%d):", file_name, line).c_str();
    439 #else
    440   return String::Format("%s:%d:", file_name, line).c_str();
    441 #endif  // _MSC_VER
    442 }
    443 
    444 // Formats a file location for compiler-independent XML output.
    445 // Although this function is not platform dependent, we put it next to
    446 // FormatFileLocation in order to contrast the two functions.
    447 // Note that FormatCompilerIndependentFileLocation() does NOT append colon
    448 // to the file location it produces, unlike FormatFileLocation().
    449 GTEST_API_ ::std::string FormatCompilerIndependentFileLocation(
    450     const char* file, int line) {
    451   const char* const file_name = file == NULL ? kUnknownFile : file;
    452 
    453   if (line < 0)
    454     return file_name;
    455   else
    456     return String::Format("%s:%d", file_name, line).c_str();
    457 }
    458 
    459 
    460 GTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)
    461     : severity_(severity) {
    462   const char* const marker =
    463       severity == GTEST_INFO ?    "[  INFO ]" :
    464       severity == GTEST_WARNING ? "[WARNING]" :
    465       severity == GTEST_ERROR ?   "[ ERROR ]" : "[ FATAL ]";
    466   GetStream() << ::std::endl << marker << " "
    467               << FormatFileLocation(file, line).c_str() << ": ";
    468 }
    469 
    470 // Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
    471 GTestLog::~GTestLog() {
    472   GetStream() << ::std::endl;
    473   if (severity_ == GTEST_FATAL) {
    474     fflush(stderr);
    475     posix::Abort();
    476   }
    477 }
    478 // Disable Microsoft deprecation warnings for POSIX functions called from
    479 // this class (creat, dup, dup2, and close)
    480 #ifdef _MSC_VER
    481 # pragma warning(push)
    482 # pragma warning(disable: 4996)
    483 #endif  // _MSC_VER
    484 
    485 #if GTEST_HAS_STREAM_REDIRECTION
    486 
    487 // Object that captures an output stream (stdout/stderr).
    488 class CapturedStream {
    489  public:
    490   // The ctor redirects the stream to a temporary file.
    491   CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
    492 
    493 # if GTEST_OS_WINDOWS
    494     char temp_dir_path[MAX_PATH + 1] = { '\0' };  // NOLINT
    495     char temp_file_path[MAX_PATH + 1] = { '\0' };  // NOLINT
    496 
    497     ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);
    498     const UINT success = ::GetTempFileNameA(temp_dir_path,
    499                                             "gtest_redir",
    500                                             0,  // Generate unique file name.
    501                                             temp_file_path);
    502     GTEST_CHECK_(success != 0)
    503         << "Unable to create a temporary file in " << temp_dir_path;
    504     const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
    505     GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file "
    506                                     << temp_file_path;
    507     filename_ = temp_file_path;
    508 // ANDROID
    509 #elif GTEST_OS_LINUX_ANDROID
    510     // Get $EXTERNAL_STORAGE from the environment, since this can change
    511     // for shell users (fallback is /data/nativetest, for emulator users).
    512     ::std::string external_storage = "/data/nativetest";
    513     char *sdcard_path = getenv("EXTERNAL_STORAGE");
    514     if (sdcard_path != NULL) {
    515       // Check that $EXTERNAL_STORAGE exists and is writable before trying to use it.
    516       struct stat sb;
    517       if (stat(sdcard_path, &sb) != -1) {
    518         if ((sb.st_mode & S_IWUSR) != 0) {
    519           external_storage = sdcard_path;
    520         }
    521       }
    522     }
    523     external_storage += "/captured_stderr.XXXXXX";
    524     char *name_template = strdup(external_storage.c_str());
    525     const int captured_fd = mkstemp(name_template);
    526     GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file "
    527                                     << name_template;
    528     filename_ = name_template;
    529     free(name_template);
    530     name_template = NULL;
    531 // END ANDROID
    532 # else
    533     // There's no guarantee that a test has write access to the
    534     // current directory, so we create the temporary file in the /tmp
    535     // directory instead.
    536     char name_template[] = "/tmp/captured_stream.XXXXXX";
    537     const int captured_fd = mkstemp(name_template);
    538     filename_ = name_template;
    539 # endif  // GTEST_OS_WINDOWS
    540     fflush(NULL);
    541     dup2(captured_fd, fd_);
    542     close(captured_fd);
    543   }
    544 
    545   ~CapturedStream() {
    546     remove(filename_.c_str());
    547   }
    548 
    549   String GetCapturedString() {
    550     if (uncaptured_fd_ != -1) {
    551       // Restores the original stream.
    552       fflush(NULL);
    553       dup2(uncaptured_fd_, fd_);
    554       close(uncaptured_fd_);
    555       uncaptured_fd_ = -1;
    556     }
    557 
    558     FILE* const file = posix::FOpen(filename_.c_str(), "r");
    559     const String content = ReadEntireFile(file);
    560     posix::FClose(file);
    561     return content;
    562   }
    563 
    564  private:
    565   // Reads the entire content of a file as a String.
    566   static String ReadEntireFile(FILE* file);
    567 
    568   // Returns the size (in bytes) of a file.
    569   static size_t GetFileSize(FILE* file);
    570 
    571   const int fd_;  // A stream to capture.
    572   int uncaptured_fd_;
    573   // Name of the temporary file holding the stderr output.
    574   ::std::string filename_;
    575 
    576   GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
    577 };
    578 
    579 // Returns the size (in bytes) of a file.
    580 size_t CapturedStream::GetFileSize(FILE* file) {
    581   fseek(file, 0, SEEK_END);
    582   return static_cast<size_t>(ftell(file));
    583 }
    584 
    585 // Reads the entire content of a file as a string.
    586 String CapturedStream::ReadEntireFile(FILE* file) {
    587   const size_t file_size = GetFileSize(file);
    588   char* const buffer = new char[file_size];
    589 
    590   size_t bytes_last_read = 0;  // # of bytes read in the last fread()
    591   size_t bytes_read = 0;       // # of bytes read so far
    592 
    593   fseek(file, 0, SEEK_SET);
    594 
    595   // Keeps reading the file until we cannot read further or the
    596   // pre-determined file size is reached.
    597   do {
    598     bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);
    599     bytes_read += bytes_last_read;
    600   } while (bytes_last_read > 0 && bytes_read < file_size);
    601 
    602   const String content(buffer, bytes_read);
    603   delete[] buffer;
    604 
    605   return content;
    606 }
    607 
    608 # ifdef _MSC_VER
    609 #  pragma warning(pop)
    610 # endif  // _MSC_VER
    611 
    612 static CapturedStream* g_captured_stderr = NULL;
    613 static CapturedStream* g_captured_stdout = NULL;
    614 
    615 // Starts capturing an output stream (stdout/stderr).
    616 void CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
    617   if (*stream != NULL) {
    618     GTEST_LOG_(FATAL) << "Only one " << stream_name
    619                       << " capturer can exist at a time.";
    620   }
    621   *stream = new CapturedStream(fd);
    622 }
    623 
    624 // Stops capturing the output stream and returns the captured string.
    625 String GetCapturedStream(CapturedStream** captured_stream) {
    626   const String content = (*captured_stream)->GetCapturedString();
    627 
    628   delete *captured_stream;
    629   *captured_stream = NULL;
    630 
    631   return content;
    632 }
    633 
    634 // Starts capturing stdout.
    635 void CaptureStdout() {
    636   CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout);
    637 }
    638 
    639 // Starts capturing stderr.
    640 void CaptureStderr() {
    641   CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr);
    642 }
    643 
    644 // Stops capturing stdout and returns the captured string.
    645 String GetCapturedStdout() { return GetCapturedStream(&g_captured_stdout); }
    646 
    647 // Stops capturing stderr and returns the captured string.
    648 String GetCapturedStderr() { return GetCapturedStream(&g_captured_stderr); }
    649 
    650 #endif  // GTEST_HAS_STREAM_REDIRECTION
    651 
    652 #if GTEST_HAS_DEATH_TEST
    653 
    654 // A copy of all command line arguments.  Set by InitGoogleTest().
    655 ::std::vector<String> g_argvs;
    656 
    657 // Returns the command line as a vector of strings.
    658 const ::std::vector<String>& GetArgvs() { return g_argvs; }
    659 
    660 #endif  // GTEST_HAS_DEATH_TEST
    661 
    662 #if GTEST_OS_WINDOWS_MOBILE
    663 namespace posix {
    664 void Abort() {
    665   DebugBreak();
    666   TerminateProcess(GetCurrentProcess(), 1);
    667 }
    668 }  // namespace posix
    669 #endif  // GTEST_OS_WINDOWS_MOBILE
    670 
    671 // Returns the name of the environment variable corresponding to the
    672 // given flag.  For example, FlagToEnvVar("foo") will return
    673 // "GTEST_FOO" in the open-source version.
    674 static String FlagToEnvVar(const char* flag) {
    675   const String full_flag =
    676       (Message() << GTEST_FLAG_PREFIX_ << flag).GetString();
    677 
    678   Message env_var;
    679   for (size_t i = 0; i != full_flag.length(); i++) {
    680     env_var << ToUpper(full_flag.c_str()[i]);
    681   }
    682 
    683   return env_var.GetString();
    684 }
    685 
    686 // Parses 'str' for a 32-bit signed integer.  If successful, writes
    687 // the result to *value and returns true; otherwise leaves *value
    688 // unchanged and returns false.
    689 bool ParseInt32(const Message& src_text, const char* str, Int32* value) {
    690   // Parses the environment variable as a decimal integer.
    691   char* end = NULL;
    692   const long long_value = strtol(str, &end, 10);  // NOLINT
    693 
    694   // Has strtol() consumed all characters in the string?
    695   if (*end != '\0') {
    696     // No - an invalid character was encountered.
    697     Message msg;
    698     msg << "WARNING: " << src_text
    699         << " is expected to be a 32-bit integer, but actually"
    700         << " has value \"" << str << "\".\n";
    701     printf("%s", msg.GetString().c_str());
    702     fflush(stdout);
    703     return false;
    704   }
    705 
    706   // Is the parsed value in the range of an Int32?
    707   const Int32 result = static_cast<Int32>(long_value);
    708   if (long_value == LONG_MAX || long_value == LONG_MIN ||
    709       // The parsed value overflows as a long.  (strtol() returns
    710       // LONG_MAX or LONG_MIN when the input overflows.)
    711       result != long_value
    712       // The parsed value overflows as an Int32.
    713       ) {
    714     Message msg;
    715     msg << "WARNING: " << src_text
    716         << " is expected to be a 32-bit integer, but actually"
    717         << " has value " << str << ", which overflows.\n";
    718     printf("%s", msg.GetString().c_str());
    719     fflush(stdout);
    720     return false;
    721   }
    722 
    723   *value = result;
    724   return true;
    725 }
    726 
    727 // Reads and returns the Boolean environment variable corresponding to
    728 // the given flag; if it's not set, returns default_value.
    729 //
    730 // The value is considered true iff it's not "0".
    731 bool BoolFromGTestEnv(const char* flag, bool default_value) {
    732   const String env_var = FlagToEnvVar(flag);
    733   const char* const string_value = posix::GetEnv(env_var.c_str());
    734   return string_value == NULL ?
    735       default_value : strcmp(string_value, "0") != 0;
    736 }
    737 
    738 // Reads and returns a 32-bit integer stored in the environment
    739 // variable corresponding to the given flag; if it isn't set or
    740 // doesn't represent a valid 32-bit integer, returns default_value.
    741 Int32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
    742   const String env_var = FlagToEnvVar(flag);
    743   const char* const string_value = posix::GetEnv(env_var.c_str());
    744   if (string_value == NULL) {
    745     // The environment variable is not set.
    746     return default_value;
    747   }
    748 
    749   Int32 result = default_value;
    750   if (!ParseInt32(Message() << "Environment variable " << env_var,
    751                   string_value, &result)) {
    752     printf("The default value %s is used.\n",
    753            (Message() << default_value).GetString().c_str());
    754     fflush(stdout);
    755     return default_value;
    756   }
    757 
    758   return result;
    759 }
    760 
    761 // Reads and returns the string environment variable corresponding to
    762 // the given flag; if it's not set, returns default_value.
    763 const char* StringFromGTestEnv(const char* flag, const char* default_value) {
    764   const String env_var = FlagToEnvVar(flag);
    765   const char* const value = posix::GetEnv(env_var.c_str());
    766   return value == NULL ? default_value : value;
    767 }
    768 
    769 }  // namespace internal
    770 }  // namespace testing
    771