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