111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Copyright 2008, Google Inc.
211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// All rights reserved.
311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//
411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Redistribution and use in source and binary forms, with or without
511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// modification, are permitted provided that the following conditions are
611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// met:
711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//
811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//     * Redistributions of source code must retain the above copyright
911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// notice, this list of conditions and the following disclaimer.
1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//     * Redistributions in binary form must reproduce the above
1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// copyright notice, this list of conditions and the following disclaimer
1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// in the documentation and/or other materials provided with the
1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// distribution.
1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//     * Neither the name of Google Inc. nor the names of its
1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// contributors may be used to endorse or promote products derived from
1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// this software without specific prior written permission.
1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//
1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//
3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Author: wan@google.com (Zhanyong Wan)
3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "gtest/internal/gtest-port.h"
3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <limits.h>
3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <stdlib.h>
3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <stdio.h>
3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <string.h>
3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if GTEST_OS_WINDOWS_MOBILE
4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <windows.h>  // For TerminateProcess()
4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#elif GTEST_OS_WINDOWS
4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <io.h>
4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <sys/stat.h>
4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <unistd.h>
4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif  // GTEST_OS_WINDOWS_MOBILE
4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if GTEST_OS_MAC
4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <mach/mach_init.h>
5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <mach/task.h>
5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <mach/vm_map.h>
5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif  // GTEST_OS_MAC
5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if GTEST_OS_QNX
5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <devctl.h>
5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <sys/procfs.h>
5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif  // GTEST_OS_QNX
5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "gtest/gtest-spi.h"
6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "gtest/gtest-message.h"
6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "gtest/internal/gtest-internal.h"
6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "gtest/internal/gtest-string.h"
6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Indicates that this translation unit is part of Google Test's
6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// implementation.  It must come before gtest-internal-inl.h is
6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// included, or there will be a compiler error.  This trick is to
6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// prevent a user from accidentally including gtest-internal-inl.h in
6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// his code.
6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define GTEST_IMPLEMENTATION_ 1
7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include "src/gtest-internal-inl.h"
7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#undef GTEST_IMPLEMENTATION_
7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertnamespace testing {
7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertnamespace internal {
7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if defined(_MSC_VER) || defined(__BORLANDC__)
7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// MSVC and C++Builder do not provide a definition of STDERR_FILENO.
7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertconst int kStdOutFileno = 1;
7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertconst int kStdErrFileno = 2;
8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertconst int kStdOutFileno = STDOUT_FILENO;
8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertconst int kStdErrFileno = STDERR_FILENO;
8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif  // _MSC_VER
8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if GTEST_OS_MAC
8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Returns the number of threads running in the process, or 0 to indicate that
8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// we cannot detect it.
8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertsize_t GetThreadCount() {
9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const task_t task = mach_task_self();
9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  mach_msg_type_number_t thread_count;
9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  thread_act_array_t thread_list;
9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const kern_return_t status = task_threads(task, &thread_list, &thread_count);
9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (status == KERN_SUCCESS) {
9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // task_threads allocates resources in thread_list and we need to free them
9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // to avoid leaks.
9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    vm_deallocate(task,
9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                  reinterpret_cast<vm_address_t>(thread_list),
9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                  sizeof(thread_t) * thread_count);
10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return static_cast<size_t>(thread_count);
10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  } else {
10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return 0;
10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#elif GTEST_OS_QNX
10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Returns the number of threads running in the process, or 0 to indicate that
10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// we cannot detect it.
11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertsize_t GetThreadCount() {
11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const int fd = open("/proc/self/as", O_RDONLY);
11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (fd < 0) {
11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return 0;
11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  procfs_info process_info;
11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const int status =
11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      devctl(fd, DCMD_PROC_INFO, &process_info, sizeof(process_info), NULL);
11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  close(fd);
11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (status == EOK) {
12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return static_cast<size_t>(process_info.num_threads);
12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  } else {
12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return 0;
12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertsize_t GetThreadCount() {
12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // There's no portable way to detect the number of threads, so we just
13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // return 0 to indicate that we cannot detect it.
13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return 0;
13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif  // GTEST_OS_MAC
13511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if GTEST_USES_POSIX_RE
13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Implements RE.  Currently only needed for death tests.
13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
14011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertRE::~RE() {
14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (is_valid_) {
14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // regfree'ing an invalid regex might crash because the content
14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // of the regex is undefined. Since the regex's are essentially
14411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // the same, one cannot be valid (or invalid) without the other
14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // being so too.
14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    regfree(&partial_regex_);
14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    regfree(&full_regex_);
14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  free(const_cast<char*>(pattern_));
15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Returns true iff regular expression re matches the entire str.
15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool RE::FullMatch(const char* str, const RE& re) {
15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (!re.is_valid_) return false;
15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  regmatch_t match;
15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return regexec(&re.full_regex_, str, 1, &match, 0) == 0;
15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
16011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Returns true iff regular expression re matches a substring of str
16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// (including str itself).
16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool RE::PartialMatch(const char* str, const RE& re) {
16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (!re.is_valid_) return false;
16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  regmatch_t match;
16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return regexec(&re.partial_regex_, str, 1, &match, 0) == 0;
16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Initializes an RE from its string representation.
17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid RE::Init(const char* regex) {
17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  pattern_ = posix::StrDup(regex);
17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Reserves enough bytes to hold the regular expression used for a
17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // full match.
17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const size_t full_regex_len = strlen(regex) + 10;
17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  char* const full_pattern = new char[full_regex_len];
17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  snprintf(full_pattern, full_regex_len, "^(%s)$", regex);
17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  is_valid_ = regcomp(&full_regex_, full_pattern, REG_EXTENDED) == 0;
18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // We want to call regcomp(&partial_regex_, ...) even if the
18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // previous expression returns false.  Otherwise partial_regex_ may
18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // not be properly initialized can may cause trouble when it's
18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // freed.
18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  //
18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Some implementation of POSIX regex (e.g. on at least some
18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // versions of Cygwin) doesn't accept the empty string as a valid
18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // regex.  We change it to an equivalent form "()" to be safe.
18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (is_valid_) {
18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    const char* const partial_regex = (*regex == '\0') ? "()" : regex;
19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    is_valid_ = regcomp(&partial_regex_, partial_regex, REG_EXTENDED) == 0;
19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  EXPECT_TRUE(is_valid_)
19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      << "Regular expression \"" << regex
19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      << "\" is not a valid POSIX Extended regular expression.";
19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  delete[] full_pattern;
19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#elif GTEST_USES_SIMPLE_RE
20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Returns true iff ch appears anywhere in str (excluding the
20211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// terminating '\0' character).
20311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool IsInSet(char ch, const char* str) {
20411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return ch != '\0' && strchr(str, ch) != NULL;
20511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
20611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
20711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Returns true iff ch belongs to the given classification.  Unlike
20811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// similar functions in <ctype.h>, these aren't affected by the
20911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// current locale.
21011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool IsAsciiDigit(char ch) { return '0' <= ch && ch <= '9'; }
21111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool IsAsciiPunct(char ch) {
21211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return IsInSet(ch, "^-!\"#$%&'()*+,./:;<=>?@[\\]_`{|}~");
21311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
21411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool IsRepeat(char ch) { return IsInSet(ch, "?*+"); }
21511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool IsAsciiWhiteSpace(char ch) { return IsInSet(ch, " \f\n\r\t\v"); }
21611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool IsAsciiWordChar(char ch) {
21711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return ('a' <= ch && ch <= 'z') || ('A' <= ch && ch <= 'Z') ||
21811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      ('0' <= ch && ch <= '9') || ch == '_';
21911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
22011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
22111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Returns true iff "\\c" is a supported escape sequence.
22211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool IsValidEscape(char c) {
22311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return (IsAsciiPunct(c) || IsInSet(c, "dDfnrsStvwW"));
22411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
22511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
22611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Returns true iff the given atom (specified by escaped and pattern)
22711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// matches ch.  The result is undefined if the atom is invalid.
22811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool AtomMatchesChar(bool escaped, char pattern_char, char ch) {
22911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (escaped) {  // "\\p" where p is pattern_char.
23011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    switch (pattern_char) {
23111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      case 'd': return IsAsciiDigit(ch);
23211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      case 'D': return !IsAsciiDigit(ch);
23311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      case 'f': return ch == '\f';
23411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      case 'n': return ch == '\n';
23511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      case 'r': return ch == '\r';
23611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      case 's': return IsAsciiWhiteSpace(ch);
23711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      case 'S': return !IsAsciiWhiteSpace(ch);
23811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      case 't': return ch == '\t';
23911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      case 'v': return ch == '\v';
24011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      case 'w': return IsAsciiWordChar(ch);
24111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      case 'W': return !IsAsciiWordChar(ch);
24211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
24311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return IsAsciiPunct(pattern_char) && pattern_char == ch;
24411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
24511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
24611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return (pattern_char == '.' && ch != '\n') || pattern_char == ch;
24711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
24811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
24911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Helper function used by ValidateRegex() to format error messages.
25011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstd::string FormatRegexSyntaxError(const char* regex, int index) {
25111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return (Message() << "Syntax error at index " << index
25211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert          << " in simple regular expression \"" << regex << "\": ").GetString();
25311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
25411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
25511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Generates non-fatal failures and returns false if regex is invalid;
25611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// otherwise returns true.
25711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool ValidateRegex(const char* regex) {
25811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (regex == NULL) {
25911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // TODO(wan@google.com): fix the source file location in the
26011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // assertion failures to match where the regex is used in user
26111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // code.
26211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    ADD_FAILURE() << "NULL is not a valid simple regular expression.";
26311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return false;
26411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
26511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
26611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  bool is_valid = true;
26711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
26811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // True iff ?, *, or + can follow the previous atom.
26911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  bool prev_repeatable = false;
27011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  for (int i = 0; regex[i]; i++) {
27111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (regex[i] == '\\') {  // An escape sequence
27211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      i++;
27311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (regex[i] == '\0') {
27411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
27511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                      << "'\\' cannot appear at the end.";
27611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        return false;
27711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
27811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
27911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (!IsValidEscape(regex[i])) {
28011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        ADD_FAILURE() << FormatRegexSyntaxError(regex, i - 1)
28111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                      << "invalid escape sequence \"\\" << regex[i] << "\".";
28211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        is_valid = false;
28311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
28411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      prev_repeatable = true;
28511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    } else {  // Not an escape sequence.
28611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      const char ch = regex[i];
28711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
28811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (ch == '^' && i > 0) {
28911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
29011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                      << "'^' can only appear at the beginning.";
29111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        is_valid = false;
29211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      } else if (ch == '$' && regex[i + 1] != '\0') {
29311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
29411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                      << "'$' can only appear at the end.";
29511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        is_valid = false;
29611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      } else if (IsInSet(ch, "()[]{}|")) {
29711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
29811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                      << "'" << ch << "' is unsupported.";
29911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        is_valid = false;
30011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      } else if (IsRepeat(ch) && !prev_repeatable) {
30111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        ADD_FAILURE() << FormatRegexSyntaxError(regex, i)
30211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                      << "'" << ch << "' can only follow a repeatable token.";
30311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        is_valid = false;
30411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
30511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
30611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      prev_repeatable = !IsInSet(ch, "^$?*+");
30711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
30811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
30911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
31011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return is_valid;
31111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
31211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
31311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Matches a repeated regex atom followed by a valid simple regular
31411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// expression.  The regex atom is defined as c if escaped is false,
31511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// or \c otherwise.  repeat is the repetition meta character (?, *,
31611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// or +).  The behavior is undefined if str contains too many
31711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// characters to be indexable by size_t, in which case the test will
31811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// probably time out anyway.  We are fine with this limitation as
31911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// std::string has it too.
32011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool MatchRepetitionAndRegexAtHead(
32111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    bool escaped, char c, char repeat, const char* regex,
32211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    const char* str) {
32311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const size_t min_count = (repeat == '+') ? 1 : 0;
32411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const size_t max_count = (repeat == '?') ? 1 :
32511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      static_cast<size_t>(-1) - 1;
32611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // We cannot call numeric_limits::max() as it conflicts with the
32711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // max() macro on Windows.
32811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
32911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  for (size_t i = 0; i <= max_count; ++i) {
33011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // We know that the atom matches each of the first i characters in str.
33111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (i >= min_count && MatchRegexAtHead(regex, str + i)) {
33211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // We have enough matches at the head, and the tail matches too.
33311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // Since we only care about *whether* the pattern matches str
33411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // (as opposed to *how* it matches), there is no need to find a
33511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // greedy match.
33611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return true;
33711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
33811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (str[i] == '\0' || !AtomMatchesChar(escaped, c, str[i]))
33911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return false;
34011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
34111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return false;
34211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
34311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
34411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Returns true iff regex matches a prefix of str.  regex must be a
34511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// valid simple regular expression and not start with "^", or the
34611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// result is undefined.
34711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool MatchRegexAtHead(const char* regex, const char* str) {
34811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (*regex == '\0')  // An empty regex matches a prefix of anything.
34911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return true;
35011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
35111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // "$" only matches the end of a string.  Note that regex being
35211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // valid guarantees that there's nothing after "$" in it.
35311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (*regex == '$')
35411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return *str == '\0';
35511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
35611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Is the first thing in regex an escape sequence?
35711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const bool escaped = *regex == '\\';
35811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (escaped)
35911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    ++regex;
36011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (IsRepeat(regex[1])) {
36111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // MatchRepetitionAndRegexAtHead() calls MatchRegexAtHead(), so
36211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // here's an indirect recursion.  It terminates as the regex gets
36311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // shorter in each recursion.
36411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return MatchRepetitionAndRegexAtHead(
36511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        escaped, regex[0], regex[1], regex + 2, str);
36611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  } else {
36711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // regex isn't empty, isn't "$", and doesn't start with a
36811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // repetition.  We match the first atom of regex with the first
36911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // character of str and recurse.
37011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return (*str != '\0') && AtomMatchesChar(escaped, *regex, *str) &&
37111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        MatchRegexAtHead(regex + 1, str + 1);
37211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
37311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
37411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
37511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Returns true iff regex matches any substring of str.  regex must be
37611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// a valid simple regular expression, or the result is undefined.
37711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//
37811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// The algorithm is recursive, but the recursion depth doesn't exceed
37911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// the regex length, so we won't need to worry about running out of
38011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// stack space normally.  In rare cases the time complexity can be
38111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// exponential with respect to the regex length + the string length,
38211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// but usually it's must faster (often close to linear).
38311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool MatchRegexAnywhere(const char* regex, const char* str) {
38411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (regex == NULL || str == NULL)
38511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return false;
38611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
38711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (*regex == '^')
38811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return MatchRegexAtHead(regex + 1, str);
38911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
39011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // A successful match can be anywhere in str.
39111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  do {
39211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (MatchRegexAtHead(regex, str))
39311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return true;
39411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  } while (*str++ != '\0');
39511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return false;
39611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
39711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
39811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Implements the RE class.
39911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
40011cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertRE::~RE() {
40111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  free(const_cast<char*>(pattern_));
40211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  free(const_cast<char*>(full_pattern_));
40311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
40411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
40511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Returns true iff regular expression re matches the entire str.
40611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool RE::FullMatch(const char* str, const RE& re) {
40711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return re.is_valid_ && MatchRegexAnywhere(re.full_pattern_, str);
40811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
40911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
41011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Returns true iff regular expression re matches a substring of str
41111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// (including str itself).
41211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool RE::PartialMatch(const char* str, const RE& re) {
41311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return re.is_valid_ && MatchRegexAnywhere(re.pattern_, str);
41411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
41511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
41611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Initializes an RE from its string representation.
41711cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid RE::Init(const char* regex) {
41811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  pattern_ = full_pattern_ = NULL;
41911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (regex != NULL) {
42011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    pattern_ = posix::StrDup(regex);
42111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
42211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
42311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  is_valid_ = ValidateRegex(regex);
42411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (!is_valid_) {
42511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // No need to calculate the full pattern when the regex is invalid.
42611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return;
42711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
42811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
42911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const size_t len = strlen(regex);
43011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Reserves enough bytes to hold the regular expression used for a
43111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // full match: we need space to prepend a '^', append a '$', and
43211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // terminate the string with '\0'.
43311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  char* buffer = static_cast<char*>(malloc(len + 3));
43411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  full_pattern_ = buffer;
43511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
43611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (*regex != '^')
43711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    *buffer++ = '^';  // Makes sure full_pattern_ starts with '^'.
43811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
43911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // We don't use snprintf or strncpy, as they trigger a warning when
44011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // compiled with VC++ 8.0.
44111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  memcpy(buffer, regex, len);
44211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  buffer += len;
44311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
44411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (len == 0 || regex[len - 1] != '$')
44511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    *buffer++ = '$';  // Makes sure full_pattern_ ends with '$'.
44611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
44711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  *buffer = '\0';
44811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
44911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
45011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif  // GTEST_USES_POSIX_RE
45111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
45211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertconst char kUnknownFile[] = "unknown file";
45311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
45411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Formats a source file path and a line number as they would appear
45511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// in an error message from the compiler used to compile this code.
45611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGTEST_API_ ::std::string FormatFileLocation(const char* file, int line) {
45711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const std::string file_name(file == NULL ? kUnknownFile : file);
45811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
45911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (line < 0) {
46011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return file_name + ":";
46111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
46211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef _MSC_VER
46311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return file_name + "(" + StreamableToString(line) + "):";
46411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
46511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return file_name + ":" + StreamableToString(line) + ":";
46611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif  // _MSC_VER
46711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
46811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
46911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Formats a file location for compiler-independent XML output.
47011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Although this function is not platform dependent, we put it next to
47111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// FormatFileLocation in order to contrast the two functions.
47211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Note that FormatCompilerIndependentFileLocation() does NOT append colon
47311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// to the file location it produces, unlike FormatFileLocation().
47411cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGTEST_API_ ::std::string FormatCompilerIndependentFileLocation(
47511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    const char* file, int line) {
47611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const std::string file_name(file == NULL ? kUnknownFile : file);
47711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
47811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (line < 0)
47911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return file_name;
48011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  else
48111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return file_name + ":" + StreamableToString(line);
48211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
48311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
48411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
48511cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGTestLog::GTestLog(GTestLogSeverity severity, const char* file, int line)
48611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    : severity_(severity) {
48711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const char* const marker =
48811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      severity == GTEST_INFO ?    "[  INFO ]" :
48911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      severity == GTEST_WARNING ? "[WARNING]" :
49011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      severity == GTEST_ERROR ?   "[ ERROR ]" : "[ FATAL ]";
49111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  GetStream() << ::std::endl << marker << " "
49211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert              << FormatFileLocation(file, line).c_str() << ": ";
49311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
49411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
49511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Flushes the buffers and, if severity is GTEST_FATAL, aborts the program.
49611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertGTestLog::~GTestLog() {
49711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  GetStream() << ::std::endl;
49811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (severity_ == GTEST_FATAL) {
49911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    fflush(stderr);
50011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    posix::Abort();
50111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
50211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
50311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Disable Microsoft deprecation warnings for POSIX functions called from
50411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// this class (creat, dup, dup2, and close)
50511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifdef _MSC_VER
50611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# pragma warning(push)
50711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# pragma warning(disable: 4996)
50811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif  // _MSC_VER
50911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
51011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if GTEST_HAS_STREAM_REDIRECTION
51111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
51211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Object that captures an output stream (stdout/stderr).
51311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertclass CapturedStream {
51411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert public:
51511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // The ctor redirects the stream to a temporary file.
51611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  explicit CapturedStream(int fd) : fd_(fd), uncaptured_fd_(dup(fd)) {
51711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# if GTEST_OS_WINDOWS
51811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    char temp_dir_path[MAX_PATH + 1] = { '\0' };  // NOLINT
51911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    char temp_file_path[MAX_PATH + 1] = { '\0' };  // NOLINT
52011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
52111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    ::GetTempPathA(sizeof(temp_dir_path), temp_dir_path);
52211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    const UINT success = ::GetTempFileNameA(temp_dir_path,
52311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                            "gtest_redir",
52411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                            0,  // Generate unique file name.
52511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                            temp_file_path);
52611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    GTEST_CHECK_(success != 0)
52711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        << "Unable to create a temporary file in " << temp_dir_path;
52811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    const int captured_fd = creat(temp_file_path, _S_IREAD | _S_IWRITE);
52911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    GTEST_CHECK_(captured_fd != -1) << "Unable to open temporary file "
53011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                    << temp_file_path;
53111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    filename_ = temp_file_path;
53211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# else
53311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // There's no guarantee that a test has write access to the current
53411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // directory, so we create the temporary file in the /tmp directory
53511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // instead. We use /tmp on most systems, and /sdcard on Android.
53611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // That's because Android doesn't have /tmp.
53711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  if GTEST_OS_LINUX_ANDROID
53811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // Note: Android applications are expected to call the framework's
53911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // Context.getExternalStorageDirectory() method through JNI to get
54011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // the location of the world-writable SD Card directory. However,
54111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // this requires a Context handle, which cannot be retrieved
54211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // globally from native code. Doing so also precludes running the
54311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // code as part of a regular standalone executable, which doesn't
54411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // run in a Dalvik process (e.g. when running it through 'adb shell').
54511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    //
54611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // The location /sdcard is directly accessible from native code
54711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // and is the only location (unofficially) supported by the Android
54811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // team. It's generally a symlink to the real SD Card mount point
54911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // which can be /mnt/sdcard, /mnt/sdcard0, /system/media/sdcard, or
55011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // other OEM-customized locations. Never rely on these, and always
55111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // use /sdcard.
55211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    char name_template[] = "/sdcard/gtest_captured_stream.XXXXXX";
55311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  else
55411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    char name_template[] = "/tmp/captured_stream.XXXXXX";
55511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  endif  // GTEST_OS_LINUX_ANDROID
55611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    const int captured_fd = mkstemp(name_template);
55711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    filename_ = name_template;
55811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# endif  // GTEST_OS_WINDOWS
55911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    fflush(NULL);
56011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    dup2(captured_fd, fd_);
56111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    close(captured_fd);
56211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
56311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
56411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  ~CapturedStream() {
56511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    remove(filename_.c_str());
56611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
56711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
56811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  std::string GetCapturedString() {
56911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    if (uncaptured_fd_ != -1) {
57011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // Restores the original stream.
57111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      fflush(NULL);
57211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      dup2(uncaptured_fd_, fd_);
57311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      close(uncaptured_fd_);
57411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      uncaptured_fd_ = -1;
57511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
57611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
57711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    FILE* const file = posix::FOpen(filename_.c_str(), "r");
57811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    const std::string content = ReadEntireFile(file);
57911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    posix::FClose(file);
58011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return content;
58111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
58211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
58311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert private:
58411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Reads the entire content of a file as an std::string.
58511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static std::string ReadEntireFile(FILE* file);
58611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
58711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Returns the size (in bytes) of a file.
58811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  static size_t GetFileSize(FILE* file);
58911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
59011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const int fd_;  // A stream to capture.
59111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  int uncaptured_fd_;
59211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Name of the temporary file holding the stderr output.
59311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  ::std::string filename_;
59411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
59511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  GTEST_DISALLOW_COPY_AND_ASSIGN_(CapturedStream);
59611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert};
59711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
59811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Returns the size (in bytes) of a file.
59911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertsize_t CapturedStream::GetFileSize(FILE* file) {
60011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  fseek(file, 0, SEEK_END);
60111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return static_cast<size_t>(ftell(file));
60211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
60311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
60411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Reads the entire content of a file as a string.
60511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstd::string CapturedStream::ReadEntireFile(FILE* file) {
60611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const size_t file_size = GetFileSize(file);
60711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  char* const buffer = new char[file_size];
60811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
60911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t bytes_last_read = 0;  // # of bytes read in the last fread()
61011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  size_t bytes_read = 0;       // # of bytes read so far
61111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
61211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  fseek(file, 0, SEEK_SET);
61311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
61411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Keeps reading the file until we cannot read further or the
61511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // pre-determined file size is reached.
61611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  do {
61711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    bytes_last_read = fread(buffer+bytes_read, 1, file_size-bytes_read, file);
61811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    bytes_read += bytes_last_read;
61911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  } while (bytes_last_read > 0 && bytes_read < file_size);
62011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
62111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const std::string content(buffer, bytes_read);
62211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  delete[] buffer;
62311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
62411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return content;
62511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
62611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
62711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# ifdef _MSC_VER
62811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#  pragma warning(pop)
62911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# endif  // _MSC_VER
63011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
63111cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic CapturedStream* g_captured_stderr = NULL;
63211cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic CapturedStream* g_captured_stdout = NULL;
63311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
63411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Starts capturing an output stream (stdout/stderr).
63511cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid CaptureStream(int fd, const char* stream_name, CapturedStream** stream) {
63611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (*stream != NULL) {
63711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    GTEST_LOG_(FATAL) << "Only one " << stream_name
63811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                      << " capturer can exist at a time.";
63911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
64011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  *stream = new CapturedStream(fd);
64111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
64211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
64311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Stops capturing the output stream and returns the captured string.
64411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstd::string GetCapturedStream(CapturedStream** captured_stream) {
64511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const std::string content = (*captured_stream)->GetCapturedString();
64611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
64711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  delete *captured_stream;
64811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  *captured_stream = NULL;
64911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
65011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return content;
65111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
65211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
65311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Starts capturing stdout.
65411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid CaptureStdout() {
65511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  CaptureStream(kStdOutFileno, "stdout", &g_captured_stdout);
65611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
65711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
65811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Starts capturing stderr.
65911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid CaptureStderr() {
66011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  CaptureStream(kStdErrFileno, "stderr", &g_captured_stderr);
66111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
66211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
66311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Stops capturing stdout and returns the captured string.
66411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstd::string GetCapturedStdout() {
66511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return GetCapturedStream(&g_captured_stdout);
66611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
66711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
66811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Stops capturing stderr and returns the captured string.
66911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstd::string GetCapturedStderr() {
67011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return GetCapturedStream(&g_captured_stderr);
67111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
67211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
67311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif  // GTEST_HAS_STREAM_REDIRECTION
67411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
67511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if GTEST_HAS_DEATH_TEST
67611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
67711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// A copy of all command line arguments.  Set by InitGoogleTest().
67811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert::std::vector<testing::internal::string> g_argvs;
67911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
68011cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic const ::std::vector<testing::internal::string>* g_injected_test_argvs =
68111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                                        NULL;  // Owned.
68211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
68311cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid SetInjectableArgvs(const ::std::vector<testing::internal::string>* argvs) {
68411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (g_injected_test_argvs != argvs)
68511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    delete g_injected_test_argvs;
68611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  g_injected_test_argvs = argvs;
68711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
68811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
68911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertconst ::std::vector<testing::internal::string>& GetInjectableArgvs() {
69011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (g_injected_test_argvs != NULL) {
69111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return *g_injected_test_argvs;
69211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
69311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return g_argvs;
69411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
69511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif  // GTEST_HAS_DEATH_TEST
69611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
69711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if GTEST_OS_WINDOWS_MOBILE
69811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertnamespace posix {
69911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertvoid Abort() {
70011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  DebugBreak();
70111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  TerminateProcess(GetCurrentProcess(), 1);
70211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
70311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}  // namespace posix
70411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif  // GTEST_OS_WINDOWS_MOBILE
70511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
70611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Returns the name of the environment variable corresponding to the
70711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// given flag.  For example, FlagToEnvVar("foo") will return
70811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// "GTEST_FOO" in the open-source version.
70911cd02dfb91661c65134cac258cf5924270e9d2Dan Albertstatic std::string FlagToEnvVar(const char* flag) {
71011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const std::string full_flag =
71111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      (Message() << GTEST_FLAG_PREFIX_ << flag).GetString();
71211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
71311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  Message env_var;
71411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  for (size_t i = 0; i != full_flag.length(); i++) {
71511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    env_var << ToUpper(full_flag.c_str()[i]);
71611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
71711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
71811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return env_var.GetString();
71911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
72011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
72111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Parses 'str' for a 32-bit signed integer.  If successful, writes
72211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// the result to *value and returns true; otherwise leaves *value
72311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// unchanged and returns false.
72411cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool ParseInt32(const Message& src_text, const char* str, Int32* value) {
72511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Parses the environment variable as a decimal integer.
72611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  char* end = NULL;
72711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const long long_value = strtol(str, &end, 10);  // NOLINT
72811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
72911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Has strtol() consumed all characters in the string?
73011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (*end != '\0') {
73111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // No - an invalid character was encountered.
73211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    Message msg;
73311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    msg << "WARNING: " << src_text
73411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        << " is expected to be a 32-bit integer, but actually"
73511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        << " has value \"" << str << "\".\n";
73611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    printf("%s", msg.GetString().c_str());
73711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    fflush(stdout);
73811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return false;
73911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
74011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
74111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Is the parsed value in the range of an Int32?
74211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const Int32 result = static_cast<Int32>(long_value);
74311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (long_value == LONG_MAX || long_value == LONG_MIN ||
74411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // The parsed value overflows as a long.  (strtol() returns
74511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // LONG_MAX or LONG_MIN when the input overflows.)
74611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      result != long_value
74711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // The parsed value overflows as an Int32.
74811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      ) {
74911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    Message msg;
75011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    msg << "WARNING: " << src_text
75111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        << " is expected to be a 32-bit integer, but actually"
75211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        << " has value " << str << ", which overflows.\n";
75311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    printf("%s", msg.GetString().c_str());
75411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    fflush(stdout);
75511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return false;
75611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
75711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
75811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  *value = result;
75911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return true;
76011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
76111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
76211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Reads and returns the Boolean environment variable corresponding to
76311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// the given flag; if it's not set, returns default_value.
76411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//
76511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// The value is considered true iff it's not "0".
76611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertbool BoolFromGTestEnv(const char* flag, bool default_value) {
76711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const std::string env_var = FlagToEnvVar(flag);
76811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const char* const string_value = posix::GetEnv(env_var.c_str());
76911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return string_value == NULL ?
77011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      default_value : strcmp(string_value, "0") != 0;
77111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
77211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
77311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Reads and returns a 32-bit integer stored in the environment
77411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// variable corresponding to the given flag; if it isn't set or
77511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// doesn't represent a valid 32-bit integer, returns default_value.
77611cd02dfb91661c65134cac258cf5924270e9d2Dan AlbertInt32 Int32FromGTestEnv(const char* flag, Int32 default_value) {
77711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const std::string env_var = FlagToEnvVar(flag);
77811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const char* const string_value = posix::GetEnv(env_var.c_str());
77911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (string_value == NULL) {
78011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // The environment variable is not set.
78111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return default_value;
78211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
78311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
78411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  Int32 result = default_value;
78511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  if (!ParseInt32(Message() << "Environment variable " << env_var,
78611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert                  string_value, &result)) {
78711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    printf("The default value %s is used.\n",
78811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert           (Message() << default_value).GetString().c_str());
78911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    fflush(stdout);
79011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return default_value;
79111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
79211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
79311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return result;
79411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
79511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
79611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Reads and returns the string environment variable corresponding to
79711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// the given flag; if it's not set, returns default_value.
79811cd02dfb91661c65134cac258cf5924270e9d2Dan Albertconst char* StringFromGTestEnv(const char* flag, const char* default_value) {
79911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const std::string env_var = FlagToEnvVar(flag);
80011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  const char* const value = posix::GetEnv(env_var.c_str());
80111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  return value == NULL ? default_value : value;
80211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}
80311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
80411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}  // namespace internal
80511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert}  // namespace testing
806